{"model_name":"qwen3.6-plus","codes":{"1":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Global data\nint N;\nvector<int> X, Y;\nvector<long long> R;\nstruct Rect { int x1, y1, x2, y2; };\n\nvector<Rect> best_ans;\ndouble best_score = -1.0;\n\ndouble calc_score(const vector<Rect>& rects) {\n    double total = 0.0;\n    for (int i = 0; i < N; ++i) {\n        long long s = (long long)(rects[i].x2 - rects[i].x1) * (rects[i].y2 - rects[i].y1);\n        double ratio = min(R[i], s) / (double)max(R[i], s);\n        total += 1.0 - (1.0 - ratio) * (1.0 - ratio);\n    }\n    return total;\n}\n\nbool validate(const vector<Rect>& rects) {\n    for (int i = 0; i < N; ++i) {\n        // Check bounds\n        if (rects[i].x1 < 0 || rects[i].x2 > 10000 || rects[i].y1 < 0 || rects[i].y2 > 10000) return false;\n        if (rects[i].x1 >= rects[i].x2 || rects[i].y1 >= rects[i].y2) return false;\n        // Check containment: point is (x_i+0.5, y_i+0.5) => x1 <= x_i < x2, y1 <= y_i < y2\n        if (!(rects[i].x1 <= X[i] && X[i] < rects[i].x2 && rects[i].y1 <= Y[i] && Y[i] < rects[i].y2)) return false;\n    }\n    // Check non-overlap (O(N^2), acceptable for N<=200)\n    for (int i = 0; i < N; ++i) {\n        for (int j = i + 1; j < N; ++j) {\n            if (rects[i].x1 < rects[j].x2 && rects[j].x1 < rects[i].x2 &&\n                rects[i].y1 < rects[j].y2 && rects[j].y1 < rects[i].y2) {\n                return false;\n            }\n        }\n    }\n    return true;\n}\n\n// Recursive guillotine partitioner\nvoid solve(int x1, int y1, int x2, int y2, vector<int> ids, vector<Rect>& current_ans) {\n    if (ids.empty()) return;\n    if (ids.size() == 1) {\n        current_ans[ids[0]] = {x1, y1, x2, y2};\n        return;\n    }\n\n    auto try_axis = [&](bool vertical) {\n        vector<int> sorted_ids = ids;\n        if (vertical) sort(sorted_ids.begin(), sorted_ids.end(), [&](int a, int b) { return X[a] < X[b]; });\n        else sort(sorted_ids.begin(), sorted_ids.end(), [&](int a, int b) { return Y[a] < Y[b]; });\n\n        long long cur_r = 0;\n        double best_err = 1e18;\n        int best_k = -1, best_c = -1;\n\n        for (int k = 0; k < sorted_ids.size() - 1; ++k) {\n            cur_r += R[sorted_ids[k]];\n            double len = vertical ? (y2 - y1) : (x2 - x1);\n            double ideal_c = (vertical ? x1 : y1) + (double)cur_r / len;\n            int c1 = floor(ideal_c);\n            int c2 = c1 + 1;\n\n            int min_pos = vertical ? X[sorted_ids[k]] : Y[sorted_ids[k]];\n            int max_pos = vertical ? X[sorted_ids[k+1]] : Y[sorted_ids[k+1]];\n\n            for (int c : {c1, c2}) {\n                if (c <= (vertical ? x1 : y1) || c >= (vertical ? x2 : y2)) continue;\n                if (min_pos < c && c <= max_pos) {\n                    double err = abs(ideal_c - c);\n                    if (err < best_err) {\n                        best_err = err;\n                        best_k = k;\n                        best_c = c;\n                    }\n                }\n            }\n        }\n        return make_tuple(best_k, best_c, best_err, sorted_ids);\n    };\n\n    auto [k_x, c_x, err_x, s_x] = try_axis(true);\n    auto [k_y, c_y, err_y, s_y] = try_axis(false);\n\n    // Prefer axis with valid cut and minimal error\n    if (err_x < 1e10 && err_x <= err_y) {\n        vector<int> left(s_x.begin(), s_x.begin() + k_x + 1);\n        vector<int> right(s_x.begin() + k_x + 1, s_x.end());\n        solve(x1, y1, c_x, y2, left, current_ans);\n        solve(c_x, y1, x2, y2, right, current_ans);\n    } else if (err_y < 1e10) {\n        vector<int> bottom(s_y.begin(), s_y.begin() + k_y + 1);\n        vector<int> top(s_y.begin() + k_y + 1, s_y.end());\n        solve(x1, y1, x2, c_y, bottom, current_ans);\n        solve(x1, c_y, x2, y2, top, current_ans);\n    } else {\n        // Fallback: geometric median split (rarely reached for random data)\n        int mid = ids.size() / 2;\n        vector<int> left(ids.begin(), ids.begin() + mid);\n        vector<int> right(ids.begin() + mid, ids.end());\n        int c = (x1 + x2) / 2;\n        solve(x1, y1, c, y2, left, current_ans);\n        solve(c, y1, x2, y2, right, current_ans);\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N)) return 0;\n    X.resize(N); Y.resize(N); R.resize(N);\n    for (int i = 0; i < N; ++i) cin >> X[i] >> Y[i] >> R[i];\n\n    best_ans.resize(N);\n    vector<int> ids(N);\n    iota(ids.begin(), ids.end(), 0);\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    auto start_time = chrono::steady_clock::now();\n\n    // Multi-run stochastic wrapper to find best partition\n    while (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() < 4.5) {\n        shuffle(ids.begin(), ids.end(), rng);\n        vector<Rect> current_ans(N, {-1, -1, -1, -1});\n        solve(0, 0, 10000, 10000, ids, current_ans);\n\n        if (validate(current_ans)) {\n            double sc = calc_score(current_ans);\n            if (sc > best_score) {\n                best_score = sc;\n                best_ans = current_ans;\n            }\n        }\n    }\n\n    // Output\n    for (int i = 0; i < N; ++i) {\n        cout << best_ans[i].x1 << \" \" << best_ans[i].y1 << \" \"\n             << best_ans[i].x2 << \" \" << best_ans[i].y2 << \"\\n\";\n    }\n\n    cerr << \"Final Score: \" << (long long)(best_score * 1e9 / N) << \"\\n\";\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nint main() {\n    cin.tie(nullptr);\n    ios::sync_with_stdio(false);\n\n    int si, sj;\n    if (!(cin >> si >> sj)) return 0;\n\n    int t[50][50], p[50][50];\n    int M = 0;\n    for (int i = 0; i < 50; ++i)\n        for (int j = 0; j < 50; ++j) {\n            cin >> t[i][j];\n            M = max(M, t[i][j] + 1);\n        }\n    for (int i = 0; i < 50; ++i)\n        for (int j = 0; j < 50; ++j)\n            cin >> p[i][j];\n\n    // Precompute tile values\n    vector<ll> tile_val(M, 0);\n    for (int i = 0; i < 50; ++i)\n        for (int j = 0; j < 50; ++j)\n            tile_val[t[i][j]] += p[i][j];\n\n    auto start_t = chrono::steady_clock::now();\n    mt19937 rng(42);\n    uniform_real_distribution<double> noise(0.0, 15.0); // Random exploration noise\n\n    // Reusable visited array to avoid allocations\n    vector<char> vis(M);\n\n    // Simulates the path up to keep_len, then greedily extends it.\n    // Modifies `path` in place and returns the final score.\n    auto simulate_and_extend = [&](vector<char>& path, int keep_len) -> ll {\n        int r = si, c = sj;\n        fill(vis.begin(), vis.end(), 0);\n        vis[t[r][c]] = 1;\n        ll score = p[r][c];\n\n        // Simulate existing prefix\n        for (int i = 0; i < keep_len; ++i) {\n            char d = path[i];\n            if (d == 'U') r--; else if (d == 'D') r++; else if (d == 'L') c--; else c++;\n            if (!vis[t[r][c]]) vis[t[r][c]] = 1;\n            score += p[r][c];\n        }\n\n        const int dr[] = {-1, 1, 0, 0};\n        const int dc[] = {0, 0, -1, 1};\n        const char dirs[] = {'U', 'D', 'L', 'R'};\n\n        // Greedy extension with noise\n        while (true) {\n            double best_h = -1.0;\n            int best_k = -1, nr_best = 0, nc_best = 0;\n            for (int k = 0; k < 4; ++k) {\n                int nr = r + dr[k], nc = c + dc[k];\n                if (nr >= 0 && nr < 50 && nc >= 0 && nc < 50 && !vis[t[nr][nc]]) {\n                    double h = (double)tile_val[t[nr][nc]] + noise(rng);\n                    if (h > best_h) {\n                        best_h = h;\n                        best_k = k;\n                        nr_best = nr;\n                        nc_best = nc;\n                    }\n                }\n            }\n            if (best_k == -1) break; // Dead end\n\n            path.push_back(dirs[best_k]);\n            r = nr_best;\n            c = nc_best;\n            if (!vis[t[r][c]]) vis[t[r][c]] = 1;\n            score += p[r][c];\n        }\n        return score;\n    };\n\n    vector<char> best_path;\n    ll best_score = -1;\n\n    // Initial greedy construction\n    {\n        vector<char> init;\n        ll sc = simulate_and_extend(init, 0);\n        if (sc > best_score) {\n            best_score = sc;\n            best_path = init;\n        }\n    }\n\n    vector<char> cur_path = best_path;\n    ll cur_score = best_score;\n    double T = 60.0; // Initial temperature\n    const double T_DECAY = 0.99992;\n    int iter = 0;\n\n    // Simulated Annealing Loop\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_t).count();\n        if (elapsed > 1.85) break; // Leave safety margin\n\n        int sz = cur_path.size();\n        // Randomly truncate the path (keep_len in [0, sz])\n        int keep_len = (sz == 0) ? 0 : (rng() % (sz + 1));\n        \n        vector<char> nxt = cur_path;\n        nxt.resize(keep_len);\n        ll nxt_score = simulate_and_extend(nxt, keep_len);\n\n        // Update global best\n        if (nxt_score > best_score) {\n            best_score = nxt_score;\n            best_path = nxt;\n        }\n\n        // SA acceptance criterion\n        bool accept = false;\n        if (nxt_score > cur_score) {\n            accept = true;\n        } else {\n            double delta = nxt_score - cur_score;\n            if (delta / T > -20.0) { // Avoid underflow\n                double prob = exp(delta / T);\n                if (prob > (double)(rng() & 0xFFFFFF) / (double)(0xFFFFFF + 1)) {\n                    accept = true;\n                }\n            }\n        }\n\n        if (accept) {\n            cur_score = nxt_score;\n            cur_path = move(nxt);\n        }\n\n        T *= T_DECAY;\n        iter++;\n    }\n\n    // Output result\n    for (char c : best_path) cout << c;\n    cout << \"\\n\";\n\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Edge weight estimates: h[row][col], v[row][col]\n    double h[30][29], v[29][30];\n    const double INIT_W = 5000.0;\n    for(int i=0; i<30; ++i) for(int j=0; j<29; ++j) h[i][j] = INIT_W;\n    for(int i=0; i<29; ++i) for(int j=0; j<30; ++j) v[i][j] = INIT_W;\n\n    int si, sj, ti, tj;\n    for(int k=0; k<1000; ++k) {\n        if(!(cin >> si >> sj >> ti >> tj)) break;\n\n        // Dijkstra's Algorithm\n        priority_queue<pair<long long, pair<int, int>>, \n                       vector<pair<long long, pair<int, int>>>, \n                       greater<>> pq;\n        long long dist[30][30];\n        for(int i=0; i<30; ++i) fill(begin(dist[i]), end(dist[i]), 1e18);\n        \n        dist[si][sj] = 0;\n        pq.push({0, {si, sj}});\n\n        int from_i[30][30], from_j[30][30];\n        char from_dir[30][30];\n\n        int di[4] = {-1, 1, 0, 0};\n        int dj[4] = {0, 0, -1, 1};\n        char dc[4] = {'U', 'D', 'L', 'R'};\n\n        while(!pq.empty()){\n            auto [d, p] = pq.top(); pq.pop();\n            int i = p.first, j = p.second;\n            if(d > dist[i][j]) continue;\n            if(i == ti && j == tj) break;\n\n            for(int m=0; m<4; ++m){\n                int ni = i + di[m], nj = j + dj[m];\n                if(ni < 0 || ni >= 30 || nj < 0 || nj >= 30) continue;\n\n                long long w;\n                if(m == 0)      w = (long long)round(v[ni][nj]); // U\n                else if(m == 1) w = (long long)round(v[i][j]);   // D\n                else if(m == 2) w = (long long)round(h[i][nj]);  // L\n                else            w = (long long)round(h[i][j]);   // R\n\n                if(dist[i][j] + w < dist[ni][nj]){\n                    dist[ni][nj] = dist[i][j] + w;\n                    from_i[ni][nj] = i;\n                    from_j[ni][nj] = j;\n                    from_dir[ni][nj] = dc[m];\n                    pq.push({dist[ni][nj], {ni, nj}});\n                }\n            }\n        }\n\n        // Reconstruct path\n        string path = \"\";\n        int ci = ti, cj = tj;\n        while(!(ci == si && cj == sj)){\n            path += from_dir[ci][cj];\n            int pi = from_i[ci][cj];\n            int pj = from_j[ci][cj];\n            ci = pi; cj = pj;\n        }\n        reverse(path.begin(), path.end());\n        cout << path << endl;\n\n        // Read feedback\n        int L;\n        cin >> L;\n\n        // Calculate estimated path length B\n        double B = 0.0;\n        ci = si; cj = sj;\n        for(char c : path){\n            if(c == 'U') { B += v[ci-1][cj]; ci--; }\n            else if(c == 'D') { B += v[ci][cj]; ci++; }\n            else if(c == 'L') { B += h[ci][cj-1]; cj--; }\n            else if(c == 'R') { B += h[ci][cj]; cj++; }\n        }\n\n        // Online gradient descent update\n        double err = L - B;\n        double alpha = 0.12; // Constant learning rate for stable convergence\n        double delta = alpha * err / path.length();\n\n        ci = si; cj = sj;\n        for(char c : path){\n            if(c == 'U') { v[ci-1][cj] = max(500.0, v[ci-1][cj] + delta); ci--; }\n            else if(c == 'D') { v[ci][cj] = max(500.0, v[ci][cj] + delta); ci++; }\n            else if(c == 'L') { h[ci][cj-1] = max(500.0, h[ci][cj-1] + delta); cj--; }\n            else if(c == 'R') { h[ci][cj] = max(500.0, h[ci][cj] + delta); cj++; }\n        }\n\n        // Spatial smoothing (denoising)\n        double beta = 0.18;\n        for(int i=0; i<30; ++i){\n            double s = 0;\n            for(int j=0; j<29; ++j) s += h[i][j];\n            s /= 29.0;\n            for(int j=0; j<29; ++j) h[i][j] = (1-beta)*h[i][j] + beta*s;\n        }\n        for(int j=0; j<30; ++j){\n            double s = 0;\n            for(int i=0; i<29; ++i) s += v[i][j];\n            s /= 29.0;\n            for(int i=0; i<29; ++i) v[i][j] = (1-beta)*v[i][j] + beta*s;\n        }\n    }\n    return 0;\n}","ahc004":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <chrono>\n#include <random>\n#include <algorithm>\n\nusing namespace std;\n\nconst int N = 20;\nconst int MAX_M = 800;\nconst int MAX_PLACEMENTS = 640000;\n\nint M;\nint S_len[MAX_M];\nchar S_chars[MAX_M][15];\n\nstruct Placement {\n    int str_id;\n    int len;\n};\n\nstruct CellLink {\n    int p_idx;\n    char exp_char;\n};\n\nvector<Placement> placements;\nvector<CellLink> cell_placements[N][N];\nint placement_matches[MAX_PLACEMENTS];\nint str_full_cnt[MAX_M];\nchar grid[N][N];\nchar best_grid[N][N];\nint total_score = 0;\nint best_score = -1;\n\nmt19937_64 rng;\n\ninline int calc_diff(int r, int c, char new_c, char old_c) {\n    if (new_c == old_c) return 0;\n    int diff = 0;\n    for (const auto& cl : cell_placements[r][c]) {\n        bool old_match = (old_c == cl.exp_char);\n        bool new_match = (new_c == cl.exp_char);\n        if (old_match == new_match) continue;\n\n        int k = placements[cl.p_idx].str_id;\n        bool was_full = (placement_matches[cl.p_idx] == S_len[k]);\n\n        // Simulate\n        int cur_matches = placement_matches[cl.p_idx];\n        if (old_match) cur_matches--;\n        else cur_matches++;\n\n        bool is_full = (cur_matches == S_len[k]);\n        if (was_full && !is_full) {\n            if (str_full_cnt[k] == 1) diff--;\n        } else if (!was_full && is_full) {\n            if (str_full_cnt[k] == 0) diff++;\n        }\n    }\n    return diff;\n}\n\ninline void apply_change(int r, int c, char new_c, char old_c, int diff) {\n    grid[r][c] = new_c;\n    total_score += diff;\n    for (const auto& cl : cell_placements[r][c]) {\n        bool old_match = (old_c == cl.exp_char);\n        bool new_match = (new_c == cl.exp_char);\n        if (old_match == new_match) continue;\n\n        int k = placements[cl.p_idx].str_id;\n        bool was_full = (placement_matches[cl.p_idx] == S_len[k]);\n\n        if (old_match) placement_matches[cl.p_idx]--;\n        else placement_matches[cl.p_idx]++;\n\n        bool is_full = (placement_matches[cl.p_idx] == S_len[k]);\n        if (was_full && !is_full) {\n            str_full_cnt[k]--;\n        } else if (!was_full && is_full) {\n            str_full_cnt[k]++;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    rng.seed(chrono::steady_clock::now().time_since_epoch().count());\n\n    int N_in;\n    if (!(cin >> N_in >> M)) return 0;\n    for (int i = 0; i < M; ++i) {\n        cin >> S_chars[i];\n        S_len[i] = strlen(S_chars[i]);\n    }\n\n    // Precompute all placements\n    int p_idx = 0;\n    for (int k = 0; k < M; ++k) {\n        int L = S_len[k];\n        // Horizontal\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                Placement p;\n                p.str_id = k;\n                p.len = L;\n                placements.push_back(p);\n\n                for (int p = 0; p < L; ++p) {\n                    int cc = (c + p) % N;\n                    cell_placements[r][cc].push_back({p_idx, S_chars[k][p]});\n                }\n                p_idx++;\n            }\n        }\n        // Vertical\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                Placement p;\n                p.str_id = k;\n                p.len = L;\n                placements.push_back(p);\n\n                for (int pp = 0; pp < L; ++pp) {\n                    int rr = (r + pp) % N;\n                    cell_placements[rr][c].push_back({p_idx, S_chars[k][pp]});\n                }\n                p_idx++;\n            }\n        }\n    }\n\n    // Greedy initialization\n    int cnt[N][N][8] = {};\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            for (const auto& cl : cell_placements[r][c]) {\n                cnt[r][c][cl.exp_char - 'A']++;\n            }\n            char best_c = 'A';\n            int max_v = -1;\n            for (int x = 0; x < 8; ++x) {\n                if (cnt[r][c][x] > max_v) {\n                    max_v = cnt[r][c][x];\n                    best_c = 'A' + x;\n                }\n            }\n            grid[r][c] = best_c;\n        }\n    }\n\n    // Initialize matches\n    int total_placements = placements.size();\n    for (int i = 0; i < total_placements; ++i) {\n        int len = placements[i].len;\n        int matches = 0;\n        int k = placements[i].str_id;\n        // Re-scan cells for this placement to count initial matches\n        // Actually, we can just compute by checking grid against expected\n        // To avoid scanning again, we rely on the fact that we can compute from grid\n        // Let's just compute directly for correctness\n    }\n    // Direct computation of initial placement_matches\n    for (int i = 0; i < total_placements; ++i) {\n        const auto& p = placements[i];\n        int matches = 0;\n        // We need to know coordinates of placement. Since we didn't store them, \n        // we can recompute or store them. Given constraints, storing coords is easy.\n        // But to save memory/time, let's just compute matches by iterating cell_placements?\n        // Actually, it's faster to just compute matches during greedy init.\n    }\n    // Redo placement_matches calculation cleanly\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            for (const auto& cl : cell_placements[r][c]) {\n                if (grid[r][c] == cl.exp_char) {\n                    placement_matches[cl.p_idx]++;\n                }\n            }\n        }\n    }\n    for (int i = 0; i < total_placements; ++i) {\n        int k = placements[i].str_id;\n        if (placement_matches[i] == S_len[k]) {\n            str_full_cnt[k]++;\n        }\n    }\n    for (int k = 0; k < M; ++k) {\n        if (str_full_cnt[k] > 0) total_score++;\n    }\n\n    best_score = 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    // Simulated Annealing\n    double T = 2.0;\n    auto start = chrono::steady_clock::now();\n    uniform_int_distribution<int> dist_rc(0, N-1);\n    uniform_int_distribution<int> dist_char(0, 7);\n    uniform_real_distribution<double> prob_dist(0.0, 1.0);\n\n    // Run until time limit\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration_cast<chrono::milliseconds>(now - start).count() / 1000.0;\n        if (elapsed >= 2.85) break;\n\n        // Cooling schedule\n        T = 2.0 * pow(1e-5 / 2.0, elapsed / 2.85);\n        if (T < 1e-9) T = 1e-9;\n\n        int r = dist_rc(rng);\n        int c = dist_rc(rng);\n        char old_c = grid[r][c];\n        char new_c = 'A' + dist_char(rng);\n        if (new_c == old_c) continue;\n\n        int diff = calc_diff(r, c, new_c, old_c);\n        if (diff > 0 || prob_dist(rng) < exp(diff / T)) {\n            apply_change(r, c, new_c, old_c, diff);\n            if (total_score > best_score) {\n                best_score = 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                if (best_score == M) break; // Optimal reached\n            }\n        }\n    }\n\n    // Output best grid\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            cout << best_grid[r][c];\n        }\n        cout << '\\n';\n    }\n\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\n\nconst int INF = 1e9;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, si, sj;\n    if (!(cin >> N >> si >> sj)) return 0;\n    vector<string> grid(N);\n    for (int i = 0; i < N; ++i) cin >> grid[i];\n\n    vector<pair<int, int>> points;\n    vector<vector<int>> idx_grid(N, vector<int>(N, -1));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] != '#') {\n                idx_grid[i][j] = (int)points.size();\n                points.emplace_back(i, j);\n            }\n        }\n    }\n    int V = points.size();\n    int start_idx = idx_grid[si][sj];\n\n    // Precompute all-pairs shortest paths between road cells\n    auto precompute_distances = [&](int limit_ms) {\n        vector<int> dist(V * V, INF);\n        vector<int> d(N * N, INF);\n        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;\n        int dirs[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\n        auto t0 = chrono::high_resolution_clock::now();\n\n        for (int i = 0; i < V; ++i) {\n            auto now = chrono::high_resolution_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(now - t0).count() > limit_ms) break;\n            \n            fill(d.begin(), d.end(), INF);\n            auto [r0, c0] = points[i];\n            int u0 = r0 * N + c0;\n            d[u0] = 0;\n            pq.emplace(0, u0);\n            dist[i * V + i] = 0;\n\n            while (!pq.empty()) {\n                auto [dst, u] = pq.top(); pq.pop();\n                if (dst > d[u]) continue;\n                int ur = u / N, uc = u % N;\n                if (idx_grid[ur][uc] != -1) dist[i * V + idx_grid[ur][uc]] = dst;\n\n                for (auto& dr : dirs) {\n                    int vr = ur + dr[0], vc = uc + dr[1];\n                    if (vr < 0 || vr >= N || vc < 0 || vc >= N || grid[vr][vc] == '#') continue;\n                    int v = vr * N + vc;\n                    int w = grid[vr][vc] - '0';\n                    if (d[u] + w < d[v]) {\n                        d[v] = d[u] + w;\n                        pq.emplace(d[v], v);\n                    }\n                }\n            }\n        }\n        return dist;\n    };\n\n    // Reserve up to 2000ms for distance computation\n    vector<int> dist_mat = precompute_distances(2000);\n\n    // Nearest Insertion TSP (O(V^2))\n    vector<int> tour = {start_idx};\n    vector<bool> visited(V, false);\n    visited[start_idx] = true;\n    vector<int> min_dist(V, INF);\n    for (int k = 0; k < V; ++k) min_dist[k] = dist_mat[start_idx * V + k];\n\n    for (int count = 1; count < V; ++count) {\n        int best_k = -1;\n        int best_val = INF;\n        for (int k = 0; k < V; ++k) {\n            if (!visited[k] && min_dist[k] < best_val) {\n                best_val = min_dist[k];\n                best_k = k;\n            }\n        }\n        int best_pos = 0;\n        int best_insert_cost = INF;\n        for (int i = 0; i < (int)tour.size(); ++i) {\n            int j = tour[(i + 1) % tour.size()];\n            int cost = dist_mat[tour[i] * V + best_k] + dist_mat[best_k * V + j] - dist_mat[tour[i] * V + j];\n            if (cost < best_insert_cost) {\n                best_insert_cost = cost;\n                best_pos = i + 1;\n            }\n        }\n        tour.insert(tour.begin() + best_pos, best_k);\n        visited[best_k] = true;\n        for (int k = 0; k < V; ++k) {\n            if (!visited[k]) min_dist[k] = min(min_dist[k], dist_mat[best_k * V + k]);\n        }\n    }\n\n    // 2-opt Local Search Improvement\n    auto start_time = chrono::high_resolution_clock::now();\n    bool improved = true;\n    while (improved) {\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 800) break;\n        improved = false;\n        for (int i = 0; i < V; ++i) {\n            for (int j = i + 2; j < V; ++j) {\n                if (j == V - 1 && i == 0) continue;\n                int u1 = tour[i], v1 = tour[(i + 1) % V];\n                int u2 = tour[j], v2 = tour[(j + 1) % V];\n                int current = dist_mat[u1 * V + v1] + dist_mat[u2 * V + v2];\n                int swapped  = dist_mat[u1 * V + u2] + dist_mat[v1 * V + v2];\n                if (swapped < current) {\n                    reverse(tour.begin() + i + 1, tour.begin() + j + 1);\n                    improved = true;\n                }\n            }\n        }\n    }\n\n    // Path Reconstruction using Dijkstra on grid\n    string result = \"\";\n    result.reserve(V * 20); // heuristic reservation\n\n    vector<int> d(N * N);\n    vector<int> parent(N * N, -1);\n    vector<char> move_char(N * N);\n    int dirs[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\n    char moves[4] = {'U', 'D', 'L', 'R'};\n\n    auto get_path = [&](int from_idx, int to_idx) {\n        auto [r1, c1] = points[from_idx];\n        auto [r2, c2] = points[to_idx];\n        if (r1 == r2 && c1 == c2) return string(\"\");\n        \n        fill(d.begin(), d.end(), INF);\n        fill(parent.begin(), parent.end(), -1);\n        \n        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;\n        int u0 = r1 * N + c1;\n        int target = r2 * N + c2;\n        \n        d[u0] = 0;\n        pq.emplace(0, u0);\n\n        while (!pq.empty()) {\n            auto [dst, u] = pq.top(); pq.pop();\n            if (dst > d[u]) continue;\n            if (u == target) break;\n            \n            int ur = u / N, uc = u % N;\n            for (int k = 0; k < 4; ++k) {\n                int vr = ur + dirs[k][0], vc = uc + dirs[k][1];\n                if (vr < 0 || vr >= N || vc < 0 || vc >= N || grid[vr][vc] == '#') continue;\n                int v = vr * N + vc;\n                int w = grid[vr][vc] - '0';\n                if (d[u] + w < d[v]) {\n                    d[v] = d[u] + w;\n                    parent[v] = u;\n                    move_char[v] = moves[k];\n                    pq.emplace(d[v], v);\n                }\n            }\n        }\n\n        string path = \"\";\n        int curr = target;\n        while (curr != u0) {\n            path += move_char[curr];\n            curr = parent[curr];\n        }\n        reverse(path.begin(), path.end());\n        return path;\n    };\n\n    for (int i = 0; i < V; ++i) {\n        result += get_path(tour[i], tour[(i + 1) % V]);\n    }\n\n    cout << result << \"\\n\";\n    return 0;\n}","future-contest-2022-qual":"#pragma GCC optimize(\"O3,unroll-loops\")\n#pragma GCC target(\"avx2,fma\")\n\n#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K, R;\n    if (!(cin >> N >> M >> K >> R)) return 0;\n\n    // Task difficulties\n    vector<vector<int>> d(N, vector<int>(K));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < K; ++j)\n            cin >> d[i][j];\n\n    // Dependency graph\n    vector<vector<int>> adj(N);\n    vector<int> in_degree(N, 0);\n    for (int i = 0; i < R; ++i) {\n        int u, v; cin >> u >> v; --u; --v;\n        adj[u].push_back(v);\n        in_degree[v]++;\n    }\n\n    // State tracking\n    vector<vector<double>> est_s(M, vector<double>(K, 10.0)); // Initialize with reasonable mid-range value\n    vector<int> member_task(M, -1);\n    vector<int> member_start_day(M, -1);\n    vector<int> tasks_done(M, 0);\n    vector<bool> task_done(N, false);\n    vector<bool> task_assigned(N, false);\n\n    // Precompute priorities (sum of required skills)\n    vector<long long> priority(N, 0);\n    for (int i = 0; i < N; ++i) {\n        long long s = 0;\n        for (int x : d[i]) s += x;\n        priority[i] = s;\n    }\n\n    // Initially ready tasks (in-degree 0)\n    vector<int> ready;\n    ready.reserve(N);\n    for (int i = 0; i < N; ++i)\n        if (in_degree[i] == 0) ready.push_back(i);\n\n    auto cmp_priority = [&](int a, int b) { return priority[a] > priority[b]; };\n\n    for (int day = 1; day <= 2000; ++day) {\n        int nf;\n        cin >> nf;\n        if (nf == -1) break;\n\n        vector<int> completed_members;\n        completed_members.reserve(nf);\n        for (int i = 0; i < nf; ++i) {\n            int f; cin >> f; --f;\n            completed_members.push_back(f);\n        }\n\n        // Process task completions & update skill estimates\n        for (int f : completed_members) {\n            int tid = member_task[f];\n            int sd = member_start_day[f];\n            if (tid == -1) continue;\n\n            int actual_t = day - sd + 1;\n            task_done[tid] = true;\n            task_assigned[tid] = false;\n            member_task[f] = -1;\n            member_start_day[f] = -1;\n            tasks_done[f]++;\n\n            // Compute prediction error\n            double pred = 0;\n            int def = 0;\n            for (int k = 0; k < K; ++k) {\n                if (d[tid][k] > est_s[f][k]) {\n                    pred += d[tid][k] - est_s[f][k];\n                    def++;\n                }\n            }\n\n            // Online gradient update with noise clipping\n            if (def > 0 && pred > 0.5) {\n                double err = actual_t - pred;\n                double lr = 0.5 / (1.0 + 0.02 * tasks_done[f]);\n                double delta = max(-2.0, min(2.0, err / def));\n                for (int k = 0; k < K; ++k) {\n                    if (d[tid][k] > est_s[f][k]) {\n                        est_s[f][k] += lr * delta;\n                        if (est_s[f][k] < 0) est_s[f][k] = 0;\n                        if (est_s[f][k] > 80) est_s[f][k] = 80;\n                    }\n                }\n            }\n\n            // Release dependencies\n            for (int v : adj[tid]) {\n                if (--in_degree[v] == 0) {\n                    ready.push_back(v);\n                }\n            }\n        }\n\n        // Collect free members\n        vector<int> free_ms;\n        free_ms.reserve(M);\n        for (int m = 0; m < M; ++m)\n            if (member_task[m] == -1) free_ms.push_back(m);\n\n        // Sort ready tasks by difficulty descending\n        sort(ready.begin(), ready.end(), cmp_priority);\n\n        vector<pair<int, int>> out_assign;\n        out_assign.reserve(free_ms.size());\n        vector<int> next_ready;\n        next_ready.reserve(ready.size());\n\n        // Greedy assignment: highest priority task to best fitting free member\n        for (int t : ready) {\n            if (task_assigned[t] || task_done[t]) continue;\n            if (free_ms.empty()) {\n                next_ready.push_back(t);\n                continue;\n            }\n\n            int best_m = -1;\n            double best_et = 1e18;\n            for (int m : free_ms) {\n                double w = 0;\n                const auto& dt = d[t];\n                const auto& es = est_s[m];\n                for (int k = 0; k < K; ++k) {\n                    if (dt[k] > es[k]) w += dt[k] - es[k];\n                }\n                double et = (w > 0) ? w : 1.0;\n                if (et < best_et) {\n                    best_et = et;\n                    best_m = m;\n                }\n            }\n\n            if (best_m != -1) {\n                member_task[best_m] = t;\n                member_start_day[best_m] = day;\n                task_assigned[t] = true;\n                out_assign.push_back({best_m, t});\n                \n                // Remove used member from free list\n                for (auto it = free_ms.begin(); it != free_ms.end(); ++it) {\n                    if (*it == best_m) { free_ms.erase(it); break; }\n                }\n            } else {\n                next_ready.push_back(t);\n            }\n        }\n        ready = next_ready;\n\n        // Output assignments\n        cout << out_assign.size();\n        for (auto& p : out_assign) {\n            cout << \" \" << p.first + 1 << \" \" << p.second + 1;\n        }\n        cout << \"\\n\" << flush;\n    }\n\n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <chrono>\n#include <random>\n#include <numeric>\n#include <iomanip>\n\nusing namespace std;\n\n// ==================== Geometry & Helpers ====================\nstruct Pt { int x, y; };\ninline int dist(const Pt& a, const Pt& b) { return abs(a.x - b.x) + abs(a.y - b.y); }\n\nconst Pt BASE = {400, 400};\n\nstruct Order {\n    int id; // 1-based index\n    Pt p, d; // pickup, delivery\n};\n\nvector<Order> all_orders(1000);\nint sel_ids[50];          // Selected order indices (1-based)\nPt sp[50], sd[50];        // Selected pickup/delivery coordinates\nvector<int> route;        // Route stores 0..49 (pickup), 50..99 (delivery)\n\ninline Pt get_pt(int idx) {\n    return idx < 50 ? sp[idx] : sd[idx - 50];\n}\n\n// ==================== Core Functions ====================\nint calc_cost(const vector<int>& r) {\n    int c = dist(BASE, get_pt(r[0]));\n    for (int i = 0; i < 99; ++i) c += dist(get_pt(r[i]), get_pt(r[i+1]));\n    c += dist(get_pt(r[99]), BASE);\n    return c;\n}\n\nbool check_precedence(const vector<int>& r) {\n    int pos[50]; fill(pos, pos + 50, -1);\n    for (int i = 0; i < 100; ++i) {\n        if (r[i] < 50) pos[r[i]] = i;\n        else if (pos[r[i] - 50] == -1 || pos[r[i] - 50] >= i) return false;\n    }\n    return true;\n}\n\n// ==================== Phase 1: Greedy Construction ====================\nvoid build_initial_route() {\n    route.clear();\n    vector<bool> in_pickup(50, false), in_delivery(50, false);\n    int placed = 0;\n\n    while (placed < 100) {\n        int best_pos = -1, best_pt = -1;\n        int min_delta = 2e9;\n\n        // Try inserting any available pickup or valid delivery\n        for (int p = 0; p < 50; ++p) {\n            if (in_pickup[p] || in_delivery[p]) continue;\n            int pt = p; // pickup\n            for (int pos = 0; pos <= placed; ++pos) {\n                int delta;\n                if (placed == 0) delta = dist(BASE, get_pt(pt)) + dist(get_pt(pt), BASE) - dist(BASE, BASE);\n                else {\n                    Pt prev = (pos == 0) ? BASE : get_pt(route[pos - 1]);\n                    Pt next = (pos == placed) ? BASE : get_pt(route[pos]);\n                    delta = dist(prev, get_pt(pt)) + dist(get_pt(pt), next) - dist(prev, next);\n                }\n                if (delta < min_delta) { min_delta = delta; best_pos = pos; best_pt = pt; }\n            }\n        }\n        for (int p = 0; p < 50; ++p) {\n            if (!in_pickup[p] || in_delivery[p]) continue;\n            int pt = p + 50; // delivery\n            for (int pos = 0; pos <= placed; ++pos) {\n                int delta;\n                if (placed == 0) delta = dist(BASE, get_pt(pt)) + dist(get_pt(pt), BASE);\n                else {\n                    Pt prev = (pos == 0) ? BASE : get_pt(route[pos - 1]);\n                    Pt next = (pos == placed) ? BASE : get_pt(route[pos]);\n                    delta = dist(prev, get_pt(pt)) + dist(get_pt(pt), next) - dist(prev, next);\n                }\n                if (delta < min_delta) { min_delta = delta; best_pos = pos; best_pt = pt; }\n            }\n        }\n\n        route.insert(route.begin() + best_pos, best_pt);\n        if (best_pt < 50) in_pickup[best_pt] = true;\n        else in_delivery[best_pt - 50] = true;\n        placed++;\n    }\n}\n\n// ==================== Phase 2: Local Search (2-opt & Relocate) ====================\nauto start_time = chrono::steady_clock::now();\ninline double elapsed() {\n    return chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n}\n\nvoid run_local_search(double time_budget) {\n    bool improved = true;\n    double deadline = elapsed() + time_budget;\n    while (improved && elapsed() < deadline) {\n        improved = false;\n        \n        // 2-opt\n        for (int l = 0; l < 99 && elapsed() < deadline; ++l) {\n            for (int r = l + 1; r < 100; ++r) {\n                vector<int> tmp = route;\n                reverse(tmp.begin() + l, tmp.begin() + r + 1);\n                \n                int old_c = calc_cost(route);\n                int new_c = calc_cost(tmp);\n                \n                if (new_c < old_c && check_precedence(tmp)) {\n                    route = tmp;\n                    improved = true;\n                    goto next_iter;\n                }\n            }\n        }\n        \n        // Relocate\n        for (int i = 0; i < 100 && elapsed() < deadline; ++i) {\n            for (int j = 0; j < 100; ++j) {\n                if (i == j || i == j + 1) continue;\n                vector<int> tmp = route;\n                int pt = tmp[i];\n                tmp.erase(tmp.begin() + i);\n                tmp.insert(tmp.begin() + j, pt);\n                \n                int old_c = calc_cost(route);\n                int new_c = calc_cost(tmp);\n                \n                if (new_c < old_c && check_precedence(tmp)) {\n                    route = tmp;\n                    improved = true;\n                    goto next_iter;\n                }\n            }\n        }\n        next_iter:;\n    }\n}\n\n// ==================== Phase 3: Order Swapping ====================\nvoid run_order_swap(double time_budget) {\n    mt19937 rng(42);\n    double deadline = elapsed() + time_budget;\n    int best_cost = calc_cost(route);\n    \n    while (elapsed() < deadline) {\n        int in_idx = rng() % 50;\n        int out_idx;\n        do { out_idx = rng() % 1000; } while (find(sel_ids, sel_ids + 50, out_idx) != sel_ids + 50);\n        \n        // Try swapping\n        vector<int> old_route = route;\n        int old_id = sel_ids[in_idx];\n        sel_ids[in_idx] = out_idx + 1; // store 1-based\n        sp[in_idx] = all_orders[out_idx].p;\n        sd[in_idx] = all_orders[out_idx].d;\n        \n        // Remove old order points\n        route.erase(remove_if(route.begin(), route.end(), [&](int x) { return x == in_idx || x == in_idx + 50; }), route.end());\n        \n        // Insert new order points\n        vector<int> tmp = route;\n        // Insert pickup\n        int best_p_pos = -1, min_pd = 2e9;\n        for (int pos = 0; pos <= 98; ++pos) {\n            int delta = dist(pos == 0 ? BASE : get_pt(tmp[pos-1]), get_pt(in_idx)) +\n                        dist(get_pt(in_idx), pos == 98 ? BASE : get_pt(tmp[pos])) -\n                        dist(pos == 0 ? BASE : get_pt(tmp[pos-1]), pos == 98 ? BASE : get_pt(tmp[pos]));\n            if (delta < min_pd) { min_pd = delta; best_p_pos = pos; }\n        }\n        tmp.insert(tmp.begin() + best_p_pos, in_idx);\n        \n        // Insert delivery (must be after pickup)\n        int pickup_pos = best_p_pos;\n        int best_d_pos = -1, min_dd = 2e9;\n        for (int pos = pickup_pos + 1; pos <= 99; ++pos) {\n            int delta = dist(pos == 0 ? BASE : get_pt(tmp[pos-1]), get_pt(in_idx+50)) +\n                        dist(get_pt(in_idx+50), pos == 100 ? BASE : get_pt(tmp[pos])) -\n                        dist(pos == 0 ? BASE : get_pt(tmp[pos-1]), pos == 100 ? BASE : get_pt(tmp[pos]));\n            if (delta < min_dd) { min_dd = delta; best_d_pos = pos; }\n        }\n        tmp.insert(tmp.begin() + best_d_pos, in_idx + 50);\n        \n        int new_cost = calc_cost(tmp);\n        if (new_cost < best_cost) {\n            route = tmp;\n            best_cost = new_cost;\n            run_local_search(0.05); // Quick polish\n        } else {\n            // Revert\n            route = old_route;\n            sel_ids[in_idx] = old_id;\n            // Restore coordinates\n            for (int k = 0; k < 50; ++k) {\n                sp[k] = all_orders[sel_ids[k]-1].p;\n                sd[k] = all_orders[sel_ids[k]-1].d;\n            }\n        }\n    }\n}\n\n// ==================== Main ====================\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    for (int i = 0; i < 1000; ++i) {\n        cin >> all_orders[i].p.x >> all_orders[i].p.y >> all_orders[i].d.x >> all_orders[i].d.y;\n        all_orders[i].id = i + 1;\n    }\n    \n    // Initial Selection: 50 orders with pickups closest to base\n    vector<pair<int, int>> dists;\n    for (int i = 0; i < 1000; ++i) {\n        dists.emplace_back(dist(BASE, all_orders[i].p), i);\n    }\n    nth_element(dists.begin(), dists.begin() + 50, dists.end());\n    for (int i = 0; i < 50; ++i) {\n        int id = dists[i].second;\n        sel_ids[i] = all_orders[id].id;\n        sp[i] = all_orders[id].p;\n        sd[i] = all_orders[id].d;\n    }\n    \n    build_initial_route();\n    \n    // Phase 2: Intensive Route Optimization\n    run_local_search(0.8);\n    \n    // Phase 3: Order Set Optimization\n    run_order_swap(1.0);\n    \n    // Final Polish\n    run_local_search(0.2);\n    \n    // Output\n    cout << \"50\";\n    for (int i = 0; i < 50; ++i) cout << \" \" << sel_ids[i];\n    cout << \"\\n\";\n    \n    vector<Pt> out_path;\n    out_path.push_back(BASE);\n    for (int p : route) out_path.push_back(get_pt(p));\n    out_path.push_back(BASE);\n    \n    cout << out_path.size();\n    for (auto& p : out_path) cout << \" \" << p.x << \" \" << p.y;\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <utility>\n\nusing namespace std;\n\n// Disjoint Set Union (DSU) with path compression\nstruct DSU {\n    vector<int> parent;\n    DSU(int n) : parent(n) {\n        for (int i = 0; i < n; ++i) parent[i] = i;\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        i = find(i); j = find(j);\n        if (i != j) {\n            parent[i] = j;\n            return true;\n        }\n        return false;\n    }\n};\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 400;\n    const int M = 1995;\n\n    // 1. Read vertex coordinates\n    vector<pair<int, int>> coords(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n\n    // 2. Read edge endpoints and precompute d_i\n    vector<pair<int, int>> edges(M);\n    vector<int> d(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> edges[i].first >> edges[i].second;\n        long long dx = coords[edges[i].first].first - coords[edges[i].second].first;\n        long long dy = coords[edges[i].first].second - coords[edges[i].second].second;\n        // Euclidean distance rounded to nearest integer\n        d[i] = static_cast<int>(round(sqrt(dx * dx + dy * dy)));\n    }\n\n    DSU dsu(N);\n    const int INF = 1e9;\n\n    // 3. Process edges online\n    for (int i = 0; i < M; ++i) {\n        int l;\n        cin >> l;\n\n        int u = edges[i].first;\n        int v = edges[i].second;\n        int ru = dsu.find(u);\n        int rv = dsu.find(v);\n\n        if (ru == rv) {\n            // Already connected, accepting would form a cycle. Reject.\n            cout << \"0\\n\";\n        } else {\n            // Look ahead to find the minimum base distance of future edges\n            // that connect the current components ru and rv.\n            int best_d = INF;\n            for (int j = i + 1; j < M; ++j) {\n                int rju = dsu.find(edges[j].first);\n                int rjv = dsu.find(edges[j].second);\n                if ((rju == ru && rjv == rv) || (rju == rv && rjv == ru)) {\n                    if (d[j] < best_d) best_d = d[j];\n                }\n            }\n\n            // Heuristic threshold: accept if current cost is significantly lower\n            // than the scaled expectation of the best future option.\n            // Threshold 1.8 balances risk and expectation (E[l] = 2*d).\n            if (best_d == INF || l * 5 < best_d * 9) {\n                cout << \"1\\n\";\n                dsu.unite(ru, rv);\n            } else {\n                cout << \"0\\n\";\n            }\n        }\n        // Interactive requirement: flush output after each decision\n        cout.flush();\n    }\n\n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <cstring>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nconst int H = 30, W = 30;\nint grid[H][W]; // 0: passable, 1: blocked\nstruct Pos { int x, y; };\nvector<Pos> pets, humans;\n\ninline bool in_bounds(int x, int y) {\n    return x >= 0 && x < H && y >= 0 && y < W;\n}\n\n// BFS to compute component size and pet count from (sx, sy)\npair<int, int> bfs(int sx, int sy, const int g[H][W], const vector<Pos>& cur_pets) {\n    static int vis[H][W];\n    static int token = 0;\n    token++;\n    queue<pair<int,int>> q;\n    q.emplace(sx, sy);\n    vis[sx][sy] = token;\n    int sz = 0;\n\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    while(!q.empty()){\n        auto [cx, cy] = q.front(); q.pop();\n        sz++;\n        for(int i=0; i<4; i++){\n            int nx = cx + dx[i], ny = cy + dy[i];\n            if(in_bounds(nx, ny) && vis[nx][ny] != token && g[nx][ny] == 0){\n                vis[nx][ny] = token;\n                q.emplace(nx, ny);\n            }\n        }\n    }\n    int np = 0;\n    for(auto& p : cur_pets){\n        if(vis[p.x][p.y] == token) np++;\n    }\n    return {sz, np};\n}\n\nbool can_block_target(int tx, int ty, int hx, int hy) {\n    if(!in_bounds(tx, ty)) return false;\n    if(grid[tx][ty] == 1) return true; // Already blocked, valid but useless\n    \n    // Target cannot contain pets or humans (except the actor)\n    for(auto& p : pets) if(p.x == tx && p.y == ty) return false;\n    for(const auto& h : humans){\n        if(h.x == tx && h.y == ty && !(h.x == hx && h.y == hy)) return false;\n    }\n    // Target's adjacent squares cannot contain pets\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    for(int i=0; i<4; i++){\n        int nx = tx + dx[i], ny = ty + dy[i];\n        if(in_bounds(nx, ny)){\n            for(auto& p : pets) if(p.x == nx && p.y == ny) return false;\n        }\n    }\n    return true;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N; cin >> N;\n    pets.resize(N);\n    for(int i=0; i<N; i++) {\n        cin >> pets[i].x >> pets[i].y;\n        pets[i].x--; pets[i].y--;\n    }\n    int M; cin >> M;\n    humans.resize(M);\n    for(int i=0; i<M; i++) {\n        cin >> humans[i].x >> humans[i].y;\n        humans[i].x--; humans[i].y--;\n    }\n\n    // Initialize grid\n    for(int i=0; i<H; i++) for(int j=0; j<W; j++) grid[i][j] = 0;\n\n    const char acts[] = {'.', 'U', 'D', 'L', 'R', 'u', 'd', 'l', 'r'};\n    const int ddx[9] = {0, -1, 1, 0, 0, 0, 0, 0, 0};\n    const int ddy[9] = {0, 0, 0, -1, 1, 0, 0, 0, 0};\n    const bool is_block_act[9] = {false, false, false, false, false, true, true, true, true};\n\n    for(int turn=0; turn<300; turn++){\n        string res = \"\";\n        vector<char> my_acts(M);\n\n        // Evaluate best action for each human independently\n        for(int i=0; i<M; i++){\n            int hx = humans[i].x, hy = humans[i].y;\n            double best_val = -1.0;\n            char best_a = '.';\n            bool best_blk_effective = false;\n\n            for(int a=0; a<9; a++){\n                if(a == 0) {\n                    // Stay action\n                } else {\n                    int nx = hx + ddx[a];\n                    int ny = hy + ddy[a];\n                    if(!in_bounds(nx, ny)) continue;\n                    if(is_block_act[a]){\n                        if(!can_block_target(nx, ny, hx, hy)) continue;\n                    } else {\n                        if(grid[nx][ny] != 0) continue; // Move target must be passable\n                    }\n                }\n\n                // Simulate action on a temporary grid\n                int tmp_grid[H][W];\n                memcpy(tmp_grid, grid, sizeof(tmp_grid));\n                Pos tmp_human = humans[i];\n                bool effective_blk = false;\n\n                if(a == 0) {\n                    // stay\n                } else if(is_block_act[a]) {\n                    if(tmp_grid[hx + ddx[a]][hy + ddy[a]] == 0) {\n                        tmp_grid[hx + ddx[a]][hy + ddy[a]] = 1;\n                        effective_blk = true;\n                    }\n                } else {\n                    tmp_human.x += ddx[a];\n                    tmp_human.y += ddy[a];\n                }\n\n                auto [sz, np] = bfs(tmp_human.x, tmp_human.y, tmp_grid, pets);\n                double val = sz / (double)(1LL << np);\n                \n                // Pick action with highest heuristic value. Break ties in favor of effective blocks.\n                if(val > best_val + 1e-9 || (abs(val - best_val) < 1e-9 && effective_blk && !best_blk_effective)){\n                    best_val = val;\n                    best_a = acts[a];\n                    best_blk_effective = effective_blk;\n                }\n            }\n            my_acts[i] = best_a;\n        }\n\n        // Output actions\n        for(char c : my_acts) res += c;\n        cout << res << endl;\n\n        // Read pet movements for this turn\n        for(int i=0; i<N; i++){\n            string mv; cin >> mv;\n            int cx = pets[i].x, cy = pets[i].y;\n            for(char c : mv){\n                int nx = cx, ny = cy;\n                if(c=='U') nx--;\n                else if(c=='D') nx++;\n                else if(c=='L') ny--;\n                else if(c=='R') ny++;\n\n                if(in_bounds(nx, ny) && grid[nx][ny] == 0){\n                    cx = nx; cy = ny;\n                } else {\n                    break; // Invalid move, pet stays\n                }\n            }\n            pets[i].x = cx; pets[i].y = cy;\n        }\n\n        // Update local state to match judge's simultaneous execution\n        // 1. Apply blocks first (blocks take precedence over moves)\n        for(int i=0; i<M; i++){\n            int a_idx = -1;\n            for(int k=0; k<9; k++) if(acts[k] == my_acts[i]) { a_idx = k; break; }\n            if(a_idx != -1 && is_block_act[a_idx]){\n                int tx = humans[i].x + ddx[a_idx];\n                int ty = humans[i].y + ddy[a_idx];\n                if(in_bounds(tx, ty) && grid[tx][ty] == 0){\n                    grid[tx][ty] = 1;\n                }\n            }\n        }\n        // 2. Apply moves\n        vector<Pos> next_humans(M);\n        for(int i=0; i<M; i++){\n            int a_idx = -1;\n            for(int k=0; k<9; k++) if(acts[k] == my_acts[i]) { a_idx = k; break; }\n            next_humans[i] = humans[i];\n            if(a_idx != -1 && !is_block_act[a_idx] && my_acts[i] != '.'){\n                int nx = humans[i].x + ddx[a_idx];\n                int ny = humans[i].y + ddy[a_idx];\n                if(in_bounds(nx, ny) && grid[nx][ny] == 0){\n                    next_humans[i] = {nx, ny};\n                }\n            }\n        }\n        humans = next_humans;\n    }\n\n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cstring>\n#include <queue>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\n// Precomputed transition tables for O(1) state updates\nint nxt[400][4];       // 0:U, 1:D, 2:L, 3:R\nbool blocked[400][4];  // True if wall or boundary blocks the move\ndouble dp[400];\ndouble new_dp[400];\n\n// Fast evaluation of expected score for a given move sequence\ninline double evaluate(const string& s, int s_i, int s_j, int t_i, int t_j, double p, int L) {\n    memset(dp, 0, sizeof(dp));\n    dp[s_i * 20 + s_j] = 1.0;\n    double expected_score = 0.0;\n    int tidx = t_i * 20 + t_j;\n    double move_prob = 1.0 - p;\n\n    for (int t = 0; t < L; ++t) {\n        memset(new_dp, 0, sizeof(new_dp));\n        int d = (s[t] == 'U' ? 0 : s[t] == 'D' ? 1 : s[t] == 'L' ? 2 : 3);\n        double target_prev = dp[tidx];\n\n        for (int idx = 0; idx < 400; ++idx) {\n            double prob = dp[idx];\n            if (prob < 1e-15) continue; // Skip negligible probabilities\n\n            if (idx == tidx) {\n                new_dp[tidx] += prob; // Absorbing state\n                continue;\n            }\n\n            // Probability of staying due to forgetting\n            new_dp[idx] += prob * p;\n\n            // Probability of moving or staying due to wall\n            if (blocked[idx][d]) {\n                new_dp[idx] += prob * move_prob;\n            } else {\n                new_dp[nxt[idx][d]] += prob * move_prob;\n            }\n        }\n\n        double target_now = new_dp[tidx];\n        double first_reach = target_now - target_prev;\n        if (first_reach > 1e-15) {\n            // S = 401 - t (1-indexed turn) -> 400 - t (0-indexed)\n            expected_score += (400.0 - t) * first_reach;\n        }\n        memcpy(dp, new_dp, sizeof(dp));\n    }\n    return expected_score;\n}\n\n// BFS to find shortest path for initialization\nstring get_bfs_path(int s_i, int s_j, int t_i, int t_j, const vector<string>& h, const vector<string>& v) {\n    int dist[20][20];\n    memset(dist, -1, sizeof(dist));\n    int pi[20][20], pj[20][20];\n    memset(pi, -1, sizeof(pi)); memset(pj, -1, sizeof(pj));\n    \n    queue<pair<int,int>> q;\n    q.push({s_i, s_j});\n    dist[s_i][s_j] = 0;\n    \n    int dr[] = {-1, 1, 0, 0};\n    int dc[] = {0, 0, -1, 1};\n    \n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        if (r == t_i && c == t_j) break;\n        \n        for (int k = 0; k < 4; ++k) {\n            int nr = r + dr[k], nc = c + dc[k];\n            if (nr < 0 || nr >= 20 || nc < 0 || nc >= 20) continue;\n            \n            bool wall = false;\n            if (k == 0) wall = (v[r-1][c] == '1'); // U\n            else if (k == 1) wall = (v[r][c] == '1'); // D\n            else if (k == 2) wall = (h[r][c-1] == '1'); // L\n            else if (k == 3) wall = (h[r][c] == '1'); // R\n            \n            if (!wall && dist[nr][nc] == -1) {\n                dist[nr][nc] = dist[r][c] + 1;\n                pi[nr][nc] = r; pj[nr][nc] = c;\n                q.push({nr, nc});\n            }\n        }\n    }\n    \n    string path = \"\";\n    int r = t_i, c = t_j;\n    while (r != s_i || c != s_j) {\n        int pr = pi[r][c], pc = pj[r][c];\n        if (pr == r) path += (pc < c ? 'R' : 'L');\n        else path += (pr < r ? 'D' : 'U');\n        r = pr; c = pc;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int s_i, s_j, t_i, t_j;\n    double p;\n    if (!(cin >> s_i >> s_j >> t_i >> t_j >> p)) return 0;\n    \n    vector<string> h(20), v(19);\n    for (int i = 0; i < 20; ++i) cin >> h[i];\n    for (int i = 0; i < 19; ++i) cin >> v[i];\n    \n    // Precompute transition tables\n    for (int r = 0; r < 20; ++r) {\n        for (int c = 0; c < 20; ++c) {\n            int idx = r * 20 + c;\n            // U: 0\n            if (r > 0 && v[r-1][c] == '0') { nxt[idx][0] = (r-1)*20+c; blocked[idx][0] = false; }\n            else { nxt[idx][0] = idx; blocked[idx][0] = true; }\n            // D: 1\n            if (r < 19 && v[r][c] == '0') { nxt[idx][1] = (r+1)*20+c; blocked[idx][1] = false; }\n            else { nxt[idx][1] = idx; blocked[idx][1] = true; }\n            // L: 2\n            if (c > 0 && h[r][c-1] == '0') { nxt[idx][2] = r*20+(c-1); blocked[idx][2] = false; }\n            else { nxt[idx][2] = idx; blocked[idx][2] = true; }\n            // R: 3\n            if (c < 19 && h[r][c] == '0') { nxt[idx][3] = r*20+(c+1); blocked[idx][3] = false; }\n            else { nxt[idx][3] = idx; blocked[idx][3] = true; }\n        }\n    }\n    \n    // Initial solution: repeat BFS shortest path to length 200\n    string path = get_bfs_path(s_i, s_j, t_i, t_j, h, v);\n    string best_s = \"\";\n    int plen = path.empty() ? 1 : path.size();\n    best_s.reserve(200);\n    for (int i = 0; i < 200; ++i) best_s += path[i % plen];\n    \n    double best_score = evaluate(best_s, s_i, s_j, t_i, t_j, p, 200);\n    string cur_s = best_s;\n    double cur_score = best_score;\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist_pos(0, 199);\n    uniform_int_distribution<int> dist_char(0, 3);\n    uniform_real_distribution<double> dist_uni(0.0, 1.0);\n    char dirs[] = {'U', 'D', 'L', 'R'};\n    \n    auto start_time = chrono::steady_clock::now();\n    double T = 15.0; // Initial temperature\n    int iter = 0;\n    \n    // Simulated Annealing loop\n    while (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() < 1.85) {\n        T = 15.0 * pow(0.99996, iter); // Geometric cooling\n        if (T < 1e-9) T = 1e-9;\n        \n        int pos = dist_pos(rng);\n        char old_c = cur_s[pos];\n        cur_s[pos] = dirs[dist_char(rng)];\n        \n        double new_score = evaluate(cur_s, s_i, s_j, t_i, t_j, p, 200);\n        double delta = new_score - cur_score;\n        \n        if (delta > 0 || dist_uni(rng) < exp(delta / T)) {\n            cur_score = new_score;\n            if (new_score > best_score) {\n                best_score = new_score;\n                best_s = cur_s;\n            }\n        } else {\n            cur_s[pos] = old_c;\n        }\n        iter++;\n    }\n    \n    cout << best_s << \"\\n\";\n    return 0;\n}","ahc010":"/*\n    Solution for AHC010\n    Approach: Simulated Annealing\n    The problem asks to maximize the product of the lengths of the two longest loops.\n    We use Simulated Annealing to search for the optimal rotation configuration.\n    The score calculation is done in O(N) time by traversing the grid states.\n*/\n#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cstring>\n#include <cmath>\n\nusing namespace std;\n\nconst int H = 30;\nconst int W = 30;\nconst int DIRS = 4;\n\n// Directions: 0: Left, 1: Up, 2: Right, 3: Down\n// di, dj represent the change in coordinates when moving in that direction\nconst int di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n\n// to_table[type][enter_dir] -> exit_dir\n// If -1, the tile cannot be entered from that direction or the path is broken.\n// Directions are indexed as: 0: Left, 1: Up, 2: Right, 3: Down\nconst int to_table[8][4] = {\n    {1, 0, -1, -1}, // 0: Curve L-U\n    {3, -1, -1, 0}, // 1: Curve L-D\n    {-1, -1, 3, 2}, // 2: Curve R-D\n    {-1, 2, 1, -1}, // 3: Curve R-U\n    {1, 0, 3, 2},   // 4: Two curves (L-U) and (R-D)\n    {3, 2, 1, 0},   // 5: Two curves (L-D) and (U-R)\n    {2, -1, 0, -1}, // 6: Straight Horizontal (L-R)\n    {-1, 3, -1, 1}  // 7: Straight Vertical (U-D)\n};\n\nint grid[H][W];\nint initial_grid[H][W];\nint best_grid[H][W];\nlong long best_score = 0;\n\n// Visited arrays for cycle detection\n// vis_call stores the global call ID to avoid resetting the array every time\nint vis_call[H][W][DIRS];\nint vis_trace[H][W][DIRS];\nint vis_idx[H][W][DIRS];\nint global_call_id = 0;\n\n// Precomputed valid moves for each tile based on its initial type\nvector<int> valid_moves[H][W];\n\nvoid precompute_valid_moves() {\n    for (int i = 0; i < H; ++i) {\n        for (int j = 0; j < W; ++j) {\n            int t = initial_grid[i][j];\n            if (t >= 0 && t <= 3) {\n                valid_moves[i][j] = {0, 1, 2, 3};\n            } else if (t == 4 || t == 5) {\n                valid_moves[i][j] = {4, 5};\n            } else { // 6, 7\n                valid_moves[i][j] = {6, 7};\n            }\n        }\n    }\n}\n\n// Calculates the score of the current grid configuration\n// Score = L1 * L2, where L1, L2 are lengths of two longest loops\nlong long calc_score() {\n    global_call_id++;\n    int current_trace_id = 0;\n    \n    long long max1 = 0, max2 = 0;\n    \n    // Iterate over all possible entry states (i, j, d)\n    for (int i = 0; i < H; ++i) {\n        for (int j = 0; j < W; ++j) {\n            for (int d = 0; d < 4; ++d) {\n                int type = grid[i][j];\n                int exit_d = to_table[type][d];\n                // If entering from d is invalid, skip\n                if (exit_d == -1) continue;\n                \n                // If this state was already visited in this score calculation, skip\n                if (vis_call[i][j][d] == global_call_id) continue;\n                \n                current_trace_id++;\n                int trace_len = 0;\n                int ci = i, cj = j, cd = d;\n                bool is_cycle = false;\n                long long cycle_len = 0;\n                \n                while (true) {\n                    // Mark current state as visited\n                    vis_call[ci][cj][cd] = global_call_id;\n                    vis_trace[ci][cj][cd] = current_trace_id;\n                    vis_idx[ci][cj][cd] = trace_len;\n                    trace_len++;\n                    \n                    int type_curr = grid[ci][cj];\n                    int exit_dir = to_table[type_curr][cd];\n                    \n                    // If exit is blocked, path ends\n                    if (exit_dir == -1) break;\n                    \n                    // Move to next tile\n                    int ni = ci + di[exit_dir];\n                    int nj = cj + dj[exit_dir];\n                    \n                    // Check bounds\n                    if (ni < 0 || ni >= H || nj < 0 || nj >= W) break;\n                    \n                    // Entering next tile from opposite direction\n                    int nd = (exit_dir + 2) % 4;\n                    \n                    // Check if next state was visited\n                    if (vis_call[ni][nj][nd] == global_call_id) {\n                        // If visited in current trace, we found a cycle\n                        if (vis_trace[ni][nj][nd] == current_trace_id) {\n                            // Cycle length is difference in indices\n                            // trace_len is the count of states visited so far (1-based index of next state)\n                            // vis_idx is 0-based index of the repeated state\n                            cycle_len = trace_len - vis_idx[ni][nj][nd];\n                            is_cycle = true;\n                        }\n                        // If visited in previous trace, we merged into an existing path/cycle\n                        // No new cycle found starting here\n                        break;\n                    }\n                    \n                    ci = ni;\n                    cj = nj;\n                    cd = nd;\n                }\n                \n                if (is_cycle) {\n                    if (cycle_len > max1) {\n                        max2 = max1;\n                        max1 = cycle_len;\n                    } else if (cycle_len > max2) {\n                        max2 = cycle_len;\n                    }\n                }\n            }\n        }\n    }\n    return max1 * max2;\n}\n\n// Helper to compute rotation count from initial to current type\nint get_rotation(int initial, int current) {\n    if (initial >= 0 && initial <= 3) {\n        return (current - initial + 4) % 4;\n    } else if (initial == 4 || initial == 5) {\n        return (current != initial ? 1 : 0);\n    } else { // 6, 7\n        return (current != initial ? 1 : 0);\n    }\n}\n\nint main() {\n    // Fast IO\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    char c;\n    for (int i = 0; i < H; ++i) {\n        for (int j = 0; j < W; ++j) {\n            cin >> c;\n            initial_grid[i][j] = c - '0';\n            grid[i][j] = initial_grid[i][j];\n        }\n    }\n    \n    precompute_valid_moves();\n    \n    // Initial score calculation\n    best_score = calc_score();\n    memcpy(best_grid, grid, sizeof(grid));\n    \n    // Random number generator\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist_i(0, H - 1);\n    uniform_int_distribution<int> dist_j(0, W - 1);\n    \n    auto start_time = chrono::high_resolution_clock::now();\n    double time_limit = 1.85; // Leave some buffer for output\n    \n    long long current_score = best_score;\n    \n    // Simulated Annealing Loop\n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > time_limit) break;\n        \n        // Temperature schedule: linear cooling\n        double progress = elapsed / time_limit;\n        double T = 10000.0 * (1.0 - progress);\n        if (T < 0.1) T = 0.1;\n        \n        // Pick a random tile\n        int r = dist_i(rng);\n        int c_idx = dist_j(rng);\n        \n        // Pick a random valid move for that tile\n        const auto& moves = valid_moves[r][c_idx];\n        int new_type = moves[rng() % moves.size()];\n        \n        int old_type = grid[r][c_idx];\n        if (new_type == old_type) continue;\n        \n        // Apply change\n        grid[r][c_idx] = new_type;\n        long long new_score = calc_score();\n        \n        long long delta = new_score - current_score;\n        \n        bool accept = false;\n        if (delta > 0) {\n            accept = true;\n        } else {\n            // Metropolis criterion\n            // delta is negative\n            if (delta / T > -50.0) { // Avoid underflow for very small probabilities\n                double prob = exp((double)delta / T);\n                uint32_t rand_val = rng();\n                double r_val = (double)rand_val / 4294967296.0;\n                if (r_val < prob) accept = true;\n            }\n        }\n        \n        if (accept) {\n            current_score = new_score;\n            if (new_score > best_score) {\n                best_score = new_score;\n                memcpy(best_grid, grid, sizeof(grid));\n            }\n        } else {\n            // Revert change\n            grid[r][c_idx] = old_type;\n        }\n    }\n    \n    // Construct output string\n    string res;\n    res.resize(900);\n    int idx = 0;\n    for (int i = 0; i < H; ++i) {\n        for (int j = 0; j < W; ++j) {\n            int r = get_rotation(initial_grid[i][j], best_grid[i][j]);\n            res[idx++] = (char)('0' + r);\n        }\n    }\n    cout << res << \"\\n\";\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Union-Find with copy support for backtracking\nstruct UF {\n    vector<int> p;\n    UF(int n = 0) : p(n, -1) {}\n    UF(const UF& other) : p(other.p) {}\n    int find(int x) { return p[x] == -1 ? x : p[x] = find(p[x]); }\n    void unite(int a, int b) {\n        a = find(a); b = find(b);\n        if (a != b) p[b] = a;\n    }\n    bool same(int a, int b) { return find(a) == find(b); }\n};\n\nint N;\nlong long T;\nvector<int> init_masks; // bitmask for each original tile\nvector<int> target_layout; // target_layout[pos] = original tile index\nstring moves;\n\n// Layout Finder State\nvector<int> tiles_mask;\nvector<bool> used;\nchrono::steady_clock::time_point start_time;\nbool found_layout = false;\n\nvoid dfs_layout(int pos, vector<int>& board, UF uf) {\n    if (found_layout) return;\n    auto now = chrono::steady_clock::now();\n    if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 900) return;\n\n    if (pos == N * N - 1) {\n        int root = uf.find(0);\n        for (int i = 1; i < N * N - 1; ++i) {\n            if (uf.find(i) != root) return;\n        }\n        target_layout = board;\n        found_layout = true;\n        return;\n    }\n\n    int r = pos / N, c = pos % N;\n    bool req_up = (r > 0 && board[(r - 1) * N + c] != -1 && (tiles_mask[board[(r - 1) * N + c]] & 8));\n    bool req_left = (c > 0 && board[r * N + c - 1] != -1 && (tiles_mask[board[r * N + c - 1]] & 4));\n\n    static vector<int> perm;\n    if (pos == 0) {\n        perm.resize(N * N - 1);\n        iota(perm.begin(), perm.end(), 0);\n        mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n        shuffle(perm.begin(), perm.end(), rng);\n    }\n\n    for (int tid : perm) {\n        if (used[tid]) continue;\n        int m = tiles_mask[tid];\n        if (req_up && !(m & 2)) continue;\n        if (req_left && !(m & 1)) continue;\n\n        board[pos] = tid;\n        used[tid] = true;\n\n        bool conn_up = false, conn_left = false;\n        if (r > 0 && board[(r - 1) * N + c] != -1 && (m & 2)) {\n            conn_up = true;\n            uf.unite(pos, pos - N);\n        }\n        if (c > 0 && board[r * N + c - 1] != -1 && (m & 1)) {\n            conn_left = true;\n            uf.unite(pos, pos - 1);\n        }\n\n        bool cycle = false;\n        if (conn_up && conn_left && uf.same(pos - N, pos - 1)) cycle = true;\n\n        if (!cycle) {\n            dfs_layout(pos + 1, board, uf);\n            if (found_layout) return;\n        }\n\n        used[tid] = false;\n        board[pos] = -1;\n    }\n}\n\n// BFS to move empty space to target position, avoiding solved cells and the current tile\nstring bfs_empty(int er, int ec, int tr, int tc, int gr, int gc, const vector<bool>& solved) {\n    if (er == gr && ec == gc) return \"\";\n    queue<pair<int, int>> q;\n    q.push({er, ec});\n    vector<int> par(N * N, -1);\n    vector<char> move_to(N * N, 0);\n    auto id = [&](int r, int c) { return r * N + c; };\n    par[id(er, ec)] = id(er, ec);\n\n    int dr[] = {-1, 1, 0, 0};\n    int dc[] = {0, 0, -1, 1};\n    char out_chars[] = {'D', 'U', 'R', 'L'}; // internal move -> output char\n\n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        if (r == gr && c == gc) {\n            string path;\n            int cur = id(r, c);\n            while (cur != id(er, ec)) {\n                path += move_to[cur];\n                cur = par[cur];\n            }\n            reverse(path.begin(), path.end());\n            return path;\n        }\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i], nc = c + dc[i];\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n            int nid = id(nr, nc);\n            if (par[nid] != -1) continue;\n            if (solved[nid]) continue;\n            if (nr == tr && nc == tc) continue;\n            par[nid] = id(r, c);\n            move_to[nid] = out_chars[i];\n            q.push({nr, nc});\n        }\n    }\n    return \"\"; // Should not reach here with valid constraints\n}\n\nvoid apply_move(char c, vector<int>& board, int& empty_pos, vector<int>& cur_pos) {\n    int tr = empty_pos / N, tc = empty_pos % N;\n    int nr = tr, nc = tc;\n    if (c == 'U') nr--;      // Tile moves up, empty moves down\n    else if (c == 'D') nr++; // Tile moves down, empty moves up\n    else if (c == 'L') nc--; // Tile moves left, empty moves right\n    else if (c == 'R') nc++; // Tile moves right, empty moves left\n\n    int new_empty = nr * N + nc;\n    int tid = board[new_empty];\n    board[empty_pos] = tid;\n    board[new_empty] = -1;\n    cur_pos[tid] = empty_pos;\n    empty_pos = new_empty;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> T;\n    vector<string> grid(N);\n    init_masks.reserve(N * N - 1);\n    for (int i = 0; i < N; ++i) cin >> grid[i];\n\n    int empty_init_pos = -1;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            char c = grid[i][j];\n            if (c == '0') {\n                empty_init_pos = i * N + j;\n                continue;\n            }\n            int val;\n            if (c >= '0' && c <= '9') val = c - '0';\n            else val = c - 'a' + 10;\n            init_masks.push_back(val);\n        }\n    }\n\n    // Phase 1: Find valid tree layout\n    tiles_mask = init_masks;\n    used.assign(N * N - 1, false);\n    vector<int> board(N * N, -1);\n    start_time = chrono::steady_clock::now();\n    \n    // Run layout finder with a couple of attempts if needed\n    for (int attempt = 0; attempt < 5 && !found_layout; ++attempt) {\n        dfs_layout(0, board, UF(N * N));\n        if (!found_layout) {\n            // Reshuffle and retry\n            fill(used.begin(), used.end(), false);\n            fill(board.begin(), board.end(), -1);\n            mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n            shuffle(tiles_mask.begin(), tiles_mask.end(), rng);\n        }\n    }\n\n    if (!found_layout) {\n        // Fallback: simple row-major assignment (shouldn't happen given problem guarantee)\n        iota(target_layout.begin(), target_layout.end() - 1, 0);\n        target_layout.back() = -1;\n    }\n\n    // Phase 2: Solve sliding puzzle\n    vector<int> cur_board(N * N);\n    vector<int> cur_pos(N * N - 1);\n    int empty_pos = empty_init_pos;\n    \n    int tile_idx = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int pos = i * N + j;\n            if (i == N - 1 && j == N - 1) {\n                cur_board[pos] = -1;\n                continue;\n            }\n            int tid = target_layout[pos];\n            cur_board[pos] = tid; // temporary, will be overwritten during moves\n            cur_pos[tid] = -1;    // placeholder\n            tile_idx++;\n        }\n    }\n\n    // Initialize current board state correctly from input\n    tile_idx = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int pos = i * N + j;\n            if (grid[i][j] == '0') {\n                cur_board[pos] = -1;\n            } else {\n                cur_board[pos] = tile_idx;\n                cur_pos[tile_idx] = pos;\n                tile_idx++;\n            }\n        }\n    }\n\n    vector<bool> pos_solved(N * N, false);\n    moves.reserve(T);\n\n    for (int target_pos = 0; target_pos < N * N - 1; ++target_pos) {\n        int tid = target_layout[target_pos];\n        if (cur_pos[tid] == target_pos) {\n            pos_solved[target_pos] = true;\n            continue;\n        }\n\n        int tr = cur_pos[tid] / N, tc = cur_pos[tid] % N;\n        int tr_t = target_pos / N, tc_t = target_pos % N;\n\n        // Move tile towards target step by step\n        while (cur_pos[tid] != target_pos) {\n            int dtr = (tr > tr_t) ? -1 : (tr < tr_t) ? 1 : 0;\n            int dtc = (tc > tc_t) ? -1 : (tc < tc_t) ? 1 : 0;\n\n            // Empty needs to be opposite to desired tile movement\n            int need_r = tr - dtr, need_c = tc - dtc;\n            int empty_r = empty_pos / N, empty_c = empty_pos % N;\n\n            string path = bfs_empty(empty_r, empty_c, tr, tc, need_r, need_c, pos_solved);\n            for (char c : path) {\n                apply_move(c, cur_board, empty_pos, cur_pos);\n                moves += c;\n            }\n            tr = need_r; tc = need_c; // tile is still at (tr, tc), empty is now at (need_r, need_c)\n\n            // Slide tile\n            char slide_char;\n            if (dtr == -1) slide_char = 'U';\n            else if (dtr == 1) slide_char = 'D';\n            else if (dtc == -1) slide_char = 'L';\n            else slide_char = 'R';\n\n            apply_move(slide_char, cur_board, empty_pos, cur_pos);\n            moves += slide_char;\n\n            tr = cur_pos[tid] / N;\n            tc = cur_pos[tid] % N;\n        }\n        pos_solved[target_pos] = true;\n    }\n\n    // Trim empty moves if any (shouldn't happen)\n    while (!moves.empty() && moves.back() == '\\0') moves.pop_back();\n\n    cout << moves << \"\\n\";\n    return 0;\n}","ahc012":"/*\n    Solution for AtCoder Heuristic Contest 012\n    Strategy: Greedy separation of subsets matching demand sizes using random projections.\n*/\n#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\ntypedef long long ll;\n\nstruct Point {\n    ll x, y;\n    int id;\n};\n\nll gcd(ll a, ll b) {\n    while (b) {\n        a %= b;\n        swap(a, b);\n    }\n    return a;\n}\n\n// Extended Euclidean Algorithm\n// Finds x, y such that a*x + b*y = g\nll extgcd(ll a, ll b, ll &x, ll &y) {\n    if (b == 0) {\n        x = 1; y = 0;\n        return a;\n    }\n    ll x1, y1;\n    ll d = extgcd(b, a % b, x1, y1);\n    x = y1;\n    y = x1 - y1 * (a / b);\n    return d;\n}\n\nstruct Line {\n    ll p1x, p1y, p2x, p2y;\n};\n\nint main() {\n    // Optimize I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, K;\n    if (!(cin >> N >> K)) return 0;\n\n    vector<int> a(11);\n    for (int i = 1; i <= 10; ++i) {\n        cin >> a[i];\n    }\n\n    vector<Point> pts(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> pts[i].x >> pts[i].y;\n        pts[i].id = i;\n    }\n\n    vector<Line> cuts;\n    \n    // Random generator\n    mt19937_64 rng(12345); \n    \n    // Number of random directions to try per cut\n    const int TRIES = 150;\n\n    while ((int)cuts.size() < K) {\n        // Check if we can satisfy any demand\n        bool possible = false;\n        for (int d = 1; d <= 10; ++d) {\n            if (a[d] > 0 && (int)pts.size() >= d) {\n                possible = true;\n                break;\n            }\n        }\n        if (!possible) break;\n        if (pts.size() < 2) break;\n\n        bool found = false;\n        ll best_u = 0, best_v = 0, best_C = 0;\n        bool take_right = false;\n        int best_cnt = 0;\n\n        for (int t = 0; t < TRIES; ++t) {\n            // Random direction in range [-50, 50]\n            ll u = (ll)rng() % 101 - 50;\n            ll v = (ll)rng() % 101 - 50;\n            \n            if (u == 0 && v == 0) continue;\n            // Ensure gcd(u, v) = 1 for easier integer line construction\n            if (gcd(abs(u), abs(v)) != 1) continue;\n\n            // Project points\n            // Store pair {projection_value, original_index}\n            vector<pair<ll, int>> projs;\n            projs.reserve(pts.size());\n            for (int i = 0; i < (int)pts.size(); ++i) {\n                projs.push_back({u * pts[i].x + v * pts[i].y, i});\n            }\n            \n            // Sort by projection value\n            sort(projs.begin(), projs.end());\n            \n            // Check gaps\n            // We look for a gap >= 2 at a split point that satisfies a demand\n            for (size_t i = 0; i < projs.size() - 1; ++i) {\n                int L = i + 1; // Size of left set\n                int R = (int)projs.size() - L; // Size of right set\n                ll val_left = projs[i].first;\n                ll val_right = projs[i+1].first;\n                \n                // Need integer C such that val_left < C < val_right\n                // Since values are integers, we need val_right - val_left >= 2\n                if (val_right - val_left >= 2) {\n                    ll C = val_left + 1;\n                    \n                    // Check if Left set size satisfies demand\n                    if (L <= 10 && a[L] > 0) {\n                        best_u = u; best_v = v; best_C = C;\n                        take_right = false; best_cnt = L;\n                        found = true;\n                        goto end_search;\n                    }\n                    // Check if Right set size satisfies demand\n                    if (R <= 10 && a[R] > 0) {\n                        best_u = u; best_v = v; best_C = C;\n                        take_right = true; best_cnt = R;\n                        found = true;\n                        goto end_search;\n                    }\n                }\n            }\n        }\n\n        end_search:\n        if (!found) {\n            // Could not find a valid cut with random directions\n            break;\n        }\n\n        // Construct two points on the line: best_u x + best_v y = best_C\n        ll x0, y0;\n        extgcd(best_u, best_v, x0, y0);\n        // Scale particular solution\n        ll X0 = x0 * best_C;\n        ll Y0 = y0 * best_C;\n        \n        // Two points on the line\n        ll p1x = X0;\n        ll p1y = Y0;\n        ll p2x = X0 + best_v;\n        ll p2y = Y0 - best_u;\n        \n        cuts.push_back({p1x, p1y, p2x, p2y});\n        a[best_cnt]--;\n        \n        // Update pts vector\n        // If take_right is true, we used the Right set to satisfy demand.\n        // So we remove Right set, keeping Left set.\n        // If take_right is false, we used Left set.\n        // So we remove Left set, keeping Right set.\n        \n        vector<Point> next_pts;\n        next_pts.reserve(pts.size());\n        \n        if (take_right) {\n            // Keep Left set: val < best_C\n            for (const auto& p : pts) {\n                if (best_u * p.x + best_v * p.y < best_C) {\n                    next_pts.push_back(p);\n                }\n            }\n        } else {\n            // Keep Right set: val > best_C\n            for (const auto& p : pts) {\n                if (best_u * p.x + best_v * p.y > best_C) {\n                    next_pts.push_back(p);\n                }\n            }\n        }\n        pts = move(next_pts);\n    }\n\n    cout << cuts.size() << \"\\n\";\n    for (const auto& line : cuts) {\n        cout << line.p1x << \" \" << line.p1y << \" \" << line.p2x << \" \" << line.p2y << \"\\n\";\n    }\n\n    return 0;\n}","ahc014":"#pragma GCC optimize(\"O3,unroll-loops\")\n#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nbool has_dot[65][65];\nbool used_right[65][65], used_up[65][65], used_ur[65][65], used_dr[65][65];\nlong long weight[65][65];\n\nstruct Point { int x, y; };\nvector<Point> all_points;\nvector<tuple<Point, Point, Point, Point>> result;\n\ninline int sgn(int x) { return (x > 0) - (x < 0); }\n\n// Checks edge segments and interior dots between a and b.\n// If mark is true, commits the edges as used.\nbool check_segment(Point a, Point b, bool mark) {\n    int dx = sgn(b.x - a.x), dy = sgn(b.y - a.y);\n    int cx = a.x, cy = a.y;\n    while (cx != b.x || cy != b.y) {\n        int nx = cx + dx, ny = cy + dy;\n        // Check interior dots (exclude the endpoint b)\n        if (nx != b.x || ny != b.y) {\n            if (has_dot[nx][ny]) return false;\n        }\n        // Check edge usage\n        bool used = false;\n        if (dx == 1 && dy == 0) used = used_right[cx][cy];\n        else if (dx == -1 && dy == 0) used = used_right[cx-1][cy];\n        else if (dx == 0 && dy == 1) used = used_up[cx][cy];\n        else if (dx == 0 && dy == -1) used = used_up[cx][cy-1];\n        else if (dx == 1 && dy == 1) used = used_ur[cx][cy];\n        else if (dx == -1 && dy == -1) used = used_ur[cx-1][cy-1];\n        else if (dx == -1 && dy == 1) used = used_dr[cx-1][cy];\n        else if (dx == 1 && dy == -1) used = used_dr[cx][cy];\n\n        if (used) return false;\n\n        if (mark) {\n            if (dx == 1 && dy == 0) used_right[cx][cy] = true;\n            else if (dx == -1 && dy == 0) used_right[cx-1][cy] = true;\n            else if (dx == 0 && dy == 1) used_up[cx][cy] = true;\n            else if (dx == 0 && dy == -1) used_up[cx][cy-1] = true;\n            else if (dx == 1 && dy == 1) used_ur[cx][cy] = true;\n            else if (dx == -1 && dy == -1) used_ur[cx-1][cy-1] = true;\n            else if (dx == -1 && dy == 1) used_dr[cx-1][cy] = true;\n            else if (dx == 1 && dy == -1) used_dr[cx][cy] = true;\n        }\n        cx = nx; cy = ny;\n    }\n    return true;\n}\n\n// Validates the entire rectangle perimeter\nbool check_rect(Point p1, Point p2, Point p3, Point p4, bool mark) {\n    Point pts[4] = {p1, p2, p3, p4};\n    for(int i = 0; i < 4; i++) {\n        if (!check_segment(pts[i], pts[(i+1)%4], false)) return false;\n    }\n    if (mark) {\n        for(int i = 0; i < 4; i++) {\n            check_segment(pts[i], pts[(i+1)%4], true);\n        }\n    }\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M)) return 0;\n    \n    int c = (N - 1) / 2;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            weight[i][j] = (long long)(i - c) * (i - c) + (j - c) * (j - c) + 1;\n            all_points.push_back({i, j});\n        }\n    }\n\n    vector<int> row_dots[65], col_dots[65];\n    for (int i = 0; i < M; i++) {\n        int x, y; cin >> x >> y;\n        has_dot[x][y] = true;\n        row_dots[y].push_back(x);\n        col_dots[x].push_back(y);\n    }\n\n    // Sort by weight descending\n    sort(all_points.begin(), all_points.end(), [](const Point& a, const Point& b) {\n        return weight[a.x][a.y] > weight[b.x][b.y];\n    });\n\n    clock_t start = clock();\n    double time_limit = 4.5 * CLOCKS_PER_SEC; // Safety margin for system test overhead\n\n    while ((double)(clock() - start) / CLOCKS_PER_SEC < 4.5) {\n        bool found = false;\n        for (auto& p1 : all_points) {\n            if (has_dot[p1.x][p1.y]) continue;\n            int px = p1.x, py = p1.y;\n            bool found_rect = false;\n            Point p2, p3, p4;\n\n            // Quick prune: must have at least one dot in row or col for axis-aligned,\n            // or on diagonals for 45-deg. We rely on fast inner loops instead of complex pruning.\n\n            // 1. Axis-Aligned Check\n            // p1=(px,py), p2=(x2,py), p4=(px,y2), p3=(x2,y2)\n            if (!row_dots[py].empty() && !col_dots[px].empty()) {\n                for (int x2 : row_dots[py]) {\n                    if (x2 == px) continue;\n                    for (int y2 : col_dots[px]) {\n                        if (y2 == py) continue;\n                        if (has_dot[x2][y2]) {\n                            p2 = {x2, py}; p3 = {x2, y2}; p4 = {px, y2};\n                            if (check_rect(p1, p2, p3, p4, false)) {\n                                found_rect = true;\n                                goto axis_done;\n                            }\n                        }\n                    }\n                }\n            }\n        axis_done:\n            if (found_rect) {\n                check_rect(p1, p2, p3, p4, true);\n                has_dot[p1.x][p1.y] = true;\n                row_dots[py].push_back(p1.x);\n                col_dots[px].push_back(p1.y);\n                result.push_back({p1, p2, p3, p4});\n                found = true;\n                break;\n            }\n\n            // 2. 45-Degree Rotated Check\n            // p1=(px,py), p2=(px+a, py+a), p4=(px+b, py-b), p3=(px+a+b, py+a-b)\n            for (int a = -N; a <= N; a++) {\n                if (a == 0) continue;\n                int x2 = px + a, y2 = py + a;\n                if (x2 < 0 || x2 >= N || y2 < 0 || y2 >= N || !has_dot[x2][y2]) continue;\n                for (int b = -N; b <= N; b++) {\n                    if (b == 0) continue;\n                    int x4 = px + b, y4 = py - b;\n                    if (x4 < 0 || x4 >= N || y4 < 0 || y4 >= N || !has_dot[x4][y4]) continue;\n                    int x3 = x2 + b, y3 = y2 - b;\n                    if (x3 < 0 || x3 >= N || y3 < 0 || y3 >= N) continue;\n                    if (has_dot[x3][y3]) {\n                        p2 = {x2, y2}; p4 = {x4, y4}; p3 = {x3, y3};\n                        if (check_rect(p1, p2, p3, p4, false)) {\n                            found_rect = true;\n                            goto deg45_done;\n                        }\n                    }\n                }\n            }\n        deg45_done:\n            if (found_rect) {\n                check_rect(p1, p2, p3, p4, true);\n                has_dot[p1.x][p1.y] = true;\n                row_dots[py].push_back(p1.x);\n                col_dots[px].push_back(p1.y);\n                result.push_back({p1, p2, p3, p4});\n                found = true;\n                break;\n            }\n        }\n        if (!found) break; // No more valid moves\n    }\n\n    // Output\n    cout << result.size() << \"\\n\";\n    for (const auto& op : result) {\n        const auto& [p1, p2, p3, p4] = op;\n        cout << p1.x << \" \" << p1.y << \" \"\n             << p2.x << \" \" << p2.y << \" \"\n             << p3.x << \" \" << p3.y << \" \"\n             << p4.x << \" \" << p4.y << \"\\n\";\n    }\n\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <utility>\n\nusing namespace std;\n\n// Calculate sum of squares of connected component sizes\nint calc_score(const vector<vector<int>>& grid) {\n    vector<vector<bool>> visited(10, vector<bool>(10, false));\n    int total_score = 0;\n    int dr[] = {-1, 1, 0, 0};\n    int dc[] = {0, 0, -1, 1};\n    \n    for (int r = 0; r < 10; ++r) {\n        for (int c = 0; c < 10; ++c) {\n            if (grid[r][c] != 0 && !visited[r][c]) {\n                int flavor = grid[r][c];\n                int size = 0;\n                // Simple BFS using vector as queue\n                vector<pair<int, int>> q;\n                q.push_back({r, c});\n                visited[r][c] = true;\n                int head = 0;\n                while(head < (int)q.size()){\n                    auto [cr, cc] = q[head++];\n                    size++;\n                    for(int i=0; i<4; ++i){\n                        int nr = cr + dr[i];\n                        int nc = cc + dc[i];\n                        if(nr >= 0 && nr < 10 && nc >= 0 && nc < 10 && \n                           !visited[nr][nc] && grid[nr][nc] == flavor){\n                            visited[nr][nc] = true;\n                            q.push_back({nr, nc});\n                        }\n                    }\n                }\n                total_score += size * size;\n            }\n        }\n    }\n    return total_score;\n}\n\n// Apply tilt to grid\nvector<vector<int>> tilt(const vector<vector<int>>& grid, char dir) {\n    vector<vector<int>> next_grid = grid;\n    if (dir == 'L') {\n        for (int r = 0; r < 10; ++r) {\n            vector<int> row;\n            row.reserve(10);\n            for (int c = 0; c < 10; ++c) if (grid[r][c] != 0) row.push_back(grid[r][c]);\n            for (int c = 0; c < 10; ++c) {\n                if (c < (int)row.size()) next_grid[r][c] = row[c];\n                else next_grid[r][c] = 0;\n            }\n        }\n    } else if (dir == 'R') {\n        for (int r = 0; r < 10; ++r) {\n            vector<int> row;\n            row.reserve(10);\n            for (int c = 0; c < 10; ++c) if (grid[r][c] != 0) row.push_back(grid[r][c]);\n            int idx = 9;\n            for (int i = (int)row.size() - 1; i >= 0; --i) {\n                next_grid[r][idx--] = row[i];\n            }\n            for (int c = idx; c >= 0; --c) next_grid[r][c] = 0;\n        }\n    } else if (dir == 'F') {\n        for (int c = 0; c < 10; ++c) {\n            vector<int> col;\n            col.reserve(10);\n            for (int r = 0; r < 10; ++r) if (grid[r][c] != 0) col.push_back(grid[r][c]);\n            for (int r = 0; r < 10; ++r) {\n                if (r < (int)col.size()) next_grid[r][c] = col[r];\n                else next_grid[r][c] = 0;\n            }\n        }\n    } else if (dir == 'B') {\n        for (int c = 0; c < 10; ++c) {\n            vector<int> col;\n            col.reserve(10);\n            for (int r = 0; r < 10; ++r) if (grid[r][c] != 0) col.push_back(grid[r][c]);\n            int idx = 9;\n            for (int i = (int)col.size() - 1; i >= 0; --i) {\n                next_grid[idx--][c] = col[i];\n            }\n            for (int r = idx; r >= 0; --r) next_grid[r][c] = 0;\n        }\n    }\n    return next_grid;\n}\n\nint main() {\n    // Fast I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    vector<int> f(100);\n    for (int i = 0; i < 100; ++i) {\n        if (!(cin >> f[i])) return 0;\n    }\n\n    vector<vector<int>> grid(10, vector<int>(10, 0));\n    vector<char> dirs = {'F', 'B', 'L', 'R'};\n\n    for (int t = 0; t < 100; ++t) {\n        int p;\n        cin >> p;\n\n        // Place candy\n        int count = 0;\n        bool found = false;\n        for (int r = 0; r < 10; ++r) {\n            for (int c = 0; c < 10; ++c) {\n                if (grid[r][c] == 0) {\n                    count++;\n                    if (count == p) {\n                        grid[r][c] = f[t];\n                        found = true;\n                        break;\n                    }\n                }\n            }\n            if (found) break;\n        }\n\n        // For the 100th candy (t=99), the grid is full, so tilt does nothing.\n        // We can skip the output as per problem statement.\n        if (t < 99) {\n            int best_score = -1;\n            char best_dir = 'F';\n\n            for (char d : dirs) {\n                vector<vector<int>> next_grid = tilt(grid, d);\n                int s = calc_score(next_grid);\n                if (s > best_score) {\n                    best_score = s;\n                    best_dir = d;\n                }\n            }\n\n            grid = tilt(grid, best_dir);\n            cout << best_dir << endl;\n        }\n    }\n\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    cin.tie(nullptr);\n    ios::sync_with_stdio(false);\n\n    double eps;\n    int M;\n    if (!(cin >> M >> eps)) return 0;\n\n    // N=88 provides a good balance between feature richness and speed.\n    // Larger N increases signal-to-noise ratio for degree statistics.\n    const int N = 88;\n    cout << N << \"\\n\";\n\n    vector<vector<int>> sorted_degs(M, vector<int>(N));\n    vector<double> mean_degs(M), var_degs(M);\n    vector<int> edge_counts(M, 0);\n    \n    mt19937 rng(42); // Fixed seed for reproducibility\n\n    for (int k = 0; k < M; ++k) {\n        // Space edge probabilities to ensure distinct degree distributions\n        double p = 0.15 + 0.7 * k / (M - 1.0);\n        \n        vector<int> deg(N, 0);\n        string s;\n        s.resize(N * (N - 1) / 2);\n        int pos = 0;\n        \n        // Generate graph and compute degrees on the fly\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                // Fast probabilistic edge placement\n                bool edge = (rng() % 100000 < (int)(p * 100000));\n                if (edge) {\n                    s[pos] = '1';\n                    deg[i]++;\n                    deg[j]++;\n                    edge_counts[k]++;\n                } else {\n                    s[pos] = '0';\n                }\n                pos++;\n            }\n        }\n        \n        // Sort degrees to obtain a permutation-invariant fingerprint\n        sort(deg.begin(), deg.end());\n        sorted_degs[k] = deg;\n        \n        // Precompute statistics for fast correlation decoding\n        double mu = (double)edge_counts[k] * 2.0 / N;\n        mean_degs[k] = mu;\n        double var = 0.0;\n        for (int d : deg) var += (d - mu) * (d - mu);\n        var_degs[k] = var;\n        \n        cout << s << \"\\n\";\n    }\n    cout.flush();\n\n    vector<int> H_deg(N);\n    for (int q = 0; q < 100; ++q) {\n        string h_str;\n        cin >> h_str;\n        \n        // Decode degrees from input string\n        fill(H_deg.begin(), H_deg.end(), 0);\n        int h_edges = 0;\n        int idx = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                if (h_str[idx] == '1') {\n                    H_deg[i]++;\n                    H_deg[j]++;\n                    h_edges++;\n                }\n                idx++;\n            }\n        }\n        sort(H_deg.begin(), H_deg.end());\n\n        double best_score = -2.0;\n        int best_k = 0;\n        double mu_H = (double)h_edges * 2.0 / N;\n        double var_H = 0.0;\n        for (int d : H_deg) var_H += (d - mu_H) * (d - mu_H);\n        if (var_H < 1e-9) var_H = 1e-9; // Avoid division by zero\n\n        for (int k = 0; k < M; ++k) {\n            // Compute Pearson correlation between sorted degree sequences\n            // Correlation is robust to the linear shift/scaling caused by noise\n            double cov = 0.0;\n            for (int i = 0; i < N; ++i) {\n                cov += (H_deg[i] - mu_H) * (sorted_degs[k][i] - mean_degs[k]);\n            }\n            \n            double corr = cov / sqrt(var_H * var_degs[k]);\n            // Slight penalty for edge count mismatch to break ties\n            double score = corr - 1e-4 * abs(h_edges - edge_counts[k]);\n            \n            if (score > best_score) {\n                best_score = score;\n                best_k = k;\n            }\n        }\n        \n        cout << best_k << \"\\n\";\n        cout.flush();\n    }\n\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n\n    struct EdgeInfo { int u, v, w; };\n    vector<EdgeInfo> edges(M);\n    vector<vector<pair<int, int>>> adj(N);\n\n    for (int i = 0; i < M; ++i) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        --u; --v;\n        edges[i] = {u, v, w};\n        adj[u].emplace_back(v, i);\n        adj[v].emplace_back(u, i);\n    }\n\n    // Skip coordinates\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n    }\n\n    mt19937_64 rng(42);\n    vector<long double> eb(M, 0.0);\n    vector<int> dist(N);\n    vector<vector<int>> pred(N);\n    vector<long double> sigma(N);\n    vector<long double> delta(N);\n    vector<int> nodes(N);\n    iota(nodes.begin(), nodes.end(), 0);\n\n    // Compute exact edge betweenness centrality\n    for (int s = 0; s < N; ++s) {\n        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;\n        fill(dist.begin(), dist.end(), 2e9);\n        dist[s] = 0;\n        pq.emplace(0, s);\n\n        for (int i = 0; i < N; ++i) pred[i].clear();\n\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u]) continue;\n            for (auto [v, id] : adj[u]) {\n                int w = edges[id].w;\n                if (dist[v] > d + w) {\n                    dist[v] = d + w;\n                    pred[v].clear();\n                    pred[v].push_back(id);\n                    pq.emplace(dist[v], v);\n                } else if (dist[v] == d + w) {\n                    pred[v].push_back(id);\n                }\n            }\n        }\n\n        sort(nodes.begin(), nodes.end(), [&](int a, int b) {\n            return dist[a] < dist[b];\n        });\n\n        fill(sigma.begin(), sigma.end(), 0.0);\n        sigma[s] = 1.0;\n        for (int u : nodes) {\n            if (u == s) continue;\n            for (int id : pred[u]) {\n                int p = (edges[id].u == u) ? edges[id].v : edges[id].u;\n                sigma[u] += sigma[p];\n            }\n        }\n\n        fill(delta.begin(), delta.end(), 0.0);\n        for (auto it = nodes.rbegin(); it != nodes.rend(); ++it) {\n            int u = *it;\n            if (sigma[u] == 0.0) continue;\n            for (int id : pred[u]) {\n                int p = (edges[id].u == u) ? edges[id].v : edges[id].u;\n                long double val = (sigma[p] / sigma[u]) * (1.0L + delta[u]);\n                delta[p] += val;\n                eb[id] += val;\n            }\n        }\n    }\n\n    // Add tiny noise to break ties deterministically\n    for (int i = 0; i < M; ++i) {\n        eb[i] += uniform_real_distribution<double>(0, 1e-9)(rng);\n    }\n\n    // Greedy initial assignment\n    vector<pair<long double, int>> sorted(M);\n    for (int i = 0; i < M; ++i) sorted[i] = {eb[i], i};\n    sort(sorted.begin(), sorted.end(), greater<>());\n\n    vector<int> assign(M);\n    vector<long double> day_sum(D, 0.0);\n\n    for (auto [w, idx] : sorted) {\n        int best_day = 0;\n        long double min_sum = day_sum[0];\n        for (int d = 1; d < D; ++d) {\n            if (day_sum[d] < min_sum) {\n                min_sum = day_sum[d];\n                best_day = d;\n            }\n        }\n        assign[idx] = best_day;\n        day_sum[best_day] += w;\n    }\n\n    // Local Search: Swap edges between days to minimize sum of squares of day sums\n    auto start = chrono::steady_clock::now();\n    while (true) {\n        if (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start).count() > 5000) break;\n\n        int i = rng() % M;\n        int j = rng() % M;\n        if (assign[i] == assign[j]) continue;\n\n        int d1 = assign[i], d2 = assign[j];\n        long double b1 = eb[i], b2 = eb[j];\n        long double s1 = day_sum[d1], s2 = day_sum[d2];\n        long double ns1 = s1 - b1 + b2;\n        long double ns2 = s2 - b2 + b1;\n\n        // Accept if strictly improves the load balance objective\n        if (ns1 * ns1 + ns2 * ns2 < s1 * s1 + s2 * s2 - 1e-9L) {\n            day_sum[d1] = ns1;\n            day_sum[d2] = ns2;\n            swap(assign[i], assign[j]);\n        }\n    }\n\n    // Output result (1-indexed days)\n    for (int i = 0; i < M; ++i) {\n        cout << assign[i] + 1 << (i == M - 1 ? \"\\n\" : \" \");\n    }\n\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\n\nint D;\nbool A[2][14][14][14];\nint rots[24][3][3];\n\n// Global best solution tracking\nint best_n = 0;\nint best_b1[14][14][14];\nint best_b2[14][14][14];\nvector<int> best_vol;\nlong double best_score = 1e18;\n\nvoid gen_rots() {\n    int cnt = 0;\n    queue<array<array<int,3>,3>> q;\n    set<vector<int>> seen;\n    array<array<int,3>,3> id = {1,0,0, 0,1,0, 0,0,1};\n    q.push(id);\n    seen.insert({1,0,0, 0,1,0, 0,0,1});\n    \n    int rot_ops[3][3][3] = {\n        {{1,0,0},{0,0,-1},{0,1,0}},   // Rot X\n        {{0,0,1},{0,1,0},{-1,0,0}},   // Rot Y\n        {{0,-1,0},{1,0,0},{0,0,1}}    // Rot Z\n    };\n\n    while(!q.empty()) {\n        auto cur = q.front(); q.pop();\n        for(int i=0;i<3;i++) for(int j=0;j<3;j++) rots[cnt][i][j] = cur[i][j];\n        cnt++;\n        if(cnt >= 24) break;\n\n        for(auto& op : rot_ops) {\n            array<array<int,3>,3> nxt{};\n            for(int i=0;i<3;i++) for(int j=0;j<3;j++) {\n                nxt[i][j] = 0;\n                for(int k=0;k<3;k++) nxt[i][j] += cur[i][k] * op[k][j];\n            }\n            vector<int> vec;\n            for(auto& r : nxt) for(int v : r) vec.push_back(v);\n            if(seen.find(vec) == seen.end()) {\n                seen.insert(vec);\n                q.push(nxt);\n            }\n        }\n    }\n}\n\nlong double compute_score(int n, const int b1[14][14][14], const int b2[14][14][14], const vector<int>& vol) {\n    long double r1 = 0, r2 = 0, sum_inv = 0;\n    for(int i=1; i<=n; i++) {\n        bool u1 = false, u2 = false;\n        for(int x=0; x<D && !u1; x++) for(int y=0; y<D && !u1; y++) for(int z=0; z<D; z++) if(b1[x][y][z]==i) u1=true;\n        for(int x=0; x<D && !u2; x++) for(int y=0; y<D && !u2; y++) for(int z=0; z<D; z++) if(b2[x][y][z]==i) u2=true;\n        \n        if(u1 && u2) sum_inv += 1.0 / vol[i];\n        else if(u1) r2 += vol[i];\n        else if(u2) r1 += vol[i];\n        else r1 += vol[i], r2 += vol[i];\n    }\n    return r1 + r2 + sum_inv;\n}\n\nbool check_fit(const vector<pair<int,int>>& shape, bool used[14][14][14], int rot_idx) {\n    int minx=14, miny=14, minz=14, maxx=-1, maxy=-1, maxz=-1;\n    vector<array<int,3>> rs(shape.size());\n    const auto& R = rots[rot_idx];\n    for(int k=0; k<shape.size(); k++) {\n        int x = shape[k].first, y = shape[k].second, z = shape[k].second; // placeholder, fix below\n    }\n    // Correct coordinate handling\n    struct Pt { int x,y,z; };\n    vector<Pt> rot_shape(shape.size());\n    for(int k=0; k<shape.size(); k++) {\n        auto [x,y,z] = shape[k];\n        // Wait, shape stores as pair<int,int> in my draft, let's fix struct.\n    }\n    return false; // Placeholder, implementation below\n}\n\n// Refined structures\nstruct Pt { int x,y,z; };\n\nbool try_place_block(const vector<Pt>& rel_shape, bool used[14][14][14]) {\n    for(int rot=0; rot<24; rot++) {\n        int minx=14, miny=14, minz=14, maxx=-1, maxy=-1, maxz=-1;\n        vector<Pt> rotated(rel_shape.size());\n        for(int k=0; k<rel_shape.size(); k++) {\n            const auto& p = rel_shape[k];\n            rotated[k] = {\n                rots[rot][0][0]*p.x + rots[rot][0][1]*p.y + rots[rot][0][2]*p.z,\n                rots[rot][1][0]*p.x + rots[rot][1][1]*p.y + rots[rot][1][2]*p.z,\n                rots[rot][2][0]*p.x + rots[rot][2][1]*p.y + rots[rot][2][2]*p.z\n            };\n            minx = min(minx, rotated[k].x); miny = min(miny, rotated[k].y); minz = min(minz, rotated[k].z);\n            maxx = max(maxx, rotated[k].x); maxy = max(maxy, rotated[k].y); maxz = max(maxz, rotated[k].z);\n        }\n        for(auto& p : rotated) { p.x -= minx; p.y -= miny; p.z -= minz; }\n        maxx -= minx; maxy -= miny; maxz -= minz;\n\n        for(int dx=0; dx <= D-1-maxx; dx++) {\n            for(int dy=0; dy <= D-1-maxy; dy++) {\n                for(int dz=0; dz <= D-1-maxz; dz++) {\n                    bool ok = true;\n                    for(const auto& p : rotated) {\n                        if(used[dx+p.x][dy+p.y][dz+p.z]) { ok = false; break; }\n                    }\n                    if(ok) return true;\n                }\n            }\n        }\n    }\n    return false;\n}\n\nvoid place_block(const vector<Pt>& rel_shape, bool used[14][14][14], int grid[14][14][14], int bid) {\n    for(int rot=0; rot<24; rot++) {\n        int minx=14, miny=14, minz=14, maxx=-1, maxy=-1, maxz=-1;\n        vector<Pt> rotated(rel_shape.size());\n        for(int k=0; k<rel_shape.size(); k++) {\n            const auto& p = rel_shape[k];\n            rotated[k] = {\n                rots[rot][0][0]*p.x + rots[rot][0][1]*p.y + rots[rot][0][2]*p.z,\n                rots[rot][1][0]*p.x + rots[rot][1][1]*p.y + rots[rot][1][2]*p.z,\n                rots[rot][2][0]*p.x + rots[rot][2][1]*p.y + rots[rot][2][2]*p.z\n            };\n            minx = min(minx, rotated[k].x); miny = min(miny, rotated[k].y); minz = min(minz, rotated[k].z);\n            maxx = max(maxx, rotated[k].x); maxy = max(maxy, rotated[k].y); maxz = max(maxz, rotated[k].z);\n        }\n        for(auto& p : rotated) { p.x -= minx; p.y -= miny; p.z -= minz; }\n        maxx -= minx; maxy -= miny; maxz -= minz;\n\n        for(int dx=0; dx <= D-1-maxx; dx++) {\n            for(int dy=0; dy <= D-1-maxy; dy++) {\n                for(int dz=0; dz <= D-1-maxz; dz++) {\n                    bool ok = true;\n                    for(const auto& p : rotated) if(used[dx+p.x][dy+p.y][dz+p.z]) ok = false;\n                    if(ok) {\n                        for(const auto& p : rotated) {\n                            used[dx+p.x][dy+p.y][dz+p.z] = true;\n                            grid[dx+p.x][dy+p.y][dz+p.z] = bid;\n                        }\n                        return;\n                    }\n                }\n            }\n        }\n    }\n}\n\nvoid run_search(mt19937_64& rng) {\n    static bool g1[14][14][14], g2[14][14][14];\n    static int cur_b1[14][14][14], cur_b2[14][14][14];\n    static vector<int> cur_vol;\n    \n    memcpy(g1, A[0], sizeof(g1));\n    memcpy(g2, A[1], sizeof(g2));\n    memset(cur_b1, 0, sizeof(cur_b1));\n    memset(cur_b2, 0, sizeof(cur_b2));\n    cur_vol.clear();\n    int n = 0;\n    \n    vector<Pt> free1, free2;\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++) {\n        if(g1[x][y][z]) free1.push_back({x,y,z});\n        if(g2[x][y][z]) free2.push_back({x,y,z});\n    }\n\n    auto shuffle_vec = [&](vector<Pt>& v) {\n        shuffle(v.begin(), v.end(), rng);\n    };\n    shuffle_vec(free1); shuffle_vec(free2);\n\n    // Greedy shared packing\n    int max_iters = 3000;\n    while(max_iters-- > 0 && !free1.empty() && !free2.empty()) {\n        Pt seed = free1[rng() % free1.size()];\n        if(!g1[seed.x][seed.y][seed.z]) continue;\n\n        vector<Pt> shape = {seed};\n        g1[seed.x][seed.y][seed.z] = false;\n        bool ok = false;\n\n        // Try growing\n        for(int step=0; step<20; step++) {\n            vector<Pt> candidates;\n            for(const auto& p : shape) {\n                const int dirs[6][3] = {{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}};\n                for(auto& d : dirs) {\n                    int nx=p.x+d[0], ny=p.y+d[1], nz=p.z+d[2];\n                    if(nx>=0 && nx<D && ny>=0 && ny<D && nz>=0 && nz<D && g1[nx][ny][nz]) {\n                        bool exists = false;\n                        for(const auto& q : shape) if(q.x==nx && q.y==ny && q.z==nz) exists=true;\n                        if(!exists) candidates.push_back({nx,ny,nz});\n                    }\n                }\n            }\n            if(candidates.empty()) { ok = true; break; }\n            Pt next = candidates[rng() % candidates.size()];\n            shape.push_back(next);\n            g1[next.x][next.y][next.z] = false;\n            if(!try_place_block(shape, g2)) {\n                // Backtrack\n                g1[next.x][next.y][next.z] = true;\n                shape.pop_back();\n                break;\n            }\n        }\n        if(shape.empty()) continue;\n        ok = true;\n        if(!try_place_block(shape, g2)) {\n            // Restore\n            for(const auto& p : shape) g1[p.x][p.y][p.z] = true;\n            continue;\n        }\n\n        n++;\n        cur_vol.push_back(shape.size());\n        place_block(shape, g2, cur_b2, n); // Place in g2 (marks used)\n        // Mark in g1 and place in cur_b1\n        for(const auto& p : shape) {\n            cur_b1[p.x][p.y][p.z] = n;\n        }\n    }\n\n    // Fill remaining with connected components\n    auto fill_remaining = [&](bool grid[14][14][14], int b[14][14][14]) {\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(!grid[x][y][z]) continue;\n                    n++;\n                    cur_vol.push_back(0);\n                    vector<Pt> q = {{x,y,z}};\n                    grid[x][y][z] = false;\n                    b[x][y][z] = n;\n                    cur_vol.back()++;\n                    int head = 0;\n                    while(head < q.size()) {\n                        Pt cur = q[head++];\n                        const int dirs[6][3] = {{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}};\n                        for(auto& d : dirs) {\n                            int nx=cur.x+d[0], ny=cur.y+d[1], nz=cur.z+d[2];\n                            if(nx>=0 && nx<D && ny>=0 && ny<D && nz>=0 && nz<D && grid[nx][ny][nz]) {\n                                grid[nx][ny][nz] = false;\n                                b[nx][ny][nz] = n;\n                                cur_vol.back()++;\n                                q.push_back({nx,ny,nz});\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    };\n    fill_remaining(g1, cur_b1);\n    fill_remaining(g2, cur_b2);\n\n    long double sc = compute_score(n, cur_b1, cur_b2, cur_vol);\n    if(sc < best_score) {\n        best_score = sc;\n        best_n = n;\n        memcpy(best_b1, cur_b1, sizeof(cur_b1));\n        memcpy(best_b2, cur_b2, sizeof(cur_b2));\n        best_vol = cur_vol;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(0); cin.tie(0);\n    cin >> D;\n    string s;\n    for(int k=0; k<2; k++) {\n        for(int z=0; z<D; z++) { cin >> s; for(int x=0; x<D; x++) if(s[x]=='1') A[k][z][x] = true; } // f(z,x)\n        for(int z=0; z<D; z++) { cin >> s; for(int y=0; y<D; y++) if(s[y]=='1') A[k][z][y] = true; } // r(z,y) -> wait\n    }\n    // Correct mapping based on problem:\n    // f_i(z,x): z rows, x cols. input gives D strings. each string length D.\n    // r_i(z,y): z rows, y cols.\n    // b(x,y,z)=1 if occupied.\n    // Silhouette constraints: b(x,y,z) can be 1 only if f(z,x)=1 and r(z,y)=1.\n    // So A[k][x][y][z] = f[k][z][x] && r[k][z][y]\n    \n    // Re-read input correctly\n    // Actually input gives f then r for each k.\n    // Let's store them temporarily\n    bool F[2][14][14], R[2][14][14];\n    for(int k=0; k<2; k++) {\n        for(int z=0; z<D; z++) { cin >> s; for(int x=0; x<D; x++) F[k][z][x] = (s[x]=='1'); }\n        for(int z=0; z<D; z++) { cin >> s; for(int y=0; y<D; y++) R[k][z][y] = (s[y]=='1'); }\n        for(int z=0; z<D; z++) for(int x=0; x<D; x++) for(int y=0; y<D; y++)\n            A[k][x][y][z] = (F[k][z][x] && R[k][z][y]);\n    }\n\n    gen_rots();\n\n    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n    auto start = chrono::steady_clock::now();\n    while(chrono::duration<double>(chrono::steady_clock::now() - start).count() < 5.5) {\n        run_search(rng);\n    }\n\n    cout << best_n << \"\\n\";\n    for(int iter=0; iter<2; iter++) {\n        for(int x=0; x<D; x++) {\n            for(int y=0; y<D; y++) {\n                for(int z=0; z<D; z++) {\n                    cout << (iter==0 ? best_b1[x][y][z] : best_b2[x][y][z]) << (z==D-1 ? \"\" : \" \");\n                }\n            }\n        }\n        cout << \"\\n\";\n    }\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nusing ld = long double;\n\nstruct Point { int x, y; };\nstruct Edge { int u, v; ll w; int id; };\n\nint main() {\n    cin.tie(nullptr)->sync_with_stdio(false);\n    mt19937_64 rng(12345);\n\n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n\n    vector<Point> pts(N);\n    for (int i = 0; i < N; ++i) cin >> pts[i].x >> pts[i].y;\n\n    vector<Edge> edges(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> edges[i].u >> edges[i].v >> edges[i].w;\n        --edges[i].u; --edges[i].v;\n        edges[i].id = i;\n    }\n\n    vector<Point> residents(K);\n    for (int i = 0; i < K; ++i) cin >> residents[i].x >> residents[i].y;\n\n    // Precompute Euclidean distances\n    vector<vector<ld>> dist_v_r(N, vector<ld>(K));\n    for (int i = 0; i < N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            dist_v_r[i][k] = hypot(pts[i].x - residents[k].x, pts[i].y - residents[k].y);\n        }\n    }\n\n    // State variables\n    vector<bool> active(N, true);\n    vector<int> assign(K, 0);\n    vector<vector<int>> res_in(N);\n    vector<ld> max_dist(N, 0.0);\n    ll edge_cost = 0;\n    vector<bool> edge_used(M, false);\n\n    auto compute_mst = [&](const vector<bool>& act) -> ll {\n        vector<int> parent(N);\n        iota(parent.begin(), parent.end(), 0);\n        function<int(int)> find = [&](int x) {\n            return x == parent[x] ? x : parent[x] = find(parent[x]);\n        };\n        auto unite = [&](int x, int y) {\n            x = find(x); y = find(y);\n            if (x != y) { parent[x] = y; return true; }\n            return false;\n        };\n\n        ll cost = 0;\n        int comps = 0;\n        vector<bool> used(M, false);\n        int active_cnt = 0;\n        for (int i = 0; i < N; ++i) if (act[i]) active_cnt++;\n\n        // Sort edges by weight once\n        static vector<int> sorted_ids(M);\n        static bool sorted = false;\n        if (!sorted) {\n            iota(sorted_ids.begin(), sorted_ids.end(), 0);\n            sort(sorted_ids.begin(), sorted_ids.end(), [&](int a, int b) { return edges[a].w < edges[b].w; });\n            sorted = true;\n        }\n\n        for (int idx : sorted_ids) {\n            if (act[edges[idx].u] && act[edges[idx].v]) {\n                if (unite(edges[idx].u, edges[idx].v)) {\n                    cost += edges[idx].w;\n                    used[idx] = true;\n                    if (++comps == active_cnt - 1) break;\n                }\n            }\n        }\n        edge_used = used;\n        return cost;\n    };\n\n    auto check_connectivity = [&](const vector<bool>& act) -> bool {\n        if (!act[0]) return false;\n        int active_cnt = 0, vis_cnt = 0;\n        vector<bool> vis(N, false);\n        vector<int> q; q.reserve(N);\n        q.push_back(0); vis[0] = true; vis_cnt = 1;\n\n        for (int i = 0; i < N; ++i) if (act[i]) active_cnt++;\n\n        int head = 0;\n        while (head < (int)q.size()) {\n            int u = q[head++];\n            for (const auto& e : edges) {\n                int v = (e.u == u) ? e.v : e.u;\n                if (v != u && act[v] && !vis[v] && (e.u == u || e.v == u)) { // ensure edge connects u and v\n                    // Actually edges list contains both directions? No, undirected.\n                    // Check if edge connects u and v\n                    if ((e.u == u && e.v == v) || (e.u == v && e.v == u)) {\n                        vis[v] = true; vis_cnt++; q.push_back(v);\n                    }\n                }\n            }\n        }\n        // More efficient edge lookup: precompute adj\n        return vis_cnt == active_cnt;\n    };\n    // Precompute adj for fast connectivity check\n    vector<vector<pair<int, int>>> adj(N); // u -> (v, edge_index)\n    for (int i = 0; i < M; ++i) {\n        adj[edges[i].u].emplace_back(edges[i].v, i);\n        adj[edges[i].v].emplace_back(edges[i].u, i);\n    }\n    auto check_conn_fast = [&](const vector<bool>& act) -> bool {\n        if (!act[0]) return false;\n        int active_cnt = 0, vis_cnt = 0;\n        vector<bool> vis(N, false);\n        vector<int> q; q.reserve(N);\n        q.push_back(0); vis[0] = true; vis_cnt = 1;\n        for (int i = 0; i < N; ++i) if (act[i]) active_cnt++;\n\n        int head = 0;\n        while (head < (int)q.size()) {\n            int u = q[head++];\n            for (auto [v, id] : adj[u]) {\n                if (act[v] && !vis[v]) {\n                    vis[v] = true; vis_cnt++; q.push_back(v);\n                }\n            }\n        }\n        return vis_cnt == active_cnt;\n    };\n\n    // Initial assignment\n    for (int k = 0; k < K; ++k) {\n        int best_u = 0; ld best_d = dist_v_r[0][k];\n        for (int i = 1; i < N; ++i) {\n            if (dist_v_r[i][k] < best_d) { best_d = dist_v_r[i][k]; best_u = i; }\n        }\n        assign[k] = best_u;\n        res_in[best_u].push_back(k);\n    }\n    for (int i = 0; i < N; ++i) {\n        for (int k : res_in[i]) max_dist[i] = max(max_dist[i], dist_v_r[i][k]);\n    }\n    edge_cost = compute_mst(active);\n    ld cur_S = edge_cost;\n    for (int i = 0; i < N; ++i) if (active[i]) cur_S += max_dist[i] * max_dist[i];\n\n    ld best_S = cur_S;\n    vector<bool> best_active = active;\n    vector<int> best_assign = assign;\n    vector<vector<int>> best_res_in = res_in;\n    vector<ld> best_max_dist = max_dist;\n    ll best_edge_cost = edge_cost;\n\n    auto auto_now = [&]() { return chrono::steady_clock::now(); };\n    auto start = auto_now();\n    const double time_limit = 1.85;\n    double T = 1e7;\n    int steps = 0;\n    const int max_steps = 50000;\n\n    vector<int> changed_residents; changed_residents.reserve(K);\n\n    while (steps < max_steps) {\n        if ((auto_now() - start).count() / 1e9 > time_limit) break;\n\n        int v = uniform_int_distribution<>(1, N-1)(rng);\n        bool was_active = active[v];\n        changed_residents.clear();\n\n        // Apply move tentatively\n        active[v] = !was_active;\n        if (!check_conn_fast(active)) {\n            active[v] = was_active; // Revert immediately\n            steps++; continue;\n        }\n\n        ld delta_P2 = 0.0;\n        if (was_active) { // Remove v\n            // Reassign residents previously at v\n            vector<int> moved = res_in[v];\n            res_in[v].clear();\n            delta_P2 -= max_dist[v] * max_dist[v];\n            max_dist[v] = 0.0;\n\n            for (int k : moved) {\n                int best_u = -1; ld best_d = 1e18;\n                for (int u = 0; u < N; ++u) {\n                    if (active[u] && dist_v_r[u][k] < best_d) {\n                        best_d = dist_v_r[u][k]; best_u = u;\n                    }\n                }\n                assign[k] = best_u;\n                res_in[best_u].push_back(k);\n                max_dist[best_u] = max(max_dist[best_u], best_d);\n                changed_residents.push_back(k);\n            }\n            // Recompute affected max_dist accurately\n            vector<int> affected;\n            for (int k : moved) affected.push_back(assign[k]);\n            sort(affected.begin(), affected.end()); affected.erase(unique(affected.begin(), affected.end()), affected.end());\n            for (int u : affected) {\n                ld md = 0.0;\n                for (int k : res_in[u]) md = max(md, dist_v_r[u][k]);\n                delta_P2 += md * md; // Will be added to old later\n                // Actually simpler: just track new sum vs old sum\n            }\n        } else { // Add v\n            // Check if v can steal residents\n            for (int k = 0; k < K; ++k) {\n                ld d = dist_v_r[v][k];\n                if (d < dist_v_r[assign[k]][k]) {\n                    int old_u = assign[k];\n                    // Remove k from old_u\n                    auto& lst = res_in[old_u];\n                    lst.erase(remove(lst.begin(), lst.end(), k), lst.end());\n                    \n                    assign[k] = v;\n                    res_in[v].push_back(k);\n                    changed_residents.push_back(k);\n                }\n            }\n        }\n\n        // Recompute max_dist and P^2 cost for affected vertices\n        ld new_P2 = 0.0;\n        vector<int> to_recalc;\n        for (int k : changed_residents) {\n            to_recalc.push_back(assign[k]);\n            if (!was_active) to_recalc.push_back(v); // Also check new vertex\n        }\n        sort(to_recalc.begin(), to_recalc.end()); to_recalc.erase(unique(to_recalc.begin(), to_recalc.end()), to_recalc.end());\n\n        for (int u : to_recalc) {\n            ld md = 0.0;\n            for (int k : res_in[u]) md = max(md, dist_v_r[u][k]);\n            max_dist[u] = md;\n            new_P2 += md * md;\n        }\n        // Add unaffected vertices\n        for (int u = 0; u < N; ++u) {\n            if (find(to_recalc.begin(), to_recalc.end(), u) == to_recalc.end()) {\n                if (active[u]) new_P2 += max_dist[u] * max_dist[u];\n            }\n        }\n\n        ll new_E = compute_mst(active);\n        ld new_S = new_E + new_P2;\n\n        bool accept = false;\n        if (new_S < cur_S) accept = true;\n        else if (uniform_real_distribution<ld>(0, 1)(rng) < exp(-(new_S - cur_S) / T)) accept = true;\n\n        if (accept) {\n            cur_S = new_S;\n            edge_cost = new_E;\n            if (cur_S < best_S) {\n                best_S = cur_S;\n                best_active = active;\n                best_assign = assign;\n                best_res_in = res_in;\n                best_max_dist = max_dist;\n                best_edge_cost = edge_cost;\n            }\n        } else {\n            // Rollback\n            active[v] = was_active;\n            compute_mst(active); // Restore edge_used\n            // We don't fully rollback arrays to save time; next iteration will overwrite correctly\n            // But to be safe, we recalc state from best occasionally or just continue.\n            // For robustness, we re-sync if we reject too many times, but SA is resilient.\n            // Here we just let it be; next accepted state will be valid.\n            // To prevent drift, we'll occasionally reset to best.\n        }\n        steps++;\n        T *= 0.99985;\n        \n        // Occasional reset to prevent getting stuck in invalid drift\n        if (steps % 2000 == 0) {\n            active = best_active;\n            assign = best_assign;\n            res_in = best_res_in;\n            max_dist = best_max_dist;\n            edge_cost = best_edge_cost;\n            cur_S = best_S;\n        }\n    }\n\n    // Final cleanup & output\n    active = best_active;\n    assign = best_assign;\n    res_in = best_res_in;\n    max_dist = best_max_dist;\n    compute_mst(active);\n\n    cout << fixed << setprecision(0);\n    for (int i = 0; i < N; ++i) {\n        if (!active[i]) { cout << 0 << (i == N-1 ? \"\" : \" \"); continue; }\n        int p = (int)ceil(max_dist[i]);\n        if (p < 0) p = 0;\n        if (p > 5000) p = 5000; // Safety clamp\n        cout << p << (i == N-1 ? \"\" : \" \");\n    }\n    cout << \"\\n\";\n    for (int i = 0; i < M; ++i) {\n        cout << (edge_used[i] ? 1 : 0) << (i == M-1 ? \"\" : \" \");\n    }\n    cout << \"\\n\";\n\n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <array>\n#include <utility>\n\nusing namespace std;\n\nint main() {\n    // Optimize I/O operations\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 30;\n    // Grid to store ball values. grid[x][y] holds the value at tier x, position y.\n    vector<vector<int>> grid(N, vector<int>(N));\n\n    // Read input\n    for (int x = 0; x < N; ++x) {\n        for (int y = 0; y <= x; ++y) {\n            cin >> grid[x][y];\n        }\n    }\n\n    // Store swap operations\n    vector<array<int, 4>> ops;\n    ops.reserve(5000); // Reserve reasonable memory to avoid reallocations\n\n    // Bottom-up heapify: process from second last tier up to the top\n    for (int x = N - 2; x >= 0; --x) {\n        for (int y = 0; y <= x; ++y) {\n            int cx = x, cy = y;\n            // Sift down the current node until it satisfies the min-heap property\n            while (cx < N - 1) {\n                int child1_val = grid[cx + 1][cy];\n                int child2_val = grid[cx + 1][cy + 1];\n                \n                // Find the smaller child\n                int target_y = cy;\n                if (child2_val < child1_val) {\n                    target_y = cy + 1;\n                }\n\n                // If current node is larger than the smaller child, swap them\n                if (grid[cx][cy] > grid[cx + 1][target_y]) {\n                    swap(grid[cx][cy], grid[cx + 1][target_y]);\n                    ops.push_back({cx, cy, cx + 1, target_y});\n                    // Move down to continue sifting\n                    cx++;\n                    cy = target_y;\n                } else {\n                    // Heap property satisfied for this branch\n                    break;\n                }\n            }\n        }\n    }\n\n    // Output results\n    cout << ops.size() << \"\\n\";\n    for (const auto& op : ops) {\n        cout << op[0] << \" \" << op[1] << \" \" << op[2] << \" \" << op[3] << \"\\n\";\n    }\n\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D, N;\nint grid[10][10]; // 0: empty, -1: obstacle, -2: entrance, >0: container (id+1)\nint dr[4] = {-1, 1, 0, 0};\nint dc[4] = {0, 0, -1, 1};\npair<int, int> placed[100]; // placed[id] = {r, c}\n\nbool valid(int r, int c) {\n    return r >= 0 && r < D && c >= 0 && c < D;\n}\n\nint empty_neighbors(int r, int c) {\n    int cnt = 0;\n    for (int i = 0; i < 4; i++) {\n        int nr = r + dr[i], nc = c + dc[i];\n        if (valid(nr, nc) && grid[nr][nc] == 0) cnt++;\n    }\n    return cnt;\n}\n\nint main() {\n    // Interactive problems often work better without full sync off, \n    // but we manually flush anyway.\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> D >> N;\n    int er = 0, ec = (D - 1) / 2;\n    \n    for (int i = 0; i < D; i++) fill(grid[i], grid[i] + D, 0);\n    grid[er][ec] = -2; // Mark entrance\n    \n    for (int i = 0; i < N; i++) {\n        int r, c; cin >> r >> c;\n        grid[r][c] = -1;\n    }\n\n    int M = D * D - 1 - N; // Total containers to place\n    \n    // Placement Phase\n    for (int d = 0; d < M; d++) {\n        int t; cin >> t;\n        \n        // BFS to find reachable empty squares and compute distances\n        vector<tuple<int, int, int, int>> reach; // (distance, degree, r, c)\n        bool vis[10][10] = {};\n        queue<tuple<int, int, int>> q; // r, c, dist\n        q.push({er, ec, 0});\n        vis[er][ec] = true;\n\n        while (!q.empty()) {\n            auto [r, c, dist] = q.front(); q.pop();\n            for (int i = 0; i < 4; i++) {\n                int nr = r + dr[i], nc = c + dc[i];\n                if (valid(nr, nc) && !vis[nr][nc] && grid[nr][nc] == 0) {\n                    vis[nr][nc] = true;\n                    reach.emplace_back(dist + 1, empty_neighbors(nr, nc), nr, nc);\n                    q.push({nr, nc, dist + 1});\n                }\n            }\n        }\n\n        // Sort by distance (asc), then by empty neighbors (asc) to fill dead-ends first\n        sort(reach.begin(), reach.end());\n\n        // Map ID t to a position in the sorted list\n        int idx = 0;\n        if (M > 1) idx = (int)((long long)t * (reach.size() - 1) / (M - 1));\n        if (idx >= (int)reach.size()) idx = reach.size() - 1;\n\n        auto [dist, deg, pr, pc] = reach[idx];\n        placed[t] = {pr, pc};\n        grid[pr][pc] = t + 1;\n        cout << pr << \" \" << pc << \"\\n\" << flush;\n    }\n\n    // Retrieval Phase\n    vector<bool> retrieved(M, false);\n    for (int k = 0; k < M; k++) {\n        // BFS to find all reachable empty squares + entrance\n        bool is_reach[10][10] = {};\n        bool vis[10][10] = {};\n        queue<pair<int, int>> q;\n        q.push({er, ec});\n        vis[er][ec] = true;\n        is_reach[er][ec] = true;\n\n        while (!q.empty()) {\n            auto [r, c] = q.front(); q.pop();\n            for (int i = 0; i < 4; i++) {\n                int nr = r + dr[i], nc = c + dc[i];\n                if (valid(nr, nc) && !vis[nr][nc] && grid[nr][nc] == 0) {\n                    vis[nr][nc] = true;\n                    is_reach[nr][nc] = true;\n                    q.push({nr, nc});\n                }\n            }\n        }\n\n        // Greedily pick the smallest ID that is adjacent to a reachable empty square\n        int best_id = -1;\n        pair<int, int> best_pos = {-1, -1};\n        \n        for (int id = 0; id < M; id++) {\n            if (retrieved[id]) continue;\n            auto [r, c] = placed[id];\n            bool reachable = false;\n            for (int i = 0; i < 4; i++) {\n                int nr = r + dr[i], nc = c + dc[i];\n                if (valid(nr, nc) && is_reach[nr][nc]) {\n                    reachable = true;\n                    break;\n                }\n            }\n            if (reachable) {\n                best_id = id;\n                best_pos = {r, c};\n                break; // Since we iterate in increasing order, first match is minimal ID\n            }\n        }\n\n        retrieved[best_id] = true;\n        grid[best_pos.first][best_pos.second] = 0; // Free up the square\n        cout << best_pos.first << \" \" << best_pos.second << \"\\n\" << flush;\n    }\n\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 52;\nconst int MAXM = 101;\n\nint grid[MAXN][MAXN];\nint contacts[MAXM][MAXM] = {0};\nbool adj_target[MAXM][MAXM] = {false};\nint n, m;\n\n// BFS to check if all 0-cells are connected to the boundary (and thus to the outside)\nbool is_zero_connected() {\n    int zero_cnt = 0;\n    for (int i = 0; i <= n + 1; ++i)\n        for (int j = 0; j <= n + 1; ++j)\n            if (grid[i][j] == 0) zero_cnt++;\n    if (zero_cnt == 0) return true;\n\n    static int q[MAXN * MAXN][2];\n    static bool vis[MAXN][MAXN];\n    int head = 0, tail = 0;\n    memset(vis, 0, sizeof(vis));\n\n    // Start from (0,0), which is always 0 due to padding\n    vis[0][0] = true;\n    q[tail][0] = 0; q[tail][1] = 0; tail++;\n    int cnt = 0;\n    const int dirs[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};\n    \n    while (head < tail) {\n        int r = q[head][0], c = q[head][1]; head++; cnt++;\n        for (auto& d : dirs) {\n            int nr = r + d[0], nc = c + d[1];\n            if (nr >= 0 && nr <= n + 1 && nc >= 0 && nc <= n + 1 && \n                grid[nr][nc] == 0 && !vis[nr][nc]) {\n                vis[nr][nc] = true;\n                q[tail][0] = nr; q[tail][1] = nc; tail++;\n            }\n        }\n    }\n    return cnt == zero_cnt;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> n >> m;\n    memset(grid, 0, sizeof(grid)); // Initialize border with 0\n    for (int i = 1; i <= n; ++i)\n        for (int j = 1; j <= n; ++j)\n            cin >> grid[i][j];\n\n    const int dirs[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};\n    \n    // Compute initial adjacency targets and contact counts on padded grid\n    for (int i = 0; i <= n + 1; ++i) {\n        for (int j = 0; j <= n + 1; ++j) {\n            for (int k = 0; k < 2; ++k) { // Check right and down to avoid double counting\n                int ni = i + (k == 1), nj = j + (k == 0);\n                if (ni <= n + 1 && nj <= n + 1) {\n                    int u = grid[i][j], v = grid[ni][nj];\n                    if (u != v) {\n                        if (u > v) swap(u, v);\n                        contacts[u][v]++;\n                        adj_target[u][v] = adj_target[v][u] = true;\n                    }\n                }\n            }\n        }\n    }\n\n    vector<pair<int, int>> zeros;\n    for (int i = 1; i <= n; ++i)\n        for (int j = 1; j <= n; ++j)\n            if (grid[i][j] == 0) zeros.emplace_back(i, j);\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    auto start_time = chrono::steady_clock::now();\n\n    for (int iter = 0; iter < 20; ++iter) {\n        // Time guard\n        if (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() > 1850) break;\n        \n        shuffle(zeros.begin(), zeros.end(), rng);\n        bool changed = false;\n\n        for (auto& [r, c] : zeros) {\n            if (grid[r][c] != 0) continue;\n\n            int zero_nb = 0;\n            for (auto& d : dirs) {\n                if (grid[r + d[0]][c + d[1]] == 0) zero_nb++;\n            }\n\n            // Collect unique neighboring colors\n            vector<int> cands;\n            for (auto& d : dirs) {\n                int x = grid[r + d[0]][c + d[1]];\n                if (x != 0) {\n                    if (find(cands.begin(), cands.end(), x) == cands.end())\n                        cands.push_back(x);\n                }\n            }\n            if (cands.empty()) continue;\n\n            for (int col : cands) {\n                // 1. Check forbidden adjacencies\n                bool bad = false;\n                for (auto& d : dirs) {\n                    int x = grid[r + d[0]][c + d[1]];\n                    if (x != 0 && x != col && !adj_target[col][x]) {\n                        bad = true; break;\n                    }\n                }\n                if (bad) continue;\n\n                // 2. Tentatively update contact counts\n                vector<pair<int, int>> dec_c, inc_c;\n                for (auto& d : dirs) {\n                    int x = grid[r + d[0]][c + d[1]];\n                    if (x == 0) continue;\n                    dec_c.emplace_back(min(0, x), max(0, x));\n                    inc_c.emplace_back(min(col, x), max(col, x));\n                }\n\n                bool dropped_req = false;\n                for (auto& p : dec_c) {\n                    if (--contacts[p.first][p.second] == 0 && adj_target[p.first][p.second]) {\n                        dropped_req = true;\n                    }\n                    if (dropped_req) break;\n                }\n                if (dropped_req) {\n                    for (auto& p : dec_c) contacts[p.first][p.second]++;\n                    continue;\n                }\n                for (auto& p : inc_c) contacts[p.first][p.second]++;\n\n                // 3. Check 0-connectivity (skip if safe by graph property)\n                bool conn_ok = true;\n                if (zero_nb > 1) {\n                    grid[r][c] = col;\n                    conn_ok = is_zero_connected();\n                    grid[r][c] = 0;\n                }\n\n                if (conn_ok) {\n                    grid[r][c] = col; // Commit change\n                    changed = true;\n                } else {\n                    // Revert contacts\n                    for (auto& p : inc_c) contacts[p.first][p.second]--;\n                    for (auto& p : dec_c) contacts[p.first][p.second]++;\n                }\n            }\n        }\n\n        // Update zeros list for next iteration\n        zeros.clear();\n        for (int i = 1; i <= n; ++i)\n            for (int j = 1; j <= n; ++j)\n                if (grid[i][j] == 0) zeros.emplace_back(i, j);\n                \n        if (!changed) break; // Local optimum reached\n    }\n\n    // Output result\n    for (int i = 1; i <= n; ++i) {\n        for (int j = 1; j <= n; ++j) {\n            cout << grid[i][j] << (j == n ? \"\\n\" : \" \");\n        }\n    }\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <string>\n\nusing namespace std;\n\nint main() {\n    // Optimize I/O operations\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, D, Q;\n    if (!(cin >> N >> D >> Q)) return 0;\n\n    // Current permutation of items, initially [0, 1, ..., N-1]\n    vector<int> p(N);\n    iota(p.begin(), p.end(), 0);\n    \n    // Score array to estimate relative weights\n    vector<double> score(N, 0.0);\n\n    // Perform exactly Q comparisons using a sorting-network-like pass\n    while (Q > 0) {\n        for (int i = 0; i < N - 1 && Q > 0; ++i) {\n            // Query: compare p[i] and p[i+1]\n            cout << \"1 1 \" << p[i] << \" \" << p[i+1] << \"\\n\";\n            cout.flush();\n            \n            string res;\n            cin >> res;\n            Q--;\n\n            // If left is lighter, swap to maintain descending order of estimated weight\n            if (res == \"<\") {\n                swap(p[i], p[i+1]);\n            }\n            \n            // Update scores: heavier gets +1, lighter gets -1\n            // After potential swap, p[i] is always the heavier (or equal) one\n            score[p[i]] += 1.0;\n            score[p[i+1]] -= 1.0;\n        }\n    }\n\n    // Sort items by their accumulated score (descending)\n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n    sort(items.begin(), items.end(), [&](int a, int b) {\n        return score[a] > score[b];\n    });\n\n    // Greedy partition into D sets\n    // bin_weight tracks the current total weight proxy of each bin\n    vector<double> bin_weight(D, 0.0);\n    vector<int> ans(N);\n    \n    for (int item : items) {\n        int best_d = 0;\n        double min_w = bin_weight[0];\n        for (int d = 1; d < D; ++d) {\n            if (bin_weight[d] < min_w) {\n                min_w = bin_weight[d];\n                best_d = d;\n            }\n        }\n        ans[item] = best_d;\n        bin_weight[best_d] += 1.0; // Proxy weight; order matters more than exact value\n    }\n\n    // Output the final assignment\n    for (int i = 0; i < N; ++i) {\n        cout << ans[i] << (i == N - 1 ? \"\" : \" \");\n    }\n    cout << \"\\n\";\n    cout.flush();\n\n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\nstruct State {\n    int n, m;\n    vector<vector<int>> stacks;\n    vector<pair<int, int>> pos; // box -> {stack_idx, index}\n    vector<int> ops_v, ops_i;\n    long long energy = 0;\n    int op_count = 0;\n\n    void init(int n, int m, const vector<vector<int>>& input_stacks) {\n        this->n = n;\n        this->m = m;\n        stacks = input_stacks;\n        pos.assign(n + 1, {-1, -1});\n        for (int i = 0; i < m; ++i) {\n            for (int j = 0; j < (int)stacks[i].size(); ++j) {\n                pos[stacks[i][j]] = {i, j};\n            }\n        }\n    }\n\n    void move_box(int v, int dest_stack) {\n        auto [src_stack, idx] = pos[v];\n        int chunk_size = stacks[src_stack].size() - idx;\n        energy += chunk_size + 1;\n        op_count++;\n        ops_v.push_back(v);\n        ops_i.push_back(dest_stack + 1); // 1-indexed output\n\n        vector<int> chunk;\n        chunk.reserve(chunk_size);\n        for (int k = idx; k < (int)stacks[src_stack].size(); ++k) {\n            chunk.push_back(stacks[src_stack][k]);\n        }\n\n        // Update destination\n        for (int box : chunk) {\n            pos[box] = {dest_stack, (int)stacks[dest_stack].size()};\n            stacks[dest_stack].push_back(box);\n        }\n\n        // Remove from source: keep elements 0..idx\n        stacks[src_stack].resize(idx + 1);\n    }\n\n    void remove_box(int v) {\n        op_count++;\n        ops_v.push_back(v);\n        ops_i.push_back(0);\n        auto [src, idx] = pos[v];\n        stacks[src].pop_back();\n        pos[v] = {-1, -1}; \n    }\n\n    int get_top(int s) const {\n        if (stacks[s].empty()) return 2000000;\n        return stacks[s].back();\n    }\n};\n\nint find_dest(const State& state, int u, int src, int next_target) {\n    int best_dest = -1;\n    int best_top = -1;\n    bool found_gt = false;\n    bool best_covers_next = false;\n\n    for (int i = 0; i < state.m; ++i) {\n        if (i == src) continue;\n        int top_val = state.get_top(i);\n        bool is_good = top_val > u;\n        bool covers_next = (top_val == next_target);\n\n        if (best_dest == -1) {\n            best_dest = i;\n            best_top = top_val;\n            found_gt = is_good;\n            best_covers_next = covers_next;\n        } else {\n            bool cur_good = is_good;\n            bool cur_covers = covers_next;\n\n            bool better = false;\n            // Priority 1: Prefer top > u to maintain decreasing order\n            if (cur_good && !found_gt) {\n                better = true;\n            } else if (cur_good == found_gt) {\n                // Priority 2: Avoid covering next_target\n                if (!cur_covers && best_covers_next) {\n                    better = true;\n                } else if (cur_covers == best_covers_next) {\n                    // Priority 3: If good (top > u), prefer smallest top to pack tightly\n                    //           If not good (top < u), prefer largest top to cover a less urgent number\n                    if (cur_good) {\n                        if (top_val < best_top) better = true;\n                    } else {\n                        if (top_val > best_top) better = true;\n                    }\n                }\n            }\n            if (better) {\n                best_dest = i;\n                best_top = top_val;\n                found_gt = cur_good;\n                best_covers_next = cur_covers;\n            }\n        }\n    }\n    // Fallback if somehow not set\n    if (best_dest == -1) {\n        for (int i = 0; i < state.m; ++i) {\n            if (i != src) {\n                best_dest = i;\n                break;\n            }\n        }\n    }\n    return best_dest;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; ++i) {\n        for (int j = 0; j < n / m; ++j) {\n            int x; cin >> x;\n            stacks[i].push_back(x);\n        }\n    }\n\n    State S;\n    S.init(n, m, stacks);\n\n    for (int v = 1; v <= n; ++v) {\n        while (true) {\n            auto [src, idx] = S.pos[v];\n            if (src == -1) break; // Already removed or not found\n            if (idx == (int)S.stacks[src].size() - 1) {\n                S.remove_box(v);\n                break;\n            } else {\n                int u = S.stacks[src][idx + 1];\n                int dest = find_dest(S, u, src, v + 1);\n                S.move_box(u, dest);\n            }\n        }\n    }\n\n    for (int k = 0; k < S.op_count; ++k) {\n        cout << S.ops_v[k] << \" \" << S.ops_i[k] << \"\\n\";\n    }\n\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\nvector<vector<int>> children;\nvector<bool> vis;\nvector<int> c, extra;\nstring res;\n\n// Check if move from (i,j) to (ni,nj) is valid (no wall)\nbool can_move(int i, int j, int ni, int nj) {\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    if (ni == i + 1 && nj == j) return h[i][j] == '0';\n    if (ni == i - 1 && nj == j) return h[ni][j] == '0';\n    if (ni == i && nj == j + 1) return v[i][j] == '0';\n    if (ni == i && nj == j - 1) return v[i][nj] == '0';\n    return false;\n}\n\n// Get move character\nchar get_dir(int r1, int c1, int r2, int c2) {\n    if (r1 < r2) return 'D';\n    if (r1 > r2) return 'U';\n    if (c1 < c2) return 'R';\n    if (c1 > c2) return 'L';\n    return 0;\n}\n\n// Build DFS spanning tree\nvoid build_tree(int u) {\n    vis[u] = true;\n    int ui = u / N, uj = u % N;\n    int dirs[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n    for (auto& dir : dirs) {\n        int ni = ui + dir[0], nj = uj + dir[1];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n            if (can_move(ui, uj, ni, nj)) {\n                int nxt = ni * N + nj;\n                if (!vis[nxt]) {\n                    children[u].push_back(nxt);\n                    build_tree(nxt);\n                }\n            }\n        }\n    }\n}\n\n// Generate route with extra loops\nvoid gen_route(int u, int p) {\n    for (int vtx : children[u]) {\n        int ui = u / N, uj = u % N;\n        int vi = vtx / N, vj = vtx % N;\n        char to_v = get_dir(ui, uj, vi, vj);\n        char to_u = get_dir(vi, vj, ui, uj);\n        // Insert extra out-and-back loops to child\n        for (int k = 0; k < extra[vtx]; ++k) {\n            res += to_v;\n            res += to_u;\n        }\n        // Normal traversal to child\n        res += to_v;\n        gen_route(vtx, u);\n        // Return to parent\n        res += to_u;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    h.resize(N-1);\n    for (int i = 0; i < N-1; ++i) cin >> h[i];\n    v.resize(N);\n    for (int i = 0; i < N; ++i) cin >> v[i];\n    d.assign(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> d[i][j];\n\n    // 1. Build Spanning Tree\n    children.assign(N*N, vector<int>());\n    vis.assign(N*N, false);\n    build_tree(0);\n\n    // 2. Compute base visit counts\n    // In DFS traversal, each node is visited deg_tree(node) times as a destination.\n    c.assign(N*N, 0);\n    for (int u = 0; u < N*N; ++u) {\n        c[u] = children[u].size();\n        if (u != 0) c[u] += 1; // +1 from parent edge\n    }\n\n    // 3. Greedily allocate extra visits\n    priority_queue<pair<double, int>> pq;\n    int L = 2 * (N*N - 1);\n    for (int u = 1; u < N*N; ++u) { // Skip root, its visit count is naturally high\n        double gain = (double)d[u/N][u%N] / (c[u] * (c[u] + 1.0));\n        pq.push({gain, u});\n    }\n\n    extra.assign(N*N, 0);\n    while (L + 2 <= 99000) {\n        auto top = pq.top(); pq.pop();\n        int u = top.second;\n        c[u]++;\n        extra[u]++;\n        L += 2;\n        double new_gain = (double)d[u/N][u%N] / (c[u] * (c[u] + 1.0));\n        pq.push({new_gain, u});\n    }\n\n    // 4. Construct final route\n    res.reserve(100005);\n    gen_route(0, -1);\n\n    cout << res << \"\\n\";\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\n#pragma GCC optimize(\"O3,unroll-loops\")\n\nstruct Point {\n    int r, c;\n    int dist(const Point& o) const {\n        return abs(r - o.r) + abs(c - o.c);\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n    int sr, sc;\n    cin >> sr >> sc;\n\n    vector<string> A(N);\n    for (int i = 0; i < N; i++) cin >> A[i];\n\n    vector<string> T(M);\n    for (int i = 0; i < M; i++) cin >> T[i];\n\n    // Precompute positions of each character in the grid\n    vector<vector<Point>> pos(26);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            pos[A[i][j] - 'A'].push_back({i, j});\n        }\n    }\n\n    // Precompute position lists for each target string to avoid repeated lookups\n    vector<vector<vector<Point>>> T_pos(M, vector<vector<Point>>(5));\n    for (int i = 0; i < M; i++) {\n        for (int l = 0; l < 5; l++) {\n            T_pos[i][l] = pos[T[i][l] - 'A'];\n        }\n    }\n\n    vector<bool> covered(M, false);\n    int covered_cnt = 0;\n    Point cur = {sr, sc};\n    vector<Point> ans;\n    ans.reserve(M * 5);\n\n    string S;\n    S.reserve(M * 5);\n\n    // Efficiently check which strings are covered by the newly appended characters\n    auto check_coverage = [&]() {\n        int nS = S.size();\n        if (nS < 5) return;\n        // Any new match of length 5 must end at or after index nS-5\n        // It could start as early as nS-9, so we check that window.\n        int start_check = max(0, nS - 9);\n        int end_check = nS - 5;\n\n        for (int i = 0; i < M; i++) {\n            if (!covered[i]) {\n                bool found = false;\n                for (int s = start_check; s <= end_check; s++) {\n                    bool match = true;\n                    for (int k = 0; k < 5; k++) {\n                        if (S[s + k] != T[i][k]) {\n                            match = false;\n                            break;\n                        }\n                    }\n                    if (match) {\n                        found = true;\n                        break;\n                    }\n                }\n                if (found) {\n                    covered[i] = true;\n                    covered_cnt++;\n                }\n            }\n        }\n    };\n\n    while (covered_cnt < M) {\n        int best_k = -1;\n        int best_cost = INT_MAX;\n        vector<Point> best_path;\n\n        for (int i = 0; i < M; i++) {\n            if (covered[i]) continue;\n\n            // Layered DP to find min-cost path for T[i] from current position\n            const int L = 5;\n            vector<vector<int>> dp(L);\n            vector<vector<int>> pred(L);\n\n            for (int l = 0; l < L; l++) {\n                int sz = T_pos[i][l].size();\n                dp[l].assign(sz, INT_MAX);\n                pred[l].assign(sz, -1);\n            }\n\n            // Base case: first character\n            for (int u = 0; u < T_pos[i][0].size(); u++) {\n                dp[0][u] = cur.dist(T_pos[i][0][u]) + 1;\n            }\n\n            // Transition through characters 2..5\n            for (int l = 1; l < L; l++) {\n                for (int u = 0; u < T_pos[i][l].size(); u++) {\n                    int best_prev_cost = INT_MAX;\n                    int best_v = -1;\n                    for (int v = 0; v < T_pos[i][l-1].size(); v++) {\n                        if (dp[l-1][v] == INT_MAX) continue;\n                        int cost = dp[l-1][v] + T_pos[i][l-1][v].dist(T_pos[i][l][u]) + 1;\n                        if (cost < best_prev_cost) {\n                            best_prev_cost = cost;\n                            best_v = v;\n                        }\n                    }\n                    dp[l][u] = best_prev_cost;\n                    pred[l][u] = best_v;\n                }\n            }\n\n            // Find minimum cost in the final layer\n            int min_cost = INT_MAX;\n            int best_u = -1;\n            for (int u = 0; u < T_pos[i][4].size(); u++) {\n                if (dp[4][u] < min_cost) {\n                    min_cost = dp[4][u];\n                    best_u = u;\n                }\n            }\n\n            if (min_cost < best_cost) {\n                best_cost = min_cost;\n                best_k = i;\n                best_path.resize(5);\n                int u = best_u;\n                for (int l = 4; l >= 0; l--) {\n                    best_path[l] = T_pos[i][l][u];\n                    if (l > 0) u = pred[l][u];\n                }\n            }\n        }\n\n        if (best_k == -1) break; // Should not happen given problem constraints\n\n        // Execute the chosen path\n        for (const auto& p : best_path) {\n            ans.push_back(p);\n            S += A[p.r][p.c];\n            cur = p;\n        }\n\n        check_coverage();\n    }\n\n    // Output result\n    for (const auto& p : ans) {\n        cout << p.r << \" \" << p.c << \"\\n\";\n    }\n\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Shape {\n    vector<pair<int, int>> cells;\n};\n\nint N, M;\ndouble eps;\nvector<Shape> shapes;\nint max_r[20], max_c[20];\n\nstruct Observation {\n    int r, c, v;\n};\nvector<Observation> obs;\n\nint grid[20][20];\npair<int, int> pos[20];\n\n// Compute squared error between model and observations\nint compute_cost() {\n    int c = 0;\n    for (const auto& o : obs) {\n        int d = grid[o.r][o.c] - o.v;\n        c += d * d;\n    }\n    return c;\n}\n\n// Add/remove polyomino k from grid at offset (dr, dc)\nvoid apply_shape(int k, int dr, int dc, int sign) {\n    for (const auto& cell : shapes[k].cells) {\n        grid[cell.first + dr][cell.second + dc] += sign;\n    }\n}\n\nmt19937 rng;\nint rand_int(int l, int r) {\n    return uniform_int_distribution<int>(l, r)(rng);\n}\n\n// Simulated Annealing to find polyomino placements matching observations\nvoid run_sa(const vector<pair<int,int>>& init_pos) {\n    for (int k = 0; k < M; k++) {\n        if (!init_pos.empty()) {\n            pos[k] = init_pos[k];\n        } else {\n            pos[k] = {rand_int(0, N - 1 - max_r[k]), rand_int(0, N - 1 - max_c[k])};\n        }\n    }\n    memset(grid, 0, sizeof(grid));\n    for (int k = 0; k < M; k++) apply_shape(k, pos[k].first, pos[k].second, 1);\n    \n    int current_cost = compute_cost();\n    int best_cost = current_cost;\n    pair<int, int> best_pos_arr[20];\n    memcpy(best_pos_arr, pos, sizeof(pos));\n    \n    double T = 300.0;\n    int iterations = 40000;\n    uniform_real_distribution<double> dis(0, 1);\n    for (int iter = 0; iter < iterations; iter++) {\n        int k = rand_int(0, M - 1);\n        int dr = rand_int(-1, 1);\n        int dc = rand_int(-1, 1);\n        if (dr == 0 && dc == 0) continue;\n        \n        int nr = pos[k].first + dr;\n        int nc = pos[k].second + dc;\n        if (nr < 0 || nr > N - 1 - max_r[k] || nc < 0 || nc > N - 1 - max_c[k]) continue;\n        \n        int old_r = pos[k].first;\n        int old_c = pos[k].second;\n        \n        // Apply move\n        apply_shape(k, old_r, old_c, -1);\n        pos[k] = {nr, nc};\n        apply_shape(k, nr, nc, 1);\n        \n        int new_cost = compute_cost();\n        \n        // Metropolis criterion\n        double prob = exp(-(new_cost - current_cost) / T);\n        if (new_cost < current_cost || dis(rng) < prob) {\n            current_cost = new_cost;\n            if (current_cost < best_cost) {\n                best_cost = current_cost;\n                memcpy(best_pos_arr, pos, sizeof(pos));\n            }\n        } else {\n            // Revert move\n            apply_shape(k, nr, nc, -1);\n            pos[k] = {old_r, old_c};\n            apply_shape(k, old_r, old_c, 1);\n        }\n        T *= 0.9999; // Cool down\n    }\n    memcpy(pos, best_pos_arr, sizeof(pos));\n    // Rebuild grid for best configuration\n    memset(grid, 0, sizeof(grid));\n    for (int k = 0; k < M; k++) apply_shape(k, pos[k].first, pos[k].second, 1);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    rng.seed(chrono::steady_clock::now().time_since_epoch().count());\n    \n    cin >> N >> M >> eps;\n    shapes.resize(M);\n    for (int k = 0; k < M; k++) {\n        int d; cin >> d;\n        for (int l = 0; l < d; l++) {\n            int r, c; cin >> r >> c;\n            shapes[k].cells.push_back({r, c});\n            max_r[k] = max(max_r[k], r);\n            max_c[k] = max(max_c[k], c);\n        }\n    }\n    \n    memset(grid, 0, sizeof(grid));\n    bool is_drilled[20][20] = {};\n    int op_count = 0;\n    int limit = 2 * N * N;\n    \n    auto drill = [&](int r, int c) {\n        cout << \"q 1 \" << r << \" \" << c << \"\\n\";\n        cout.flush();\n        int v; cin >> v;\n        obs.push_back({r, c, v});\n        op_count++;\n        return v;\n    };\n    \n    auto guess = [&](const vector<pair<int,int>>& union_cells) {\n        cout << \"a \" << union_cells.size();\n        for (const auto& p : union_cells) cout << \" \" << p.first << \" \" << p.second;\n        cout << \"\\n\";\n        cout.flush();\n        op_count++;\n        int res; cin >> res;\n        return res == 1;\n    };\n\n    // Phase 1: Initial random drilling\n    int init_drills = min(25, N*N);\n    for (int i = 0; i < init_drills; i++) {\n        int r = rand_int(0, N-1);\n        int c = rand_int(0, N-1);\n        if (!is_drilled[r][c]) {\n            is_drilled[r][c] = true;\n            drill(r, c);\n        } else { i--; }\n    }\n    \n    vector<pair<int,int>> current_best_pos(M);\n    auto start_time = chrono::steady_clock::now();\n\n    // Phase 2: SA + Adaptive Drilling Loop\n    while (op_count < limit - 5) {\n        if (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() > 2600) break;\n        \n        run_sa(current_best_pos);\n        for(int k=0; k<M; k++) current_best_pos[k] = pos[k];\n        \n        // Compute union\n        vector<pair<int,int>> union_cells;\n        bool seen[20][20] = {};\n        for (int k = 0; k < M; k++) {\n            for (const auto& cell : shapes[k].cells) {\n                int r = cell.first + pos[k].first;\n                int c = cell.second + pos[k].second;\n                if (!seen[r][c]) {\n                    seen[r][c] = true;\n                    union_cells.push_back({r, c});\n                }\n            }\n        }\n        \n        if (guess(union_cells)) return 0;\n        \n        // Phase 3: Drill informative cells where model predicts 0\n        int drills_needed = 4;\n        vector<pair<int,int>> to_drill;\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                if (grid[r][c] == 0 && !is_drilled[r][c]) {\n                    to_drill.push_back({r, c});\n                }\n            }\n        }\n        // Fallback to any undrilled cell if needed\n        if ((int)to_drill.size() < drills_needed) {\n            for (int r = 0; r < N; r++) {\n                for (int c = 0; c < N; c++) {\n                    if (!is_drilled[r][c]) to_drill.push_back({r, c});\n                }\n            }\n        }\n        shuffle(to_drill.begin(), to_drill.end(), rng);\n        \n        for (int i = 0; i < drills_needed && i < (int)to_drill.size(); i++) {\n            auto p = to_drill[i];\n            is_drilled[p.first][p.second] = true;\n            drill(p.first, p.second);\n        }\n    }\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\n#include <chrono>\n#include <random>\nusing namespace std;\n\n// Problem constants\nconst int W = 1000;\nconst int MAX_D = 55;\nconst int MAX_N = 55;\n\n// Global state\nint D, N;\nlong long A[MAX_D][MAX_N];\n\nstruct Rect {\n    int x1, y1, x2, y2;\n};\n\nRect rects[MAX_D][MAX_N];\nRect best_rects[MAX_D][MAX_N];\n\n// Partition grids: H[d][y][x] for horizontal segments at row y, between x and x+1\n// V[d][y][x] for vertical segments at col x, between y and y+1\n// We use char for cache efficiency and speed. Padding to avoid bounds checks.\nchar H[MAX_D][W+5][W+5];\nchar V[MAX_D][W+5][W+5];\n\nlong long L[MAX_D]; // L[d] stores partition change cost between d-1 and d\nlong long area_pen[MAX_D][MAX_N];\nlong long total_cost = 0;\nlong long best_cost = 1LL << 60;\n\nmt19937 rng(42);\nuniform_int_distribution<int> dist_int(0, 1000000);\nuniform_real_distribution<double> dist_real(0.0, 1.0);\n\nint rand_int(int l, int r) {\n    return l + dist_int(rng) % (r - l + 1);\n}\ndouble rand_real() {\n    return dist_real(rng);\n}\n\n// Check overlap on day d for reservation k with candidate rect r\nbool overlap(int d, int k, const Rect& r) {\n    for (int i = 0; i < N; ++i) {\n        if (i == k) continue;\n        if (rects[d][i].x1 < r.x2 && rects[d][i].x2 > r.x1 &&\n            rects[d][i].y1 < r.y2 && rects[d][i].y2 > r.y1)\n            return true;\n    }\n    return false;\n}\n\n// Compute area penalty\nlong long calc_area_pen(const Rect& r, long long req) {\n    long long area = 1LL * (r.x2 - r.x1) * (r.y2 - r.y1);\n    return max(0LL, 100LL * (req - area));\n}\n\n// Update total cost when flipping a single partition segment\n// Returns delta to total_cost\nlong long flip_segment(int d, bool is_H, int y, int x, char new_val, bool apply = true) {\n    if (d == 0) return 0; // L_0 is always 0, no change affects it\n    char* grid = is_H ? &H[d][y][x] : &V[d][y][x];\n    char old_val = *grid;\n    if (old_val == new_val) return 0;\n\n    long long delta = 0;\n    // Contribution to L[d]: compares with day d-1\n    char prev = is_H ? H[d-1][y][x] : V[d-1][y][x];\n    if ((prev != old_val) && (prev == new_val)) delta -= 1;\n    else if ((prev == old_val) && (prev != new_val)) delta += 1;\n\n    // Contribution to L[d+1]: compares with day d+1\n    if (d < D - 1) {\n        char next = is_H ? H[d+1][y][x] : V[d+1][y][x];\n        if ((next != old_val) && (next == new_val)) delta -= 1;\n        else if ((next == old_val) && (next != new_val)) delta += 1;\n    }\n\n    if (apply) {\n        *grid = new_val;\n        total_cost += delta;\n        if (d > 0) L[d] += delta; // Note: L array not strictly needed if we track total_cost, but kept for debug/sanity\n    }\n    return delta;\n}\n\n// Apply or revert rectangle on day d\n// sign = 1 to add, -1 to remove\nvoid apply_rect(int d, int k, const Rect& r, int sign) {\n    // Horizontal edges\n    for (int x = r.x1; x < r.x2; ++x) {\n        if (r.y1 >= 1 && r.y1 <= W - 1) flip_segment(d, true, r.y1, x, sign == 1, true);\n        if (r.y2 >= 1 && r.y2 <= W - 1) flip_segment(d, true, r.y2, x, sign == 1, true);\n    }\n    // Vertical edges\n    for (int y = r.y1; y < r.y2; ++y) {\n        if (r.x1 >= 1 && r.x1 <= W - 1) flip_segment(d, false, y, r.x1, sign == 1, true);\n        if (r.x2 >= 1 && r.x2 <= W - 1) flip_segment(d, false, y, r.x2, sign == 1, true);\n    }\n    rects[d][k] = r;\n}\n\n// Compute delta cost for a proposed change without modifying state\nlong long simulate_change(int d, int k, const Rect& old_r, const Rect& new_r) {\n    long long delta = 0;\n    // Remove old\n    delta -= calc_area_pen(old_r, A[d][k]);\n    for (int x = old_r.x1; x < old_r.x2; ++x) {\n        if (old_r.y1 >= 1 && old_r.y1 <= W - 1) delta += flip_segment(d, true, old_r.y1, x, 0, false);\n        if (old_r.y2 >= 1 && old_r.y2 <= W - 1) delta += flip_segment(d, true, old_r.y2, x, 0, false);\n    }\n    for (int y = old_r.y1; y < old_r.y2; ++y) {\n        if (old_r.x1 >= 1 && old_r.x1 <= W - 1) delta += flip_segment(d, false, y, old_r.x1, 0, false);\n        if (old_r.x2 >= 1 && old_r.x2 <= W - 1) delta += flip_segment(d, false, y, old_r.x2, 0, false);\n    }\n\n    // Add new\n    delta += calc_area_pen(new_r, A[d][k]);\n    for (int x = new_r.x1; x < new_r.x2; ++x) {\n        if (new_r.y1 >= 1 && new_r.y1 <= W - 1) delta += flip_segment(d, true, new_r.y1, x, 1, false);\n        if (new_r.y2 >= 1 && new_r.y2 <= W - 1) delta += flip_segment(d, true, new_r.y2, x, 1, false);\n    }\n    for (int y = new_r.y1; y < new_r.y2; ++y) {\n        if (new_r.x1 >= 1 && new_r.x1 <= W - 1) delta += flip_segment(d, false, y, new_r.x1, 1, false);\n        if (new_r.x2 >= 1 && new_r.x2 <= W - 1) delta += flip_segment(d, false, y, new_r.x2, 1, false);\n    }\n    return delta;\n}\n\n// Initial packing: simple shelf algorithm\nvoid pack_initial() {\n    for (int d = 0; d < D; ++d) {\n        int cx = 0, cy = 0, rh = 0;\n        for (int k = 0; k < N; ++k) {\n            long long area = A[d][k];\n            int w = min(W, max(1, (int)ceil(sqrt(area))));\n            int h = max(1, (int)((area + w - 1) / w));\n            if (cx + w > W) {\n                cy += rh;\n                rh = 0;\n                cx = 0;\n                w = min(W, max(1, (int)ceil(sqrt(area))));\n                h = max(1, (int)((area + w - 1) / w));\n            }\n            rects[d][k] = {cx, cy, cx + w, cy + h};\n            cx += w;\n            rh = max(rh, h);\n        }\n    }\n\n    // Build grids and compute costs\n    total_cost = 0;\n    memset(H, 0, sizeof(H));\n    memset(V, 0, sizeof(V));\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            area_pen[d][k] = calc_area_pen(rects[d][k], A[d][k]);\n            total_cost += area_pen[d][k];\n            // Add to grids\n            for (int x = rects[d][k].x1; x < rects[d][k].x2; ++x) {\n                if (rects[d][k].y1 >= 1 && rects[d][k].y1 <= W - 1) H[d][rects[d][k].y1][x] = 1;\n                if (rects[d][k].y2 >= 1 && rects[d][k].y2 <= W - 1) H[d][rects[d][k].y2][x] = 1;\n            }\n            for (int y = rects[d][k].y1; y < rects[d][k].y2; ++y) {\n                if (rects[d][k].x1 >= 1 && rects[d][k].x1 <= W - 1) V[d][y][rects[d][k].x1] = 1;\n                if (rects[d][k].x2 >= 1 && rects[d][k].x2 <= W - 1) V[d][y][rects[d][k].x2] = 1;\n            }\n        }\n    }\n    // Compute L[d]\n    for (int d = 1; d < D; ++d) {\n        for (int y = 1; y < W; ++y) {\n            for (int x = 0; x < W; ++x) {\n                if (H[d][y][x] != H[d-1][y][x]) total_cost++;\n            }\n            for (int x = 1; x < W; ++x) {\n                if (V[d][y-1][x] != V[d-1][y-1][x]) total_cost++;\n            }\n        }\n        // Last row for V\n        for (int x = 1; x < W; ++x) {\n            if (V[d][W-1][x] != V[d-1][W-1][x]) total_cost++;\n        }\n    }\n}\n\nvoid solve() {\n    pack_initial();\n    if (total_cost < best_cost) {\n        best_cost = total_cost;\n        memcpy(best_rects, rects, sizeof(rects));\n    }\n\n    auto start = chrono::high_resolution_clock::now();\n    double temp = 5000.0;\n    const double COOLING = 0.99995;\n    int moves = 0;\n\n    while (chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start).count() < 2800) {\n        int d = rand_int(0, D - 1);\n        int k = rand_int(0, N - 1);\n        Rect old_r = rects[d][k];\n\n        // Perturb\n        int dx = rand_int(-4, 4);\n        int dy = rand_int(-4, 4);\n        int dw = rand_int(-3, 3);\n        int dh = rand_int(-3, 3);\n\n        Rect new_r;\n        new_r.x1 = max(0, min(W, old_r.x1 + dx));\n        new_r.y1 = max(0, min(W, old_r.y1 + dy));\n        new_r.x2 = max(new_r.x1 + 1, min(W, old_r.x2 + dw));\n        new_r.y2 = max(new_r.y1 + 1, min(W, old_r.y2 + dh));\n\n        // Enforce area constraint\n        long long cur_area = 1LL * (new_r.x2 - new_r.x1) * (new_r.y2 - new_r.y1);\n        if (cur_area < A[d][k]) {\n            long long needed = A[d][k];\n            // Try to expand width first, then height\n            int add_w = max(0, (int)((needed + new_r.y2 - new_r.y1 - 1) / (new_r.y2 - new_r.y1)) - (new_r.x2 - new_r.x1));\n            if (new_r.x2 + add_w <= W) new_r.x2 += add_w;\n            else {\n                int add_h = max(0, (int)((needed + new_r.x2 - new_r.x1 - 1) / (new_r.x2 - new_r.x1)) - (new_r.y2 - new_r.y1));\n                if (new_r.y2 + add_h <= W) new_r.y2 += add_h;\n                else continue; // Cannot fit\n            }\n        }\n\n        if (overlap(d, k, new_r)) continue;\n\n        long long delta = simulate_change(d, k, old_r, new_r);\n        \n        if (delta < 0 || rand_real() < exp(-delta / temp)) {\n            apply_rect(d, k, new_r, 1); // Apply new\n            area_pen[d][k] = calc_area_pen(new_r, A[d][k]);\n            total_cost += delta; // delta already includes area penalty change\n            \n            // Revert old state in grids manually to keep consistency (simulate_change didn't apply)\n            // Actually, apply_rect adds new, but we need to remove old first.\n            // Let's fix the logic: apply_rect assumes grid has old state, flips to new_val.\n            // But simulate_change didn't modify grid. So we must remove old, add new.\n            // I'll rewrite apply to be atomic:\n            // Remove old\n            for (int x = old_r.x1; x < old_r.x2; ++x) {\n                if (old_r.y1 >= 1 && old_r.y1 <= W - 1) flip_segment(d, true, old_r.y1, x, 0, true);\n                if (old_r.y2 >= 1 && old_r.y2 <= W - 1) flip_segment(d, true, old_r.y2, x, 0, true);\n            }\n            for (int y = old_r.y1; y < old_r.y2; ++y) {\n                if (old_r.x1 >= 1 && old_r.x1 <= W - 1) flip_segment(d, false, y, old_r.x1, 0, true);\n                if (old_r.x2 >= 1 && old_r.x2 <= W - 1) flip_segment(d, false, y, old_r.x2, 0, true);\n            }\n            // Add new\n            for (int x = new_r.x1; x < new_r.x2; ++x) {\n                if (new_r.y1 >= 1 && new_r.y1 <= W - 1) flip_segment(d, true, new_r.y1, x, 1, true);\n                if (new_r.y2 >= 1 && new_r.y2 <= W - 1) flip_segment(d, true, new_r.y2, x, 1, true);\n            }\n            for (int y = new_r.y1; y < new_r.y2; ++y) {\n                if (new_r.x1 >= 1 && new_r.x1 <= W - 1) flip_segment(d, false, y, new_r.x1, 1, true);\n                if (new_r.x2 >= 1 && new_r.x2 <= W - 1) flip_segment(d, false, y, new_r.x2, 1, true);\n            }\n            \n            // Wait, flip_segment already updates total_cost. So I double counted.\n            // Let's simplify: I'll just call a direct apply function that does everything correctly.\n            // Reverting logic below handles this cleanly.\n        } else {\n            // Reject\n        }\n        temp *= COOLING;\n        moves++;\n        if (total_cost < best_cost) {\n            best_cost = total_cost;\n            memcpy(best_rects, rects, sizeof(rects));\n        }\n    }\n}\n\n// Correct atomic apply\nvoid atomic_apply(int d, int k, Rect old_r, Rect new_r) {\n    // Remove old\n    for (int x = old_r.x1; x < old_r.x2; ++x) {\n        if (old_r.y1 >= 1 && old_r.y1 <= W - 1) flip_segment(d, true, old_r.y1, x, 0, true);\n        if (old_r.y2 >= 1 && old_r.y2 <= W - 1) flip_segment(d, true, old_r.y2, x, 0, true);\n    }\n    for (int y = old_r.y1; y < old_r.y2; ++y) {\n        if (old_r.x1 >= 1 && old_r.x1 <= W - 1) flip_segment(d, false, y, old_r.x1, 0, true);\n        if (old_r.x2 >= 1 && old_r.x2 <= W - 1) flip_segment(d, false, y, old_r.x2, 0, true);\n    }\n    // Add new\n    for (int x = new_r.x1; x < new_r.x2; ++x) {\n        if (new_r.y1 >= 1 && new_r.y1 <= W - 1) flip_segment(d, true, new_r.y1, x, 1, true);\n        if (new_r.y2 >= 1 && new_r.y2 <= W - 1) flip_segment(d, true, new_r.y2, x, 1, true);\n    }\n    for (int y = new_r.y1; y < new_r.y2; ++y) {\n        if (new_r.x1 >= 1 && new_r.x1 <= W - 1) flip_segment(d, false, y, new_r.x1, 1, true);\n        if (new_r.x2 >= 1 && new_r.x2 <= W - 1) flip_segment(d, false, y, new_r.x2, 1, true);\n    }\n    rects[d][k] = new_r;\n}\n\n// Re-implement SA loop correctly\nvoid run_sa() {\n    auto start = chrono::high_resolution_clock::now();\n    double temp = 8000.0;\n    const double COOLING = 0.99994;\n\n    while (chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start).count() < 2850) {\n        int d = rand_int(0, D - 1);\n        int k = rand_int(0, N - 1);\n        Rect old_r = rects[d][k];\n\n        int dx = rand_int(-5, 5);\n        int dy = rand_int(-5, 5);\n        int dw = rand_int(-3, 3);\n        int dh = rand_int(-3, 3);\n\n        Rect new_r;\n        new_r.x1 = max(0, min(W, old_r.x1 + dx));\n        new_r.y1 = max(0, min(W, old_r.y1 + dy));\n        new_r.x2 = max(new_r.x1 + 1, min(W, old_r.x2 + dw));\n        new_r.y2 = max(new_r.y1 + 1, min(W, old_r.y2 + dh));\n\n        long long cur_area = 1LL * (new_r.x2 - new_r.x1) * (new_r.y2 - new_r.y1);\n        if (cur_area < A[d][k]) {\n            long long needed = A[d][k];\n            int add_w = max(0, (int)((needed + new_r.y2 - new_r.y1 - 1) / (new_r.y2 - new_r.y1)) - (new_r.x2 - new_r.x1));\n            if (new_r.x2 + add_w <= W) new_r.x2 += add_w;\n            else {\n                int add_h = max(0, (int)((needed + new_r.x2 - new_r.x1 - 1) / (new_r.x2 - new_r.x1)) - (new_r.y2 - new_r.y1));\n                if (new_r.y2 + add_h <= W) new_r.y2 += add_h;\n                else continue;\n            }\n        }\n\n        if (overlap(d, k, new_r)) continue;\n\n        long long delta = simulate_change(d, k, old_r, new_r);\n        if (delta < 0 || rand_real() < exp(-delta / temp)) {\n            long long old_total = total_cost;\n            atomic_apply(d, k, old_r, new_r);\n            area_pen[d][k] = calc_area_pen(new_r, A[d][k]);\n            \n            if (total_cost > old_total + delta) {\n                // Should not happen if simulate is correct, but fallback: revert\n                atomic_apply(d, k, new_r, old_r);\n                area_pen[d][k] = calc_area_pen(old_r, A[d][k]);\n                total_cost = old_total;\n            }\n        }\n\n        temp *= COOLING;\n        if (total_cost < best_cost) {\n            best_cost = total_cost;\n            memcpy(best_rects, rects, sizeof(rects));\n        }\n    }\n}\n\nint main() {\n    ios_base::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)\n        for (int k = 0; k < N; ++k)\n            cin >> A[d][k];\n\n    pack_initial();\n    best_cost = total_cost;\n    memcpy(best_rects, rects, sizeof(rects));\n    \n    run_sa();\n\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            cout << best_rects[d][k].y1 << \" \" << best_rects[d][k].x1 << \" \"\n                 << best_rects[d][k].y2 << \" \" << best_rects[d][k].x2 << \"\\n\";\n        }\n    }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\n#pragma GCC optimize(\"O3,unroll-loops\")\n\nusing namespace std;\nusing ll = long long;\n\nconst ll MOD = 998244353;\n\nint N, M, K;\nll board[9][9];\nll board_mod[9][9];\nll stamps[20][3][3];\n\nstruct Op { int m, p, q; };\nvector<Op> ops;\n\nll current_score = 0;\nll best_score = 0;\nvector<Op> best_ops;\n\n// Fast delta calculation without modifying the board\ninline ll calc_delta(int m, int p, int q) {\n    ll d = 0;\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            ll old_val = board_mod[p + i][q + j];\n            ll new_val = old_val + stamps[m][i][j];\n            if (new_val >= MOD) new_val -= MOD;\n            d += new_val - old_val;\n        }\n    }\n    return d;\n}\n\n// Apply operation: updates board and board_mod\ninline void apply(int m, int p, int q) {\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            board[p + i][q + j] += stamps[m][i][j];\n            board_mod[p + i][q + j] += stamps[m][i][j];\n            if (board_mod[p + i][q + j] >= MOD) board_mod[p + i][q + j] -= MOD;\n        }\n    }\n}\n\n// Revert operation: undoes apply\ninline void revert(int m, int p, int q) {\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            board[p + i][q + j] -= stamps[m][i][j];\n            board_mod[p + i][q + j] -= stamps[m][i][j];\n            if (board_mod[p + i][q + j] < 0) board_mod[p + i][q + j] += MOD;\n        }\n    }\n}\n\n// Compute full score (used for initialization and verification)\nll compute_score() {\n    ll s = 0;\n    for (int i = 0; i < N; ++i) \n        for (int j = 0; j < N; ++j) \n            s += board_mod[i][j];\n    return s;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> K)) return 0;\n    for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) {\n        cin >> board[i][j];\n        board_mod[i][j] = board[i][j] % MOD;\n    }\n    for (int m = 0; m < M; ++m) for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) {\n        cin >> stamps[m][i][j];\n    }\n\n    ops.resize(K);\n    // High-quality RNG\n    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist_m(0, M - 1);\n    uniform_int_distribution<int> dist_pq(0, N - 3);\n    uniform_int_distribution<int> dist_idx(0, K - 1);\n    uniform_real_distribution<double> dist_real(0.0, 1.0);\n\n    // Initialize with random operations\n    for (int i = 0; i < K; ++i) {\n        ops[i] = {dist_m(rng), dist_pq(rng), dist_pq(rng)};\n        apply(ops[i].m, ops[i].p, ops[i].q);\n    }\n    current_score = compute_score();\n    best_score = current_score;\n    best_ops = ops;\n\n    // Simulated Annealing Parameters\n    double T = 1e10;\n    const double T_end = 100;\n    const int MAX_ITER = 7000000;\n    const double decay = pow(T_end / T, 1.0 / MAX_ITER);\n\n    auto start = chrono::steady_clock::now();\n    for (int step = 0; step < MAX_ITER; ++step) {\n        // Soft time limit to ensure safe exit\n        if (step % 200000 == 0 && chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start).count() > 1850) break;\n\n        int idx = dist_idx(rng);\n        int m = dist_m(rng);\n        int p = dist_pq(rng);\n        int q = dist_pq(rng);\n\n        // Temporarily remove old operation\n        revert(ops[idx].m, ops[idx].p, ops[idx].q);\n        ll delta = calc_delta(m, p, q);\n\n        bool accept = false;\n        if (delta > 0) {\n            accept = true;\n        } else {\n            // Metropolis criterion with underflow protection\n            if (delta > -20.0 * T) {\n                double prob = exp(delta / T);\n                if (dist_real(rng) < prob) accept = true;\n            }\n        }\n\n        if (accept) {\n            apply(m, p, q);\n            ops[idx] = {m, p, q};\n            current_score += delta;\n            if (current_score > best_score) {\n                best_score = current_score;\n                best_ops = ops;\n            }\n        } else {\n            // Restore old operation\n            apply(ops[idx].m, ops[idx].p, ops[idx].q);\n        }\n        T *= decay;\n    }\n\n    // Optional: Greedy post-processing to remove clearly detrimental operations\n    for (int i = (int)best_ops.size() - 1; i >= 0; --i) {\n        revert(best_ops[i].m, best_ops[i].p, best_ops[i].q);\n        if (compute_score() < best_score) {\n            apply(best_ops[i].m, best_ops[i].p, best_ops[i].q);\n        } else {\n            best_ops.erase(best_ops.begin() + i);\n        }\n    }\n\n    // Output\n    cout << best_ops.size() << \"\\n\";\n    for (const auto& op : best_ops) {\n        cout << op.m << \" \" << op.p << \" \" << op.q << \"\\n\";\n    }\n\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    if (!(cin >> N)) return 0;\n    int A[5][5];\n    for (int i = 0; i < 5; ++i)\n        for (int j = 0; j < 5; ++j)\n            cin >> A[i][j];\n\n    // Grid state: -1 means empty\n    int grid[5][5];\n    memset(grid, -1, sizeof(grid));\n    \n    // Crane positions and held containers\n    pair<int, int> cpos[5];\n    for (int i = 0; i < 5; ++i) cpos[i] = {i, 0};\n    int chold[5];\n    memset(chold, -1, sizeof(chold));\n    \n    // Dispatch progress and Receiving progress\n    int dnext[5];\n    for (int i = 0; i < 5; ++i) dnext[i] = i * 5;\n    int rptr[5] = {0};\n    int dispatched_count = 0;\n\n    vector<string> S(5, \"\");\n\n    auto is_valid = [](int r, int c) { return r >= 0 && r < 5 && c >= 0 && c < 5; };\n\n    for (int turn = 1; turn <= 10000; ++turn) {\n        // Step 1: Receiving\n        for (int i = 0; i < 5; ++i) {\n            if (grid[i][0] == -1 && rptr[i] < 5) {\n                grid[i][0] = A[i][rptr[i]];\n                rptr[i]++;\n            }\n        }\n\n        char actions[5] = {'.'};\n        pair<int, int> next_cpos[5];\n        for (int i = 0; i < 5; ++i) next_cpos[i] = cpos[i];\n\n        // Priority assignment (0: large, then 1..4: small)\n        for (int k = 0; k < 5; ++k) {\n            bool is_large = (k == 0);\n            bool holding = (chold[k] != -1);\n            int r = cpos[k].first, c = cpos[k].second;\n            char best_act = '.';\n            int best_nr = r, best_nc = c;\n\n            if (holding) {\n                int cid = chold[k];\n                int target_r = cid / 5;\n                bool is_correct = (cid == dnext[target_r]);\n                // Buffer at col 3, dispatch at col 4 only if correct order\n                pair<int, int> target = is_correct ? make_pair(target_r, 4) : make_pair(target_r, 3);\n\n                if (r == target.first && c == target.second) {\n                    if (is_correct && grid[target.first][target.second] == -1) {\n                        best_act = 'Q';\n                    }\n                } else {\n                    // BFS to find best step towards target\n                    queue<pair<int, int>> q;\n                    q.push({r, c});\n                    bool vis[5][5] = {}; vis[r][c] = true;\n                    int dist[5][5]; memset(dist, 0x3f, sizeof(dist));\n                    dist[r][c] = 0;\n\n                    while (!q.empty()) {\n                        auto [cr, cc] = q.front(); q.pop();\n                        if (cr == target.first && cc == target.second) break;\n                        int dr[4] = {-1, 1, 0, 0};\n                        int dc[4] = {0, 0, -1, 1};\n                        for (int d = 0; d < 4; ++d) {\n                            int nr = cr + dr[d], nc = cc + dc[d];\n                            if (!is_valid(nr, nc) || vis[nr][nc]) continue;\n                            // Crane obstacles (current positions)\n                            bool blocked_crane = false;\n                            for (int j = 0; j < 5; ++j) if (j != k && cpos[j].first == nr && cpos[j].second == nc) { blocked_crane = true; break; }\n                            if (blocked_crane) continue;\n                            // Container obstacles for small cranes carrying\n                            if (!is_large && holding && grid[nr][nc] != -1) continue;\n\n                            vis[nr][nc] = true;\n                            dist[nr][nc] = dist[cr][cc] + 1;\n                            q.push({nr, nc});\n                        }\n                    }\n\n                    int min_d = 1e9;\n                    char chars[4] = {'U', 'D', 'L', 'R'};\n                    int dr[4] = {-1, 1, 0, 0};\n                    int dc[4] = {0, 0, -1, 1};\n                    for (int d = 0; d < 4; ++d) {\n                        int nr = r + dr[d], nc = c + dc[d];\n                        if (is_valid(nr, nc) && vis[nr][nc] && dist[nr][nc] < min_d) {\n                            min_d = dist[nr][nc];\n                            best_act = chars[d];\n                            best_nr = nr; best_nc = nc;\n                        }\n                    }\n                }\n            } else {\n                // Not holding\n                if (grid[r][c] != -1) {\n                    best_act = 'P';\n                } else {\n                    // Find nearest available container\n                    pair<int, int> best_tgt = {-1, -1};\n                    int best_d = 1e9;\n                    for (int rr = 0; rr < 5; ++rr) {\n                        for (int cc = 0; cc < 5; ++cc) {\n                            if (grid[rr][cc] == -1) continue;\n                            bool held = false;\n                            for (int j = 0; j < 5; ++j) if (j != k && chold[j] == grid[rr][cc]) { held = true; break; }\n                            if (held) continue;\n                            int d = abs(r - rr) + abs(c - cc);\n                            if (d < best_d) { best_d = d; best_tgt = {rr, cc}; }\n                        }\n                    }\n                    if (best_tgt.first != -1) {\n                        queue<pair<int, int>> q;\n                        q.push({r, c});\n                        bool vis[5][5] = {}; vis[r][c] = true;\n                        int dist[5][5]; memset(dist, 0x3f, sizeof(dist));\n                        dist[r][c] = 0;\n                        while (!q.empty()) {\n                            auto [cr, cc] = q.front(); q.pop();\n                            if (cr == best_tgt.first && cc == best_tgt.second) break;\n                            int dr[4] = {-1, 1, 0, 0};\n                            int dc[4] = {0, 0, -1, 1};\n                            for (int d = 0; d < 4; ++d) {\n                                int nr = cr + dr[d], nc = cc + dc[d];\n                                if (!is_valid(nr, nc) || vis[nr][nc]) continue;\n                                bool blocked_crane = false;\n                                for (int j = 0; j < 5; ++j) if (j != k && cpos[j].first == nr && cpos[j].second == nc) { blocked_crane = true; break; }\n                                if (blocked_crane) continue;\n                                vis[nr][nc] = true;\n                                dist[nr][nc] = dist[cr][cc] + 1;\n                                q.push({nr, nc});\n                            }\n                        }\n                        int min_d = 1e9;\n                        char chars[4] = {'U', 'D', 'L', 'R'};\n                        int dr[4] = {-1, 1, 0, 0};\n                        int dc[4] = {0, 0, -1, 1};\n                        for (int d = 0; d < 4; ++d) {\n                            int nr = r + dr[d], nc = c + dc[d];\n                            if (is_valid(nr, nc) && vis[nr][nc] && dist[nr][nc] < min_d) {\n                                min_d = dist[nr][nc];\n                                best_act = chars[d];\n                                best_nr = nr; best_nc = nc;\n                            }\n                        }\n                    }\n                }\n            }\n\n            // Conflict resolution (sequential priority assignment)\n            bool conflict = false;\n            for (int j = 0; j < k; ++j) {\n                if (next_cpos[j].first == best_nr && next_cpos[j].second == best_nc) {\n                    conflict = true; break;\n                }\n                // Swap detection\n                if (next_cpos[j].first == r && next_cpos[j].second == c &&\n                    best_nr == cpos[j].first && best_nc == cpos[j].second) {\n                    conflict = true; break;\n                }\n            }\n            if (conflict) {\n                best_act = '.';\n                best_nr = r; best_nc = c;\n            }\n            // Safety re-check for small crane movement rules\n            if (chold[k] != -1 && best_act != '.' && best_act != 'P' && best_act != 'Q') {\n                if (!is_large && grid[best_nr][best_nc] != -1) {\n                    best_act = '.'; best_nr = r; best_nc = c;\n                }\n            }\n\n            actions[k] = best_act;\n            next_cpos[k] = {best_nr, best_nc};\n        }\n\n        // Apply moves simultaneously\n        for (int k = 0; k < 5; ++k) {\n            if (actions[k] != 'P' && actions[k] != 'Q') {\n                cpos[k] = next_cpos[k];\n            }\n        }\n        for (int k = 0; k < 5; ++k) {\n            if (actions[k] == 'P') {\n                int r = cpos[k].first, c = cpos[k].second;\n                if (grid[r][c] != -1) {\n                    chold[k] = grid[r][c];\n                    grid[r][c] = -1;\n                }\n            } else if (actions[k] == 'Q') {\n                int r = cpos[k].first, c = cpos[k].second;\n                if (grid[r][c] == -1 && chold[k] != -1) {\n                    grid[r][c] = chold[k];\n                    chold[k] = -1;\n                }\n            }\n        }\n\n        // Record actions\n        for (int k = 0; k < 5; ++k) S[k] += actions[k];\n\n        // Step 3: Dispatch\n        for (int i = 0; i < 5; ++i) {\n            if (grid[i][4] != -1) {\n                if (grid[i][4] == dnext[i]) {\n                    grid[i][4] = -1;\n                    dnext[i]++;\n                    dispatched_count++;\n                }\n            }\n        }\n\n        if (dispatched_count == 25) break;\n    }\n\n    for (int i = 0; i < 5; ++i) cout << S[i] << \"\\n\";\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Global state\nint N;\nint h[25][25];\nint cur_r = 0, cur_c = 0;\nlong long load = 0;\nint turns = 0;\n\n// Manhattan distance\nint manhattan(int r1, int c1, int r2, int c2) {\n    return abs(r1 - r2) + abs(c1 - c2);\n}\n\n// Output single move step and update state\nvoid move_step(char dir) {\n    cout << dir << \"\\n\";\n    turns++;\n    if (dir == 'U') cur_r--;\n    else if (dir == 'D') cur_r++;\n    else if (dir == 'L') cur_c--;\n    else if (dir == 'R') cur_c++;\n}\n\n// Move truck to target using Manhattan path\nvoid move_to(int tr, int tc) {\n    while (cur_r != tr) {\n        if (cur_r < tr) move_step('D');\n        else move_step('U');\n    }\n    while (cur_c != tc) {\n        if (cur_c < tc) move_step('R');\n        else move_step('L');\n    }\n}\n\n// Load soil from current cell\nvoid do_load(int r, int c) {\n    int d = h[r][c];\n    if (d <= 0) return;\n    cout << \"+\" << d << \"\\n\";\n    load += d;\n    h[r][c] = 0;\n    turns++;\n}\n\n// Unload soil to current cell\nvoid do_unload(int r, int c) {\n    if (load <= 0) return;\n    int d = (int)min((long long)-h[r][c], load);\n    cout << \"-\" << d << \"\\n\";\n    load -= d;\n    h[r][c] += d;\n    turns++;\n}\n\n// Check if grid is completely flat\nbool is_flat() {\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (h[i][j] != 0) return false;\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> h[i][j];\n\n    // Heuristic coefficient balancing distance vs amount processed\n    const double ALPHA = 50.0;\n\n    while (!is_flat() && turns < 99000) {\n        int best_r = -1, best_c = -1;\n        double best_score = 1e18;\n\n        if (load == 0) {\n            // Truck is empty: find best source to pick up soil\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    if (h[i][j] > 0) {\n                        int d = manhattan(cur_r, cur_c, i, j);\n                        // Score = movement cost - benefit of picking up soil\n                        double score = (double)d * 100.0 - (double)h[i][j] * ALPHA;\n                        if (score < best_score) {\n                            best_score = score;\n                            best_r = i; best_c = j;\n                        }\n                    }\n                }\n            }\n        } else {\n            // Truck has load: find best sink to drop soil\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    if (h[i][j] < 0) {\n                        int d = manhattan(cur_r, cur_c, i, j);\n                        int unload_amt = (int)min((long long)-h[i][j], load);\n                        // Score = movement cost (load-dependent) - benefit of dropping soil\n                        double score = (double)d * (100.0 + (double)load) - (double)unload_amt * ALPHA;\n                        if (score < best_score) {\n                            best_score = score;\n                            best_r = i; best_c = j;\n                        }\n                    }\n                }\n            }\n        }\n\n        // Invariant: sum(h) = 0 guarantees we always find a valid target unless flat\n        if (best_r == -1) break;\n\n        move_to(best_r, best_c);\n        if (load == 0) do_load(best_r, best_c);\n        else do_unload(best_r, best_c);\n    }\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <numeric>\n#include <cmath>\n\n#pragma GCC optimize(\"O3,unroll-loops\")\n\nusing namespace std;\n\n// Problem parameters\nint N = 6, M = 15, T = 10;\nint SEED_COUNT = 60;\nvector<vector<int>> X;\nvector<int> V;\n\n// Grid structure\nvector<vector<int>> adj(36);\nbool is_adj[36][36] = {false};\nint degree[36] = {0};\n\nvoid precompute_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 (j + 1 < N) {\n                int v = i * N + (j + 1);\n                adj[u].push_back(v);\n                adj[v].push_back(u);\n                is_adj[u][v] = is_adj[v][u] = true;\n                degree[u]++; degree[v]++;\n            }\n            if (i + 1 < N) {\n                int v = (i + 1) * N + j;\n                adj[u].push_back(v);\n                adj[v].push_back(u);\n                is_adj[u][v] = is_adj[v][u] = true;\n                degree[u]++; degree[v]++;\n            }\n        }\n    }\n}\n\n// Score for a single edge: encourages high expected value + high diversity\ninline double edge_score(int u, int v, double lambda) {\n    double s = V[u] + V[v];\n    double d = 0;\n    const auto& xu = X[u];\n    const auto& xv = X[v];\n    #pragma GCC ivdep\n    for (int l = 0; l < M; ++l) {\n        d += abs(xu[l] - xv[l]);\n    }\n    return s + lambda * d;\n}\n\n// Compute the change in total score if we swap seeds at pos1 and pos2\ndouble calc_delta(const vector<int>& P, int p1, int p2, double lambda, int u1, int u2) {\n    if (p1 == p2) return 0;\n\n    auto get_seed = [&](int pos, bool swapped) -> int {\n        if (swapped) {\n            if (pos == p1) return u2;\n            if (pos == p2) return u1;\n        }\n        return P[pos];\n    };\n\n    auto sum_all = [&](int p, bool swapped) {\n        double s = 0;\n        int seed_p = get_seed(p, swapped);\n        for (int nb : adj[p]) {\n            s += edge_score(seed_p, get_seed(nb, swapped), lambda);\n        }\n        return s;\n    };\n\n    double before = sum_all(p1, false) + sum_all(p2, false);\n    double after  = sum_all(p1, true)  + sum_all(p2, true);\n\n    // If p1 and p2 are adjacent, their edge is counted twice in both sums\n    if (is_adj[p1][p2]) {\n        before -= edge_score(P[p1], P[p2], lambda);\n        after  -= edge_score(u2, u1, lambda);\n    }\n\n    return after - before;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read initial configuration\n    if (!(cin >> N >> M >> T)) return 0;\n    SEED_COUNT = 2 * N * (N - 1);\n    X.assign(SEED_COUNT, vector<int>(M));\n    V.assign(SEED_COUNT, 0);\n\n    for (int i = 0; i < SEED_COUNT; ++i) {\n        for (int j = 0; j < M; ++j) {\n            cin >> X[i][j];\n            V[i] += X[i][j];\n        }\n    }\n\n    precompute_grid();\n\n    mt19937 rng(42);\n    uniform_int_distribution<int> pos_dist(0, 35);\n    \n    // Weight for diversity vs expected value. \n    // 1.0 balances mean value and L1 distance effectively for M=15.\n    const double lambda = 1.0;\n    const int MAX_ITER = 250000;\n\n    vector<int> P(36);\n    vector<int> pos_by_degree(36);\n    iota(pos_by_degree.begin(), pos_by_degree.end(), 0);\n    sort(pos_by_degree.begin(), pos_by_degree.end(), [&](int a, int b) {\n        return degree[a] > degree[b];\n    });\n\n    vector<pair<int, int>> seed_idx_val(SEED_COUNT);\n    for (int i = 0; i < SEED_COUNT; ++i) seed_idx_val[i] = {i, V[i]};\n\n    for (int t = 0; t < T; ++t) {\n        // 1. Select top 36 seeds by current value\n        sort(seed_idx_val.begin(), seed_idx_val.end(), [&](const auto& a, const auto& b) {\n            return a.second > b.second;\n        });\n\n        vector<int> top_seeds(36);\n        for (int i = 0; i < 36; ++i) top_seeds[i] = seed_idx_val[i].first;\n\n        // 2. Initial placement: highest value seeds to highest degree positions\n        sort(top_seeds.begin(), top_seeds.end(), [&](int a, int b) {\n            return V[a] > V[b];\n        });\n        for (int i = 0; i < 36; ++i) P[pos_by_degree[i]] = top_seeds[i];\n\n        // 3. Hill climbing to maximize placement score\n        for (int iter = 0; iter < MAX_ITER; ++iter) {\n            int p1 = pos_dist(rng);\n            int p2 = pos_dist(rng);\n            if (p1 == p2) continue;\n\n            int u1 = P[p1], u2 = P[p2];\n            double delta = calc_delta(P, p1, p2, lambda, u1, u2);\n            if (delta > 0) {\n                P[p1] = u2;\n                P[p2] = u1;\n            }\n        }\n\n        // 4. Output placement\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                cout << P[i * N + j] << (j == N - 1 ? \"\" : \" \");\n            }\n            cout << \"\\n\";\n        }\n        cout.flush();\n\n        // 5. Read new seeds if not the last turn\n        if (t < T - 1) {\n            for (int i = 0; i < SEED_COUNT; ++i) {\n                V[i] = 0;\n                for (int j = 0; j < M; ++j) {\n                    cin >> X[i][j];\n                    V[i] += X[i][j];\n                }\n            }\n            for (int i = 0; i < SEED_COUNT; ++i) seed_idx_val[i] = {i, V[i]};\n        }\n    }\n\n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n\nusing namespace std;\n\nint N, M, V;\nvector<string> S, T;\nint finger_dir[20]; // 0:R, 1:D, 2:L, 3:U\nint carried = 0;\nint rx = 0, ry = 0;\nconst int dx[4] = {0, 1, 0, -1}; // R, D, L, U\nconst int dy[4] = {1, 0, -1, 0};\nconst char dch[4] = {'R', 'D', 'L', 'U'};\n\nvector<vector<bool>> is_pickup;\nvector<vector<bool>> is_drop;\nint dist[30][30];\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> V)) return 0;\n    S.resize(N); T.resize(N);\n    for (int i = 0; i < N; ++i) cin >> S[i];\n    for (int i = 0; i < N; ++i) cin >> T[i];\n\n    is_pickup.assign(N, vector<bool>(N, false));\n    is_drop.assign(N, vector<bool>(N, false));\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (S[i][j] == '1' && T[i][j] == '0') is_pickup[i][j] = true;\n            if (T[i][j] == '1' && S[i][j] == '0') is_drop[i][j] = true;\n        }\n    }\n\n    // Output tree design: Star graph with root 0 and leaves 1..V-1\n    cout << V << \"\\n\";\n    for (int i = 1; i < V; ++i) {\n        cout << \"0 1\\n\";\n    }\n    // Initial root position\n    cout << rx << \" \" << ry << \"\\n\";\n\n    // Initialize finger directions (all pointing Right initially)\n    for (int i = 0; i < V; ++i) finger_dir[i] = 0;\n\n    int turn = 0;\n    const int MAX_TURNS = 100000;\n\n    while (turn < MAX_TURNS) {\n        // Check if done\n        bool has_pickup = false, has_drop = false;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (is_pickup[i][j]) has_pickup = true;\n                if (is_drop[i][j]) has_drop = true;\n            }\n        }\n        if (!has_pickup && carried == 0) break;\n\n        // Multi-source BFS to find distance to nearest actionable root position\n        // Actionable root positions are neighbors of pickup/drop cells\n        vector<pair<int, int>> sources;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (is_pickup[i][j] || is_drop[i][j]) {\n                    for (int d = 0; d < 4; ++d) {\n                        int ni = i + dx[d], nj = j + dy[d];\n                        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                            sources.push_back({ni, nj});\n                        }\n                    }\n                }\n            }\n        }\n\n        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) dist[i][j] = 1e9;\n        queue<pair<int, int>> q;\n        for (auto& p : sources) {\n            if (dist[p.first][p.second] == 1e9) {\n                dist[p.first][p.second] = 0;\n                q.push(p);\n            }\n        }\n\n        while (!q.empty()) {\n            auto [cx, cy] = q.front(); q.pop();\n            for (int d = 0; d < 4; ++d) {\n                int nx = cx + dx[d], ny = cy + dy[d];\n                if (nx >= 0 && nx < N && ny >= 0 && ny < N) {\n                    if (dist[nx][ny] == 1e9) {\n                        dist[nx][ny] = dist[cx][cy] + 1;\n                        q.push({nx, ny});\n                    }\n                }\n            }\n        }\n\n        // Decide root move: choose direction that minimizes dist to actionable position\n        int best_d = -1;\n        int best_dist = 1e9;\n        for (int d = 0; d < 4; ++d) {\n            int nx = rx + dx[d], ny = ry + dy[d];\n            if (nx >= 0 && nx < N && ny >= 0 && ny < N) {\n                if (dist[nx][ny] < best_dist) {\n                    best_dist = dist[nx][ny];\n                    best_d = d;\n                }\n            }\n        }\n        // If staying is optimal or no move improves, stay\n        if (best_dist > dist[rx][ry]) best_d = -1;\n\n        char move_c = '.';\n        if (best_d != -1) {\n            move_c = dch[best_d];\n            rx += dx[best_d];\n            ry += dy[best_d];\n        }\n\n        // Collect immediate tasks from neighbors\n        struct Task { int dir, type; }; // type: 1 pickup, 2 drop\n        vector<Task> tasks;\n        for (int d = 0; d < 4; ++d) {\n            int nx = rx + dx[d], ny = ry + dy[d];\n            if (nx >= 0 && nx < N && ny >= 0 && ny < N) {\n                if (is_pickup[nx][ny]) tasks.push_back({d, 1});\n                else if (is_drop[nx][ny]) tasks.push_back({d, 2});\n            }\n        }\n\n        // Prioritize tasks based on capacity\n        if (carried > (V - 1) / 2) {\n            // Full: prioritize drops\n            stable_sort(tasks.begin(), tasks.end(), [](const Task& a, const Task& b) {\n                return a.type > b.type; // drops (2) first\n            });\n        } else {\n            // Not full: prioritize pickups\n            stable_sort(tasks.begin(), tasks.end(), [](const Task& a, const Task& b) {\n                return a.type < b.type; // pickups (1) first\n            });\n        }\n\n        string cmd(2 * V, '.');\n        cmd[0] = move_c;\n\n        int task_idx = 0;\n        for (int i = 1; i < V; ++i) {\n            char rot = '.';\n            int target_d = -1;\n\n            if (task_idx < tasks.size()) {\n                target_d = tasks[task_idx].dir;\n                int cur = finger_dir[i];\n                int target = target_d;\n                int diff = (target - cur + 4) % 4;\n\n                if (diff == 1) rot = 'R';       // CW\n                else if (diff == 2) rot = 'R';  // 2 steps CW\n                else if (diff == 3) rot = 'L';  // CCW\n                else rot = '.';\n\n                // Update simulated direction\n                if (rot == 'R') finger_dir[i] = (cur + 1) % 4;\n                else if (rot == 'L') finger_dir[i] = (cur + 3) % 4;\n            }\n\n            cmd[i] = rot;\n\n            // Perform action if aligned\n            if (target_d != -1 && finger_dir[i] == target_d) {\n                int nx = rx + dx[target_d], ny = ry + dy[target_d];\n                bool success = false;\n\n                if (tasks[task_idx].type == 1) { // Pickup\n                    if (carried < V - 1) {\n                        is_pickup[nx][ny] = false;\n                        carried++;\n                        success = true;\n                    }\n                } else { // Drop\n                    if (carried > 0) {\n                        is_drop[nx][ny] = false;\n                        carried--;\n                        success = true;\n                    }\n                }\n\n                if (success) {\n                    cmd[V + i] = 'P';\n                    task_idx++; // Task completed, move to next\n                }\n                // If failed due to capacity, keep task_idx so next finger can try (though likely same capacity constraint)\n                // But to prevent infinite attempts, we just move forward if capacity blocks\n                if (tasks[task_idx].type == 1 && carried >= V - 1) task_idx = tasks.size();\n                if (tasks[task_idx].type == 2 && carried <= 0) task_idx = tasks.size();\n            }\n        }\n\n        cout << cmd << \"\\n\";\n        turn++;\n    }\n\n    return 0;\n}","ahc039":"#include <iostream>\n#include <vector>\n#include <random>\n#include <cmath>\n#include <algorithm>\n#include <map>\n#include <queue>\n#include <set>\n\nusing namespace std;\n\nstruct Pt {\n    int x, y;\n    bool operator==(const Pt& o) const { return x == o.x && y == o.y; }\n    bool operator<(const Pt& o) const { return x != o.x ? x < o.x : y < o.y; }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    if (!(cin >> N)) return 0;\n    vector<Pt> mack(N), sard(N);\n    for (int i = 0; i < N; ++i) cin >> mack[i].x >> mack[i].y;\n    for (int i = 0; i < N; ++i) cin >> sard[i].x >> sard[i].y;\n\n    // Grid parameters: D = cell size, G = grid dimensions\n    const int D = 400;\n    const int G = 100000 / D + 2; // ~252\n    vector<vector<int>> grid(G, vector<int>(G, 0));\n    vector<vector<bool>> sel(G, vector<bool>(G, false));\n\n    auto add_points = [&](const vector<Pt>& pts, int val) {\n        for (auto& p : pts) {\n            int cx = p.x / D;\n            int cy = p.y / D;\n            if (cx >= 0 && cx < G && cy >= 0 && cy < G) {\n                grid[cy][cx] += val;\n            }\n        }\n    };\n    add_points(mack, 1);\n    add_points(sard, -1);\n\n    mt19937 rng(42); // Fixed seed for reproducibility\n    double T = 100.0;\n    int iters = 350000;\n\n    // Initialize SA with the best single cell\n    int best_r = 0, best_c = 0, best_w = -1e9;\n    for (int r = 0; r < G; ++r) {\n        for (int c = 0; c < G; ++c) {\n            if (grid[r][c] > best_w) {\n                best_w = grid[r][c]; best_r = r; best_c = c;\n            }\n        }\n    }\n    sel[best_r][best_c] = true;\n\n    int dr[] = {-1, 1, 0, 0};\n    int dc[] = {0, 0, -1, 1};\n\n    for (int it = 0; it < iters; ++it) {\n        T *= 0.99996;\n        if (T < 0.05) T = 0.05;\n\n        int r = rng() % G;\n        int c = rng() % G;\n\n        bool is_sel = sel[r][c];\n        bool can_toggle = false;\n\n        if (!is_sel) {\n            // Only add if adjacent to selected region\n            for (int i = 0; i < 4; ++i) {\n                int nr = r + dr[i], nc = c + dc[i];\n                if (nr >= 0 && nr < G && nc >= 0 && nc < G && sel[nr][nc]) {\n                    can_toggle = true; break;\n                }\n            }\n        } else {\n            // Only remove if on boundary (has unselected neighbor or grid edge)\n            bool on_boundary = false;\n            for (int i = 0; i < 4; ++i) {\n                int nr = r + dr[i], nc = c + dc[i];\n                if (nr < 0 || nr >= G || nc < 0 || nc >= G || !sel[nr][nc]) {\n                    on_boundary = true; break;\n                }\n            }\n            can_toggle = on_boundary;\n        }\n\n        if (!can_toggle) continue;\n\n        int delta = is_sel ? -grid[r][c] : grid[r][c];\n        // Clamp exponent to avoid overflow/underflow\n        double prob = 0.0;\n        if (delta > 0) prob = 1.0;\n        else {\n            double val = delta / T;\n            if (val < -50) val = -50;\n            if (val > 50) val = 50;\n            prob = exp(val);\n        }\n        if ((rng() / 4294967295.0) < prob) {\n            sel[r][c] = !is_sel;\n        }\n    }\n\n    // Post-processing 1: Keep only the largest 4-connected component\n    vector<vector<bool>> final_sel(G, vector<bool>(G, false));\n    vector<vector<bool>> visited(G, vector<bool>(G, false));\n    int start_r = -1, start_c = -1;\n    for (int r = 0; r < G; ++r) {\n        for (int c = 0; c < G; ++c) {\n            if (sel[r][c]) { start_r = r; start_c = c; r = G; break; }\n        }\n    }\n\n    if (start_r != -1) {\n        queue<pair<int, int>> q;\n        q.emplace(start_r, start_c);\n        visited[start_r][start_c] = true;\n        while (!q.empty()) {\n            auto [r, c] = q.front(); q.pop();\n            final_sel[r][c] = true;\n            for (int i = 0; i < 4; ++i) {\n                int nr = r + dr[i], nc = c + dc[i];\n                if (nr >= 0 && nr < G && nc >= 0 && nc < G && sel[nr][nc] && !visited[nr][nc]) {\n                    visited[nr][nc] = true;\n                    q.emplace(nr, nc);\n                }\n            }\n        }\n    }\n\n    // Post-processing 2: Fill holes using flood fill from outside\n    vector<vector<bool>> outside(G, vector<bool>(G, false));\n    queue<pair<int, int>> q_out;\n    // Push boundary cells that are not selected\n    for (int c = 0; c < G; ++c) {\n        if (!final_sel[0][c]) { outside[0][c] = true; q_out.emplace(0, c); }\n        if (!final_sel[G-1][c]) { outside[G-1][c] = true; q_out.emplace(G-1, c); }\n    }\n    for (int r = 0; r < G; ++r) {\n        if (!final_sel[r][0]) { outside[r][0] = true; q_out.emplace(r, 0); }\n        if (!final_sel[r][G-1]) { outside[r][G-1] = true; q_out.emplace(r, G-1); }\n    }\n    while (!q_out.empty()) {\n        auto [r, c] = q_out.front(); q_out.pop();\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i], nc = c + dc[i];\n            if (nr >= 0 && nr < G && nc >= 0 && nc < G && !final_sel[nr][nc] && !outside[nr][nc]) {\n                outside[nr][nc] = true;\n                q_out.emplace(nr, nc);\n            }\n        }\n    }\n    for (int r = 0; r < G; ++r) {\n        for (int c = 0; c < G; ++c) {\n            if (!final_sel[r][c] && !outside[r][c]) {\n                final_sel[r][c] = true; // Hole filled\n            }\n        }\n    }\n\n    // Edge extraction: interior edges cancel out, boundary edges remain\n    map<pair<Pt, Pt>, int> edge_cnt;\n    auto add_edge = [&](Pt u, Pt v) {\n        if (u.x > v.x || (u.x == v.x && u.y > v.y)) swap(u, v);\n        edge_cnt[{u, v}]++;\n    };\n\n    for (int r = 0; r < G; ++r) {\n        for (int c = 0; c < G; ++c) {\n            if (final_sel[r][c]) {\n                Pt p1 = {c * D, r * D};\n                Pt p2 = {(c + 1) * D, r * D};\n                Pt p3 = {(c + 1) * D, (r + 1) * D};\n                Pt p4 = {c * D, (r + 1) * D};\n                add_edge(p1, p2); add_edge(p2, p3);\n                add_edge(p3, p4); add_edge(p4, p1);\n            }\n        }\n    }\n\n    // Build adjacency graph for tracing\n    map<Pt, vector<Pt>> adj;\n    for (auto& [e, cnt] : edge_cnt) {\n        if (cnt % 2 == 1) { // Boundary edge\n            adj[e.first.first].push_back(e.first.second);\n            adj[e.first.second].push_back(e.first.first);\n        }\n    }\n\n    // Trace the polygon\n    vector<Pt> poly;\n    if (!adj.empty()) {\n        Pt curr = adj.begin()->first;\n        Pt prev = {-1, -1};\n        int steps = 0;\n        while (steps < 20000) { // Safety limit\n            poly.push_back(curr);\n            Pt next = {-1, -1};\n            for (auto& nb : adj[curr]) {\n                if (!(nb == prev)) {\n                    next = nb;\n                    break;\n                }\n            }\n            prev = curr;\n            curr = next;\n            if (curr == poly[0]) break;\n            steps++;\n        }\n    }\n\n    // Remove collinear vertices to reduce vertex count\n    vector<Pt> simplified;\n    int m = poly.size();\n    for (int i = 0; i < m; ++i) {\n        Pt prev = poly[(i - 1 + m) % m];\n        Pt curr = poly[i];\n        Pt next = poly[(i + 1) % m];\n        long long dx1 = curr.x - prev.x;\n        long long dy1 = curr.y - prev.y;\n        long long dx2 = next.x - curr.x;\n        long long dy2 = next.y - curr.y;\n        // Cross product != 0 means not collinear\n        if (dx1 * dy2 != dx2 * dy1) {\n            simplified.push_back(curr);\n        }\n    }\n    if (simplified.empty() && !poly.empty()) simplified = poly;\n\n    // Ensure m >= 4 and valid format\n    while (simplified.size() < 4) {\n        if (simplified.empty()) {\n            simplified = {{0, 0}, {D, 0}, {D, D}, {0, D}};\n        } else {\n            Pt p = simplified.back();\n            simplified.push_back(p);\n        }\n    }\n\n    // Output\n    cout << simplified.size() << \"\\n\";\n    for (auto& p : simplified) {\n        cout << p.x << \" \" << p.y << \"\\n\";\n    }\n\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\n#include <cmath>\nusing namespace std;\n#pragma GCC optimize(\"O3,unroll-loops\")\n\nstruct Choice { \n    bool skipped = false; \n    bool rot = false; \n    char dir = 'U'; \n    int ref = -1; \n};\nstruct Rect { int x, y, w, h; };\n\nmt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Fast simulation of the packing process\nlong long evaluate(int N, const vector<Choice>& cfg, const vector<pair<int,int>>& wh, long long& skip_pen) {\n    vector<pair<int, Rect>> placed;\n    placed.reserve(N);\n    int max_x = 0, max_y = 0;\n    \n    for (int i = 0; i < N; ++i) {\n        if (cfg[i].skipped) continue;\n        int w = cfg[i].rot ? wh[i].second : wh[i].first;\n        int h = cfg[i].rot ? wh[i].first : wh[i].second;\n        int x = 0, y = 0;\n        int ref = cfg[i].ref;\n        \n        // Align with reference rectangle if valid\n        if (ref != -1 && !cfg[ref].skipped) {\n            for (auto& p : placed) if (p.first == ref) {\n                if (cfg[i].dir == 'U') x = p.second.x + p.second.w;\n                else y = p.second.y + p.second.h;\n                break;\n            }\n        }\n        \n        if (cfg[i].dir == 'U') {\n            // Move upward (decrease y) until hitting y=0 or bottom of another rect\n            int y_floor = 0;\n            for (auto& p : placed) {\n                // Check horizontal overlap\n                if (x < p.second.x + p.second.w && p.second.x < x + w)\n                    y_floor = max(y_floor, p.second.y);\n            }\n            y = max(0, y_floor - h);\n        } else {\n            // Move leftward (decrease x) until hitting x=0 or right edge of another rect\n            int x_floor = 0;\n            for (auto& p : placed) {\n                // Check vertical overlap\n                if (y < p.second.y + p.second.h && p.second.y < y + h)\n                    x_floor = max(x_floor, p.second.x + p.second.w);\n            }\n            x = max(0, x_floor);\n        }\n        \n        placed.push_back({i, {x, y, w, h}});\n        if (x + w > max_x) max_x = x + w;\n        if (y + h > max_y) max_y = y + h;\n    }\n    \n    skip_pen = 0;\n    for (int i = 0; i < N; ++i) \n        if (cfg[i].skipped) skip_pen += wh[i].first + wh[i].second;\n        \n    return max_x + max_y + skip_pen;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    \n    int N, T, sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n    \n    vector<pair<int,int>> wh(N);\n    for (int i = 0; i < N; ++i) cin >> wh[i].first >> wh[i].second;\n\n    // Initial configuration\n    vector<Choice> cur(N), best(N);\n    for (int i = 0; i < N; ++i) {\n        cur[i].rot = rng() & 1;\n        cur[i].dir = (rng() & 1) ? 'U' : 'L';\n        cur[i].ref = -1;\n        cur[i].skipped = (rng() % 5 == 0); // Start with ~20% skipped\n    }\n\n    long long skip_pen;\n    long long cur_cost = evaluate(N, cur, wh, skip_pen);\n    long long best_cost = cur_cost;\n    best = cur;\n\n    double temp = 5000.0;\n    auto start_time = chrono::steady_clock::now();\n\n    for (int turn = 0; turn < T; ++turn) {\n        // Read feedback from previous turn (ignored as noise is high, local sim is reliable)\n        if (turn > 0) {\n            int W_in, H_in; \n            cin >> W_in >> H_in;\n        }\n\n        // Simulated Annealing loop\n        while (true) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double, std::milli>(now - start_time).count();\n            if (elapsed > 2850.0) break; // Leave margin for I/O and final output\n\n            vector<Choice> next = cur;\n            int i = rng() % N;\n            int type = rng() % 5;\n\n            if (type == 0) {\n                next[i].skipped = !next[i].skipped;\n            } else if (type == 1) {\n                next[i].rot = !next[i].rot;\n            } else if (type == 2) {\n                next[i].dir = (next[i].dir == 'U' ? 'L' : 'U');\n            } else {\n                // Change reference to a valid non-skipped previous rectangle\n                int r = -1;\n                if (i > 0) {\n                    int cand = rng() % i;\n                    if (!next[cand].skipped) r = cand;\n                }\n                next[i].ref = r;\n            }\n\n            long long n_skip_pen;\n            long long next_cost = evaluate(N, next, wh, n_skip_pen);\n\n            // Metropolis acceptance criterion\n            if (next_cost < cur_cost || (double)(rng() & 0xFFFFFF) / 0xFFFFFF < exp(max(-50.0, (cur_cost - next_cost) / temp))) {\n                cur = next;\n                cur_cost = next_cost;\n                skip_pen = n_skip_pen;\n                if (cur_cost < best_cost) {\n                    best_cost = cur_cost;\n                    best = cur;\n                }\n            }\n            \n            if (temp > 1e-5) temp *= 0.99995;\n        }\n\n        if (cur_cost < best_cost) {\n            best = cur;\n            best_cost = cur_cost;\n        }\n\n        // Output best configuration found so far\n        int n_place = 0;\n        for (int i = 0; i < N; ++i) if (!best[i].skipped) n_place++;\n        \n        cout << n_place << \"\\n\";\n        for (int i = 0; i < N; ++i) {\n            if (!best[i].skipped) {\n                cout << i << \" \" << best[i].rot << \" \" << best[i].dir << \" \" << best[i].ref << \"\\n\";\n            }\n        }\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc041":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n\nusing namespace std;\n\nconst int INF = 1e9;\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, H;\n    if (!(cin >> N >> M >> H)) return 0;\n\n    vector<int> A(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> A[i];\n    }\n\n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n\n    // Read and ignore coordinates\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    // APSP using BFS from each node\n    vector<vector<int>> dist(N, vector<int>(N, INF));\n\n    for (int i = 0; i < N; ++i) {\n        queue<int> q;\n        dist[i][i] = 0;\n        q.push(i);\n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            for (int v : adj[u]) {\n                if (dist[i][v] == INF) {\n                    dist[i][v] = dist[i][u] + 1;\n                    q.push(v);\n                }\n            }\n        }\n    }\n\n    // d[u] stores the distance from u to the nearest root found so far.\n    vector<int> d(N, INF);\n\n    // Greedy root selection loop\n    while (true) {\n        int best_v = -1;\n        int min_A = INF;\n        bool all_covered = true;\n\n        // Find uncovered node with minimum beauty value\n        for (int i = 0; i < N; ++i) {\n            if (d[i] > H) {\n                all_covered = false;\n                if (A[i] < min_A) {\n                    min_A = A[i];\n                    best_v = i;\n                }\n            }\n        }\n\n        if (all_covered) break;\n\n        // Candidates are nodes that can cover best_v (distance <= H)\n        vector<int> candidates;\n        candidates.reserve(N);\n        for (int r = 0; r < N; ++r) {\n            if (dist[r][best_v] <= H) {\n                candidates.push_back(r);\n            }\n        }\n\n        // Sort candidates by their beauty value ascending\n        sort(candidates.begin(), candidates.end(), [&](int a, int b) {\n            return A[a] < A[b];\n        });\n\n        // Evaluate top K candidates to find the one that maximizes the score\n        int K = 50; \n        int limit = min((int)candidates.size(), K);\n\n        int best_r = -1;\n        long long best_score = -1;\n\n        for (int i = 0; i < limit; ++i) {\n            int r = candidates[i];\n            long long current_score = 0;\n            const auto& dist_r = dist[r];\n            \n            // Compute score if root r is added\n            for (int u = 0; u < N; ++u) {\n                int new_dist = d[u];\n                if (dist_r[u] < new_dist) {\n                    new_dist = dist_r[u];\n                }\n                \n                // If distance > H, contribution is capped at H * A[u]\n                int val = (new_dist > H) ? H : new_dist;\n                current_score += (long long)A[u] * val;\n            }\n\n            if (current_score > best_score) {\n                best_score = current_score;\n                best_r = r;\n            }\n        }\n\n        // Add the best root and update distances\n        const auto& dist_br = dist[best_r];\n        for (int u = 0; u < N; ++u) {\n            if (dist_br[u] < d[u]) {\n                d[u] = dist_br[u];\n            }\n        }\n    }\n\n    // Construct the forest\n    vector<int> p(N, -1);\n    vector<int> h(N);\n    for (int i = 0; i < N; ++i) {\n        h[i] = d[i];\n    }\n\n    for (int i = 0; i < N; ++i) {\n        if (h[i] > 0) {\n            int target_h = h[i] - 1;\n            int parent = -1;\n            // Find a neighbor with height target_h\n            for (int neighbor : adj[i]) {\n                if (h[neighbor] == target_h) {\n                    parent = neighbor;\n                    break;\n                }\n            }\n            p[i] = parent;\n        }\n    }\n\n    // Output\n    for (int i = 0; i < N; ++i) {\n        cout << p[i] << (i == N - 1 ? \"\" : \" \");\n    }\n    cout << \"\\n\";\n\n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <utility>\n\nusing namespace std;\n\nint N;\nvector<string> board;\n\n// Shift row r to the left\nvoid shift_row_left(int r) {\n    for (int j = 0; j < N - 1; j++) {\n        board[r][j] = board[r][j + 1];\n    }\n    board[r][N - 1] = '.'; // Vacated space becomes empty\n}\n\n// Shift row r to the right\nvoid shift_row_right(int r) {\n    for (int j = N - 1; j > 0; j--) {\n        board[r][j] = board[r][j - 1];\n    }\n    board[r][0] = '.'; // Vacated space becomes empty\n}\n\n// Shift column c upward\nvoid shift_col_up(int c) {\n    for (int i = 0; i < N - 1; i++) {\n        board[i][c] = board[i + 1][c];\n    }\n    board[N - 1][c] = '.'; // Vacated space becomes empty\n}\n\n// Shift column c downward\nvoid shift_col_down(int c) {\n    for (int i = N - 1; i > 0; i--) {\n        board[i][c] = board[i - 1][c];\n    }\n    board[0][c] = '.'; // Vacated space becomes empty\n}\n\n// Check if there are no Fukunokami ('o') above (r, c)\nbool is_clear_up(int r, int c) {\n    for (int i = 0; i < r; i++) {\n        if (board[i][c] == 'o') return false;\n    }\n    return true;\n}\n\n// Check if there are no Fukunokami ('o') below (r, c)\nbool is_clear_down(int r, int c) {\n    for (int i = r + 1; i < N; i++) {\n        if (board[i][c] == 'o') return false;\n    }\n    return true;\n}\n\n// Check if there are no Fukunokami ('o') to the left of (r, c)\nbool is_clear_left(int r, int c) {\n    for (int j = 0; j < c; j++) {\n        if (board[r][j] == 'o') return false;\n    }\n    return true;\n}\n\n// Check if there are no Fukunokami ('o') to the right of (r, c)\nbool is_clear_right(int r, int c) {\n    for (int j = c + 1; j < N; j++) {\n        if (board[r][j] == 'o') return false;\n    }\n    return true;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    if (!(cin >> N)) return 0;\n    board.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> board[i];\n    }\n    \n    vector<pair<char, int>> ops;\n    \n    // Loop until all Oni are removed\n    while (true) {\n        int min_cost = 1e9;\n        char best_dir = 0;\n        int best_r = -1, best_c = -1;\n        bool found_oni = false;\n        \n        // Find the Oni with the minimum removal cost\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (board[i][j] == 'x') {\n                    found_oni = true;\n                    // Check Up\n                    if (is_clear_up(i, j)) {\n                        int cost = 2 * (i + 1);\n                        if (cost < min_cost) {\n                            min_cost = cost;\n                            best_dir = 'U';\n                            best_r = i;\n                            best_c = j;\n                        }\n                    }\n                    // Check Down\n                    if (is_clear_down(i, j)) {\n                        int cost = 2 * (N - i);\n                        if (cost < min_cost) {\n                            min_cost = cost;\n                            best_dir = 'D';\n                            best_r = i;\n                            best_c = j;\n                        }\n                    }\n                    // Check Left\n                    if (is_clear_left(i, j)) {\n                        int cost = 2 * (j + 1);\n                        if (cost < min_cost) {\n                            min_cost = cost;\n                            best_dir = 'L';\n                            best_r = i;\n                            best_c = j;\n                        }\n                    }\n                    // Check Right\n                    if (is_clear_right(i, j)) {\n                        int cost = 2 * (N - j);\n                        if (cost < min_cost) {\n                            min_cost = cost;\n                            best_dir = 'R';\n                            best_r = i;\n                            best_c = j;\n                        }\n                    }\n                }\n            }\n        }\n        \n        if (!found_oni) break;\n        if (best_dir == 0) {\n            // Should not happen based on problem guarantees\n            break;\n        }\n        \n        int shifts = 0;\n        if (best_dir == 'U') shifts = best_r + 1;\n        else if (best_dir == 'D') shifts = N - best_r;\n        else if (best_dir == 'L') shifts = best_c + 1;\n        else if (best_dir == 'R') shifts = N - best_c;\n        \n        // Parameter for the operation: column index for U/D, row index for L/R\n        int param = (best_dir == 'U' || best_dir == 'D') ? best_c : best_r;\n        \n        // Push phase: Shift in the clear direction to remove the Oni\n        for (int k = 0; k < shifts; k++) {\n            ops.push_back({best_dir, param});\n            if (best_dir == 'U') shift_col_up(best_c);\n            else if (best_dir == 'D') shift_col_down(best_c);\n            else if (best_dir == 'L') shift_row_left(best_r);\n            else if (best_dir == 'R') shift_row_right(best_r);\n        }\n        \n        // Pull phase: Shift back to restore the board state\n        char pull_dir = 0;\n        if (best_dir == 'U') pull_dir = 'D';\n        else if (best_dir == 'D') pull_dir = 'U';\n        else if (best_dir == 'L') pull_dir = 'R';\n        else if (best_dir == 'R') pull_dir = 'L';\n        \n        for (int k = 0; k < shifts; k++) {\n            ops.push_back({pull_dir, param});\n            if (pull_dir == 'U') shift_col_up(best_c);\n            else if (pull_dir == 'D') shift_col_down(best_c);\n            else if (pull_dir == 'L') shift_row_left(best_r);\n            else if (pull_dir == 'R') shift_row_right(best_r);\n        }\n    }\n    \n    // Output the sequence of operations\n    for (const auto& op : ops) {\n        cout << op.first << \" \" << op.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Global variables to store input and best solution\nint N, L;\nint T[105];\nint best_a[105], best_b[105];\nlong long best_err = 2e18;\n\n// Simulation function\n// Computes the error and optionally stores the final counts in res_cnt\nlong long simulate(int* a, int* b, int* res_cnt) {\n    int cnt[105] = {0};\n    int cur = 0;\n    // Simulate L weeks\n    for(int w = 0; w < L; ++w) {\n        cnt[cur]++;\n        if(w == L - 1) break;\n        int t = cnt[cur];\n        // If t is odd, next is a[cur], else b[cur]\n        cur = (t & 1) ? a[cur] : b[cur];\n    }\n    \n    if(res_cnt) {\n        for(int i = 0; i < N; ++i) res_cnt[i] = cnt[i];\n    }\n    \n    long long err = 0;\n    for(int i = 0; i < N; ++i) {\n        err += abs(cnt[i] - T[i]);\n    }\n    return err;\n}\n\nint main() {\n    // Fast I/O\n    cin.tie(nullptr);\n    ios::sync_with_stdio(false);\n    \n    if(!(cin >> N >> L)) return 0;\n    for(int i = 0; i < N; ++i) cin >> T[i];\n\n    // Random number generator\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist(0, N - 1);\n    uniform_real_distribution<double> dist01(0.0, 1.0);\n\n    int cur_a[105], cur_b[105];\n    // Initialize with -1 to indicate undefined\n    for(int i = 0; i < N; ++i) cur_a[i] = cur_b[i] = -1;\n\n    // Greedy initialization to get a valid and decent starting solution\n    {\n        int g_cnt[105] = {0};\n        int cur = 0;\n        for(int w = 0; w < L; ++w) {\n            g_cnt[cur]++;\n            if(w == L - 1) break;\n            int t = g_cnt[cur];\n            int next = -1;\n            if(t & 1) { // Odd\n                if(cur_a[cur] != -1) {\n                    next = cur_a[cur];\n                } else {\n                    // Choose the employee with the largest deficit (T[i] - g_cnt[i])\n                    int best = 0, max_def = -1e9;\n                    for(int i = 0; i < N; ++i) {\n                        int def = T[i] - g_cnt[i];\n                        if(def > max_def) {\n                            max_def = def;\n                            best = i;\n                        }\n                    }\n                    cur_a[cur] = best;\n                    next = best;\n                }\n            } else { // Even\n                if(cur_b[cur] != -1) {\n                    next = cur_b[cur];\n                } else {\n                    int best = 0, max_def = -1e9;\n                    for(int i = 0; i < N; ++i) {\n                        int def = T[i] - g_cnt[i];\n                        if(def > max_def) {\n                            max_def = def;\n                            best = i;\n                        }\n                    }\n                    cur_b[cur] = best;\n                    next = best;\n                }\n            }\n            cur = next;\n        }\n        // Fill any remaining undefined transitions randomly\n        for(int i = 0; i < N; ++i) {\n            if(cur_a[i] == -1) cur_a[i] = dist(rng);\n            if(cur_b[i] == -1) cur_b[i] = dist(rng);\n        }\n    }\n\n    // Evaluate the initial solution\n    int current_cnt[105];\n    long long current_err = simulate(cur_a, cur_b, current_cnt);\n    best_err = current_err;\n    for(int i = 0; i < N; ++i) {\n        best_a[i] = cur_a[i];\n        best_b[i] = cur_b[i];\n    }\n\n    // Simulated Annealing\n    double temp = 50000.0;\n    auto start = chrono::steady_clock::now();\n\n    while(true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if(elapsed > 1.85) break; // Leave some margin for output\n\n        // Cooling schedule\n        temp *= 0.998;\n\n        // Perturbation: change one random transition\n        int idx = dist(rng);\n        bool change_a = (dist(rng) & 1);\n        int old_val = change_a ? cur_a[idx] : cur_b[idx];\n        int new_val = dist(rng);\n        \n        if(change_a) cur_a[idx] = new_val;\n        else cur_b[idx] = new_val;\n\n        long long next_err = simulate(cur_a, cur_b, current_cnt);\n\n        if(next_err < current_err) {\n            current_err = next_err;\n            if(next_err < best_err) {\n                best_err = next_err;\n                for(int i = 0; i < N; ++i) {\n                    best_a[i] = cur_a[i];\n                    best_b[i] = cur_b[i];\n                }\n            }\n        } else {\n            // Metropolis criterion\n            double prob = exp((current_err - next_err) / temp);\n            if(dist01(rng) < prob) {\n                current_err = next_err;\n            } else {\n                // Revert change\n                if(change_a) cur_a[idx] = old_val;\n                else cur_b[idx] = old_val;\n            }\n        }\n    }\n\n    // Output the best solution found\n    for(int i = 0; i < N; ++i) {\n        cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n    }\n\n    return 0;\n}","ahc045":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <numeric>\n#include <tuple>\n\nusing namespace std;\n\n// Disjoint Set Union (Union-Find) structure\nstruct DSU {\n    vector<int> parent;\n    vector<int> rank;\n    DSU(int n) : parent(n), rank(n, 0) { \n        iota(parent.begin(), parent.end(), 0); \n    }\n    int find(int x) { \n        return parent[x] == x ? x : parent[x] = find(parent[x]); \n    }\n    bool unite(int x, int y) {\n        x = find(x); y = find(y);\n        if (x != y) {\n            if (rank[x] < rank[y]) swap(x, y);\n            parent[y] = x;\n            if (rank[x] == rank[y]) rank[x]++;\n            return true;\n        }\n        return false;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, Q, L, W;\n    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n    \n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    \n    vector<int> lx(N), rx(N), ly(N), ry(N);\n    vector<long long> cx2(N), cy2(N); // 2 * center coordinates to avoid floats\n    for (int i = 0; i < N; ++i) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n        cx2[i] = lx[i] + rx[i];\n        cy2[i] = ly[i] + ry[i];\n    }\n\n    // Sort cities by estimated center position\n    vector<int> p(N);\n    iota(p.begin(), p.end(), 0);\n    sort(p.begin(), p.end(), [&](int a, int b) {\n        if (cx2[a] != cx2[b]) return cx2[a] < cx2[b];\n        return cy2[a] < cy2[b];\n    });\n\n    // Partition sorted cities into groups of specified sizes\n    vector<vector<int>> groups(M);\n    int idx = 0;\n    for (int i = 0; i < M; ++i) {\n        groups[i].resize(G[i]);\n        for (int j = 0; j < G[i]; ++j) {\n            groups[i][j] = p[idx++];\n        }\n    }\n\n    // Store edges discovered from queries for each group\n    vector<vector<pair<int, int>>> group_edges(M);\n    int q_cnt = 0;\n\n    // Query chunks of each group\n    for (int k = 0; k < M; ++k) {\n        if (groups[k].size() <= 1) continue;\n        \n        for (size_t start = 0; start < groups[k].size(); start += L) {\n            if (q_cnt >= Q) goto finish_queries;\n            \n            size_t end = min(start + L, groups[k].size());\n            size_t len = end - start;\n            if (len < 2) continue;\n\n            cout << \"? \" << len;\n            for (size_t i = start; i < end; ++i) {\n                cout << \" \" << groups[k][i];\n            }\n            cout << \"\\n\";\n            cout.flush();\n            q_cnt++;\n\n            for (size_t i = 0; i < len - 1; ++i) {\n                int u, v;\n                cin >> u >> v;\n                // Judge guarantees u < v, but store consistently\n                if (u > v) swap(u, v);\n                group_edges[k].push_back({u, v});\n            }\n        }\n    }\nfinish_queries:;\n\n    vector<vector<pair<int, int>>> final_edges(M);\n\n    // Complete MST for each group using discovered edges + estimated edges\n    for (int k = 0; k < M; ++k) {\n        if (groups[k].empty()) continue;\n        int sz = groups[k].size();\n        if (sz <= 1) continue;\n\n        DSU dsu(N);\n        // Prioritize edges from queries (they are exact MST edges for their subsets)\n        for (auto& e : group_edges[k]) {\n            if (dsu.unite(e.first, e.second)) {\n                final_edges[k].push_back(e);\n            }\n        }\n\n        if (final_edges[k].size() == sz - 1) continue; // Already fully connected\n\n        // Generate candidate edges based on estimated distances\n        vector<tuple<long long, int, int>> candidates;\n        candidates.reserve(sz * (sz - 1) / 2);\n        \n        for (int i = 0; i < sz; ++i) {\n            for (int j = i + 1; j < sz; ++j) {\n                int u = groups[k][i];\n                int v = groups[k][j];\n                if (dsu.find(u) == dsu.find(v)) continue;\n                long long dx = cx2[u] - cx2[v];\n                long long dy = cy2[u] - cy2[v];\n                // Store squared distance to avoid sqrt and preserve ordering\n                candidates.push_back({dx*dx + dy*dy, u, v});\n            }\n        }\n        sort(candidates.begin(), candidates.end());\n\n        // Kruskal's algorithm to connect remaining components\n        for (auto& c : candidates) {\n            if (final_edges[k].size() == sz - 1) break;\n            auto [w, u, v] = c;\n            if (dsu.unite(u, v)) {\n                final_edges[k].push_back({u, v});\n            }\n        }\n    }\n\n    // Output results\n    cout << \"!\\n\";\n    cout.flush();\n\n    for (int k = 0; k < M; ++k) {\n        for (size_t i = 0; i < groups[k].size(); ++i) {\n            if (i > 0) cout << \" \";\n            cout << groups[k][i];\n        }\n        cout << \"\\n\";\n        for (auto& e : final_edges[k]) {\n            cout << e.first << \" \" << e.second << \"\\n\";\n        }\n    }\n    cout.flush();\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n\n    int start_r, start_c;\n    cin >> start_r >> start_c;\n\n    // Read M-1 target squares\n    vector<pair<int, int>> targets(M - 1);\n    for (int k = 0; k < M - 1; ++k) {\n        cin >> targets[k].first >> targets[k].second;\n    }\n\n    int cur_r = start_r;\n    int cur_c = start_c;\n\n    // Grid state: true if a block is present\n    bool block[20][20] = {};\n    auto is_block = [&](int r, int c) {\n        if (r < 0 || r >= N || c < 0 || c >= N) return true; // Boundaries act as blocks\n        return block[r][c];\n    };\n\n    const int dr[] = {-1, 1, 0, 0};\n    const int dc[] = {0, 0, -1, 1};\n    const char d_name[] = {'U', 'D', 'L', 'R'};\n\n    int dist[20][20];\n    int parent_r[20][20], parent_c[20][20];\n    char act[20][20], dir[20][20];\n\n    struct Node {\n        int f, r, c, g;\n        bool operator>(const Node& other) const { return f > other.f; }\n    };\n\n    const int INF = 1e9;\n\n    for (auto [tr, tc] : targets) {\n        // Initialize distance matrix\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                dist[i][j] = INF;\n\n        priority_queue<Node, vector<Node>, greater<Node>> pq;\n        dist[cur_r][cur_c] = 0;\n        pq.push(Node{abs(cur_r - tr) + abs(cur_c - tc), cur_r, cur_c, 0});\n\n        // A* Search\n        while (!pq.empty()) {\n            auto [f, r, c, g] = pq.top(); pq.pop();\n            if (dist[r][c] < g) continue;\n            if (r == tr && c == tc) break;\n\n            // Try Move\n            for (int d = 0; d < 4; ++d) {\n                int nr = r + dr[d], nc = c + dc[d];\n                if (!is_block(nr, nc)) {\n                    if (dist[nr][nc] > g + 1) {\n                        dist[nr][nc] = g + 1;\n                        parent_r[nr][nc] = r; parent_c[nr][nc] = c;\n                        act[nr][nc] = 'M'; dir[nr][nc] = d_name[d];\n                        int nh = abs(nr - tr) + abs(nc - tc);\n                        pq.push(Node{dist[nr][nc] + nh, nr, nc, g + 1});\n                    }\n                }\n            }\n\n            // Try Slide\n            for (int d = 0; d < 4; ++d) {\n                int nr = r + dr[d], nc = c + dc[d];\n                while (!is_block(nr, nc)) {\n                    nr += dr[d]; nc += dc[d];\n                }\n                nr -= dr[d]; nc -= dc[d]; // Step back to last valid cell\n                if (nr == r && nc == c) continue; // Didn't move\n\n                if (dist[nr][nc] > g + 1) {\n                    dist[nr][nc] = g + 1;\n                    parent_r[nr][nc] = r; parent_c[nr][nc] = c;\n                    act[nr][nc] = 'S'; dir[nr][nc] = d_name[d];\n                    int nh = abs(nr - tr) + abs(nc - tc);\n                    pq.push(Node{dist[nr][nc] + nh, nr, nc, g + 1});\n                }\n            }\n        }\n\n        // Reconstruct path\n        vector<pair<char, char>> path;\n        int r = tr, c = tc;\n        while (r != cur_r || c != cur_c) {\n            path.emplace_back(act[r][c], dir[r][c]);\n            int pr = parent_r[r][c];\n            int pc = parent_c[r][c];\n            r = pr; c = pc;\n        }\n        reverse(path.begin(), path.end());\n\n        // Execute path\n        for (auto [a, d] : path) {\n            cout << a << ' ' << d << '\\n';\n            if (a == 'M') {\n                if (d == 'U') cur_r--;\n                else if (d == 'D') cur_r++;\n                else if (d == 'L') cur_c--;\n                else if (d == 'R') cur_c++;\n            } else if (a == 'S') {\n                if (d == 'U') while (true) { int nr = cur_r - 1; if (is_block(nr, cur_c)) break; cur_r = nr; }\n                else if (d == 'D') while (true) { int nr = cur_r + 1; if (is_block(nr, cur_c)) break; cur_r = nr; }\n                else if (d == 'L') while (true) { int nc = cur_c - 1; if (is_block(cur_r, nc)) break; cur_c = nc; }\n                else if (d == 'R') while (true) { int nc = cur_c + 1; if (is_block(cur_r, nc)) break; cur_c = nc; }\n            }\n        }\n    }\n\n    return 0;\n}"},"2":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Global data\nint N;\nvector<int> X, Y;\nvector<long long> R;\nstruct Rect { int x1, y1, x2, y2; };\n\nvector<Rect> best_ans;\ndouble best_score = -1.0;\n\ndouble calc_score(const vector<Rect>& rects) {\n    double total = 0.0;\n    for (int i = 0; i < N; ++i) {\n        long long s = (long long)(rects[i].x2 - rects[i].x1) * (rects[i].y2 - rects[i].y1);\n        double ratio = min(R[i], s) / (double)max(R[i], s);\n        total += 1.0 - (1.0 - ratio) * (1.0 - ratio);\n    }\n    return total;\n}\n\nbool validate(const vector<Rect>& rects) {\n    for (int i = 0; i < N; ++i) {\n        // Check bounds\n        if (rects[i].x1 < 0 || rects[i].x2 > 10000 || rects[i].y1 < 0 || rects[i].y2 > 10000) return false;\n        if (rects[i].x1 >= rects[i].x2 || rects[i].y1 >= rects[i].y2) return false;\n        // Check containment: point is (x_i+0.5, y_i+0.5) => x1 <= x_i < x2, y1 <= y_i < y2\n        if (!(rects[i].x1 <= X[i] && X[i] < rects[i].x2 && rects[i].y1 <= Y[i] && Y[i] < rects[i].y2)) return false;\n    }\n    // Check non-overlap (O(N^2), acceptable for N<=200)\n    for (int i = 0; i < N; ++i) {\n        for (int j = i + 1; j < N; ++j) {\n            if (rects[i].x1 < rects[j].x2 && rects[j].x1 < rects[i].x2 &&\n                rects[i].y1 < rects[j].y2 && rects[j].y1 < rects[i].y2) {\n                return false;\n            }\n        }\n    }\n    return true;\n}\n\n// Recursive guillotine partitioner\nvoid solve(int x1, int y1, int x2, int y2, vector<int> ids, vector<Rect>& current_ans) {\n    if (ids.empty()) return;\n    if (ids.size() == 1) {\n        current_ans[ids[0]] = {x1, y1, x2, y2};\n        return;\n    }\n\n    auto try_axis = [&](bool vertical) {\n        vector<int> sorted_ids = ids;\n        if (vertical) sort(sorted_ids.begin(), sorted_ids.end(), [&](int a, int b) { return X[a] < X[b]; });\n        else sort(sorted_ids.begin(), sorted_ids.end(), [&](int a, int b) { return Y[a] < Y[b]; });\n\n        long long cur_r = 0;\n        double best_err = 1e18;\n        int best_k = -1, best_c = -1;\n\n        for (int k = 0; k < sorted_ids.size() - 1; ++k) {\n            cur_r += R[sorted_ids[k]];\n            double len = vertical ? (y2 - y1) : (x2 - x1);\n            double ideal_c = (vertical ? x1 : y1) + (double)cur_r / len;\n            int c1 = floor(ideal_c);\n            int c2 = c1 + 1;\n\n            int min_pos = vertical ? X[sorted_ids[k]] : Y[sorted_ids[k]];\n            int max_pos = vertical ? X[sorted_ids[k+1]] : Y[sorted_ids[k+1]];\n\n            for (int c : {c1, c2}) {\n                if (c <= (vertical ? x1 : y1) || c >= (vertical ? x2 : y2)) continue;\n                if (min_pos < c && c <= max_pos) {\n                    double err = abs(ideal_c - c);\n                    if (err < best_err) {\n                        best_err = err;\n                        best_k = k;\n                        best_c = c;\n                    }\n                }\n            }\n        }\n        return make_tuple(best_k, best_c, best_err, sorted_ids);\n    };\n\n    auto [k_x, c_x, err_x, s_x] = try_axis(true);\n    auto [k_y, c_y, err_y, s_y] = try_axis(false);\n\n    // Prefer axis with valid cut and minimal error\n    if (err_x < 1e10 && err_x <= err_y) {\n        vector<int> left(s_x.begin(), s_x.begin() + k_x + 1);\n        vector<int> right(s_x.begin() + k_x + 1, s_x.end());\n        solve(x1, y1, c_x, y2, left, current_ans);\n        solve(c_x, y1, x2, y2, right, current_ans);\n    } else if (err_y < 1e10) {\n        vector<int> bottom(s_y.begin(), s_y.begin() + k_y + 1);\n        vector<int> top(s_y.begin() + k_y + 1, s_y.end());\n        solve(x1, y1, x2, c_y, bottom, current_ans);\n        solve(x1, c_y, x2, y2, top, current_ans);\n    } else {\n        // Fallback: geometric median split (rarely reached for random data)\n        int mid = ids.size() / 2;\n        vector<int> left(ids.begin(), ids.begin() + mid);\n        vector<int> right(ids.begin() + mid, ids.end());\n        int c = (x1 + x2) / 2;\n        solve(x1, y1, c, y2, left, current_ans);\n        solve(c, y1, x2, y2, right, current_ans);\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N)) return 0;\n    X.resize(N); Y.resize(N); R.resize(N);\n    for (int i = 0; i < N; ++i) cin >> X[i] >> Y[i] >> R[i];\n\n    best_ans.resize(N);\n    vector<int> ids(N);\n    iota(ids.begin(), ids.end(), 0);\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    auto start_time = chrono::steady_clock::now();\n\n    // Multi-run stochastic wrapper to find best partition\n    while (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() < 4.5) {\n        shuffle(ids.begin(), ids.end(), rng);\n        vector<Rect> current_ans(N, {-1, -1, -1, -1});\n        solve(0, 0, 10000, 10000, ids, current_ans);\n\n        if (validate(current_ans)) {\n            double sc = calc_score(current_ans);\n            if (sc > best_score) {\n                best_score = sc;\n                best_ans = current_ans;\n            }\n        }\n    }\n\n    // Output\n    for (int i = 0; i < N; ++i) {\n        cout << best_ans[i].x1 << \" \" << best_ans[i].y1 << \" \"\n             << best_ans[i].x2 << \" \" << best_ans[i].y2 << \"\\n\";\n    }\n\n    cerr << \"Final Score: \" << (long long)(best_score * 1e9 / N) << \"\\n\";\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nint main() {\n    cin.tie(nullptr);\n    ios::sync_with_stdio(false);\n\n    int si, sj;\n    if (!(cin >> si >> sj)) return 0;\n\n    int t[50][50], p[50][50];\n    int M = 0;\n    for (int i = 0; i < 50; ++i)\n        for (int j = 0; j < 50; ++j) {\n            cin >> t[i][j];\n            M = max(M, t[i][j] + 1);\n        }\n    for (int i = 0; i < 50; ++i)\n        for (int j = 0; j < 50; ++j)\n            cin >> p[i][j];\n\n    // Precompute max score per tile for heuristic bonus\n    vector<int> tile_max(M, 0);\n    for (int i = 0; i < 50; ++i)\n        for (int j = 0; j < 50; ++j)\n            tile_max[t[i][j]] = max(tile_max[t[i][j]], p[i][j]);\n\n    auto start_t = chrono::steady_clock::now();\n    mt19937 rng(42);\n    uniform_real_distribution<double> noise(0.0, 15.0);\n\n    vector<char> vis(M);\n    const int dr[] = {-1, 1, 0, 0};\n    const int dc[] = {0, 0, -1, 1};\n    const char dirs[] = {'U', 'D', 'L', 'R'};\n\n    // Simulates path up to keep_len, extends greedily, returns score.\n    // Assumes nxt has size == keep_len on entry.\n    auto extend = [&](vector<char>& nxt, int keep_len) -> ll {\n        int r = si, c = sj;\n        fill(vis.begin(), vis.end(), 0);\n        vis[t[r][c]] = 1;\n        ll score = p[r][c];\n\n        for (int i = 0; i < keep_len; ++i) {\n            char d = nxt[i];\n            if (d == 'U') r--; else if (d == 'D') r++; else if (d == 'L') c--; else c++;\n            vis[t[r][c]] = 1;\n            score += p[r][c];\n        }\n\n        while (true) {\n            double best_h = -1e18;\n            int best_k = -1, nr_best = 0, nc_best = 0;\n            \n            for (int k = 0; k < 4; ++k) {\n                int nr = r + dr[k], nc = c + dc[k];\n                if (nr >= 0 && nr < 50 && nc >= 0 && nc < 50 && !vis[t[nr][nc]]) {\n                    int tid = t[nr][nc];\n                    \n                    // Degree heuristic: count unvisited neighboring squares of this candidate tile\n                    int deg = 0;\n                    for(int d=0; d<4; ++d) {\n                        int tr = nr + dr[d], tc = nc + dc[d];\n                        if(tr>=0 && tr<50 && tc>=0 && tc<50 && !vis[t[tr][tc]]) deg++;\n                    }\n                    \n                    // Heuristic: exact step score + potential tile bonus + degree freedom + noise\n                    double h = (double)p[nr][nc] + (double)tile_max[tid] * 0.4 + (double)deg * 18.0 + noise(rng);\n                    if (h > best_h) {\n                        best_h = h;\n                        best_k = k;\n                        nr_best = nr;\n                        nc_best = nc;\n                    }\n                }\n            }\n            if (best_k == -1) break;\n\n            nxt.push_back(dirs[best_k]);\n            r = nr_best;\n            c = nc_best;\n            vis[t[r][c]] = 1;\n            score += p[r][c];\n        }\n        return score;\n    };\n\n    vector<char> best_path;\n    ll best_score = -1;\n\n    // Multi-start: generate diverse initial paths to avoid poor basins\n    const int NUM_STARTS = 8;\n    for (int start = 0; start < NUM_STARTS; ++start) {\n        vector<char> init;\n        ll sc = extend(init, 0);\n        if (sc > best_score) {\n            best_score = sc;\n            best_path = move(init);\n        }\n    }\n\n    vector<char> cur_path = best_path;\n    vector<char> nxt_path;\n    nxt_path.reserve(2500);\n    ll cur_score = best_score;\n    \n    // Simulated Annealing Parameters\n    double T = 60.0;\n    const double T_DECAY = 0.99975;\n    \n    while (true) {\n        auto now = chrono::steady_clock::now();\n        if (chrono::duration<double>(now - start_t).count() > 1.93) break;\n\n        int sz = cur_path.size();\n        // Random truncation: keep prefix of length [0, sz]\n        int keep_len = (sz == 0) ? 0 : (rng() % (sz + 1));\n        \n        nxt_path.assign(cur_path.begin(), cur_path.begin() + keep_len);\n        ll nxt_score = extend(nxt_path, keep_len);\n\n        if (nxt_score > best_score) {\n            best_score = nxt_score;\n            best_path = nxt_path;\n        }\n\n        bool accept = false;\n        if (nxt_score >= cur_score) {\n            accept = true;\n        } else {\n            double delta = nxt_score - cur_score;\n            // Avoid underflow in exp()\n            if (delta / T > -18.0) {\n                double prob = exp(delta / T);\n                if (prob > (double)(rng() & 0xFFFFFF) / 16777216.0) {\n                    accept = true;\n                }\n            }\n        }\n\n        if (accept) {\n            cur_score = nxt_score;\n            cur_path = nxt_path;\n        }\n\n        T *= T_DECAY;\n    }\n\n    for (char c : best_path) cout << c;\n    cout << \"\\n\";\n\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Edge weight estimates: h[row][col], v[row][col]\n    double h[30][29], v[29][30];\n    const double INIT_W = 5000.0;\n    for(int i=0; i<30; ++i) for(int j=0; j<29; ++j) h[i][j] = INIT_W;\n    for(int i=0; i<29; ++i) for(int j=0; j<30; ++j) v[i][j] = INIT_W;\n\n    int si, sj, ti, tj;\n    for(int k=0; k<1000; ++k) {\n        if(!(cin >> si >> sj >> ti >> tj)) break;\n\n        // Dijkstra's Algorithm\n        priority_queue<pair<long long, pair<int, int>>, \n                       vector<pair<long long, pair<int, int>>>, \n                       greater<>> pq;\n        long long dist[30][30];\n        for(int i=0; i<30; ++i) fill(begin(dist[i]), end(dist[i]), 1e18);\n        \n        dist[si][sj] = 0;\n        pq.push({0, {si, sj}});\n\n        int from_i[30][30], from_j[30][30];\n        char from_dir[30][30];\n\n        int di[4] = {-1, 1, 0, 0};\n        int dj[4] = {0, 0, -1, 1};\n        char dc[4] = {'U', 'D', 'L', 'R'};\n\n        while(!pq.empty()){\n            auto [d, p] = pq.top(); pq.pop();\n            int i = p.first, j = p.second;\n            if(d > dist[i][j]) continue;\n            if(i == ti && j == tj) break;\n\n            for(int m=0; m<4; ++m){\n                int ni = i + di[m], nj = j + dj[m];\n                if(ni < 0 || ni >= 30 || nj < 0 || nj >= 30) continue;\n\n                long long w;\n                if(m == 0)      w = (long long)round(v[ni][nj]); // U\n                else if(m == 1) w = (long long)round(v[i][j]);   // D\n                else if(m == 2) w = (long long)round(h[i][nj]);  // L\n                else            w = (long long)round(h[i][j]);   // R\n\n                if(dist[i][j] + w < dist[ni][nj]){\n                    dist[ni][nj] = dist[i][j] + w;\n                    from_i[ni][nj] = i;\n                    from_j[ni][nj] = j;\n                    from_dir[ni][nj] = dc[m];\n                    pq.push({dist[ni][nj], {ni, nj}});\n                }\n            }\n        }\n\n        // Reconstruct path\n        string path = \"\";\n        int ci = ti, cj = tj;\n        while(!(ci == si && cj == sj)){\n            path += from_dir[ci][cj];\n            int pi = from_i[ci][cj];\n            int pj = from_j[ci][cj];\n            ci = pi; cj = pj;\n        }\n        reverse(path.begin(), path.end());\n        cout << path << endl;\n\n        // Read feedback\n        int L;\n        cin >> L;\n\n        // Calculate estimated path length B\n        double B = 0.0;\n        ci = si; cj = sj;\n        for(char c : path){\n            if(c == 'U') { B += v[ci-1][cj]; ci--; }\n            else if(c == 'D') { B += v[ci][cj]; ci++; }\n            else if(c == 'L') { B += h[ci][cj-1]; cj--; }\n            else if(c == 'R') { B += h[ci][cj]; cj++; }\n        }\n\n        // Online gradient descent update\n        double err = L - B;\n        double alpha = 0.12; // Constant learning rate for stable convergence\n        double delta = alpha * err / path.length();\n\n        ci = si; cj = sj;\n        for(char c : path){\n            if(c == 'U') { v[ci-1][cj] = max(500.0, v[ci-1][cj] + delta); ci--; }\n            else if(c == 'D') { v[ci][cj] = max(500.0, v[ci][cj] + delta); ci++; }\n            else if(c == 'L') { h[ci][cj-1] = max(500.0, h[ci][cj-1] + delta); cj--; }\n            else if(c == 'R') { h[ci][cj] = max(500.0, h[ci][cj] + delta); cj++; }\n        }\n\n        // Spatial smoothing (denoising)\n        double beta = 0.18;\n        for(int i=0; i<30; ++i){\n            double s = 0;\n            for(int j=0; j<29; ++j) s += h[i][j];\n            s /= 29.0;\n            for(int j=0; j<29; ++j) h[i][j] = (1-beta)*h[i][j] + beta*s;\n        }\n        for(int j=0; j<30; ++j){\n            double s = 0;\n            for(int i=0; i<29; ++i) s += v[i][j];\n            s /= 29.0;\n            for(int i=0; i<29; ++i) v[i][j] = (1-beta)*v[i][j] + beta*s;\n        }\n    }\n    return 0;\n}","ahc004":"#pragma GCC optimize(\"O3,unroll-loops,fast-math\")\n#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <chrono>\n#include <random>\n#include <algorithm>\n#include <cstring>\n\nusing namespace std;\n\nconst int N = 20;\nconst int MAX_M = 800;\nconst int MAX_PLACEMENTS = 650000;\n\nint M;\nint S_len[MAX_M];\nchar S_chars[MAX_M][15];\n\nstruct CellLink {\n    int p_idx;\n    char exp_char;\n};\n\nstruct Placement {\n    int str_id;\n    int len;\n};\n\nvector<Placement> placements;\nvector<CellLink> cell_placements[N][N];\nint placement_matches[MAX_PLACEMENTS];\nint str_full_cnt[MAX_M];\nchar grid[N][N];\nchar best_grid[N][N];\nint total_score = 0;\nint best_score = -1;\n\nmt19937_64 rng;\n\ninline int calc_diff(int r, int c, char new_c, char old_c) {\n    if (new_c == old_c) return 0;\n    int diff = 0;\n    const auto& links = cell_placements[r][c];\n    for (const auto& cl : links) {\n        bool old_match = (old_c == cl.exp_char);\n        bool new_match = (new_c == cl.exp_char);\n        if (old_match == new_match) continue;\n\n        int k = placements[cl.p_idx].str_id;\n        bool was_full = (placement_matches[cl.p_idx] == S_len[k]);\n\n        int cur_matches = placement_matches[cl.p_idx] + (new_match ? 1 : -1);\n        bool is_full = (cur_matches == S_len[k]);\n        \n        if (was_full && !is_full) {\n            if (str_full_cnt[k] == 1) diff--;\n        } else if (!was_full && is_full) {\n            if (str_full_cnt[k] == 0) diff++;\n        }\n    }\n    return diff;\n}\n\ninline void apply_change(int r, int c, char new_c, char old_c, int diff) {\n    grid[r][c] = new_c;\n    total_score += diff;\n    const auto& links = cell_placements[r][c];\n    for (const auto& cl : links) {\n        bool old_match = (old_c == cl.exp_char);\n        bool new_match = (new_c == cl.exp_char);\n        if (old_match == new_match) continue;\n\n        int k = placements[cl.p_idx].str_id;\n        bool was_full = (placement_matches[cl.p_idx] == S_len[k]);\n\n        if (old_match) placement_matches[cl.p_idx]--;\n        else placement_matches[cl.p_idx]++;\n\n        bool is_full = (placement_matches[cl.p_idx] == S_len[k]);\n        if (was_full && !is_full) str_full_cnt[k]--;\n        else if (!was_full && is_full) str_full_cnt[k]++;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    rng.seed(chrono::steady_clock::now().time_since_epoch().count());\n\n    int N_in;\n    if (!(cin >> N_in >> M)) return 0;\n    for (int i = 0; i < M; ++i) {\n        string s;\n        cin >> s;\n        S_len[i] = (int)s.length();\n        memcpy(S_chars[i], s.c_str(), S_len[i] + 1);\n    }\n\n    int p_idx = 0;\n    placements.reserve(MAX_PLACEMENTS);\n    for (int k = 0; k < M; ++k) {\n        int L = S_len[k];\n        // Horizontal placements\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                placements.push_back({k, L});\n                for (int p = 0; p < L; ++p) {\n                    cell_placements[r][(c + p) % N].push_back({p_idx, S_chars[k][p]});\n                }\n                p_idx++;\n            }\n        }\n        // Vertical placements\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                placements.push_back({k, L});\n                for (int pp = 0; pp < L; ++pp) {\n                    cell_placements[(r + pp) % N][c].push_back({p_idx, S_chars[k][pp]});\n                }\n                p_idx++;\n            }\n        }\n    }\n\n    // Greedy initialization\n    int cnt[N][N][8] = {};\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            for (const auto& cl : cell_placements[r][c]) {\n                cnt[r][c][cl.exp_char - 'A']++;\n            }\n            char best_c = 'A';\n            int max_v = -1;\n            for (int x = 0; x < 8; ++x) {\n                if (cnt[r][c][x] > max_v) {\n                    max_v = cnt[r][c][x];\n                    best_c = 'A' + x;\n                }\n            }\n            grid[r][c] = best_c;\n        }\n    }\n\n    // Initialize state\n    int total_placements = placements.size();\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            for (const auto& cl : cell_placements[r][c]) {\n                if (grid[r][c] == cl.exp_char) {\n                    placement_matches[cl.p_idx]++;\n                }\n            }\n        }\n    }\n    for (int i = 0; i < total_placements; ++i) {\n        int k = placements[i].str_id;\n        if (placement_matches[i] == S_len[k]) {\n            str_full_cnt[k]++;\n        }\n    }\n    for (int k = 0; k < M; ++k) {\n        if (str_full_cnt[k] > 0) total_score++;\n    }\n\n    best_score = total_score;\n    memcpy(best_grid, grid, sizeof(grid));\n\n    // Simulated Annealing\n    double T = 2.0;\n    auto start = chrono::steady_clock::now();\n    uniform_int_distribution<int> dist_rc(0, N-1);\n    uniform_int_distribution<int> dist_char(0, 7);\n    uniform_real_distribution<double> prob_dist(0.0, 1.0);\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration_cast<chrono::milliseconds>(now - start).count() / 1000.0;\n        if (elapsed >= 2.85) break;\n\n        T = 2.0 * pow(1e-5 / 2.0, elapsed / 2.85);\n        if (T < 1e-9) T = 1e-9;\n\n        int r = dist_rc(rng);\n        int c = dist_rc(rng);\n        char old_c = grid[r][c];\n        char new_c = 'A' + dist_char(rng);\n        if (new_c == old_c) continue;\n\n        int diff = calc_diff(r, c, new_c, old_c);\n        if (diff > 0 || prob_dist(rng) < exp(diff / T)) {\n            apply_change(r, c, new_c, old_c, diff);\n            if (total_score > best_score) {\n                best_score = total_score;\n                memcpy(best_grid, grid, sizeof(grid));\n                if (best_score == M) break;\n            }\n        }\n    }\n\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            cout << best_grid[r][c];\n        }\n        cout << '\\n';\n    }\n\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\n#pragma GCC optimize(\"O3,unroll-loops\")\nusing namespace std;\n\nconst int INF = 1e9;\n\nstruct Point { int r, c; };\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, si, sj;\n    if (!(cin >> N >> si >> sj)) return 0;\n    vector<string> grid(N);\n    vector<Point> roads;\n    vector<vector<int>> idx(N, vector<int>(N, -1));\n    for (int i = 0; i < N; ++i) {\n        cin >> grid[i];\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] != '#') {\n                idx[i][j] = roads.size();\n                roads.emplace_back(Point{i, j});\n            }\n        }\n    }\n    int V = roads.size();\n    int start_idx = idx[si][sj];\n\n    // Precompute horizontal and vertical segment boundaries\n    vector<vector<int>> L(N, vector<int>(N)), R(N, vector<int>(N));\n    vector<vector<int>> U(N, vector<int>(N)), D(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) if (grid[i][j] != '#') {\n            L[i][j] = (j > 0 && grid[i][j-1] != '#') ? L[i][j-1] : j;\n        }\n        for (int j = N - 1; j >= 0; --j) if (grid[i][j] != '#') {\n            R[i][j] = (j < N - 1 && grid[i][j+1] != '#') ? R[i][j+1] : j;\n        }\n    }\n    for (int j = 0; j < N; ++j) {\n        for (int i = 0; i < N; ++i) if (grid[i][j] != '#') {\n            U[i][j] = (i > 0 && grid[i-1][j] != '#') ? U[i-1][j] : i;\n        }\n        for (int i = N - 1; i >= 0; --i) if (grid[i][j] != '#') {\n            D[i][j] = (i < N - 1 && grid[i+1][j] != '#') ? D[i+1][j] : i;\n        }\n    }\n\n    // Greedy Set Cover to select guard points\n    vector<bool> covered(N * N, false);\n    vector<int> guards;\n    int uncovered_cnt = V;\n    \n    while (uncovered_cnt > 0) {\n        int best_g = -1, best_gain = 0;\n        // Find road cell that covers the most currently uncovered cells\n        for (int i = 0; i < V; ++i) {\n            int r = roads[i].r, c = roads[i].c;\n            int gain = 0;\n            for (int j = L[r][c]; j <= R[r][c]; ++j) if (!covered[r * N + j]) gain++;\n            for (int i2 = U[r][c]; i2 <= D[r][c]; ++i2) if (!covered[i2 * N + c]) gain++;\n            if (!covered[r * N + c]) gain--; // center counted twice\n            if (gain > best_gain) {\n                best_gain = gain;\n                best_g = i;\n            }\n        }\n        if (best_g == -1) break; // Should not happen if uncovered_cnt > 0\n        \n        guards.push_back(best_g);\n        int r = roads[best_g].r, c = roads[best_g].c;\n        for (int j = L[r][c]; j <= R[r][c]; ++j) {\n            if (!covered[r * N + j]) { covered[r * N + j] = true; uncovered_cnt--; }\n        }\n        for (int i2 = U[r][c]; i2 <= D[r][c]; ++i2) {\n            if (!covered[i2 * N + c]) { covered[i2 * N + c] = true; uncovered_cnt--; }\n        }\n    }\n\n    // Ensure start point is in guards\n    if (idx[si][sj] == -1 || find(guards.begin(), guards.end(), idx[si][sj]) == guards.end()) {\n        guards.push_back(idx[si][sj]);\n    }\n\n    int M = guards.size();\n    vector<vector<int>> dist_mat(M, vector<int>(M, INF));\n    \n    // Compute pairwise distances using Dijkstra from each guard\n    int dirs[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\n    vector<int> d(N * N);\n    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;\n\n    for (int i = 0; i < M; ++i) {\n        fill(d.begin(), d.end(), INF);\n        int sr = roads[guards[i]].r, sc = roads[guards[i]].c;\n        int u0 = sr * N + sc;\n        d[u0] = 0;\n        pq.emplace(0, u0);\n        dist_mat[i][i] = 0;\n\n        while (!pq.empty()) {\n            auto [dst, u] = pq.top(); pq.pop();\n            if (dst > d[u]) continue;\n            int ur = u / N, uc = u % N;\n            if (idx[ur][uc] != -1) {\n                // Check if u is a guard\n                for (int k = 0; k < M; ++k) {\n                    if (guards[k] == idx[ur][uc]) {\n                        dist_mat[i][k] = dst;\n                    }\n                }\n            }\n            for (auto& dr : dirs) {\n                int vr = ur + dr[0], vc = uc + dr[1];\n                if (vr < 0 || vr >= N || vc < 0 || vc >= N || grid[vr][vc] == '#') continue;\n                int v = vr * N + vc;\n                int w = grid[vr][vc] - '0';\n                if (d[u] + w < d[v]) {\n                    d[v] = d[u] + w;\n                    pq.emplace(d[v], v);\n                }\n            }\n        }\n    }\n\n    // TSP: Nearest Insertion\n    vector<int> tour;\n    vector<bool> in_tour(M, false);\n    int start_in_guards = -1;\n    for (int i = 0; i < M; ++i) if (guards[i] == start_idx) { start_in_guards = i; break; }\n    \n    tour.push_back(start_in_guards);\n    in_tour[start_in_guards] = true;\n    vector<int> min_dist(M, INF);\n    for (int i = 0; i < M; ++i) min_dist[i] = dist_mat[start_in_guards][i];\n\n    for (int count = 1; count < M; ++count) {\n        int best_k = -1, best_val = INF;\n        for (int k = 0; k < M; ++k) {\n            if (!in_tour[k] && min_dist[k] < best_val) {\n                best_val = min_dist[k];\n                best_k = k;\n            }\n        }\n        int best_pos = 0, best_insert_cost = INF;\n        for (int i = 0; i < (int)tour.size(); ++i) {\n            int j = tour[(i + 1) % tour.size()];\n            int cost = dist_mat[tour[i]][best_k] + dist_mat[best_k][j] - dist_mat[tour[i]][j];\n            if (cost < best_insert_cost) {\n                best_insert_cost = cost;\n                best_pos = i + 1;\n            }\n        }\n        tour.insert(tour.begin() + best_pos, best_k);\n        in_tour[best_k] = true;\n        for (int k = 0; k < M; ++k) {\n            if (!in_tour[k]) min_dist[k] = min(min_dist[k], dist_mat[best_k][k]);\n        }\n    }\n\n    // 2-opt Local Search\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (int i = 0; i < M; ++i) {\n            for (int j = i + 2; j < M; ++j) {\n                if (j == M - 1 && i == 0) continue;\n                int u1 = tour[i], v1 = tour[(i + 1) % M];\n                int u2 = tour[j], v2 = tour[(j + 1) % M];\n                int current = dist_mat[u1][v1] + dist_mat[u2][v2];\n                int swapped  = dist_mat[u1][u2] + dist_mat[v1][v2];\n                if (swapped < current) {\n                    reverse(tour.begin() + i + 1, tour.begin() + j + 1);\n                    improved = true;\n                }\n            }\n        }\n    }\n\n    // Reconstruct path\n    string result = \"\";\n    result.reserve(M * 15);\n    vector<int> parent(N * N, -1);\n    vector<char> move_char(N * N);\n\n    auto get_path = [&](int from_idx, int to_idx) {\n        if (from_idx == to_idx) return string(\"\");\n        auto [r1, c1] = roads[guards[from_idx]];\n        auto [r2, c2] = roads[guards[to_idx]];\n        if (r1 == r2 && c1 == c2) return string(\"\");\n        \n        fill(d.begin(), d.end(), INF);\n        fill(parent.begin(), parent.end(), -1);\n        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq2;\n        \n        int u0 = r1 * N + c1, target = r2 * N + c2;\n        d[u0] = 0;\n        pq2.emplace(0, u0);\n\n        while (!pq2.empty()) {\n            auto [dst, u] = pq2.top(); pq2.pop();\n            if (dst > d[u]) continue;\n            if (u == target) break;\n            \n            int ur = u / N, uc = u % N;\n            for (int k = 0; k < 4; ++k) {\n                int vr = ur + dirs[k][0], vc = uc + dirs[k][1];\n                if (vr < 0 || vr >= N || vc < 0 || vc >= N || grid[vr][vc] == '#') continue;\n                int v = vr * N + vc;\n                int w = grid[vr][vc] - '0';\n                if (d[u] + w < d[v]) {\n                    d[v] = d[u] + w;\n                    parent[v] = u;\n                    move_char[v] = \"UDLR\"[k];\n                    pq2.emplace(d[v], v);\n                }\n            }\n        }\n\n        string path = \"\";\n        int curr = target;\n        while (curr != u0) {\n            path += move_char[curr];\n            curr = parent[curr];\n        }\n        reverse(path.begin(), path.end());\n        return path;\n    };\n\n    for (int i = 0; i < M; ++i) {\n        result += get_path(tour[i], tour[(i + 1) % M]);\n    }\n\n    cout << result << \"\\n\";\n    return 0;\n}","future-contest-2022-qual":"#pragma GCC optimize(\"O3,unroll-loops\")\n#pragma GCC target(\"avx2,fma\")\n\n#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K, R;\n    if (!(cin >> N >> M >> K >> R)) return 0;\n\n    // Task difficulties\n    vector<vector<int>> d(N, vector<int>(K));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < K; ++j)\n            cin >> d[i][j];\n\n    // Dependency graph\n    vector<vector<int>> adj(N);\n    vector<int> in_degree(N, 0);\n    for (int i = 0; i < R; ++i) {\n        int u, v; cin >> u >> v; --u; --v;\n        adj[u].push_back(v);\n        in_degree[v]++;\n    }\n\n    // State tracking\n    vector<vector<double>> est_s(M, vector<double>(K, 10.0)); // Initialize with reasonable mid-range value\n    vector<int> member_task(M, -1);\n    vector<int> member_start_day(M, -1);\n    vector<int> tasks_done(M, 0);\n    vector<bool> task_done(N, false);\n    vector<bool> task_assigned(N, false);\n\n    // Precompute priorities (sum of required skills)\n    vector<long long> priority(N, 0);\n    for (int i = 0; i < N; ++i) {\n        long long s = 0;\n        for (int x : d[i]) s += x;\n        priority[i] = s;\n    }\n\n    // Initially ready tasks (in-degree 0)\n    vector<int> ready;\n    ready.reserve(N);\n    for (int i = 0; i < N; ++i)\n        if (in_degree[i] == 0) ready.push_back(i);\n\n    auto cmp_priority = [&](int a, int b) { return priority[a] > priority[b]; };\n\n    for (int day = 1; day <= 2000; ++day) {\n        int nf;\n        cin >> nf;\n        if (nf == -1) break;\n\n        vector<int> completed_members;\n        completed_members.reserve(nf);\n        for (int i = 0; i < nf; ++i) {\n            int f; cin >> f; --f;\n            completed_members.push_back(f);\n        }\n\n        // Process task completions & update skill estimates\n        for (int f : completed_members) {\n            int tid = member_task[f];\n            int sd = member_start_day[f];\n            if (tid == -1) continue;\n\n            int actual_t = day - sd + 1;\n            task_done[tid] = true;\n            task_assigned[tid] = false;\n            member_task[f] = -1;\n            member_start_day[f] = -1;\n            tasks_done[f]++;\n\n            // Compute prediction error\n            double pred = 0;\n            int def = 0;\n            for (int k = 0; k < K; ++k) {\n                if (d[tid][k] > est_s[f][k]) {\n                    pred += d[tid][k] - est_s[f][k];\n                    def++;\n                }\n            }\n\n            // Online gradient update with noise clipping\n            if (def > 0 && pred > 0.5) {\n                double err = actual_t - pred;\n                double lr = 0.5 / (1.0 + 0.02 * tasks_done[f]);\n                double delta = max(-2.0, min(2.0, err / def));\n                for (int k = 0; k < K; ++k) {\n                    if (d[tid][k] > est_s[f][k]) {\n                        est_s[f][k] += lr * delta;\n                        if (est_s[f][k] < 0) est_s[f][k] = 0;\n                        if (est_s[f][k] > 80) est_s[f][k] = 80;\n                    }\n                }\n            }\n\n            // Release dependencies\n            for (int v : adj[tid]) {\n                if (--in_degree[v] == 0) {\n                    ready.push_back(v);\n                }\n            }\n        }\n\n        // Collect free members\n        vector<int> free_ms;\n        free_ms.reserve(M);\n        for (int m = 0; m < M; ++m)\n            if (member_task[m] == -1) free_ms.push_back(m);\n\n        // Sort ready tasks by difficulty descending\n        sort(ready.begin(), ready.end(), cmp_priority);\n\n        vector<pair<int, int>> out_assign;\n        out_assign.reserve(free_ms.size());\n        vector<int> next_ready;\n        next_ready.reserve(ready.size());\n\n        // Greedy assignment: highest priority task to best fitting free member\n        for (int t : ready) {\n            if (task_assigned[t] || task_done[t]) continue;\n            if (free_ms.empty()) {\n                next_ready.push_back(t);\n                continue;\n            }\n\n            int best_m = -1;\n            double best_et = 1e18;\n            for (int m : free_ms) {\n                double w = 0;\n                const auto& dt = d[t];\n                const auto& es = est_s[m];\n                for (int k = 0; k < K; ++k) {\n                    if (dt[k] > es[k]) w += dt[k] - es[k];\n                }\n                double et = (w > 0) ? w : 1.0;\n                if (et < best_et) {\n                    best_et = et;\n                    best_m = m;\n                }\n            }\n\n            if (best_m != -1) {\n                member_task[best_m] = t;\n                member_start_day[best_m] = day;\n                task_assigned[t] = true;\n                out_assign.push_back({best_m, t});\n                \n                // Remove used member from free list\n                for (auto it = free_ms.begin(); it != free_ms.end(); ++it) {\n                    if (*it == best_m) { free_ms.erase(it); break; }\n                }\n            } else {\n                next_ready.push_back(t);\n            }\n        }\n        ready = next_ready;\n\n        // Output assignments\n        cout << out_assign.size();\n        for (auto& p : out_assign) {\n            cout << \" \" << p.first + 1 << \" \" << p.second + 1;\n        }\n        cout << \"\\n\" << flush;\n    }\n\n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <chrono>\n#include <random>\n#include <numeric>\n#include <iomanip>\n\nusing namespace std;\n\n// ==================== Geometry & Helpers ====================\nstruct Pt { int x, y; };\ninline int dist(const Pt& a, const Pt& b) { return abs(a.x - b.x) + abs(a.y - b.y); }\n\nconst Pt BASE = {400, 400};\n\nstruct Order {\n    int id; // 1-based index\n    Pt p, d; // pickup, delivery\n};\n\nvector<Order> all_orders(1000);\nint sel_ids[50];          // Selected order indices (1-based)\nPt sp[50], sd[50];        // Selected pickup/delivery coordinates\nvector<int> route;        // Route stores 0..49 (pickup), 50..99 (delivery)\n\ninline Pt get_pt(int idx) {\n    return idx < 50 ? sp[idx] : sd[idx - 50];\n}\n\n// ==================== Core Functions ====================\nint calc_cost(const vector<int>& r) {\n    int c = dist(BASE, get_pt(r[0]));\n    for (int i = 0; i < 99; ++i) c += dist(get_pt(r[i]), get_pt(r[i+1]));\n    c += dist(get_pt(r[99]), BASE);\n    return c;\n}\n\nbool check_precedence(const vector<int>& r) {\n    int pos[50]; fill(pos, pos + 50, -1);\n    for (int i = 0; i < 100; ++i) {\n        if (r[i] < 50) pos[r[i]] = i;\n        else if (pos[r[i] - 50] == -1 || pos[r[i] - 50] >= i) return false;\n    }\n    return true;\n}\n\n// ==================== Phase 1: Greedy Construction ====================\nvoid build_initial_route() {\n    route.clear();\n    vector<bool> in_pickup(50, false), in_delivery(50, false);\n    int placed = 0;\n\n    while (placed < 100) {\n        int best_pos = -1, best_pt = -1;\n        int min_delta = 2e9;\n\n        // Try inserting any available pickup or valid delivery\n        for (int p = 0; p < 50; ++p) {\n            if (in_pickup[p] || in_delivery[p]) continue;\n            int pt = p; // pickup\n            for (int pos = 0; pos <= placed; ++pos) {\n                int delta;\n                if (placed == 0) delta = dist(BASE, get_pt(pt)) + dist(get_pt(pt), BASE) - dist(BASE, BASE);\n                else {\n                    Pt prev = (pos == 0) ? BASE : get_pt(route[pos - 1]);\n                    Pt next = (pos == placed) ? BASE : get_pt(route[pos]);\n                    delta = dist(prev, get_pt(pt)) + dist(get_pt(pt), next) - dist(prev, next);\n                }\n                if (delta < min_delta) { min_delta = delta; best_pos = pos; best_pt = pt; }\n            }\n        }\n        for (int p = 0; p < 50; ++p) {\n            if (!in_pickup[p] || in_delivery[p]) continue;\n            int pt = p + 50; // delivery\n            for (int pos = 0; pos <= placed; ++pos) {\n                int delta;\n                if (placed == 0) delta = dist(BASE, get_pt(pt)) + dist(get_pt(pt), BASE);\n                else {\n                    Pt prev = (pos == 0) ? BASE : get_pt(route[pos - 1]);\n                    Pt next = (pos == placed) ? BASE : get_pt(route[pos]);\n                    delta = dist(prev, get_pt(pt)) + dist(get_pt(pt), next) - dist(prev, next);\n                }\n                if (delta < min_delta) { min_delta = delta; best_pos = pos; best_pt = pt; }\n            }\n        }\n\n        route.insert(route.begin() + best_pos, best_pt);\n        if (best_pt < 50) in_pickup[best_pt] = true;\n        else in_delivery[best_pt - 50] = true;\n        placed++;\n    }\n}\n\n// ==================== Phase 2: Local Search (2-opt & Relocate) ====================\nauto start_time = chrono::steady_clock::now();\ninline double elapsed() {\n    return chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n}\n\nvoid run_local_search(double time_budget) {\n    bool improved = true;\n    double deadline = elapsed() + time_budget;\n    while (improved && elapsed() < deadline) {\n        improved = false;\n        \n        // 2-opt\n        for (int l = 0; l < 99 && elapsed() < deadline; ++l) {\n            for (int r = l + 1; r < 100; ++r) {\n                vector<int> tmp = route;\n                reverse(tmp.begin() + l, tmp.begin() + r + 1);\n                \n                int old_c = calc_cost(route);\n                int new_c = calc_cost(tmp);\n                \n                if (new_c < old_c && check_precedence(tmp)) {\n                    route = tmp;\n                    improved = true;\n                    goto next_iter;\n                }\n            }\n        }\n        \n        // Relocate\n        for (int i = 0; i < 100 && elapsed() < deadline; ++i) {\n            for (int j = 0; j < 100; ++j) {\n                if (i == j || i == j + 1) continue;\n                vector<int> tmp = route;\n                int pt = tmp[i];\n                tmp.erase(tmp.begin() + i);\n                tmp.insert(tmp.begin() + j, pt);\n                \n                int old_c = calc_cost(route);\n                int new_c = calc_cost(tmp);\n                \n                if (new_c < old_c && check_precedence(tmp)) {\n                    route = tmp;\n                    improved = true;\n                    goto next_iter;\n                }\n            }\n        }\n        next_iter:;\n    }\n}\n\n// ==================== Phase 3: Order Swapping ====================\nvoid run_order_swap(double time_budget) {\n    mt19937 rng(42);\n    double deadline = elapsed() + time_budget;\n    int best_cost = calc_cost(route);\n    \n    while (elapsed() < deadline) {\n        int in_idx = rng() % 50;\n        int out_idx;\n        do { out_idx = rng() % 1000; } while (find(sel_ids, sel_ids + 50, out_idx) != sel_ids + 50);\n        \n        // Try swapping\n        vector<int> old_route = route;\n        int old_id = sel_ids[in_idx];\n        sel_ids[in_idx] = out_idx + 1; // store 1-based\n        sp[in_idx] = all_orders[out_idx].p;\n        sd[in_idx] = all_orders[out_idx].d;\n        \n        // Remove old order points\n        route.erase(remove_if(route.begin(), route.end(), [&](int x) { return x == in_idx || x == in_idx + 50; }), route.end());\n        \n        // Insert new order points\n        vector<int> tmp = route;\n        // Insert pickup\n        int best_p_pos = -1, min_pd = 2e9;\n        for (int pos = 0; pos <= 98; ++pos) {\n            int delta = dist(pos == 0 ? BASE : get_pt(tmp[pos-1]), get_pt(in_idx)) +\n                        dist(get_pt(in_idx), pos == 98 ? BASE : get_pt(tmp[pos])) -\n                        dist(pos == 0 ? BASE : get_pt(tmp[pos-1]), pos == 98 ? BASE : get_pt(tmp[pos]));\n            if (delta < min_pd) { min_pd = delta; best_p_pos = pos; }\n        }\n        tmp.insert(tmp.begin() + best_p_pos, in_idx);\n        \n        // Insert delivery (must be after pickup)\n        int pickup_pos = best_p_pos;\n        int best_d_pos = -1, min_dd = 2e9;\n        for (int pos = pickup_pos + 1; pos <= 99; ++pos) {\n            int delta = dist(pos == 0 ? BASE : get_pt(tmp[pos-1]), get_pt(in_idx+50)) +\n                        dist(get_pt(in_idx+50), pos == 100 ? BASE : get_pt(tmp[pos])) -\n                        dist(pos == 0 ? BASE : get_pt(tmp[pos-1]), pos == 100 ? BASE : get_pt(tmp[pos]));\n            if (delta < min_dd) { min_dd = delta; best_d_pos = pos; }\n        }\n        tmp.insert(tmp.begin() + best_d_pos, in_idx + 50);\n        \n        int new_cost = calc_cost(tmp);\n        if (new_cost < best_cost) {\n            route = tmp;\n            best_cost = new_cost;\n            run_local_search(0.05); // Quick polish\n        } else {\n            // Revert\n            route = old_route;\n            sel_ids[in_idx] = old_id;\n            // Restore coordinates\n            for (int k = 0; k < 50; ++k) {\n                sp[k] = all_orders[sel_ids[k]-1].p;\n                sd[k] = all_orders[sel_ids[k]-1].d;\n            }\n        }\n    }\n}\n\n// ==================== Main ====================\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    for (int i = 0; i < 1000; ++i) {\n        cin >> all_orders[i].p.x >> all_orders[i].p.y >> all_orders[i].d.x >> all_orders[i].d.y;\n        all_orders[i].id = i + 1;\n    }\n    \n    // Initial Selection: 50 orders with pickups closest to base\n    vector<pair<int, int>> dists;\n    for (int i = 0; i < 1000; ++i) {\n        dists.emplace_back(dist(BASE, all_orders[i].p), i);\n    }\n    nth_element(dists.begin(), dists.begin() + 50, dists.end());\n    for (int i = 0; i < 50; ++i) {\n        int id = dists[i].second;\n        sel_ids[i] = all_orders[id].id;\n        sp[i] = all_orders[id].p;\n        sd[i] = all_orders[id].d;\n    }\n    \n    build_initial_route();\n    \n    // Phase 2: Intensive Route Optimization\n    run_local_search(0.8);\n    \n    // Phase 3: Order Set Optimization\n    run_order_swap(1.0);\n    \n    // Final Polish\n    run_local_search(0.2);\n    \n    // Output\n    cout << \"50\";\n    for (int i = 0; i < 50; ++i) cout << \" \" << sel_ids[i];\n    cout << \"\\n\";\n    \n    vector<Pt> out_path;\n    out_path.push_back(BASE);\n    for (int p : route) out_path.push_back(get_pt(p));\n    out_path.push_back(BASE);\n    \n    cout << out_path.size();\n    for (auto& p : out_path) cout << \" \" << p.x << \" \" << p.y;\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <utility>\n\nusing namespace std;\n\n// Disjoint Set Union (DSU) with path compression\nstruct DSU {\n    vector<int> parent;\n    DSU(int n) : parent(n) {\n        for (int i = 0; i < n; ++i) parent[i] = i;\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        i = find(i); j = find(j);\n        if (i != j) {\n            parent[i] = j;\n            return true;\n        }\n        return false;\n    }\n};\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 400;\n    const int M = 1995;\n\n    // 1. Read vertex coordinates\n    vector<pair<int, int>> coords(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n\n    // 2. Read edge endpoints and precompute d_i\n    vector<pair<int, int>> edges(M);\n    vector<int> d(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> edges[i].first >> edges[i].second;\n        long long dx = coords[edges[i].first].first - coords[edges[i].second].first;\n        long long dy = coords[edges[i].first].second - coords[edges[i].second].second;\n        // Euclidean distance rounded to nearest integer\n        d[i] = static_cast<int>(round(sqrt(dx * dx + dy * dy)));\n    }\n\n    DSU dsu(N);\n    const int INF = 1e9;\n\n    // 3. Process edges online\n    for (int i = 0; i < M; ++i) {\n        int l;\n        cin >> l;\n\n        int u = edges[i].first;\n        int v = edges[i].second;\n        int ru = dsu.find(u);\n        int rv = dsu.find(v);\n\n        if (ru == rv) {\n            // Already connected, accepting would form a cycle. Reject.\n            cout << \"0\\n\";\n        } else {\n            // Look ahead to find the minimum base distance of future edges\n            // that connect the current components ru and rv.\n            int best_d = INF;\n            for (int j = i + 1; j < M; ++j) {\n                int rju = dsu.find(edges[j].first);\n                int rjv = dsu.find(edges[j].second);\n                if ((rju == ru && rjv == rv) || (rju == rv && rjv == ru)) {\n                    if (d[j] < best_d) best_d = d[j];\n                }\n            }\n\n            // Heuristic threshold: accept if current cost is significantly lower\n            // than the scaled expectation of the best future option.\n            // Threshold 1.8 balances risk and expectation (E[l] = 2*d).\n            if (best_d == INF || l * 5 < best_d * 9) {\n                cout << \"1\\n\";\n                dsu.unite(ru, rv);\n            } else {\n                cout << \"0\\n\";\n            }\n        }\n        // Interactive requirement: flush output after each decision\n        cout.flush();\n    }\n\n    return 0;\n}","ahc008":"#pragma GCC optimize(\"O2\")\n#include <iostream>\n#include <vector>\n#include <string>\n#include <cstring>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nconst int H = 30, W = 30;\nint grid[H][W]; // 0: passable, 1: blocked\nstruct Pos { int x, y; };\nvector<Pos> pets;\nvector<Pos> humans;\n\ninline bool in_bounds(int x, int y) {\n    return x >= 0 && x < H && y >= 0 && y < W;\n}\n\n// Optimized BFS to compute component size and pet count from (sx, sy)\npair<int, int> bfs(int sx, int sy, const int g[H][W], const vector<Pos>& cur_pets) {\n    static int vis[H][W] = {0};\n    static int token = 0;\n    token++;\n    // Safety reset for token if it approaches limits\n    if (token > 1000000000) {\n        memset(vis, 0, sizeof(vis));\n        token = 1;\n    }\n\n    // Static array-based queue avoids heap allocation overhead\n    static pair<int,int> q[900];\n    int head = 0, tail = 0;\n    q[tail++] = {sx, sy};\n    vis[sx][sy] = token;\n    int sz = 0;\n\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    while(head < tail){\n        auto [cx, cy] = q[head++];\n        sz++;\n        for(int i=0; i<4; i++){\n            int nx = cx + dx[i], ny = cy + dy[i];\n            if(in_bounds(nx, ny) && vis[nx][ny] != token && g[nx][ny] == 0){\n                vis[nx][ny] = token;\n                q[tail++] = {nx, ny};\n            }\n        }\n    }\n    int np = 0;\n    for(auto& p : cur_pets){\n        if(vis[p.x][p.y] == token) np++;\n    }\n    return {sz, np};\n}\n\nbool can_block_target(int tx, int ty, int hx, int hy) {\n    if(!in_bounds(tx, ty)) return false;\n    if(grid[tx][ty] == 1) return true; // Already blocked\n    \n    // Target cannot contain pets or humans (except the actor)\n    for(auto& p : pets) if(p.x == tx && p.y == ty) return false;\n    for(const auto& h : humans){\n        if(h.x == tx && h.y == ty && !(h.x == hx && h.y == hy)) return false;\n    }\n    // Target's adjacent squares cannot contain pets\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    for(int i=0; i<4; i++){\n        int nx = tx + dx[i], ny = ty + dy[i];\n        if(in_bounds(nx, ny)){\n            for(auto& p : pets) if(p.x == nx && p.y == ny) return false;\n        }\n    }\n    return true;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N; cin >> N;\n    pets.resize(N);\n    vector<int> pet_types(N);\n    for(int i=0; i<N; i++) {\n        cin >> pets[i].x >> pets[i].y >> pet_types[i];\n        pets[i].x--; pets[i].y--;\n    }\n    int M; cin >> M;\n    humans.resize(M);\n    for(int i=0; i<M; i++) {\n        cin >> humans[i].x >> humans[i].y;\n        humans[i].x--; humans[i].y--;\n    }\n\n    // Initialize grid\n    for(int i=0; i<H; i++) for(int j=0; j<W; j++) grid[i][j] = 0;\n\n    const char acts[] = {'.', 'U', 'D', 'L', 'R', 'u', 'd', 'l', 'r'};\n    // Fixed direction mapping: moves and blocks share the same directional offsets\n    const int ddx[9] = {0, -1, 1, 0, 0, -1, 1, 0, 0};\n    const int ddy[9] = {0, 0, 0, -1, 1, 0, 0, -1, 1};\n    const bool is_block_act[9] = {false, false, false, false, false, true, true, true, true};\n\n    for(int turn=0; turn<300; turn++){\n        string res = \"\";\n        vector<char> my_acts(M);\n\n        // Evaluate best action for each human independently\n        for(int i=0; i<M; i++){\n            int hx = humans[i].x, hy = humans[i].y;\n            double best_val = -1.0;\n            char best_a = '.';\n            bool best_blk_effective = false;\n\n            for(int a=0; a<9; a++){\n                if(a == 0) {\n                    // Stay action, always valid\n                } else {\n                    int tx = hx + ddx[a];\n                    int ty = hy + ddy[a];\n                    if(!in_bounds(tx, ty)) continue;\n                    if(is_block_act[a]){\n                        if(!can_block_target(tx, ty, hx, hy)) continue;\n                    } else {\n                        if(grid[tx][ty] != 0) continue; // Move target must be passable\n                    }\n                }\n\n                // Simulate action on a temporary grid\n                int tmp_grid[H][W];\n                memcpy(tmp_grid, grid, sizeof(tmp_grid));\n                Pos tmp_human = humans[i];\n                bool effective_blk = false;\n\n                if(a == 0) {\n                    // stay\n                } else if(is_block_act[a]) {\n                    int tx = hx + ddx[a], ty = hy + ddy[a];\n                    if(tmp_grid[tx][ty] == 0) {\n                        tmp_grid[tx][ty] = 1;\n                        effective_blk = true;\n                    }\n                } else {\n                    tmp_human.x += ddx[a];\n                    tmp_human.y += ddy[a];\n                }\n\n                auto [sz, np] = bfs(tmp_human.x, tmp_human.y, tmp_grid, pets);\n                double val = sz / (double)(1LL << np);\n                \n                // Greedy selection with tie-breaking favoring wall construction\n                if(val > best_val + 1e-9 || (abs(val - best_val) < 1e-9 && effective_blk && !best_blk_effective)){\n                    best_val = val;\n                    best_a = acts[a];\n                    best_blk_effective = effective_blk;\n                }\n            }\n            my_acts[i] = best_a;\n        }\n\n        // Output actions\n        for(char c : my_acts) res += c;\n        cout << res << \"\\n\";\n        cout.flush();\n\n        // Read pet movements for this turn\n        for(int i=0; i<N; i++){\n            string mv; cin >> mv;\n            int cx = pets[i].x, cy = pets[i].y;\n            for(char c : mv){\n                int nx = cx, ny = cy;\n                if(c=='U') nx--;\n                else if(c=='D') nx++;\n                else if(c=='L') ny--;\n                else if(c=='R') ny++;\n\n                if(in_bounds(nx, ny) && grid[nx][ny] == 0){\n                    cx = nx; cy = ny;\n                } else {\n                    break; // Invalid move, pet stays in current cell\n                }\n            }\n            pets[i].x = cx; pets[i].y = cy;\n        }\n\n        // Update local state to match judge's simultaneous execution\n        // 1. Apply blocks first (blocks take precedence over moves)\n        for(int i=0; i<M; i++){\n            int a_idx = -1;\n            for(int k=0; k<9; k++) if(acts[k] == my_acts[i]) { a_idx = k; break; }\n            if(a_idx != -1 && is_block_act[a_idx]){\n                int tx = humans[i].x + ddx[a_idx];\n                int ty = humans[i].y + ddy[a_idx];\n                if(in_bounds(tx, ty) && grid[tx][ty] == 0){\n                    grid[tx][ty] = 1;\n                }\n            }\n        }\n        // 2. Apply moves\n        vector<Pos> next_humans(M);\n        for(int i=0; i<M; i++){\n            int a_idx = -1;\n            for(int k=0; k<9; k++) if(acts[k] == my_acts[i]) { a_idx = k; break; }\n            next_humans[i] = humans[i];\n            if(a_idx != -1 && !is_block_act[a_idx] && my_acts[i] != '.'){\n                int nx = humans[i].x + ddx[a_idx];\n                int ny = humans[i].y + ddy[a_idx];\n                if(in_bounds(nx, ny) && grid[nx][ny] == 0){\n                    next_humans[i] = {nx, ny};\n                }\n            }\n        }\n        humans = next_humans;\n    }\n\n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cstring>\n#include <queue>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n\n#pragma GCC optimize(\"O3,unroll-loops\")\n\nusing namespace std;\n\n// Global arrays for cache locality and speed\nint nxt[400][4];\nbool blocked[400][4];\ndouble dp[201][400];\ndouble head_score[201];\ndouble cur_dp[201][400];\n\nstring get_bfs_path(int s_i, int s_j, int t_i, int t_j, const vector<string>& h, const vector<string>& v) {\n    int dist[20][20];\n    memset(dist, -1, sizeof(dist));\n    int pi[20][20], pj[20][20];\n    memset(pi, -1, sizeof(pi)); memset(pj, -1, sizeof(pj));\n    queue<pair<int,int>> q;\n    q.push({s_i, s_j});\n    dist[s_i][s_j] = 0;\n    int dr[] = {-1, 1, 0, 0};\n    int dc[] = {0, 0, -1, 1};\n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        if (r == t_i && c == t_j) break;\n        for (int k = 0; k < 4; ++k) {\n            int nr = r + dr[k], nc = c + dc[k];\n            if (nr < 0 || nr >= 20 || nc < 0 || nc >= 20) continue;\n            bool wall = false;\n            if (k == 0) wall = (v[r-1][c] == '1');\n            else if (k == 1) wall = (v[r][c] == '1');\n            else if (k == 2) wall = (h[r][c-1] == '1');\n            else if (k == 3) wall = (h[r][c] == '1');\n            if (!wall && dist[nr][nc] == -1) {\n                dist[nr][nc] = dist[r][c] + 1;\n                pi[nr][nc] = r; pj[nr][nc] = c;\n                q.push({nr, nc});\n            }\n        }\n    }\n    string path = \"\";\n    int r = t_i, c = t_j;\n    while (r != s_i || c != s_j) {\n        int pr = pi[r][c], pc = pj[r][c];\n        if (pr == r) path += (pc < c ? 'R' : 'L');\n        else path += (pr < r ? 'D' : 'U');\n        r = pr; c = pc;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int s_i, s_j, t_i, t_j;\n    double p;\n    if (!(cin >> s_i >> s_j >> t_i >> t_j >> p)) return 0;\n\n    vector<string> h(20), v(19);\n    for (int i = 0; i < 20; ++i) cin >> h[i];\n    for (int i = 0; i < 19; ++i) cin >> v[i];\n\n    // Precompute transition tables for O(1) access\n    for (int r = 0; r < 20; ++r) {\n        for (int c = 0; c < 20; ++c) {\n            int idx = r * 20 + c;\n            if (r > 0 && v[r-1][c] == '0') { nxt[idx][0] = (r-1)*20+c; blocked[idx][0] = false; }\n            else { nxt[idx][0] = idx; blocked[idx][0] = true; }\n            \n            if (r < 19 && v[r][c] == '0') { nxt[idx][1] = (r+1)*20+c; blocked[idx][1] = false; }\n            else { nxt[idx][1] = idx; blocked[idx][1] = true; }\n            \n            if (c > 0 && h[r][c-1] == '0') { nxt[idx][2] = r*20+(c-1); blocked[idx][2] = false; }\n            else { nxt[idx][2] = idx; blocked[idx][2] = true; }\n            \n            if (c < 19 && h[r][c] == '0') { nxt[idx][3] = r*20+(c+1); blocked[idx][3] = false; }\n            else { nxt[idx][3] = idx; blocked[idx][3] = true; }\n        }\n    }\n\n    int start_idx = s_i * 20 + s_j;\n    int target_idx = t_i * 20 + t_j;\n    double move_prob = 1.0 - p;\n\n    // Initial string: repeat BFS path to length 200\n    string path = get_bfs_path(s_i, s_j, t_i, t_j, h, v);\n    string s = \"\";\n    s.reserve(200);\n    int plen = path.empty() ? 1 : path.size();\n    for (int i = 0; i < 200; ++i) s += path[i % plen];\n\n    // Full DP initialization\n    memset(dp, 0, sizeof(dp));\n    memset(head_score, 0, sizeof(head_score));\n    dp[0][start_idx] = 1.0;\n\n    for (int t = 0; t < 200; ++t) {\n        int d = (s[t] == 'U' ? 0 : s[t] == 'D' ? 1 : s[t] == 'L' ? 2 : 3);\n        for (int idx = 0; idx < 400; ++idx) {\n            double prob = dp[t][idx];\n            if (prob < 1e-18) continue;\n            if (idx == target_idx) {\n                dp[t+1][target_idx] += prob;\n            } else {\n                dp[t+1][idx] += prob * p;\n                if (blocked[idx][d]) dp[t+1][idx] += prob * move_prob;\n                else dp[t+1][nxt[idx][d]] += prob * move_prob;\n            }\n        }\n        head_score[t+1] = head_score[t] + (400.0 - t) * (dp[t+1][target_idx] - dp[t][target_idx]);\n    }\n    double best_score = head_score[200];\n    double cur_score = best_score;\n    string best_s = s;\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist_pos(0, 199);\n    uniform_int_distribution<int> dist_char(0, 3);\n    uniform_real_distribution<double> dist_uni(0.0, 1.0);\n    char dirs[] = {'U', 'D', 'L', 'R'};\n\n    auto start_time = chrono::steady_clock::now();\n    double T = 12.0;\n    int iter = 0;\n    int improve_iter = 0;\n\n    // Simulated Annealing with incremental evaluation\n    while (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() < 1.85) {\n        T *= 0.99996; \n        if (T < 1e-10) T = 1e-10;\n        if (iter % 5000 == 0 && T < 0.5) T = max(T, 0.5); // Reheat to escape plateaus\n\n        int pos = dist_pos(rng);\n        char old_c = s[pos];\n        char new_c = dirs[dist_char(rng)];\n        if (new_c == old_c) { iter++; continue; }\n        s[pos] = new_c;\n\n        // Incremental DP evaluation\n        memcpy(&cur_dp[pos][0], &dp[pos][0], sizeof(double) * 400);\n        memset(&cur_dp[pos+1][0], 0, sizeof(double) * 400 * (200 - pos));\n        \n        double new_tail_score = 0.0;\n        for (int t = pos; t < 200; ++t) {\n            int td = (s[t] == 'U' ? 0 : s[t] == 'D' ? 1 : s[t] == 'L' ? 2 : 3);\n            double prev_target = cur_dp[t][target_idx];\n            for (int idx = 0; idx < 400; ++idx) {\n                double prob = cur_dp[t][idx];\n                if (prob < 1e-18) continue;\n                if (idx == target_idx) {\n                    cur_dp[t+1][target_idx] += prob;\n                } else {\n                    cur_dp[t+1][idx] += prob * p;\n                    if (blocked[idx][td]) cur_dp[t+1][idx] += prob * move_prob;\n                    else cur_dp[t+1][nxt[idx][td]] += prob * move_prob;\n                }\n            }\n            double reach = cur_dp[t+1][target_idx] - prev_target;\n            new_tail_score += (400.0 - t) * reach;\n        }\n\n        double total_new_score = head_score[pos] + new_tail_score;\n        double delta = total_new_score - cur_score;\n\n        if (delta > 0 || dist_uni(rng) < exp(min(delta / T, 0.0))) {\n            cur_score = total_new_score;\n            if (total_new_score > best_score) {\n                best_score = total_new_score;\n                best_s = s;\n                improve_iter = iter;\n            }\n            // Apply changes to main state\n            memcpy(&dp[pos+1][0], &cur_dp[pos+1][0], sizeof(double)*400*(200-pos));\n            double running = head_score[pos];\n            for (int t = pos; t < 200; ++t) {\n                double reach = dp[t+1][target_idx] - dp[t][target_idx];\n                running += (400.0 - t) * reach;\n                head_score[t+1] = running;\n            }\n        } else {\n            s[pos] = old_c;\n        }\n        iter++;\n\n        // Random restart if stuck for too long\n        if (iter - improve_iter > 40000) {\n            s = best_s;\n            for(int k=0; k<15; ++k) s[dist_pos(rng)] = dirs[dist_char(rng)];\n            \n            memset(dp, 0, sizeof(dp));\n            dp[0][start_idx] = 1.0;\n            for (int t = 0; t < 200; ++t) {\n                int d = (s[t] == 'U' ? 0 : s[t] == 'D' ? 1 : s[t] == 'L' ? 2 : 3);\n                for (int idx = 0; idx < 400; ++idx) {\n                    double prob = dp[t][idx];\n                    if (prob < 1e-18) continue;\n                    if (idx == target_idx) dp[t+1][target_idx] += prob;\n                    else {\n                        dp[t+1][idx] += prob * p;\n                        if (blocked[idx][d]) dp[t+1][idx] += prob * move_prob;\n                        else dp[t+1][nxt[idx][d]] += prob * move_prob;\n                    }\n                }\n                head_score[t+1] = head_score[t] + (400.0 - t) * (dp[t+1][target_idx] - dp[t][target_idx]);\n            }\n            cur_score = head_score[200];\n            T = 8.0; \n            improve_iter = iter;\n        }\n    }\n\n    cout << best_s << \"\\n\";\n    return 0;\n}","ahc010":"/*\n    Solution for AHC010\n    Improved with Heuristic-Guided Simulated Annealing\n    - Uses a connectivity heuristic to bias move selection.\n    - Optimized grid representation and loop detection.\n    - Efficient memory usage to fit within time limits.\n*/\n#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <cstring>\n\nusing namespace std;\n\nconst int H = 30;\nconst int W = 30;\nconst int N = H * W;\nconst int DIRS = 4;\n\n// Directions: 0: Left, 1: Up, 2: Right, 3: Down\n// di, dj represent the change in coordinates\nconst int di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n\n// to_table[type][enter_dir] -> exit_dir\n// If -1, the tile cannot be entered from such a direction.\nconst int to_table[8][4] = {\n    {1, 0, -1, -1}, // 0: Curve L-U\n    {3, -1, -1, 0}, // 1: Curve L-D\n    {-1, -1, 3, 2}, // 2: Curve R-D\n    {-1, 2, 1, -1}, // 3: Curve R-U\n    {1, 0, 3, 2},   // 4: Two curves (L-U) and (R-D)\n    {3, 2, 1, 0},   // 5: Two curves (L-D) and (U-R)\n    {2, -1, 0, -1}, // 6: Straight Horizontal (L-R)\n    {-1, 3, -1, 1}  // 7: Straight Vertical (U-D)\n};\n\n// Paths for each type: list of pairs {d1, d2} representing connections\n// -1 indicates no second path\nconst pair<int, int> type_paths[8][2] = {\n    {{0, 1}, {-1, -1}}, // 0: L-U\n    {{0, 3}, {-1, -1}}, // 1: L-D\n    {{2, 3}, {-1, -1}}, // 2: R-D\n    {{2, 1}, {-1, -1}}, // 3: R-U\n    {{0, 1}, {2, 3}},   // 4: L-U, R-D\n    {{0, 3}, {1, 2}},   // 5: L-D, U-R\n    {{0, 2}, {-1, -1}}, // 6: L-R\n    {{1, 3}, {-1, -1}}  // 7: U-D\n};\n\nint grid[N];\nint initial_grid[N];\nint best_grid[N];\nlong long best_score = 0;\n\n// Visited arrays for cycle detection\n// vis_call stores the global call ID\n// vis_trace stores the current trace ID within a call\n// vis_idx stores the step index in the trace\nint vis_call[N][DIRS];\nint vis_trace[N][DIRS];\nint vis_idx[N][DIRS];\nint global_call_id = 0;\n\nvector<int> valid_moves[N];\nint r_coord[N];\nint c_coord[N];\n\nvoid precompute() {\n    for (int i = 0; i < H; ++i) {\n        for (int j = 0; j < W; ++j) {\n            int idx = i * W + j;\n            r_coord[idx] = i;\n            c_coord[idx] = j;\n            \n            int t = initial_grid[idx];\n            if (t >= 0 && t <= 3) {\n                valid_moves[idx] = {0, 1, 2, 3};\n            } else if (t == 4 || t == 5) {\n                valid_moves[idx] = {4, 5};\n            } else { // 6, 7\n                valid_moves[idx] = {6, 7};\n            }\n        }\n    }\n}\n\n// Heuristic: Returns a score based on how well the tile connects to neighbors\n// Score += 2 for each fully connected path (both ends match neighbors)\ninline int get_heuristic(int idx, int type) {\n    int r = r_coord[idx];\n    int c = c_coord[idx];\n    int score = 0;\n    \n    const pair<int, int>* paths = type_paths[type];\n    \n    // Check Path 1\n    int d1_1 = paths[0].first;\n    int d1_2 = paths[0].second;\n    \n    // Check connection for d1_1\n    bool p1 = false;\n    int nr1 = r + di[d1_1];\n    int nc1 = c + dj[d1_1];\n    if (nr1 >= 0 && nr1 < H && nc1 >= 0 && nc1 < W) {\n        int nidx1 = nr1 * W + nc1;\n        int ntype1 = grid[nidx1];\n        int opp1 = (d1_1 + 2) & 3;\n        if (to_table[ntype1][opp1] != -1) p1 = true;\n    }\n    \n    // Check connection for d1_2\n    bool p2 = false;\n    int nr2 = r + di[d1_2];\n    int nc2 = c + dj[d1_2];\n    if (nr2 >= 0 && nr2 < H && nc2 >= 0 && nc2 < W) {\n        int nidx2 = nr2 * W + nc2;\n        int ntype2 = grid[nidx2];\n        int opp2 = (d1_2 + 2) & 3;\n        if (to_table[ntype2][opp2] != -1) p2 = true;\n    }\n    \n    if (p1 && p2) score += 2;\n    \n    // Check Path 2 (if exists)\n    int d2_1 = paths[1].first;\n    if (d2_1 != -1) {\n        int d2_2 = paths[1].second;\n        \n        bool p3 = false;\n        int nr3 = r + di[d2_1];\n        int nc3 = c + dj[d2_1];\n        if (nr3 >= 0 && nr3 < H && nc3 >= 0 && nc3 < W) {\n            int nidx3 = nr3 * W + nc3;\n            int ntype3 = grid[nidx3];\n            int opp3 = (d2_1 + 2) & 3;\n            if (to_table[ntype3][opp3] != -1) p3 = true;\n        }\n        \n        bool p4 = false;\n        int nr4 = r + di[d2_2];\n        int nc4 = c + dj[d2_2];\n        if (nr4 >= 0 && nr4 < H && nc4 >= 0 && nc4 < W) {\n            int nidx4 = nr4 * W + nc4;\n            int ntype4 = grid[nidx4];\n            int opp4 = (d2_2 + 2) & 3;\n            if (to_table[ntype4][opp4] != -1) p4 = true;\n        }\n        \n        if (p3 && p4) score += 2;\n    }\n    return score;\n}\n\n// Calculates the score of the current grid configuration\n// Score = L1 * L2\nlong long calc_score() {\n    global_call_id++;\n    int current_trace_id = 0;\n    \n    long long max1 = 0, max2 = 0;\n    \n    for (int idx = 0; idx < N; ++idx) {\n        for (int d = 0; d < 4; ++d) {\n            int type = grid[idx];\n            int exit_d = to_table[type][d];\n            if (exit_d == -1) continue;\n            \n            // If visited, skip\n            if (vis_call[idx][d] == global_call_id) continue;\n            \n            current_trace_id++;\n            int cur_idx = idx;\n            int cur_d = d;\n            int len = 0;\n            bool is_cycle = false;\n            long long cycle_len = 0;\n            \n            // Mark start state\n            vis_call[cur_idx][cur_d] = global_call_id;\n            vis_trace[cur_idx][cur_d] = current_trace_id;\n            vis_idx[cur_idx][cur_d] = 0;\n            \n            while (true) {\n                int type_curr = grid[cur_idx];\n                int exit_dir = to_table[type_curr][cur_d];\n                if (exit_dir == -1) break;\n                \n                int r = r_coord[cur_idx];\n                int c = c_coord[cur_idx];\n                int nr = r + di[exit_dir];\n                int nc = c + dj[exit_dir];\n                \n                if (nr < 0 || nr >= H || nc < 0 || nc >= W) break;\n                \n                int next_idx = nr * W + nc;\n                int next_d = (exit_dir + 2) & 3;\n                \n                // Check if next state visited\n                if (vis_call[next_idx][next_d] == global_call_id) {\n                    if (vis_trace[next_idx][next_d] == current_trace_id) {\n                        // Cycle detected\n                        cycle_len = (len + 1) - vis_idx[next_idx][next_d];\n                        is_cycle = true;\n                    }\n                    break;\n                }\n                \n                // Mark next state\n                vis_call[next_idx][next_d] = global_call_id;\n                vis_trace[next_idx][next_d] = current_trace_id;\n                vis_idx[next_idx][next_d] = len + 1;\n                \n                cur_idx = next_idx;\n                cur_d = next_d;\n                len++;\n            }\n            \n            if (is_cycle) {\n                if (cycle_len > max1) {\n                    max2 = max1;\n                    max1 = cycle_len;\n                } else if (cycle_len > max2) {\n                    max2 = cycle_len;\n                }\n            }\n        }\n    }\n    return max1 * max2;\n}\n\nint get_rotation(int initial, int current) {\n    if (initial >= 0 && initial <= 3) {\n        return (current - initial + 4) % 4;\n    } else if (initial == 4 || initial == 5) {\n        return (current != initial ? 1 : 0);\n    } else { // 6, 7\n        return (current != initial ? 1 : 0);\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    char c;\n    for (int i = 0; i < N; ++i) {\n        cin >> c;\n        initial_grid[i] = c - '0';\n        grid[i] = initial_grid[i];\n    }\n    \n    precompute();\n    \n    best_score = calc_score();\n    memcpy(best_grid, grid, sizeof(grid));\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist_idx(0, N - 1);\n    \n    auto start_time = chrono::high_resolution_clock::now();\n    double time_limit = 1.90; // Leave buffer\n    \n    long long current_score = best_score;\n    \n    // Heuristic weights (exp(h/T_heur))\n    double T_heur = 0.5;\n    double w0 = 1.0;\n    double w2 = exp(2.0 / T_heur);\n    double w4 = exp(4.0 / T_heur);\n    \n    double weights[4];\n    int moves_list[4];\n    \n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > time_limit) break;\n        \n        // Temperature schedule\n        double progress = elapsed / time_limit;\n        double T = 5000.0 * (1.0 - progress); \n        if (T < 0.01) T = 0.01;\n        \n        int idx = dist_idx(rng);\n        int num_moves = valid_moves[idx].size();\n        \n        // Prepare moves and calculate heuristic weights\n        double sum_w = 0;\n        for (int k = 0; k < num_moves; ++k) {\n            int m = valid_moves[idx][k];\n            moves_list[k] = m;\n            int h = get_heuristic(idx, m);\n            double w = (h == 4) ? w4 : ((h == 2) ? w2 : w0);\n            weights[k] = w;\n            sum_w += w;\n        }\n        \n        // Select move\n        int selected_move = -1;\n        double r_val = (double)rng() / 4294967296.0 * sum_w;\n        double acc = 0;\n        for (int k = 0; k < num_moves; ++k) {\n            acc += weights[k];\n            if (r_val < acc) {\n                selected_move = moves_list[k];\n                break;\n            }\n        }\n        if (selected_move == -1) selected_move = moves_list[num_moves - 1];\n        \n        int current_type = grid[idx];\n        if (selected_move == current_type) continue;\n        \n        // Apply move\n        grid[idx] = selected_move;\n        long long new_score = calc_score();\n        \n        long long delta = new_score - current_score;\n        bool accept = false;\n        \n        if (delta > 0) {\n            accept = true;\n        } else {\n            // Metropolis criterion\n            if (delta / T > -50.0) {\n                double prob = exp((double)delta / T);\n                double r_prob = (double)rng() / 4294967296.0;\n                if (r_prob < prob) accept = true;\n            }\n        }\n        \n        if (accept) {\n            current_score = new_score;\n            if (new_score > best_score) {\n                best_score = new_score;\n                memcpy(best_grid, grid, sizeof(grid));\n            }\n        } else {\n            grid[idx] = current_type;\n        }\n    }\n    \n    string res;\n    res.resize(N);\n    for (int i = 0; i < N; ++i) {\n        int r = get_rotation(initial_grid[i], best_grid[i]);\n        res[i] = (char)('0' + r);\n    }\n    cout << res << \"\\n\";\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Union-Find with copy support for backtracking\nstruct UF {\n    vector<int> p;\n    UF(int n = 0) : p(n, -1) {}\n    UF(const UF& other) : p(other.p) {}\n    int find(int x) { return p[x] == -1 ? x : p[x] = find(p[x]); }\n    void unite(int a, int b) {\n        a = find(a); b = find(b);\n        if (a != b) p[b] = a;\n    }\n    bool same(int a, int b) { return find(a) == find(b); }\n};\n\nint N;\nlong long T;\nvector<int> init_masks; // bitmask for each original tile\nvector<int> target_layout; // target_layout[pos] = original tile index\nstring moves;\n\n// Layout Finder State\nvector<int> tiles_mask;\nvector<bool> used;\nchrono::steady_clock::time_point start_time;\nbool found_layout = false;\n\nvoid dfs_layout(int pos, vector<int>& board, UF uf) {\n    if (found_layout) return;\n    auto now = chrono::steady_clock::now();\n    if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 900) return;\n\n    if (pos == N * N - 1) {\n        int root = uf.find(0);\n        for (int i = 1; i < N * N - 1; ++i) {\n            if (uf.find(i) != root) return;\n        }\n        target_layout = board;\n        found_layout = true;\n        return;\n    }\n\n    int r = pos / N, c = pos % N;\n    bool req_up = (r > 0 && board[(r - 1) * N + c] != -1 && (tiles_mask[board[(r - 1) * N + c]] & 8));\n    bool req_left = (c > 0 && board[r * N + c - 1] != -1 && (tiles_mask[board[r * N + c - 1]] & 4));\n\n    static vector<int> perm;\n    if (pos == 0) {\n        perm.resize(N * N - 1);\n        iota(perm.begin(), perm.end(), 0);\n        mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n        shuffle(perm.begin(), perm.end(), rng);\n    }\n\n    for (int tid : perm) {\n        if (used[tid]) continue;\n        int m = tiles_mask[tid];\n        if (req_up && !(m & 2)) continue;\n        if (req_left && !(m & 1)) continue;\n\n        board[pos] = tid;\n        used[tid] = true;\n\n        bool conn_up = false, conn_left = false;\n        if (r > 0 && board[(r - 1) * N + c] != -1 && (m & 2)) {\n            conn_up = true;\n            uf.unite(pos, pos - N);\n        }\n        if (c > 0 && board[r * N + c - 1] != -1 && (m & 1)) {\n            conn_left = true;\n            uf.unite(pos, pos - 1);\n        }\n\n        bool cycle = false;\n        if (conn_up && conn_left && uf.same(pos - N, pos - 1)) cycle = true;\n\n        if (!cycle) {\n            dfs_layout(pos + 1, board, uf);\n            if (found_layout) return;\n        }\n\n        used[tid] = false;\n        board[pos] = -1;\n    }\n}\n\n// BFS to move empty space to target position, avoiding solved cells and the current tile\nstring bfs_empty(int er, int ec, int tr, int tc, int gr, int gc, const vector<bool>& solved) {\n    if (er == gr && ec == gc) return \"\";\n    queue<pair<int, int>> q;\n    q.push({er, ec});\n    vector<int> par(N * N, -1);\n    vector<char> move_to(N * N, 0);\n    auto id = [&](int r, int c) { return r * N + c; };\n    par[id(er, ec)] = id(er, ec);\n\n    int dr[] = {-1, 1, 0, 0};\n    int dc[] = {0, 0, -1, 1};\n    char out_chars[] = {'D', 'U', 'R', 'L'}; // internal move -> output char\n\n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        if (r == gr && c == gc) {\n            string path;\n            int cur = id(r, c);\n            while (cur != id(er, ec)) {\n                path += move_to[cur];\n                cur = par[cur];\n            }\n            reverse(path.begin(), path.end());\n            return path;\n        }\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i], nc = c + dc[i];\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n            int nid = id(nr, nc);\n            if (par[nid] != -1) continue;\n            if (solved[nid]) continue;\n            if (nr == tr && nc == tc) continue;\n            par[nid] = id(r, c);\n            move_to[nid] = out_chars[i];\n            q.push({nr, nc});\n        }\n    }\n    return \"\"; // Should not reach here with valid constraints\n}\n\nvoid apply_move(char c, vector<int>& board, int& empty_pos, vector<int>& cur_pos) {\n    int tr = empty_pos / N, tc = empty_pos % N;\n    int nr = tr, nc = tc;\n    if (c == 'U') nr--;      // Tile moves up, empty moves down\n    else if (c == 'D') nr++; // Tile moves down, empty moves up\n    else if (c == 'L') nc--; // Tile moves left, empty moves right\n    else if (c == 'R') nc++; // Tile moves right, empty moves left\n\n    int new_empty = nr * N + nc;\n    int tid = board[new_empty];\n    board[empty_pos] = tid;\n    board[new_empty] = -1;\n    cur_pos[tid] = empty_pos;\n    empty_pos = new_empty;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> T;\n    vector<string> grid(N);\n    init_masks.reserve(N * N - 1);\n    for (int i = 0; i < N; ++i) cin >> grid[i];\n\n    int empty_init_pos = -1;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            char c = grid[i][j];\n            if (c == '0') {\n                empty_init_pos = i * N + j;\n                continue;\n            }\n            int val;\n            if (c >= '0' && c <= '9') val = c - '0';\n            else val = c - 'a' + 10;\n            init_masks.push_back(val);\n        }\n    }\n\n    // Phase 1: Find valid tree layout\n    tiles_mask = init_masks;\n    used.assign(N * N - 1, false);\n    vector<int> board(N * N, -1);\n    start_time = chrono::steady_clock::now();\n    \n    // Run layout finder with a couple of attempts if needed\n    for (int attempt = 0; attempt < 5 && !found_layout; ++attempt) {\n        dfs_layout(0, board, UF(N * N));\n        if (!found_layout) {\n            // Reshuffle and retry\n            fill(used.begin(), used.end(), false);\n            fill(board.begin(), board.end(), -1);\n            mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n            shuffle(tiles_mask.begin(), tiles_mask.end(), rng);\n        }\n    }\n\n    if (!found_layout) {\n        // Fallback: simple row-major assignment (shouldn't happen given problem guarantee)\n        iota(target_layout.begin(), target_layout.end() - 1, 0);\n        target_layout.back() = -1;\n    }\n\n    // Phase 2: Solve sliding puzzle\n    vector<int> cur_board(N * N);\n    vector<int> cur_pos(N * N - 1);\n    int empty_pos = empty_init_pos;\n    \n    int tile_idx = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int pos = i * N + j;\n            if (i == N - 1 && j == N - 1) {\n                cur_board[pos] = -1;\n                continue;\n            }\n            int tid = target_layout[pos];\n            cur_board[pos] = tid; // temporary, will be overwritten during moves\n            cur_pos[tid] = -1;    // placeholder\n            tile_idx++;\n        }\n    }\n\n    // Initialize current board state correctly from input\n    tile_idx = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int pos = i * N + j;\n            if (grid[i][j] == '0') {\n                cur_board[pos] = -1;\n            } else {\n                cur_board[pos] = tile_idx;\n                cur_pos[tile_idx] = pos;\n                tile_idx++;\n            }\n        }\n    }\n\n    vector<bool> pos_solved(N * N, false);\n    moves.reserve(T);\n\n    for (int target_pos = 0; target_pos < N * N - 1; ++target_pos) {\n        int tid = target_layout[target_pos];\n        if (cur_pos[tid] == target_pos) {\n            pos_solved[target_pos] = true;\n            continue;\n        }\n\n        int tr = cur_pos[tid] / N, tc = cur_pos[tid] % N;\n        int tr_t = target_pos / N, tc_t = target_pos % N;\n\n        // Move tile towards target step by step\n        while (cur_pos[tid] != target_pos) {\n            int dtr = (tr > tr_t) ? -1 : (tr < tr_t) ? 1 : 0;\n            int dtc = (tc > tc_t) ? -1 : (tc < tc_t) ? 1 : 0;\n\n            // Empty needs to be opposite to desired tile movement\n            int need_r = tr - dtr, need_c = tc - dtc;\n            int empty_r = empty_pos / N, empty_c = empty_pos % N;\n\n            string path = bfs_empty(empty_r, empty_c, tr, tc, need_r, need_c, pos_solved);\n            for (char c : path) {\n                apply_move(c, cur_board, empty_pos, cur_pos);\n                moves += c;\n            }\n            tr = need_r; tc = need_c; // tile is still at (tr, tc), empty is now at (need_r, need_c)\n\n            // Slide tile\n            char slide_char;\n            if (dtr == -1) slide_char = 'U';\n            else if (dtr == 1) slide_char = 'D';\n            else if (dtc == -1) slide_char = 'L';\n            else slide_char = 'R';\n\n            apply_move(slide_char, cur_board, empty_pos, cur_pos);\n            moves += slide_char;\n\n            tr = cur_pos[tid] / N;\n            tc = cur_pos[tid] % N;\n        }\n        pos_solved[target_pos] = true;\n    }\n\n    // Trim empty moves if any (shouldn't happen)\n    while (!moves.empty() && moves.back() == '\\0') moves.pop_back();\n\n    cout << moves << \"\\n\";\n    return 0;\n}","ahc012":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\ntypedef long long ll;\n\nstruct Point {\n    ll x, y;\n    int id;\n};\n\nstruct Line {\n    ll p1x, p1y, p2x, p2y;\n};\n\nint main() {\n    // Optimize I/O operations\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, K;\n    if (!(cin >> N >> K)) return 0;\n\n    vector<int> a(11);\n    for (int i = 1; i <= 10; ++i) cin >> a[i];\n\n    vector<Point> pts(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> pts[i].x >> pts[i].y;\n        pts[i].id = i;\n    }\n\n    // Place the convergence point Q far outside the cake.\n    // All cuts will pass through Q, making them non-intersecting chords inside the cake.\n    // This guarantees that pieces once cut off remain intact.\n    ll Qx = 50000, Qy = 50000;\n    \n    // Sort points by polar angle around Q\n    vector<pair<long double, int>> angles(N);\n    for (int i = 0; i < N; ++i) {\n        angles[i] = {atan2((long double)(pts[i].y - Qy), (long double)(pts[i].x - Qx)), i};\n    }\n    sort(angles.begin(), angles.end());\n\n    vector<Line> cuts;\n    int cur = 0;\n    int fail_count = 0;\n    const int MAX_FAIL = N; // Safety break\n\n    while ((int)cuts.size() < K && fail_count < MAX_FAIL) {\n        bool satisfied_any = false;\n        \n        // Try to satisfy available demands\n        for (int d = 1; d <= 10; ++d) {\n            if (a[d] <= 0) continue;\n            \n            // Identify the two boundary points of the candidate wedge\n            int idx1 = (cur + d - 1) % N;\n            int idx2 = (cur + d) % N;\n            \n            ll x1 = pts[angles[idx1].second].x;\n            ll y1 = pts[angles[idx1].second].y;\n            ll x2 = pts[angles[idx2].second].x;\n            ll y2 = pts[angles[idx2].second].y;\n            \n            // Vectors from Q to boundary points\n            ll dx1 = x1 - Qx, dy1 = y1 - Qy;\n            ll dx2 = x2 - Qx, dy2 = y2 - Qy;\n            \n            bool found = false;\n            ll best_ux = 0, best_uy = 0;\n            \n            // Try positive linear combinations to find a direction strictly between the two vectors\n            for (int ca = 1; ca <= 5; ++ca) {\n                for (int cb = 1; cb <= 5; ++cb) {\n                    ll ux = ca * dx1 + cb * dx2;\n                    ll uy = ca * dy1 + cb * dy2;\n                    if (ux == 0 && uy == 0) continue;\n                    \n                    // Verify the line through Q with direction (ux, uy) doesn't pass through any strawberry\n                    bool ok = true;\n                    for (int i = 0; i < N; ++i) {\n                        ll px = pts[i].x - Qx;\n                        ll py = pts[i].y - Qy;\n                        // Cross product == 0 means collinear\n                        if (ux * py - uy * px == 0) {\n                            ok = false; break;\n                        }\n                    }\n                    if (ok) {\n                        best_ux = ux; best_uy = uy;\n                        found = true;\n                        break;\n                    }\n                }\n                if (found) break;\n            }\n            \n            if (found) {\n                // Output line passing through Q and Q + direction vector\n                cuts.push_back({Qx, Qy, Qx + best_ux, Qy + best_uy});\n                a[d]--;\n                cur = (cur + d) % N;\n                satisfied_any = true;\n                fail_count = 0;\n                break;\n            }\n        }\n        if (!satisfied_any) {\n            fail_count++;\n            cur = (cur + 1) % N; // Advance to avoid infinite loops on tight gaps\n        }\n    }\n\n    // Output results\n    cout << cuts.size() << \"\\n\";\n    for (const auto& l : cuts) {\n        cout << l.p1x << \" \" << l.p1y << \" \" << l.p2x << \" \" << l.p2y << \"\\n\";\n    }\n\n    return 0;\n}","ahc014":"#pragma GCC optimize(\"O3,unroll-loops\")\n#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nbool has_dot[65][65];\nbool used_right[65][65], used_up[65][65], used_ur[65][65], used_dr[65][65];\nlong long weight[65][65];\n\nstruct Point { int x, y; };\nvector<Point> all_points;\nvector<tuple<Point, Point, Point, Point>> result;\n\ninline int sgn(int x) { return (x > 0) - (x < 0); }\n\n// Checks edge segments and interior dots between a and b.\n// If mark is true, commits the edges as used.\nbool check_segment(Point a, Point b, bool mark) {\n    int dx = sgn(b.x - a.x), dy = sgn(b.y - a.y);\n    int cx = a.x, cy = a.y;\n    while (cx != b.x || cy != b.y) {\n        int nx = cx + dx, ny = cy + dy;\n        // Check interior dots (exclude the endpoint b)\n        if (nx != b.x || ny != b.y) {\n            if (has_dot[nx][ny]) return false;\n        }\n        // Check edge usage\n        bool used = false;\n        if (dx == 1 && dy == 0) used = used_right[cx][cy];\n        else if (dx == -1 && dy == 0) used = used_right[cx-1][cy];\n        else if (dx == 0 && dy == 1) used = used_up[cx][cy];\n        else if (dx == 0 && dy == -1) used = used_up[cx][cy-1];\n        else if (dx == 1 && dy == 1) used = used_ur[cx][cy];\n        else if (dx == -1 && dy == -1) used = used_ur[cx-1][cy-1];\n        else if (dx == -1 && dy == 1) used = used_dr[cx-1][cy];\n        else if (dx == 1 && dy == -1) used = used_dr[cx][cy];\n\n        if (used) return false;\n\n        if (mark) {\n            if (dx == 1 && dy == 0) used_right[cx][cy] = true;\n            else if (dx == -1 && dy == 0) used_right[cx-1][cy] = true;\n            else if (dx == 0 && dy == 1) used_up[cx][cy] = true;\n            else if (dx == 0 && dy == -1) used_up[cx][cy-1] = true;\n            else if (dx == 1 && dy == 1) used_ur[cx][cy] = true;\n            else if (dx == -1 && dy == -1) used_ur[cx-1][cy-1] = true;\n            else if (dx == -1 && dy == 1) used_dr[cx-1][cy] = true;\n            else if (dx == 1 && dy == -1) used_dr[cx][cy] = true;\n        }\n        cx = nx; cy = ny;\n    }\n    return true;\n}\n\n// Validates the entire rectangle perimeter\nbool check_rect(Point p1, Point p2, Point p3, Point p4, bool mark) {\n    Point pts[4] = {p1, p2, p3, p4};\n    for(int i = 0; i < 4; i++) {\n        if (!check_segment(pts[i], pts[(i+1)%4], false)) return false;\n    }\n    if (mark) {\n        for(int i = 0; i < 4; i++) {\n            check_segment(pts[i], pts[(i+1)%4], true);\n        }\n    }\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M)) return 0;\n    \n    int c = (N - 1) / 2;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            weight[i][j] = (long long)(i - c) * (i - c) + (j - c) * (j - c) + 1;\n            all_points.push_back({i, j});\n        }\n    }\n\n    vector<int> row_dots[65], col_dots[65];\n    for (int i = 0; i < M; i++) {\n        int x, y; cin >> x >> y;\n        has_dot[x][y] = true;\n        row_dots[y].push_back(x);\n        col_dots[x].push_back(y);\n    }\n\n    // Sort by weight descending\n    sort(all_points.begin(), all_points.end(), [](const Point& a, const Point& b) {\n        return weight[a.x][a.y] > weight[b.x][b.y];\n    });\n\n    clock_t start = clock();\n    double time_limit = 4.5 * CLOCKS_PER_SEC; // Safety margin for system test overhead\n\n    while ((double)(clock() - start) / CLOCKS_PER_SEC < 4.5) {\n        bool found = false;\n        for (auto& p1 : all_points) {\n            if (has_dot[p1.x][p1.y]) continue;\n            int px = p1.x, py = p1.y;\n            bool found_rect = false;\n            Point p2, p3, p4;\n\n            // Quick prune: must have at least one dot in row or col for axis-aligned,\n            // or on diagonals for 45-deg. We rely on fast inner loops instead of complex pruning.\n\n            // 1. Axis-Aligned Check\n            // p1=(px,py), p2=(x2,py), p4=(px,y2), p3=(x2,y2)\n            if (!row_dots[py].empty() && !col_dots[px].empty()) {\n                for (int x2 : row_dots[py]) {\n                    if (x2 == px) continue;\n                    for (int y2 : col_dots[px]) {\n                        if (y2 == py) continue;\n                        if (has_dot[x2][y2]) {\n                            p2 = {x2, py}; p3 = {x2, y2}; p4 = {px, y2};\n                            if (check_rect(p1, p2, p3, p4, false)) {\n                                found_rect = true;\n                                goto axis_done;\n                            }\n                        }\n                    }\n                }\n            }\n        axis_done:\n            if (found_rect) {\n                check_rect(p1, p2, p3, p4, true);\n                has_dot[p1.x][p1.y] = true;\n                row_dots[py].push_back(p1.x);\n                col_dots[px].push_back(p1.y);\n                result.push_back({p1, p2, p3, p4});\n                found = true;\n                break;\n            }\n\n            // 2. 45-Degree Rotated Check\n            // p1=(px,py), p2=(px+a, py+a), p4=(px+b, py-b), p3=(px+a+b, py+a-b)\n            for (int a = -N; a <= N; a++) {\n                if (a == 0) continue;\n                int x2 = px + a, y2 = py + a;\n                if (x2 < 0 || x2 >= N || y2 < 0 || y2 >= N || !has_dot[x2][y2]) continue;\n                for (int b = -N; b <= N; b++) {\n                    if (b == 0) continue;\n                    int x4 = px + b, y4 = py - b;\n                    if (x4 < 0 || x4 >= N || y4 < 0 || y4 >= N || !has_dot[x4][y4]) continue;\n                    int x3 = x2 + b, y3 = y2 - b;\n                    if (x3 < 0 || x3 >= N || y3 < 0 || y3 >= N) continue;\n                    if (has_dot[x3][y3]) {\n                        p2 = {x2, y2}; p4 = {x4, y4}; p3 = {x3, y3};\n                        if (check_rect(p1, p2, p3, p4, false)) {\n                            found_rect = true;\n                            goto deg45_done;\n                        }\n                    }\n                }\n            }\n        deg45_done:\n            if (found_rect) {\n                check_rect(p1, p2, p3, p4, true);\n                has_dot[p1.x][p1.y] = true;\n                row_dots[py].push_back(p1.x);\n                col_dots[px].push_back(p1.y);\n                result.push_back({p1, p2, p3, p4});\n                found = true;\n                break;\n            }\n        }\n        if (!found) break; // No more valid moves\n    }\n\n    // Output\n    cout << result.size() << \"\\n\";\n    for (const auto& op : result) {\n        const auto& [p1, p2, p3, p4] = op;\n        cout << p1.x << \" \" << p1.y << \" \"\n             << p2.x << \" \" << p2.y << \" \"\n             << p3.x << \" \" << p3.y << \" \"\n             << p4.x << \" \" << p4.y << \"\\n\";\n    }\n\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <utility>\n\nusing namespace std;\n\n// Calculate sum of squares of connected component sizes\nint calc_score(const vector<vector<int>>& grid) {\n    vector<vector<bool>> visited(10, vector<bool>(10, false));\n    int total_score = 0;\n    int dr[] = {-1, 1, 0, 0};\n    int dc[] = {0, 0, -1, 1};\n    \n    for (int r = 0; r < 10; ++r) {\n        for (int c = 0; c < 10; ++c) {\n            if (grid[r][c] != 0 && !visited[r][c]) {\n                int flavor = grid[r][c];\n                int size = 0;\n                // Simple BFS using vector as queue\n                vector<pair<int, int>> q;\n                q.push_back({r, c});\n                visited[r][c] = true;\n                int head = 0;\n                while(head < (int)q.size()){\n                    auto [cr, cc] = q[head++];\n                    size++;\n                    for(int i=0; i<4; ++i){\n                        int nr = cr + dr[i];\n                        int nc = cc + dc[i];\n                        if(nr >= 0 && nr < 10 && nc >= 0 && nc < 10 && \n                           !visited[nr][nc] && grid[nr][nc] == flavor){\n                            visited[nr][nc] = true;\n                            q.push_back({nr, nc});\n                        }\n                    }\n                }\n                total_score += size * size;\n            }\n        }\n    }\n    return total_score;\n}\n\n// Apply tilt to grid\nvector<vector<int>> tilt(const vector<vector<int>>& grid, char dir) {\n    vector<vector<int>> next_grid = grid;\n    if (dir == 'L') {\n        for (int r = 0; r < 10; ++r) {\n            vector<int> row;\n            row.reserve(10);\n            for (int c = 0; c < 10; ++c) if (grid[r][c] != 0) row.push_back(grid[r][c]);\n            for (int c = 0; c < 10; ++c) {\n                if (c < (int)row.size()) next_grid[r][c] = row[c];\n                else next_grid[r][c] = 0;\n            }\n        }\n    } else if (dir == 'R') {\n        for (int r = 0; r < 10; ++r) {\n            vector<int> row;\n            row.reserve(10);\n            for (int c = 0; c < 10; ++c) if (grid[r][c] != 0) row.push_back(grid[r][c]);\n            int idx = 9;\n            for (int i = (int)row.size() - 1; i >= 0; --i) {\n                next_grid[r][idx--] = row[i];\n            }\n            for (int c = idx; c >= 0; --c) next_grid[r][c] = 0;\n        }\n    } else if (dir == 'F') {\n        for (int c = 0; c < 10; ++c) {\n            vector<int> col;\n            col.reserve(10);\n            for (int r = 0; r < 10; ++r) if (grid[r][c] != 0) col.push_back(grid[r][c]);\n            for (int r = 0; r < 10; ++r) {\n                if (r < (int)col.size()) next_grid[r][c] = col[r];\n                else next_grid[r][c] = 0;\n            }\n        }\n    } else if (dir == 'B') {\n        for (int c = 0; c < 10; ++c) {\n            vector<int> col;\n            col.reserve(10);\n            for (int r = 0; r < 10; ++r) if (grid[r][c] != 0) col.push_back(grid[r][c]);\n            int idx = 9;\n            for (int i = (int)col.size() - 1; i >= 0; --i) {\n                next_grid[idx--][c] = col[i];\n            }\n            for (int r = idx; r >= 0; --r) next_grid[r][c] = 0;\n        }\n    }\n    return next_grid;\n}\n\nint main() {\n    // Fast I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    vector<int> f(100);\n    for (int i = 0; i < 100; ++i) {\n        if (!(cin >> f[i])) return 0;\n    }\n\n    vector<vector<int>> grid(10, vector<int>(10, 0));\n    vector<char> dirs = {'F', 'B', 'L', 'R'};\n\n    for (int t = 0; t < 100; ++t) {\n        int p;\n        cin >> p;\n\n        // Place candy\n        int count = 0;\n        bool found = false;\n        for (int r = 0; r < 10; ++r) {\n            for (int c = 0; c < 10; ++c) {\n                if (grid[r][c] == 0) {\n                    count++;\n                    if (count == p) {\n                        grid[r][c] = f[t];\n                        found = true;\n                        break;\n                    }\n                }\n            }\n            if (found) break;\n        }\n\n        // For the 100th candy (t=99), the grid is full, so tilt does nothing.\n        // We can skip the output as per problem statement.\n        if (t < 99) {\n            int best_score = -1;\n            char best_dir = 'F';\n\n            for (char d : dirs) {\n                vector<vector<int>> next_grid = tilt(grid, d);\n                int s = calc_score(next_grid);\n                if (s > best_score) {\n                    best_score = s;\n                    best_dir = d;\n                }\n            }\n\n            grid = tilt(grid, best_dir);\n            cout << best_dir << endl;\n        }\n    }\n\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    cin.tie(nullptr);\n    ios::sync_with_stdio(false);\n\n    int M;\n    double eps;\n    if (!(cin >> M >> eps)) return 0;\n\n    // N=28 balances distinguishability and the 1/N score multiplier\n    const int N = 28;\n    cout << N << \"\\n\";\n\n    mt19937 rng(42);\n    vector<vector<int>> stored_degs(M, vector<int>(N));\n    vector<int> stored_edges(M), stored_tris(M);\n    vector<double> stored_mu(M), stored_var(M);\n\n    for (int k = 0; k < M; ++k) {\n        // Space densities uniformly to maximize feature separation\n        double p = 0.05 + 0.9 * k / (M - 1.0);\n        vector<bitset<30>> adj(N);\n        vector<int> deg(N, 0);\n        int ec = 0;\n\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                if (rng() % 10000 < static_cast<int>(p * 10000)) {\n                    adj[i][j] = adj[j][i] = 1;\n                    deg[i]++; deg[j]++;\n                    ec++;\n                }\n            }\n        }\n\n        // Count triangles using bitset intersection: O(N^3 / 64)\n        int tc = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                if (adj[i][j]) {\n                    tc += (adj[i] & adj[j]).count();\n                }\n            }\n        }\n        tc /= 3; // Each triangle counted 3 times (once per edge)\n\n        vector<int> sdeg = deg;\n        sort(sdeg.begin(), sdeg.end());\n        stored_degs[k] = sdeg;\n        stored_edges[k] = ec;\n        stored_tris[k] = tc;\n\n        // Precompute statistics for fast correlation\n        double mu = (double)ec * 2.0 / N;\n        stored_mu[k] = mu;\n        double var = 0.0;\n        for (int d : sdeg) var += (d - mu) * (d - mu);\n        stored_var[k] = var;\n\n        // Output graph string\n        string out;\n        out.reserve(N * (N - 1) / 2);\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                out += adj[i][j] ? '1' : '0';\n            }\n        }\n        cout << out << \"\\n\";\n    }\n    cout.flush();\n\n    // Process 100 queries\n    vector<int> q_deg(N);\n    for (int q = 0; q < 100; ++q) {\n        string h;\n        cin >> h;\n        vector<bitset<30>> q_adj(N);\n        fill(q_deg.begin(), q_deg.end(), 0);\n        int q_edges = 0, idx = 0;\n\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                if (h[idx] == '1') {\n                    q_adj[i][j] = q_adj[j][i] = 1;\n                    q_deg[i]++; q_deg[j]++;\n                    q_edges++;\n                }\n                idx++;\n            }\n        }\n\n        int q_tris = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                if (q_adj[i][j]) {\n                    q_tris += (q_adj[i] & q_adj[j]).count();\n                }\n            }\n        }\n        q_tris /= 3;\n\n        vector<int> sq_deg = q_deg;\n        sort(sq_deg.begin(), sq_deg.end());\n\n        double mu_q = (double)q_edges * 2.0 / N;\n        double var_q = 0.0;\n        for (int d : sq_deg) var_q += (d - mu_q) * (d - mu_q);\n\n        int best_k = 0;\n        double best_score = -1e18;\n\n        for (int k = 0; k < M; ++k) {\n            // Pearson correlation (invariant to linear noise transformation)\n            double cov = 0.0;\n            for (int i = 0; i < N; ++i) {\n                cov += (sq_deg[i] - mu_q) * (stored_degs[k][i] - stored_mu[k]);\n            }\n            double corr = (var_q < 1e-9 || stored_var[k] < 1e-9) \n                          ? 0.0 \n                          : cov / sqrt(max(0.0, var_q * stored_var[k]));\n\n            // Weighted scoring: correlation dominates, penalties break ties\n            double score = corr \n                           - 0.003 * abs(q_edges - stored_edges[k]) \n                           - 0.00003 * abs(q_tris - stored_tris[k]);\n\n            if (score > best_score) {\n                best_score = score;\n                best_k = k;\n            }\n        }\n\n        cout << best_k << \"\\n\";\n        cout.flush();\n    }\n\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n\n    struct EdgeInfo { int u, v, w; };\n    vector<EdgeInfo> edges(M);\n    vector<vector<pair<int, int>>> adj(N);\n\n    for (int i = 0; i < M; ++i) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        --u; --v;\n        edges[i] = {u, v, w};\n        adj[u].emplace_back(v, i);\n        adj[v].emplace_back(u, i);\n    }\n\n    // Skip coordinates\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n    }\n\n    mt19937_64 rng(42);\n    vector<long double> eb(M, 0.0);\n    vector<int> dist(N);\n    vector<vector<int>> pred(N);\n    vector<long double> sigma(N);\n    vector<long double> delta(N);\n    vector<int> nodes(N);\n    iota(nodes.begin(), nodes.end(), 0);\n\n    // Compute exact edge betweenness centrality\n    for (int s = 0; s < N; ++s) {\n        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;\n        fill(dist.begin(), dist.end(), 2e9);\n        dist[s] = 0;\n        pq.emplace(0, s);\n\n        for (int i = 0; i < N; ++i) pred[i].clear();\n\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u]) continue;\n            for (auto [v, id] : adj[u]) {\n                int w = edges[id].w;\n                if (dist[v] > d + w) {\n                    dist[v] = d + w;\n                    pred[v].clear();\n                    pred[v].push_back(id);\n                    pq.emplace(dist[v], v);\n                } else if (dist[v] == d + w) {\n                    pred[v].push_back(id);\n                }\n            }\n        }\n\n        sort(nodes.begin(), nodes.end(), [&](int a, int b) {\n            return dist[a] < dist[b];\n        });\n\n        fill(sigma.begin(), sigma.end(), 0.0);\n        sigma[s] = 1.0;\n        for (int u : nodes) {\n            if (u == s) continue;\n            for (int id : pred[u]) {\n                int p = (edges[id].u == u) ? edges[id].v : edges[id].u;\n                sigma[u] += sigma[p];\n            }\n        }\n\n        fill(delta.begin(), delta.end(), 0.0);\n        for (auto it = nodes.rbegin(); it != nodes.rend(); ++it) {\n            int u = *it;\n            if (sigma[u] == 0.0) continue;\n            for (int id : pred[u]) {\n                int p = (edges[id].u == u) ? edges[id].v : edges[id].u;\n                long double val = (sigma[p] / sigma[u]) * (1.0L + delta[u]);\n                delta[p] += val;\n                eb[id] += val;\n            }\n        }\n    }\n\n    // Add tiny noise to break ties deterministically\n    for (int i = 0; i < M; ++i) {\n        eb[i] += uniform_real_distribution<double>(0, 1e-9)(rng);\n    }\n\n    // Greedy initial assignment\n    vector<pair<long double, int>> sorted(M);\n    for (int i = 0; i < M; ++i) sorted[i] = {eb[i], i};\n    sort(sorted.begin(), sorted.end(), greater<>());\n\n    vector<int> assign(M);\n    vector<long double> day_sum(D, 0.0);\n\n    for (auto [w, idx] : sorted) {\n        int best_day = 0;\n        long double min_sum = day_sum[0];\n        for (int d = 1; d < D; ++d) {\n            if (day_sum[d] < min_sum) {\n                min_sum = day_sum[d];\n                best_day = d;\n            }\n        }\n        assign[idx] = best_day;\n        day_sum[best_day] += w;\n    }\n\n    // Local Search: Swap edges between days to minimize sum of squares of day sums\n    auto start = chrono::steady_clock::now();\n    while (true) {\n        if (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start).count() > 5000) break;\n\n        int i = rng() % M;\n        int j = rng() % M;\n        if (assign[i] == assign[j]) continue;\n\n        int d1 = assign[i], d2 = assign[j];\n        long double b1 = eb[i], b2 = eb[j];\n        long double s1 = day_sum[d1], s2 = day_sum[d2];\n        long double ns1 = s1 - b1 + b2;\n        long double ns2 = s2 - b2 + b1;\n\n        // Accept if strictly improves the load balance objective\n        if (ns1 * ns1 + ns2 * ns2 < s1 * s1 + s2 * s2 - 1e-9L) {\n            day_sum[d1] = ns1;\n            day_sum[d2] = ns2;\n            swap(assign[i], assign[j]);\n        }\n    }\n\n    // Output result (1-indexed days)\n    for (int i = 0; i < M; ++i) {\n        cout << assign[i] + 1 << (i == M - 1 ? \"\\n\" : \" \");\n    }\n\n    return 0;\n}","ahc019":"/*\n    Solution for AHC019\n    Heuristic approach:\n    1. Compute valid volume U1, U2 as intersection of silhouettes.\n       A block can only occupy (x,y,z) if f(z,x)=1 and r(z,y)=1.\n    2. Greedily find shared blocks by growing random connected shapes in U1 \n       and checking if they can fit into U2 (with rotation/translation).\n       This maximizes the volume of shared blocks, which is the primary score driver.\n    3. Fill remaining cells in U1 and U2 with 1x1x1 blocks, pairing them up \n       where possible to keep score low.\n*/\n#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\n\nint D;\nbool F[2][14][14], R[2][14][14];\nbool Grid[2][14][14][14];\nint Sol[2][14][14][14];\nbool visited[14][14][14];\n\nstruct Pt { int x, y, z; };\nvector<array<array<int,3>,3>> Rots;\n\n// Generate all 24 proper rotations (determinant 1)\nvoid gen_rots() {\n    vector<array<int,3>> basis = {\n        {1,0,0}, {-1,0,0}, {0,1,0}, {0,-1,0}, {0,0,1}, {0,0,-1}\n    };\n    for(const auto& r1 : basis) {\n        for(const auto& r2 : basis) {\n            // Check orthogonality\n            if(r1[0]*r2[0] + r1[1]*r2[1] + r1[2]*r2[2] != 0) continue;\n            for(const auto& r3 : basis) {\n                if(r1[0]*r3[0] + r1[1]*r3[1] + r1[2]*r3[2] != 0) continue;\n                if(r2[0]*r3[0] + r2[1]*r3[1] + r2[2]*r3[2] != 0) continue;\n                \n                // Check determinant is 1 (proper rotation, no flip)\n                int det = r1[0]*(r2[1]*r3[2] - r2[2]*r3[1])\n                        - r1[1]*(r2[0]*r3[2] - r2[2]*r3[0])\n                        + r1[2]*(r2[0]*r3[1] - r2[1]*r3[0]);\n                \n                if(det == 1) {\n                    array<array<int,3>,3> m;\n                    m[0] = r1; m[1] = r2; m[2] = r3;\n                    bool dup = false;\n                    for(const auto& exist : Rots) {\n                        if(exist == m) { dup = true; break; }\n                    }\n                    if(!dup) Rots.push_back(m);\n                }\n            }\n        }\n    }\n}\n\n// Check if shape fits in grid at given offset and rotation\nbool fits(const vector<Pt>& shape, int rot_idx, int dx, int dy, int dz, bool grid[14][14][14]) {\n    const auto& rot = Rots[rot_idx];\n    for(const auto& p : shape) {\n        int nx = rot[0][0]*p.x + rot[0][1]*p.y + rot[0][2]*p.z + dx;\n        int ny = rot[1][0]*p.x + rot[1][1]*p.y + rot[1][2]*p.z + dy;\n        int nz = rot[2][0]*p.x + rot[2][1]*p.y + rot[2][2]*p.z + dz;\n        if(nx < 0 || nx >= D || ny < 0 || ny >= D || nz < 0 || nz >= D) return false;\n        if(!grid[nx][ny][nz]) return false;\n    }\n    return true;\n}\n\n// Find any valid placement of shape in grid\ntuple<int,int,int,int> find_placement(const vector<Pt>& shape, bool grid[14][14][14]) {\n    for(int ri=0; ri<(int)Rots.size(); ri++) {\n        const auto& rot = Rots[ri];\n        int r_minx=14, r_miny=14, r_minz=14, r_maxx=-1, r_maxy=-1, r_maxz=-1;\n        // Compute bounding box of rotated shape\n        for(const auto& p : shape) {\n            int nx = rot[0][0]*p.x + rot[0][1]*p.y + rot[0][2]*p.z;\n            int ny = rot[1][0]*p.x + rot[1][1]*p.y + rot[1][2]*p.z;\n            int nz = rot[2][0]*p.x + rot[2][1]*p.y + rot[2][2]*p.z;\n            r_minx = min(r_minx, nx); r_miny = min(r_miny, ny); r_minz = min(r_minz, nz);\n            r_maxx = max(r_maxx, nx); r_maxy = max(r_maxy, ny); r_maxz = max(r_maxz, nz);\n        }\n        int rsx = r_maxx - r_minx + 1;\n        int rsy = r_maxy - r_miny + 1;\n        int rsz = r_maxz - r_minz + 1;\n        \n        if(rsx > D || rsy > D || rsz > D) continue;\n        \n        // Determine valid translation range\n        int dx_min = -r_minx;\n        int dx_max = D - 1 - r_maxx;\n        int dy_min = -r_miny;\n        int dy_max = D - 1 - r_maxy;\n        int dz_min = -r_minz;\n        int dz_max = D - 1 - r_maxz;\n        \n        for(int dx=dx_min; dx<=dx_max; dx++) {\n            for(int dy=dy_min; dy<=dy_max; dy++) {\n                for(int dz=dz_min; dz<=dz_max; dz++) {\n                    if(fits(shape, ri, dx, dy, dz, grid)) {\n                        return {dx, dy, dz, ri};\n                    }\n                }\n            }\n        }\n    }\n    return {-1, -1, -1, -1};\n}\n\n// Place shape in grid and solution array\nvoid place_shape(const vector<Pt>& shape, int rot_idx, int dx, int dy, int dz, int block_id, int sol[14][14][14], bool grid[14][14][14]) {\n    const auto& rot = Rots[rot_idx];\n    for(const auto& p : shape) {\n        int nx = rot[0][0]*p.x + rot[0][1]*p.y + rot[0][2]*p.z + dx;\n        int ny = rot[1][0]*p.x + rot[1][1]*p.y + rot[1][2]*p.z + dy;\n        int nz = rot[2][0]*p.x + rot[2][1]*p.y + rot[2][2]*p.z + dz;\n        grid[nx][ny][nz] = false;\n        sol[nx][ny][nz] = block_id;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(0); cin.tie(0);\n    if(!(cin >> D)) return 0;\n    \n    // Read Input\n    for(int k=0; k<2; k++) {\n        for(int z=0; z<D; z++) {\n            string s; cin >> s;\n            for(int x=0; x<D; x++) F[k][z][x] = (s[x] == '1');\n        }\n        for(int z=0; z<D; z++) {\n            string s; cin >> s;\n            for(int y=0; y<D; y++) R[k][z][y] = (s[y] == '1');\n        }\n    }\n    \n    gen_rots();\n    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n    shuffle(Rots.begin(), Rots.end(), rng);\n    \n    // Initialize Grids with intersection of silhouettes\n    for(int k=0; k<2; k++) {\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                    // A cell is valid only if both silhouettes allow it\n                    Grid[k][x][y][z] = F[k][z][x] && R[k][z][y];\n                    Sol[k][x][y][z] = 0;\n                }\n            }\n        }\n    }\n    \n    int block_id = 1;\n    auto start_time = chrono::steady_clock::now();\n    \n    int dirs[6][3] = {{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}};\n    vector<Pt> visited_list;\n    visited_list.reserve(D*D*D);\n    \n    // Helper to mark visited and track for reset\n    auto mark = [&](int x, int y, int z) -> bool {\n        if(!visited[x][y][z]) {\n            visited[x][y][z] = true;\n            visited_list.push_back({x,y,z});\n            return true;\n        }\n        return false;\n    };\n    \n    // Phase 1: Greedy shared block packing\n    while(chrono::duration<double>(chrono::steady_clock::now() - start_time).count() < 5.5) {\n        // Find a random starting cell in Grid[0]\n        int sx=-1, sy=-1, sz=-1;\n        int attempts = 0;\n        while(sx == -1 && attempts < 2000) {\n            int rx = rng() % D;\n            int ry = rng() % D;\n            int rz = rng() % D;\n            if(Grid[0][rx][ry][rz]) {\n                sx=rx; sy=ry; sz=rz;\n            }\n            attempts++;\n        }\n        if(sx == -1) break; // No more cells in Grid[0]\n        \n        // Grow a random connected shape\n        vector<Pt> shape;\n        shape.reserve(20);\n        vector<Pt> candidates;\n        candidates.reserve(50);\n        \n        mark(sx, sy, sz);\n        shape.push_back({sx, sy, sz});\n        \n        for(auto& d : dirs) {\n            int nx=sx+d[0], ny=sy+d[1], nz=sz+d[2];\n            if(nx>=0 && nx<D && ny>=0 && ny<D && nz>=0 && nz<D && Grid[0][nx][ny][nz]) {\n                if(mark(nx, ny, nz)) {\n                    candidates.push_back({nx,ny,nz});\n                }\n            }\n        }\n        \n        int target_size = 2 + rng() % 10; // Target size 2 to 11\n        while((int)shape.size() < target_size && !candidates.empty()) {\n            int idx = rng() % candidates.size();\n            Pt p = candidates[idx];\n            candidates[idx] = candidates.back();\n            candidates.pop_back();\n            \n            shape.push_back(p);\n            \n            for(auto& d : dirs) {\n                int nx=p.x+d[0], ny=p.y+d[1], nz=p.z+d[2];\n                if(nx>=0 && nx<D && ny>=0 && ny<D && nz>=0 && nz<D && Grid[0][nx][ny][nz]) {\n                    if(mark(nx, ny, nz)) {\n                        candidates.push_back({nx,ny,nz});\n                    }\n                }\n            }\n        }\n        \n        // Reset visited array for next iteration\n        for(auto& p : visited_list) visited[p.x][p.y][p.z] = false;\n        visited_list.clear();\n        \n        // Check if shape fits in Grid[1]\n        auto res = find_placement(shape, Grid[1]);\n        int dx, dy, dz, ri;\n        tie(dx, dy, dz, ri) = res;\n        \n        if(ri != -1) {\n            // Place in Grid[1]\n            place_shape(shape, ri, dx, dy, dz, block_id, Sol[1], Grid[1]);\n            // Place in Grid[0] (shape is already in Grid[0] coordinates)\n            for(const auto& p : shape) {\n                Grid[0][p.x][p.y][p.z] = false;\n                Sol[0][p.x][p.y][p.z] = block_id;\n            }\n            block_id++;\n        }\n    }\n    \n    // Phase 2: Fill remaining cells\n    vector<Pt> rem0, rem1;\n    for(int x=0; x<D; x++) for(int y=0; y<D; y++) for(int z=0; z<D; z++) {\n        if(Grid[0][x][y][z]) rem0.push_back({x,y,z});\n        if(Grid[1][x][y][z]) rem1.push_back({x,y,z});\n    }\n    \n    // Shuffle to randomize matching\n    shuffle(rem0.begin(), rem0.end(), rng);\n    shuffle(rem1.begin(), rem1.end(), rng);\n    \n    // Match remaining cells as 1x1x1 shared blocks\n    int common = min(rem0.size(), rem1.size());\n    for(int i=0; i<common; i++) {\n        Sol[0][rem0[i].x][rem0[i].y][rem0[i].z] = block_id;\n        Sol[1][rem1[i].x][rem1[i].y][rem1[i].z] = block_id;\n        block_id++;\n    }\n    \n    // Fill remaining single-use blocks\n    for(int i=common; i<(int)rem0.size(); i++) {\n        Sol[0][rem0[i].x][rem0[i].y][rem0[i].z] = block_id;\n        block_id++;\n    }\n    for(int i=common; i<(int)rem1.size(); i++) {\n        Sol[1][rem1[i].x][rem1[i].y][rem1[i].z] = block_id;\n        block_id++;\n    }\n    \n    int n = block_id - 1;\n    cout << n << \"\\n\";\n    // Output format: x, then y, then z (based on index formula x*D^2 + y*D + z)\n    for(int k=0; k<2; k++) {\n        bool first = true;\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(!first) cout << \" \";\n                    cout << Sol[k][x][y][z];\n                    first = false;\n                }\n            }\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\n\n// Use fast I/O\nvoid fast_io() {\n    cin.tie(nullptr)->sync_with_stdio(false);\n}\n\nstruct Point { int x, y; };\nstruct Edge { int u, v; int w; };\n\n// Global variables to minimize allocation\nint N, M, K;\nvector<Point> pts;\nvector<Edge> edges;\nvector<Point> residents;\n\n// Precomputed distances: dists[u][k]\n// Stored as vector of vectors. 100 pointers overhead is negligible.\nvector<vector<float>> dists; \n// sorted_vertices[k] contains indices of vertices sorted by distance to resident k\nvector<vector<int>> sorted_vertices;\n\n// State\nvector<bool> active;\nvector<int> assignment; // assignment[k] = u\nvector<float> resident_dist; // resident_dist[k] = dist(assignment[k], k)\nvector<float> max_radius; // max_radius[u]\n\n// Helper for MST\nvector<int> sorted_edge_indices;\nvector<int> parent;\nint find_set(int v) {\n    if (v == parent[v]) return v;\n    return parent[v] = find_set(parent[v]);\n}\nbool union_sets(int a, int b) {\n    a = find_set(a); b = find_set(b);\n    if (a != b) { parent[b] = a; return true; }\n    return false;\n}\n\n// Precomputed Adjacency\nvector<vector<pair<int, int>>> adj;\n\n// Connectivity buffers\nvector<int> q_bfs;\nvector<int> vis_token;\nint current_token = 0;\n\n// Check if all active vertices are connected to vertex 0\n// Assumes active[0] is true.\nbool is_connected() {\n    current_token++;\n    q_bfs.clear();\n    q_bfs.push_back(0);\n    vis_token[0] = current_token;\n    int count = 1;\n    int active_count = 0;\n    for(int i=0; i<N; ++i) if(active[i]) active_count++;\n    \n    int head = 0;\n    while(head < (int)q_bfs.size()){\n        int u = q_bfs[head++];\n        for(auto& edge : adj[u]){\n            int v = edge.first;\n            if(active[v] && vis_token[v] != current_token){\n                vis_token[v] = current_token;\n                count++;\n                q_bfs.push_back(v);\n            }\n        }\n    }\n    return count == active_count;\n}\n\n// Compute MST cost for current active vertices\n// Returns -1 if disconnected\nlong long compute_mst() {\n    for(int i=0; i<N; ++i) parent[i] = i;\n    long long cost = 0;\n    int edges_used = 0;\n    int active_count = 0;\n    for(int i=0; i<N; ++i) if(active[i]) active_count++;\n    if (active_count == 0) return -1;\n    if (active_count == 1) return 0;\n    \n    for (int idx : sorted_edge_indices) {\n        const auto& e = edges[idx];\n        if (active[e.u] && active[e.v]) {\n            if (union_sets(e.u, e.v)) {\n                cost += e.w;\n                edges_used++;\n                if (edges_used == active_count - 1) break;\n            }\n        }\n    }\n    if (edges_used < active_count - 1) return -1;\n    return cost;\n}\n\nint main() {\n    fast_io();\n    // Use random seed based on time\n    mt19937_64 rng(chrono::high_resolution_clock::now().time_since_epoch().count());\n\n    if (!(cin >> N >> M >> K)) return 0;\n\n    pts.resize(N);\n    for (int i = 0; i < N; ++i) cin >> pts[i].x >> pts[i].y;\n\n    edges.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> edges[i].u >> edges[i].v >> edges[i].w;\n        --edges[i].u; --edges[i].v;\n    }\n\n    residents.resize(K);\n    for (int i = 0; i < K; ++i) cin >> residents[i].x >> residents[i].y;\n\n    // Precompute distances\n    dists.assign(N, vector<float>(K));\n    for (int i = 0; i < N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            dists[i][k] = hypot(pts[i].x - residents[k].x, pts[i].y - residents[k].y);\n        }\n    }\n\n    // Precompute sorted vertices for each resident\n    sorted_vertices.assign(K, vector<int>(N));\n    for (int k = 0; k < K; ++k) {\n        iota(sorted_vertices[k].begin(), sorted_vertices[k].end(), 0);\n        sort(sorted_vertices[k].begin(), sorted_vertices[k].end(), [&](int a, int b) {\n            return dists[a][k] < dists[b][k];\n        });\n    }\n\n    // Precompute adjacency\n    adj.assign(N, vector<pair<int, int>>());\n    for (int i = 0; i < M; ++i) {\n        adj[edges[i].u].push_back({edges[i].v, i});\n        adj[edges[i].v].push_back({edges[i].u, i});\n    }\n\n    // Precompute sorted edge indices\n    sorted_edge_indices.resize(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) {\n        return edges[a].w < edges[b].w;\n    });\n\n    // State initialization\n    active.assign(N, true); // Start with all active\n    assignment.assign(K, 0);\n    resident_dist.assign(K, 0);\n    max_radius.assign(N, 0);\n\n    // Initial assignment: assign each resident to closest vertex\n    for (int k = 0; k < K; ++k) {\n        int best_u = 0;\n        float best_d = dists[0][k];\n        for (int u = 1; u < N; ++u) {\n            if (dists[u][k] < best_d) {\n                best_d = dists[u][k];\n                best_u = u;\n            }\n        }\n        assignment[k] = best_u;\n        resident_dist[k] = best_d;\n    }\n    \n    // Init max_radius\n    fill(max_radius.begin(), max_radius.end(), 0.0f);\n    for(int k=0; k<K; ++k){\n        if(active[assignment[k]] && resident_dist[k] > max_radius[assignment[k]]){\n            max_radius[assignment[k]] = resident_dist[k];\n        }\n    }\n\n    parent.resize(N);\n    long long cur_S_mst = compute_mst();\n    double cur_S_radii = 0;\n    for(int i=0; i<N; ++i){\n        if(active[i]){\n            int p = (int)ceil(max_radius[i]);\n            if(p > 5000) p = 5000;\n            if(p < 0) p = 0;\n            cur_S_radii += (double)p * p;\n        }\n    }\n    \n    double cur_S = cur_S_mst + cur_S_radii;\n    double best_S = cur_S;\n    \n    // Store best state\n    vector<bool> best_active = active;\n    vector<int> best_assignment = assignment;\n    vector<float> best_resident_dist = resident_dist;\n    vector<float> best_max_radius = max_radius;\n\n    // Buffers\n    q_bfs.reserve(N);\n    vis_token.assign(N, 0);\n    \n    vector<int> changed_residents;\n    changed_residents.reserve(K);\n    vector<int> old_assignment;\n    old_assignment.reserve(K);\n    vector<float> old_resident_dist;\n    old_resident_dist.reserve(K);\n\n    // Distributions for SA\n    std::uniform_int_distribution<int> dist_u(0, N-1);\n    std::uniform_real_distribution<double> dist_01(0.0, 1.0);\n\n    double temp = 50000.0;\n    auto start_time = chrono::steady_clock::now();\n    \n    while (true) {\n        double elapsed = chrono::duration_cast<chrono::duration<double>>(chrono::steady_clock::now() - start_time).count();\n        if (elapsed > 1.90) break; // Leave 0.1s buffer for output\n        \n        int u = dist_u(rng);\n        bool was_active = active[u];\n        \n        // Connectivity check for removal\n        if (was_active && u != 0) {\n            active[u] = false;\n            if (!is_connected()) {\n                active[u] = true;\n                continue;\n            }\n            active[u] = true; // Restore before applying move\n        } else if (was_active && u == 0) {\n            // Cannot remove vertex 0 (Office)\n            continue;\n        }\n\n        // Propose move\n        active[u] = !was_active;\n        changed_residents.clear();\n        old_assignment.clear();\n        old_resident_dist.clear();\n        \n        bool move_valid = true;\n        \n        if (was_active) {\n            // Removing u: Reassign residents currently at u\n            for (int k = 0; k < K; ++k) {\n                if (assignment[k] == u) {\n                    int new_u = -1;\n                    float new_d = 1e9;\n                    // Find first active vertex in sorted list\n                    const auto& candidates = sorted_vertices[k];\n                    for (int cand : candidates) {\n                        if (active[cand]) {\n                            new_u = cand;\n                            new_d = dists[cand][k];\n                            break;\n                        }\n                    }\n                    if (new_u == -1 || new_d > 5000.0f) { \n                        move_valid = false; break; \n                    }\n                    \n                    changed_residents.push_back(k);\n                    old_assignment.push_back(assignment[k]);\n                    old_resident_dist.push_back(resident_dist[k]);\n                    \n                    assignment[k] = new_u;\n                    resident_dist[k] = new_d;\n                }\n            }\n        } else {\n            // Adding u: Check if u improves any resident's assignment\n            const auto& dist_row = dists[u];\n            for (int k = 0; k < K; ++k) {\n                float d = dist_row[k];\n                if (d < resident_dist[k]) {\n                    changed_residents.push_back(k);\n                    old_assignment.push_back(assignment[k]);\n                    old_resident_dist.push_back(resident_dist[k]);\n                    \n                    assignment[k] = u;\n                    resident_dist[k] = d;\n                }\n            }\n        }\n        \n        if (!move_valid) {\n            active[u] = was_active;\n            for (size_t i = 0; i < changed_residents.size(); ++i) {\n                assignment[changed_residents[i]] = old_assignment[i];\n                resident_dist[changed_residents[i]] = old_resident_dist[i];\n            }\n            continue;\n        }\n        \n        // Recompute max_radius\n        fill(max_radius.begin(), max_radius.end(), 0.0f);\n        for (int k = 0; k < K; ++k) {\n            int u_curr = assignment[k];\n            if (active[u_curr]) {\n                if (resident_dist[k] > max_radius[u_curr]) {\n                    max_radius[u_curr] = resident_dist[k];\n                }\n            }\n        }\n        \n        // Compute Score\n        long long new_mst = compute_mst();\n        bool ok = true;\n        double radii_cost = 0.0;\n        if (new_mst != -1) {\n            for (int i = 0; i < N; ++i) {\n                if (active[i]) {\n                    int p = (int)ceil(max_radius[i]);\n                    if (p > 5000) p = 5000;\n                    if (max_radius[i] > 5000.0f + 1e-6f) ok = false;\n                    radii_cost += (double)p * p;\n                }\n            }\n        } else {\n            ok = false;\n        }\n        \n        if (ok) {\n            double new_S = new_mst + radii_cost;\n            bool accept = false;\n            if (new_S < cur_S) accept = true;\n            else {\n                double delta = new_S - cur_S;\n                if (temp > 1e-9) {\n                    double prob = exp(-delta / temp);\n                    if (dist_01(rng) < prob) accept = true;\n                }\n            }\n            \n            if (accept) {\n                cur_S = new_S;\n                if (new_S < best_S) {\n                    best_S = new_S;\n                    best_active = active;\n                    best_assignment = assignment;\n                    best_resident_dist = resident_dist;\n                    best_max_radius = max_radius;\n                }\n            } else {\n                active[u] = was_active;\n                for (size_t i = 0; i < changed_residents.size(); ++i) {\n                    assignment[changed_residents[i]] = old_assignment[i];\n                    resident_dist[changed_residents[i]] = old_resident_dist[i];\n                }\n            }\n        } else {\n            active[u] = was_active;\n            for (size_t i = 0; i < changed_residents.size(); ++i) {\n                assignment[changed_residents[i]] = old_assignment[i];\n                resident_dist[changed_residents[i]] = old_resident_dist[i];\n            }\n        }\n        \n        temp *= 0.99995; // Slow cooling\n    }\n    \n    // Restore best state\n    active = best_active;\n    assignment = best_assignment;\n    resident_dist = best_resident_dist;\n    max_radius = best_max_radius;\n    \n    // Final MST calculation to determine used edges\n    // Re-run Kruskal\n    for(int i=0; i<N; ++i) parent[i] = i;\n    vector<int> edge_used(M, 0);\n    int active_cnt = 0;\n    for(int i=0; i<N; ++i) if(active[i]) active_cnt++;\n    \n    // Sort edges again or use pre-sorted. Pre-sorted is ready.\n    // Note: compute_mst modifies parent, so we reset it above.\n    // But we need to track which edges are used.\n    for (int idx : sorted_edge_indices) {\n        const auto& e = edges[idx];\n        if (active[e.u] && active[e.v]) {\n            if (union_sets(e.u, e.v)) {\n                edge_used[idx] = 1;\n            }\n        }\n    }\n    \n    cout << fixed << setprecision(0);\n    for (int i = 0; i < N; ++i) {\n        int p = 0;\n        if (active[i]) {\n            p = (int)ceil(max_radius[i]);\n            if (p < 0) p = 0;\n            if (p > 5000) p = 5000;\n        }\n        cout << p << (i == N-1 ? \"\" : \" \");\n    }\n    cout << \"\\n\";\n    \n    for (int i = 0; i < M; ++i) {\n        cout << edge_used[i] << (i == M-1 ? \"\" : \" \");\n    }\n    cout << \"\\n\";\n\n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <array>\n#include <utility>\n\nusing namespace std;\n\nint main() {\n    // Optimize I/O operations\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 30;\n    // Grid to store ball values. grid[x][y] holds the value at tier x, position y.\n    vector<vector<int>> grid(N, vector<int>(N));\n\n    // Read input\n    for (int x = 0; x < N; ++x) {\n        for (int y = 0; y <= x; ++y) {\n            cin >> grid[x][y];\n        }\n    }\n\n    // Store swap operations\n    vector<array<int, 4>> ops;\n    ops.reserve(5000); // Reserve reasonable memory to avoid reallocations\n\n    // Bottom-up heapify: process from second last tier up to the top\n    for (int x = N - 2; x >= 0; --x) {\n        for (int y = 0; y <= x; ++y) {\n            int cx = x, cy = y;\n            // Sift down the current node until it satisfies the min-heap property\n            while (cx < N - 1) {\n                int child1_val = grid[cx + 1][cy];\n                int child2_val = grid[cx + 1][cy + 1];\n                \n                // Find the smaller child\n                int target_y = cy;\n                if (child2_val < child1_val) {\n                    target_y = cy + 1;\n                }\n\n                // If current node is larger than the smaller child, swap them\n                if (grid[cx][cy] > grid[cx + 1][target_y]) {\n                    swap(grid[cx][cy], grid[cx + 1][target_y]);\n                    ops.push_back({cx, cy, cx + 1, target_y});\n                    // Move down to continue sifting\n                    cx++;\n                    cy = target_y;\n                } else {\n                    // Heap property satisfied for this branch\n                    break;\n                }\n            }\n        }\n    }\n\n    // Output results\n    cout << ops.size() << \"\\n\";\n    for (const auto& op : ops) {\n        cout << op[0] << \" \" << op[1] << \" \" << op[2] << \" \" << op[3] << \"\\n\";\n    }\n\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D, N;\nint grid[12][12]; \nint er, ec;\nint dr[4] = {-1, 1, 0, 0};\nint dc[4] = {0, 0, -1, 1};\npair<int, int> placed[100]; // Maps container ID to its position\n\n// Check if coordinates are within grid\nbool valid(int r, int c) {\n    return r >= 0 && r < D && c >= 0 && c < D;\n}\n\n// BFS to count reachable empty squares (0) from entrance.\n// Traversable cells: Empty (0) or Entrance (-2).\n// Obstacles (-1), Blocked (-3), and Containers (>0) are walls.\nint count_reachable_empty() {\n    int count = 0;\n    bool vis[12][12] = {};\n    queue<pair<int, int>> q;\n    q.push({er, ec});\n    vis[er][ec] = true;\n    \n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        if (grid[r][c] == 0) count++;\n        \n        for (int i = 0; i < 4; i++) {\n            int nr = r + dr[i], nc = c + dc[i];\n            if (valid(nr, nc) && !vis[nr][nc]) {\n                // Can only traverse empty squares or entrance\n                if (grid[nr][nc] == 0 || grid[nr][nc] == -2) {\n                    vis[nr][nc] = true;\n                    q.push({nr, nc});\n                }\n            }\n        }\n    }\n    return count;\n}\n\nint main() {\n    // Optimize I/O operations\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> D >> N;\n    er = 0; ec = (D - 1) / 2;\n    \n    // Initialize grid\n    for (int i = 0; i < D; i++) fill(grid[i], grid[i] + D, 0);\n    grid[er][ec] = -2; // Mark entrance\n    \n    for (int i = 0; i < N; i++) {\n        int r, c; cin >> r >> c;\n        grid[r][c] = -1; // Mark obstacle\n    }\n\n    int M = D * D - 1 - N; // Total containers to place\n    \n    // Placement Phase\n    for (int d = 0; d < M; d++) {\n        int t; cin >> t;\n        \n        // 1. Find all currently reachable empty squares and their distances from entrance\n        // Store as tuples: {distance, row, col}\n        vector<tuple<int, int, int>> reach; \n        bool vis[12][12] = {};\n        queue<tuple<int, int, int>> q; // r, c, dist\n        q.push({er, ec, 0});\n        vis[er][ec] = true;\n\n        while (!q.empty()) {\n            auto [r, c, dist] = q.front(); q.pop();\n            \n            for (int i = 0; i < 4; i++) {\n                int nr = r + dr[i], nc = c + dc[i];\n                if (valid(nr, nc) && !vis[nr][nc]) {\n                    if (grid[nr][nc] == 0) {\n                        vis[nr][nc] = true;\n                        reach.emplace_back(dist + 1, nr, nc);\n                        q.push({nr, nc, dist + 1});\n                    }\n                }\n            }\n        }\n        \n        // 2. Filter \"safe\" squares.\n        // A square is safe if placing a container there does not disconnect any other empty square from the entrance.\n        // We check this by temporarily blocking the square and verifying connectivity.\n        int total_empty = 0;\n        for(int i=0; i<D; ++i) for(int j=0; j<D; ++j) if(grid[i][j] == 0) total_empty++;\n        \n        vector<tuple<int, int, int>> safe_reach; \n        \n        for(auto& tup : reach) {\n            int dist = get<0>(tup);\n            int r = get<1>(tup);\n            int c = get<2>(tup);\n\n            // Temporarily block the square\n            grid[r][c] = -3; \n            int cnt = count_reachable_empty();\n            \n            // If we can still reach all other empty squares, it is safe.\n            // The blocked square itself is no longer empty, so we expect count to be total_empty - 1.\n            if(cnt == total_empty - 1) {\n                safe_reach.emplace_back(dist, r, c);\n            }\n            \n            // Revert the block\n            grid[r][c] = 0;\n        }\n        \n        // Fallback: If no safe squares found (unlikely if logic holds), allow placement in any reachable square\n        // to avoid getting stuck, though this might lead to suboptimal connectivity.\n        if(safe_reach.empty()) {\n            for(auto& tup : reach) {\n                safe_reach.push_back(tup);\n            }\n        }\n        \n        // 3. Sort safe squares by distance (closest to entrance first)\n        sort(safe_reach.begin(), safe_reach.end());\n\n        // 4. Choose a square based on the container ID t.\n        // Strategy: Place smaller IDs (retrieved earlier) closer to the entrance.\n        // Map t (0..M-1) to an index in the sorted list of safe squares.\n        int idx = 0;\n        if(!safe_reach.empty()) {\n            if(safe_reach.size() > 1)\n                idx = (int)((long long)t * (safe_reach.size() - 1) / (M - 1));\n            else\n                idx = 0;\n        }\n        \n        // Safety check for index bounds\n        if(idx >= (int)safe_reach.size()) idx = safe_reach.size() - 1;\n        if(idx < 0) idx = 0;\n\n        auto [dist, pr, pc] = safe_reach[idx];\n        placed[t] = {pr, pc};\n        grid[pr][pc] = t + 1; // Store container ID (+1 to distinguish from 0/empty)\n        cout << pr << \" \" << pc << \"\\n\" << flush;\n    }\n\n    // Retrieval Phase\n    vector<bool> retrieved(M, false);\n    for (int k = 0; k < M; k++) {\n        // BFS to find all empty squares reachable from the entrance\n        bool is_reach[12][12] = {};\n        bool vis[12][12] = {};\n        queue<pair<int, int>> q;\n        q.push({er, ec});\n        vis[er][ec] = true;\n        is_reach[er][ec] = true; // Entrance is reachable and empty\n\n        while (!q.empty()) {\n            auto [r, c] = q.front(); q.pop();\n            for (int i = 0; i < 4; i++) {\n                int nr = r + dr[i], nc = c + dc[i];\n                if (valid(nr, nc) && !vis[nr][nc]) {\n                    if (grid[nr][nc] == 0) { // Only traverse empty squares\n                        vis[nr][nc] = true;\n                        is_reach[nr][nc] = true;\n                        q.push({nr, nc});\n                    }\n                }\n            }\n        }\n\n        int best_id = -1;\n        pair<int, int> best_pos = {-1, -1};\n\n        // Greedily pick the smallest ID that is accessible.\n        // A container is accessible if it is adjacent to a reachable empty square.\n        for (int id = 0; id < M; id++) {\n            if (retrieved[id]) continue;\n            auto [r, c] = placed[id];\n            \n            bool reachable = false;\n            for (int i = 0; i < 4; i++) {\n                int nr = r + dr[i], nc = c + dc[i];\n                if (valid(nr, nc) && is_reach[nr][nc]) {\n                    reachable = true;\n                    break;\n                }\n            }\n            \n            if (reachable) {\n                best_id = id;\n                best_pos = {r, c};\n                break; // Found the smallest retrievable ID\n            }\n        }\n        \n        if(best_id != -1) {\n            retrieved[best_id] = true;\n            grid[best_pos.first][best_pos.second] = 0; // Free up the square\n            cout << best_pos.first << \" \" << best_pos.second << \"\\n\" << flush;\n        }\n    }\n\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 52;\nconst int MAXM = 101;\n\nint grid[MAXN][MAXN];\nint contacts[MAXM][MAXM] = {0};\nbool adj_target[MAXM][MAXM] = {false};\nint n, m;\n\n// BFS to check if all 0-cells are connected to the boundary (and thus to the outside)\nbool is_zero_connected() {\n    int zero_cnt = 0;\n    for (int i = 0; i <= n + 1; ++i)\n        for (int j = 0; j <= n + 1; ++j)\n            if (grid[i][j] == 0) zero_cnt++;\n    if (zero_cnt == 0) return true;\n\n    static int q[MAXN * MAXN][2];\n    static bool vis[MAXN][MAXN];\n    int head = 0, tail = 0;\n    memset(vis, 0, sizeof(vis));\n\n    // Start from (0,0), which is always 0 due to padding\n    vis[0][0] = true;\n    q[tail][0] = 0; q[tail][1] = 0; tail++;\n    int cnt = 0;\n    const int dirs[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};\n    \n    while (head < tail) {\n        int r = q[head][0], c = q[head][1]; head++; cnt++;\n        for (auto& d : dirs) {\n            int nr = r + d[0], nc = c + d[1];\n            if (nr >= 0 && nr <= n + 1 && nc >= 0 && nc <= n + 1 && \n                grid[nr][nc] == 0 && !vis[nr][nc]) {\n                vis[nr][nc] = true;\n                q[tail][0] = nr; q[tail][1] = nc; tail++;\n            }\n        }\n    }\n    return cnt == zero_cnt;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> n >> m;\n    memset(grid, 0, sizeof(grid)); // Initialize border with 0\n    for (int i = 1; i <= n; ++i)\n        for (int j = 1; j <= n; ++j)\n            cin >> grid[i][j];\n\n    const int dirs[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};\n    \n    // Compute initial adjacency targets and contact counts on padded grid\n    for (int i = 0; i <= n + 1; ++i) {\n        for (int j = 0; j <= n + 1; ++j) {\n            for (int k = 0; k < 2; ++k) { // Check right and down to avoid double counting\n                int ni = i + (k == 1), nj = j + (k == 0);\n                if (ni <= n + 1 && nj <= n + 1) {\n                    int u = grid[i][j], v = grid[ni][nj];\n                    if (u != v) {\n                        if (u > v) swap(u, v);\n                        contacts[u][v]++;\n                        adj_target[u][v] = adj_target[v][u] = true;\n                    }\n                }\n            }\n        }\n    }\n\n    vector<pair<int, int>> zeros;\n    for (int i = 1; i <= n; ++i)\n        for (int j = 1; j <= n; ++j)\n            if (grid[i][j] == 0) zeros.emplace_back(i, j);\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    auto start_time = chrono::steady_clock::now();\n\n    for (int iter = 0; iter < 20; ++iter) {\n        // Time guard\n        if (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() > 1850) break;\n        \n        shuffle(zeros.begin(), zeros.end(), rng);\n        bool changed = false;\n\n        for (auto& [r, c] : zeros) {\n            if (grid[r][c] != 0) continue;\n\n            int zero_nb = 0;\n            for (auto& d : dirs) {\n                if (grid[r + d[0]][c + d[1]] == 0) zero_nb++;\n            }\n\n            // Collect unique neighboring colors\n            vector<int> cands;\n            for (auto& d : dirs) {\n                int x = grid[r + d[0]][c + d[1]];\n                if (x != 0) {\n                    if (find(cands.begin(), cands.end(), x) == cands.end())\n                        cands.push_back(x);\n                }\n            }\n            if (cands.empty()) continue;\n\n            for (int col : cands) {\n                // 1. Check forbidden adjacencies\n                bool bad = false;\n                for (auto& d : dirs) {\n                    int x = grid[r + d[0]][c + d[1]];\n                    if (x != 0 && x != col && !adj_target[col][x]) {\n                        bad = true; break;\n                    }\n                }\n                if (bad) continue;\n\n                // 2. Tentatively update contact counts\n                vector<pair<int, int>> dec_c, inc_c;\n                for (auto& d : dirs) {\n                    int x = grid[r + d[0]][c + d[1]];\n                    if (x == 0) continue;\n                    dec_c.emplace_back(min(0, x), max(0, x));\n                    inc_c.emplace_back(min(col, x), max(col, x));\n                }\n\n                bool dropped_req = false;\n                for (auto& p : dec_c) {\n                    if (--contacts[p.first][p.second] == 0 && adj_target[p.first][p.second]) {\n                        dropped_req = true;\n                    }\n                    if (dropped_req) break;\n                }\n                if (dropped_req) {\n                    for (auto& p : dec_c) contacts[p.first][p.second]++;\n                    continue;\n                }\n                for (auto& p : inc_c) contacts[p.first][p.second]++;\n\n                // 3. Check 0-connectivity (skip if safe by graph property)\n                bool conn_ok = true;\n                if (zero_nb > 1) {\n                    grid[r][c] = col;\n                    conn_ok = is_zero_connected();\n                    grid[r][c] = 0;\n                }\n\n                if (conn_ok) {\n                    grid[r][c] = col; // Commit change\n                    changed = true;\n                } else {\n                    // Revert contacts\n                    for (auto& p : inc_c) contacts[p.first][p.second]--;\n                    for (auto& p : dec_c) contacts[p.first][p.second]++;\n                }\n            }\n        }\n\n        // Update zeros list for next iteration\n        zeros.clear();\n        for (int i = 1; i <= n; ++i)\n            for (int j = 1; j <= n; ++j)\n                if (grid[i][j] == 0) zeros.emplace_back(i, j);\n                \n        if (!changed) break; // Local optimum reached\n    }\n\n    // Output result\n    for (int i = 1; i <= n; ++i) {\n        for (int j = 1; j <= n; ++j) {\n            cout << grid[i][j] << (j == n ? \"\\n\" : \" \");\n        }\n    }\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <string>\n\nusing namespace std;\n\nint main() {\n    // Optimize I/O operations\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, D, Q;\n    if (!(cin >> N >> D >> Q)) return 0;\n\n    // Current permutation of items, initially [0, 1, ..., N-1]\n    vector<int> p(N);\n    iota(p.begin(), p.end(), 0);\n    \n    // Score array to estimate relative weights\n    vector<double> score(N, 0.0);\n\n    // Perform exactly Q comparisons using a sorting-network-like pass\n    while (Q > 0) {\n        for (int i = 0; i < N - 1 && Q > 0; ++i) {\n            // Query: compare p[i] and p[i+1]\n            cout << \"1 1 \" << p[i] << \" \" << p[i+1] << \"\\n\";\n            cout.flush();\n            \n            string res;\n            cin >> res;\n            Q--;\n\n            // If left is lighter, swap to maintain descending order of estimated weight\n            if (res == \"<\") {\n                swap(p[i], p[i+1]);\n            }\n            \n            // Update scores: heavier gets +1, lighter gets -1\n            // After potential swap, p[i] is always the heavier (or equal) one\n            score[p[i]] += 1.0;\n            score[p[i+1]] -= 1.0;\n        }\n    }\n\n    // Sort items by their accumulated score (descending)\n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n    sort(items.begin(), items.end(), [&](int a, int b) {\n        return score[a] > score[b];\n    });\n\n    // Greedy partition into D sets\n    // bin_weight tracks the current total weight proxy of each bin\n    vector<double> bin_weight(D, 0.0);\n    vector<int> ans(N);\n    \n    for (int item : items) {\n        int best_d = 0;\n        double min_w = bin_weight[0];\n        for (int d = 1; d < D; ++d) {\n            if (bin_weight[d] < min_w) {\n                min_w = bin_weight[d];\n                best_d = d;\n            }\n        }\n        ans[item] = best_d;\n        bin_weight[best_d] += 1.0; // Proxy weight; order matters more than exact value\n    }\n\n    // Output the final assignment\n    for (int i = 0; i < N; ++i) {\n        cout << ans[i] << (i == N - 1 ? \"\" : \" \");\n    }\n    cout << \"\\n\";\n    cout.flush();\n\n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\nstruct State {\n    int n, m;\n    vector<vector<int>> stacks;\n    vector<pair<int, int>> pos; // box -> {stack_idx, index}\n    vector<int> ops_v, ops_i;\n    long long energy = 0;\n    int op_count = 0;\n\n    void init(int n, int m, const vector<vector<int>>& input_stacks) {\n        this->n = n;\n        this->m = m;\n        stacks = input_stacks;\n        pos.assign(n + 1, {-1, -1});\n        for (int i = 0; i < m; ++i) {\n            for (int j = 0; j < (int)stacks[i].size(); ++j) {\n                pos[stacks[i][j]] = {i, j};\n            }\n        }\n    }\n\n    void move_box(int box, int dest_stack) {\n        auto [src_stack, idx] = pos[box];\n        int cur_size = (int)stacks[src_stack].size();\n        if (idx < 0 || idx >= cur_size) return; // Safety guard\n\n        int chunk_size = cur_size - idx;\n        energy += chunk_size + 1;\n        op_count++;\n        ops_v.push_back(box);\n        ops_i.push_back(dest_stack + 1);\n\n        vector<int> chunk;\n        chunk.reserve(chunk_size);\n        for (int k = idx; k < cur_size; ++k) {\n            chunk.push_back(stacks[src_stack][k]);\n        }\n\n        for (int b : chunk) {\n            pos[b] = {dest_stack, (int)stacks[dest_stack].size()};\n            stacks[dest_stack].push_back(b);\n        }\n\n        stacks[src_stack].resize(idx);\n    }\n\n    void remove_box(int box) {\n        op_count++;\n        ops_v.push_back(box);\n        ops_i.push_back(0);\n        auto [src, idx] = pos[box];\n        stacks[src].pop_back();\n        pos[box] = {-1, -1}; \n    }\n\n    int get_top(int s) const {\n        if (stacks[s].empty()) return n + 1;\n        return stacks[s].back();\n    }\n};\n\nint find_dest(const State& state, int u, int src, int next_target) {\n    int best_dest = -1;\n    int best_score = -2000000000;\n\n    for (int i = 0; i < state.m; ++i) {\n        if (i == src) continue;\n        int top_val = state.get_top(i);\n        int score = 0;\n        bool is_good = (top_val > u);\n        bool covers_next = (top_val == next_target);\n\n        if (is_good) score += 1000000;\n        if (!covers_next) score += 10000;\n        if (is_good) {\n            score -= top_val; // Prefer smaller top to keep larger tops available for larger boxes\n        } else {\n            score += top_val; // Prefer larger top to cover less critical numbers\n        }\n\n        if (best_dest == -1 || score > best_score) {\n            best_dest = i;\n            best_score = score;\n        }\n    }\n    return best_dest;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; ++i) {\n        for (int j = 0; j < n / m; ++j) {\n            int x; cin >> x;\n            stacks[i].push_back(x);\n        }\n    }\n\n    State S;\n    S.init(n, m, stacks);\n\n    for (int v = 1; v <= n; ++v) {\n        while (true) {\n            auto [src, idx] = S.pos[v];\n            if (src == -1) break;\n            if (idx == (int)S.stacks[src].size() - 1) {\n                S.remove_box(v);\n                break;\n            } else {\n                int u = S.stacks[src][idx + 1];\n                int dest = find_dest(S, u, src, v + 1);\n                S.move_box(u, dest);\n            }\n        }\n    }\n\n    for (int k = 0; k < S.op_count; ++k) {\n        cout << S.ops_v[k] << \" \" << S.ops_i[k] << \"\\n\";\n    }\n\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\nvector<vector<int>> children;\nvector<bool> vis;\nvector<int> c, extra;\nstring res;\n\n// Check if move from (i,j) to (ni,nj) is valid (no wall)\nbool can_move(int i, int j, int ni, int nj) {\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    if (ni == i + 1 && nj == j) return h[i][j] == '0';\n    if (ni == i - 1 && nj == j) return h[ni][j] == '0';\n    if (ni == i && nj == j + 1) return v[i][j] == '0';\n    if (ni == i && nj == j - 1) return v[i][nj] == '0';\n    return false;\n}\n\n// Get move character\nchar get_dir(int r1, int c1, int r2, int c2) {\n    if (r1 < r2) return 'D';\n    if (r1 > r2) return 'U';\n    if (c1 < c2) return 'R';\n    if (c1 > c2) return 'L';\n    return 0;\n}\n\n// Build DFS spanning tree\nvoid build_tree(int u) {\n    vis[u] = true;\n    int ui = u / N, uj = u % N;\n    int dirs[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n    for (auto& dir : dirs) {\n        int ni = ui + dir[0], nj = uj + dir[1];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n            if (can_move(ui, uj, ni, nj)) {\n                int nxt = ni * N + nj;\n                if (!vis[nxt]) {\n                    children[u].push_back(nxt);\n                    build_tree(nxt);\n                }\n            }\n        }\n    }\n}\n\n// Generate route with extra loops\nvoid gen_route(int u, int p) {\n    for (int vtx : children[u]) {\n        int ui = u / N, uj = u % N;\n        int vi = vtx / N, vj = vtx % N;\n        char to_v = get_dir(ui, uj, vi, vj);\n        char to_u = get_dir(vi, vj, ui, uj);\n        // Insert extra out-and-back loops to child\n        for (int k = 0; k < extra[vtx]; ++k) {\n            res += to_v;\n            res += to_u;\n        }\n        // Normal traversal to child\n        res += to_v;\n        gen_route(vtx, u);\n        // Return to parent\n        res += to_u;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    h.resize(N-1);\n    for (int i = 0; i < N-1; ++i) cin >> h[i];\n    v.resize(N);\n    for (int i = 0; i < N; ++i) cin >> v[i];\n    d.assign(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> d[i][j];\n\n    // 1. Build Spanning Tree\n    children.assign(N*N, vector<int>());\n    vis.assign(N*N, false);\n    build_tree(0);\n\n    // 2. Compute base visit counts\n    // In DFS traversal, each node is visited deg_tree(node) times as a destination.\n    c.assign(N*N, 0);\n    for (int u = 0; u < N*N; ++u) {\n        c[u] = children[u].size();\n        if (u != 0) c[u] += 1; // +1 from parent edge\n    }\n\n    // 3. Greedily allocate extra visits\n    priority_queue<pair<double, int>> pq;\n    int L = 2 * (N*N - 1);\n    for (int u = 1; u < N*N; ++u) { // Skip root, its visit count is naturally high\n        double gain = (double)d[u/N][u%N] / (c[u] * (c[u] + 1.0));\n        pq.push({gain, u});\n    }\n\n    extra.assign(N*N, 0);\n    while (L + 2 <= 99000) {\n        auto top = pq.top(); pq.pop();\n        int u = top.second;\n        c[u]++;\n        extra[u]++;\n        L += 2;\n        double new_gain = (double)d[u/N][u%N] / (c[u] * (c[u] + 1.0));\n        pq.push({new_gain, u});\n    }\n\n    // 4. Construct final route\n    res.reserve(100005);\n    gen_route(0, -1);\n\n    cout << res << \"\\n\";\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\n#pragma GCC optimize(\"O3,unroll-loops\")\n\nstruct Point {\n    int r, c;\n    int dist(const Point& o) const {\n        return abs(r - o.r) + abs(c - o.c);\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n    int sr, sc;\n    cin >> sr >> sc;\n\n    vector<string> A(N);\n    for (int i = 0; i < N; i++) cin >> A[i];\n\n    vector<string> T(M);\n    for (int i = 0; i < M; i++) cin >> T[i];\n\n    // Precompute positions of each character in the grid\n    vector<vector<Point>> pos(26);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            pos[A[i][j] - 'A'].push_back({i, j});\n        }\n    }\n\n    // Precompute position lists for each target string to avoid repeated lookups\n    vector<vector<vector<Point>>> T_pos(M, vector<vector<Point>>(5));\n    for (int i = 0; i < M; i++) {\n        for (int l = 0; l < 5; l++) {\n            T_pos[i][l] = pos[T[i][l] - 'A'];\n        }\n    }\n\n    vector<bool> covered(M, false);\n    int covered_cnt = 0;\n    Point cur = {sr, sc};\n    vector<Point> ans;\n    ans.reserve(M * 5);\n\n    string S;\n    S.reserve(M * 5);\n\n    // Efficiently check which strings are covered by the newly appended characters\n    auto check_coverage = [&]() {\n        int nS = S.size();\n        if (nS < 5) return;\n        // Any new match of length 5 must end at or after index nS-5\n        // It could start as early as nS-9, so we check that window.\n        int start_check = max(0, nS - 9);\n        int end_check = nS - 5;\n\n        for (int i = 0; i < M; i++) {\n            if (!covered[i]) {\n                bool found = false;\n                for (int s = start_check; s <= end_check; s++) {\n                    bool match = true;\n                    for (int k = 0; k < 5; k++) {\n                        if (S[s + k] != T[i][k]) {\n                            match = false;\n                            break;\n                        }\n                    }\n                    if (match) {\n                        found = true;\n                        break;\n                    }\n                }\n                if (found) {\n                    covered[i] = true;\n                    covered_cnt++;\n                }\n            }\n        }\n    };\n\n    while (covered_cnt < M) {\n        int best_k = -1;\n        int best_cost = INT_MAX;\n        vector<Point> best_path;\n\n        for (int i = 0; i < M; i++) {\n            if (covered[i]) continue;\n\n            // Layered DP to find min-cost path for T[i] from current position\n            const int L = 5;\n            vector<vector<int>> dp(L);\n            vector<vector<int>> pred(L);\n\n            for (int l = 0; l < L; l++) {\n                int sz = T_pos[i][l].size();\n                dp[l].assign(sz, INT_MAX);\n                pred[l].assign(sz, -1);\n            }\n\n            // Base case: first character\n            for (int u = 0; u < T_pos[i][0].size(); u++) {\n                dp[0][u] = cur.dist(T_pos[i][0][u]) + 1;\n            }\n\n            // Transition through characters 2..5\n            for (int l = 1; l < L; l++) {\n                for (int u = 0; u < T_pos[i][l].size(); u++) {\n                    int best_prev_cost = INT_MAX;\n                    int best_v = -1;\n                    for (int v = 0; v < T_pos[i][l-1].size(); v++) {\n                        if (dp[l-1][v] == INT_MAX) continue;\n                        int cost = dp[l-1][v] + T_pos[i][l-1][v].dist(T_pos[i][l][u]) + 1;\n                        if (cost < best_prev_cost) {\n                            best_prev_cost = cost;\n                            best_v = v;\n                        }\n                    }\n                    dp[l][u] = best_prev_cost;\n                    pred[l][u] = best_v;\n                }\n            }\n\n            // Find minimum cost in the final layer\n            int min_cost = INT_MAX;\n            int best_u = -1;\n            for (int u = 0; u < T_pos[i][4].size(); u++) {\n                if (dp[4][u] < min_cost) {\n                    min_cost = dp[4][u];\n                    best_u = u;\n                }\n            }\n\n            if (min_cost < best_cost) {\n                best_cost = min_cost;\n                best_k = i;\n                best_path.resize(5);\n                int u = best_u;\n                for (int l = 4; l >= 0; l--) {\n                    best_path[l] = T_pos[i][l][u];\n                    if (l > 0) u = pred[l][u];\n                }\n            }\n        }\n\n        if (best_k == -1) break; // Should not happen given problem constraints\n\n        // Execute the chosen path\n        for (const auto& p : best_path) {\n            ans.push_back(p);\n            S += A[p.r][p.c];\n            cur = p;\n        }\n\n        check_coverage();\n    }\n\n    // Output result\n    for (const auto& p : ans) {\n        cout << p.r << \" \" << p.c << \"\\n\";\n    }\n\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Shape {\n    vector<pair<int, int>> cells;\n};\n\nint N, M;\ndouble eps;\nvector<Shape> shapes;\nint max_r[20], max_c[20];\n\nstruct Observation {\n    int r, c, v;\n};\nvector<Observation> obs;\n\nint grid[20][20];\npair<int, int> pos[20];\n\n// Compute squared error between model and observations\nint compute_cost() {\n    int c = 0;\n    for (const auto& o : obs) {\n        int d = grid[o.r][o.c] - o.v;\n        c += d * d;\n    }\n    return c;\n}\n\n// Add/remove polyomino k from grid at offset (dr, dc)\nvoid apply_shape(int k, int dr, int dc, int sign) {\n    for (const auto& cell : shapes[k].cells) {\n        grid[cell.first + dr][cell.second + dc] += sign;\n    }\n}\n\nmt19937 rng;\nint rand_int(int l, int r) {\n    return uniform_int_distribution<int>(l, r)(rng);\n}\n\n// Simulated Annealing to find polyomino placements matching observations\nvoid run_sa(const vector<pair<int,int>>& init_pos) {\n    for (int k = 0; k < M; k++) {\n        if (!init_pos.empty()) {\n            pos[k] = init_pos[k];\n        } else {\n            pos[k] = {rand_int(0, N - 1 - max_r[k]), rand_int(0, N - 1 - max_c[k])};\n        }\n    }\n    memset(grid, 0, sizeof(grid));\n    for (int k = 0; k < M; k++) apply_shape(k, pos[k].first, pos[k].second, 1);\n    \n    int current_cost = compute_cost();\n    int best_cost = current_cost;\n    pair<int, int> best_pos_arr[20];\n    memcpy(best_pos_arr, pos, sizeof(pos));\n    \n    double T = 300.0;\n    int iterations = 40000;\n    uniform_real_distribution<double> dis(0, 1);\n    for (int iter = 0; iter < iterations; iter++) {\n        int k = rand_int(0, M - 1);\n        int dr = rand_int(-1, 1);\n        int dc = rand_int(-1, 1);\n        if (dr == 0 && dc == 0) continue;\n        \n        int nr = pos[k].first + dr;\n        int nc = pos[k].second + dc;\n        if (nr < 0 || nr > N - 1 - max_r[k] || nc < 0 || nc > N - 1 - max_c[k]) continue;\n        \n        int old_r = pos[k].first;\n        int old_c = pos[k].second;\n        \n        // Apply move\n        apply_shape(k, old_r, old_c, -1);\n        pos[k] = {nr, nc};\n        apply_shape(k, nr, nc, 1);\n        \n        int new_cost = compute_cost();\n        \n        // Metropolis criterion\n        double prob = exp(-(new_cost - current_cost) / T);\n        if (new_cost < current_cost || dis(rng) < prob) {\n            current_cost = new_cost;\n            if (current_cost < best_cost) {\n                best_cost = current_cost;\n                memcpy(best_pos_arr, pos, sizeof(pos));\n            }\n        } else {\n            // Revert move\n            apply_shape(k, nr, nc, -1);\n            pos[k] = {old_r, old_c};\n            apply_shape(k, old_r, old_c, 1);\n        }\n        T *= 0.9999; // Cool down\n    }\n    memcpy(pos, best_pos_arr, sizeof(pos));\n    // Rebuild grid for best configuration\n    memset(grid, 0, sizeof(grid));\n    for (int k = 0; k < M; k++) apply_shape(k, pos[k].first, pos[k].second, 1);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    rng.seed(chrono::steady_clock::now().time_since_epoch().count());\n    \n    cin >> N >> M >> eps;\n    shapes.resize(M);\n    for (int k = 0; k < M; k++) {\n        int d; cin >> d;\n        for (int l = 0; l < d; l++) {\n            int r, c; cin >> r >> c;\n            shapes[k].cells.push_back({r, c});\n            max_r[k] = max(max_r[k], r);\n            max_c[k] = max(max_c[k], c);\n        }\n    }\n    \n    memset(grid, 0, sizeof(grid));\n    bool is_drilled[20][20] = {};\n    int op_count = 0;\n    int limit = 2 * N * N;\n    \n    auto drill = [&](int r, int c) {\n        cout << \"q 1 \" << r << \" \" << c << \"\\n\";\n        cout.flush();\n        int v; cin >> v;\n        obs.push_back({r, c, v});\n        op_count++;\n        return v;\n    };\n    \n    auto guess = [&](const vector<pair<int,int>>& union_cells) {\n        cout << \"a \" << union_cells.size();\n        for (const auto& p : union_cells) cout << \" \" << p.first << \" \" << p.second;\n        cout << \"\\n\";\n        cout.flush();\n        op_count++;\n        int res; cin >> res;\n        return res == 1;\n    };\n\n    // Phase 1: Initial random drilling\n    int init_drills = min(25, N*N);\n    for (int i = 0; i < init_drills; i++) {\n        int r = rand_int(0, N-1);\n        int c = rand_int(0, N-1);\n        if (!is_drilled[r][c]) {\n            is_drilled[r][c] = true;\n            drill(r, c);\n        } else { i--; }\n    }\n    \n    vector<pair<int,int>> current_best_pos(M);\n    auto start_time = chrono::steady_clock::now();\n\n    // Phase 2: SA + Adaptive Drilling Loop\n    while (op_count < limit - 5) {\n        if (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() > 2600) break;\n        \n        run_sa(current_best_pos);\n        for(int k=0; k<M; k++) current_best_pos[k] = pos[k];\n        \n        // Compute union\n        vector<pair<int,int>> union_cells;\n        bool seen[20][20] = {};\n        for (int k = 0; k < M; k++) {\n            for (const auto& cell : shapes[k].cells) {\n                int r = cell.first + pos[k].first;\n                int c = cell.second + pos[k].second;\n                if (!seen[r][c]) {\n                    seen[r][c] = true;\n                    union_cells.push_back({r, c});\n                }\n            }\n        }\n        \n        if (guess(union_cells)) return 0;\n        \n        // Phase 3: Drill informative cells where model predicts 0\n        int drills_needed = 4;\n        vector<pair<int,int>> to_drill;\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                if (grid[r][c] == 0 && !is_drilled[r][c]) {\n                    to_drill.push_back({r, c});\n                }\n            }\n        }\n        // Fallback to any undrilled cell if needed\n        if ((int)to_drill.size() < drills_needed) {\n            for (int r = 0; r < N; r++) {\n                for (int c = 0; c < N; c++) {\n                    if (!is_drilled[r][c]) to_drill.push_back({r, c});\n                }\n            }\n        }\n        shuffle(to_drill.begin(), to_drill.end(), rng);\n        \n        for (int i = 0; i < drills_needed && i < (int)to_drill.size(); i++) {\n            auto p = to_drill[i];\n            is_drilled[p.first][p.second] = true;\n            drill(p.first, p.second);\n        }\n    }\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\n#include <chrono>\n#include <random>\nusing namespace std;\n\n// Problem constants\nconst int W = 1000;\nconst int MAX_D = 55;\nconst int MAX_N = 55;\n\n// Global state\nint D, N;\nlong long A[MAX_D][MAX_N];\n\nstruct Rect {\n    int x1, y1, x2, y2;\n};\n\nRect rects[MAX_D][MAX_N];\nRect best_rects[MAX_D][MAX_N];\n\n// Partition grids: H[d][y][x] for horizontal segments at row y, between x and x+1\n// V[d][y][x] for vertical segments at col x, between y and y+1\n// We use char for cache efficiency and speed. Padding to avoid bounds checks.\nchar H[MAX_D][W+5][W+5];\nchar V[MAX_D][W+5][W+5];\n\nlong long L[MAX_D]; // L[d] stores partition change cost between d-1 and d\nlong long area_pen[MAX_D][MAX_N];\nlong long total_cost = 0;\nlong long best_cost = 1LL << 60;\n\nmt19937 rng(42);\nuniform_int_distribution<int> dist_int(0, 1000000);\nuniform_real_distribution<double> dist_real(0.0, 1.0);\n\nint rand_int(int l, int r) {\n    return l + dist_int(rng) % (r - l + 1);\n}\ndouble rand_real() {\n    return dist_real(rng);\n}\n\n// Check overlap on day d for reservation k with candidate rect r\nbool overlap(int d, int k, const Rect& r) {\n    for (int i = 0; i < N; ++i) {\n        if (i == k) continue;\n        if (rects[d][i].x1 < r.x2 && rects[d][i].x2 > r.x1 &&\n            rects[d][i].y1 < r.y2 && rects[d][i].y2 > r.y1)\n            return true;\n    }\n    return false;\n}\n\n// Compute area penalty\nlong long calc_area_pen(const Rect& r, long long req) {\n    long long area = 1LL * (r.x2 - r.x1) * (r.y2 - r.y1);\n    return max(0LL, 100LL * (req - area));\n}\n\n// Update total cost when flipping a single partition segment\n// Returns delta to total_cost\nlong long flip_segment(int d, bool is_H, int y, int x, char new_val, bool apply = true) {\n    if (d == 0) return 0; // L_0 is always 0, no change affects it\n    char* grid = is_H ? &H[d][y][x] : &V[d][y][x];\n    char old_val = *grid;\n    if (old_val == new_val) return 0;\n\n    long long delta = 0;\n    // Contribution to L[d]: compares with day d-1\n    char prev = is_H ? H[d-1][y][x] : V[d-1][y][x];\n    if ((prev != old_val) && (prev == new_val)) delta -= 1;\n    else if ((prev == old_val) && (prev != new_val)) delta += 1;\n\n    // Contribution to L[d+1]: compares with day d+1\n    if (d < D - 1) {\n        char next = is_H ? H[d+1][y][x] : V[d+1][y][x];\n        if ((next != old_val) && (next == new_val)) delta -= 1;\n        else if ((next == old_val) && (next != new_val)) delta += 1;\n    }\n\n    if (apply) {\n        *grid = new_val;\n        total_cost += delta;\n        if (d > 0) L[d] += delta; // Note: L array not strictly needed if we track total_cost, but kept for debug/sanity\n    }\n    return delta;\n}\n\n// Apply or revert rectangle on day d\n// sign = 1 to add, -1 to remove\nvoid apply_rect(int d, int k, const Rect& r, int sign) {\n    // Horizontal edges\n    for (int x = r.x1; x < r.x2; ++x) {\n        if (r.y1 >= 1 && r.y1 <= W - 1) flip_segment(d, true, r.y1, x, sign == 1, true);\n        if (r.y2 >= 1 && r.y2 <= W - 1) flip_segment(d, true, r.y2, x, sign == 1, true);\n    }\n    // Vertical edges\n    for (int y = r.y1; y < r.y2; ++y) {\n        if (r.x1 >= 1 && r.x1 <= W - 1) flip_segment(d, false, y, r.x1, sign == 1, true);\n        if (r.x2 >= 1 && r.x2 <= W - 1) flip_segment(d, false, y, r.x2, sign == 1, true);\n    }\n    rects[d][k] = r;\n}\n\n// Compute delta cost for a proposed change without modifying state\nlong long simulate_change(int d, int k, const Rect& old_r, const Rect& new_r) {\n    long long delta = 0;\n    // Remove old\n    delta -= calc_area_pen(old_r, A[d][k]);\n    for (int x = old_r.x1; x < old_r.x2; ++x) {\n        if (old_r.y1 >= 1 && old_r.y1 <= W - 1) delta += flip_segment(d, true, old_r.y1, x, 0, false);\n        if (old_r.y2 >= 1 && old_r.y2 <= W - 1) delta += flip_segment(d, true, old_r.y2, x, 0, false);\n    }\n    for (int y = old_r.y1; y < old_r.y2; ++y) {\n        if (old_r.x1 >= 1 && old_r.x1 <= W - 1) delta += flip_segment(d, false, y, old_r.x1, 0, false);\n        if (old_r.x2 >= 1 && old_r.x2 <= W - 1) delta += flip_segment(d, false, y, old_r.x2, 0, false);\n    }\n\n    // Add new\n    delta += calc_area_pen(new_r, A[d][k]);\n    for (int x = new_r.x1; x < new_r.x2; ++x) {\n        if (new_r.y1 >= 1 && new_r.y1 <= W - 1) delta += flip_segment(d, true, new_r.y1, x, 1, false);\n        if (new_r.y2 >= 1 && new_r.y2 <= W - 1) delta += flip_segment(d, true, new_r.y2, x, 1, false);\n    }\n    for (int y = new_r.y1; y < new_r.y2; ++y) {\n        if (new_r.x1 >= 1 && new_r.x1 <= W - 1) delta += flip_segment(d, false, y, new_r.x1, 1, false);\n        if (new_r.x2 >= 1 && new_r.x2 <= W - 1) delta += flip_segment(d, false, y, new_r.x2, 1, false);\n    }\n    return delta;\n}\n\n// Initial packing: simple shelf algorithm\nvoid pack_initial() {\n    for (int d = 0; d < D; ++d) {\n        int cx = 0, cy = 0, rh = 0;\n        for (int k = 0; k < N; ++k) {\n            long long area = A[d][k];\n            int w = min(W, max(1, (int)ceil(sqrt(area))));\n            int h = max(1, (int)((area + w - 1) / w));\n            if (cx + w > W) {\n                cy += rh;\n                rh = 0;\n                cx = 0;\n                w = min(W, max(1, (int)ceil(sqrt(area))));\n                h = max(1, (int)((area + w - 1) / w));\n            }\n            rects[d][k] = {cx, cy, cx + w, cy + h};\n            cx += w;\n            rh = max(rh, h);\n        }\n    }\n\n    // Build grids and compute costs\n    total_cost = 0;\n    memset(H, 0, sizeof(H));\n    memset(V, 0, sizeof(V));\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            area_pen[d][k] = calc_area_pen(rects[d][k], A[d][k]);\n            total_cost += area_pen[d][k];\n            // Add to grids\n            for (int x = rects[d][k].x1; x < rects[d][k].x2; ++x) {\n                if (rects[d][k].y1 >= 1 && rects[d][k].y1 <= W - 1) H[d][rects[d][k].y1][x] = 1;\n                if (rects[d][k].y2 >= 1 && rects[d][k].y2 <= W - 1) H[d][rects[d][k].y2][x] = 1;\n            }\n            for (int y = rects[d][k].y1; y < rects[d][k].y2; ++y) {\n                if (rects[d][k].x1 >= 1 && rects[d][k].x1 <= W - 1) V[d][y][rects[d][k].x1] = 1;\n                if (rects[d][k].x2 >= 1 && rects[d][k].x2 <= W - 1) V[d][y][rects[d][k].x2] = 1;\n            }\n        }\n    }\n    // Compute L[d]\n    for (int d = 1; d < D; ++d) {\n        for (int y = 1; y < W; ++y) {\n            for (int x = 0; x < W; ++x) {\n                if (H[d][y][x] != H[d-1][y][x]) total_cost++;\n            }\n            for (int x = 1; x < W; ++x) {\n                if (V[d][y-1][x] != V[d-1][y-1][x]) total_cost++;\n            }\n        }\n        // Last row for V\n        for (int x = 1; x < W; ++x) {\n            if (V[d][W-1][x] != V[d-1][W-1][x]) total_cost++;\n        }\n    }\n}\n\nvoid solve() {\n    pack_initial();\n    if (total_cost < best_cost) {\n        best_cost = total_cost;\n        memcpy(best_rects, rects, sizeof(rects));\n    }\n\n    auto start = chrono::high_resolution_clock::now();\n    double temp = 5000.0;\n    const double COOLING = 0.99995;\n    int moves = 0;\n\n    while (chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start).count() < 2800) {\n        int d = rand_int(0, D - 1);\n        int k = rand_int(0, N - 1);\n        Rect old_r = rects[d][k];\n\n        // Perturb\n        int dx = rand_int(-4, 4);\n        int dy = rand_int(-4, 4);\n        int dw = rand_int(-3, 3);\n        int dh = rand_int(-3, 3);\n\n        Rect new_r;\n        new_r.x1 = max(0, min(W, old_r.x1 + dx));\n        new_r.y1 = max(0, min(W, old_r.y1 + dy));\n        new_r.x2 = max(new_r.x1 + 1, min(W, old_r.x2 + dw));\n        new_r.y2 = max(new_r.y1 + 1, min(W, old_r.y2 + dh));\n\n        // Enforce area constraint\n        long long cur_area = 1LL * (new_r.x2 - new_r.x1) * (new_r.y2 - new_r.y1);\n        if (cur_area < A[d][k]) {\n            long long needed = A[d][k];\n            // Try to expand width first, then height\n            int add_w = max(0, (int)((needed + new_r.y2 - new_r.y1 - 1) / (new_r.y2 - new_r.y1)) - (new_r.x2 - new_r.x1));\n            if (new_r.x2 + add_w <= W) new_r.x2 += add_w;\n            else {\n                int add_h = max(0, (int)((needed + new_r.x2 - new_r.x1 - 1) / (new_r.x2 - new_r.x1)) - (new_r.y2 - new_r.y1));\n                if (new_r.y2 + add_h <= W) new_r.y2 += add_h;\n                else continue; // Cannot fit\n            }\n        }\n\n        if (overlap(d, k, new_r)) continue;\n\n        long long delta = simulate_change(d, k, old_r, new_r);\n        \n        if (delta < 0 || rand_real() < exp(-delta / temp)) {\n            apply_rect(d, k, new_r, 1); // Apply new\n            area_pen[d][k] = calc_area_pen(new_r, A[d][k]);\n            total_cost += delta; // delta already includes area penalty change\n            \n            // Revert old state in grids manually to keep consistency (simulate_change didn't apply)\n            // Actually, apply_rect adds new, but we need to remove old first.\n            // Let's fix the logic: apply_rect assumes grid has old state, flips to new_val.\n            // But simulate_change didn't modify grid. So we must remove old, add new.\n            // I'll rewrite apply to be atomic:\n            // Remove old\n            for (int x = old_r.x1; x < old_r.x2; ++x) {\n                if (old_r.y1 >= 1 && old_r.y1 <= W - 1) flip_segment(d, true, old_r.y1, x, 0, true);\n                if (old_r.y2 >= 1 && old_r.y2 <= W - 1) flip_segment(d, true, old_r.y2, x, 0, true);\n            }\n            for (int y = old_r.y1; y < old_r.y2; ++y) {\n                if (old_r.x1 >= 1 && old_r.x1 <= W - 1) flip_segment(d, false, y, old_r.x1, 0, true);\n                if (old_r.x2 >= 1 && old_r.x2 <= W - 1) flip_segment(d, false, y, old_r.x2, 0, true);\n            }\n            // Add new\n            for (int x = new_r.x1; x < new_r.x2; ++x) {\n                if (new_r.y1 >= 1 && new_r.y1 <= W - 1) flip_segment(d, true, new_r.y1, x, 1, true);\n                if (new_r.y2 >= 1 && new_r.y2 <= W - 1) flip_segment(d, true, new_r.y2, x, 1, true);\n            }\n            for (int y = new_r.y1; y < new_r.y2; ++y) {\n                if (new_r.x1 >= 1 && new_r.x1 <= W - 1) flip_segment(d, false, y, new_r.x1, 1, true);\n                if (new_r.x2 >= 1 && new_r.x2 <= W - 1) flip_segment(d, false, y, new_r.x2, 1, true);\n            }\n            \n            // Wait, flip_segment already updates total_cost. So I double counted.\n            // Let's simplify: I'll just call a direct apply function that does everything correctly.\n            // Reverting logic below handles this cleanly.\n        } else {\n            // Reject\n        }\n        temp *= COOLING;\n        moves++;\n        if (total_cost < best_cost) {\n            best_cost = total_cost;\n            memcpy(best_rects, rects, sizeof(rects));\n        }\n    }\n}\n\n// Correct atomic apply\nvoid atomic_apply(int d, int k, Rect old_r, Rect new_r) {\n    // Remove old\n    for (int x = old_r.x1; x < old_r.x2; ++x) {\n        if (old_r.y1 >= 1 && old_r.y1 <= W - 1) flip_segment(d, true, old_r.y1, x, 0, true);\n        if (old_r.y2 >= 1 && old_r.y2 <= W - 1) flip_segment(d, true, old_r.y2, x, 0, true);\n    }\n    for (int y = old_r.y1; y < old_r.y2; ++y) {\n        if (old_r.x1 >= 1 && old_r.x1 <= W - 1) flip_segment(d, false, y, old_r.x1, 0, true);\n        if (old_r.x2 >= 1 && old_r.x2 <= W - 1) flip_segment(d, false, y, old_r.x2, 0, true);\n    }\n    // Add new\n    for (int x = new_r.x1; x < new_r.x2; ++x) {\n        if (new_r.y1 >= 1 && new_r.y1 <= W - 1) flip_segment(d, true, new_r.y1, x, 1, true);\n        if (new_r.y2 >= 1 && new_r.y2 <= W - 1) flip_segment(d, true, new_r.y2, x, 1, true);\n    }\n    for (int y = new_r.y1; y < new_r.y2; ++y) {\n        if (new_r.x1 >= 1 && new_r.x1 <= W - 1) flip_segment(d, false, y, new_r.x1, 1, true);\n        if (new_r.x2 >= 1 && new_r.x2 <= W - 1) flip_segment(d, false, y, new_r.x2, 1, true);\n    }\n    rects[d][k] = new_r;\n}\n\n// Re-implement SA loop correctly\nvoid run_sa() {\n    auto start = chrono::high_resolution_clock::now();\n    double temp = 8000.0;\n    const double COOLING = 0.99994;\n\n    while (chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start).count() < 2850) {\n        int d = rand_int(0, D - 1);\n        int k = rand_int(0, N - 1);\n        Rect old_r = rects[d][k];\n\n        int dx = rand_int(-5, 5);\n        int dy = rand_int(-5, 5);\n        int dw = rand_int(-3, 3);\n        int dh = rand_int(-3, 3);\n\n        Rect new_r;\n        new_r.x1 = max(0, min(W, old_r.x1 + dx));\n        new_r.y1 = max(0, min(W, old_r.y1 + dy));\n        new_r.x2 = max(new_r.x1 + 1, min(W, old_r.x2 + dw));\n        new_r.y2 = max(new_r.y1 + 1, min(W, old_r.y2 + dh));\n\n        long long cur_area = 1LL * (new_r.x2 - new_r.x1) * (new_r.y2 - new_r.y1);\n        if (cur_area < A[d][k]) {\n            long long needed = A[d][k];\n            int add_w = max(0, (int)((needed + new_r.y2 - new_r.y1 - 1) / (new_r.y2 - new_r.y1)) - (new_r.x2 - new_r.x1));\n            if (new_r.x2 + add_w <= W) new_r.x2 += add_w;\n            else {\n                int add_h = max(0, (int)((needed + new_r.x2 - new_r.x1 - 1) / (new_r.x2 - new_r.x1)) - (new_r.y2 - new_r.y1));\n                if (new_r.y2 + add_h <= W) new_r.y2 += add_h;\n                else continue;\n            }\n        }\n\n        if (overlap(d, k, new_r)) continue;\n\n        long long delta = simulate_change(d, k, old_r, new_r);\n        if (delta < 0 || rand_real() < exp(-delta / temp)) {\n            long long old_total = total_cost;\n            atomic_apply(d, k, old_r, new_r);\n            area_pen[d][k] = calc_area_pen(new_r, A[d][k]);\n            \n            if (total_cost > old_total + delta) {\n                // Should not happen if simulate is correct, but fallback: revert\n                atomic_apply(d, k, new_r, old_r);\n                area_pen[d][k] = calc_area_pen(old_r, A[d][k]);\n                total_cost = old_total;\n            }\n        }\n\n        temp *= COOLING;\n        if (total_cost < best_cost) {\n            best_cost = total_cost;\n            memcpy(best_rects, rects, sizeof(rects));\n        }\n    }\n}\n\nint main() {\n    ios_base::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)\n        for (int k = 0; k < N; ++k)\n            cin >> A[d][k];\n\n    pack_initial();\n    best_cost = total_cost;\n    memcpy(best_rects, rects, sizeof(rects));\n    \n    run_sa();\n\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            cout << best_rects[d][k].y1 << \" \" << best_rects[d][k].x1 << \" \"\n                 << best_rects[d][k].y2 << \" \" << best_rects[d][k].x2 << \"\\n\";\n        }\n    }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\n#pragma GCC optimize(\"O3,unroll-loops\")\n\nusing namespace std;\nusing ll = long long;\n\nconst ll MOD = 998244353;\n\nint N, M, K;\nll board[9][9];\nll board_mod[9][9];\nll stamps[20][3][3];\n\nstruct Op { int m, p, q; };\nvector<Op> ops;\n\nll current_score = 0;\nll best_score = 0;\nvector<Op> best_ops;\n\n// Fast delta calculation without modifying the board\ninline ll calc_delta(int m, int p, int q) {\n    ll d = 0;\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            ll old_val = board_mod[p + i][q + j];\n            ll new_val = old_val + stamps[m][i][j];\n            if (new_val >= MOD) new_val -= MOD;\n            d += new_val - old_val;\n        }\n    }\n    return d;\n}\n\n// Apply operation: updates board and board_mod\ninline void apply(int m, int p, int q) {\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            board[p + i][q + j] += stamps[m][i][j];\n            board_mod[p + i][q + j] += stamps[m][i][j];\n            if (board_mod[p + i][q + j] >= MOD) board_mod[p + i][q + j] -= MOD;\n        }\n    }\n}\n\n// Revert operation: undoes apply\ninline void revert(int m, int p, int q) {\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            board[p + i][q + j] -= stamps[m][i][j];\n            board_mod[p + i][q + j] -= stamps[m][i][j];\n            if (board_mod[p + i][q + j] < 0) board_mod[p + i][q + j] += MOD;\n        }\n    }\n}\n\n// Compute full score (used for initialization and verification)\nll compute_score() {\n    ll s = 0;\n    for (int i = 0; i < N; ++i) \n        for (int j = 0; j < N; ++j) \n            s += board_mod[i][j];\n    return s;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> K)) return 0;\n    for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) {\n        cin >> board[i][j];\n        board_mod[i][j] = board[i][j] % MOD;\n    }\n    for (int m = 0; m < M; ++m) for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) {\n        cin >> stamps[m][i][j];\n    }\n\n    ops.resize(K);\n    // High-quality RNG\n    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist_m(0, M - 1);\n    uniform_int_distribution<int> dist_pq(0, N - 3);\n    uniform_int_distribution<int> dist_idx(0, K - 1);\n    uniform_real_distribution<double> dist_real(0.0, 1.0);\n\n    // Initialize with random operations\n    for (int i = 0; i < K; ++i) {\n        ops[i] = {dist_m(rng), dist_pq(rng), dist_pq(rng)};\n        apply(ops[i].m, ops[i].p, ops[i].q);\n    }\n    current_score = compute_score();\n    best_score = current_score;\n    best_ops = ops;\n\n    // Simulated Annealing Parameters\n    double T = 1e10;\n    const double T_end = 100;\n    const int MAX_ITER = 7000000;\n    const double decay = pow(T_end / T, 1.0 / MAX_ITER);\n\n    auto start = chrono::steady_clock::now();\n    for (int step = 0; step < MAX_ITER; ++step) {\n        // Soft time limit to ensure safe exit\n        if (step % 200000 == 0 && chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start).count() > 1850) break;\n\n        int idx = dist_idx(rng);\n        int m = dist_m(rng);\n        int p = dist_pq(rng);\n        int q = dist_pq(rng);\n\n        // Temporarily remove old operation\n        revert(ops[idx].m, ops[idx].p, ops[idx].q);\n        ll delta = calc_delta(m, p, q);\n\n        bool accept = false;\n        if (delta > 0) {\n            accept = true;\n        } else {\n            // Metropolis criterion with underflow protection\n            if (delta > -20.0 * T) {\n                double prob = exp(delta / T);\n                if (dist_real(rng) < prob) accept = true;\n            }\n        }\n\n        if (accept) {\n            apply(m, p, q);\n            ops[idx] = {m, p, q};\n            current_score += delta;\n            if (current_score > best_score) {\n                best_score = current_score;\n                best_ops = ops;\n            }\n        } else {\n            // Restore old operation\n            apply(ops[idx].m, ops[idx].p, ops[idx].q);\n        }\n        T *= decay;\n    }\n\n    // Optional: Greedy post-processing to remove clearly detrimental operations\n    for (int i = (int)best_ops.size() - 1; i >= 0; --i) {\n        revert(best_ops[i].m, best_ops[i].p, best_ops[i].q);\n        if (compute_score() < best_score) {\n            apply(best_ops[i].m, best_ops[i].p, best_ops[i].q);\n        } else {\n            best_ops.erase(best_ops.begin() + i);\n        }\n    }\n\n    // Output\n    cout << best_ops.size() << \"\\n\";\n    for (const auto& op : best_ops) {\n        cout << op.m << \" \" << op.p << \" \" << op.q << \"\\n\";\n    }\n\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    if (!(cin >> N)) return 0;\n    int A[5][5];\n    for (int i = 0; i < 5; ++i)\n        for (int j = 0; j < 5; ++j)\n            cin >> A[i][j];\n\n    int grid[5][5];\n    memset(grid, -1, sizeof(grid));\n    \n    pair<int, int> cpos[5];\n    for (int i = 0; i < 5; ++i) cpos[i] = {i, 0};\n    int chold[5];\n    memset(chold, -1, sizeof(chold));\n    \n    int dnext[5];\n    for (int i = 0; i < 5; ++i) dnext[i] = i * 5;\n    int rptr[5] = {0};\n\n    vector<string> S(5, \"\");\n\n    auto is_valid = [](int r, int c) { return r >= 0 && r < 5 && c >= 0 && c < 5; };\n\n    for (int turn = 1; turn <= 10000; ++turn) {\n        // Step 1: Receiving\n        for (int i = 0; i < 5; ++i) {\n            bool crane_here = false;\n            for(int k=0; k<5; ++k) if(cpos[k].first == i && cpos[k].second == 0) crane_here = true;\n            if (!crane_here && grid[i][0] == -1 && rptr[i] < 5) {\n                grid[i][0] = A[i][rptr[i]];\n                rptr[i]++;\n            }\n        }\n\n        char actions[5] = {'.'};\n        pair<int, int> next_cpos[5];\n        copy(begin(cpos), end(cpos), begin(next_cpos));\n\n        auto bfs_step = [&](int k, pair<int, int> start, pair<int, int> target, \n                            bool holding, bool is_large) {\n            queue<pair<int, int>> q;\n            q.push(start);\n            bool vis[5][5] = {}; vis[start.first][start.second] = true;\n            pair<int, int> parent[5][5];\n            for(int i=0;i<5;++i) for(int j=0;j<5;++j) parent[i][j] = {-1, -1};\n            char move_act[5][5] = {};\n            \n            bool found = false;\n            while (!q.empty()) {\n                auto [r, c] = q.front(); q.pop();\n                if (r == target.first && c == target.second) { found = true; break; }\n                int dr[4] = {-1, 1, 0, 0};\n                int dc[4] = {0, 0, -1, 1};\n                const char dirs[4] = {'U', 'D', 'L', 'R'};\n                for (int d = 0; d < 4; ++d) {\n                    int nr = r + dr[d], nc = c + dc[d];\n                    if (!is_valid(nr, nc) || vis[nr][nc]) continue;\n                    \n                    bool blocked = false;\n                    for (int j = 0; j < 5; ++j) if (cpos[j].first == nr && cpos[j].second == nc) { blocked = true; break; }\n                    if (blocked) continue;\n                    if (!is_large && holding && grid[nr][nc] != -1) continue;\n                    \n                    vis[nr][nc] = true;\n                    parent[nr][nc] = {r, c};\n                    move_act[nr][nc] = dirs[d];\n                    q.push({nr, nc});\n                }\n            }\n            \n            if (!found) return make_pair(make_pair(-1, -1), '.');\n            pair<int, int> cur = target;\n            while (parent[cur.first][cur.second] != start) {\n                cur = parent[cur.first][cur.second];\n                if(cur.first == -1) return make_pair(make_pair(-1, -1), '.');\n            }\n            return make_pair(cur, move_act[cur.first][cur.second]);\n        };\n\n        for (int k = 0; k < 5; ++k) {\n            bool is_large = (k == 0);\n            bool holding = (chold[k] != -1);\n            int r = cpos[k].first, c = cpos[k].second;\n            char best_act = '.';\n            int best_nr = r, best_nc = c;\n\n            // Priority 1: Unblock receiving gates if necessary\n            if (c == 0 && !holding && grid[r][c] == -1 && rptr[r] < 5) {\n                best_act = 'R'; best_nr = r; best_nc = 1;\n            } else if (holding) {\n                int cid = chold[k];\n                int tr = cid / 5;\n                bool is_correct = (cid == dnext[tr]);\n                pair<int, int> target = is_correct ? make_pair(tr, 4) : make_pair(tr, 3);\n                if (r == target.first && c == target.second) {\n                    best_act = 'Q';\n                } else {\n                    auto res = bfs_step(k, {r, c}, target, true, is_large);\n                    if (res.first.first != -1) {\n                        best_act = res.second;\n                        best_nr = res.first.first; best_nc = res.first.second;\n                    }\n                }\n            } else {\n                if (grid[r][c] != -1) {\n                    best_act = 'P';\n                } else {\n                    // Find best container to pick up\n                    int best_d = 1e9, best_pri = 2, br = -1, bc = -1;\n                    for (int rr = 0; rr < 5; ++rr) {\n                        for (int cc = 0; cc < 5; ++cc) {\n                            if (grid[rr][cc] == -1) continue;\n                            bool held = false;\n                            for (int j = 0; j < 5; ++j) if (j != k && chold[j] == grid[rr][cc]) { held = true; break; }\n                            if (held) continue;\n                            int cid = grid[rr][cc];\n                            int pri = (cid == dnext[cid/5]) ? 0 : 1;\n                            int d = abs(r - rr) + abs(c - cc);\n                            if (d < best_d || (d == best_d && pri < best_pri)) {\n                                best_d = d; best_pri = pri; br = rr; bc = cc;\n                            }\n                        }\n                    }\n                    if (br != -1) {\n                        auto res = bfs_step(k, {r, c}, {br, bc}, false, is_large);\n                        if (res.first.first != -1) {\n                            best_act = res.second;\n                            best_nr = res.first.first; best_nc = res.first.second;\n                        }\n                    }\n                }\n            }\n\n            // Conflict resolution (Sequential Priority)\n            bool conflict = false;\n            for (int j = 0; j < k; ++j) {\n                if (next_cpos[j].first == best_nr && next_cpos[j].second == best_nc) { conflict = true; break; }\n                if (next_cpos[j].first == r && next_cpos[j].second == c &&\n                    best_nr == cpos[j].first && best_nc == cpos[j].second) { conflict = true; break; }\n            }\n            if (!is_large && holding && best_act != '.' && best_act != 'Q') {\n                if (is_valid(best_nr, best_nc) && grid[best_nr][best_nc] != -1) conflict = true;\n            }\n            if (!is_valid(best_nr, best_nc)) conflict = true;\n\n            if (conflict) { best_act = '.'; best_nr = r; best_nc = c; }\n\n            actions[k] = best_act;\n            next_cpos[k] = {best_nr, best_nc};\n        }\n\n        // Apply moves simultaneously\n        for (int k = 0; k < 5; ++k) if (actions[k] != 'P' && actions[k] != 'Q') cpos[k] = next_cpos[k];\n        for (int k = 0; k < 5; ++k) {\n            if (actions[k] == 'P' && grid[cpos[k].first][cpos[k].second] != -1) {\n                chold[k] = grid[cpos[k].first][cpos[k].second]; grid[cpos[k].first][cpos[k].second] = -1;\n            } else if (actions[k] == 'Q' && chold[k] != -1 && grid[cpos[k].first][cpos[k].second] == -1) {\n                grid[cpos[k].first][cpos[k].second] = chold[k]; chold[k] = -1;\n            }\n        }\n\n        for (int k = 0; k < 5; ++k) S[k] += actions[k];\n\n        // Step 3: Dispatch\n        bool all_done = true;\n        for (int i = 0; i < 5; ++i) {\n            if (grid[i][4] != -1) {\n                if (grid[i][4] == dnext[i]) dnext[i]++;\n                grid[i][4] = -1; // Dispatched (or penalized and removed by judge)\n            }\n            if (dnext[i] != i * 5 + 5) all_done = false;\n        }\n\n        if (all_done) break;\n    }\n\n    for (int i = 0; i < 5; ++i) cout << S[i] << \"\\n\";\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nint grid[20][20];\nint cur_r = 0, cur_c = 0;\nlong long load = 0;\nint turns = 0;\n\ninline int dist(int r1, int c1, int r2, int c2) {\n    return abs(r1 - r2) + abs(c1 - c2);\n}\n\nvoid output_move(char d) {\n    cout << d << '\\n';\n    turns++;\n    if (d == 'U') cur_r--;\n    else if (d == 'D') cur_r++;\n    else if (d == 'L') cur_c--;\n    else if (d == 'R') cur_c++;\n}\n\nvoid move_to(int tr, int tc) {\n    while (cur_r != tr) output_move(cur_r < tr ? 'D' : 'U');\n    while (cur_c != tc) output_move(cur_c < tc ? 'R' : 'L');\n}\n\nvoid do_load() {\n    if (grid[cur_r][cur_c] <= 0) return;\n    cout << '+' << grid[cur_r][cur_c] << '\\n';\n    load += grid[cur_r][cur_c];\n    grid[cur_r][cur_c] = 0;\n    turns++;\n}\n\nvoid do_unload() {\n    if (load <= 0 || grid[cur_r][cur_c] >= 0) return;\n    int d = (int)min((long long)-grid[cur_r][cur_c], load);\n    cout << '-' << d << '\\n';\n    load -= d;\n    grid[cur_r][cur_c] += d;\n    turns++;\n}\n\nbool is_flat() {\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (grid[i][j] != 0) return false;\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N)) return 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> grid[i][j];\n\n    // Heuristic coefficient balancing distance vs amount processed\n    const double ALPHA = 900.0;\n    const int TOP_K = 30;\n    int sim_grid[20][20];\n\n    while (!is_flat() && turns < 99000) {\n        struct Cand { int r, c; double score; };\n        vector<Cand> cands;\n        cands.reserve(400);\n\n        // Collect and score valid targets\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (grid[i][j] == 0) continue;\n                if (load == 0 && grid[i][j] <= 0) continue;\n                if (load > 0 && grid[i][j] >= 0) continue;\n                \n                int d = dist(cur_r, cur_c, i, j);\n                int amt = (load == 0) ? grid[i][j] : (int)min((long long)-grid[i][j], load);\n                double cost = (double)d * (100.0 + load);\n                double score = cost - ALPHA * amt;\n                cands.push_back({i, j, score});\n            }\n        }\n\n        if (cands.empty()) break;\n        sort(cands.begin(), cands.end(), [](const Cand& a, const Cand& b) {\n            return a.score < b.score;\n        });\n        if (cands.size() > TOP_K) cands.resize(TOP_K);\n\n        // Depth-2 Lookahead\n        double best_total = 1e18;\n        int best_r = cands[0].r, best_c = cands[0].c;\n\n        for (const auto& c1 : cands) {\n            // Simulate step 1\n            memcpy(sim_grid, grid, sizeof(sim_grid));\n            long long sim_load = load;\n            int d1 = dist(cur_r, cur_c, c1.r, c1.c);\n            double cost1 = d1 * (100.0 + load);\n            \n            int amt1 = (load == 0) ? sim_grid[c1.r][c1.c] : (int)min(sim_load, (long long)-sim_grid[c1.r][c1.c]);\n            if (load == 0) {\n                sim_load += amt1;\n                sim_grid[c1.r][c1.c] -= amt1;\n            } else {\n                sim_load -= amt1;\n                sim_grid[c1.r][c1.c] += amt1;\n            }\n\n            // Find minimal cost for step 2\n            double min_cost2 = 1e18;\n            bool possible = false;\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    if (sim_grid[i][j] == 0) continue;\n                    if (sim_load == 0 && sim_grid[i][j] <= 0) continue;\n                    if (sim_load > 0 && sim_grid[i][j] >= 0) continue;\n                    \n                    int d2 = dist(c1.r, c1.c, i, j);\n                    double cost2 = d2 * (100.0 + sim_load);\n                    if (cost2 < min_cost2) min_cost2 = cost2;\n                    possible = true;\n                }\n            }\n            \n            double total = cost1 + (possible ? min_cost2 : 0.0);\n            // Tie-breaker: prefer processing more soil\n            total -= 0.01 * amt1;\n            \n            if (total < best_total) {\n                best_total = total;\n                best_r = c1.r; best_c = c1.c;\n            }\n        }\n\n        move_to(best_r, best_c);\n        if (load == 0) do_load();\n        else do_unload();\n    }\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n\n#pragma GCC optimize(\"O3,unroll-loops\")\n\nusing namespace std;\n\nint N, M, T, SEED_COUNT;\nvector<vector<int>> X;\nvector<int> V, max_coord;\nint adj[36][4], deg[36];\nbool is_adj[36][36];\nmt19937 rng(42);\n\n// Fast edge score calculation\ninline double edge_val(int u, int v, double lambda) {\n    double d = 0;\n    const auto& xu = X[u];\n    const auto& xv = X[v];\n    #pragma GCC ivdep\n    for (int l = 0; l < M; ++l) {\n        d += abs(xu[l] - xv[l]);\n    }\n    return V[u] + V[v] + lambda * d;\n}\n\nvoid precompute_grid() {\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int u = i * N + j;\n            deg[u] = 0;\n            if (j + 1 < N) {\n                int v = i * N + (j + 1);\n                adj[u][deg[u]++] = v;\n                adj[v][deg[v]++] = u;\n                is_adj[u][v] = is_adj[v][u] = true;\n            }\n            if (i + 1 < N) {\n                int v = (i + 1) * N + j;\n                adj[u][deg[u]++] = v;\n                adj[v][deg[v]++] = u;\n                is_adj[u][v] = is_adj[v][u] = true;\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> T)) return 0;\n    SEED_COUNT = 2 * N * (N - 1);\n    X.assign(SEED_COUNT, vector<int>(M));\n    V.assign(SEED_COUNT, 0);\n    max_coord.assign(SEED_COUNT, 0);\n\n    for (int i = 0; i < SEED_COUNT; ++i) {\n        for (int j = 0; j < M; ++j) {\n            cin >> X[i][j];\n            V[i] += X[i][j];\n            if (X[i][j] > max_coord[i]) max_coord[i] = X[i][j];\n        }\n    }\n\n    precompute_grid();\n\n    const double lambda = 1.2;\n    const int MAX_ITER = 300000;\n    vector<int> P(36);\n    vector<pair<int, int>> scores(SEED_COUNT);\n    vector<int> pos_by_degree(36);\n    iota(pos_by_degree.begin(), pos_by_degree.end(), 0);\n    sort(pos_by_degree.begin(), pos_by_degree.end(), [&](int a, int b) {\n        return deg[a] > deg[b];\n    });\n\n    uniform_int_distribution<int> pos_dist(0, 35);\n\n    for (int t = 0; t < T; ++t) {\n        // 1. Score and select seeds\n        for (int i = 0; i < SEED_COUNT; ++i) {\n            scores[i] = {i, V[i] + 50 * max_coord[i]};\n        }\n        nth_element(scores.begin(), scores.begin() + 36, scores.end(), [](const auto& a, const auto& b) {\n            return a.second > b.second;\n        });\n        vector<int> top_seeds(36);\n        for (int i = 0; i < 36; ++i) top_seeds[i] = scores[i].first;\n\n        // Sort top seeds by value for degree-aware initialization\n        sort(top_seeds.begin(), top_seeds.end(), [&](int a, int b) {\n            return V[a] > V[b];\n        });\n\n        // 2. Initialize placement\n        for (int i = 0; i < 36; ++i) P[pos_by_degree[i]] = top_seeds[i];\n\n        // 3. Hill Climbing\n        for (int iter = 0; iter < MAX_ITER; ++iter) {\n            int p1 = pos_dist(rng);\n            int p2 = pos_dist(rng);\n            if (p1 == p2) continue;\n\n            int u1 = P[p1], u2 = P[p2];\n            \n            // Calculate score change efficiently\n            double before = 0, after = 0;\n            \n            auto eval_pos = [&](int pos, bool swapped, double& total) {\n                int cur = (pos == p1) ? (swapped ? u2 : u1) : (pos == p2) ? (swapped ? u1 : u2) : P[pos];\n                for (int k = 0; k < deg[pos]; ++k) {\n                    int nb = adj[pos][k];\n                    int other = (nb == p1) ? (swapped ? u2 : u1) : (nb == p2) ? (swapped ? u1 : u2) : P[nb];\n                    total += edge_val(cur, other, lambda);\n                }\n            };\n\n            eval_pos(p1, false, before);\n            eval_pos(p2, false, before);\n            eval_pos(p1, true, after);\n            eval_pos(p2, true, after);\n\n            if (is_adj[p1][p2]) {\n                before -= edge_val(u1, u2, lambda);\n                after  -= edge_val(u2, u1, lambda);\n            }\n\n            if (after > before) {\n                P[p1] = u2;\n                P[p2] = u1;\n            }\n        }\n\n        // 4. Output\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                cout << P[i * N + j] << (j == N - 1 ? \"\" : \" \");\n            }\n            cout << \"\\n\";\n        }\n        cout.flush();\n\n        // 5. Read next generation\n        if (t < T - 1) {\n            for (int i = 0; i < SEED_COUNT; ++i) {\n                V[i] = 0;\n                max_coord[i] = 0;\n                for (int j = 0; j < M; ++j) {\n                    cin >> X[i][j];\n                    V[i] += X[i][j];\n                    if (X[i][j] > max_coord[i]) max_coord[i] = X[i][j];\n                }\n            }\n        }\n    }\n\n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n\nusing namespace std;\n\nint N, M, V;\nvector<string> S, T;\nint finger_dir[20]; // 0:R, 1:D, 2:L, 3:U\nint carried = 0;\nint rx = 0, ry = 0;\nconst int dx[4] = {0, 1, 0, -1}; // R, D, L, U\nconst int dy[4] = {1, 0, -1, 0};\nconst char dch[4] = {'R', 'D', 'L', 'U'};\n\nvector<vector<bool>> is_pickup;\nvector<vector<bool>> is_drop;\nint dist[30][30];\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> V)) return 0;\n    S.resize(N); T.resize(N);\n    for (int i = 0; i < N; ++i) cin >> S[i];\n    for (int i = 0; i < N; ++i) cin >> T[i];\n\n    is_pickup.assign(N, vector<bool>(N, false));\n    is_drop.assign(N, vector<bool>(N, false));\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (S[i][j] == '1' && T[i][j] == '0') is_pickup[i][j] = true;\n            if (T[i][j] == '1' && S[i][j] == '0') is_drop[i][j] = true;\n        }\n    }\n\n    // Output tree design: Star graph with root 0 and leaves 1..V-1\n    cout << V << \"\\n\";\n    for (int i = 1; i < V; ++i) {\n        cout << \"0 1\\n\";\n    }\n    // Initial root position\n    cout << rx << \" \" << ry << \"\\n\";\n\n    // Initialize finger directions (all pointing Right initially)\n    for (int i = 0; i < V; ++i) finger_dir[i] = 0;\n\n    int turn = 0;\n    const int MAX_TURNS = 100000;\n\n    while (turn < MAX_TURNS) {\n        // Check if done\n        bool has_pickup = false, has_drop = false;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (is_pickup[i][j]) has_pickup = true;\n                if (is_drop[i][j]) has_drop = true;\n            }\n        }\n        if (!has_pickup && carried == 0) break;\n\n        // Multi-source BFS to find distance to nearest actionable root position\n        // Actionable root positions are neighbors of pickup/drop cells\n        vector<pair<int, int>> sources;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (is_pickup[i][j] || is_drop[i][j]) {\n                    for (int d = 0; d < 4; ++d) {\n                        int ni = i + dx[d], nj = j + dy[d];\n                        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                            sources.push_back({ni, nj});\n                        }\n                    }\n                }\n            }\n        }\n\n        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) dist[i][j] = 1e9;\n        queue<pair<int, int>> q;\n        for (auto& p : sources) {\n            if (dist[p.first][p.second] == 1e9) {\n                dist[p.first][p.second] = 0;\n                q.push(p);\n            }\n        }\n\n        while (!q.empty()) {\n            auto [cx, cy] = q.front(); q.pop();\n            for (int d = 0; d < 4; ++d) {\n                int nx = cx + dx[d], ny = cy + dy[d];\n                if (nx >= 0 && nx < N && ny >= 0 && ny < N) {\n                    if (dist[nx][ny] == 1e9) {\n                        dist[nx][ny] = dist[cx][cy] + 1;\n                        q.push({nx, ny});\n                    }\n                }\n            }\n        }\n\n        // Decide root move: choose direction that minimizes dist to actionable position\n        int best_d = -1;\n        int best_dist = 1e9;\n        for (int d = 0; d < 4; ++d) {\n            int nx = rx + dx[d], ny = ry + dy[d];\n            if (nx >= 0 && nx < N && ny >= 0 && ny < N) {\n                if (dist[nx][ny] < best_dist) {\n                    best_dist = dist[nx][ny];\n                    best_d = d;\n                }\n            }\n        }\n        // If staying is optimal or no move improves, stay\n        if (best_dist > dist[rx][ry]) best_d = -1;\n\n        char move_c = '.';\n        if (best_d != -1) {\n            move_c = dch[best_d];\n            rx += dx[best_d];\n            ry += dy[best_d];\n        }\n\n        // Collect immediate tasks from neighbors\n        struct Task { int dir, type; }; // type: 1 pickup, 2 drop\n        vector<Task> tasks;\n        for (int d = 0; d < 4; ++d) {\n            int nx = rx + dx[d], ny = ry + dy[d];\n            if (nx >= 0 && nx < N && ny >= 0 && ny < N) {\n                if (is_pickup[nx][ny]) tasks.push_back({d, 1});\n                else if (is_drop[nx][ny]) tasks.push_back({d, 2});\n            }\n        }\n\n        // Prioritize tasks based on capacity\n        if (carried > (V - 1) / 2) {\n            // Full: prioritize drops\n            stable_sort(tasks.begin(), tasks.end(), [](const Task& a, const Task& b) {\n                return a.type > b.type; // drops (2) first\n            });\n        } else {\n            // Not full: prioritize pickups\n            stable_sort(tasks.begin(), tasks.end(), [](const Task& a, const Task& b) {\n                return a.type < b.type; // pickups (1) first\n            });\n        }\n\n        string cmd(2 * V, '.');\n        cmd[0] = move_c;\n\n        int task_idx = 0;\n        for (int i = 1; i < V; ++i) {\n            char rot = '.';\n            int target_d = -1;\n\n            if (task_idx < tasks.size()) {\n                target_d = tasks[task_idx].dir;\n                int cur = finger_dir[i];\n                int target = target_d;\n                int diff = (target - cur + 4) % 4;\n\n                if (diff == 1) rot = 'R';       // CW\n                else if (diff == 2) rot = 'R';  // 2 steps CW\n                else if (diff == 3) rot = 'L';  // CCW\n                else rot = '.';\n\n                // Update simulated direction\n                if (rot == 'R') finger_dir[i] = (cur + 1) % 4;\n                else if (rot == 'L') finger_dir[i] = (cur + 3) % 4;\n            }\n\n            cmd[i] = rot;\n\n            // Perform action if aligned\n            if (target_d != -1 && finger_dir[i] == target_d) {\n                int nx = rx + dx[target_d], ny = ry + dy[target_d];\n                bool success = false;\n\n                if (tasks[task_idx].type == 1) { // Pickup\n                    if (carried < V - 1) {\n                        is_pickup[nx][ny] = false;\n                        carried++;\n                        success = true;\n                    }\n                } else { // Drop\n                    if (carried > 0) {\n                        is_drop[nx][ny] = false;\n                        carried--;\n                        success = true;\n                    }\n                }\n\n                if (success) {\n                    cmd[V + i] = 'P';\n                    task_idx++; // Task completed, move to next\n                }\n                // If failed due to capacity, keep task_idx so next finger can try (though likely same capacity constraint)\n                // But to prevent infinite attempts, we just move forward if capacity blocks\n                if (tasks[task_idx].type == 1 && carried >= V - 1) task_idx = tasks.size();\n                if (tasks[task_idx].type == 2 && carried <= 0) task_idx = tasks.size();\n            }\n        }\n\n        cout << cmd << \"\\n\";\n        turn++;\n    }\n\n    return 0;\n}","ahc039":"#include <iostream>\n#include <vector>\n#include <random>\n#include <cmath>\n#include <algorithm>\n#include <map>\n#include <queue>\n#include <set>\n\nusing namespace std;\n\nstruct Pt {\n    int x, y;\n    bool operator==(const Pt& o) const { return x == o.x && y == o.y; }\n    bool operator<(const Pt& o) const { return x != o.x ? x < o.x : y < o.y; }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    if (!(cin >> N)) return 0;\n    vector<Pt> mack(N), sard(N);\n    for (int i = 0; i < N; ++i) cin >> mack[i].x >> mack[i].y;\n    for (int i = 0; i < N; ++i) cin >> sard[i].x >> sard[i].y;\n\n    // Grid parameters: D = cell size, G = grid dimensions\n    const int D = 400;\n    const int G = 100000 / D + 2; // ~252\n    vector<vector<int>> grid(G, vector<int>(G, 0));\n    vector<vector<bool>> sel(G, vector<bool>(G, false));\n\n    auto add_points = [&](const vector<Pt>& pts, int val) {\n        for (auto& p : pts) {\n            int cx = p.x / D;\n            int cy = p.y / D;\n            if (cx >= 0 && cx < G && cy >= 0 && cy < G) {\n                grid[cy][cx] += val;\n            }\n        }\n    };\n    add_points(mack, 1);\n    add_points(sard, -1);\n\n    mt19937 rng(42); // Fixed seed for reproducibility\n    double T = 100.0;\n    int iters = 350000;\n\n    // Initialize SA with the best single cell\n    int best_r = 0, best_c = 0, best_w = -1e9;\n    for (int r = 0; r < G; ++r) {\n        for (int c = 0; c < G; ++c) {\n            if (grid[r][c] > best_w) {\n                best_w = grid[r][c]; best_r = r; best_c = c;\n            }\n        }\n    }\n    sel[best_r][best_c] = true;\n\n    int dr[] = {-1, 1, 0, 0};\n    int dc[] = {0, 0, -1, 1};\n\n    for (int it = 0; it < iters; ++it) {\n        T *= 0.99996;\n        if (T < 0.05) T = 0.05;\n\n        int r = rng() % G;\n        int c = rng() % G;\n\n        bool is_sel = sel[r][c];\n        bool can_toggle = false;\n\n        if (!is_sel) {\n            // Only add if adjacent to selected region\n            for (int i = 0; i < 4; ++i) {\n                int nr = r + dr[i], nc = c + dc[i];\n                if (nr >= 0 && nr < G && nc >= 0 && nc < G && sel[nr][nc]) {\n                    can_toggle = true; break;\n                }\n            }\n        } else {\n            // Only remove if on boundary (has unselected neighbor or grid edge)\n            bool on_boundary = false;\n            for (int i = 0; i < 4; ++i) {\n                int nr = r + dr[i], nc = c + dc[i];\n                if (nr < 0 || nr >= G || nc < 0 || nc >= G || !sel[nr][nc]) {\n                    on_boundary = true; break;\n                }\n            }\n            can_toggle = on_boundary;\n        }\n\n        if (!can_toggle) continue;\n\n        int delta = is_sel ? -grid[r][c] : grid[r][c];\n        // Clamp exponent to avoid overflow/underflow\n        double prob = 0.0;\n        if (delta > 0) prob = 1.0;\n        else {\n            double val = delta / T;\n            if (val < -50) val = -50;\n            if (val > 50) val = 50;\n            prob = exp(val);\n        }\n        if ((rng() / 4294967295.0) < prob) {\n            sel[r][c] = !is_sel;\n        }\n    }\n\n    // Post-processing 1: Keep only the largest 4-connected component\n    vector<vector<bool>> final_sel(G, vector<bool>(G, false));\n    vector<vector<bool>> visited(G, vector<bool>(G, false));\n    int start_r = -1, start_c = -1;\n    for (int r = 0; r < G; ++r) {\n        for (int c = 0; c < G; ++c) {\n            if (sel[r][c]) { start_r = r; start_c = c; r = G; break; }\n        }\n    }\n\n    if (start_r != -1) {\n        queue<pair<int, int>> q;\n        q.emplace(start_r, start_c);\n        visited[start_r][start_c] = true;\n        while (!q.empty()) {\n            auto [r, c] = q.front(); q.pop();\n            final_sel[r][c] = true;\n            for (int i = 0; i < 4; ++i) {\n                int nr = r + dr[i], nc = c + dc[i];\n                if (nr >= 0 && nr < G && nc >= 0 && nc < G && sel[nr][nc] && !visited[nr][nc]) {\n                    visited[nr][nc] = true;\n                    q.emplace(nr, nc);\n                }\n            }\n        }\n    }\n\n    // Post-processing 2: Fill holes using flood fill from outside\n    vector<vector<bool>> outside(G, vector<bool>(G, false));\n    queue<pair<int, int>> q_out;\n    // Push boundary cells that are not selected\n    for (int c = 0; c < G; ++c) {\n        if (!final_sel[0][c]) { outside[0][c] = true; q_out.emplace(0, c); }\n        if (!final_sel[G-1][c]) { outside[G-1][c] = true; q_out.emplace(G-1, c); }\n    }\n    for (int r = 0; r < G; ++r) {\n        if (!final_sel[r][0]) { outside[r][0] = true; q_out.emplace(r, 0); }\n        if (!final_sel[r][G-1]) { outside[r][G-1] = true; q_out.emplace(r, G-1); }\n    }\n    while (!q_out.empty()) {\n        auto [r, c] = q_out.front(); q_out.pop();\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i], nc = c + dc[i];\n            if (nr >= 0 && nr < G && nc >= 0 && nc < G && !final_sel[nr][nc] && !outside[nr][nc]) {\n                outside[nr][nc] = true;\n                q_out.emplace(nr, nc);\n            }\n        }\n    }\n    for (int r = 0; r < G; ++r) {\n        for (int c = 0; c < G; ++c) {\n            if (!final_sel[r][c] && !outside[r][c]) {\n                final_sel[r][c] = true; // Hole filled\n            }\n        }\n    }\n\n    // Edge extraction: interior edges cancel out, boundary edges remain\n    map<pair<Pt, Pt>, int> edge_cnt;\n    auto add_edge = [&](Pt u, Pt v) {\n        if (u.x > v.x || (u.x == v.x && u.y > v.y)) swap(u, v);\n        edge_cnt[{u, v}]++;\n    };\n\n    for (int r = 0; r < G; ++r) {\n        for (int c = 0; c < G; ++c) {\n            if (final_sel[r][c]) {\n                Pt p1 = {c * D, r * D};\n                Pt p2 = {(c + 1) * D, r * D};\n                Pt p3 = {(c + 1) * D, (r + 1) * D};\n                Pt p4 = {c * D, (r + 1) * D};\n                add_edge(p1, p2); add_edge(p2, p3);\n                add_edge(p3, p4); add_edge(p4, p1);\n            }\n        }\n    }\n\n    // Build adjacency graph for tracing\n    map<Pt, vector<Pt>> adj;\n    for (auto& [e, cnt] : edge_cnt) {\n        if (cnt % 2 == 1) { // Boundary edge\n            adj[e.first.first].push_back(e.first.second);\n            adj[e.first.second].push_back(e.first.first);\n        }\n    }\n\n    // Trace the polygon\n    vector<Pt> poly;\n    if (!adj.empty()) {\n        Pt curr = adj.begin()->first;\n        Pt prev = {-1, -1};\n        int steps = 0;\n        while (steps < 20000) { // Safety limit\n            poly.push_back(curr);\n            Pt next = {-1, -1};\n            for (auto& nb : adj[curr]) {\n                if (!(nb == prev)) {\n                    next = nb;\n                    break;\n                }\n            }\n            prev = curr;\n            curr = next;\n            if (curr == poly[0]) break;\n            steps++;\n        }\n    }\n\n    // Remove collinear vertices to reduce vertex count\n    vector<Pt> simplified;\n    int m = poly.size();\n    for (int i = 0; i < m; ++i) {\n        Pt prev = poly[(i - 1 + m) % m];\n        Pt curr = poly[i];\n        Pt next = poly[(i + 1) % m];\n        long long dx1 = curr.x - prev.x;\n        long long dy1 = curr.y - prev.y;\n        long long dx2 = next.x - curr.x;\n        long long dy2 = next.y - curr.y;\n        // Cross product != 0 means not collinear\n        if (dx1 * dy2 != dx2 * dy1) {\n            simplified.push_back(curr);\n        }\n    }\n    if (simplified.empty() && !poly.empty()) simplified = poly;\n\n    // Ensure m >= 4 and valid format\n    while (simplified.size() < 4) {\n        if (simplified.empty()) {\n            simplified = {{0, 0}, {D, 0}, {D, D}, {0, D}};\n        } else {\n            Pt p = simplified.back();\n            simplified.push_back(p);\n        }\n    }\n\n    // Output\n    cout << simplified.size() << \"\\n\";\n    for (auto& p : simplified) {\n        cout << p.x << \" \" << p.y << \"\\n\";\n    }\n\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\n#include <cmath>\nusing namespace std;\n#pragma GCC optimize(\"O3,unroll-loops\")\n\nstruct Choice { \n    bool skipped = false; \n    bool rot = false; \n    char dir = 'U'; \n    int ref = -1; \n};\nstruct Rect { int x, y, w, h; };\n\nmt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Fast simulation of the packing process\nlong long evaluate(int N, const vector<Choice>& cfg, const vector<pair<int,int>>& wh, long long& skip_pen) {\n    vector<pair<int, Rect>> placed;\n    placed.reserve(N);\n    int max_x = 0, max_y = 0;\n    \n    for (int i = 0; i < N; ++i) {\n        if (cfg[i].skipped) continue;\n        int w = cfg[i].rot ? wh[i].second : wh[i].first;\n        int h = cfg[i].rot ? wh[i].first : wh[i].second;\n        int x = 0, y = 0;\n        int ref = cfg[i].ref;\n        \n        // Align with reference rectangle if valid\n        if (ref != -1 && !cfg[ref].skipped) {\n            for (auto& p : placed) if (p.first == ref) {\n                if (cfg[i].dir == 'U') x = p.second.x + p.second.w;\n                else y = p.second.y + p.second.h;\n                break;\n            }\n        }\n        \n        if (cfg[i].dir == 'U') {\n            // Move upward (decrease y) until hitting y=0 or bottom of another rect\n            int y_floor = 0;\n            for (auto& p : placed) {\n                // Check horizontal overlap\n                if (x < p.second.x + p.second.w && p.second.x < x + w)\n                    y_floor = max(y_floor, p.second.y);\n            }\n            y = max(0, y_floor - h);\n        } else {\n            // Move leftward (decrease x) until hitting x=0 or right edge of another rect\n            int x_floor = 0;\n            for (auto& p : placed) {\n                // Check vertical overlap\n                if (y < p.second.y + p.second.h && p.second.y < y + h)\n                    x_floor = max(x_floor, p.second.x + p.second.w);\n            }\n            x = max(0, x_floor);\n        }\n        \n        placed.push_back({i, {x, y, w, h}});\n        if (x + w > max_x) max_x = x + w;\n        if (y + h > max_y) max_y = y + h;\n    }\n    \n    skip_pen = 0;\n    for (int i = 0; i < N; ++i) \n        if (cfg[i].skipped) skip_pen += wh[i].first + wh[i].second;\n        \n    return max_x + max_y + skip_pen;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    \n    int N, T, sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n    \n    vector<pair<int,int>> wh(N);\n    for (int i = 0; i < N; ++i) cin >> wh[i].first >> wh[i].second;\n\n    // Initial configuration\n    vector<Choice> cur(N), best(N);\n    for (int i = 0; i < N; ++i) {\n        cur[i].rot = rng() & 1;\n        cur[i].dir = (rng() & 1) ? 'U' : 'L';\n        cur[i].ref = -1;\n        cur[i].skipped = (rng() % 5 == 0); // Start with ~20% skipped\n    }\n\n    long long skip_pen;\n    long long cur_cost = evaluate(N, cur, wh, skip_pen);\n    long long best_cost = cur_cost;\n    best = cur;\n\n    double temp = 5000.0;\n    auto start_time = chrono::steady_clock::now();\n\n    for (int turn = 0; turn < T; ++turn) {\n        // Read feedback from previous turn (ignored as noise is high, local sim is reliable)\n        if (turn > 0) {\n            int W_in, H_in; \n            cin >> W_in >> H_in;\n        }\n\n        // Simulated Annealing loop\n        while (true) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double, std::milli>(now - start_time).count();\n            if (elapsed > 2850.0) break; // Leave margin for I/O and final output\n\n            vector<Choice> next = cur;\n            int i = rng() % N;\n            int type = rng() % 5;\n\n            if (type == 0) {\n                next[i].skipped = !next[i].skipped;\n            } else if (type == 1) {\n                next[i].rot = !next[i].rot;\n            } else if (type == 2) {\n                next[i].dir = (next[i].dir == 'U' ? 'L' : 'U');\n            } else {\n                // Change reference to a valid non-skipped previous rectangle\n                int r = -1;\n                if (i > 0) {\n                    int cand = rng() % i;\n                    if (!next[cand].skipped) r = cand;\n                }\n                next[i].ref = r;\n            }\n\n            long long n_skip_pen;\n            long long next_cost = evaluate(N, next, wh, n_skip_pen);\n\n            // Metropolis acceptance criterion\n            if (next_cost < cur_cost || (double)(rng() & 0xFFFFFF) / 0xFFFFFF < exp(max(-50.0, (cur_cost - next_cost) / temp))) {\n                cur = next;\n                cur_cost = next_cost;\n                skip_pen = n_skip_pen;\n                if (cur_cost < best_cost) {\n                    best_cost = cur_cost;\n                    best = cur;\n                }\n            }\n            \n            if (temp > 1e-5) temp *= 0.99995;\n        }\n\n        if (cur_cost < best_cost) {\n            best = cur;\n            best_cost = cur_cost;\n        }\n\n        // Output best configuration found so far\n        int n_place = 0;\n        for (int i = 0; i < N; ++i) if (!best[i].skipped) n_place++;\n        \n        cout << n_place << \"\\n\";\n        for (int i = 0; i < N; ++i) {\n            if (!best[i].skipped) {\n                cout << i << \" \" << best[i].rot << \" \" << best[i].dir << \" \" << best[i].ref << \"\\n\";\n            }\n        }\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc041":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <chrono>\n#include <random>\n\nusing namespace std;\n\nconst int INF = 1e9;\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    auto start_time = chrono::steady_clock::now();\n\n    int N, M, H;\n    if (!(cin >> N >> M >> H)) return 0;\n\n    vector<int> A(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> A[i];\n    }\n\n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    // Read and ignore coordinates\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    // 1. All-Pairs Shortest Paths using BFS\n    vector<vector<int>> dist(N, vector<int>(N, INF));\n    for (int i = 0; i < N; ++i) {\n        queue<int> q;\n        dist[i][i] = 0;\n        q.push(i);\n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            for (int v : adj[u]) {\n                if (dist[i][v] == INF) {\n                    dist[i][v] = dist[i][u] + 1;\n                    q.push(v);\n                }\n            }\n        }\n    }\n\n    // 2. Greedy Root Selection\n    vector<int> d(N, INF);\n    vector<bool> is_root(N, false);\n    vector<int> roots;\n\n    while (true) {\n        int best_v = -1;\n        int min_A = INF;\n        bool all_covered = true;\n        for (int i = 0; i < N; ++i) {\n            if (d[i] > H) {\n                all_covered = false;\n                if (A[i] < min_A) {\n                    min_A = A[i];\n                    best_v = i;\n                }\n            }\n        }\n        if (all_covered) break;\n\n        vector<int> candidates;\n        candidates.reserve(N);\n        for (int r = 0; r < N; ++r) {\n            if (dist[r][best_v] <= H) {\n                candidates.push_back(r);\n            }\n        }\n        // Sort candidates by beauty value ascending\n        sort(candidates.begin(), candidates.end(), [&](int a, int b) {\n            return A[a] < A[b];\n        });\n\n        int K = min((int)candidates.size(), 50);\n        int best_r = -1;\n        long long best_sc = -1;\n\n        for (int i = 0; i < K; ++i) {\n            int r = candidates[i];\n            long long current_sc = 0;\n            for (int u = 0; u < N; ++u) {\n                int nd = d[u];\n                if (dist[r][u] < nd) nd = dist[r][u];\n                int val = (nd > H) ? H : nd;\n                current_sc += (long long)(val + 1) * A[u];\n            }\n            if (current_sc > best_sc) {\n                best_sc = current_sc;\n                best_r = r;\n            }\n        }\n\n        is_root[best_r] = true;\n        roots.push_back(best_r);\n        for (int u = 0; u < N; ++u) {\n            if (dist[best_r][u] < d[u]) {\n                d[u] = dist[best_r][u];\n            }\n        }\n    }\n\n    // 3. Local Search Improvement\n    vector<int> current_roots = roots;\n    sort(current_roots.begin(), current_roots.end());\n    current_roots.erase(unique(current_roots.begin(), current_roots.end()), current_roots.end());\n\n    vector<int> cur_d(N, INF);\n    for (int r : current_roots) {\n        for (int u = 0; u < N; ++u) {\n            cur_d[u] = min(cur_d[u], dist[r][u]);\n        }\n    }\n    long long cur_score = 0;\n    for (int i = 0; i < N; ++i) {\n        cur_score += (long long)(cur_d[i] + 1) * A[i];\n    }\n\n    mt19937 rng(42);\n    const double TIME_LIMIT = 1.8; // Reserve 0.2s for I/O and final construction\n    auto get_time = [&]() { return chrono::duration<double>(chrono::steady_clock::now() - start_time).count(); };\n\n    while (get_time() < TIME_LIMIT) {\n        bool improved = false;\n        shuffle(current_roots.begin(), current_roots.end(), rng);\n\n        // Try removing roots\n        for (int i = 0; i < (int)current_roots.size(); ++i) {\n            if (get_time() > TIME_LIMIT) goto end_search;\n            \n            int r = current_roots[i];\n            vector<int> new_roots = current_roots;\n            new_roots.erase(new_roots.begin() + i);\n            if (new_roots.empty()) continue;\n\n            vector<int> new_d(N, INF);\n            bool possible = true;\n            for (int u = 0; u < N; ++u) {\n                int md = INF;\n                for (int nr : new_roots) {\n                    if (dist[nr][u] < md) md = dist[nr][u];\n                }\n                new_d[u] = md;\n                if (md > H) {\n                    possible = false;\n                    break;\n                }\n            }\n            \n            if (possible) {\n                long long new_sc = 0;\n                for (int u = 0; u < N; ++u) new_sc += (long long)(new_d[u] + 1) * A[u];\n                if (new_sc > cur_score) {\n                    current_roots = new_roots;\n                    cur_d = new_d;\n                    cur_score = new_sc;\n                    improved = true;\n                    break;\n                }\n            }\n        }\n        if (improved) continue;\n\n        // Try moving roots\n        shuffle(current_roots.begin(), current_roots.end(), rng);\n        for (int i = 0; i < (int)current_roots.size(); ++i) {\n            if (get_time() > TIME_LIMIT) goto end_search;\n            \n            int r = current_roots[i];\n            shuffle(adj[r].begin(), adj[r].end(), rng);\n            for (int nr : adj[r]) {\n                bool exists = false;\n                for (int ex : current_roots) if (ex == nr) { exists = true; break; }\n                if (exists) continue;\n\n                vector<int> new_roots = current_roots;\n                new_roots[i] = nr;\n                \n                vector<int> new_d(N, INF);\n                bool possible = true;\n                for (int u = 0; u < N; ++u) {\n                    int md = INF;\n                    for (int root : new_roots) {\n                        if (dist[root][u] < md) md = dist[root][u];\n                    }\n                    new_d[u] = md;\n                    if (md > H) {\n                        possible = false;\n                        break;\n                    }\n                }\n\n                if (possible) {\n                    long long new_sc = 0;\n                    for (int u = 0; u < N; ++u) new_sc += (long long)(new_d[u] + 1) * A[u];\n                    if (new_sc > cur_score) {\n                        current_roots = new_roots;\n                        cur_d = new_d;\n                        cur_score = new_sc;\n                        improved = true;\n                        goto after_move;\n                    }\n                }\n            }\n        }\n        after_move:\n        if (!improved) break;\n    }\n    end_search:;\n\n    // 4. Construct Trees\n    vector<int> p(N, -1);\n    for (int i = 0; i < N; ++i) {\n        if (cur_d[i] > 0) {\n            int target = cur_d[i] - 1;\n            int best_p = -1;\n            for (int nb : adj[i]) {\n                if (cur_d[nb] == target) {\n                    best_p = nb;\n                    break;\n                }\n            }\n            p[i] = best_p;\n        }\n    }\n\n    // Output\n    for (int i = 0; i < N; ++i) {\n        cout << p[i] << (i == N - 1 ? \"\" : \" \");\n    }\n    cout << \"\\n\";\n\n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <utility>\n\nusing namespace std;\n\nint N;\nvector<string> board;\n\n// Shift row r to the left\nvoid shift_row_left(int r) {\n    for (int j = 0; j < N - 1; j++) {\n        board[r][j] = board[r][j + 1];\n    }\n    board[r][N - 1] = '.'; // Vacated space becomes empty\n}\n\n// Shift row r to the right\nvoid shift_row_right(int r) {\n    for (int j = N - 1; j > 0; j--) {\n        board[r][j] = board[r][j - 1];\n    }\n    board[r][0] = '.'; // Vacated space becomes empty\n}\n\n// Shift column c upward\nvoid shift_col_up(int c) {\n    for (int i = 0; i < N - 1; i++) {\n        board[i][c] = board[i + 1][c];\n    }\n    board[N - 1][c] = '.'; // Vacated space becomes empty\n}\n\n// Shift column c downward\nvoid shift_col_down(int c) {\n    for (int i = N - 1; i > 0; i--) {\n        board[i][c] = board[i - 1][c];\n    }\n    board[0][c] = '.'; // Vacated space becomes empty\n}\n\n// Check if there are no Fukunokami ('o') above (r, c)\nbool is_clear_up(int r, int c) {\n    for (int i = 0; i < r; i++) {\n        if (board[i][c] == 'o') return false;\n    }\n    return true;\n}\n\n// Check if there are no Fukunokami ('o') below (r, c)\nbool is_clear_down(int r, int c) {\n    for (int i = r + 1; i < N; i++) {\n        if (board[i][c] == 'o') return false;\n    }\n    return true;\n}\n\n// Check if there are no Fukunokami ('o') to the left of (r, c)\nbool is_clear_left(int r, int c) {\n    for (int j = 0; j < c; j++) {\n        if (board[r][j] == 'o') return false;\n    }\n    return true;\n}\n\n// Check if there are no Fukunokami ('o') to the right of (r, c)\nbool is_clear_right(int r, int c) {\n    for (int j = c + 1; j < N; j++) {\n        if (board[r][j] == 'o') return false;\n    }\n    return true;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    if (!(cin >> N)) return 0;\n    board.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> board[i];\n    }\n    \n    vector<pair<char, int>> ops;\n    \n    // Loop until all Oni are removed\n    while (true) {\n        int min_cost = 1e9;\n        char best_dir = 0;\n        int best_r = -1, best_c = -1;\n        bool found_oni = false;\n        \n        // Find the Oni with the minimum removal cost\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (board[i][j] == 'x') {\n                    found_oni = true;\n                    // Check Up\n                    if (is_clear_up(i, j)) {\n                        int cost = 2 * (i + 1);\n                        if (cost < min_cost) {\n                            min_cost = cost;\n                            best_dir = 'U';\n                            best_r = i;\n                            best_c = j;\n                        }\n                    }\n                    // Check Down\n                    if (is_clear_down(i, j)) {\n                        int cost = 2 * (N - i);\n                        if (cost < min_cost) {\n                            min_cost = cost;\n                            best_dir = 'D';\n                            best_r = i;\n                            best_c = j;\n                        }\n                    }\n                    // Check Left\n                    if (is_clear_left(i, j)) {\n                        int cost = 2 * (j + 1);\n                        if (cost < min_cost) {\n                            min_cost = cost;\n                            best_dir = 'L';\n                            best_r = i;\n                            best_c = j;\n                        }\n                    }\n                    // Check Right\n                    if (is_clear_right(i, j)) {\n                        int cost = 2 * (N - j);\n                        if (cost < min_cost) {\n                            min_cost = cost;\n                            best_dir = 'R';\n                            best_r = i;\n                            best_c = j;\n                        }\n                    }\n                }\n            }\n        }\n        \n        if (!found_oni) break;\n        if (best_dir == 0) {\n            // Should not happen based on problem guarantees\n            break;\n        }\n        \n        int shifts = 0;\n        if (best_dir == 'U') shifts = best_r + 1;\n        else if (best_dir == 'D') shifts = N - best_r;\n        else if (best_dir == 'L') shifts = best_c + 1;\n        else if (best_dir == 'R') shifts = N - best_c;\n        \n        // Parameter for the operation: column index for U/D, row index for L/R\n        int param = (best_dir == 'U' || best_dir == 'D') ? best_c : best_r;\n        \n        // Push phase: Shift in the clear direction to remove the Oni\n        for (int k = 0; k < shifts; k++) {\n            ops.push_back({best_dir, param});\n            if (best_dir == 'U') shift_col_up(best_c);\n            else if (best_dir == 'D') shift_col_down(best_c);\n            else if (best_dir == 'L') shift_row_left(best_r);\n            else if (best_dir == 'R') shift_row_right(best_r);\n        }\n        \n        // Pull phase: Shift back to restore the board state\n        char pull_dir = 0;\n        if (best_dir == 'U') pull_dir = 'D';\n        else if (best_dir == 'D') pull_dir = 'U';\n        else if (best_dir == 'L') pull_dir = 'R';\n        else if (best_dir == 'R') pull_dir = 'L';\n        \n        for (int k = 0; k < shifts; k++) {\n            ops.push_back({pull_dir, param});\n            if (pull_dir == 'U') shift_col_up(best_c);\n            else if (pull_dir == 'D') shift_col_down(best_c);\n            else if (pull_dir == 'L') shift_row_left(best_r);\n            else if (pull_dir == 'R') shift_row_right(best_r);\n        }\n    }\n    \n    // Output the sequence of operations\n    for (const auto& op : ops) {\n        cout << op.first << \" \" << op.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Global variables to store input and best solution\nint N, L;\nint T[105];\nint best_a[105], best_b[105];\nlong long best_err = 2e18;\n\n// Simulation function\n// Computes the error and optionally stores the final counts in res_cnt\nlong long simulate(int* a, int* b, int* res_cnt) {\n    int cnt[105] = {0};\n    int cur = 0;\n    // Simulate L weeks\n    for(int w = 0; w < L; ++w) {\n        cnt[cur]++;\n        if(w == L - 1) break;\n        int t = cnt[cur];\n        // If t is odd, next is a[cur], else b[cur]\n        cur = (t & 1) ? a[cur] : b[cur];\n    }\n    \n    if(res_cnt) {\n        for(int i = 0; i < N; ++i) res_cnt[i] = cnt[i];\n    }\n    \n    long long err = 0;\n    for(int i = 0; i < N; ++i) {\n        err += abs(cnt[i] - T[i]);\n    }\n    return err;\n}\n\nint main() {\n    // Fast I/O\n    cin.tie(nullptr);\n    ios::sync_with_stdio(false);\n    \n    if(!(cin >> N >> L)) return 0;\n    for(int i = 0; i < N; ++i) cin >> T[i];\n\n    // Random number generator\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist(0, N - 1);\n    uniform_real_distribution<double> dist01(0.0, 1.0);\n\n    int cur_a[105], cur_b[105];\n    // Initialize with -1 to indicate undefined\n    for(int i = 0; i < N; ++i) cur_a[i] = cur_b[i] = -1;\n\n    // Greedy initialization to get a valid and decent starting solution\n    {\n        int g_cnt[105] = {0};\n        int cur = 0;\n        for(int w = 0; w < L; ++w) {\n            g_cnt[cur]++;\n            if(w == L - 1) break;\n            int t = g_cnt[cur];\n            int next = -1;\n            if(t & 1) { // Odd\n                if(cur_a[cur] != -1) {\n                    next = cur_a[cur];\n                } else {\n                    // Choose the employee with the largest deficit (T[i] - g_cnt[i])\n                    int best = 0, max_def = -1e9;\n                    for(int i = 0; i < N; ++i) {\n                        int def = T[i] - g_cnt[i];\n                        if(def > max_def) {\n                            max_def = def;\n                            best = i;\n                        }\n                    }\n                    cur_a[cur] = best;\n                    next = best;\n                }\n            } else { // Even\n                if(cur_b[cur] != -1) {\n                    next = cur_b[cur];\n                } else {\n                    int best = 0, max_def = -1e9;\n                    for(int i = 0; i < N; ++i) {\n                        int def = T[i] - g_cnt[i];\n                        if(def > max_def) {\n                            max_def = def;\n                            best = i;\n                        }\n                    }\n                    cur_b[cur] = best;\n                    next = best;\n                }\n            }\n            cur = next;\n        }\n        // Fill any remaining undefined transitions randomly\n        for(int i = 0; i < N; ++i) {\n            if(cur_a[i] == -1) cur_a[i] = dist(rng);\n            if(cur_b[i] == -1) cur_b[i] = dist(rng);\n        }\n    }\n\n    // Evaluate the initial solution\n    int current_cnt[105];\n    long long current_err = simulate(cur_a, cur_b, current_cnt);\n    best_err = current_err;\n    for(int i = 0; i < N; ++i) {\n        best_a[i] = cur_a[i];\n        best_b[i] = cur_b[i];\n    }\n\n    // Simulated Annealing\n    double temp = 50000.0;\n    auto start = chrono::steady_clock::now();\n\n    while(true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if(elapsed > 1.85) break; // Leave some margin for output\n\n        // Cooling schedule\n        temp *= 0.998;\n\n        // Perturbation: change one random transition\n        int idx = dist(rng);\n        bool change_a = (dist(rng) & 1);\n        int old_val = change_a ? cur_a[idx] : cur_b[idx];\n        int new_val = dist(rng);\n        \n        if(change_a) cur_a[idx] = new_val;\n        else cur_b[idx] = new_val;\n\n        long long next_err = simulate(cur_a, cur_b, current_cnt);\n\n        if(next_err < current_err) {\n            current_err = next_err;\n            if(next_err < best_err) {\n                best_err = next_err;\n                for(int i = 0; i < N; ++i) {\n                    best_a[i] = cur_a[i];\n                    best_b[i] = cur_b[i];\n                }\n            }\n        } else {\n            // Metropolis criterion\n            double prob = exp((current_err - next_err) / temp);\n            if(dist01(rng) < prob) {\n                current_err = next_err;\n            } else {\n                // Revert change\n                if(change_a) cur_a[idx] = old_val;\n                else cur_b[idx] = old_val;\n            }\n        }\n    }\n\n    // Output the best solution found\n    for(int i = 0; i < N; ++i) {\n        cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n    }\n\n    return 0;\n}","ahc045":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <numeric>\n#include <tuple>\n\nusing namespace std;\n\n// Disjoint Set Union (Union-Find) structure\nstruct DSU {\n    vector<int> parent;\n    vector<int> rank;\n    DSU(int n) : parent(n), rank(n, 0) { \n        iota(parent.begin(), parent.end(), 0); \n    }\n    int find(int x) { \n        return parent[x] == x ? x : parent[x] = find(parent[x]); \n    }\n    bool unite(int x, int y) {\n        x = find(x); y = find(y);\n        if (x != y) {\n            if (rank[x] < rank[y]) swap(x, y);\n            parent[y] = x;\n            if (rank[x] == rank[y]) rank[x]++;\n            return true;\n        }\n        return false;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, Q, L, W;\n    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n    \n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    \n    vector<int> lx(N), rx(N), ly(N), ry(N);\n    vector<long long> cx2(N), cy2(N); // 2 * center coordinates to avoid floats\n    for (int i = 0; i < N; ++i) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n        cx2[i] = lx[i] + rx[i];\n        cy2[i] = ly[i] + ry[i];\n    }\n\n    // Sort cities by estimated center position\n    vector<int> p(N);\n    iota(p.begin(), p.end(), 0);\n    sort(p.begin(), p.end(), [&](int a, int b) {\n        if (cx2[a] != cx2[b]) return cx2[a] < cx2[b];\n        return cy2[a] < cy2[b];\n    });\n\n    // Partition sorted cities into groups of specified sizes\n    vector<vector<int>> groups(M);\n    int idx = 0;\n    for (int i = 0; i < M; ++i) {\n        groups[i].resize(G[i]);\n        for (int j = 0; j < G[i]; ++j) {\n            groups[i][j] = p[idx++];\n        }\n    }\n\n    // Store edges discovered from queries for each group\n    vector<vector<pair<int, int>>> group_edges(M);\n    int q_cnt = 0;\n\n    // Query chunks of each group\n    for (int k = 0; k < M; ++k) {\n        if (groups[k].size() <= 1) continue;\n        \n        for (size_t start = 0; start < groups[k].size(); start += L) {\n            if (q_cnt >= Q) goto finish_queries;\n            \n            size_t end = min(start + L, groups[k].size());\n            size_t len = end - start;\n            if (len < 2) continue;\n\n            cout << \"? \" << len;\n            for (size_t i = start; i < end; ++i) {\n                cout << \" \" << groups[k][i];\n            }\n            cout << \"\\n\";\n            cout.flush();\n            q_cnt++;\n\n            for (size_t i = 0; i < len - 1; ++i) {\n                int u, v;\n                cin >> u >> v;\n                // Judge guarantees u < v, but store consistently\n                if (u > v) swap(u, v);\n                group_edges[k].push_back({u, v});\n            }\n        }\n    }\nfinish_queries:;\n\n    vector<vector<pair<int, int>>> final_edges(M);\n\n    // Complete MST for each group using discovered edges + estimated edges\n    for (int k = 0; k < M; ++k) {\n        if (groups[k].empty()) continue;\n        int sz = groups[k].size();\n        if (sz <= 1) continue;\n\n        DSU dsu(N);\n        // Prioritize edges from queries (they are exact MST edges for their subsets)\n        for (auto& e : group_edges[k]) {\n            if (dsu.unite(e.first, e.second)) {\n                final_edges[k].push_back(e);\n            }\n        }\n\n        if (final_edges[k].size() == sz - 1) continue; // Already fully connected\n\n        // Generate candidate edges based on estimated distances\n        vector<tuple<long long, int, int>> candidates;\n        candidates.reserve(sz * (sz - 1) / 2);\n        \n        for (int i = 0; i < sz; ++i) {\n            for (int j = i + 1; j < sz; ++j) {\n                int u = groups[k][i];\n                int v = groups[k][j];\n                if (dsu.find(u) == dsu.find(v)) continue;\n                long long dx = cx2[u] - cx2[v];\n                long long dy = cy2[u] - cy2[v];\n                // Store squared distance to avoid sqrt and preserve ordering\n                candidates.push_back({dx*dx + dy*dy, u, v});\n            }\n        }\n        sort(candidates.begin(), candidates.end());\n\n        // Kruskal's algorithm to connect remaining components\n        for (auto& c : candidates) {\n            if (final_edges[k].size() == sz - 1) break;\n            auto [w, u, v] = c;\n            if (dsu.unite(u, v)) {\n                final_edges[k].push_back({u, v});\n            }\n        }\n    }\n\n    // Output results\n    cout << \"!\\n\";\n    cout.flush();\n\n    for (int k = 0; k < M; ++k) {\n        for (size_t i = 0; i < groups[k].size(); ++i) {\n            if (i > 0) cout << \" \";\n            cout << groups[k][i];\n        }\n        cout << \"\\n\";\n        for (auto& e : final_edges[k]) {\n            cout << e.first << \" \" << e.second << \"\\n\";\n        }\n    }\n    cout.flush();\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n\n    int start_r, start_c;\n    cin >> start_r >> start_c;\n\n    // Read M-1 target squares\n    vector<pair<int, int>> targets(M - 1);\n    for (int k = 0; k < M - 1; ++k) {\n        cin >> targets[k].first >> targets[k].second;\n    }\n\n    int cur_r = start_r;\n    int cur_c = start_c;\n\n    // Grid state: true if a block is present\n    bool block[20][20] = {};\n    auto is_block = [&](int r, int c) {\n        if (r < 0 || r >= N || c < 0 || c >= N) return true; // Boundaries act as blocks\n        return block[r][c];\n    };\n\n    const int dr[] = {-1, 1, 0, 0};\n    const int dc[] = {0, 0, -1, 1};\n    const char d_name[] = {'U', 'D', 'L', 'R'};\n\n    int dist[20][20];\n    int parent_r[20][20], parent_c[20][20];\n    char act[20][20], dir[20][20];\n\n    struct Node {\n        int f, r, c, g;\n        bool operator>(const Node& other) const { return f > other.f; }\n    };\n\n    const int INF = 1e9;\n\n    for (auto [tr, tc] : targets) {\n        // Initialize distance matrix\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                dist[i][j] = INF;\n\n        priority_queue<Node, vector<Node>, greater<Node>> pq;\n        dist[cur_r][cur_c] = 0;\n        pq.push(Node{abs(cur_r - tr) + abs(cur_c - tc), cur_r, cur_c, 0});\n\n        // A* Search\n        while (!pq.empty()) {\n            auto [f, r, c, g] = pq.top(); pq.pop();\n            if (dist[r][c] < g) continue;\n            if (r == tr && c == tc) break;\n\n            // Try Move\n            for (int d = 0; d < 4; ++d) {\n                int nr = r + dr[d], nc = c + dc[d];\n                if (!is_block(nr, nc)) {\n                    if (dist[nr][nc] > g + 1) {\n                        dist[nr][nc] = g + 1;\n                        parent_r[nr][nc] = r; parent_c[nr][nc] = c;\n                        act[nr][nc] = 'M'; dir[nr][nc] = d_name[d];\n                        int nh = abs(nr - tr) + abs(nc - tc);\n                        pq.push(Node{dist[nr][nc] + nh, nr, nc, g + 1});\n                    }\n                }\n            }\n\n            // Try Slide\n            for (int d = 0; d < 4; ++d) {\n                int nr = r + dr[d], nc = c + dc[d];\n                while (!is_block(nr, nc)) {\n                    nr += dr[d]; nc += dc[d];\n                }\n                nr -= dr[d]; nc -= dc[d]; // Step back to last valid cell\n                if (nr == r && nc == c) continue; // Didn't move\n\n                if (dist[nr][nc] > g + 1) {\n                    dist[nr][nc] = g + 1;\n                    parent_r[nr][nc] = r; parent_c[nr][nc] = c;\n                    act[nr][nc] = 'S'; dir[nr][nc] = d_name[d];\n                    int nh = abs(nr - tr) + abs(nc - tc);\n                    pq.push(Node{dist[nr][nc] + nh, nr, nc, g + 1});\n                }\n            }\n        }\n\n        // Reconstruct path\n        vector<pair<char, char>> path;\n        int r = tr, c = tc;\n        while (r != cur_r || c != cur_c) {\n            path.emplace_back(act[r][c], dir[r][c]);\n            int pr = parent_r[r][c];\n            int pc = parent_c[r][c];\n            r = pr; c = pc;\n        }\n        reverse(path.begin(), path.end());\n\n        // Execute path\n        for (auto [a, d] : path) {\n            cout << a << ' ' << d << '\\n';\n            if (a == 'M') {\n                if (d == 'U') cur_r--;\n                else if (d == 'D') cur_r++;\n                else if (d == 'L') cur_c--;\n                else if (d == 'R') cur_c++;\n            } else if (a == 'S') {\n                if (d == 'U') while (true) { int nr = cur_r - 1; if (is_block(nr, cur_c)) break; cur_r = nr; }\n                else if (d == 'D') while (true) { int nr = cur_r + 1; if (is_block(nr, cur_c)) break; cur_r = nr; }\n                else if (d == 'L') while (true) { int nc = cur_c - 1; if (is_block(cur_r, nc)) break; cur_c = nc; }\n                else if (d == 'R') while (true) { int nc = cur_c + 1; if (is_block(cur_r, nc)) break; cur_c = nc; }\n            }\n        }\n    }\n\n    return 0;\n}"},"4":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <chrono>\n#include <random>\n#include <numeric>\n\nusing namespace std;\n\nstruct Rect { int x1, y1, x2, y2; };\n\nint N;\nvector<int> X, Y;\nvector<long long> R;\nvector<Rect> best_ans;\ndouble best_score = -1.0;\n\ndouble calc_score(const vector<Rect>& rects) {\n    double total = 0.0;\n    for (int i = 0; i < N; ++i) {\n        long long s = (long long)(rects[i].x2 - rects[i].x1) * (rects[i].y2 - rects[i].y1);\n        double ratio = min((long long)R[i], s) / (double)max((long long)R[i], s);\n        total += 1.0 - (1.0 - ratio) * (1.0 - ratio);\n    }\n    return total;\n}\n\nbool validate(const vector<Rect>& rects) {\n    for (int i = 0; i < N; ++i) {\n        // Check bounds\n        if (rects[i].x1 < 0 || rects[i].x2 > 10000 || rects[i].y1 < 0 || rects[i].y2 > 10000) return false;\n        // Check positive area\n        if (rects[i].x1 >= rects[i].x2 || rects[i].y1 >= rects[i].y2) return false;\n        // Check containment of (x_i+0.5, y_i+0.5)\n        // This is equivalent to x1 <= x_i < x2 and y1 <= y_i < y2\n        if (!(rects[i].x1 <= X[i] && X[i] < rects[i].x2 && rects[i].y1 <= Y[i] && Y[i] < rects[i].y2)) return false;\n    }\n    // Non-overlap is guaranteed by the guillotine partition structure\n    return true;\n}\n\nvoid solve(int x1, int y1, int x2, int y2, const vector<int>& ids, vector<Rect>& ans) {\n    if (ids.empty()) return;\n    if (ids.size() == 1) {\n        ans[ids[0]] = {x1, y1, x2, y2};\n        return;\n    }\n\n    struct Candidate { bool vertical; int c; int k; double err; };\n    Candidate best_cand = {false, -1, -1, 1e18};\n    bool found = false;\n\n    // Lambda to check possible cuts along one axis\n    auto check_axis = [&](bool vertical) {\n        vector<int> s = ids;\n        // Sort points based on the axis\n        if (vertical) sort(s.begin(), s.end(), [&](int a, int b){ return X[a] < X[b]; });\n        else sort(s.begin(), s.end(), [&](int a, int b){ return Y[a] < Y[b]; });\n\n        long long cur_r = 0;\n        double len = vertical ? (x2 - x1) : (y2 - y1);\n        // Cannot cut if the dimension size is 1 (need at least 2 to place an integer cut strictly inside)\n        if (len < 2) return;\n\n        int b1 = vertical ? x1 : y1;\n        int b2 = vertical ? x2 : y2;\n\n        // Iterate over all possible split points between sorted points\n        for (int k = 0; k < (int)s.size() - 1; ++k) {\n            cur_r += R[s[k]];\n            // Ideal cut position to match area ratio\n            double ideal = b1 + (double)cur_r / len;\n            \n            int p1 = vertical ? X[s[k]] : Y[s[k]];\n            int p2 = vertical ? X[s[k+1]] : Y[s[k+1]];\n            \n            // Valid integer cut c must satisfy:\n            // 1. Separate points: p1 < c <= p2  => c in [p1+1, p2]\n            // 2. Maintain positive area for children: b1 < c < b2 => c in [b1+1, b2-1]\n            int low = max(p1 + 1, b1 + 1);\n            int high = min(p2, b2 - 1);\n            \n            if (low > high) continue;\n            \n            // Find best integer c in [low, high] close to ideal\n            int c = (int)std::round(ideal);\n            if (c < low) c = low;\n            if (c > high) c = high;\n            \n            double err = std::abs(ideal - c);\n            if (!found || err < best_cand.err) {\n                best_cand = {vertical, c, k, err};\n                found = true;\n            }\n        }\n    };\n\n    check_axis(true);\n    check_axis(false);\n\n    // If no valid cut found, we cannot proceed. \n    // Theoretically shouldn't happen for distinct points in a valid box.\n    if (!found) return;\n\n    // Execute the best cut found\n    vector<int> s = ids;\n    if (best_cand.vertical) sort(s.begin(), s.end(), [&](int a, int b){ return X[a] < X[b]; });\n    else sort(s.begin(), s.end(), [&](int a, int b){ return Y[a] < Y[b]; });\n\n    vector<int> left(s.begin(), s.begin() + best_cand.k + 1);\n    vector<int> right(s.begin() + best_cand.k + 1, s.end());\n\n    if (best_cand.vertical) {\n        solve(x1, y1, best_cand.c, y2, left, ans);\n        solve(best_cand.c, y1, x2, y2, right, ans);\n    } else {\n        solve(x1, y1, x2, best_cand.c, left, ans);\n        solve(x1, best_cand.c, x2, y2, right, ans);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N)) return 0;\n    X.resize(N); Y.resize(N); R.resize(N);\n    for (int i = 0; i < N; ++i) cin >> X[i] >> Y[i] >> R[i];\n\n    best_ans.resize(N);\n    vector<int> ids(N);\n    iota(ids.begin(), ids.end(), 0);\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    auto start = chrono::steady_clock::now();\n\n    // Run solver multiple times with different random permutations\n    // Time limit is 5.0s, we use ~4.8s\n    while (chrono::duration<double>(chrono::steady_clock::now() - start).count() < 4.8) {\n        shuffle(ids.begin(), ids.end(), rng);\n        vector<Rect> current_ans(N, {-1, -1, -1, -1});\n        \n        solve(0, 0, 10000, 10000, ids, current_ans);\n\n        if (validate(current_ans)) {\n            double sc = calc_score(current_ans);\n            if (sc > best_score) {\n                best_score = sc;\n                best_ans = current_ans;\n            }\n        }\n    }\n\n    // Output the best solution found\n    for (int i = 0; i < N; ++i) {\n        cout << best_ans[i].x1 << \" \" << best_ans[i].y1 << \" \"\n             << best_ans[i].x2 << \" \" << best_ans[i].y2 << \"\\n\";\n    }\n    return 0;\n}","ahc002":"#pragma GCC optimize(\"O3,unroll-loops\")\n#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\nusing ll = long long;\n\nint main() {\n    cin.tie(nullptr);\n    ios::sync_with_stdio(false);\n\n    int si, sj;\n    if (!(cin >> si >> sj)) return 0;\n\n    int t[50][50], p[50][50];\n    int M = 0;\n    for (int i = 0; i < 50; ++i)\n        for (int j = 0; j < 50; ++j) {\n            cin >> t[i][j];\n            M = max(M, t[i][j] + 1);\n        }\n    for (int i = 0; i < 50; ++i)\n        for (int j = 0; j < 50; ++j)\n            cin >> p[i][j];\n\n    const int dr[] = {-1, 1, 0, 0};\n    const int dc[] = {0, 0, -1, 1};\n    const char dirs[] = {'U', 'D', 'L', 'R'};\n\n    vector<char> vis(M);\n    vector<char> best_path;\n    ll best_score = -1;\n\n    auto start_t = chrono::steady_clock::now();\n    auto now = [&]() { return chrono::duration<double>(chrono::steady_clock::now() - start_t).count(); };\n    const double TIME_LIMIT = 1.95;\n    mt19937_64 rng(123456789);\n    uniform_real_distribution<double> noise(0.0, 15.0);\n\n    // Fast simulation & extension\n    auto extend = [&](vector<char>& path, int keep_len) -> ll {\n        int r = si, c = sj;\n        fill(vis.begin(), vis.end(), 0);\n        vis[t[r][c]] = 1;\n        ll score = p[r][c];\n\n        for (int i = 0; i < keep_len; ++i) {\n            char d = path[i];\n            if (d == 'U') r--; else if (d == 'D') r++; else if (d == 'L') c--; else c++;\n            vis[t[r][c]] = 1;\n            score += p[r][c];\n        }\n\n        while (true) {\n            double best_h = -1e18;\n            int best_k = -1, nr_best = 0, nc_best = 0;\n            for (int k = 0; k < 4; ++k) {\n                int nr = r + dr[k], nc = c + dc[k];\n                if (nr >= 0 && nr < 50 && nc >= 0 && nc < 50 && !vis[t[nr][nc]]) {\n                    // Count unvisited adjacent tiles (freedom heuristic)\n                    int deg = 0;\n                    for (int d = 0; d < 4; ++d) {\n                        int tr = nr + dr[d], tc = nc + dc[d];\n                        if (tr >= 0 && tr < 50 && tc >= 0 && tc < 50 && !vis[t[tr][tc]]) deg++;\n                    }\n                    double h = (double)p[nr][nc] + deg * 12.0 + noise(rng);\n                    if (h > best_h) {\n                        best_h = h;\n                        best_k = k;\n                        nr_best = nr;\n                        nc_best = nc;\n                    }\n                }\n            }\n            if (best_k == -1) break;\n\n            path.push_back(dirs[best_k]);\n            r = nr_best; c = nc_best;\n            vis[t[r][c]] = 1;\n            score += p[r][c];\n        }\n        return score;\n    };\n\n    // Initial greedy construction\n    vector<char> cur_path;\n    ll cur_score = extend(cur_path, 0);\n    best_path = cur_path;\n    best_score = cur_score;\n\n    // Simulated Annealing: Cut & Regrow\n    double T0 = 80.0;\n    const double T_TARGET = 0.1;\n    int iter = 0;\n    vector<char> nxt_path;\n    nxt_path.reserve(2500);\n\n    while (true) {\n        if ((iter & 4095) == 0 && now() > TIME_LIMIT) break;\n        ++iter;\n\n        double elapsed = now();\n        if (elapsed > TIME_LIMIT) break;\n        double progress = elapsed / TIME_LIMIT;\n        double T = T0 * pow(T_TARGET / T0, progress); // Exponential time-decay\n\n        int sz = cur_path.size();\n        int keep_len = (sz == 0) ? 0 : (rng() % (sz + 1));\n        nxt_path.assign(cur_path.begin(), cur_path.begin() + keep_len);\n        ll nxt_score = extend(nxt_path, keep_len);\n\n        if (nxt_score > best_score) {\n            best_score = nxt_score;\n            best_path = nxt_path;\n        }\n\n        double delta = nxt_score - cur_score;\n        bool accept = false;\n        if (delta >= 0) {\n            accept = true;\n        } else {\n            double ratio = delta / T;\n            if (ratio > -18.0) {\n                double prob = exp(ratio);\n                if (prob > (double)(rng() & 0xFFFFFF) / 16777216.0) {\n                    accept = true;\n                }\n            }\n        }\n\n        if (accept) {\n            cur_score = nxt_score;\n            cur_path = nxt_path;\n        }\n    }\n\n    for (char c : best_path) cout << c;\n    cout << \"\\n\";\n\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Edge weight estimates: h[row][col], v[row][col]\n    // Initialized to the midpoint of the expected range [1000, 9000]\n    double h[30][29], v[29][30];\n    const double INIT_W = 5000.0;\n    for(int i=0; i<30; ++i) for(int j=0; j<29; ++j) h[i][j] = INIT_W;\n    for(int i=0; i<29; ++i) for(int j=0; j<30; ++j) v[i][j] = INIT_W;\n\n    const double ALPHA = 0.12;   // Constant learning rate for exponential score weighting\n    const double BETA = 0.08;    // Spatial smoothing factor for denoising\n    const double MIN_W = 500.0;  // Lower bound (prevents negative/zero weights)\n    const double MAX_W = 9500.0; // Upper bound (matches generation range [1000, 9000])\n\n    int si, sj, ti, tj;\n    for(int k=0; k<1000; ++k) {\n        if(!(cin >> si >> sj >> ti >> tj)) break;\n\n        // Dijkstra's Algorithm with long long distances for precision\n        priority_queue<tuple<long long, int, int>, vector<tuple<long long, int, int>>, greater<>> pq;\n        long long dist[30][30];\n        const long long INF = 4000000000000000000LL;\n        for(int i=0; i<30; ++i) fill(dist[i], dist[i]+30, INF);\n        \n        dist[si][sj] = 0;\n        pq.emplace(0, si, sj);\n\n        int pi[30][30], pj[30][30];\n        char dir[30][30];\n\n        const int di[4] = {-1, 1, 0, 0};\n        const int dj[4] = {0, 0, -1, 1};\n        const char dc[4] = {'U', 'D', 'L', 'R'};\n\n        while(!pq.empty()){\n            auto [d, i, j] = pq.top(); pq.pop();\n            if(d > dist[i][j]) continue;\n            if(i == ti && j == tj) break;\n\n            for(int m=0; m<4; ++m){\n                int ni = i + di[m], nj = j + dj[m];\n                if(ni < 0 || ni >= 30 || nj < 0 || nj >= 30) continue;\n\n                long long w;\n                if(m == 0)      w = (long long)(v[ni][nj] + 0.5); // U\n                else if(m == 1) w = (long long)(v[i][j] + 0.5);   // D\n                else if(m == 2) w = (long long)(h[i][nj] + 0.5);  // L\n                else            w = (long long)(h[i][j] + 0.5);   // R\n\n                if(dist[i][j] + w < dist[ni][nj]){\n                    dist[ni][nj] = dist[i][j] + w;\n                    pi[ni][nj] = i;\n                    pj[ni][nj] = j;\n                    dir[ni][nj] = dc[m];\n                    pq.emplace(dist[ni][nj], ni, nj);\n                }\n            }\n        }\n\n        // Reconstruct path\n        string path; path.reserve(60);\n        int ci = ti, cj = tj;\n        while(!(ci == si && cj == sj)){\n            path += dir[ci][cj];\n            int ni = pi[ci][cj], nj = pj[ci][cj];\n            ci = ni; cj = nj;\n        }\n        reverse(path.begin(), path.end());\n        cout << path << \"\\n\" << flush;\n\n        // Read feedback\n        int L; cin >> L;\n\n        // Calculate estimated path length B using current weights\n        double B = 0.0;\n        ci = si; cj = sj;\n        for(char c : path){\n            if(c == 'U') { B += v[ci-1][cj]; ci--; }\n            else if(c == 'D') { B += v[ci][cj]; ci++; }\n            else if(c == 'L') { B += h[ci][cj-1]; cj--; }\n            else { B += h[ci][cj]; cj++; }\n        }\n\n        // Online gradient descent update: distribute error equally across path edges\n        double delta = ALPHA * (L - B) / (double)path.size();\n        ci = si; cj = sj;\n        for(char c : path){\n            if(c == 'U') { v[ci-1][cj] += delta; ci--; }\n            else if(c == 'D') { v[ci][cj] += delta; ci++; }\n            else if(c == 'L') { h[ci][cj-1] += delta; cj--; }\n            else { h[ci][cj] += delta; cj++; }\n        }\n\n        // Spatial Smoothing (Denoising)\n        // Pulls estimates toward row/column means to exploit problem structure\n        double h_row_mean[30], v_col_mean[30];\n        for(int i=0; i<30; ++i) {\n            double s = 0; for(int j=0; j<29; ++j) s += h[i][j];\n            h_row_mean[i] = s / 29.0;\n        }\n        for(int j=0; j<30; ++j) {\n            double s = 0; for(int i=0; i<29; ++i) s += v[i][j];\n            v_col_mean[j] = s / 29.0;\n        }\n        for(int i=0; i<30; ++i) for(int j=0; j<29; ++j) \n            h[i][j] = h[i][j] * (1.0 - BETA) + h_row_mean[i] * BETA;\n        for(int i=0; i<29; ++i) for(int j=0; j<30; ++j) \n            v[i][j] = v[i][j] * (1.0 - BETA) + v_col_mean[j] * BETA;\n\n        // Clamp weights to valid range to prevent noise divergence\n        for(int i=0; i<30; ++i) for(int j=0; j<29; ++j) \n            h[i][j] = max(MIN_W, min(MAX_W, h[i][j]));\n        for(int i=0; i<29; ++i) for(int j=0; j<30; ++j) \n            v[i][j] = max(MIN_W, min(MAX_W, v[i][j]));\n    }\n    return 0;\n}","ahc004":"#pragma GCC optimize(\"O3,unroll-loops,fast-math\")\n#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <chrono>\n#include <random>\n#include <algorithm>\n#include <cstring>\n\nusing namespace std;\n\nconst int N = 20;\nconst int MAX_M = 800;\nconst int MAX_PLACEMENTS = 650000;\n\nint M;\nint S_len[MAX_M];\nchar S_chars[MAX_M][15];\n\nstruct CellLink {\n    int p_idx;\n    char exp_char;\n};\n\nstruct Placement {\n    int str_id;\n    int len;\n};\n\nvector<Placement> placements;\nvector<CellLink> cell_placements[N][N];\nint placement_matches[MAX_PLACEMENTS];\nint str_full_cnt[MAX_M];\nchar grid[N][N];\nchar best_grid[N][N];\nint total_score = 0;\nint best_score = -1;\n\nmt19937_64 rng;\n\ninline int calc_diff(int r, int c, char new_c, char old_c) {\n    if (new_c == old_c) return 0;\n    int diff = 0;\n    const auto& links = cell_placements[r][c];\n    for (const auto& cl : links) {\n        bool old_match = (old_c == cl.exp_char);\n        bool new_match = (new_c == cl.exp_char);\n        if (old_match == new_match) continue;\n\n        int k = placements[cl.p_idx].str_id;\n        bool was_full = (placement_matches[cl.p_idx] == S_len[k]);\n\n        int cur_matches = placement_matches[cl.p_idx] + (new_match ? 1 : -1);\n        bool is_full = (cur_matches == S_len[k]);\n        \n        if (was_full && !is_full) {\n            if (str_full_cnt[k] == 1) diff--;\n        } else if (!was_full && is_full) {\n            if (str_full_cnt[k] == 0) diff++;\n        }\n    }\n    return diff;\n}\n\ninline void apply_change(int r, int c, char new_c, char old_c, int diff) {\n    grid[r][c] = new_c;\n    total_score += diff;\n    const auto& links = cell_placements[r][c];\n    for (const auto& cl : links) {\n        bool old_match = (old_c == cl.exp_char);\n        bool new_match = (new_c == cl.exp_char);\n        if (old_match == new_match) continue;\n\n        int k = placements[cl.p_idx].str_id;\n        bool was_full = (placement_matches[cl.p_idx] == S_len[k]);\n\n        if (old_match) placement_matches[cl.p_idx]--;\n        else placement_matches[cl.p_idx]++;\n\n        bool is_full = (placement_matches[cl.p_idx] == S_len[k]);\n        if (was_full && !is_full) str_full_cnt[k]--;\n        else if (!was_full && is_full) str_full_cnt[k]++;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    rng.seed(chrono::steady_clock::now().time_since_epoch().count());\n\n    int N_in;\n    if (!(cin >> N_in >> M)) return 0;\n    for (int i = 0; i < M; ++i) {\n        string s;\n        cin >> s;\n        S_len[i] = (int)s.length();\n        memcpy(S_chars[i], s.c_str(), S_len[i] + 1);\n    }\n\n    int p_idx = 0;\n    placements.reserve(MAX_PLACEMENTS);\n    for (int k = 0; k < M; ++k) {\n        int L = S_len[k];\n        // Horizontal placements\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                placements.push_back({k, L});\n                for (int p = 0; p < L; ++p) {\n                    cell_placements[r][(c + p) % N].push_back({p_idx, S_chars[k][p]});\n                }\n                p_idx++;\n            }\n        }\n        // Vertical placements\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                placements.push_back({k, L});\n                for (int pp = 0; pp < L; ++pp) {\n                    cell_placements[(r + pp) % N][c].push_back({p_idx, S_chars[k][pp]});\n                }\n                p_idx++;\n            }\n        }\n    }\n\n    // Greedy initialization\n    int cnt[N][N][8] = {};\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            for (const auto& cl : cell_placements[r][c]) {\n                cnt[r][c][cl.exp_char - 'A']++;\n            }\n            char best_c = 'A';\n            int max_v = -1;\n            for (int x = 0; x < 8; ++x) {\n                if (cnt[r][c][x] > max_v) {\n                    max_v = cnt[r][c][x];\n                    best_c = 'A' + x;\n                }\n            }\n            grid[r][c] = best_c;\n        }\n    }\n\n    // Initialize state\n    int total_placements = placements.size();\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            for (const auto& cl : cell_placements[r][c]) {\n                if (grid[r][c] == cl.exp_char) {\n                    placement_matches[cl.p_idx]++;\n                }\n            }\n        }\n    }\n    for (int i = 0; i < total_placements; ++i) {\n        int k = placements[i].str_id;\n        if (placement_matches[i] == S_len[k]) {\n            str_full_cnt[k]++;\n        }\n    }\n    for (int k = 0; k < M; ++k) {\n        if (str_full_cnt[k] > 0) total_score++;\n    }\n\n    best_score = total_score;\n    memcpy(best_grid, grid, sizeof(grid));\n\n    // Simulated Annealing\n    double T = 2.0;\n    auto start = chrono::steady_clock::now();\n    uniform_int_distribution<int> dist_rc(0, N-1);\n    uniform_int_distribution<int> dist_char(0, 7);\n    uniform_real_distribution<double> prob_dist(0.0, 1.0);\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration_cast<chrono::milliseconds>(now - start).count() / 1000.0;\n        if (elapsed >= 2.85) break;\n\n        T = 2.0 * pow(1e-5 / 2.0, elapsed / 2.85);\n        if (T < 1e-9) T = 1e-9;\n\n        int r = dist_rc(rng);\n        int c = dist_rc(rng);\n        char old_c = grid[r][c];\n        char new_c = 'A' + dist_char(rng);\n        if (new_c == old_c) continue;\n\n        int diff = calc_diff(r, c, new_c, old_c);\n        if (diff > 0 || prob_dist(rng) < exp(diff / T)) {\n            apply_change(r, c, new_c, old_c, diff);\n            if (total_score > best_score) {\n                best_score = total_score;\n                memcpy(best_grid, grid, sizeof(grid));\n                if (best_score == M) break;\n            }\n        }\n    }\n\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            cout << best_grid[r][c];\n        }\n        cout << '\\n';\n    }\n\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\n\nconst int INF = 1e9;\nconst int MAX_ROAD = 5000; // 69*69 = 4761\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, si, sj;\n    if (!(cin >> N >> si >> sj)) return 0;\n    vector<string> grid(N);\n    vector<vector<int>> idx(N, vector<int>(N, -1));\n    vector<pair<int, int>> road_cells;\n    int R = 0;\n    for (int i = 0; i < N; ++i) {\n        cin >> grid[i];\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] != '#') {\n                idx[i][j] = R++;\n                road_cells.emplace_back(i, j);\n            }\n        }\n    }\n    int start_idx = idx[si][sj];\n    auto t0 = chrono::high_resolution_clock::now();\n    auto get_time = [&]() { return chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - t0).count(); };\n\n    // 1. Extract Strategic Candidates (Junctions, Endpoints, Start)\n    struct Point { int r, c, id; };\n    vector<Point> cands;\n    vector<int> cand_to_global(R, -1);\n    int dirs[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};\n    \n    auto add_candidate = [&](int r, int c) {\n        int gid = idx[r][c];\n        if (cand_to_global[gid] == -1) {\n            cand_to_global[gid] = cands.size();\n            cands.push_back({r, c, gid});\n        }\n    };\n\n    add_candidate(si, sj);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] == '#') continue;\n            int road_neighbors = 0;\n            for (auto& d : dirs) {\n                int ni = i + d[0], nj = j + d[1];\n                if (ni >= 0 && ni < N && nj >= 0 && nj < N && grid[ni][nj] != '#') road_neighbors++;\n            }\n            // Junctions (>=3), Endpoints (1), or isolated (0, though graph is connected)\n            if (road_neighbors != 2) add_candidate(i, j);\n            // Also add midpoints of long straight segments to ensure good coverage\n            if (road_neighbors == 2 && (i == 0 || i == N-1 || j == 0 || j == N-1)) add_candidate(i, j);\n        }\n    }\n    int M = cands.size();\n\n    // 2. Precompute Coverage for each candidate\n    vector<bitset<MAX_ROAD>> cov(M);\n    for (int k = 0; k < M; ++k) {\n        int r = cands[k].r, c = cands[k].c;\n        // Horizontal\n        for (int j = c; j >= 0 && grid[r][j] != '#'; --j) cov[k][idx[r][j]] = 1;\n        for (int j = c + 1; j < N && grid[r][j] != '#'; ++j) cov[k][idx[r][j]] = 1;\n        // Vertical\n        for (int i = r - 1; i >= 0 && grid[i][c] != '#'; --i) cov[k][idx[i][c]] = 1;\n        for (int i = r + 1; i < N && grid[i][c] != '#'; ++i) cov[k][idx[i][c]] = 1;\n    }\n\n    // 3. Precompute Pairwise Distances\n    vector<vector<int>> dist(M, vector<int>(M, INF));\n    vector<int> d(N * N);\n    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;\n    \n    for (int i = 0; i < M; ++i) {\n        fill(d.begin(), d.end(), INF);\n        int sr = cands[i].r, sc = cands[i].c;\n        int u0 = sr * N + sc;\n        d[u0] = 0;\n        pq.emplace(0, u0);\n        dist[i][i] = 0;\n\n        while (!pq.empty()) {\n            auto [dst, u] = pq.top(); pq.pop();\n            if (dst > d[u]) continue;\n            int ur = u / N, uc = u % N;\n            if (idx[ur][uc] != -1 && dist[i][cand_to_global[idx[ur][uc]]] == INF)\n                dist[i][cand_to_global[idx[ur][uc]]] = dst;\n\n            for (auto& dr : dirs) {\n                int vr = ur + dr[0], vc = uc + dr[1];\n                if (vr < 0 || vr >= N || vc < 0 || vc >= N || grid[vr][vc] == '#') continue;\n                int v = vr * N + vc;\n                int w = grid[vr][vc] - '0';\n                if (d[u] + w < d[v]) { d[v] = d[u] + w; pq.emplace(d[v], v); }\n            }\n        }\n    }\n\n    // 4. Build Initial Tour (Greedy Coverage/Insertion)\n    vector<int> tour;\n    int start_cand = cand_to_global[start_idx];\n    tour.push_back(start_cand);\n    \n    bitset<MAX_ROAD> covered = cov[start_cand];\n    int uncovered_cnt = R - covered.count();\n    vector<bool> in_tour(M, false);\n    in_tour[start_cand] = true;\n\n    while (uncovered_cnt > 0 && get_time() < 2000) {\n        int best_k = -1, best_pos = 0;\n        double best_ratio = 0.0;\n        \n        for (int k = 0; k < M; ++k) {\n            if (in_tour[k]) continue;\n            bitset<MAX_ROAD> new_cov = cov[k] & ~covered;\n            int gain = new_cov.count();\n            if (gain == 0) continue;\n            \n            for (int i = 0; i < (int)tour.size(); ++i) {\n                int j = tour[(i + 1) % tour.size()];\n                int cost = dist[tour[i]][k] + dist[k][j] - dist[tour[i]][j];\n                if (cost <= 0) continue;\n                double ratio = (double)gain / cost;\n                if (ratio > best_ratio) {\n                    best_ratio = ratio;\n                    best_k = k;\n                    best_pos = i + 1;\n                }\n            }\n        }\n        if (best_k == -1) break;\n        \n        tour.insert(tour.begin() + best_pos, best_k);\n        in_tour[best_k] = true;\n        covered |= cov[best_k];\n        uncovered_cnt = R - covered.count();\n    }\n\n    // 5. Local Search Optimization (2-opt, Or-opt, Remove)\n    bool improved = true;\n    while (improved && get_time() < 2500) {\n        improved = false;\n        // 2-opt\n        for (int i = 0; i < (int)tour.size(); ++i) {\n            for (int j = i + 2; j < (int)tour.size(); ++j) {\n                if (j == (int)tour.size() - 1 && i == 0) continue;\n                int u1 = tour[i], v1 = tour[(i+1)%(int)tour.size()];\n                int u2 = tour[j], v2 = tour[(j+1)%(int)tour.size()];\n                if (dist[u1][v2] + dist[v1][u2] < dist[u1][v1] + dist[u2][v2]) {\n                    reverse(tour.begin() + i + 1, tour.begin() + j + 1);\n                    improved = true;\n                }\n            }\n        }\n        if (improved) continue;\n\n        // Or-opt (relocate 1 or 2 nodes)\n        for (int len = 1; len <= 2; ++len) {\n            for (int i = 0; i < (int)tour.size(); ++i) {\n                int next_i = (i + 1) % tour.size();\n                if (len == 2) next_i = (next_i + 1) % tour.size();\n                \n                int from = tour[i];\n                int to = tour[(next_i + 1) % tour.size()];\n                \n                for (int j = 0; j < (int)tour.size(); ++j) {\n                    if (j == i || j == (i-1+tour.size())%tour.size() || j == next_i) continue;\n                    int insert_pos = (j + 1) % tour.size();\n                    int cost_remove = dist[from][to];\n                    int cost_insert = dist[tour[j]][tour[(i+1)%tour.size()]];\n                    for(int l=0;l<len-1;++l) cost_insert += dist[tour[(i+1+l)%tour.size()]][tour[(i+2+l)%tour.size()]];\n                    cost_insert += dist[tour[(i+len)%tour.size()]][tour[insert_pos]] - dist[tour[j]][tour[insert_pos]];\n                    \n                    if (cost_insert < cost_remove) {\n                        // Perform relocation\n                        vector<int> moved;\n                        for(int l=0;l<len;++l) moved.push_back(tour[(i+1+l)%tour.size()]);\n                        tour.erase(tour.begin() + (i+1), tour.begin() + (i+1+len));\n                        // Handle wrap-around carefully\n                        int insert_idx = (j + 1);\n                        if (insert_idx > (int)tour.size()) insert_idx = tour.size();\n                        tour.insert(tour.begin() + insert_idx, moved.begin(), moved.end());\n                        improved = true;\n                        break;\n                    }\n                }\n                if (improved) break;\n            }\n            if (improved) break;\n        }\n        if (improved) continue;\n\n        // Remove Redundant Nodes\n        for (int i = (int)tour.size() - 1; i >= 0; --i) {\n            int node = tour[i];\n            tour.erase(tour.begin() + i);\n            bitset<MAX_ROAD> test_cov;\n            for (int x : tour) test_cov |= cov[x];\n            if (test_cov.count() == R) {\n                improved = true;\n            } else {\n                tour.insert(tour.begin() + i, node);\n            }\n        }\n    }\n\n    // 6. Path Reconstruction\n    string result = \"\";\n    result.reserve(tour.size() * 20);\n    vector<int> parent(N * N, -1);\n    vector<char> move_char(N * N);\n    char moves[4] = {'U', 'D', 'L', 'R'};\n\n    auto get_path = [&](int from_idx, int to_idx) {\n        if (from_idx == to_idx) return string(\"\");\n        auto [r1, c1] = road_cells[cands[from_idx].id];\n        auto [r2, c2] = road_cells[cands[to_idx].id];\n        if (r1 == r2 && c1 == c2) return string(\"\");\n        \n        fill(d.begin(), d.end(), INF);\n        fill(parent.begin(), parent.end(), -1);\n        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq2;\n        \n        int u0 = r1 * N + c1, target = r2 * N + c2;\n        d[u0] = 0;\n        pq2.emplace(0, u0);\n\n        while (!pq2.empty()) {\n            auto [dst, u] = pq2.top(); pq2.pop();\n            if (dst > d[u]) continue;\n            if (u == target) break;\n            int ur = u / N, uc = u % N;\n            for (int k = 0; k < 4; ++k) {\n                int vr = ur + dirs[k][0], vc = uc + dirs[k][1];\n                if (vr < 0 || vr >= N || vc < 0 || vc >= N || grid[vr][vc] == '#') continue;\n                int v = vr * N + vc;\n                int w = grid[vr][vc] - '0';\n                if (d[u] + w < d[v]) {\n                    d[v] = d[u] + w;\n                    parent[v] = u;\n                    move_char[v] = moves[k];\n                    pq2.emplace(d[v], v);\n                }\n            }\n        }\n        string path = \"\";\n        int curr = target;\n        while (curr != u0) { path += move_char[curr]; curr = parent[curr]; }\n        reverse(path.begin(), path.end());\n        return path;\n    };\n\n    for (int i = 0; i < (int)tour.size(); ++i) {\n        result += get_path(tour[i], tour[(i + 1) % tour.size()]);\n    }\n\n    cout << result << \"\\n\";\n    return 0;\n}","future-contest-2022-qual":"#pragma GCC optimize(\"O3,unroll-loops\")\n#pragma GCC target(\"avx2,fma\")\n\n#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K, R;\n    if (!(cin >> N >> M >> K >> R)) return 0;\n\n    // Task difficulties\n    vector<vector<int>> d(N, vector<int>(K));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < K; ++j)\n            cin >> d[i][j];\n\n    // Dependency graph\n    vector<vector<int>> adj(N);\n    vector<int> in_degree(N, 0);\n    for (int i = 0; i < R; ++i) {\n        int u, v; cin >> u >> v; --u; --v;\n        adj[u].push_back(v);\n        in_degree[v]++;\n    }\n\n    // State tracking\n    vector<vector<double>> est_s(M, vector<double>(K, 10.0)); // Initialize with reasonable mid-range value\n    vector<int> member_task(M, -1);\n    vector<int> member_start_day(M, -1);\n    vector<int> tasks_done(M, 0);\n    vector<bool> task_done(N, false);\n    vector<bool> task_assigned(N, false);\n\n    // Precompute priorities (sum of required skills)\n    vector<long long> priority(N, 0);\n    for (int i = 0; i < N; ++i) {\n        long long s = 0;\n        for (int x : d[i]) s += x;\n        priority[i] = s;\n    }\n\n    // Initially ready tasks (in-degree 0)\n    vector<int> ready;\n    ready.reserve(N);\n    for (int i = 0; i < N; ++i)\n        if (in_degree[i] == 0) ready.push_back(i);\n\n    auto cmp_priority = [&](int a, int b) { return priority[a] > priority[b]; };\n\n    for (int day = 1; day <= 2000; ++day) {\n        int nf;\n        cin >> nf;\n        if (nf == -1) break;\n\n        vector<int> completed_members;\n        completed_members.reserve(nf);\n        for (int i = 0; i < nf; ++i) {\n            int f; cin >> f; --f;\n            completed_members.push_back(f);\n        }\n\n        // Process task completions & update skill estimates\n        for (int f : completed_members) {\n            int tid = member_task[f];\n            int sd = member_start_day[f];\n            if (tid == -1) continue;\n\n            int actual_t = day - sd + 1;\n            task_done[tid] = true;\n            task_assigned[tid] = false;\n            member_task[f] = -1;\n            member_start_day[f] = -1;\n            tasks_done[f]++;\n\n            // Compute prediction error\n            double pred = 0;\n            int def = 0;\n            for (int k = 0; k < K; ++k) {\n                if (d[tid][k] > est_s[f][k]) {\n                    pred += d[tid][k] - est_s[f][k];\n                    def++;\n                }\n            }\n\n            // Online gradient update with noise clipping\n            if (def > 0 && pred > 0.5) {\n                double err = actual_t - pred;\n                double lr = 0.5 / (1.0 + 0.02 * tasks_done[f]);\n                double delta = max(-2.0, min(2.0, err / def));\n                for (int k = 0; k < K; ++k) {\n                    if (d[tid][k] > est_s[f][k]) {\n                        est_s[f][k] += lr * delta;\n                        if (est_s[f][k] < 0) est_s[f][k] = 0;\n                        if (est_s[f][k] > 80) est_s[f][k] = 80;\n                    }\n                }\n            }\n\n            // Release dependencies\n            for (int v : adj[tid]) {\n                if (--in_degree[v] == 0) {\n                    ready.push_back(v);\n                }\n            }\n        }\n\n        // Collect free members\n        vector<int> free_ms;\n        free_ms.reserve(M);\n        for (int m = 0; m < M; ++m)\n            if (member_task[m] == -1) free_ms.push_back(m);\n\n        // Sort ready tasks by difficulty descending\n        sort(ready.begin(), ready.end(), cmp_priority);\n\n        vector<pair<int, int>> out_assign;\n        out_assign.reserve(free_ms.size());\n        vector<int> next_ready;\n        next_ready.reserve(ready.size());\n\n        // Greedy assignment: highest priority task to best fitting free member\n        for (int t : ready) {\n            if (task_assigned[t] || task_done[t]) continue;\n            if (free_ms.empty()) {\n                next_ready.push_back(t);\n                continue;\n            }\n\n            int best_m = -1;\n            double best_et = 1e18;\n            for (int m : free_ms) {\n                double w = 0;\n                const auto& dt = d[t];\n                const auto& es = est_s[m];\n                for (int k = 0; k < K; ++k) {\n                    if (dt[k] > es[k]) w += dt[k] - es[k];\n                }\n                double et = (w > 0) ? w : 1.0;\n                if (et < best_et) {\n                    best_et = et;\n                    best_m = m;\n                }\n            }\n\n            if (best_m != -1) {\n                member_task[best_m] = t;\n                member_start_day[best_m] = day;\n                task_assigned[t] = true;\n                out_assign.push_back({best_m, t});\n                \n                // Remove used member from free list\n                for (auto it = free_ms.begin(); it != free_ms.end(); ++it) {\n                    if (*it == best_m) { free_ms.erase(it); break; }\n                }\n            } else {\n                next_ready.push_back(t);\n            }\n        }\n        ready = next_ready;\n\n        // Output assignments\n        cout << out_assign.size();\n        for (auto& p : out_assign) {\n            cout << \" \" << p.first + 1 << \" \" << p.second + 1;\n        }\n        cout << \"\\n\" << flush;\n    }\n\n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <chrono>\n#include <random>\n#include <numeric>\n#include <iomanip>\n\nusing namespace std;\n\n// ==================== Geometry & Helpers ====================\nstruct Pt { int x, y; };\ninline int dist(const Pt& a, const Pt& b) { return abs(a.x - b.x) + abs(a.y - b.y); }\n\nconst Pt BASE = {400, 400};\n\nstruct Order {\n    int id; // 1-based index\n    Pt p, d; // pickup, delivery\n};\n\nvector<Order> all_orders(1000);\nint sel_ids[50];          // Selected order indices (1-based)\nPt sp[50], sd[50];        // Selected pickup/delivery coordinates\nvector<int> route;        // Route stores 0..49 (pickup), 50..99 (delivery)\n\ninline Pt get_pt(int idx) {\n    return idx < 50 ? sp[idx] : sd[idx - 50];\n}\n\n// ==================== Core Functions ====================\nint calc_cost(const vector<int>& r) {\n    int c = dist(BASE, get_pt(r[0]));\n    for (int i = 0; i < 99; ++i) c += dist(get_pt(r[i]), get_pt(r[i+1]));\n    c += dist(get_pt(r[99]), BASE);\n    return c;\n}\n\nbool check_precedence(const vector<int>& r) {\n    int pos[50]; fill(pos, pos + 50, -1);\n    for (int i = 0; i < 100; ++i) {\n        if (r[i] < 50) pos[r[i]] = i;\n        else if (pos[r[i] - 50] == -1 || pos[r[i] - 50] >= i) return false;\n    }\n    return true;\n}\n\n// ==================== Phase 1: Greedy Construction ====================\nvoid build_initial_route() {\n    route.clear();\n    vector<bool> in_pickup(50, false), in_delivery(50, false);\n    int placed = 0;\n\n    while (placed < 100) {\n        int best_pos = -1, best_pt = -1;\n        int min_delta = 2e9;\n\n        // Try inserting any available pickup or valid delivery\n        for (int p = 0; p < 50; ++p) {\n            if (in_pickup[p] || in_delivery[p]) continue;\n            int pt = p; // pickup\n            for (int pos = 0; pos <= placed; ++pos) {\n                int delta;\n                if (placed == 0) delta = dist(BASE, get_pt(pt)) + dist(get_pt(pt), BASE) - dist(BASE, BASE);\n                else {\n                    Pt prev = (pos == 0) ? BASE : get_pt(route[pos - 1]);\n                    Pt next = (pos == placed) ? BASE : get_pt(route[pos]);\n                    delta = dist(prev, get_pt(pt)) + dist(get_pt(pt), next) - dist(prev, next);\n                }\n                if (delta < min_delta) { min_delta = delta; best_pos = pos; best_pt = pt; }\n            }\n        }\n        for (int p = 0; p < 50; ++p) {\n            if (!in_pickup[p] || in_delivery[p]) continue;\n            int pt = p + 50; // delivery\n            for (int pos = 0; pos <= placed; ++pos) {\n                int delta;\n                if (placed == 0) delta = dist(BASE, get_pt(pt)) + dist(get_pt(pt), BASE);\n                else {\n                    Pt prev = (pos == 0) ? BASE : get_pt(route[pos - 1]);\n                    Pt next = (pos == placed) ? BASE : get_pt(route[pos]);\n                    delta = dist(prev, get_pt(pt)) + dist(get_pt(pt), next) - dist(prev, next);\n                }\n                if (delta < min_delta) { min_delta = delta; best_pos = pos; best_pt = pt; }\n            }\n        }\n\n        route.insert(route.begin() + best_pos, best_pt);\n        if (best_pt < 50) in_pickup[best_pt] = true;\n        else in_delivery[best_pt - 50] = true;\n        placed++;\n    }\n}\n\n// ==================== Phase 2: Local Search (2-opt & Relocate) ====================\nauto start_time = chrono::steady_clock::now();\ninline double elapsed() {\n    return chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n}\n\nvoid run_local_search(double time_budget) {\n    bool improved = true;\n    double deadline = elapsed() + time_budget;\n    while (improved && elapsed() < deadline) {\n        improved = false;\n        \n        // 2-opt\n        for (int l = 0; l < 99 && elapsed() < deadline; ++l) {\n            for (int r = l + 1; r < 100; ++r) {\n                vector<int> tmp = route;\n                reverse(tmp.begin() + l, tmp.begin() + r + 1);\n                \n                int old_c = calc_cost(route);\n                int new_c = calc_cost(tmp);\n                \n                if (new_c < old_c && check_precedence(tmp)) {\n                    route = tmp;\n                    improved = true;\n                    goto next_iter;\n                }\n            }\n        }\n        \n        // Relocate\n        for (int i = 0; i < 100 && elapsed() < deadline; ++i) {\n            for (int j = 0; j < 100; ++j) {\n                if (i == j || i == j + 1) continue;\n                vector<int> tmp = route;\n                int pt = tmp[i];\n                tmp.erase(tmp.begin() + i);\n                tmp.insert(tmp.begin() + j, pt);\n                \n                int old_c = calc_cost(route);\n                int new_c = calc_cost(tmp);\n                \n                if (new_c < old_c && check_precedence(tmp)) {\n                    route = tmp;\n                    improved = true;\n                    goto next_iter;\n                }\n            }\n        }\n        next_iter:;\n    }\n}\n\n// ==================== Phase 3: Order Swapping ====================\nvoid run_order_swap(double time_budget) {\n    mt19937 rng(42);\n    double deadline = elapsed() + time_budget;\n    int best_cost = calc_cost(route);\n    \n    while (elapsed() < deadline) {\n        int in_idx = rng() % 50;\n        int out_idx;\n        do { out_idx = rng() % 1000; } while (find(sel_ids, sel_ids + 50, out_idx) != sel_ids + 50);\n        \n        // Try swapping\n        vector<int> old_route = route;\n        int old_id = sel_ids[in_idx];\n        sel_ids[in_idx] = out_idx + 1; // store 1-based\n        sp[in_idx] = all_orders[out_idx].p;\n        sd[in_idx] = all_orders[out_idx].d;\n        \n        // Remove old order points\n        route.erase(remove_if(route.begin(), route.end(), [&](int x) { return x == in_idx || x == in_idx + 50; }), route.end());\n        \n        // Insert new order points\n        vector<int> tmp = route;\n        // Insert pickup\n        int best_p_pos = -1, min_pd = 2e9;\n        for (int pos = 0; pos <= 98; ++pos) {\n            int delta = dist(pos == 0 ? BASE : get_pt(tmp[pos-1]), get_pt(in_idx)) +\n                        dist(get_pt(in_idx), pos == 98 ? BASE : get_pt(tmp[pos])) -\n                        dist(pos == 0 ? BASE : get_pt(tmp[pos-1]), pos == 98 ? BASE : get_pt(tmp[pos]));\n            if (delta < min_pd) { min_pd = delta; best_p_pos = pos; }\n        }\n        tmp.insert(tmp.begin() + best_p_pos, in_idx);\n        \n        // Insert delivery (must be after pickup)\n        int pickup_pos = best_p_pos;\n        int best_d_pos = -1, min_dd = 2e9;\n        for (int pos = pickup_pos + 1; pos <= 99; ++pos) {\n            int delta = dist(pos == 0 ? BASE : get_pt(tmp[pos-1]), get_pt(in_idx+50)) +\n                        dist(get_pt(in_idx+50), pos == 100 ? BASE : get_pt(tmp[pos])) -\n                        dist(pos == 0 ? BASE : get_pt(tmp[pos-1]), pos == 100 ? BASE : get_pt(tmp[pos]));\n            if (delta < min_dd) { min_dd = delta; best_d_pos = pos; }\n        }\n        tmp.insert(tmp.begin() + best_d_pos, in_idx + 50);\n        \n        int new_cost = calc_cost(tmp);\n        if (new_cost < best_cost) {\n            route = tmp;\n            best_cost = new_cost;\n            run_local_search(0.05); // Quick polish\n        } else {\n            // Revert\n            route = old_route;\n            sel_ids[in_idx] = old_id;\n            // Restore coordinates\n            for (int k = 0; k < 50; ++k) {\n                sp[k] = all_orders[sel_ids[k]-1].p;\n                sd[k] = all_orders[sel_ids[k]-1].d;\n            }\n        }\n    }\n}\n\n// ==================== Main ====================\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    for (int i = 0; i < 1000; ++i) {\n        cin >> all_orders[i].p.x >> all_orders[i].p.y >> all_orders[i].d.x >> all_orders[i].d.y;\n        all_orders[i].id = i + 1;\n    }\n    \n    // Initial Selection: 50 orders with pickups closest to base\n    vector<pair<int, int>> dists;\n    for (int i = 0; i < 1000; ++i) {\n        dists.emplace_back(dist(BASE, all_orders[i].p), i);\n    }\n    nth_element(dists.begin(), dists.begin() + 50, dists.end());\n    for (int i = 0; i < 50; ++i) {\n        int id = dists[i].second;\n        sel_ids[i] = all_orders[id].id;\n        sp[i] = all_orders[id].p;\n        sd[i] = all_orders[id].d;\n    }\n    \n    build_initial_route();\n    \n    // Phase 2: Intensive Route Optimization\n    run_local_search(0.8);\n    \n    // Phase 3: Order Set Optimization\n    run_order_swap(1.0);\n    \n    // Final Polish\n    run_local_search(0.2);\n    \n    // Output\n    cout << \"50\";\n    for (int i = 0; i < 50; ++i) cout << \" \" << sel_ids[i];\n    cout << \"\\n\";\n    \n    vector<Pt> out_path;\n    out_path.push_back(BASE);\n    for (int p : route) out_path.push_back(get_pt(p));\n    out_path.push_back(BASE);\n    \n    cout << out_path.size();\n    for (auto& p : out_path) cout << \" \" << p.x << \" \" << p.y;\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <utility>\n\nusing namespace std;\n\n// Disjoint Set Union (DSU) with path compression\nstruct DSU {\n    vector<int> parent;\n    DSU(int n) : parent(n) {\n        for (int i = 0; i < n; ++i) parent[i] = i;\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        i = find(i); j = find(j);\n        if (i != j) {\n            parent[i] = j;\n            return true;\n        }\n        return false;\n    }\n};\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 400;\n    const int M = 1995;\n\n    // 1. Read vertex coordinates\n    vector<pair<int, int>> coords(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n\n    // 2. Read edge endpoints and precompute d_i\n    vector<pair<int, int>> edges(M);\n    vector<int> d(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> edges[i].first >> edges[i].second;\n        long long dx = coords[edges[i].first].first - coords[edges[i].second].first;\n        long long dy = coords[edges[i].first].second - coords[edges[i].second].second;\n        // Euclidean distance rounded to nearest integer\n        d[i] = static_cast<int>(round(sqrt(dx * dx + dy * dy)));\n    }\n\n    DSU dsu(N);\n    const int INF = 1e9;\n\n    // 3. Process edges online\n    for (int i = 0; i < M; ++i) {\n        int l;\n        cin >> l;\n\n        int u = edges[i].first;\n        int v = edges[i].second;\n        int ru = dsu.find(u);\n        int rv = dsu.find(v);\n\n        if (ru == rv) {\n            // Already connected, accepting would form a cycle. Reject.\n            cout << \"0\\n\";\n        } else {\n            // Look ahead to find the minimum base distance of future edges\n            // that connect the current components ru and rv.\n            int best_d = INF;\n            for (int j = i + 1; j < M; ++j) {\n                int rju = dsu.find(edges[j].first);\n                int rjv = dsu.find(edges[j].second);\n                if ((rju == ru && rjv == rv) || (rju == rv && rjv == ru)) {\n                    if (d[j] < best_d) best_d = d[j];\n                }\n            }\n\n            // Heuristic threshold: accept if current cost is significantly lower\n            // than the scaled expectation of the best future option.\n            // Threshold 1.8 balances risk and expectation (E[l] = 2*d).\n            if (best_d == INF || l * 5 < best_d * 9) {\n                cout << \"1\\n\";\n                dsu.unite(ru, rv);\n            } else {\n                cout << \"0\\n\";\n            }\n        }\n        // Interactive requirement: flush output after each decision\n        cout.flush();\n    }\n\n    return 0;\n}","ahc008":"#pragma GCC optimize(\"O2\")\n#include <iostream>\n#include <vector>\n#include <string>\n#include <cstring>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nconst int H = 30, W = 30;\nint grid[H][W]; // 0: passable, 1: blocked\nstruct Pos { int x, y; };\nvector<Pos> pets;\nvector<Pos> humans;\n\ninline bool in_bounds(int x, int y) {\n    return x >= 0 && x < H && y >= 0 && y < W;\n}\n\n// Optimized BFS to compute component size and pet count from (sx, sy)\npair<int, int> bfs(int sx, int sy, const int g[H][W], const vector<Pos>& cur_pets) {\n    static int vis[H][W] = {0};\n    static int token = 0;\n    token++;\n    // Safety reset for token if it approaches limits\n    if (token > 1000000000) {\n        memset(vis, 0, sizeof(vis));\n        token = 1;\n    }\n\n    // Static array-based queue avoids heap allocation overhead\n    static pair<int,int> q[900];\n    int head = 0, tail = 0;\n    q[tail++] = {sx, sy};\n    vis[sx][sy] = token;\n    int sz = 0;\n\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    while(head < tail){\n        auto [cx, cy] = q[head++];\n        sz++;\n        for(int i=0; i<4; i++){\n            int nx = cx + dx[i], ny = cy + dy[i];\n            if(in_bounds(nx, ny) && vis[nx][ny] != token && g[nx][ny] == 0){\n                vis[nx][ny] = token;\n                q[tail++] = {nx, ny};\n            }\n        }\n    }\n    int np = 0;\n    for(auto& p : cur_pets){\n        if(vis[p.x][p.y] == token) np++;\n    }\n    return {sz, np};\n}\n\nbool can_block_target(int tx, int ty, int hx, int hy) {\n    if(!in_bounds(tx, ty)) return false;\n    if(grid[tx][ty] == 1) return true; // Already blocked\n    \n    // Target cannot contain pets or humans (except the actor)\n    for(auto& p : pets) if(p.x == tx && p.y == ty) return false;\n    for(const auto& h : humans){\n        if(h.x == tx && h.y == ty && !(h.x == hx && h.y == hy)) return false;\n    }\n    // Target's adjacent squares cannot contain pets\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    for(int i=0; i<4; i++){\n        int nx = tx + dx[i], ny = ty + dy[i];\n        if(in_bounds(nx, ny)){\n            for(auto& p : pets) if(p.x == nx && p.y == ny) return false;\n        }\n    }\n    return true;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N; cin >> N;\n    pets.resize(N);\n    vector<int> pet_types(N);\n    for(int i=0; i<N; i++) {\n        cin >> pets[i].x >> pets[i].y >> pet_types[i];\n        pets[i].x--; pets[i].y--;\n    }\n    int M; cin >> M;\n    humans.resize(M);\n    for(int i=0; i<M; i++) {\n        cin >> humans[i].x >> humans[i].y;\n        humans[i].x--; humans[i].y--;\n    }\n\n    // Initialize grid\n    for(int i=0; i<H; i++) for(int j=0; j<W; j++) grid[i][j] = 0;\n\n    const char acts[] = {'.', 'U', 'D', 'L', 'R', 'u', 'd', 'l', 'r'};\n    // Fixed direction mapping: moves and blocks share the same directional offsets\n    const int ddx[9] = {0, -1, 1, 0, 0, -1, 1, 0, 0};\n    const int ddy[9] = {0, 0, 0, -1, 1, 0, 0, -1, 1};\n    const bool is_block_act[9] = {false, false, false, false, false, true, true, true, true};\n\n    for(int turn=0; turn<300; turn++){\n        string res = \"\";\n        vector<char> my_acts(M);\n\n        // Evaluate best action for each human independently\n        for(int i=0; i<M; i++){\n            int hx = humans[i].x, hy = humans[i].y;\n            double best_val = -1.0;\n            char best_a = '.';\n            bool best_blk_effective = false;\n\n            for(int a=0; a<9; a++){\n                if(a == 0) {\n                    // Stay action, always valid\n                } else {\n                    int tx = hx + ddx[a];\n                    int ty = hy + ddy[a];\n                    if(!in_bounds(tx, ty)) continue;\n                    if(is_block_act[a]){\n                        if(!can_block_target(tx, ty, hx, hy)) continue;\n                    } else {\n                        if(grid[tx][ty] != 0) continue; // Move target must be passable\n                    }\n                }\n\n                // Simulate action on a temporary grid\n                int tmp_grid[H][W];\n                memcpy(tmp_grid, grid, sizeof(tmp_grid));\n                Pos tmp_human = humans[i];\n                bool effective_blk = false;\n\n                if(a == 0) {\n                    // stay\n                } else if(is_block_act[a]) {\n                    int tx = hx + ddx[a], ty = hy + ddy[a];\n                    if(tmp_grid[tx][ty] == 0) {\n                        tmp_grid[tx][ty] = 1;\n                        effective_blk = true;\n                    }\n                } else {\n                    tmp_human.x += ddx[a];\n                    tmp_human.y += ddy[a];\n                }\n\n                auto [sz, np] = bfs(tmp_human.x, tmp_human.y, tmp_grid, pets);\n                double val = sz / (double)(1LL << np);\n                \n                // Greedy selection with tie-breaking favoring wall construction\n                if(val > best_val + 1e-9 || (abs(val - best_val) < 1e-9 && effective_blk && !best_blk_effective)){\n                    best_val = val;\n                    best_a = acts[a];\n                    best_blk_effective = effective_blk;\n                }\n            }\n            my_acts[i] = best_a;\n        }\n\n        // Output actions\n        for(char c : my_acts) res += c;\n        cout << res << \"\\n\";\n        cout.flush();\n\n        // Read pet movements for this turn\n        for(int i=0; i<N; i++){\n            string mv; cin >> mv;\n            int cx = pets[i].x, cy = pets[i].y;\n            for(char c : mv){\n                int nx = cx, ny = cy;\n                if(c=='U') nx--;\n                else if(c=='D') nx++;\n                else if(c=='L') ny--;\n                else if(c=='R') ny++;\n\n                if(in_bounds(nx, ny) && grid[nx][ny] == 0){\n                    cx = nx; cy = ny;\n                } else {\n                    break; // Invalid move, pet stays in current cell\n                }\n            }\n            pets[i].x = cx; pets[i].y = cy;\n        }\n\n        // Update local state to match judge's simultaneous execution\n        // 1. Apply blocks first (blocks take precedence over moves)\n        for(int i=0; i<M; i++){\n            int a_idx = -1;\n            for(int k=0; k<9; k++) if(acts[k] == my_acts[i]) { a_idx = k; break; }\n            if(a_idx != -1 && is_block_act[a_idx]){\n                int tx = humans[i].x + ddx[a_idx];\n                int ty = humans[i].y + ddy[a_idx];\n                if(in_bounds(tx, ty) && grid[tx][ty] == 0){\n                    grid[tx][ty] = 1;\n                }\n            }\n        }\n        // 2. Apply moves\n        vector<Pos> next_humans(M);\n        for(int i=0; i<M; i++){\n            int a_idx = -1;\n            for(int k=0; k<9; k++) if(acts[k] == my_acts[i]) { a_idx = k; break; }\n            next_humans[i] = humans[i];\n            if(a_idx != -1 && !is_block_act[a_idx] && my_acts[i] != '.'){\n                int nx = humans[i].x + ddx[a_idx];\n                int ny = humans[i].y + ddy[a_idx];\n                if(in_bounds(nx, ny) && grid[nx][ny] == 0){\n                    next_humans[i] = {nx, ny};\n                }\n            }\n        }\n        humans = next_humans;\n    }\n\n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cstring>\n#include <queue>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n\n#pragma GCC optimize(\"O3,unroll-loops\")\n#pragma GCC target(\"sse4.2\")\n\nusing namespace std;\n\n// Global arrays for cache locality\nint nxt[400][4];\nbool blocked[400][4];\ndouble dp[201][400];\ndouble head_score[201];\ndouble cur_dp[201][400];\n\n// BFS initialization\nstring get_bfs_path(int s_i, int s_j, int t_i, int t_j, const vector<string>& h, const vector<string>& v) {\n    static int dist[20][20], pi[20][20], pj[20][20];\n    memset(dist, -1, sizeof(dist));\n    queue<pair<int,int>> q;\n    q.push({s_i, s_j});\n    dist[s_i][s_j] = 0;\n    int dr[] = {-1, 1, 0, 0};\n    int dc[] = {0, 0, -1, 1};\n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        if (r == t_i && c == t_j) break;\n        for (int k = 0; k < 4; ++k) {\n            int nr = r + dr[k], nc = c + dc[k];\n            if (nr < 0 || nr >= 20 || nc < 0 || nc >= 20) continue;\n            bool wall = false;\n            if (k == 0) wall = (v[r-1][c] == '1');\n            else if (k == 1) wall = (v[r][c] == '1');\n            else if (k == 2) wall = (h[r][c-1] == '1');\n            else if (k == 3) wall = (h[r][c] == '1');\n            if (!wall && dist[nr][nc] == -1) {\n                dist[nr][nc] = dist[r][c] + 1;\n                pi[nr][nc] = r; pj[nr][nc] = c;\n                q.push({nr, nc});\n            }\n        }\n    }\n    string path = \"\";\n    int r = t_i, c = t_j;\n    while (r != s_i || c != s_j) {\n        int pr = pi[r][c], pc = pj[r][c];\n        if (pr == r) path += (pc < c ? 'R' : 'L');\n        else path += (pr < r ? 'D' : 'U');\n        r = pr; c = pc;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n// Full DP evaluation (used for initialization & restart)\ndouble evaluate_full(const string& s, int start_idx, int target_idx, double p, double move_prob, double* hs) {\n    memset(dp, 0, sizeof(dp));\n    dp[0][start_idx] = 1.0;\n    double acc = 0.0;\n    hs[0] = 0.0;\n    for (int t = 0; t < 200; ++t) {\n        int d = (s[t] == 'U' ? 0 : s[t] == 'D' ? 1 : s[t] == 'L' ? 2 : 3);\n        double prev_target = dp[t][target_idx];\n        for (int idx = 0; idx < 400; ++idx) {\n            double prob = dp[t][idx];\n            if (prob < 1e-18) continue;\n            if (idx == target_idx) {\n                dp[t+1][target_idx] += prob;\n            } else {\n                dp[t+1][idx] += prob * p;\n                if (blocked[idx][d]) dp[t+1][idx] += prob * move_prob;\n                else dp[t+1][nxt[idx][d]] += prob * move_prob;\n            }\n        }\n        double reach = dp[t+1][target_idx] - prev_target;\n        acc += (400.0 - t) * reach;\n        hs[t+1] = acc;\n    }\n    return acc;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int s_i, s_j, t_i, t_j;\n    double p;\n    if (!(cin >> s_i >> s_j >> t_i >> t_j >> p)) return 0;\n\n    vector<string> h(20), v(19);\n    for (int i = 0; i < 20; ++i) cin >> h[i];\n    for (int i = 0; i < 19; ++i) cin >> v[i];\n\n    // Precompute transition tables\n    for (int r = 0; r < 20; ++r) {\n        for (int c = 0; c < 20; ++c) {\n            int idx = r * 20 + c;\n            if (r > 0 && v[r-1][c] == '0') { nxt[idx][0] = (r-1)*20+c; blocked[idx][0] = false; }\n            else { nxt[idx][0] = idx; blocked[idx][0] = true; }\n            if (r < 19 && v[r][c] == '0') { nxt[idx][1] = (r+1)*20+c; blocked[idx][1] = false; }\n            else { nxt[idx][1] = idx; blocked[idx][1] = true; }\n            if (c > 0 && h[r][c-1] == '0') { nxt[idx][2] = r*20+(c-1); blocked[idx][2] = false; }\n            else { nxt[idx][2] = idx; blocked[idx][2] = true; }\n            if (c < 19 && h[r][c] == '0') { nxt[idx][3] = r*20+(c+1); blocked[idx][3] = false; }\n            else { nxt[idx][3] = idx; blocked[idx][3] = true; }\n        }\n    }\n\n    int start_idx = s_i * 20 + s_j;\n    int target_idx = t_i * 20 + t_j;\n    double move_prob = 1.0 - p;\n\n    string path = get_bfs_path(s_i, s_j, t_i, t_j, h, v);\n    string s = \"\";\n    s.reserve(200);\n    int plen = path.empty() ? 1 : path.size();\n    for (int i = 0; i < 200; ++i) s += path[i % plen];\n\n    double best_score = evaluate_full(s, start_idx, target_idx, p, move_prob, head_score);\n    double cur_score = best_score;\n    string best_s = s;\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist_pos(0, 199);\n    uniform_int_distribution<int> dist_char(0, 3);\n    uniform_real_distribution<double> dist_uni(0.0, 1.0);\n    char dirs[] = {'U', 'D', 'L', 'R'};\n\n    // Calibrate Temperature based on initial mutation variance\n    double sum_abs_delta = 0;\n    string tmp_s = s;\n    for(int k=0; k<1000; ++k) {\n        int pos = dist_pos(rng);\n        char old = tmp_s[pos];\n        tmp_s[pos] = dirs[dist_char(rng)];\n        double tail_acc = 0;\n        memcpy(&cur_dp[pos][0], &dp[pos][0], sizeof(double)*400);\n        memset(&cur_dp[pos+1][0], 0, sizeof(double)*400*(200-pos));\n        for (int t = pos; t < 200; ++t) {\n            int d = (tmp_s[t] == 'U' ? 0 : tmp_s[t] == 'D' ? 1 : tmp_s[t] == 'L' ? 2 : 3);\n            double pt = cur_dp[t][target_idx];\n            for (int idx = 0; idx < 400; ++idx) {\n                double prob = cur_dp[t][idx];\n                if (prob < 1e-18) continue;\n                if (idx == target_idx) cur_dp[t+1][target_idx] += prob;\n                else {\n                    cur_dp[t+1][idx] += prob * p;\n                    if (blocked[idx][d]) cur_dp[t+1][idx] += prob * move_prob;\n                    else cur_dp[t+1][nxt[idx][d]] += prob * move_prob;\n                }\n            }\n            tail_acc += (400.0 - t) * (cur_dp[t+1][target_idx] - pt);\n        }\n        double sc = head_score[pos] + tail_acc;\n        sum_abs_delta += abs(sc - cur_score);\n        tmp_s[pos] = old;\n    }\n    double T = max(100.0, (sum_abs_delta / 1000.0) * 12.0);\n    double T_start = T;\n\n    auto start_time = chrono::steady_clock::now();\n    int iter = 0;\n    int improve_iter = 0;\n    const double TIME_LIMIT = 1.85;\n    const int STAGNATION_LIMIT = 15000;\n\n    while (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() < TIME_LIMIT) {\n        double progress = chrono::duration<double>(chrono::steady_clock::now() - start_time).count() / TIME_LIMIT;\n        T = T_start * pow(1.0 - progress, 2.5);\n        if (T < 0.1) T = 0.1;\n\n        int pos = dist_pos(rng);\n        char old_c = s[pos];\n        char new_c = dirs[dist_char(rng)];\n        if (new_c == old_c) { iter++; continue; }\n        s[pos] = new_c;\n\n        // Incremental DP from changed position\n        memcpy(&cur_dp[pos][0], &dp[pos][0], sizeof(double)*400);\n        memset(&cur_dp[pos+1][0], 0, sizeof(double)*400*(200-pos));\n        double tail_acc = 0;\n        for (int t = pos; t < 200; ++t) {\n            int d = (s[t] == 'U' ? 0 : s[t] == 'D' ? 1 : s[t] == 'L' ? 2 : 3);\n            double pt = cur_dp[t][target_idx];\n            for (int idx = 0; idx < 400; ++idx) {\n                double prob = cur_dp[t][idx];\n                if (prob < 1e-18) continue;\n                if (idx == target_idx) cur_dp[t+1][target_idx] += prob;\n                else {\n                    cur_dp[t+1][idx] += prob * p;\n                    if (blocked[idx][d]) cur_dp[t+1][idx] += prob * move_prob;\n                    else cur_dp[t+1][nxt[idx][d]] += prob * move_prob;\n                }\n            }\n            tail_acc += (400.0 - t) * (cur_dp[t+1][target_idx] - pt);\n        }\n        double total_new_score = head_score[pos] + tail_acc;\n        double delta = total_new_score - cur_score;\n\n        if (delta > 0 || dist_uni(rng) < exp(delta / T)) {\n            cur_score = total_new_score;\n            memcpy(&dp[pos+1][0], &cur_dp[pos+1][0], sizeof(double)*400*(200-pos));\n            \n            // Update head_score for consistency\n            double running = head_score[pos];\n            for (int t = pos; t < 200; ++t) {\n                double reach = dp[t+1][target_idx] - dp[t][target_idx];\n                running += (400.0 - t) * reach;\n                head_score[t+1] = running;\n            }\n            \n            if (total_new_score > best_score) {\n                best_score = total_new_score;\n                best_s = s;\n                improve_iter = iter;\n            }\n        } else {\n            s[pos] = old_c;\n        }\n        iter++;\n\n        // Stagnation restart\n        if (iter - improve_iter > STAGNATION_LIMIT) {\n            s = best_s;\n            cur_score = best_score;\n            // Mutate a portion of the string to explore new basins\n            for(int k=0; k<25; ++k) {\n                s[dist_pos(rng)] = dirs[dist_char(rng)];\n            }\n            best_score = evaluate_full(s, start_idx, target_idx, p, move_prob, head_score);\n            cur_score = best_score;\n            T = T_start * 0.4; // Partial reheat\n            improve_iter = iter;\n        }\n    }\n\n    cout << best_s << \"\\n\";\n    return 0;\n}","ahc010":"#include <iostream>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <cstring>\n#include <cstdint>\n\nusing namespace std;\n\nconst int H = 30, W = 30, N = H * W, S = N * 4;\n\n// Directions: 0:L, 1:U, 2:R, 3:D\nconst int di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n\n// to_table[type][enter_dir] -> exit_dir. 255 means invalid/blocked.\nconst uint8_t to_table[8][4] = {\n    {1, 0, 255, 255}, // 0: L-U\n    {3, 255, 255, 0}, // 1: L-D\n    {255, 255, 3, 2}, // 2: R-D\n    {255, 2, 1, 255}, // 3: R-U\n    {1, 0, 3, 2},     // 4: L-U, R-D\n    {3, 2, 1, 0},     // 5: L-D, U-R\n    {2, 255, 0, 255}, // 6: L-R\n    {255, 3, 255, 1}  // 7: U-D\n};\n\n// Paths for each type: pairs of directions {d1, d2}\nconst uint8_t type_paths[8][2][2] = {\n    {{0, 1}, {255, 255}}, // 0\n    {{0, 3}, {255, 255}}, // 1\n    {{2, 3}, {255, 255}}, // 2\n    {{2, 1}, {255, 255}}, // 3\n    {{0, 1}, {2, 3}},     // 4\n    {{0, 3}, {1, 2}},     // 5\n    {{0, 2}, {255, 255}}, // 6\n    {{1, 3}, {255, 255}}  // 7\n};\n\nuint8_t grid[N];\nuint8_t initial_grid[N];\nuint8_t best_grid[N];\nlong long best_score = 0;\n\nint adj[N][4];\nuint8_t vm[N][4];\nuint8_t vm_cnt[N];\n\n// vis stores (generation << 32) | trace_id\nuint64_t vis[S] = {0};\nuint32_t vis_step[S] = {0};\nuint32_t gen = 0;\n\ninline void precompute() {\n    char c;\n    for (int i = 0; i < H; ++i) {\n        for (int j = 0; j < W; ++j) {\n            cin >> c;\n            int idx = i * W + j;\n            initial_grid[idx] = c - '0';\n            grid[idx] = initial_grid[idx];\n            \n            for (int d = 0; d < 4; ++d) {\n                int ni = i + di[d], nj = j + dj[d];\n                adj[idx][d] = (ni >= 0 && ni < H && nj >= 0 && nj < W) ? (ni * W + nj) : -1;\n            }\n            \n            int t = initial_grid[idx];\n            vm_cnt[idx] = 0;\n            if (t <= 3) {\n                for (int m = 0; m < 4; ++m) vm[idx][vm_cnt[idx]++] = m;\n            } else if (t <= 5) {\n                vm[idx][0] = 4; vm[idx][1] = 5; vm_cnt[idx] = 2;\n            } else {\n                vm[idx][0] = 6; vm[idx][1] = 7; vm_cnt[idx] = 2;\n            }\n        }\n    }\n}\n\nlong long calc_score() {\n    gen++;\n    uint32_t trace_id = 0;\n    long long max1 = 0, max2 = 0;\n    \n    for (int s = 0; s < S; ++s) {\n        if (vis[s] >> 32 == gen) continue;\n        \n        trace_id++;\n        int cur = s;\n        int step = 0;\n        uint64_t token = ((uint64_t)gen << 32) | trace_id;\n        \n        while (true) {\n            vis[cur] = token;\n            vis_step[cur] = step++;\n            \n            int idx = cur >> 2;\n            int d = cur & 3;\n            int exit_d = to_table[grid[idx]][d];\n            if (exit_d == 255) break;\n            \n            int next_idx = adj[idx][exit_d];\n            if (next_idx == -1) break;\n            \n            cur = (next_idx << 2) | (exit_d ^ 2);\n            if (vis[cur] >> 32 == gen) {\n                if ((vis[cur] & 0xFFFFFFFF) == trace_id) {\n                    long long cyc = step - vis_step[cur];\n                    if (cyc > max1) { max2 = max1; max1 = cyc; }\n                    else if (cyc > max2) max2 = cyc;\n                }\n                break;\n            }\n        }\n    }\n    return max1 * max2;\n}\n\ninline int get_heuristic(int idx, int type) {\n    int conn = 0;\n    const auto& p = type_paths[type];\n    \n    auto check = [&](int d1, int d2) {\n        int n1 = adj[idx][d1], n2 = adj[idx][d2];\n        if (n1 != -1 && to_table[grid[n1]][d1^2] != 255) conn++;\n        if (n2 != -1 && to_table[grid[n2]][d2^2] != 255) conn++;\n    };\n    \n    check(p[0][0], p[0][1]);\n    if (p[1][0] != 255) check(p[1][0], p[1][1]);\n    return conn;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    precompute();\n    best_score = calc_score();\n    memcpy(best_grid, grid, sizeof(grid));\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist_idx(0, N - 1);\n    \n    auto start = chrono::high_resolution_clock::now();\n    double time_limit = 1.95;\n    long long current_score = best_score;\n    \n    double T_heur = 0.4;\n    double heur_w[5];\n    for (int i = 0; i <= 4; ++i) heur_w[i] = exp(i / T_heur);\n    \n    double weights[4];\n    uint8_t moves[4];\n    \n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > time_limit) break;\n        \n        double progress = elapsed / time_limit;\n        double T = 8000.0 * (1.0 - progress) * (1.0 - progress);\n        if (T < 0.05) T = 0.05;\n        \n        int idx = dist_idx(rng);\n        int cnt = vm_cnt[idx];\n        \n        double sum_w = 0;\n        for (int k = 0; k < cnt; ++k) {\n            moves[k] = vm[idx][k];\n            double w = heur_w[get_heuristic(idx, moves[k])];\n            weights[k] = w;\n            sum_w += w;\n        }\n        \n        int sel = cnt - 1;\n        double r = (double)rng() / 4294967296.0 * sum_w;\n        double acc = 0;\n        for (int k = 0; k < cnt; ++k) {\n            acc += weights[k];\n            if (r < acc) { sel = k; break; }\n        }\n        \n        int new_type = moves[sel];\n        int old_type = grid[idx];\n        if (new_type == old_type) continue;\n        \n        grid[idx] = new_type;\n        long long new_score = calc_score();\n        long long delta = new_score - current_score;\n        \n        if (delta > 0 || (delta / T > -50.0 && (double)rng() / 4294967296.0 < exp(delta / T))) {\n            current_score = new_score;\n            if (new_score > best_score) {\n                best_score = new_score;\n                memcpy(best_grid, grid, sizeof(grid));\n            }\n        } else {\n            grid[idx] = old_type;\n        }\n    }\n    \n    string res; res.reserve(N);\n    for (int i = 0; i < N; ++i) {\n        int r = 0;\n        int init = initial_grid[i], cur = best_grid[i];\n        if (init <= 3) r = (cur - init + 4) % 4;\n        else r = (cur != init);\n        res.push_back('0' + r);\n    }\n    cout << res << \"\\n\";\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Union-Find Structure\nstruct UF {\n    vector<int> p;\n    UF(int n = 0) : p(n, -1) {}\n    int find(int x) { return p[x] == -1 ? x : p[x] = find(p[x]); }\n    void unite(int a, int b) {\n        a = find(a); b = find(b);\n        if (a != b) p[b] = a;\n    }\n    bool same(int a, int b) { return find(a) == find(b); }\n};\n\n// Globals\nint N;\nlong long T;\nvector<int> masks; // masks[tile_id]\nint initial_parity;\nvector<int> target_layout;\nbool found_layout = false;\nvector<bool> used;\nchrono::steady_clock::time_point start_time;\n\n// Calculate Parity of the board state\n// b: board state (vector of tile_ids, -1 for empty)\n// empty_r: row index of the empty space\nint calc_parity(const vector<int>& b, int empty_r) {\n    vector<int> seq; seq.reserve(b.size());\n    for (int x : b) if (x != -1) seq.push_back(x);\n    int inv = 0;\n    for (size_t i = 0; i < seq.size(); ++i)\n        for (size_t j = i + 1; j < seq.size(); ++j)\n            if (seq[i] > seq[j]) inv++;\n    if (N % 2 == 1) return inv % 2;\n    return (inv + (N - 1 - empty_r)) % 2;\n}\n\n// DFS to find a valid tree layout matching the parity\nvoid dfs_layout(int pos, vector<int>& b, UF uf) {\n    if (found_layout) return;\n    // Time limit for layout search: 1.0 sec\n    auto now = chrono::steady_clock::now();\n    if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 1000) return;\n\n    if (pos == N * N - 1) {\n        // Check if all tiles are connected\n        int root = uf.find(0);\n        bool connected = true;\n        for (int i = 1; i < N * N - 1; ++i) {\n            if (uf.find(i) != root) { connected = false; break; }\n        }\n        if (!connected) return;\n\n        // Check parity\n        // Target empty position is N*N-1 => row N-1\n        if (calc_parity(b, N - 1) != initial_parity) return;\n\n        target_layout = b;\n        found_layout = true;\n        return;\n    }\n\n    int r = pos / N, c = pos % N;\n    bool need_up = (r > 0 && b[pos - N] != -1 && (masks[b[pos - N]] & 8));\n    bool need_left = (c > 0 && b[pos - 1] != -1 && (masks[b[pos - 1]] & 4));\n\n    static vector<int> order;\n    if (pos == 0) {\n        order.resize(N * N - 1);\n        iota(order.begin(), order.end(), 0);\n    }\n    // Shuffle only at the start of a new search attempt or root\n    static mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    if (pos == 0) {\n        shuffle(order.begin(), order.end(), rng);\n    }\n\n    for (int tid : order) {\n        if (used[tid]) continue;\n        int m = masks[tid];\n        if (need_up && !(m & 2)) continue;\n        if (need_left && !(m & 1)) continue;\n\n        b[pos] = tid; used[tid] = true;\n\n        bool conn_up = false, conn_left = false;\n        if (need_up && (m & 2)) { uf.unite(pos, pos - N); conn_up = true; }\n        if (need_left && (m & 1)) { uf.unite(pos, pos - 1); conn_left = true; }\n        \n        bool cycle = false;\n        if (conn_up && conn_left && uf.same(pos - N, pos - 1)) cycle = true;\n\n        if (!cycle) {\n            dfs_layout(pos + 1, b, uf);\n            if (found_layout) return;\n        }\n\n        used[tid] = false; b[pos] = -1;\n    }\n}\n\n// BFS to move empty space to (gr, gc) avoiding solved tiles and the specific tile at (tr, tc)\nstring bfs_empty(int er, int ec, int tr, int tc, int gr, int gc, const vector<bool>& solved) {\n    if (er == gr && ec == gc) return \"\";\n    queue<pair<int, int>> q; q.push({er, ec});\n    vector<int> par(N * N, -1);\n    vector<char> move_to(N * N, 0);\n    auto id = [&](int r, int c) { return r * N + c; };\n    par[id(er, ec)] = id(er, ec);\n\n    int dr[] = {-1, 1, 0, 0};\n    int dc[] = {0, 0, -1, 1};\n    char out_chars[] = {'U', 'D', 'L', 'R'}; \n\n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        if (r == gr && c == gc) {\n            string path;\n            int cur = id(r, c);\n            while (cur != id(er, ec)) {\n                path += move_to[cur];\n                cur = par[cur];\n            }\n            reverse(path.begin(), path.end());\n            return path;\n        }\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i], nc = c + dc[i];\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n            int nid = id(nr, nc);\n            if (par[nid] != -1) continue;\n            if (solved[nid]) continue;\n            if (nr == tr && nc == tc) continue;\n            par[nid] = id(r, c);\n            move_to[nid] = out_chars[i];\n            q.push({nr, nc});\n        }\n    }\n    return \"\";\n}\n\n// Apply a move\nvoid apply_move(char c, vector<int>& board, int& empty_pos, vector<int>& cur_pos) {\n    int tr = empty_pos / N, tc = empty_pos % N;\n    int nr = tr, nc = tc;\n    if (c == 'U') nr--;\n    else if (c == 'D') nr++;\n    else if (c == 'L') nc--;\n    else if (c == 'R') nc++;\n\n    int new_empty = nr * N + nc;\n    // Safety check\n    if (new_empty < 0 || new_empty >= N * N) return;\n    \n    int tid = board[new_empty];\n    // board[new_empty] must be a valid tile (not -1)\n    if (tid != -1) {\n        board[empty_pos] = tid;\n        board[new_empty] = -1;\n        cur_pos[tid] = empty_pos;\n        empty_pos = new_empty;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    if (!(cin >> N >> T)) return 0;\n    \n    vector<string> grid(N);\n    masks.reserve(N * N - 1);\n    int empty_init_pos = -1;\n    vector<int> init_board(N * N);\n    int tile_cnt = 0;\n\n    for (int i = 0; i < N; ++i) {\n        cin >> grid[i];\n        for (int j = 0; j < N; ++j) {\n            char c = grid[i][j];\n            int pos = i * N + j;\n            if (c == '0') {\n                init_board[pos] = -1;\n                empty_init_pos = pos;\n                continue;\n            }\n            int val = (c >= '0' && c <= '9') ? c - '0' : c - 'a' + 10;\n            masks.push_back(val);\n            init_board[pos] = tile_cnt;\n            tile_cnt++;\n        }\n    }\n\n    initial_parity = calc_parity(init_board, empty_init_pos / N);\n    \n    used.assign(N * N - 1, false);\n    vector<int> board(N * N, -1);\n    start_time = chrono::steady_clock::now();\n\n    // Run layout search with retries\n    for (int attempt = 0; attempt < 5; ++attempt) {\n        if (found_layout) break;\n        if (attempt > 0) {\n            fill(used.begin(), used.end(), false);\n            fill(board.begin(), board.end(), -1);\n            found_layout = false;\n            // Re-seed RNG for different order\n        }\n        dfs_layout(0, board, UF(N * N));\n    }\n\n    if (!found_layout) {\n        // Fallback: Identity layout\n        target_layout.resize(N * N, -1);\n        for(int i=0; i<N*N-1; ++i) target_layout[i] = i;\n    }\n\n    // Phase 2: Sliding Solver\n    vector<int> cur_board = init_board;\n    vector<int> cur_pos(N * N - 1);\n    int empty_pos = empty_init_pos;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int pos = i * N + j;\n            if (cur_board[pos] != -1) cur_pos[cur_board[pos]] = pos;\n        }\n    }\n\n    vector<bool> pos_solved(N * N, false);\n    string moves; moves.reserve(T);\n\n    for (int target_pos = 0; target_pos < N * N - 1; ++target_pos) {\n        if (moves.size() >= T) break;\n        int tid = target_layout[target_pos];\n        if (tid == -1) continue; \n\n        if (cur_pos[tid] == target_pos) {\n            pos_solved[target_pos] = true;\n            continue;\n        }\n\n        int tr = cur_pos[tid] / N, tc = cur_pos[tid] % N;\n        int tr_t = target_pos / N, tc_t = target_pos % N;\n\n        while (cur_pos[tid] != target_pos && moves.size() < T) {\n            int dtr = (tr > tr_t) ? -1 : (tr < tr_t) ? 1 : 0;\n            int dtc = (tc > tc_t) ? -1 : (tc < tc_t) ? 1 : 0;\n\n            // We want to move tile in direction (dtr, dtc).\n            // Empty space must be at (tr + dtr, tc + dtc) to allow sliding the tile.\n            int need_r = tr + dtr, need_c = tc + dtc;\n\n            int empty_r = empty_pos / N, empty_c = empty_pos % N;\n\n            string path = bfs_empty(empty_r, empty_c, tr, tc, need_r, need_c, pos_solved);\n            if (path.empty()) break; // Stuck\n            for (char c : path) {\n                if (moves.size() >= T) break;\n                apply_move(c, cur_board, empty_pos, cur_pos);\n                moves += c;\n            }\n            if (cur_pos[tid] == target_pos) break;\n            \n            // Now Empty is at (need_r, need_c).\n            // Tile is at (tr, tc).\n            // We want to move Tile in direction (dtr, dtc).\n            // Command is opposite to movement direction.\n            char slide;\n            if (dtr == -1) slide = 'D'; // Tile Up, Empty Down -> Slide D\n            else if (dtr == 1) slide = 'U'; // Tile Down, Empty Up -> Slide U\n            else if (dtc == -1) slide = 'R'; // Tile Left, Empty Right -> Slide R\n            else slide = 'L'; // Tile Right, Empty Left -> Slide L\n\n            if (moves.size() < T) {\n                apply_move(slide, cur_board, empty_pos, cur_pos);\n                moves += slide;\n            }\n            tr = cur_pos[tid] / N;\n            tc = cur_pos[tid] % N;\n        }\n        pos_solved[target_pos] = true;\n    }\n\n    if (moves.size() > T) moves.resize(T);\n    cout << moves << \"\\n\";\n    return 0;\n}","ahc012":"/*\n    Solution for AtCoder Heuristic Contest 012\n    Strategy: Greedy Randomized Local Search.\n    We maintain the current partition of strawberries (regions).\n    In each step, we try to find a random line that maximizes the score improvement.\n    A line splits regions into two parts. We only accept the line if it increases the score.\n    We track the number of pieces of each size (up to 10) to compute the score efficiently.\n    Lines that pass exactly through a strawberry are avoided.\n*/\n#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <tuple>\n#include <numeric>\n\nusing namespace std;\n\ntypedef long long ll;\n\nstruct Point {\n    ll x, y;\n};\n\nstruct Region {\n    vector<int> pts; // Indices of strawberries in this region\n};\n\nint main() {\n    // Fast IO\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, K;\n    if (!(cin >> N >> K)) return 0;\n\n    vector<int> a(11);\n    for (int i = 1; i <= 10; ++i) cin >> a[i];\n\n    vector<Point> pts(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> pts[i].x >> pts[i].y;\n    }\n\n    // Initial state: One region containing all strawberries\n    vector<Region> regions;\n    regions.reserve(K + 2);\n    Region start_reg;\n    start_reg.pts.reserve(N);\n    for (int i = 0; i < N; ++i) start_reg.pts.push_back(i);\n    regions.push_back(move(start_reg));\n\n    // b[d] stores count of pieces with exactly d strawberries (for d <= 10)\n    // We only track sizes <= 10 because demands a_d are only up to 10.\n    // Pieces with size > 10 contribute 0 to the score.\n    vector<int> b(11, 0);\n    if (N <= 10) b[N] = 1;\n\n    auto calc_score = [&](const vector<int>& counts) {\n        ll sc = 0;\n        for (int d = 1; d <= 10; ++d) {\n            sc += min((ll)a[d], (ll)counts[d]);\n        }\n        return sc;\n    };\n\n    ll current_score = calc_score(b);\n    vector<tuple<ll, ll, ll, ll>> final_lines;\n    final_lines.reserve(K);\n\n    mt19937_64 rng(12345); // Fixed seed for reproducibility, or random\n    // Range for line coordinates. Strawberries are in [-10000, 10000].\n    // We generate lines passing through points in a slightly larger box.\n    uniform_int_distribution<ll> dist(-25000, 25000);\n\n    auto start_time = chrono::steady_clock::now();\n    \n    // Parameters for search\n    // Higher TRIES_PER_STEP gives better lines but takes more time.\n    // 300 seems a good balance for N=5000, K=100 within 3s.\n    const int TRIES_PER_STEP = 300; \n\n    for (int step = 0; step < K; ++step) {\n        // Time check to ensure we finish within limit\n        auto now = chrono::steady_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 2800) break;\n\n        ll best_line_x1 = 0, best_line_y1 = 0, best_line_x2 = 0, best_line_y2 = 0;\n        ll best_score = current_score;\n        bool found_better = false;\n\n        for (int t = 0; t < TRIES_PER_STEP; ++t) {\n            // Generate random line defined by two points\n            ll x1 = dist(rng);\n            ll y1 = dist(rng);\n            ll x2 = dist(rng);\n            ll y2 = dist(rng);\n            \n            // Ensure distinct points\n            if (x1 == x2 && y1 == y2) continue;\n\n            // Precompute line coefficients for Ax + By + C = 0\n            // A = y1 - y2, B = x2 - x1, C = -A*x1 - B*y1\n            ll A = y1 - y2;\n            ll B = x2 - x1;\n            ll C = -A * x1 - B * y1;\n\n            // Check validity and calculate potential score\n            // We work on a copy of b to simulate the change\n            vector<int> temp_b = b;\n            bool possible = true;\n            \n            // Iterate over all current regions to see how they are split\n            for (const auto& reg : regions) {\n                int sz = (int)reg.pts.size();\n                if (sz <= 1) {\n                    // If size is 1, the line must not pass through the point\n                    int idx = reg.pts[0];\n                    ll val = A * pts[idx].x + B * pts[idx].y + C;\n                    if (val == 0) {\n                        possible = false; // Line cuts the strawberry\n                        break;\n                    }\n                    continue; // No split possible for single point (unless hit)\n                }\n\n                int pos_cnt = 0;\n                int neg_cnt = 0;\n                bool hit = false;\n                \n                // Check side of each point in the region\n                for (int idx : reg.pts) {\n                    ll val = A * pts[idx].x + B * pts[idx].y + C;\n                    if (val > 0) pos_cnt++;\n                    else if (val < 0) neg_cnt++;\n                    else {\n                        hit = true; // Line passes through a strawberry\n                        break;\n                    }\n                }\n                \n                if (hit) {\n                    possible = false;\n                    break;\n                }\n\n                // If the line splits the region into two non-empty sets\n                if (pos_cnt > 0 && neg_cnt > 0) {\n                    // Update the counts in temp_b\n                    // The old region of size 'sz' is removed\n                    if (sz <= 10) {\n                        temp_b[sz]--;\n                    }\n                    // Two new regions of sizes 'pos_cnt' and 'neg_cnt' are created\n                    if (pos_cnt <= 10) {\n                        temp_b[pos_cnt]++;\n                    }\n                    if (neg_cnt <= 10) {\n                        temp_b[neg_cnt]++;\n                    }\n                }\n            }\n\n            if (possible) {\n                ll sc = calc_score(temp_b);\n                if (sc > best_score) {\n                    best_score = sc;\n                    best_line_x1 = x1;\n                    best_line_y1 = y1;\n                    best_line_x2 = x2;\n                    best_line_y2 = y2;\n                    found_better = true;\n                }\n            }\n        }\n\n        if (found_better) {\n            current_score = best_score;\n            final_lines.push_back({best_line_x1, best_line_y1, best_line_x2, best_line_y2});\n            \n            // Apply the best line: Update regions and global counts b\n            ll A = best_line_y1 - best_line_y2;\n            ll B = best_line_x2 - best_line_x1;\n            ll C = -A * best_line_x1 - B * best_line_y1;\n\n            vector<Region> next_regions;\n            // Reserve memory to avoid reallocations. Max regions ~ K+1.\n            next_regions.reserve(regions.size() + 2);\n\n            for (auto& reg : regions) {\n                int sz = (int)reg.pts.size();\n                \n                // First pass: check if split is needed\n                int pos = 0;\n                int neg = 0;\n                for (int idx : reg.pts) {\n                    ll val = A * pts[idx].x + B * pts[idx].y + C;\n                    if (val > 0) pos++;\n                    else if (val < 0) neg++;\n                    // val == 0 should not happen for the selected best line\n                }\n\n                if (pos > 0 && neg > 0) {\n                    // Split occurred\n                    // Update global counts b\n                    if (sz <= 10) b[sz]--;\n                    if (pos <= 10) b[pos]++;\n                    if (neg <= 10) b[neg]++;\n\n                    // Create new regions\n                    Region r1, r2;\n                    r1.pts.reserve(pos);\n                    r2.pts.reserve(neg);\n                    \n                    for (int idx : reg.pts) {\n                        ll val = A * pts[idx].x + B * pts[idx].y + C;\n                        if (val > 0) r1.pts.push_back(idx);\n                        else if (val < 0) r2.pts.push_back(idx);\n                    }\n                    next_regions.push_back(move(r1));\n                    next_regions.push_back(move(r2));\n                } else {\n                    // No split, keep the region (move to avoid copy)\n                    next_regions.push_back(move(reg));\n                }\n            }\n            regions = move(next_regions);\n        } else {\n            // No improvement found with random lines, stop early\n            break;\n        }\n    }\n\n    // Output results\n    cout << final_lines.size() << \"\\n\";\n    for (const auto& line : final_lines) {\n        cout << get<0>(line) << \" \" << get<1>(line) << \" \" << get<2>(line) << \" \" << get<3>(line) << \"\\n\";\n    }\n\n    return 0;\n}","ahc014":"#pragma GCC optimize(\"O3,unroll-loops\")\n#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nbool has_dot[65][65];\n// used_mask stores edge usage. \n// Bitmask: 1=Right, 2=Up, 4=UpRight, 8=DownRight.\n// Indexed by the lexicographically smaller endpoint of the unit segment.\nint used_mask[65][65]; \nlong long weight[65][65];\n\nstruct Point { int x, y; };\nvector<Point> all_points;\nvector<tuple<Point, Point, Point, Point>> result;\n\n// Lists of dots for fast lookup\n// row_dots[y] contains x-coordinates of dots in row y\nvector<int> row_dots[65];\n// col_dots[x] contains y-coordinates of dots in column x\nvector<int> col_dots[65];\n// diag1[d] contains points on main diagonal y - x = d. Index offset by 65.\nvector<Point> diag1[130]; \n// diag2[s] contains points on anti-diagonal y + x = s.\nvector<Point> diag2[130];\n\ninline int sgn(int x) { return (x > 0) - (x < 0); }\n\n// Maps any unit segment to a canonical index and direction bit\nvoid get_edge_info(Point a, Point b, int &mx, int &my, int &bit) {\n    if (a.x > b.x || (a.x == b.x && a.y > b.y)) swap(a, b);\n    mx = a.x; my = a.y;\n    if (a.x == b.x) bit = 2;          // Vertical\n    else if (a.y == b.y) bit = 1;     // Horizontal\n    else if (b.y > a.y) bit = 4;      // Up-Right\n    else bit = 8;                     // Down-Right\n}\n\n// Checks edge segments and interior dots between a and b.\n// If mark is true, commits the edges as used.\nbool check_segment(Point a, Point b, bool mark) {\n    int dx = sgn(b.x - a.x), dy = sgn(b.y - a.y);\n    int cx = a.x, cy = a.y;\n    while (cx != b.x || cy != b.y) {\n        int nx = cx + dx, ny = cy + dy;\n        // Check interior dots (excluding endpoint b)\n        if ((nx != b.x || ny != b.y) && has_dot[nx][ny]) return false;\n        \n        int mx, my, bit;\n        get_edge_info({cx, cy}, {nx, ny}, mx, my, bit);\n        \n        if (used_mask[mx][my] & bit) return false;\n        if (mark) used_mask[mx][my] |= bit;\n        \n        cx = nx; cy = ny;\n    }\n    return true;\n}\n\n// Validates the entire rectangle perimeter\nbool check_rect(Point p1, Point p2, Point p3, Point p4, bool mark) {\n    Point pts[4] = {p1, p2, p3, p4};\n    for(int i = 0; i < 4; i++) {\n        if (!check_segment(pts[i], pts[(i+1)%4], false)) return false;\n    }\n    if (mark) {\n        for(int i = 0; i < 4; i++) {\n            check_segment(pts[i], pts[(i+1)%4], true);\n        }\n    }\n    return true;\n}\n\n// Helper to add a dot to data structures\nvoid add_dot(int x, int y) {\n    has_dot[x][y] = true;\n    row_dots[y].push_back(x);\n    col_dots[x].push_back(y);\n    diag1[y - x + 65].push_back({x, y});\n    diag2[y + x].push_back({x, y});\n}\n\n// Try to find a valid rectangle with p1 as the new point\n// Returns true if found, and sets p2, p3, p4\nbool find_rectangle(Point p1, Point& p2, Point& p3, Point& p4) {\n    int px = p1.x, py = p1.y;\n\n    // 1. Axis-Aligned Rectangles\n    // p2 = (x2, py), p4 = (px, y2), p3 = (x2, y2)\n    // We need p2 and p4 to be dots, and p3 to be a dot.\n    if (!row_dots[py].empty() && !col_dots[px].empty()) {\n        for (int x2 : row_dots[py]) {\n            if (x2 == px) continue;\n            for (int y2 : col_dots[px]) {\n                if (y2 == py) continue;\n                if (has_dot[x2][y2]) {\n                    p2 = {x2, py}; p4 = {px, y2}; p3 = {x2, y2};\n                    if (check_rect(p1, p2, p3, p4, false)) return true;\n                }\n            }\n        }\n    }\n\n    // 2. 45-Degree Rotated Rectangles\n    // Sides must have slopes 1 and -1.\n    // p1 is a vertex. Adjacent vertices p2, p4 must lie on diagonals passing through p1.\n    // One on main diagonal (y-x = const), one on anti-diagonal (y+x = const).\n    \n    // Case A: p2 on main diag, p4 on anti diag\n    // p1 -> p2 vector has slope 1. p1 -> p4 vector has slope -1.\n    // p2 is on same main diag as p1.\n    // p4 is on same anti diag as p1.\n    int d1_idx = py - px + 65;\n    int d2_idx = py + px;\n    \n    for (const auto& cand2 : diag1[d1_idx]) {\n        if (cand2.x == px && cand2.y == py) continue; // Skip p1 itself\n        // cand2 is p2\n        // We need p4 on anti-diag d2_idx\n        // p3 is determined by p2 + p4 - p1\n        // Actually, p3 must also be a dot.\n        // Let's iterate p4 candidates on anti-diag.\n        // But iterating all p4 might be slow?\n        // However, p3 = p2 + p4 - p1. \n        // p3 must be a valid grid point and have a dot.\n        // p3.x = p2.x + p4.x - p1.x\n        // p3.y = p2.y + p4.y - p1.y\n        // Since p2, p1 are fixed, p3 depends linearly on p4.\n        // But checking has_dot[p3] is fast.\n        \n        // Optimization: We can iterate p4.\n        // But maybe we can compute p3 required?\n        // No, p3 is a corner, we don't know it.\n        // But p3 must be a dot.\n        // Is there a relation?\n        // In a rectangle, diagonals bisect each other.\n        // Midpoint of p1-p3 == Midpoint of p2-p4.\n        // So p3 = p2 + p4 - p1.\n        // Also, since sides are 45 deg, distance(p1, p2) can be anything.\n        // Wait, for 45 deg rectangle, it's a square?\n        // No. A rectangle with sides at 45 deg to axes is not necessarily a square.\n        // But the vertices must form a rectangle.\n        // If p1, p2, p4 form a right angle (which they do if on orthogonal diagonals),\n        // then p3 is fixed. We just need to check if p3 exists.\n        \n        for (const auto& cand4 : diag2[d2_idx]) {\n            if (cand4.x == px && cand4.y == py) continue;\n            // Check if p2, p4 are distinct and valid\n            // Also check if p3 is within bounds\n            int p3x = cand2.x + cand4.x - px;\n            int p3y = cand2.y + cand4.y - py;\n            \n            if (p3x < 0 || p3x >= N || p3y < 0 || p3y >= N) continue;\n            \n            if (has_dot[p3x][p3y]) {\n                p2 = cand2; p4 = cand4; p3 = {p3x, p3y};\n                // Check order: p1, p2, p3, p4\n                // Vector p1->p2 and p4->p3 should be parallel?\n                // p2-p1 = (dx, dy), p3-p4 = (p3x-p4x, p3y-p4y)\n                // p3x-p4x = cand2.x - px. Same.\n                // So it forms a parallelogram. Since angle at p1 is 90, it's a rectangle.\n                // But we must ensure p2 and p4 are adjacent to p1 in the perimeter order.\n                // The problem says \"Connecting p1 p2 p3 p4 ... forms a rectangle\".\n                // So p1-p2 is an edge. p1-p4 is an edge? No, p1-p2, p2-p3, p3-p4, p4-p1.\n                // Yes, p1 is connected to p2 and p4.\n                // So my assignment is correct.\n                \n                if (check_rect(p1, p2, p3, p4, false)) return true;\n            }\n        }\n    }\n\n    // Case B: p2 on anti diag, p4 on main diag\n    // Swap roles. p2 from diag2, p4 from diag1.\n    for (const auto& cand2 : diag2[d2_idx]) {\n        if (cand2.x == px && cand2.y == py) continue;\n        for (const auto& cand4 : diag1[d1_idx]) {\n            if (cand4.x == px && cand4.y == py) continue;\n            \n            int p3x = cand2.x + cand4.x - px;\n            int p3y = cand2.y + cand4.y - py;\n            \n            if (p3x < 0 || p3x >= N || p3y < 0 || p3y >= N) continue;\n            \n            if (has_dot[p3x][p3y]) {\n                p2 = cand2; p4 = cand4; p3 = {p3x, p3y};\n                if (check_rect(p1, p2, p3, p4, false)) return true;\n            }\n        }\n    }\n\n    return false;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M)) return 0;\n    \n    int c = (N - 1) / 2;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            weight[i][j] = (long long)(i - c) * (i - c) + (j - c) * (j - c) + 1;\n            all_points.push_back({i, j});\n        }\n    }\n\n    for (int i = 0; i < M; i++) {\n        int x, y; cin >> x >> y;\n        add_dot(x, y);\n    }\n\n    // Sort candidates by weight descending (greedy strategy)\n    sort(all_points.begin(), all_points.end(), [](const Point& a, const Point& b) {\n        return weight[a.x][a.y] > weight[b.x][b.y];\n    });\n\n    clock_t start = clock();\n    const double TIME_LIMIT = 4.5;\n\n    for (auto& p1 : all_points) {\n        if (has_dot[p1.x][p1.y]) continue;\n        if ((double)(clock() - start) / CLOCKS_PER_SEC > TIME_LIMIT) break;\n        \n        Point p2, p3, p4;\n        if (find_rectangle(p1, p2, p3, p4)) {\n            // Commit\n            check_rect(p1, p2, p3, p4, true);\n            add_dot(p1.x, p1.y);\n            result.push_back({p1, p2, p3, p4});\n        }\n    }\n\n    cout << result.size() << \"\\n\";\n    for (const auto& op : result) {\n        const auto& [p1, p2, p3, p4] = op;\n        cout << p1.x << \" \" << p1.y << \" \"\n             << p2.x << \" \" << p2.y << \" \"\n             << p3.x << \" \" << p3.y << \" \"\n             << p4.x << \" \" << p4.y << \"\\n\";\n    }\n\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\n// Calculate sum of squares of connected component sizes\nint calc_score(const vector<int>& grid) {\n    // grid size 100\n    vector<int> visited(100, 0);\n    int total_score = 0;\n    int dr[] = {-1, 1, 0, 0};\n    int dc[] = {0, 0, -1, 1};\n    int q[100]; // Queue for BFS\n\n    for (int i = 0; i < 100; ++i) {\n        if (grid[i] != 0 && !visited[i]) {\n            int flavor = grid[i];\n            int size = 0;\n            int head = 0;\n            int tail = 0;\n            \n            q[tail++] = i;\n            visited[i] = 1;\n            \n            while(head < tail){\n                int curr = q[head++];\n                size++;\n                int r = curr / 10;\n                int c = curr % 10;\n                \n                for(int k=0; k<4; ++k){\n                    int nr = r + dr[k];\n                    int nc = c + dc[k];\n                    if(nr >= 0 && nr < 10 && nc >= 0 && nc < 10){\n                        int nidx = nr * 10 + nc;\n                        if(!visited[nidx] && grid[nidx] == flavor){\n                            visited[nidx] = 1;\n                            q[tail++] = nidx;\n                        }\n                    }\n                }\n            }\n            total_score += size * size;\n        }\n    }\n    return total_score;\n}\n\n// Apply tilt to grid\n// dir: 0=F, 1=B, 2=L, 3=R\n// F: Row 0 (Top)\n// B: Row 9 (Bottom)\n// L: Col 0 (Left)\n// R: Col 9 (Right)\nvector<int> tilt(const vector<int>& grid, int dir) {\n    vector<int> next_grid(100, 0);\n    if (dir == 2) { // L\n        for (int r = 0; r < 10; ++r) {\n            int idx = 0;\n            for (int c = 0; c < 10; ++c) {\n                int val = grid[r * 10 + c];\n                if (val != 0) {\n                    next_grid[r * 10 + idx++] = val;\n                }\n            }\n        }\n    } else if (dir == 3) { // R\n        for (int r = 0; r < 10; ++r) {\n            int idx = 9;\n            for (int c = 9; c >= 0; --c) {\n                int val = grid[r * 10 + c];\n                if (val != 0) {\n                    next_grid[r * 10 + idx--] = val;\n                }\n            }\n        }\n    } else if (dir == 0) { // F\n        for (int c = 0; c < 10; ++c) {\n            int idx = 0;\n            for (int r = 0; r < 10; ++r) {\n                int val = grid[r * 10 + c];\n                if (val != 0) {\n                    next_grid[idx * 10 + c] = val;\n                    idx++;\n                }\n            }\n        }\n    } else if (dir == 1) { // B\n        for (int c = 0; c < 10; ++c) {\n            int idx = 9;\n            for (int r = 9; r >= 0; --r) {\n                int val = grid[r * 10 + c];\n                if (val != 0) {\n                    next_grid[idx * 10 + c] = val;\n                    idx--;\n                }\n            }\n        }\n    }\n    return next_grid;\n}\n\nint main() {\n    // Optimize I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    vector<int> f(100);\n    for (int i = 0; i < 100; ++i) {\n        if (!(cin >> f[i])) return 0;\n    }\n\n    vector<int> grid(100, 0);\n    int dirs[] = {0, 1, 2, 3}; // F, B, L, R\n\n    for (int t = 0; t < 100; ++t) {\n        int p;\n        if (!(cin >> p)) break;\n\n        // Place candy f[t] at p-th empty cell\n        int count = 0;\n        for (int i = 0; i < 100; ++i) {\n            if (grid[i] == 0) {\n                count++;\n                if (count == p) {\n                    grid[i] = f[t];\n                    break;\n                }\n            }\n        }\n\n        // If last candy (100th), no tilt needed, skip output\n        if (t == 99) break;\n\n        int next_flavor = f[t+1];\n        int best_dir = 0;\n        double best_val = -1.0;\n\n        // Try all 4 directions\n        for (int d : dirs) {\n            vector<int> g_tilted = tilt(grid, d);\n            \n            // Find empty cells in the tilted grid\n            // We cannot use indices from original grid as tilting permutes them\n            vector<int> empty_indices;\n            empty_indices.reserve(100); // Max possible\n            for(int i=0; i<100; ++i) {\n                if(g_tilted[i] == 0) empty_indices.push_back(i);\n            }\n            \n            // Should not be empty since t < 99\n            if (empty_indices.empty()) continue;\n\n            double current_val = 0.0;\n            \n            // If this is the tilt before the 100th candy placement (t=98)\n            // Next step places 100th candy and ends (no tilt).\n            // We evaluate the exact final score for each possible placement of the 100th candy.\n            // Since there is only 1 empty cell at t=98 (99 candies placed), it is deterministic.\n            if (t == 98) {\n                int idx = empty_indices[0];\n                vector<int> g_final = g_tilted;\n                g_final[idx] = next_flavor;\n                current_val = (double)calc_score(g_final);\n            } else {\n                // General lookahead: \n                // Simulate placing next_flavor in each empty spot,\n                // then find the best tilt for that resulting state,\n                // and average the scores.\n                // This estimates the expected score after the next step (placement + optimal tilt).\n                long long sum_scores = 0;\n                for (int idx : empty_indices) {\n                    vector<int> g_temp = g_tilted;\n                    g_temp[idx] = next_flavor;\n                    \n                    // Find max score achievable by tilting g_temp\n                    int max_s = 0;\n                    for (int d2 : dirs) {\n                        vector<int> g_next = tilt(g_temp, d2);\n                        int s = calc_score(g_next);\n                        if (s > max_s) max_s = s;\n                    }\n                    sum_scores += max_s;\n                }\n                current_val = (double)sum_scores / empty_indices.size();\n            }\n\n            if (current_val > best_val) {\n                best_val = current_val;\n                best_dir = d;\n            }\n        }\n\n        // Apply best tilt to the actual grid\n        grid = tilt(grid, best_dir);\n        \n        char out_c;\n        if(best_dir == 0) out_c = 'F';\n        else if(best_dir == 1) out_c = 'B';\n        else if(best_dir == 2) out_c = 'L';\n        else out_c = 'R';\n        \n        cout << out_c << endl;\n    }\n\n    return 0;\n}","ahc016":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <Eigen/Dense>\n\nusing namespace std;\n\nint main() {\n    cin.tie(nullptr);\n    ios::sync_with_stdio(false);\n\n    int M;\n    double eps;\n    if (!(cin >> M >> eps)) return 0;\n\n    // Dynamic N selection to balance score ceiling (1/N) and distinguishability.\n    // We cap N at 50 to ensure the score ceiling remains high (>20M) while \n    // eigenvalues provide sufficient robustness even for epsilon=0.4.\n    int N = 25 + static_cast<int>(round(40.0 * eps));\n    N = max(25, min(50, N));\n    \n    cout << N << \"\\n\";\n\n    // Store sorted eigenvalues for each generated graph\n    vector<vector<double>> stored_evals(M, vector<double>(N));\n    mt19937 rng(42);\n\n    for (int k = 0; k < M; ++k) {\n        // Space densities to maximize separation in spectral domain\n        double p = 0.05 + 0.9 * k / (M - 1.0);\n        \n        Eigen::MatrixXd adj = Eigen::MatrixXd::Zero(N, N);\n        \n        // Generate graph\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                if (rng() % 10000 < static_cast<int>(p * 10000)) {\n                    adj(i, j) = adj(j, i) = 1.0;\n                }\n            }\n        }\n\n        // Compute eigenvalues (SelfAdjointEigenSolver is efficient for symmetric matrices)\n        // EigenvaluesOnly option speeds up computation significantly\n        Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> solver(adj, Eigen::EigenvaluesOnly);\n        \n        // Eigen::SelfAdjointEigenSolver returns eigenvalues in increasing order\n        const auto& evals = solver.eigenvalues();\n        for (int i = 0; i < N; ++i) {\n            stored_evals[k][i] = evals(i);\n        }\n\n        // Output graph as string\n        string s;\n        s.reserve(N * (N - 1) / 2);\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                s += (adj(i, j) > 0.5 ? '1' : '0');\n            }\n        }\n        cout << s << \"\\n\";\n    }\n    cout.flush();\n\n    vector<int> query_deg(N); // Reuse buffer if needed, though not used here\n    for (int q = 0; q < 100; ++q) {\n        string h;\n        cin >> h;\n        \n        Eigen::MatrixXd h_adj = Eigen::MatrixXd::Zero(N, N);\n        int idx = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                if (h[idx] == '1') {\n                    h_adj(i, j) = h_adj(j, i) = 1.0;\n                }\n                idx++;\n            }\n        }\n\n        Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> solver(h_adj, Eigen::EigenvaluesOnly);\n        const auto& h_evals = solver.eigenvalues();\n\n        int best_k = 0;\n        double min_dist = 1e18;\n\n        for (int k = 0; k < M; ++k) {\n            // Euclidean distance between sorted eigenvalue vectors\n            double dist = 0.0;\n            for (int i = 0; i < N; ++i) {\n                double diff = h_evals(i) - stored_evals[k][i];\n                dist += diff * diff;\n            }\n            // No need to sqrt for comparison\n            if (dist < min_dist) {\n                min_dist = dist;\n                best_k = k;\n            }\n        }\n        \n        cout << best_k << \"\\n\";\n        cout.flush();\n    }\n\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n\n    struct EdgeInfo { int u, v, w; };\n    vector<EdgeInfo> edges(M);\n    vector<vector<pair<int, int>>> adj(N);\n\n    for (int i = 0; i < M; ++i) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        --u; --v;\n        edges[i] = {u, v, w};\n        adj[u].emplace_back(v, i);\n        adj[v].emplace_back(u, i);\n    }\n\n    // Skip coordinates\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n    }\n\n    mt19937_64 rng(42);\n    vector<long double> eb(M, 0.0);\n    vector<int> dist(N);\n    vector<vector<int>> pred(N);\n    vector<long double> sigma(N);\n    vector<long double> delta(N);\n    vector<int> nodes(N);\n    iota(nodes.begin(), nodes.end(), 0);\n\n    // Compute exact edge betweenness centrality\n    for (int s = 0; s < N; ++s) {\n        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;\n        fill(dist.begin(), dist.end(), 2e9);\n        dist[s] = 0;\n        pq.emplace(0, s);\n\n        for (int i = 0; i < N; ++i) pred[i].clear();\n\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u]) continue;\n            for (auto [v, id] : adj[u]) {\n                int w = edges[id].w;\n                if (dist[v] > d + w) {\n                    dist[v] = d + w;\n                    pred[v].clear();\n                    pred[v].push_back(id);\n                    pq.emplace(dist[v], v);\n                } else if (dist[v] == d + w) {\n                    pred[v].push_back(id);\n                }\n            }\n        }\n\n        sort(nodes.begin(), nodes.end(), [&](int a, int b) {\n            return dist[a] < dist[b];\n        });\n\n        fill(sigma.begin(), sigma.end(), 0.0);\n        sigma[s] = 1.0;\n        for (int u : nodes) {\n            if (u == s) continue;\n            for (int id : pred[u]) {\n                int p = (edges[id].u == u) ? edges[id].v : edges[id].u;\n                sigma[u] += sigma[p];\n            }\n        }\n\n        fill(delta.begin(), delta.end(), 0.0);\n        for (auto it = nodes.rbegin(); it != nodes.rend(); ++it) {\n            int u = *it;\n            if (sigma[u] == 0.0) continue;\n            for (int id : pred[u]) {\n                int p = (edges[id].u == u) ? edges[id].v : edges[id].u;\n                long double val = (sigma[p] / sigma[u]) * (1.0L + delta[u]);\n                delta[p] += val;\n                eb[id] += val;\n            }\n        }\n    }\n\n    // Add tiny noise to break ties deterministically\n    for (int i = 0; i < M; ++i) {\n        eb[i] += uniform_real_distribution<double>(0, 1e-9)(rng);\n    }\n\n    // Greedy initial assignment\n    vector<pair<long double, int>> sorted(M);\n    for (int i = 0; i < M; ++i) sorted[i] = {eb[i], i};\n    sort(sorted.begin(), sorted.end(), greater<>());\n\n    vector<int> assign(M);\n    vector<long double> day_sum(D, 0.0);\n\n    for (auto [w, idx] : sorted) {\n        int best_day = 0;\n        long double min_sum = day_sum[0];\n        for (int d = 1; d < D; ++d) {\n            if (day_sum[d] < min_sum) {\n                min_sum = day_sum[d];\n                best_day = d;\n            }\n        }\n        assign[idx] = best_day;\n        day_sum[best_day] += w;\n    }\n\n    // Local Search: Swap edges between days to minimize sum of squares of day sums\n    auto start = chrono::steady_clock::now();\n    while (true) {\n        if (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start).count() > 5000) break;\n\n        int i = rng() % M;\n        int j = rng() % M;\n        if (assign[i] == assign[j]) continue;\n\n        int d1 = assign[i], d2 = assign[j];\n        long double b1 = eb[i], b2 = eb[j];\n        long double s1 = day_sum[d1], s2 = day_sum[d2];\n        long double ns1 = s1 - b1 + b2;\n        long double ns2 = s2 - b2 + b1;\n\n        // Accept if strictly improves the load balance objective\n        if (ns1 * ns1 + ns2 * ns2 < s1 * s1 + s2 * s2 - 1e-9L) {\n            day_sum[d1] = ns1;\n            day_sum[d2] = ns2;\n            swap(assign[i], assign[j]);\n        }\n    }\n\n    // Output result (1-indexed days)\n    for (int i = 0; i < M; ++i) {\n        cout << assign[i] + 1 << (i == M - 1 ? \"\\n\" : \" \");\n    }\n\n    return 0;\n}","ahc019":"/*\n    Solution for AHC019\n    Heuristic approach:\n    1. Identify valid regions (intersection of silhouettes).\n    2. Greedily find large shared blocks by growing shapes in Config 1 and checking fit in Config 2.\n    3. Fill remaining silhouette requirements with 1x1 blocks (shared if possible).\n*/\n#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\n\nint D;\nbool F[2][14][14], R[2][14][14];\nbool Valid[2][14][14][14];\nbool Used[2][14][14][14];\nint Sol[2][14][14][14];\n\nstruct Pt { int x, y, z; };\nvector<array<array<int,3>,3>> Rots;\nvector<Pt> free_cells[2];\n\nvoid gen_rots() {\n    vector<array<int,3>> basis = {\n        {1,0,0}, {-1,0,0}, {0,1,0}, {0,-1,0}, {0,0,1}, {0,0,-1}\n    };\n    for(const auto& r1 : basis) {\n        for(const auto& r2 : basis) {\n            if(r1[0]*r2[0] + r1[1]*r2[1] + r1[2]*r2[2] != 0) continue;\n            for(const auto& r3 : basis) {\n                if(r1[0]*r3[0] + r1[1]*r3[1] + r1[2]*r3[2] != 0) continue;\n                if(r2[0]*r3[0] + r2[1]*r3[1] + r2[2]*r3[2] != 0) continue;\n                \n                int det = r1[0]*(r2[1]*r3[2] - r2[2]*r3[1])\n                        - r1[1]*(r2[0]*r3[2] - r2[2]*r3[0])\n                        + r1[2]*(r2[0]*r3[1] - r2[1]*r3[0]);\n                \n                if(det == 1) {\n                    array<array<int,3>,3> m;\n                    m[0] = r1; m[1] = r2; m[2] = r3;\n                    bool dup = false;\n                    for(const auto& exist : Rots) {\n                        if(exist == m) { dup = true; break; }\n                    }\n                    if(!dup) Rots.push_back(m);\n                }\n            }\n        }\n    }\n}\n\nstruct Placement {\n    int dx, dy, dz, rot_idx;\n};\n\nbool is_valid(int k, int x, int y, int z) {\n    return x >= 0 && x < D && y >= 0 && y < D && z >= 0 && z < D && Valid[k][x][y][z] && !Used[k][x][y][z];\n}\n\nvoid mark_used(int k, int x, int y, int z) {\n    Used[k][x][y][z] = true;\n    auto& list = free_cells[k];\n    for(int i=0; i<(int)list.size(); i++) {\n        if(list[i].x == x && list[i].y == y && list[i].z == z) {\n            list[i] = list.back();\n            list.pop_back();\n            break;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(0); cin.tie(0);\n    if(!(cin >> D)) return 0;\n    \n    string s;\n    for(int k=0; k<2; k++) {\n        for(int z=0; z<D; z++) {\n            cin >> s;\n            for(int x=0; x<D; x++) F[k][z][x] = (s[x] == '1');\n        }\n        for(int z=0; z<D; z++) {\n            cin >> s;\n            for(int y=0; y<D; y++) R[k][z][y] = (s[y] == '1');\n        }\n        for(int x=0; x<D; x++)\n            for(int y=0; y<D; y++)\n                for(int z=0; z<D; z++) {\n                    Valid[k][x][y][z] = F[k][z][x] && R[k][z][y];\n                    if(Valid[k][x][y][z]) {\n                        free_cells[k].push_back({x,y,z});\n                    }\n                    Used[k][x][y][z] = false;\n                    Sol[k][x][y][z] = 0;\n                }\n    }\n    \n    gen_rots();\n    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n    for(int k=0; k<2; k++) shuffle(free_cells[k].begin(), free_cells[k].end(), rng);\n    \n    int block_id = 1;\n    int max_iters = 20000;\n    \n    while(max_iters-- > 0) {\n        Pt seed = {-1,-1,-1};\n        for(const auto& p : free_cells[0]) {\n            if(!Used[0][p.x][p.y][p.z]) {\n                seed = p;\n                break;\n            }\n        }\n        if(seed.x == -1) break;\n        \n        if(free_cells[1].empty()) break;\n        \n        vector<Pt> shape;\n        shape.push_back({0,0,0});\n        \n        vector<Placement> valid_placements;\n        valid_placements.reserve(free_cells[1].size());\n        for(const auto& p : free_cells[1]) {\n            valid_placements.push_back({p.x, p.y, p.z, 0});\n        }\n        \n        if(valid_placements.empty()) break;\n        \n        int growth_limit = 50;\n        bool grew = true;\n        int dirs[6][3] = {{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}};\n        \n        while(grew && (int)shape.size() < growth_limit) {\n            grew = false;\n            vector<Pt> candidates;\n            \n            for(const auto& rel : shape) {\n                int ax = seed.x + rel.x;\n                int ay = seed.y + rel.y;\n                int az = seed.z + rel.z;\n                for(auto& d : dirs) {\n                    int nx = ax + d[0];\n                    int ny = ay + d[1];\n                    int nz = az + d[2];\n                    if(is_valid(0, nx, ny, nz)) {\n                        Pt rel_n = {nx - seed.x, ny - seed.y, nz - seed.z};\n                        bool in_shape = false;\n                        for(const auto& s : shape) {\n                            if(s.x == rel_n.x && s.y == rel_n.y && s.z == rel_n.z) {\n                                in_shape = true; break;\n                            }\n                        }\n                        if(!in_shape) candidates.push_back(rel_n);\n                    }\n                }\n            }\n            \n            sort(candidates.begin(), candidates.end(), [](const Pt& a, const Pt& b){\n                if(a.x != b.x) return a.x < b.x;\n                if(a.y != b.y) return a.y < b.y;\n                return a.z < b.z;\n            });\n            candidates.erase(unique(candidates.begin(), candidates.end(), [](const Pt& a, const Pt& b){\n                return a.x==b.x && a.y==b.y && a.z==b.z;\n            }), candidates.end());\n            \n            shuffle(candidates.begin(), candidates.end(), rng);\n            \n            for(const auto& cand : candidates) {\n                vector<Placement> next_placements;\n                next_placements.reserve(valid_placements.size());\n                \n                for(const auto& pl : valid_placements) {\n                    const auto& rot = Rots[pl.rot_idx];\n                    int rx = rot[0][0]*cand.x + rot[0][1]*cand.y + rot[0][2]*cand.z;\n                    int ry = rot[1][0]*cand.x + rot[1][1]*cand.y + rot[1][2]*cand.z;\n                    int rz = rot[2][0]*cand.x + rot[2][1]*cand.y + rot[2][2]*cand.z;\n                    \n                    int ax = pl.dx + rx;\n                    int ay = pl.dy + ry;\n                    int az = pl.dz + rz;\n                    \n                    if(is_valid(1, ax, ay, az)) {\n                        next_placements.push_back(pl);\n                    }\n                }\n                \n                if(!next_placements.empty()) {\n                    shape.push_back(cand);\n                    valid_placements = next_placements;\n                    grew = true;\n                    break;\n                }\n            }\n        }\n        \n        if(!shape.empty()) {\n            Placement chosen = valid_placements[rng() % valid_placements.size()];\n            const auto& rot = Rots[chosen.rot_idx];\n            \n            for(const auto& rel : shape) {\n                mark_used(0, seed.x + rel.x, seed.y + rel.y, seed.z + rel.z);\n                Sol[0][seed.x + rel.x][seed.y + rel.y][seed.z + rel.z] = block_id;\n            }\n            \n            for(const auto& rel : shape) {\n                int rx = rot[0][0]*rel.x + rot[0][1]*rel.y + rot[0][2]*rel.z;\n                int ry = rot[1][0]*rel.x + rot[1][1]*rel.y + rot[1][2]*rel.z;\n                int rz = rot[2][0]*rel.x + rot[2][1]*rel.y + rot[2][2]*rel.z;\n                int ax = chosen.dx + rx;\n                int ay = chosen.dy + ry;\n                int az = chosen.dz + rz;\n                mark_used(1, ax, ay, az);\n                Sol[1][ax][ay][az] = block_id;\n            }\n            \n            block_id++;\n        }\n    }\n    \n    // Cover silhouettes\n    auto cover = [&](int k) {\n        for(int z=0; z<D; z++) {\n            for(int x=0; x<D; x++) {\n                if(F[k][z][x]) {\n                    bool covered = false;\n                    for(int y=0; y<D; y++) if(Sol[k][x][y][z] != 0) { covered = true; break; }\n                    if(!covered) {\n                        int best_y = -1;\n                        for(int y=0; y<D; y++) if(Valid[k][x][y][z] && !Used[k][x][y][z]) { best_y = y; break; }\n                        if(best_y != -1) {\n                            int share_x=-1, share_y=-1, share_z=-1;\n                            int other = 1-k;\n                            for(const auto& p : free_cells[other]) if(!Used[other][p.x][p.y][p.z]) { share_x=p.x; share_y=p.y; share_z=p.z; break; }\n                            if(share_x != -1) {\n                                mark_used(k, x, best_y, z); Sol[k][x][best_y][z] = block_id;\n                                mark_used(other, share_x, share_y, share_z); Sol[other][share_x][share_y][share_z] = block_id;\n                                block_id++;\n                            } else {\n                                mark_used(k, x, best_y, z); Sol[k][x][best_y][z] = block_id;\n                                block_id++;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        for(int z=0; z<D; z++) {\n            for(int y=0; y<D; y++) {\n                if(R[k][z][y]) {\n                    bool covered = false;\n                    for(int x=0; x<D; x++) if(Sol[k][x][y][z] != 0) { covered = true; break; }\n                    if(!covered) {\n                        int best_x = -1;\n                        for(int x=0; x<D; x++) if(Valid[k][x][y][z] && !Used[k][x][y][z]) { best_x = x; break; }\n                        if(best_x != -1) {\n                            int share_x=-1, share_y=-1, share_z=-1;\n                            int other = 1-k;\n                            for(const auto& p : free_cells[other]) if(!Used[other][p.x][p.y][p.z]) { share_x=p.x; share_y=p.y; share_z=p.z; break; }\n                            if(share_x != -1) {\n                                mark_used(k, best_x, y, z); Sol[k][best_x][y][z] = block_id;\n                                mark_used(other, share_x, share_y, share_z); Sol[other][share_x][share_y][share_z] = block_id;\n                                block_id++;\n                            } else {\n                                mark_used(k, best_x, y, z); Sol[k][best_x][y][z] = block_id;\n                                block_id++;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    };\n    \n    cover(0);\n    cover(1);\n    \n    cout << block_id - 1 << \"\\n\";\n    for(int k=0; k<2; k++) {\n        bool first = true;\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(!first) cout << \" \";\n                    cout << Sol[k][x][y][z];\n                    first = false;\n                }\n            }\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <chrono>\n#include <iomanip>\n\nusing namespace std;\n\n// Global variables\nint N, M, K;\nstruct Point { int x, y; };\nvector<Point> pts;\nvector<Point> residents;\n\nstruct Edge { int u, v; int w; };\nvector<Edge> edges;\n\n// Precomputed data\nvector<vector<double>> dists; \nvector<vector<int>> sorted_vertices; \n\n// Graph\nvector<vector<pair<int, int>>> adj; \nvector<int> sorted_edge_indices;\n\n// State\nvector<int> active; \nvector<int> assignment; \nvector<double> resident_dist; \nvector<vector<int>> residents_at; \nvector<double> max_radius; \n\n// Helper for MST\nvector<int> parent;\nint find_set(int v) {\n    if (v == parent[v]) return v;\n    return parent[v] = find_set(parent[v]);\n}\nbool union_sets(int a, int b) {\n    a = find_set(a); b = find_set(b);\n    if (a != b) { parent[b] = a; return true; }\n    return false;\n}\n\n// Connectivity buffers\nvector<int> q_bfs;\nvector<int> vis_token;\nint current_token = 0;\nint active_count = 0;\n\n// Check connectivity of active nodes (assuming active[0] is true)\nbool is_connected() {\n    if (active_count <= 1) return true; \n    \n    current_token++;\n    q_bfs.clear();\n    q_bfs.push_back(0);\n    vis_token[0] = current_token;\n    int count = 1;\n    \n    int head = 0;\n    while(head < (int)q_bfs.size()){\n        int u = q_bfs[head++];\n        for(auto& edge : adj[u]){\n            int v = edge.first;\n            if(active[v] && vis_token[v] != current_token){\n                vis_token[v] = current_token;\n                count++;\n                q_bfs.push_back(v);\n            }\n        }\n    }\n    return count == active_count;\n}\n\nlong long compute_mst() {\n    for(int i=0; i<N; ++i) parent[i] = i;\n    long long cost = 0;\n    int edges_used = 0;\n    if (active_count <= 1) return 0;\n    \n    for (int idx : sorted_edge_indices) {\n        const auto& e = edges[idx];\n        if (active[e.u] && active[e.v]) {\n            if (union_sets(e.u, e.v)) {\n                cost += e.w;\n                edges_used++;\n                if (edges_used == active_count - 1) break;\n            }\n        }\n    }\n    if (edges_used < active_count - 1) return -1; \n    return cost;\n}\n\nvoid update_max_radius(int u) {\n    double m = 0.0;\n    for(int k : residents_at[u]){\n        if(resident_dist[k] > m) m = resident_dist[k];\n    }\n    max_radius[u] = m;\n}\n\n// Move resident k to new_u. Updates state.\n// Expects k to be in residents_at[old_u] (usually).\nvoid move_resident(int k, int old_u, int new_u) {\n    if (old_u == new_u) return;\n    \n    // Remove from old\n    auto& old_list = residents_at[old_u];\n    bool found = false;\n    for (size_t i = 0; i < old_list.size(); ++i) {\n        if (old_list[i] == k) {\n            old_list[i] = old_list.back();\n            old_list.pop_back();\n            found = true;\n            break;\n        }\n    }\n    // If not found, it means it was already removed (e.g. via swap or logic).\n    // We proceed to add to new.\n    \n    // Add to new\n    residents_at[new_u].push_back(k);\n    \n    // Update assignment and dist\n    assignment[k] = new_u;\n    resident_dist[k] = dists[new_u][k];\n    \n    // Update max radii\n    update_max_radius(old_u);\n    update_max_radius(new_u);\n}\n\n// Reverse move\nvoid move_resident_back(int k, int new_u, int old_u) {\n    if (old_u == new_u) return;\n\n    // Remove from new\n    auto& new_list = residents_at[new_u];\n    for (size_t i = 0; i < new_list.size(); ++i) {\n        if (new_list[i] == k) {\n            new_list[i] = new_list.back();\n            new_list.pop_back();\n            break;\n        }\n    }\n    \n    // Add to old\n    residents_at[old_u].push_back(k);\n    \n    // Update assignment\n    assignment[k] = old_u;\n    resident_dist[k] = dists[old_u][k];\n    \n    update_max_radius(new_u);\n    update_max_radius(old_u);\n}\n\n// Calculate radii cost\ndouble compute_radii_cost() {\n    double cost = 0.0;\n    for(int i=0; i<N; ++i){\n        if(active[i]){\n            int p = (int)ceil(max_radius[i]);\n            if (p < 0) p = 0;\n            if (p > 5000) p = 5000;\n            cost += (double)p * p;\n        }\n    }\n    return cost;\n}\n\nstruct MoveRecord {\n    int k;\n    int old_u;\n};\n\n// Buffer to avoid allocations\nvector<int> buffer_residents;\nvector<MoveRecord> history;\n\nint main() {\n    cin.tie(nullptr)->sync_with_stdio(false);\n    mt19937_64 rng(chrono::high_resolution_clock::now().time_since_epoch().count());\n\n    if (!(cin >> N >> M >> K)) return 0;\n\n    pts.resize(N);\n    for (int i = 0; i < N; ++i) cin >> pts[i].x >> pts[i].y;\n\n    edges.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> edges[i].u >> edges[i].v >> edges[i].w;\n        --edges[i].u; --edges[i].v;\n    }\n\n    residents.resize(K);\n    for (int i = 0; i < K; ++i) cin >> residents[i].x >> residents[i].y;\n\n    dists.assign(N, vector<double>(K));\n    for (int i = 0; i < N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            dists[i][k] = hypot(pts[i].x - residents[k].x, pts[i].y - residents[k].y);\n        }\n    }\n\n    sorted_vertices.assign(K, vector<int>(N));\n    for (int k = 0; k < K; ++k) {\n        iota(sorted_vertices[k].begin(), sorted_vertices[k].end(), 0);\n        sort(sorted_vertices[k].begin(), sorted_vertices[k].end(), [&](int a, int b) {\n            return dists[a][k] < dists[b][k];\n        });\n    }\n\n    adj.assign(N, vector<pair<int, int>>());\n    for (int i = 0; i < M; ++i) {\n        adj[edges[i].u].push_back({edges[i].v, i});\n        adj[edges[i].v].push_back({edges[i].u, i});\n    }\n\n    sorted_edge_indices.resize(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) {\n        return edges[a].w < edges[b].w;\n    });\n\n    active.assign(N, 1); \n    active_count = N;\n    \n    assignment.assign(K, 0);\n    resident_dist.assign(K, 0.0);\n    residents_at.assign(N, vector<int>());\n    max_radius.assign(N, 0.0);\n\n    for (int k = 0; k < K; ++k) {\n        int best_u = 0;\n        double best_d = dists[0][k];\n        for (int u = 1; u < N; ++u) {\n            if (dists[u][k] < best_d) {\n                best_d = dists[u][k];\n                best_u = u;\n            }\n        }\n        assignment[k] = best_u;\n        resident_dist[k] = best_d;\n        residents_at[best_u].push_back(k);\n    }\n    \n    for (int u = 0; u < N; ++u) {\n        update_max_radius(u);\n    }\n\n    parent.resize(N);\n    long long cur_S_mst = compute_mst();\n    double cur_S_radii = compute_radii_cost();\n    double cur_S = cur_S_mst + cur_S_radii;\n    double best_S = cur_S;\n    \n    vector<int> best_active = active;\n\n    q_bfs.reserve(N);\n    vis_token.assign(N, 0);\n    \n    // SA Parameters\n    double temp = 1e6; \n    auto start_time = chrono::steady_clock::now();\n    \n    history.reserve(K);\n    buffer_residents.reserve(K);\n\n    uniform_int_distribution<int> dist_u(1, N-1); \n    uniform_real_distribution<double> dist_01(0.0, 1.0);\n\n    while (true) {\n        double elapsed = chrono::duration_cast<chrono::duration<double>>(chrono::steady_clock::now() - start_time).count();\n        if (elapsed > 1.90) break;\n\n        int u = dist_u(rng);\n        bool was_active = (active[u] == 1);\n        bool accepted = false;\n\n        history.clear();\n\n        if (was_active) {\n            // Try Remove u\n            active[u] = 0;\n            active_count--;\n            \n            if (!is_connected()) {\n                active[u] = 1;\n                active_count++;\n                continue;\n            }\n            \n            // Copy residents to move\n            buffer_residents = residents_at[u];\n            \n            bool possible = true;\n            \n            for (int k : buffer_residents) {\n                int best_v = -1;\n                double best_d = 1e18;\n                \n                const auto& cands = sorted_vertices[k];\n                for (int v : cands) {\n                    if (active[v]) { \n                        best_v = v;\n                        best_d = dists[v][k];\n                        break;\n                    }\n                }\n                \n                if (best_v == -1 || best_d > 5000.0 + 1e-7) {\n                    possible = false;\n                    break;\n                }\n                \n                move_resident(k, u, best_v);\n                history.push_back({k, u});\n            }\n            \n            if (possible) {\n                long long new_mst = compute_mst();\n                if (new_mst != -1) {\n                    double new_radii = compute_radii_cost();\n                    double new_S = new_mst + new_radii;\n                    double delta = new_S - cur_S;\n                    bool accept_move = false;\n                    if (delta < 0) accept_move = true;\n                    else {\n                        if (delta < 50.0 * temp) { \n                            if (dist_01(rng) < exp(-delta / temp)) accept_move = true;\n                        }\n                    }\n\n                    if (accept_move) {\n                        accepted = true;\n                        cur_S = new_S;\n                        cur_S_mst = new_mst;\n                        cur_S_radii = new_radii;\n                        if (new_S < best_S) {\n                            best_S = new_S;\n                            best_active = active;\n                        }\n                    }\n                }\n            }\n\n            if (!accepted) {\n                // Rollback\n                for (auto it = history.rbegin(); it != history.rend(); ++it) {\n                    int k = it->k;\n                    int current_u = assignment[k];\n                    move_resident_back(k, current_u, u);\n                }\n                \n                active[u] = 1;\n                active_count++;\n            }\n\n        } else {\n            // Try Add u\n            \n            // Pruning: Check if u can improve any resident's distance\n            bool improves = false;\n            for(int k=0; k<K; ++k) {\n                if(dists[u][k] < resident_dist[k]) {\n                    improves = true;\n                    break;\n                }\n            }\n            \n            if (!improves) {\n                continue; \n            }\n\n            active[u] = 1;\n            active_count++;\n            \n            for(int k=0; k<K; ++k) {\n                if(dists[u][k] < resident_dist[k]) {\n                    int old_u = assignment[k];\n                    move_resident(k, old_u, u);\n                    history.push_back({k, old_u});\n                }\n            }\n            \n            long long new_mst = compute_mst();\n            if (new_mst != -1) {\n                double new_radii = compute_radii_cost();\n                double new_S = new_mst + new_radii;\n                double delta = new_S - cur_S;\n                \n                bool accept_move = false;\n                if (delta < 0) accept_move = true;\n                else {\n                    if (delta < 50.0 * temp) {\n                        if (dist_01(rng) < exp(-delta / temp)) accept_move = true;\n                    }\n                }\n\n                if (accept_move) {\n                    accepted = true;\n                    cur_S = new_S;\n                    cur_S_mst = new_mst;\n                    cur_S_radii = new_radii;\n                    if (new_S < best_S) {\n                        best_S = new_S;\n                        best_active = active;\n                    }\n                }\n            }\n            \n            if (!accepted) {\n                for (auto it = history.rbegin(); it != history.rend(); ++it) {\n                    int k = it->k;\n                    int old_u = it->old_u;\n                    int current_u = assignment[k];\n                    move_resident_back(k, current_u, old_u);\n                }\n                active[u] = 0;\n                active_count--;\n            }\n        }\n        \n        temp *= 0.99995; \n        if (temp < 1e-9) temp = 1e-9;\n    }\n\n    // Restore best state\n    active = best_active;\n    active_count = 0;\n    for(int x : active) if(x) active_count++;\n    \n    for(int i=0; i<N; ++i) residents_at[i].clear();\n    \n    for (int k = 0; k < K; ++k) {\n        int best_u = -1;\n        double best_d = 1e18;\n        const auto& cands = sorted_vertices[k];\n        for (int v : cands) {\n            if (active[v]) {\n                best_u = v;\n                best_d = dists[v][k];\n                break;\n            }\n        }\n        assignment[k] = best_u;\n        resident_dist[k] = best_d;\n        residents_at[best_u].push_back(k);\n    }\n    for (int u = 0; u < N; ++u) update_max_radius(u);\n\n    for(int i=0; i<N; ++i) parent[i] = i;\n    vector<int> edge_used(M, 0);\n    \n    for (int idx : sorted_edge_indices) {\n        const auto& e = edges[idx];\n        if (active[e.u] && active[e.v]) {\n            if (union_sets(e.u, e.v)) {\n                edge_used[idx] = 1;\n            }\n        }\n    }\n    \n    cout << fixed << setprecision(0);\n    for (int i = 0; i < N; ++i) {\n        int p = 0;\n        if (active[i]) {\n            p = (int)ceil(max_radius[i]);\n            if (p < 0) p = 0;\n            if (p > 5000) p = 5000;\n        }\n        cout << p << (i == N-1 ? \"\" : \" \");\n    }\n    cout << \"\\n\";\n    \n    for (int i = 0; i < M; ++i) {\n        cout << edge_used[i] << (i == M-1 ? \"\" : \" \");\n    }\n    cout << \"\\n\";\n\n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <chrono>\n#include <random>\n#include <utility>\n\nusing namespace std;\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 30;\n    const int TOTAL = N * (N + 1) / 2;\n    vector<int> grid(TOTAL);\n    for (int i = 0; i < TOTAL; ++i) cin >> grid[i];\n\n    // Precompute (x, y) coordinates for each index\n    vector<int> x_coord(TOTAL), y_coord(TOTAL);\n    int idx = 0;\n    for (int x = 0; x < N; ++x)\n        for (int y = 0; y <= x; ++y)\n            x_coord[idx] = x, y_coord[idx] = y, idx++;\n\n    // Precompute children indices for O(1) access\n    vector<pair<int, int>> children(TOTAL, {-1, -1});\n    for (int i = 0; i < TOTAL; ++i) {\n        int x = x_coord[i], y = y_coord[i];\n        if (x + 1 < N) {\n            children[i] = {(x + 1) * (x + 2) / 2 + y, (x + 1) * (x + 2) / 2 + y + 1};\n        }\n    }\n\n    vector<pair<int, int>> best_ops;\n    best_ops.reserve(5000);\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    auto start = chrono::high_resolution_clock::now();\n\n    int trial = 0;\n    const int MAX_TRIALS = 5000;\n    \n    while (trial < MAX_TRIALS) {\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start).count() > 1850) break;\n\n        vector<int> g = grid;\n        vector<pair<int, int>> ops;\n        ops.reserve(5000);\n\n        // Strategy selection: 0=Baseline, 1=Value-Desc, 2+=Random\n        int strategy = (trial == 0) ? 0 : (rng() % 10 < 2 ? 1 : 2);\n\n        for (int x = N - 2; x >= 0; --x) {\n            int start_idx = x * (x + 1) / 2;\n            int count = x + 1;\n            int tier_nodes[30]; // Max nodes in a tier is 30\n            for (int i = 0; i < count; ++i) tier_nodes[i] = start_idx + i;\n\n            if (strategy == 1) {\n                // Sort by initial value descending: larger values sift down first\n                sort(tier_nodes, tier_nodes + count, [&](int a, int b) {\n                    return grid[a] > grid[b];\n                });\n            } else if (strategy >= 2) {\n                shuffle(tier_nodes, tier_nodes + count, rng);\n            }\n\n            for (int i = 0; i < count; ++i) {\n                int curr = tier_nodes[i];\n                while (true) {\n                    auto [c1, c2] = children[curr];\n                    if (c1 == -1) break; // Leaf node\n                    \n                    int target = (g[c1] < g[c2]) ? c1 : c2;\n                    if (g[curr] > g[target]) {\n                        swap(g[curr], g[target]);\n                        ops.emplace_back(curr, target);\n                        curr = target;\n                    } else {\n                        break;\n                    }\n                }\n            }\n        }\n\n        // Keep the sequence with the fewest operations\n        if ((best_ops.empty() || ops.size() < best_ops.size()) && ops.size() <= 9950) {\n            best_ops = move(ops);\n        }\n        trial++;\n    }\n\n    // Output results\n    cout << best_ops.size() << \"\\n\";\n    for (const auto& op : best_ops) {\n        cout << x_coord[op.first] << \" \" << y_coord[op.first] << \" \"\n             << x_coord[op.second] << \" \" << y_coord[op.second] << \"\\n\";\n    }\n\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D, N;\nint grid[12][12]; \nint er, ec;\nint dr[4] = {-1, 1, 0, 0};\nint dc[4] = {0, 0, -1, 1};\npair<int, int> placed[100]; // Maps container ID to its position\n\n// Check if coordinates are within grid\nbool valid(int r, int c) {\n    return r >= 0 && r < D && c >= 0 && c < D;\n}\n\n// BFS to count reachable empty squares (0) from entrance.\n// Traversable cells: Empty (0) or Entrance (-2).\n// Obstacles (-1), Blocked (-3), and Containers (>0) are walls.\nint count_reachable_empty() {\n    int count = 0;\n    bool vis[12][12] = {};\n    queue<pair<int, int>> q;\n    q.push({er, ec});\n    vis[er][ec] = true;\n    \n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        if (grid[r][c] == 0) count++;\n        \n        for (int i = 0; i < 4; i++) {\n            int nr = r + dr[i], nc = c + dc[i];\n            if (valid(nr, nc) && !vis[nr][nc]) {\n                // Can only traverse empty squares or entrance\n                if (grid[nr][nc] == 0 || grid[nr][nc] == -2) {\n                    vis[nr][nc] = true;\n                    q.push({nr, nc});\n                }\n            }\n        }\n    }\n    return count;\n}\n\nint main() {\n    // Optimize I/O operations\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> D >> N;\n    er = 0; ec = (D - 1) / 2;\n    \n    // Initialize grid\n    for (int i = 0; i < D; i++) fill(grid[i], grid[i] + D, 0);\n    grid[er][ec] = -2; // Mark entrance\n    \n    for (int i = 0; i < N; i++) {\n        int r, c; cin >> r >> c;\n        grid[r][c] = -1; // Mark obstacle\n    }\n\n    int M = D * D - 1 - N; // Total containers to place\n    \n    // Placement Phase\n    for (int d = 0; d < M; d++) {\n        int t; cin >> t;\n        \n        // 1. Find all currently reachable empty squares and their distances from entrance\n        // Store as tuples: {distance, row, col}\n        vector<tuple<int, int, int>> reach; \n        bool vis[12][12] = {};\n        queue<tuple<int, int, int>> q; // r, c, dist\n        q.push({er, ec, 0});\n        vis[er][ec] = true;\n\n        while (!q.empty()) {\n            auto [r, c, dist] = q.front(); q.pop();\n            \n            for (int i = 0; i < 4; i++) {\n                int nr = r + dr[i], nc = c + dc[i];\n                if (valid(nr, nc) && !vis[nr][nc]) {\n                    if (grid[nr][nc] == 0) {\n                        vis[nr][nc] = true;\n                        reach.emplace_back(dist + 1, nr, nc);\n                        q.push({nr, nc, dist + 1});\n                    }\n                }\n            }\n        }\n        \n        // 2. Filter \"safe\" squares.\n        // A square is safe if placing a container there does not disconnect any other empty square from the entrance.\n        // We check this by temporarily blocking the square and verifying connectivity.\n        int total_empty = 0;\n        for(int i=0; i<D; ++i) for(int j=0; j<D; ++j) if(grid[i][j] == 0) total_empty++;\n        \n        vector<tuple<int, int, int>> safe_reach; \n        \n        for(auto& tup : reach) {\n            int dist = get<0>(tup);\n            int r = get<1>(tup);\n            int c = get<2>(tup);\n\n            // Temporarily block the square\n            grid[r][c] = -3; \n            int cnt = count_reachable_empty();\n            \n            // If we can still reach all other empty squares, it is safe.\n            // The blocked square itself is no longer empty, so we expect count to be total_empty - 1.\n            if(cnt == total_empty - 1) {\n                safe_reach.emplace_back(dist, r, c);\n            }\n            \n            // Revert the block\n            grid[r][c] = 0;\n        }\n        \n        // Fallback: If no safe squares found (unlikely if logic holds), allow placement in any reachable square\n        // to avoid getting stuck, though this might lead to suboptimal connectivity.\n        if(safe_reach.empty()) {\n            for(auto& tup : reach) {\n                safe_reach.push_back(tup);\n            }\n        }\n        \n        // 3. Sort safe squares by distance (closest to entrance first)\n        sort(safe_reach.begin(), safe_reach.end());\n\n        // 4. Choose a square based on the container ID t.\n        // Strategy: Place smaller IDs (retrieved earlier) closer to the entrance.\n        // Map t (0..M-1) to an index in the sorted list of safe squares.\n        int idx = 0;\n        if(!safe_reach.empty()) {\n            if(safe_reach.size() > 1)\n                idx = (int)((long long)t * (safe_reach.size() - 1) / (M - 1));\n            else\n                idx = 0;\n        }\n        \n        // Safety check for index bounds\n        if(idx >= (int)safe_reach.size()) idx = safe_reach.size() - 1;\n        if(idx < 0) idx = 0;\n\n        auto [dist, pr, pc] = safe_reach[idx];\n        placed[t] = {pr, pc};\n        grid[pr][pc] = t + 1; // Store container ID (+1 to distinguish from 0/empty)\n        cout << pr << \" \" << pc << \"\\n\" << flush;\n    }\n\n    // Retrieval Phase\n    vector<bool> retrieved(M, false);\n    for (int k = 0; k < M; k++) {\n        // BFS to find all empty squares reachable from the entrance\n        bool is_reach[12][12] = {};\n        bool vis[12][12] = {};\n        queue<pair<int, int>> q;\n        q.push({er, ec});\n        vis[er][ec] = true;\n        is_reach[er][ec] = true; // Entrance is reachable and empty\n\n        while (!q.empty()) {\n            auto [r, c] = q.front(); q.pop();\n            for (int i = 0; i < 4; i++) {\n                int nr = r + dr[i], nc = c + dc[i];\n                if (valid(nr, nc) && !vis[nr][nc]) {\n                    if (grid[nr][nc] == 0) { // Only traverse empty squares\n                        vis[nr][nc] = true;\n                        is_reach[nr][nc] = true;\n                        q.push({nr, nc});\n                    }\n                }\n            }\n        }\n\n        int best_id = -1;\n        pair<int, int> best_pos = {-1, -1};\n\n        // Greedily pick the smallest ID that is accessible.\n        // A container is accessible if it is adjacent to a reachable empty square.\n        for (int id = 0; id < M; id++) {\n            if (retrieved[id]) continue;\n            auto [r, c] = placed[id];\n            \n            bool reachable = false;\n            for (int i = 0; i < 4; i++) {\n                int nr = r + dr[i], nc = c + dc[i];\n                if (valid(nr, nc) && is_reach[nr][nc]) {\n                    reachable = true;\n                    break;\n                }\n            }\n            \n            if (reachable) {\n                best_id = id;\n                best_pos = {r, c};\n                break; // Found the smallest retrievable ID\n            }\n        }\n        \n        if(best_id != -1) {\n            retrieved[best_id] = true;\n            grid[best_pos.first][best_pos.second] = 0; // Free up the square\n            cout << best_pos.first << \" \" << best_pos.second << \"\\n\" << flush;\n        }\n    }\n\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 52;\nconst int MAXM = 101;\n\nint grid[MAXN][MAXN];\nint contacts[MAXM][MAXM] = {0};\nbool adj_target[MAXM][MAXM] = {false};\nint n, m;\n\n// BFS to check if all 0-cells are connected to the boundary (and thus to the outside)\nbool is_zero_connected() {\n    int zero_cnt = 0;\n    for (int i = 0; i <= n + 1; ++i)\n        for (int j = 0; j <= n + 1; ++j)\n            if (grid[i][j] == 0) zero_cnt++;\n    if (zero_cnt == 0) return true;\n\n    static int q[MAXN * MAXN][2];\n    static bool vis[MAXN][MAXN];\n    int head = 0, tail = 0;\n    memset(vis, 0, sizeof(vis));\n\n    // Start from (0,0), which is always 0 due to padding\n    vis[0][0] = true;\n    q[tail][0] = 0; q[tail][1] = 0; tail++;\n    int cnt = 0;\n    const int dirs[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};\n    \n    while (head < tail) {\n        int r = q[head][0], c = q[head][1]; head++; cnt++;\n        for (auto& d : dirs) {\n            int nr = r + d[0], nc = c + d[1];\n            if (nr >= 0 && nr <= n + 1 && nc >= 0 && nc <= n + 1 && \n                grid[nr][nc] == 0 && !vis[nr][nc]) {\n                vis[nr][nc] = true;\n                q[tail][0] = nr; q[tail][1] = nc; tail++;\n            }\n        }\n    }\n    return cnt == zero_cnt;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> n >> m;\n    memset(grid, 0, sizeof(grid)); // Initialize border with 0\n    for (int i = 1; i <= n; ++i)\n        for (int j = 1; j <= n; ++j)\n            cin >> grid[i][j];\n\n    const int dirs[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};\n    \n    // Compute initial adjacency targets and contact counts on padded grid\n    for (int i = 0; i <= n + 1; ++i) {\n        for (int j = 0; j <= n + 1; ++j) {\n            for (int k = 0; k < 2; ++k) { // Check right and down to avoid double counting\n                int ni = i + (k == 1), nj = j + (k == 0);\n                if (ni <= n + 1 && nj <= n + 1) {\n                    int u = grid[i][j], v = grid[ni][nj];\n                    if (u != v) {\n                        if (u > v) swap(u, v);\n                        contacts[u][v]++;\n                        adj_target[u][v] = adj_target[v][u] = true;\n                    }\n                }\n            }\n        }\n    }\n\n    vector<pair<int, int>> zeros;\n    for (int i = 1; i <= n; ++i)\n        for (int j = 1; j <= n; ++j)\n            if (grid[i][j] == 0) zeros.emplace_back(i, j);\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    auto start_time = chrono::steady_clock::now();\n\n    for (int iter = 0; iter < 20; ++iter) {\n        // Time guard\n        if (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() > 1850) break;\n        \n        shuffle(zeros.begin(), zeros.end(), rng);\n        bool changed = false;\n\n        for (auto& [r, c] : zeros) {\n            if (grid[r][c] != 0) continue;\n\n            int zero_nb = 0;\n            for (auto& d : dirs) {\n                if (grid[r + d[0]][c + d[1]] == 0) zero_nb++;\n            }\n\n            // Collect unique neighboring colors\n            vector<int> cands;\n            for (auto& d : dirs) {\n                int x = grid[r + d[0]][c + d[1]];\n                if (x != 0) {\n                    if (find(cands.begin(), cands.end(), x) == cands.end())\n                        cands.push_back(x);\n                }\n            }\n            if (cands.empty()) continue;\n\n            for (int col : cands) {\n                // 1. Check forbidden adjacencies\n                bool bad = false;\n                for (auto& d : dirs) {\n                    int x = grid[r + d[0]][c + d[1]];\n                    if (x != 0 && x != col && !adj_target[col][x]) {\n                        bad = true; break;\n                    }\n                }\n                if (bad) continue;\n\n                // 2. Tentatively update contact counts\n                vector<pair<int, int>> dec_c, inc_c;\n                for (auto& d : dirs) {\n                    int x = grid[r + d[0]][c + d[1]];\n                    if (x == 0) continue;\n                    dec_c.emplace_back(min(0, x), max(0, x));\n                    inc_c.emplace_back(min(col, x), max(col, x));\n                }\n\n                bool dropped_req = false;\n                for (auto& p : dec_c) {\n                    if (--contacts[p.first][p.second] == 0 && adj_target[p.first][p.second]) {\n                        dropped_req = true;\n                    }\n                    if (dropped_req) break;\n                }\n                if (dropped_req) {\n                    for (auto& p : dec_c) contacts[p.first][p.second]++;\n                    continue;\n                }\n                for (auto& p : inc_c) contacts[p.first][p.second]++;\n\n                // 3. Check 0-connectivity (skip if safe by graph property)\n                bool conn_ok = true;\n                if (zero_nb > 1) {\n                    grid[r][c] = col;\n                    conn_ok = is_zero_connected();\n                    grid[r][c] = 0;\n                }\n\n                if (conn_ok) {\n                    grid[r][c] = col; // Commit change\n                    changed = true;\n                } else {\n                    // Revert contacts\n                    for (auto& p : inc_c) contacts[p.first][p.second]--;\n                    for (auto& p : dec_c) contacts[p.first][p.second]++;\n                }\n            }\n        }\n\n        // Update zeros list for next iteration\n        zeros.clear();\n        for (int i = 1; i <= n; ++i)\n            for (int j = 1; j <= n; ++j)\n                if (grid[i][j] == 0) zeros.emplace_back(i, j);\n                \n        if (!changed) break; // Local optimum reached\n    }\n\n    // Output result\n    for (int i = 1; i <= n; ++i) {\n        for (int j = 1; j <= n; ++j) {\n            cout << grid[i][j] << (j == n ? \"\\n\" : \" \");\n        }\n    }\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <string>\n\nusing namespace std;\n\nint main() {\n    // Optimize I/O operations for speed\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, D, Q;\n    if (!(cin >> N >> D >> Q)) return 0;\n\n    // Permutation of items and their accumulated strength scores\n    vector<int> p(N);\n    iota(p.begin(), p.end(), 0);\n    vector<double> score(N, 0.0);\n\n    // Phase 1: Comb Sort to quickly order heavy items\n    // Shrinking gap moves items closer to their correct positions faster than bubble sort\n    double gap = N;\n    while (gap > 1.0 && Q > 0) {\n        gap /= 1.3;\n        if (gap < 1.0) gap = 1.0;\n        int g = static_cast<int>(gap);\n        \n        for (int i = 0; i < N - g && Q > 0; ++i) {\n            cout << \"1 1 \" << p[i] << \" \" << p[i+g] << \"\\n\";\n            cout.flush();\n            \n            string res;\n            cin >> res;\n            Q--;\n\n            // Update order and scores based on balance result\n            if (res == \"<\") { // Left is lighter\n                swap(p[i], p[i+g]);\n                score[p[i]] += 1.0;\n                score[p[i+g]] -= 1.0;\n            } else if (res == \">\") { // Left is heavier\n                score[p[i]] += 1.0;\n                score[p[i+g]] -= 1.0;\n            } else { // Equal\n                score[p[i]] += 0.5;\n                score[p[i+g]] -= 0.5;\n            }\n        }\n    }\n\n    // Phase 2: Adjacent swaps to refine ordering with remaining queries\n    while (Q > 0) {\n        for (int i = 0; i < N - 1 && Q > 0; ++i) {\n            cout << \"1 1 \" << p[i] << \" \" << p[i+1] << \"\\n\";\n            cout.flush();\n            \n            string res;\n            cin >> res;\n            Q--;\n\n            if (res == \"<\") {\n                swap(p[i], p[i+1]);\n                score[p[i]] += 1.0;\n                score[p[i+1]] -= 1.0;\n            } else if (res == \">\") {\n                score[p[i]] += 1.0;\n                score[p[i+1]] -= 1.0;\n            } else {\n                score[p[i]] += 0.5;\n                score[p[i+1]] -= 0.5;\n            }\n        }\n    }\n\n    // Sort original indices by accumulated score (descending)\n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n    stable_sort(items.begin(), items.end(), [&](int a, int b) {\n        return score[a] > score[b];\n    });\n\n    // LPT (Longest Processing Time) Assignment using Rank-based proxy weights\n    // Proxy weight for item at rank k is (N - k). This ensures heavier items \n    // (lower k) have higher proxy weight, forcing them into different bins \n    // and balancing the load effectively.\n    vector<double> bin_weight(D, 0.0);\n    vector<int> ans(N);\n    for (int k = 0; k < N; ++k) {\n        int item = items[k];\n        int best_d = 0;\n        double min_w = bin_weight[0];\n        for (int d = 1; d < D; ++d) {\n            if (bin_weight[d] < min_w) {\n                min_w = bin_weight[d];\n                best_d = d;\n            }\n        }\n        ans[item] = best_d;\n        bin_weight[best_d] += (N - k); // Add rank-based proxy weight\n    }\n\n    // Output final assignment\n    for (int i = 0; i < N; ++i) {\n        cout << ans[i] << (i == N - 1 ? \"\" : \" \");\n    }\n    cout << \"\\n\";\n    cout.flush();\n\n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\nstruct State {\n    int n, m;\n    vector<vector<int>> stacks;\n    vector<pair<int, int>> pos; // box -> {stack_idx, index}\n    vector<int> ops_v, ops_i;\n    long long energy = 0;\n    int op_count = 0;\n\n    void init(int n, int m, const vector<vector<int>>& input_stacks) {\n        this->n = n;\n        this->m = m;\n        stacks = input_stacks;\n        pos.assign(n + 1, {-1, -1});\n        for (int i = 0; i < m; ++i) {\n            for (int j = 0; j < (int)stacks[i].size(); ++j) {\n                pos[stacks[i][j]] = {i, j};\n            }\n        }\n    }\n\n    void move_box(int box, int dest_stack) {\n        auto [src_stack, idx] = pos[box];\n        int cur_size = (int)stacks[src_stack].size();\n        if (idx < 0 || idx >= cur_size) return; // Safety guard\n\n        int chunk_size = cur_size - idx;\n        energy += chunk_size + 1;\n        op_count++;\n        ops_v.push_back(box);\n        ops_i.push_back(dest_stack + 1);\n\n        vector<int> chunk;\n        chunk.reserve(chunk_size);\n        for (int k = idx; k < cur_size; ++k) {\n            chunk.push_back(stacks[src_stack][k]);\n        }\n\n        for (int b : chunk) {\n            pos[b] = {dest_stack, (int)stacks[dest_stack].size()};\n            stacks[dest_stack].push_back(b);\n        }\n\n        stacks[src_stack].resize(idx);\n    }\n\n    void remove_box(int box) {\n        op_count++;\n        ops_v.push_back(box);\n        ops_i.push_back(0);\n        auto [src, idx] = pos[box];\n        stacks[src].pop_back();\n        pos[box] = {-1, -1}; \n    }\n\n    int get_top(int s) const {\n        if (stacks[s].empty()) return n + 1;\n        return stacks[s].back();\n    }\n};\n\nint find_dest(const State& state, int u, int src, int next_target) {\n    int best_dest = -1;\n    int best_score = -2000000000;\n\n    for (int i = 0; i < state.m; ++i) {\n        if (i == src) continue;\n        int top_val = state.get_top(i);\n        int score = 0;\n        bool is_good = (top_val > u);\n        bool covers_next = (top_val == next_target);\n\n        if (is_good) score += 1000000;\n        if (!covers_next) score += 10000;\n        if (is_good) {\n            score -= top_val; // Prefer smaller top to keep larger tops available for larger boxes\n        } else {\n            score += top_val; // Prefer larger top to cover less critical numbers\n        }\n\n        if (best_dest == -1 || score > best_score) {\n            best_dest = i;\n            best_score = score;\n        }\n    }\n    return best_dest;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; ++i) {\n        for (int j = 0; j < n / m; ++j) {\n            int x; cin >> x;\n            stacks[i].push_back(x);\n        }\n    }\n\n    State S;\n    S.init(n, m, stacks);\n\n    for (int v = 1; v <= n; ++v) {\n        while (true) {\n            auto [src, idx] = S.pos[v];\n            if (src == -1) break;\n            if (idx == (int)S.stacks[src].size() - 1) {\n                S.remove_box(v);\n                break;\n            } else {\n                int u = S.stacks[src][idx + 1];\n                int dest = find_dest(S, u, src, v + 1);\n                S.move_box(u, dest);\n            }\n        }\n    }\n\n    for (int k = 0; k < S.op_count; ++k) {\n        cout << S.ops_v[k] << \" \" << S.ops_i[k] << \"\\n\";\n    }\n\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\nvector<vector<int>> children;\nvector<bool> vis;\nvector<int> c, extra;\nstring res;\n\n// Check if move from (i,j) to (ni,nj) is valid (no wall)\nbool can_move(int i, int j, int ni, int nj) {\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    if (ni == i + 1 && nj == j) return h[i][j] == '0';\n    if (ni == i - 1 && nj == j) return h[ni][j] == '0';\n    if (ni == i && nj == j + 1) return v[i][j] == '0';\n    if (ni == i && nj == j - 1) return v[i][nj] == '0';\n    return false;\n}\n\n// Get move character\nchar get_dir(int r1, int c1, int r2, int c2) {\n    if (r1 < r2) return 'D';\n    if (r1 > r2) return 'U';\n    if (c1 < c2) return 'R';\n    if (c1 > c2) return 'L';\n    return 0;\n}\n\n// Build DFS spanning tree\nvoid build_tree(int u) {\n    vis[u] = true;\n    int ui = u / N, uj = u % N;\n    int dirs[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n    for (auto& dir : dirs) {\n        int ni = ui + dir[0], nj = uj + dir[1];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n            if (can_move(ui, uj, ni, nj)) {\n                int nxt = ni * N + nj;\n                if (!vis[nxt]) {\n                    children[u].push_back(nxt);\n                    build_tree(nxt);\n                }\n            }\n        }\n    }\n}\n\n// Generate route with extra loops\nvoid gen_route(int u, int p) {\n    for (int vtx : children[u]) {\n        int ui = u / N, uj = u % N;\n        int vi = vtx / N, vj = vtx % N;\n        char to_v = get_dir(ui, uj, vi, vj);\n        char to_u = get_dir(vi, vj, ui, uj);\n        // Insert extra out-and-back loops to child\n        for (int k = 0; k < extra[vtx]; ++k) {\n            res += to_v;\n            res += to_u;\n        }\n        // Normal traversal to child\n        res += to_v;\n        gen_route(vtx, u);\n        // Return to parent\n        res += to_u;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    h.resize(N-1);\n    for (int i = 0; i < N-1; ++i) cin >> h[i];\n    v.resize(N);\n    for (int i = 0; i < N; ++i) cin >> v[i];\n    d.assign(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> d[i][j];\n\n    // 1. Build Spanning Tree\n    children.assign(N*N, vector<int>());\n    vis.assign(N*N, false);\n    build_tree(0);\n\n    // 2. Compute base visit counts\n    // In DFS traversal, each node is visited deg_tree(node) times as a destination.\n    c.assign(N*N, 0);\n    for (int u = 0; u < N*N; ++u) {\n        c[u] = children[u].size();\n        if (u != 0) c[u] += 1; // +1 from parent edge\n    }\n\n    // 3. Greedily allocate extra visits\n    priority_queue<pair<double, int>> pq;\n    int L = 2 * (N*N - 1);\n    for (int u = 1; u < N*N; ++u) { // Skip root, its visit count is naturally high\n        double gain = (double)d[u/N][u%N] / (c[u] * (c[u] + 1.0));\n        pq.push({gain, u});\n    }\n\n    extra.assign(N*N, 0);\n    while (L + 2 <= 99000) {\n        auto top = pq.top(); pq.pop();\n        int u = top.second;\n        c[u]++;\n        extra[u]++;\n        L += 2;\n        double new_gain = (double)d[u/N][u%N] / (c[u] * (c[u] + 1.0));\n        pq.push({new_gain, u});\n    }\n\n    // 4. Construct final route\n    res.reserve(100005);\n    gen_route(0, -1);\n\n    cout << res << \"\\n\";\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\n#pragma GCC optimize(\"O3,unroll-loops\")\n\nstruct Point {\n    int r, c;\n    int dist(const Point& o) const {\n        return abs(r - o.r) + abs(c - o.c);\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n    int sr, sc;\n    cin >> sr >> sc;\n\n    vector<string> A(N);\n    for (int i = 0; i < N; i++) cin >> A[i];\n\n    vector<string> T(M);\n    for (int i = 0; i < M; i++) cin >> T[i];\n\n    // Precompute positions of each character in the grid\n    vector<vector<Point>> pos(26);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            pos[A[i][j] - 'A'].push_back({i, j});\n        }\n    }\n\n    // Precompute position lists for each target string to avoid repeated lookups\n    vector<vector<vector<Point>>> T_pos(M, vector<vector<Point>>(5));\n    for (int i = 0; i < M; i++) {\n        for (int l = 0; l < 5; l++) {\n            T_pos[i][l] = pos[T[i][l] - 'A'];\n        }\n    }\n\n    vector<bool> covered(M, false);\n    int covered_cnt = 0;\n    Point cur = {sr, sc};\n    vector<Point> ans;\n    ans.reserve(M * 5);\n\n    string S;\n    S.reserve(M * 5);\n\n    // Efficiently check which strings are covered by the newly appended characters\n    auto check_coverage = [&]() {\n        int nS = S.size();\n        if (nS < 5) return;\n        // Any new match of length 5 must end at or after index nS-5\n        // It could start as early as nS-9, so we check that window.\n        int start_check = max(0, nS - 9);\n        int end_check = nS - 5;\n\n        for (int i = 0; i < M; i++) {\n            if (!covered[i]) {\n                bool found = false;\n                for (int s = start_check; s <= end_check; s++) {\n                    bool match = true;\n                    for (int k = 0; k < 5; k++) {\n                        if (S[s + k] != T[i][k]) {\n                            match = false;\n                            break;\n                        }\n                    }\n                    if (match) {\n                        found = true;\n                        break;\n                    }\n                }\n                if (found) {\n                    covered[i] = true;\n                    covered_cnt++;\n                }\n            }\n        }\n    };\n\n    while (covered_cnt < M) {\n        int best_k = -1;\n        int best_cost = INT_MAX;\n        vector<Point> best_path;\n\n        for (int i = 0; i < M; i++) {\n            if (covered[i]) continue;\n\n            // Layered DP to find min-cost path for T[i] from current position\n            const int L = 5;\n            vector<vector<int>> dp(L);\n            vector<vector<int>> pred(L);\n\n            for (int l = 0; l < L; l++) {\n                int sz = T_pos[i][l].size();\n                dp[l].assign(sz, INT_MAX);\n                pred[l].assign(sz, -1);\n            }\n\n            // Base case: first character\n            for (int u = 0; u < T_pos[i][0].size(); u++) {\n                dp[0][u] = cur.dist(T_pos[i][0][u]) + 1;\n            }\n\n            // Transition through characters 2..5\n            for (int l = 1; l < L; l++) {\n                for (int u = 0; u < T_pos[i][l].size(); u++) {\n                    int best_prev_cost = INT_MAX;\n                    int best_v = -1;\n                    for (int v = 0; v < T_pos[i][l-1].size(); v++) {\n                        if (dp[l-1][v] == INT_MAX) continue;\n                        int cost = dp[l-1][v] + T_pos[i][l-1][v].dist(T_pos[i][l][u]) + 1;\n                        if (cost < best_prev_cost) {\n                            best_prev_cost = cost;\n                            best_v = v;\n                        }\n                    }\n                    dp[l][u] = best_prev_cost;\n                    pred[l][u] = best_v;\n                }\n            }\n\n            // Find minimum cost in the final layer\n            int min_cost = INT_MAX;\n            int best_u = -1;\n            for (int u = 0; u < T_pos[i][4].size(); u++) {\n                if (dp[4][u] < min_cost) {\n                    min_cost = dp[4][u];\n                    best_u = u;\n                }\n            }\n\n            if (min_cost < best_cost) {\n                best_cost = min_cost;\n                best_k = i;\n                best_path.resize(5);\n                int u = best_u;\n                for (int l = 4; l >= 0; l--) {\n                    best_path[l] = T_pos[i][l][u];\n                    if (l > 0) u = pred[l][u];\n                }\n            }\n        }\n\n        if (best_k == -1) break; // Should not happen given problem constraints\n\n        // Execute the chosen path\n        for (const auto& p : best_path) {\n            ans.push_back(p);\n            S += A[p.r][p.c];\n            cur = p;\n        }\n\n        check_coverage();\n    }\n\n    // Output result\n    for (const auto& p : ans) {\n        cout << p.r << \" \" << p.c << \"\\n\";\n    }\n\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Fast I/O\nvoid fast_io() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n}\n\nint N, M;\ndouble eps;\n\nstruct Shape {\n    vector<pair<int, int>> cells;\n} shapes[20];\n\nint max_r[20], max_c[20];\n\n// Grid state\nint grid_val[20][20];\nint target_val[20][20];\nbool is_observed[20][20];\nbool is_drilled[20][20];\n\n// Observed cells list for fast cost computation\nstruct ObsCell {\n    int r, c, val;\n};\nvector<ObsCell> obs_list;\n\n// Positions\npair<int, int> cur_pos[20];\npair<int, int> best_pos[20];\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint rand_int(int l, int r) {\n    return uniform_int_distribution<int>(l, r)(rng);\n}\n\n// Compute cost based on observed cells\nint compute_cost() {\n    int cost = 0;\n    for (const auto& o : obs_list) {\n        int diff = grid_val[o.r][o.c] - o.val;\n        cost += diff * diff;\n    }\n    return cost;\n}\n\nvoid run_sa(const vector<pair<int,int>>& init_pos) {\n    // Initialize positions\n    for (int k = 0; k < M; ++k) {\n        if (!init_pos.empty()) cur_pos[k] = init_pos[k];\n        else cur_pos[k] = {rand_int(0, N - 1 - max_r[k]), rand_int(0, N - 1 - max_c[k])};\n    }\n    \n    // Reset grid\n    for(int i=0; i<N; ++i) fill(grid_val[i], grid_val[i]+N, 0);\n    \n    // Build initial grid\n    for (int k = 0; k < M; ++k) {\n        for (const auto& cell : shapes[k].cells) {\n            grid_val[cell.first + cur_pos[k].first][cell.second + cur_pos[k].second]++;\n        }\n    }\n    \n    int current_cost = compute_cost();\n    int best_cost = current_cost;\n    memcpy(best_pos, cur_pos, sizeof(cur_pos));\n    \n    double T = 100.0;\n    int iterations = 1500; // Reduced to fit time limit\n    uniform_real_distribution<double> dis(0, 1);\n    \n    for (int iter = 0; iter < iterations; ++iter) {\n        int k = rand_int(0, M - 1);\n        int dr = rand_int(-1, 1);\n        int dc = rand_int(-1, 1);\n        if (dr == 0 && dc == 0) continue;\n        \n        int nr = cur_pos[k].first + dr;\n        int nc = cur_pos[k].second + dc;\n        \n        // Bounds check\n        if (nr < 0 || nr > N - 1 - max_r[k] || nc < 0 || nc > N - 1 - max_c[k]) continue;\n        \n        int old_r = cur_pos[k].first;\n        int old_c = cur_pos[k].second;\n        \n        // Move: Remove from old\n        for (const auto& cell : shapes[k].cells) {\n            grid_val[cell.first + old_r][cell.second + old_c]--;\n        }\n        cur_pos[k] = {nr, nc};\n        // Add to new\n        for (const auto& cell : shapes[k].cells) {\n            grid_val[cell.first + nr][cell.second + nc]++;\n        }\n        \n        int new_cost = compute_cost();\n        \n        // Metropolis criterion\n        if (new_cost < current_cost || dis(rng) < exp(-(double)(new_cost - current_cost) / T)) {\n            current_cost = new_cost;\n            if (current_cost < best_cost) {\n                best_cost = current_cost;\n                memcpy(best_pos, cur_pos, sizeof(cur_pos));\n            }\n        } else {\n            // Revert move\n            for (const auto& cell : shapes[k].cells) {\n                grid_val[cell.first + nr][cell.second + nc]--;\n            }\n            cur_pos[k] = {old_r, old_c};\n            for (const auto& cell : shapes[k].cells) {\n                grid_val[cell.first + old_r][cell.second + old_c]++;\n            }\n        }\n        \n        if (current_cost == 0) {\n            memcpy(best_pos, cur_pos, sizeof(cur_pos));\n            best_cost = 0;\n            break;\n        }\n        \n        T *= 0.999;\n    }\n    \n    // Restore best state\n    memcpy(cur_pos, best_pos, sizeof(cur_pos));\n    for(int i=0; i<N; ++i) fill(grid_val[i], grid_val[i]+N, 0);\n    for (int k = 0; k < M; ++k) {\n        for (const auto& cell : shapes[k].cells) {\n            grid_val[cell.first + cur_pos[k].first][cell.second + cur_pos[k].second]++;\n        }\n    }\n}\n\nint main() {\n    fast_io();\n    rng.seed(chrono::steady_clock::now().time_since_epoch().count());\n    \n    if (!(cin >> N >> M >> eps)) return 0;\n    \n    for (int k = 0; k < M; ++k) {\n        int d; cin >> d;\n        for (int l = 0; l < d; ++l) {\n            int r, c; cin >> r >> c;\n            shapes[k].cells.push_back({r, c});\n            max_r[k] = max(max_r[k], r);\n            max_c[k] = max(max_c[k], c);\n        }\n    }\n    \n    memset(grid_val, 0, sizeof(grid_val));\n    memset(target_val, -1, sizeof(target_val));\n    memset(is_observed, 0, sizeof(is_observed));\n    memset(is_drilled, 0, sizeof(is_drilled));\n    \n    int op_count = 0;\n    int limit = 2 * N * N;\n    \n    auto drill = [&](int r, int c) {\n        cout << \"q 1 \" << r << \" \" << c << \"\\n\";\n        cout.flush();\n        int v; cin >> v;\n        target_val[r][c] = v;\n        is_observed[r][c] = true;\n        is_drilled[r][c] = true;\n        obs_list.push_back({r, c, v});\n        op_count++;\n    };\n    \n    auto guess = [&](const vector<pair<int,int>>& cells) {\n        cout << \"a \" << cells.size();\n        for (const auto& p : cells) cout << \" \" << p.first << \" \" << p.second;\n        cout << \"\\n\";\n        cout.flush();\n        op_count++;\n        int res; cin >> res;\n        return res == 1;\n    };\n\n    // Phase 1: Initial random drilling\n    int init_drills = min(60, N*N);\n    for (int i = 0; i < init_drills && op_count < limit; ++i) {\n        int r = rand_int(0, N-1);\n        int c = rand_int(0, N-1);\n        if (!is_drilled[r][c]) {\n            drill(r, c);\n        } else {\n            i--;\n        }\n    }\n    \n    vector<pair<int,int>> current_best_pos(M, {0,0});\n    auto start_time = chrono::steady_clock::now();\n\n    // Main Loop\n    while (true) {\n        auto elapsed = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count();\n        if (elapsed > 2700) break; // Time safety margin\n        \n        run_sa(current_best_pos);\n        for(int k=0; k<M; k++) current_best_pos[k] = cur_pos[k];\n        \n        // Construct guess\n        bool guessed_arr[20][20] = {};\n        vector<pair<int,int>> guess_cells;\n        \n        // 1. Mandatory: Drilled cells with oil\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                if (is_drilled[r][c] && target_val[r][c] > 0) {\n                    guessed_arr[r][c] = true;\n                    guess_cells.push_back({r, c});\n                }\n            }\n        }\n        \n        // 2. Predicted cells from model\n        for (int k = 0; k < M; ++k) {\n            for (const auto& cell : shapes[k].cells) {\n                int r = cell.first + cur_pos[k].first;\n                int c = cell.second + cur_pos[k].second;\n                \n                // Do not include cells known to be empty\n                if (is_drilled[r][c] && target_val[r][c] == 0) continue;\n                \n                if (!guessed_arr[r][c]) {\n                    guessed_arr[r][c] = true;\n                    guess_cells.push_back({r, c});\n                }\n            }\n        }\n        \n        // Attempt guess if we have operations left\n        if (op_count < limit) {\n            if (guess(guess_cells)) return 0;\n        }\n        \n        if (op_count >= limit) break;\n        \n        // Phase 3: Adaptive drilling\n        // Reserve 1 op for future guess\n        int budget = limit - op_count - 1; \n        if (budget > 0) {\n            int drills_needed = min(8, budget);\n            vector<pair<int,int>> zero_pred;\n            vector<pair<int,int>> others;\n            for (int r = 0; r < N; ++r) {\n                for (int c = 0; c < N; ++c) {\n                    if (!is_drilled[r][c]) {\n                        if (grid_val[r][c] == 0) zero_pred.push_back({r, c});\n                        else others.push_back({r, c});\n                    }\n                }\n            }\n            // Prioritize cells where model predicts 0\n            shuffle(zero_pred.begin(), zero_pred.end(), rng);\n            \n            int count = 0;\n            for (const auto& p : zero_pred) {\n                if (count >= drills_needed) break;\n                drill(p.first, p.second);\n                count++;\n            }\n        }\n    }\n    \n    // Final guess\n    if (op_count < limit) {\n        run_sa(current_best_pos);\n        bool guessed_arr[20][20] = {};\n        vector<pair<int,int>> guess_cells;\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                if (is_drilled[r][c] && target_val[r][c] > 0) {\n                    guessed_arr[r][c] = true;\n                    guess_cells.push_back({r, c});\n                }\n            }\n        }\n        for (int k = 0; k < M; ++k) {\n            for (const auto& cell : shapes[k].cells) {\n                int r = cell.first + cur_pos[k].first;\n                int c = cell.second + cur_pos[k].second;\n                if (is_drilled[r][c] && target_val[r][c] == 0) continue;\n                if (!guessed_arr[r][c]) {\n                    guessed_arr[r][c] = true;\n                    guess_cells.push_back({r, c});\n                }\n            }\n        }\n        guess(guess_cells);\n    }\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\n#include <chrono>\n#include <random>\nusing namespace std;\n\n// Problem constants\nconst int W = 1000;\nconst int MAX_D = 55;\nconst int MAX_N = 55;\n\n// Global state\nint D, N;\nlong long A[MAX_D][MAX_N];\n\nstruct Rect {\n    int x1, y1, x2, y2;\n};\n\nRect rects[MAX_D][MAX_N];\nRect best_rects[MAX_D][MAX_N];\n\n// Partition grids: H[d][y][x] for horizontal segments at row y, between x and x+1\n// V[d][y][x] for vertical segments at col x, between y and y+1\n// We use char for cache efficiency and speed. Padding to avoid bounds checks.\nchar H[MAX_D][W+5][W+5];\nchar V[MAX_D][W+5][W+5];\n\nlong long L[MAX_D]; // L[d] stores partition change cost between d-1 and d\nlong long area_pen[MAX_D][MAX_N];\nlong long total_cost = 0;\nlong long best_cost = 1LL << 60;\n\nmt19937 rng(42);\nuniform_int_distribution<int> dist_int(0, 1000000);\nuniform_real_distribution<double> dist_real(0.0, 1.0);\n\nint rand_int(int l, int r) {\n    return l + dist_int(rng) % (r - l + 1);\n}\ndouble rand_real() {\n    return dist_real(rng);\n}\n\n// Check overlap on day d for reservation k with candidate rect r\nbool overlap(int d, int k, const Rect& r) {\n    for (int i = 0; i < N; ++i) {\n        if (i == k) continue;\n        if (rects[d][i].x1 < r.x2 && rects[d][i].x2 > r.x1 &&\n            rects[d][i].y1 < r.y2 && rects[d][i].y2 > r.y1)\n            return true;\n    }\n    return false;\n}\n\n// Compute area penalty\nlong long calc_area_pen(const Rect& r, long long req) {\n    long long area = 1LL * (r.x2 - r.x1) * (r.y2 - r.y1);\n    return max(0LL, 100LL * (req - area));\n}\n\n// Update total cost when flipping a single partition segment\n// Returns delta to total_cost\nlong long flip_segment(int d, bool is_H, int y, int x, char new_val, bool apply = true) {\n    if (d == 0) return 0; // L_0 is always 0, no change affects it\n    char* grid = is_H ? &H[d][y][x] : &V[d][y][x];\n    char old_val = *grid;\n    if (old_val == new_val) return 0;\n\n    long long delta = 0;\n    // Contribution to L[d]: compares with day d-1\n    char prev = is_H ? H[d-1][y][x] : V[d-1][y][x];\n    if ((prev != old_val) && (prev == new_val)) delta -= 1;\n    else if ((prev == old_val) && (prev != new_val)) delta += 1;\n\n    // Contribution to L[d+1]: compares with day d+1\n    if (d < D - 1) {\n        char next = is_H ? H[d+1][y][x] : V[d+1][y][x];\n        if ((next != old_val) && (next == new_val)) delta -= 1;\n        else if ((next == old_val) && (next != new_val)) delta += 1;\n    }\n\n    if (apply) {\n        *grid = new_val;\n        total_cost += delta;\n        if (d > 0) L[d] += delta; // Note: L array not strictly needed if we track total_cost, but kept for debug/sanity\n    }\n    return delta;\n}\n\n// Apply or revert rectangle on day d\n// sign = 1 to add, -1 to remove\nvoid apply_rect(int d, int k, const Rect& r, int sign) {\n    // Horizontal edges\n    for (int x = r.x1; x < r.x2; ++x) {\n        if (r.y1 >= 1 && r.y1 <= W - 1) flip_segment(d, true, r.y1, x, sign == 1, true);\n        if (r.y2 >= 1 && r.y2 <= W - 1) flip_segment(d, true, r.y2, x, sign == 1, true);\n    }\n    // Vertical edges\n    for (int y = r.y1; y < r.y2; ++y) {\n        if (r.x1 >= 1 && r.x1 <= W - 1) flip_segment(d, false, y, r.x1, sign == 1, true);\n        if (r.x2 >= 1 && r.x2 <= W - 1) flip_segment(d, false, y, r.x2, sign == 1, true);\n    }\n    rects[d][k] = r;\n}\n\n// Compute delta cost for a proposed change without modifying state\nlong long simulate_change(int d, int k, const Rect& old_r, const Rect& new_r) {\n    long long delta = 0;\n    // Remove old\n    delta -= calc_area_pen(old_r, A[d][k]);\n    for (int x = old_r.x1; x < old_r.x2; ++x) {\n        if (old_r.y1 >= 1 && old_r.y1 <= W - 1) delta += flip_segment(d, true, old_r.y1, x, 0, false);\n        if (old_r.y2 >= 1 && old_r.y2 <= W - 1) delta += flip_segment(d, true, old_r.y2, x, 0, false);\n    }\n    for (int y = old_r.y1; y < old_r.y2; ++y) {\n        if (old_r.x1 >= 1 && old_r.x1 <= W - 1) delta += flip_segment(d, false, y, old_r.x1, 0, false);\n        if (old_r.x2 >= 1 && old_r.x2 <= W - 1) delta += flip_segment(d, false, y, old_r.x2, 0, false);\n    }\n\n    // Add new\n    delta += calc_area_pen(new_r, A[d][k]);\n    for (int x = new_r.x1; x < new_r.x2; ++x) {\n        if (new_r.y1 >= 1 && new_r.y1 <= W - 1) delta += flip_segment(d, true, new_r.y1, x, 1, false);\n        if (new_r.y2 >= 1 && new_r.y2 <= W - 1) delta += flip_segment(d, true, new_r.y2, x, 1, false);\n    }\n    for (int y = new_r.y1; y < new_r.y2; ++y) {\n        if (new_r.x1 >= 1 && new_r.x1 <= W - 1) delta += flip_segment(d, false, y, new_r.x1, 1, false);\n        if (new_r.x2 >= 1 && new_r.x2 <= W - 1) delta += flip_segment(d, false, y, new_r.x2, 1, false);\n    }\n    return delta;\n}\n\n// Initial packing: simple shelf algorithm\nvoid pack_initial() {\n    for (int d = 0; d < D; ++d) {\n        int cx = 0, cy = 0, rh = 0;\n        for (int k = 0; k < N; ++k) {\n            long long area = A[d][k];\n            int w = min(W, max(1, (int)ceil(sqrt(area))));\n            int h = max(1, (int)((area + w - 1) / w));\n            if (cx + w > W) {\n                cy += rh;\n                rh = 0;\n                cx = 0;\n                w = min(W, max(1, (int)ceil(sqrt(area))));\n                h = max(1, (int)((area + w - 1) / w));\n            }\n            rects[d][k] = {cx, cy, cx + w, cy + h};\n            cx += w;\n            rh = max(rh, h);\n        }\n    }\n\n    // Build grids and compute costs\n    total_cost = 0;\n    memset(H, 0, sizeof(H));\n    memset(V, 0, sizeof(V));\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            area_pen[d][k] = calc_area_pen(rects[d][k], A[d][k]);\n            total_cost += area_pen[d][k];\n            // Add to grids\n            for (int x = rects[d][k].x1; x < rects[d][k].x2; ++x) {\n                if (rects[d][k].y1 >= 1 && rects[d][k].y1 <= W - 1) H[d][rects[d][k].y1][x] = 1;\n                if (rects[d][k].y2 >= 1 && rects[d][k].y2 <= W - 1) H[d][rects[d][k].y2][x] = 1;\n            }\n            for (int y = rects[d][k].y1; y < rects[d][k].y2; ++y) {\n                if (rects[d][k].x1 >= 1 && rects[d][k].x1 <= W - 1) V[d][y][rects[d][k].x1] = 1;\n                if (rects[d][k].x2 >= 1 && rects[d][k].x2 <= W - 1) V[d][y][rects[d][k].x2] = 1;\n            }\n        }\n    }\n    // Compute L[d]\n    for (int d = 1; d < D; ++d) {\n        for (int y = 1; y < W; ++y) {\n            for (int x = 0; x < W; ++x) {\n                if (H[d][y][x] != H[d-1][y][x]) total_cost++;\n            }\n            for (int x = 1; x < W; ++x) {\n                if (V[d][y-1][x] != V[d-1][y-1][x]) total_cost++;\n            }\n        }\n        // Last row for V\n        for (int x = 1; x < W; ++x) {\n            if (V[d][W-1][x] != V[d-1][W-1][x]) total_cost++;\n        }\n    }\n}\n\nvoid solve() {\n    pack_initial();\n    if (total_cost < best_cost) {\n        best_cost = total_cost;\n        memcpy(best_rects, rects, sizeof(rects));\n    }\n\n    auto start = chrono::high_resolution_clock::now();\n    double temp = 5000.0;\n    const double COOLING = 0.99995;\n    int moves = 0;\n\n    while (chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start).count() < 2800) {\n        int d = rand_int(0, D - 1);\n        int k = rand_int(0, N - 1);\n        Rect old_r = rects[d][k];\n\n        // Perturb\n        int dx = rand_int(-4, 4);\n        int dy = rand_int(-4, 4);\n        int dw = rand_int(-3, 3);\n        int dh = rand_int(-3, 3);\n\n        Rect new_r;\n        new_r.x1 = max(0, min(W, old_r.x1 + dx));\n        new_r.y1 = max(0, min(W, old_r.y1 + dy));\n        new_r.x2 = max(new_r.x1 + 1, min(W, old_r.x2 + dw));\n        new_r.y2 = max(new_r.y1 + 1, min(W, old_r.y2 + dh));\n\n        // Enforce area constraint\n        long long cur_area = 1LL * (new_r.x2 - new_r.x1) * (new_r.y2 - new_r.y1);\n        if (cur_area < A[d][k]) {\n            long long needed = A[d][k];\n            // Try to expand width first, then height\n            int add_w = max(0, (int)((needed + new_r.y2 - new_r.y1 - 1) / (new_r.y2 - new_r.y1)) - (new_r.x2 - new_r.x1));\n            if (new_r.x2 + add_w <= W) new_r.x2 += add_w;\n            else {\n                int add_h = max(0, (int)((needed + new_r.x2 - new_r.x1 - 1) / (new_r.x2 - new_r.x1)) - (new_r.y2 - new_r.y1));\n                if (new_r.y2 + add_h <= W) new_r.y2 += add_h;\n                else continue; // Cannot fit\n            }\n        }\n\n        if (overlap(d, k, new_r)) continue;\n\n        long long delta = simulate_change(d, k, old_r, new_r);\n        \n        if (delta < 0 || rand_real() < exp(-delta / temp)) {\n            apply_rect(d, k, new_r, 1); // Apply new\n            area_pen[d][k] = calc_area_pen(new_r, A[d][k]);\n            total_cost += delta; // delta already includes area penalty change\n            \n            // Revert old state in grids manually to keep consistency (simulate_change didn't apply)\n            // Actually, apply_rect adds new, but we need to remove old first.\n            // Let's fix the logic: apply_rect assumes grid has old state, flips to new_val.\n            // But simulate_change didn't modify grid. So we must remove old, add new.\n            // I'll rewrite apply to be atomic:\n            // Remove old\n            for (int x = old_r.x1; x < old_r.x2; ++x) {\n                if (old_r.y1 >= 1 && old_r.y1 <= W - 1) flip_segment(d, true, old_r.y1, x, 0, true);\n                if (old_r.y2 >= 1 && old_r.y2 <= W - 1) flip_segment(d, true, old_r.y2, x, 0, true);\n            }\n            for (int y = old_r.y1; y < old_r.y2; ++y) {\n                if (old_r.x1 >= 1 && old_r.x1 <= W - 1) flip_segment(d, false, y, old_r.x1, 0, true);\n                if (old_r.x2 >= 1 && old_r.x2 <= W - 1) flip_segment(d, false, y, old_r.x2, 0, true);\n            }\n            // Add new\n            for (int x = new_r.x1; x < new_r.x2; ++x) {\n                if (new_r.y1 >= 1 && new_r.y1 <= W - 1) flip_segment(d, true, new_r.y1, x, 1, true);\n                if (new_r.y2 >= 1 && new_r.y2 <= W - 1) flip_segment(d, true, new_r.y2, x, 1, true);\n            }\n            for (int y = new_r.y1; y < new_r.y2; ++y) {\n                if (new_r.x1 >= 1 && new_r.x1 <= W - 1) flip_segment(d, false, y, new_r.x1, 1, true);\n                if (new_r.x2 >= 1 && new_r.x2 <= W - 1) flip_segment(d, false, y, new_r.x2, 1, true);\n            }\n            \n            // Wait, flip_segment already updates total_cost. So I double counted.\n            // Let's simplify: I'll just call a direct apply function that does everything correctly.\n            // Reverting logic below handles this cleanly.\n        } else {\n            // Reject\n        }\n        temp *= COOLING;\n        moves++;\n        if (total_cost < best_cost) {\n            best_cost = total_cost;\n            memcpy(best_rects, rects, sizeof(rects));\n        }\n    }\n}\n\n// Correct atomic apply\nvoid atomic_apply(int d, int k, Rect old_r, Rect new_r) {\n    // Remove old\n    for (int x = old_r.x1; x < old_r.x2; ++x) {\n        if (old_r.y1 >= 1 && old_r.y1 <= W - 1) flip_segment(d, true, old_r.y1, x, 0, true);\n        if (old_r.y2 >= 1 && old_r.y2 <= W - 1) flip_segment(d, true, old_r.y2, x, 0, true);\n    }\n    for (int y = old_r.y1; y < old_r.y2; ++y) {\n        if (old_r.x1 >= 1 && old_r.x1 <= W - 1) flip_segment(d, false, y, old_r.x1, 0, true);\n        if (old_r.x2 >= 1 && old_r.x2 <= W - 1) flip_segment(d, false, y, old_r.x2, 0, true);\n    }\n    // Add new\n    for (int x = new_r.x1; x < new_r.x2; ++x) {\n        if (new_r.y1 >= 1 && new_r.y1 <= W - 1) flip_segment(d, true, new_r.y1, x, 1, true);\n        if (new_r.y2 >= 1 && new_r.y2 <= W - 1) flip_segment(d, true, new_r.y2, x, 1, true);\n    }\n    for (int y = new_r.y1; y < new_r.y2; ++y) {\n        if (new_r.x1 >= 1 && new_r.x1 <= W - 1) flip_segment(d, false, y, new_r.x1, 1, true);\n        if (new_r.x2 >= 1 && new_r.x2 <= W - 1) flip_segment(d, false, y, new_r.x2, 1, true);\n    }\n    rects[d][k] = new_r;\n}\n\n// Re-implement SA loop correctly\nvoid run_sa() {\n    auto start = chrono::high_resolution_clock::now();\n    double temp = 8000.0;\n    const double COOLING = 0.99994;\n\n    while (chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start).count() < 2850) {\n        int d = rand_int(0, D - 1);\n        int k = rand_int(0, N - 1);\n        Rect old_r = rects[d][k];\n\n        int dx = rand_int(-5, 5);\n        int dy = rand_int(-5, 5);\n        int dw = rand_int(-3, 3);\n        int dh = rand_int(-3, 3);\n\n        Rect new_r;\n        new_r.x1 = max(0, min(W, old_r.x1 + dx));\n        new_r.y1 = max(0, min(W, old_r.y1 + dy));\n        new_r.x2 = max(new_r.x1 + 1, min(W, old_r.x2 + dw));\n        new_r.y2 = max(new_r.y1 + 1, min(W, old_r.y2 + dh));\n\n        long long cur_area = 1LL * (new_r.x2 - new_r.x1) * (new_r.y2 - new_r.y1);\n        if (cur_area < A[d][k]) {\n            long long needed = A[d][k];\n            int add_w = max(0, (int)((needed + new_r.y2 - new_r.y1 - 1) / (new_r.y2 - new_r.y1)) - (new_r.x2 - new_r.x1));\n            if (new_r.x2 + add_w <= W) new_r.x2 += add_w;\n            else {\n                int add_h = max(0, (int)((needed + new_r.x2 - new_r.x1 - 1) / (new_r.x2 - new_r.x1)) - (new_r.y2 - new_r.y1));\n                if (new_r.y2 + add_h <= W) new_r.y2 += add_h;\n                else continue;\n            }\n        }\n\n        if (overlap(d, k, new_r)) continue;\n\n        long long delta = simulate_change(d, k, old_r, new_r);\n        if (delta < 0 || rand_real() < exp(-delta / temp)) {\n            long long old_total = total_cost;\n            atomic_apply(d, k, old_r, new_r);\n            area_pen[d][k] = calc_area_pen(new_r, A[d][k]);\n            \n            if (total_cost > old_total + delta) {\n                // Should not happen if simulate is correct, but fallback: revert\n                atomic_apply(d, k, new_r, old_r);\n                area_pen[d][k] = calc_area_pen(old_r, A[d][k]);\n                total_cost = old_total;\n            }\n        }\n\n        temp *= COOLING;\n        if (total_cost < best_cost) {\n            best_cost = total_cost;\n            memcpy(best_rects, rects, sizeof(rects));\n        }\n    }\n}\n\nint main() {\n    ios_base::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)\n        for (int k = 0; k < N; ++k)\n            cin >> A[d][k];\n\n    pack_initial();\n    best_cost = total_cost;\n    memcpy(best_rects, rects, sizeof(rects));\n    \n    run_sa();\n\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            cout << best_rects[d][k].y1 << \" \" << best_rects[d][k].x1 << \" \"\n                 << best_rects[d][k].y2 << \" \" << best_rects[d][k].x2 << \"\\n\";\n        }\n    }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\n#pragma GCC optimize(\"O3,unroll-loops\")\n\nusing namespace std;\nusing ll = long long;\n\nconst ll MOD = 998244353;\nconstexpr int MAX_N = 9;\nconstexpr int MAX_M = 20;\nconstexpr int MAX_K = 81;\n\nll initial_board[MAX_N][MAX_N];\nll board_mod[MAX_N][MAX_N];\nll stamps[MAX_M][3][3];\n\nstruct Op { int m, p, q; };\nvector<Op> ops(MAX_K);\nvector<Op> best_ops;\nll current_score = 0;\nll best_score = 0;\n\n// Fast Xorshift RNG\nuint64_t rng_state;\ninline uint64_t my_rand() {\n    uint64_t x = rng_state;\n    x ^= x >> 12; x ^= x << 25; x ^= x >> 27;\n    return x * 0x2545F4914F6CDD1D;\n}\ninline int rand_int(int max) { return my_rand() % max; }\n\n// Calculate score change if we add stamp m at (p, q)\ninline ll calc_delta(int m, int p, int q) {\n    ll d = 0;\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            ll old_val = board_mod[p + i][q + j];\n            ll new_val = old_val + stamps[m][i][j];\n            if (new_val >= MOD) new_val -= MOD;\n            d += new_val - old_val;\n        }\n    }\n    return d;\n}\n\n// Calculate score change if we remove stamp m at (p, q)\ninline ll calc_remove_delta(int m, int p, int q) {\n    ll d = 0;\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            ll old_val = board_mod[p + i][q + j];\n            ll new_val = old_val - stamps[m][i][j];\n            if (new_val < 0) new_val += MOD;\n            d += new_val - old_val;\n        }\n    }\n    return d;\n}\n\ninline void apply(int m, int p, int q) {\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            board_mod[p + i][q + j] += stamps[m][i][j];\n            if (board_mod[p + i][q + j] >= MOD) board_mod[p + i][q + j] -= MOD;\n        }\n    }\n}\n\ninline void revert(int m, int p, int q) {\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            board_mod[p + i][q + j] -= stamps[m][i][j];\n            if (board_mod[p + i][q + j] < 0) board_mod[p + i][q + j] += MOD;\n        }\n    }\n}\n\ninline ll compute_score() {\n    ll s = 0;\n    for (int i = 0; i < MAX_N; ++i) \n        for (int j = 0; j < MAX_N; ++j) \n            s += board_mod[i][j];\n    return s;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n\n    for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) {\n        cin >> initial_board[i][j];\n        board_mod[i][j] = initial_board[i][j] % MOD;\n    }\n    for (int m = 0; m < M; ++m) for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) {\n        cin >> stamps[m][i][j];\n    }\n\n    rng_state = chrono::steady_clock::now().time_since_epoch().count();\n\n    // 1. Greedy Initialization\n    for (int k = 0; k < K; ++k) {\n        int best_m = -1, best_p = -1, best_q = -1;\n        ll best_d = -1e18; \n        for (int m = 0; m < M; ++m) {\n            for (int p = 0; p <= N - 3; ++p) {\n                for (int q = 0; q <= N - 3; ++q) {\n                    ll d = calc_delta(m, p, q);\n                    if (d > best_d) {\n                        best_d = d; best_m = m; best_p = p; best_q = q;\n                    }\n                }\n            }\n        }\n        ops[k] = {best_m, best_p, best_q};\n        apply(best_m, best_p, best_q);\n    }\n    \n    current_score = compute_score();\n    best_score = current_score;\n    best_ops = ops;\n\n    // 2. Simulated Annealing\n    double T = 2e9;\n    const double T_end = 100;\n    const int MAX_ITER = 30000000;\n    const double decay = pow(T_end / T, 1.0 / MAX_ITER);\n    \n    const int max_m = M;\n    const int max_pq = N - 2;\n\n    auto start_time = chrono::steady_clock::now();\n    \n    for (int step = 0; step < MAX_ITER; ++step) {\n        // Soft time limit check\n        if (step % 500000 == 0) {\n            auto now = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 1900) break;\n        }\n\n        int idx = rand_int(K);\n        int m = rand_int(max_m);\n        int p = rand_int(max_pq);\n        int q = rand_int(max_pq);\n\n        ll d_remove = calc_remove_delta(ops[idx].m, ops[idx].p, ops[idx].q);\n        revert(ops[idx].m, ops[idx].p, ops[idx].q);\n        ll d_add = calc_delta(m, p, q);\n        ll delta = d_remove + d_add;\n        \n        bool accept = false;\n        if (delta > 0) {\n            accept = true;\n        } else {\n            // Metropolis criterion with underflow protection\n            if (delta > -20.0 * T) {\n                double prob = exp(delta / T);\n                // Fast probability comparison using upper 32 bits\n                if ((double)(my_rand() & 0xFFFFFFFF) / 4294967296.0 < prob) {\n                    accept = true;\n                }\n            }\n        }\n\n        if (accept) {\n            apply(m, p, q);\n            ops[idx] = {m, p, q};\n            current_score += delta;\n            if (current_score > best_score) {\n                best_score = current_score;\n                best_ops = ops;\n            }\n        } else {\n            apply(ops[idx].m, ops[idx].p, ops[idx].q);\n        }\n        T *= decay;\n    }\n\n    // 3. Post-Processing: Greedy Removal\n    for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) {\n        board_mod[i][j] = initial_board[i][j] % MOD;\n    }\n    for (const auto& op : best_ops) apply(op.m, op.p, op.q);\n    current_score = compute_score();\n\n    bool improved = true;\n    while (improved && !best_ops.empty()) {\n        improved = false;\n        int best_remove_idx = -1;\n        ll max_d_remove = 0;\n\n        for (size_t i = 0; i < best_ops.size(); ++i) {\n            ll d = calc_remove_delta(best_ops[i].m, best_ops[i].p, best_ops[i].q);\n            if (d > max_d_remove) {\n                max_d_remove = d;\n                best_remove_idx = i;\n            }\n        }\n\n        if (best_remove_idx != -1) {\n            revert(best_ops[best_remove_idx].m, best_ops[best_remove_idx].p, best_ops[best_remove_idx].q);\n            current_score += max_d_remove;\n            best_ops.erase(best_ops.begin() + best_remove_idx);\n            best_score = current_score;\n            improved = true;\n        }\n    }\n\n    cout << best_ops.size() << \"\\n\";\n    for (const auto& op : best_ops) {\n        cout << op.m << \" \" << op.p << \" \" << op.q << \"\\n\";\n    }\n\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N = 5;\n    int A[5][5];\n    for(int i=0; i<5; ++i) for(int j=0; j<5; ++j) cin >> A[i][j];\n\n    int grid[5][5];\n    memset(grid, -1, sizeof(grid));\n    \n    int cr_r[5], cr_c[5], cr_hold[5];\n    bool cr_large[5];\n    for(int i=0; i<5; ++i) { cr_r[i]=i; cr_c[i]=0; cr_hold[i]=-1; cr_large[i]=(i==0); }\n\n    int dnext[5]; for(int i=0; i<5; ++i) dnext[i] = i*5;\n    int rptr[5] = {0};\n    vector<string> S(5, \"\");\n    int dispatched = 0;\n\n    auto valid = [](int r, int c) { return r>=0 && r<5 && c>=0 && c<5; };\n    const int dr[4] = {-1,1,0,0};\n    const int dc[4] = {0,0,-1,1};\n    const char dn[4] = {'U','D','L','R'};\n\n    for(int turn=1; turn<=10000; ++turn) {\n        // 1. Receive\n        for(int i=0; i<5; ++i) {\n            if(rptr[i] < 5 && grid[i][0] == -1) {\n                bool blocked = false;\n                for(int k=0; k<5; ++k) if(cr_r[k]==i && cr_c[k]==0 && cr_hold[k]!=-1) { blocked=true; break; }\n                if(!blocked) { grid[i][0] = A[i][rptr[i]]; rptr[i]++; }\n            }\n        }\n\n        char acts[5] = {'.'};\n        // pos_r/pos_c stores planned positions. Updated sequentially.\n        int pos_r[5], pos_c[5];\n        for(int i=0; i<5; ++i) { pos_r[i] = cr_r[i]; pos_c[i] = cr_c[i]; }\n\n        for(int k=0; k<5; ++k) {\n            int r = cr_r[k], c = cr_c[k];\n            bool hold = (cr_hold[k] != -1);\n            bool large = cr_large[k];\n            \n            char best_act = '.';\n            int best_nr = r, best_nc = c;\n            int best_cost = 1000000;\n\n            // Priority 1: Drop if at target buffer/dispatch\n            if(hold) {\n                int cid = cr_hold[k];\n                int tr = cid/5;\n                bool is_next = (cid == dnext[tr]);\n                int tc = is_next ? 4 : 3;\n                if(r == tr && c == tc && grid[r][c] == -1) {\n                    best_act = 'Q'; best_nr = r; best_nc = c; best_cost = -1000;\n                }\n            }\n\n            // Priority 2: Pick up if standing on container\n            if(best_cost > 0 && !hold && grid[r][c] != -1) {\n                best_act = 'P'; best_nr = r; best_nc = c; best_cost = -900;\n            }\n\n            // Priority 3: Move towards target\n            if(best_cost > 0) {\n                pair<int,int> target = {-1, -1};\n                if(hold) {\n                    int cid = cr_hold[k];\n                    target = {cid/5, (cid == dnext[cid/5]) ? 4 : 3};\n                } else {\n                    int bd = 1e9, bp = 10;\n                    for(int rr=0; rr<5; ++rr) {\n                        for(int cc=0; cc<5; ++cc) {\n                            if(grid[rr][cc] == -1) continue;\n                            int cid = grid[rr][cc];\n                            bool taken = false;\n                            for(int j=0; j<5; ++j) if(cr_hold[j]==cid) { taken=true; break; }\n                            if(taken) continue;\n                            int p = (cid == dnext[cid/5]) ? 0 : 1;\n                            int d = abs(r-rr) + abs(c-cc);\n                            if(d < bd || (d == bd && p < bp)) { bd = d; bp = p; target = {rr, cc}; }\n                        }\n                    }\n                }\n\n                if(target.first != -1) {\n                    queue<pair<int,int>> q; q.push({r,c});\n                    int dist[5][5]; memset(dist, 0x3f, sizeof(dist)); dist[r][c] = 0;\n                    pair<int,int> par[5][5];\n                    for(int i=0;i<5;++i) for(int j=0;j<5;++j) par[i][j] = {-1,-1};\n                    char dir[5][5] = {};\n                    bool found = false;\n                    \n                    while(!q.empty()) {\n                        auto [cr, cc] = q.front(); q.pop();\n                        if(cr == target.first && cc == target.second) { found = true; break; }\n                        for(int d=0; d<4; ++d) {\n                            int nr = cr+dr[d], nc = cc+dc[d];\n                            if(!valid(nr, nc) || dist[nr][nc] < 1e9) continue;\n                            \n                            bool obs = false;\n                            // Small cranes carrying cannot move onto containers\n                            if(!large && hold && grid[nr][nc] != -1) obs = true;\n                            // Cannot move into planned/current positions of other cranes\n                            for(int j=0; j<5; ++j) {\n                                if(j==k) continue;\n                                if(pos_r[j]==nr && pos_c[j]==nc) { obs = true; break; }\n                            }\n                            if(obs) continue;\n                            \n                            dist[nr][nc] = dist[cr][cc] + 1;\n                            par[nr][nc] = {cr, cc};\n                            dir[nr][nc] = dn[d];\n                            q.push({nr, nc});\n                        }\n                    }\n                    \n                    if(found) {\n                        pair<int,int> cur = target;\n                        while(!(par[cur.first][cur.second].first == r && par[cur.first][cur.second].second == c)) {\n                            if(par[cur.first][cur.second].first == -1) { found = false; break; }\n                            cur = par[cur.first][cur.second];\n                        }\n                        if(found) {\n                            best_act = dir[cur.first][cur.second];\n                            best_nr = cur.first; best_nc = cur.second;\n                            best_cost = dist[target.first][target.second];\n                        }\n                    }\n                }\n            }\n\n            acts[k] = best_act;\n            pos_r[k] = best_nr; pos_c[k] = best_nc;\n        }\n\n        // Apply movements\n        for(int k=0; k<5; ++k) if(acts[k] != 'P' && acts[k] != 'Q') { cr_r[k] = pos_r[k]; cr_c[k] = pos_c[k]; }\n        // Apply P/Q\n        for(int k=0; k<5; ++k) {\n            if(acts[k] == 'P' && grid[cr_r[k]][cr_c[k]] != -1) {\n                cr_hold[k] = grid[cr_r[k]][cr_c[k]]; grid[cr_r[k]][cr_c[k]] = -1;\n            } else if(acts[k] == 'Q' && cr_hold[k] != -1 && grid[cr_r[k]][cr_c[k]] == -1) {\n                grid[cr_r[k]][cr_c[k]] = cr_hold[k]; cr_hold[k] = -1;\n            }\n        }\n\n        for(int k=0; k<5; ++k) S[k] += acts[k];\n\n        // 3. Dispatch\n        bool all_done = true;\n        for(int i=0; i<5; ++i) {\n            if(grid[i][4] != -1) {\n                if(grid[i][4] == dnext[i]) { dnext[i]++; dispatched++; }\n                grid[i][4] = -1; // Dispatched (or penalized & removed)\n            }\n            if(dnext[i] != i*5 + 5) all_done = false;\n        }\n        if(all_done) break;\n    }\n\n    for(int i=0; i<5; ++i) cout << S[i] << \"\\n\";\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n#pragma GCC optimize(\"O3,unroll-loops\")\n\nint N;\nint grid[20][20];\nint cur_r = 0, cur_c = 0;\nlong long load = 0;\nint turns = 0;\n\ninline int manhattan(int r1, int c1, int r2, int c2) {\n    return abs(r1 - r2) + abs(c1 - c2);\n}\n\nvoid output_move(char dir) {\n    cout << dir << \"\\n\";\n    turns++;\n    if (dir == 'U') cur_r--;\n    else if (dir == 'D') cur_r++;\n    else if (dir == 'L') cur_c--;\n    else if (dir == 'R') cur_c++;\n}\n\nvoid move_to(int tr, int tc) {\n    while (cur_r != tr) output_move(cur_r < tr ? 'D' : 'U');\n    while (cur_c != tc) output_move(cur_c < tc ? 'R' : 'L');\n}\n\nvoid do_load() {\n    if (grid[cur_r][cur_c] <= 0) return;\n    int d = grid[cur_r][cur_c];\n    cout << \"+\" << d << \"\\n\";\n    load += d;\n    grid[cur_r][cur_c] = 0;\n    turns++;\n}\n\nvoid do_unload() {\n    if (load <= 0) return;\n    int d = (int)min((long long)-grid[cur_r][cur_c], load);\n    cout << \"-\" << d << \"\\n\";\n    load -= d;\n    grid[cur_r][cur_c] += d;\n    turns++;\n}\n\nbool is_flat() {\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (grid[i][j] != 0) return false;\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N)) return 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> grid[i][j];\n\n    // Penalty per unit of remaining load after step 1.\n    // Balances immediate movement cost vs future load-carrying penalty.\n    const long long LOAD_PENALTY = 110;\n    const int TOP_K = 60;\n\n    // Pre-allocated candidate storage\n    struct Candidate {\n        int r, c, amt;\n        long long cost1;\n    };\n    vector<Candidate> cands;\n    cands.reserve(400);\n\n    while (!is_flat() && turns < 99000) {\n        cands.clear();\n\n        // 1. Collect all valid immediate targets\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (grid[i][j] == 0) continue;\n                if (load == 0 && grid[i][j] < 0) continue;\n                if (load > 0 && grid[i][j] > 0) continue;\n\n                int d = manhattan(cur_r, cur_c, i, j);\n                int amt = (load == 0) ? grid[i][j] : (int)min((long long)-grid[i][j], load);\n                long long cost1 = (long long)d * (100LL + load);\n                cands.push_back({i, j, amt, cost1});\n            }\n        }\n\n        if (cands.empty()) break;\n\n        // 2. Sort by immediate cost to process most promising first\n        sort(cands.begin(), cands.end(), [](const Candidate& a, const Candidate& b) {\n            return a.cost1 < b.cost1;\n        });\n        if (cands.size() > TOP_K) cands.resize(TOP_K);\n\n        // 3. Depth-2 Lookahead with Load Penalty\n        long long best_score = -1;\n        int best_r = -1, best_c = -1, best_amt = 0;\n\n        for (const auto& cand : cands) {\n            long long sim_load = (load == 0) ? load + cand.amt : load - cand.amt;\n            \n            // Simulate state change (backtracking avoids memcpy)\n            int orig_val = grid[cand.r][cand.c];\n            grid[cand.r][cand.c] = (load == 0) ? orig_val - cand.amt : orig_val + cand.amt;\n\n            // Find minimum cost for step 2 from the new state\n            long long min_cost2 = 2000000000000000000LL;\n            bool found_next = false;\n\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    if (grid[i][j] == 0) continue;\n                    if (sim_load == 0 && grid[i][j] < 0) continue;\n                    if (sim_load > 0 && grid[i][j] > 0) continue;\n\n                    int d2 = manhattan(cand.r, cand.c, i, j);\n                    long long cost2 = (long long)d2 * (100LL + sim_load);\n                    if (cost2 < min_cost2) {\n                        min_cost2 = cost2;\n                        found_next = true;\n                    }\n                }\n            }\n\n            long long step2_cost = found_next ? min_cost2 : 0;\n            long long total_score = cand.cost1 + step2_cost + LOAD_PENALTY * sim_load;\n\n            // Update best candidate\n            if (best_score == -1 || total_score < best_score || \n               (total_score == best_score && cand.amt > best_amt)) {\n                best_score = total_score;\n                best_r = cand.r;\n                best_c = cand.c;\n                best_amt = cand.amt;\n            }\n\n            // Backtrack simulation\n            grid[cand.r][cand.c] = orig_val;\n        }\n\n        // 4. Execute optimal move\n        move_to(best_r, best_c);\n        if (load == 0) do_load();\n        else do_unload();\n    }\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <cstring>\n\n#pragma GCC optimize(\"O3,unroll-loops,fast-math\")\n\nusing namespace std;\n\nint N, M, T, SEED_COUNT;\nint X[60][15];\nint V[60], max_c[60];\nint adj[36][4], deg[36];\nbool is_adj[36][36];\nint P[36];\nmt19937 rng(42);\n\n// Fast L1 distance, branchless for vectorization\ninline int l1_dist(int u, int v) {\n    int s = 0;\n    const int* xu = X[u];\n    const int* xv = X[v];\n    #pragma GCC ivdep\n    for (int l = 0; l < M; ++l) {\n        int d = xu[l] - xv[l];\n        s += (d < 0) ? -d : d;\n    }\n    return s;\n}\n\nvoid precompute_grid() {\n    memset(is_adj, 0, sizeof(is_adj));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int u = i * N + j;\n            deg[u] = 0;\n            if (j + 1 < N) {\n                int v = i * N + (j + 1);\n                adj[u][deg[u]++] = v;\n                adj[v][deg[v]++] = u;\n                is_adj[u][v] = is_adj[v][u] = true;\n            }\n            if (i + 1 < N) {\n                int v = (i + 1) * N + j;\n                adj[u][deg[u]++] = v;\n                adj[v][deg[v]++] = u;\n                is_adj[u][v] = is_adj[v][u] = true;\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> T)) return 0;\n    SEED_COUNT = 2 * N * (N - 1);\n    for (int i = 0; i < SEED_COUNT; ++i) {\n        V[i] = 0; max_c[i] = 0;\n        for (int j = 0; j < M; ++j) {\n            cin >> X[i][j];\n            V[i] += X[i][j];\n            if (X[i][j] > max_c[i]) max_c[i] = X[i][j];\n        }\n    }\n\n    precompute_grid();\n\n    // Adaptive parameters: balance diversity early, value late\n    const double alphas[10]   = {40.0, 35.0, 25.0, 20.0, 15.0, 12.0, 10.0, 8.0, 5.0, 2.0};\n    const double lambdas[10]  = {1.4, 1.3, 1.2, 1.1, 1.0, 0.9, 0.8, 0.7, 0.6, 0.5};\n    const int    iters[10]    = {100000, 95000, 90000, 85000, 80000, 75000, 70000, 65000, 60000, 55000};\n\n    vector<int> pos_by_degree(36);\n    iota(pos_by_degree.begin(), pos_by_degree.end(), 0);\n    sort(pos_by_degree.begin(), pos_by_degree.end(), [&](int a, int b) {\n        return deg[a] > deg[b];\n    });\n\n    vector<pair<int, double>> seed_scores(SEED_COUNT);\n    uniform_int_distribution<int> pos_dist(0, 35);\n    const double INV_MAX = 1.0 / rng.max();\n\n    for (int t = 0; t < T; ++t) {\n        double alpha = alphas[t];\n        double lambda = lambdas[t];\n        int MAX_ITER = iters[t];\n\n        // 1. Score & Select Top 36 Seeds\n        for (int i = 0; i < SEED_COUNT; ++i) {\n            seed_scores[i] = {i, V[i] + alpha * max_c[i]};\n        }\n        nth_element(seed_scores.begin(), seed_scores.begin() + 36, seed_scores.end(),\n                    [](const auto& a, const auto& b) { return a.second > b.second; });\n\n        int top_seeds[36];\n        for (int i = 0; i < 36; ++i) top_seeds[i] = seed_scores[i].first;\n\n        // Place highest value seeds in highest degree positions\n        sort(top_seeds, top_seeds + 36, [&](int a, int b) { return V[a] > V[b]; });\n        for (int i = 0; i < 36; ++i) P[pos_by_degree[i]] = top_seeds[i];\n\n        // 2. Simulated Annealing (Tight Delta Calculation)\n        double temp = 10.0;\n        const double cool_factor = 0.99995;\n        \n        for (int iter = 0; iter < MAX_ITER; ++iter) {\n            temp *= cool_factor;\n            if (temp < 0.01) temp = 0.01;\n\n            int p1 = pos_dist(rng);\n            int p2 = pos_dist(rng);\n            if (p1 == p2) continue;\n\n            int u1 = P[p1], u2 = P[p2];\n            double delta = 0.0;\n            int v_diff = V[u2] - V[u1];\n\n            // Delta for edges incident to p1\n            for (int k = 0; k < deg[p1]; ++k) {\n                int nb = adj[p1][k];\n                if (nb == p2) continue;\n                delta += lambda * (l1_dist(u2, P[nb]) - l1_dist(u1, P[nb]));\n            }\n            delta += deg[p1] * v_diff;\n\n            // Delta for edges incident to p2\n            for (int k = 0; k < deg[p2]; ++k) {\n                int nb = adj[p2][k];\n                if (nb == p1) continue;\n                delta += lambda * (l1_dist(u1, P[nb]) - l1_dist(u2, P[nb]));\n            }\n            delta += deg[p2] * (-v_diff);\n\n            // Note: The edge (p1, p2) itself has \u0394=0 for both V and L1 terms, so it's correctly skipped.\n\n            if (delta > 0.0 || std::exp(delta / temp) > rng() * INV_MAX) {\n                P[p1] = u2; P[p2] = u1;\n            }\n        }\n\n        // 3. Output Placement\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                cout << P[i * N + j] << (j == N - 1 ? \"\" : \" \");\n            }\n            cout << \"\\n\";\n        }\n        cout.flush();\n\n        // 4. Read Next Generation\n        if (t < T - 1) {\n            for (int i = 0; i < SEED_COUNT; ++i) {\n                V[i] = 0; max_c[i] = 0;\n                for (int j = 0; j < M; ++j) {\n                    cin >> X[i][j];\n                    V[i] += X[i][j];\n                    if (X[i][j] > max_c[i]) max_c[i] = X[i][j];\n                }\n            }\n        }\n    }\n\n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n\nusing namespace std;\n\nint N, M, V;\nvector<string> T_grid;\nvector<vector<int>> grid; // 1 if takoyaki present, 0 otherwise\nint finger_dir[20];       // 0:R, 1:D, 2:L, 3:U\nbool holding[20];         // true if holding takoyaki\nint rx = 0, ry = 0;\nconst int dx[4] = {0, 1, 0, -1}; // R, D, L, U\nconst int dy[4] = {1, 0, -1, 0};\nconst char dch[4] = {'R', 'D', 'L', 'U'};\n\nstruct Pos { int r, c; };\n\nint dist[35][35];\nPos parent[35][35];\n\n// Check if (r, c) is a valid root position for pickup\n// Valid if a neighbor has a takoyaki that is not at its target, and we have capacity.\nbool is_valid_pickup_pos(int r, int c, int carried) {\n    if (carried >= V - 1) return false; // No capacity\n    for (int d = 0; d < 4; ++d) {\n        int nr = r + dx[d], nc = c + dy[d];\n        if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n            // Source has item, but is not a target (or item is misplaced)\n            // Actually, if T_grid is '1', it's a target. If grid is 1, it's satisfied.\n            // We only want to pick up if grid=1 and T='0' (misplaced item).\n            if (grid[nr][nc] == 1 && T_grid[nr][nc] == '0') {\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\n// Check if (r, c) is a valid root position for drop\n// Valid if a neighbor is a target and is currently empty, and we are holding something.\nbool is_valid_drop_pos(int r, int c, int carried) {\n    if (carried <= 0) return false; // Empty hands\n    for (int d = 0; d < 4; ++d) {\n        int nr = r + dx[d], nc = c + dy[d];\n        if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n            // Cell is empty but should be a target\n            if (grid[nr][nc] == 0 && T_grid[nr][nc] == '1') {\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> V)) return 0;\n    T_grid.resize(N); \n    grid.assign(N, vector<int>(N, 0));\n    \n    string s_row;\n    for (int i = 0; i < N; ++i) {\n        cin >> s_row;\n        for (int j = 0; j < N; ++j) {\n            if (s_row[j] == '1') grid[i][j] = 1;\n        }\n    }\n    for (int i = 0; i < N; ++i) cin >> T_grid[i];\n\n    // Output tree design: Star graph with root 0 and leaves 1..V-1\n    cout << V << \"\\n\";\n    for (int i = 1; i < V; ++i) cout << \"0 1\\n\";\n    cout << rx << \" \" << ry << \"\\n\";\n\n    for (int i = 0; i < V; ++i) {\n        finger_dir[i] = 0;\n        holding[i] = false;\n    }\n\n    int turn = 0;\n    const int MAX_TURNS = 100000;\n\n    while (turn < MAX_TURNS) {\n        // Check if done\n        bool done = true;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (grid[i][j] != (T_grid[i][j] - '0')) {\n                    done = false;\n                    break;\n                }\n            }\n            if (!done) break;\n        }\n        if (done) break;\n\n        int carried = 0;\n        for(int i = 0; i < V; ++i) if(holding[i]) carried++;\n\n        // BFS to find nearest valid pickup and drop positions\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                dist[i][j] = -1;\n                parent[i][j] = {-1, -1};\n            }\n        }\n\n        queue<Pos> q;\n        q.push({rx, ry});\n        dist[rx][ry] = 0;\n\n        bool found_p = false, found_d = false;\n        Pos target_p = {-1, -1}, target_d = {-1, -1};\n        int dist_p = -1, dist_d = -1;\n\n        // Determine what we need to find based on capacity\n        bool need_p = (carried < V - 1);\n        bool need_d = (carried > 0);\n\n        while (!q.empty()) {\n            Pos u = q.front(); q.pop();\n            \n            // Check validity\n            if (need_p && !found_p && is_valid_pickup_pos(u.r, u.c, carried)) {\n                found_p = true;\n                target_p = u;\n                dist_p = dist[u.r][u.c];\n            }\n            if (need_d && !found_d && is_valid_drop_pos(u.r, u.c, carried)) {\n                found_d = true;\n                target_d = u;\n                dist_d = dist[u.r][u.c];\n            }\n            \n            // Optimization: If we found both needed targets, we can stop.\n            // Since BFS explores in increasing distance, these are the nearest.\n            if ((need_p && found_p) && (need_d && found_d)) {\n                break;\n            }\n            // If we only needed one and found it, break\n            if ((need_p && !need_d && found_p) || (need_d && !need_p && found_d)) {\n                break;\n            }\n\n            // Expand\n            int d_u = dist[u.r][u.c];\n            // Pruning: if current distance is already worse than found targets (if any), \n            // we might not need to expand, but since we break above, it's fine.\n            \n            for (int dir = 0; dir < 4; ++dir) {\n                int nr = u.r + dx[dir], nc = u.c + dy[dir];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                    if (dist[nr][nc] == -1) {\n                        dist[nr][nc] = d_u + 1;\n                        parent[nr][nc] = u;\n                        q.push({nr, nc});\n                    }\n                }\n            }\n        }\n\n        Pos target = {-1, -1};\n        \n        // Decide target based on needs and distances\n        if (!need_p && !need_d) {\n            break; // Should be done\n        } else if (need_p && !need_d) {\n            if (found_p) target = target_p;\n        } else if (!need_p && need_d) {\n            if (found_d) target = target_d;\n        } else {\n            // Both needed\n            if (found_p && found_d) {\n                // Prefer drop if distances are equal to free up capacity\n                if (dist_d <= dist_p) target = target_d;\n                else target = target_p;\n            } else if (found_p) {\n                target = target_p;\n            } else if (found_d) {\n                target = target_d;\n            }\n        }\n\n        // Move root towards target\n        char move_cmd = '.';\n        if (target.r != -1 && (target.r != rx || target.c != ry)) {\n            // Trace back to find first step\n            Pos curr = target;\n            while (dist[curr.r][curr.c] > 1) {\n                curr = parent[curr.r][curr.c];\n            }\n            // curr is now the neighbor of root on the path\n            int dr = curr.r - rx;\n            int dc = curr.c - ry;\n            if (dr == 1) move_cmd = 'D';\n            else if (dr == -1) move_cmd = 'U';\n            else if (dc == 1) move_cmd = 'R';\n            else if (dc == -1) move_cmd = 'L';\n            \n            // Update root pos\n            rx = curr.r; ry = curr.c;\n        }\n\n        // Action phase\n        // Identify all possible actions from current root position\n        struct Action { int dir; bool is_drop; int neighbor_r, neighbor_c; };\n        vector<Action> actions;\n\n        for (int d = 0; d < 4; ++d) {\n            int nr = rx + dx[d], nc = ry + dy[d];\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                bool can_pick = (grid[nr][nc] == 1 && T_grid[nr][nc] == '0');\n                bool can_drop = (grid[nr][nc] == 0 && T_grid[nr][nc] == '1');\n                \n                // Check capacity dynamically? \n                // Strictly, we check if there exists a finger that can perform this.\n                // But for listing potential actions, we check global capacity constraints.\n                // However, since we might drop first, capacity might increase.\n                // But to simplify, we list all geometrically valid actions.\n                // The matching phase will filter based on available fingers.\n                \n                if (can_pick) actions.push_back({d, false, nr, nc});\n                if (can_drop) actions.push_back({d, true, nr, nc});\n            }\n        }\n\n        // Sort actions: Drops first (to free up capacity), then Pickups\n        sort(actions.begin(), actions.end(), [](const Action& a, const Action& b) {\n            return a.is_drop > b.is_drop;\n        });\n\n        // Generate command string\n        string cmd(2 * V, '.');\n        cmd[0] = move_cmd;\n        // cmd[1..V-1] for rotation, cmd[V..2V-1] for action (vertex i -> index V+i)\n        \n        // Matching actions to fingers\n        vector<bool> finger_used(V, false);\n        vector<Action> pending_actions = actions;\n\n        // Greedy matching: find best (action, finger) pair with min rotation cost\n        while (!pending_actions.empty()) {\n            int best_cost = 100;\n            int best_action_idx = -1;\n            int best_finger_id = -1;\n            \n            for (int i = 0; i < pending_actions.size(); ++i) {\n                const Action& act = pending_actions[i];\n                bool need_holding = act.is_drop;\n                \n                for (int f = 1; f < V; ++f) {\n                    if (finger_used[f]) continue;\n                    // Finger must match holding state required by action\n                    if (holding[f] != need_holding) continue;\n                    \n                    // Calculate rotation cost\n                    int cur = finger_dir[f];\n                    int target_d = act.dir;\n                    int diff = (target_d - cur + 4) % 4;\n                    int cost = min(diff, 4 - diff);\n                    \n                    if (cost < best_cost) {\n                        best_cost = cost;\n                        best_action_idx = i;\n                        best_finger_id = f;\n                    }\n                }\n            }\n            \n            if (best_action_idx == -1) break; // No compatible finger found\n            \n            // Assign\n            const Action& act = pending_actions[best_action_idx];\n            int f = best_finger_id;\n            finger_used[f] = true;\n            \n            // Determine rotation command\n            int cur = finger_dir[f];\n            int target_d = act.dir;\n            int diff = (target_d - cur + 4) % 4;\n            char rot = '.';\n            if (diff == 1) rot = 'R';\n            else if (diff == 2) rot = 'R'; // 180 deg -> 90 CW\n            else if (diff == 3) rot = 'L';\n            else rot = '.';\n            \n            cmd[f] = rot; // Rotation command for vertex f\n            \n            // Update simulated direction\n            if (rot == 'R') finger_dir[f] = (cur + 1) % 4;\n            else if (rot == 'L') finger_dir[f] = (cur + 3) % 4;\n            \n            // Check if aligned after rotation\n            bool aligned_after = false;\n            if (diff == 0) aligned_after = true;\n            else if (diff == 1 && rot == 'R') aligned_after = true;\n            else if (diff == 3 && rot == 'L') aligned_after = true;\n            \n            if (aligned_after) {\n                // Perform action\n                cmd[V + f] = 'P';\n                if (act.is_drop) {\n                    grid[act.neighbor_r][act.neighbor_c] = 1;\n                    holding[f] = false;\n                } else {\n                    grid[act.neighbor_r][act.neighbor_c] = 0;\n                    holding[f] = true;\n                }\n            }\n            \n            pending_actions.erase(pending_actions.begin() + best_action_idx);\n        }\n        \n        cout << cmd << \"\\n\";\n        turn++;\n    }\n\n    return 0;\n}","ahc039":"#include <iostream>\n#include <vector>\n#include <random>\n#include <cmath>\n#include <algorithm>\n#include <map>\n#include <queue>\n\nusing namespace std;\n\nstruct Pt {\n    int x, y;\n    bool operator==(const Pt& o) const { return x == o.x && y == o.y; }\n    bool operator!=(const Pt& o) const { return !(*this == o); }\n    bool operator<(const Pt& o) const { return x != o.x ? x < o.x : y < o.y; }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    if (!(cin >> N)) return 0;\n    vector<Pt> mack(N), sard(N);\n    for (int i = 0; i < N; ++i) cin >> mack[i].x >> mack[i].y;\n    for (int i = 0; i < N; ++i) cin >> sard[i].x >> sard[i].y;\n\n    const int D = 400;\n    const int G = 100000 / D + 2;\n    vector<vector<int>> grid(G, vector<int>(G, 0));\n    vector<vector<bool>> sel(G, vector<bool>(G, false));\n\n    auto add_points = [&](const vector<Pt>& pts, int val) {\n        for (auto& p : pts) {\n            int cx = p.x / D;\n            int cy = p.y / D;\n            if (cx >= 0 && cx < G && cy >= 0 && cy < G) {\n                grid[cy][cx] += val;\n            }\n        }\n    };\n    add_points(mack, 1);\n    add_points(sard, -1);\n\n    mt19937 rng(42);\n    double T = 100.0;\n    int iters = 400000;\n\n    int best_r = 0, best_c = 0, best_w = -1e9;\n    for (int r = 0; r < G; ++r) {\n        for (int c = 0; c < G; ++c) {\n            if (grid[r][c] > best_w) {\n                best_w = grid[r][c]; best_r = r; best_c = c;\n            }\n        }\n    }\n    if (best_w > 0) sel[best_r][best_c] = true;\n\n    const int dr[4] = {-1, 1, 0, 0};\n    const int dc[4] = {0, 0, -1, 1};\n\n    for (int it = 0; it < iters; ++it) {\n        T *= 0.99995;\n        if (T < 0.05) T = 0.05;\n\n        int r = rng() % G;\n        int c = rng() % G;\n\n        bool is_sel = sel[r][c];\n        bool can_toggle = false;\n\n        if (!is_sel) {\n            for (int i = 0; i < 4; ++i) {\n                int nr = r + dr[i], nc = c + dc[i];\n                if (nr >= 0 && nr < G && nc >= 0 && nc < G && sel[nr][nc]) {\n                    can_toggle = true; break;\n                }\n            }\n        } else {\n            bool on_boundary = false;\n            for (int i = 0; i < 4; ++i) {\n                int nr = r + dr[i], nc = c + dc[i];\n                if (nr < 0 || nr >= G || nc < 0 || nc >= G || !sel[nr][nc]) {\n                    on_boundary = true; break;\n                }\n            }\n            can_toggle = on_boundary;\n        }\n\n        if (!can_toggle) continue;\n\n        int delta = is_sel ? -grid[r][c] : grid[r][c];\n        double prob = 0.0;\n        if (delta > 0) prob = 1.0;\n        else {\n            double val = delta / T;\n            if (val < -50) val = -50;\n            if (val > 50) val = 50;\n            prob = exp(val);\n        }\n        uniform_real_distribution<double> dist(0.0, 1.0);\n        if (dist(rng) < prob) {\n            sel[r][c] = !is_sel;\n        }\n    }\n\n    vector<vector<bool>> final_sel(G, vector<bool>(G, false));\n    vector<vector<bool>> visited(G, vector<bool>(G, false));\n    int start_r = -1, start_c = -1;\n    for (int r = 0; r < G; ++r) {\n        for (int c = 0; c < G; ++c) {\n            if (sel[r][c]) { start_r = r; start_c = c; r = G; break; }\n        }\n    }\n\n    if (start_r != -1) {\n        queue<pair<int, int>> q;\n        q.emplace(start_r, start_c);\n        visited[start_r][start_c] = true;\n        while (!q.empty()) {\n            auto [r, c] = q.front(); q.pop();\n            final_sel[r][c] = true;\n            for (int i = 0; i < 4; ++i) {\n                int nr = r + dr[i], nc = c + dc[i];\n                if (nr >= 0 && nr < G && nc >= 0 && nc < G && sel[nr][nc] && !visited[nr][nc]) {\n                    visited[nr][nc] = true;\n                    q.emplace(nr, nc);\n                }\n            }\n        }\n    }\n\n    vector<vector<bool>> outside(G, vector<bool>(G, false));\n    queue<pair<int, int>> q_out;\n    for (int c = 0; c < G; ++c) {\n        if (!final_sel[0][c]) { outside[0][c] = true; q_out.emplace(0, c); }\n        if (!final_sel[G-1][c]) { outside[G-1][c] = true; q_out.emplace(G-1, c); }\n    }\n    for (int r = 0; r < G; ++r) {\n        if (!final_sel[r][0]) { outside[r][0] = true; q_out.emplace(r, 0); }\n        if (!final_sel[r][G-1]) { outside[r][G-1] = true; q_out.emplace(r, G-1); }\n    }\n    while (!q_out.empty()) {\n        auto [r, c] = q_out.front(); q_out.pop();\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i], nc = c + dc[i];\n            if (nr >= 0 && nr < G && nc >= 0 && nc < G && !final_sel[nr][nc] && !outside[nr][nc]) {\n                outside[nr][nc] = true;\n                q_out.emplace(nr, nc);\n            }\n        }\n    }\n    for (int r = 0; r < G; ++r) {\n        for (int c = 0; c < G; ++c) {\n            if (!final_sel[r][c] && !outside[r][c]) {\n                final_sel[r][c] = true;\n            }\n        }\n    }\n\n    map<pair<Pt, Pt>, int> edge_cnt;\n    auto add_edge = [&](Pt u, Pt v) {\n        if (u.x > v.x || (u.x == v.x && u.y > v.y)) swap(u, v);\n        edge_cnt[{u, v}]++;\n    };\n\n    for (int r = 0; r < G; ++r) {\n        for (int c = 0; c < G; ++c) {\n            if (final_sel[r][c]) {\n                Pt p1 = {c * D, r * D};\n                Pt p2 = {min((c + 1) * D, 100000), r * D};\n                Pt p3 = {min((c + 1) * D, 100000), min((r + 1) * D, 100000)};\n                Pt p4 = {c * D, min((r + 1) * D, 100000)};\n                add_edge(p1, p2); add_edge(p2, p3);\n                add_edge(p3, p4); add_edge(p4, p1);\n            }\n        }\n    }\n\n    map<Pt, vector<Pt>> adj;\n    for (auto& [e, cnt] : edge_cnt) {\n        if (cnt % 2 == 1) {\n            adj[e.first].push_back(e.second);\n            adj[e.second].push_back(e.first);\n        }\n    }\n\n    vector<Pt> poly;\n    if (!adj.empty()) {\n        Pt curr = adj.begin()->first;\n        Pt prev = {-1, -1};\n        int steps = 0;\n        while (steps < 100000) {\n            poly.push_back(curr);\n            Pt next = {-1, -1};\n            for (auto& nb : adj[curr]) {\n                if (nb != prev) {\n                    next = nb;\n                    break;\n                }\n            }\n            prev = curr;\n            curr = next;\n            if (curr == poly[0] || curr.x < 0) break;\n            steps++;\n        }\n    }\n\n    vector<Pt> simplified;\n    int m = poly.size();\n    if (m >= 3) {\n        for (int i = 0; i < m; ++i) {\n            Pt prev = poly[(i - 1 + m) % m];\n            Pt curr = poly[i];\n            Pt next = poly[(i + 1) % m];\n            long long dx1 = curr.x - prev.x;\n            long long dy1 = curr.y - prev.y;\n            long long dx2 = next.x - curr.x;\n            long long dy2 = next.y - curr.y;\n            if (dx1 * dy2 != dx2 * dy1) {\n                if (simplified.empty() || !(curr == simplified.back())) {\n                    simplified.push_back(curr);\n                }\n            }\n        }\n    }\n    if (simplified.empty()) simplified = poly;\n\n    vector<Pt> final_poly;\n    for (size_t i = 0; i < simplified.size(); ++i) {\n        if (final_poly.empty() || !(simplified[i] == final_poly.back())) {\n            final_poly.push_back(simplified[i]);\n        }\n    }\n    if (final_poly.size() > 1 && final_poly.front() == final_poly.back()) {\n        final_poly.pop_back();\n    }\n\n    if (final_poly.size() < 4) {\n        final_poly = {{0, 0}, {D, 0}, {D, D}, {0, D}};\n    }\n\n    cout << final_poly.size() << \"\\n\";\n    for (auto& p : final_poly) {\n        cout << p.x << \" \" << p.y << \"\\n\";\n    }\n\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n#pragma GCC optimize(\"O3,unroll-loops\")\n\nstruct Config { \n    bool skip = false; \n    bool rot = false; \n    char dir = 'U'; \n    int ref = -1; \n};\nstruct Rect { int x, y, w, h; };\n\nmt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Fast deterministic simulation matching judge rules exactly\n// Packs rectangles towards (0,0). 'U' minimizes y, 'L' minimizes x.\npair<long long, long long> simulate(int N, const vector<Config>& cfg, const vector<pair<int,int>>& wh, long long& skip_pen) {\n    vector<Rect> p(N);\n    int max_x = 0, max_y = 0;\n    skip_pen = 0;\n    \n    for(int i = 0; i < N; ++i) {\n        if(cfg[i].skip) { \n            skip_pen += wh[i].first + wh[i].second; \n            continue; \n        }\n        int w = cfg[i].rot ? wh[i].second : wh[i].first;\n        int h = cfg[i].rot ? wh[i].first : wh[i].second;\n        int x = 0, y = 0;\n        \n        // Align with reference rectangle if valid\n        if(cfg[i].ref != -1 && !cfg[cfg[i].ref].skip) {\n            if(cfg[i].dir == 'U') x = p[cfg[i].ref].x + p[cfg[i].ref].w;\n            else y = p[cfg[i].ref].y + p[cfg[i].ref].h;\n        }\n        \n        // Gravity simulation\n        if(cfg[i].dir == 'U') {\n            // Slide upward (decrease y) until hitting y=0 or bottom of another rect\n            y = 0;\n            for(int j = 0; j < i; ++j) {\n                if(cfg[j].skip) continue;\n                // Check horizontal overlap\n                if(x < p[j].x + p[j].w && p[j].x < x + w)\n                    y = max(y, p[j].y + p[j].h);\n            }\n        } else {\n            // Slide leftward (decrease x) until hitting x=0 or right edge of another rect\n            x = 0;\n            for(int j = 0; j < i; ++j) {\n                if(cfg[j].skip) continue;\n                // Check vertical overlap\n                if(y < p[j].y + p[j].h && p[j].y < y + h)\n                    x = max(x, p[j].x + p[j].w);\n            }\n        }\n        \n        p[i] = {x, y, w, h};\n        if(x + w > max_x) max_x = x + w;\n        if(y + h > max_y) max_y = y + h;\n    }\n    return {max_x, max_y};\n}\n\ninline long long calc_cost(int N, const vector<Config>& cfg, const vector<pair<int,int>>& wh) {\n    long long skip_pen;\n    auto [mx, my] = simulate(N, cfg, wh, skip_pen);\n    return mx + my + skip_pen;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    \n    int N, T, sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n    \n    vector<pair<int,int>> wh(N);\n    vector<int> ids(N); iota(ids.begin(), ids.end(), 0);\n    for (int i = 0; i < N; ++i) cin >> wh[i].first >> wh[i].second;\n\n    // Initialize configuration\n    vector<Config> cur(N), best(N);\n    for (int i = 0; i < N; ++i) {\n        cur[i].rot = (rng() & 1);\n        cur[i].dir = (rng() & 1) ? 'U' : 'L';\n        cur[i].ref = (i > 0 && rng() % 3 != 0) ? (rng() % i) : -1;\n        cur[i].skip = (rng() % 5 == 0); // Start with ~20% skipped\n    }\n    \n    long long cur_cost = calc_cost(N, cur, wh);\n    long long best_cost = cur_cost;\n    best = cur;\n\n    double temp = 8000.0;\n    auto start_time = chrono::steady_clock::now();\n\n    for (int turn = 0; turn < T; ++turn) {\n        // Read feedback from previous turn\n        if (turn > 0) {\n            int W_in, H_in; \n            cin >> W_in >> H_in;\n        }\n\n        // Simulated Annealing Loop\n        while (true) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double, std::milli>(now - start_time).count();\n            if (elapsed > 2750.0) break; // Safe cutoff for I/O\n\n            vector<Config> next = cur;\n            int i = rng() % N;\n            int mt = rng() % 100;\n            \n            // Safe, bounded mutations\n            if (mt < 15) { // Toggle skip\n                next[i].skip = !next[i].skip;\n            } else if (mt < 30) { // Toggle rotation\n                next[i].rot = !next[i].rot;\n            } else if (mt < 45) { // Toggle direction\n                next[i].dir = (next[i].dir == 'U' ? 'L' : 'U');\n            } else if (mt < 80) { // Change reference to valid previous index\n                if (i > 0) next[i].ref = rng() % i;\n                else next[i].ref = -1;\n            } else { // Reset reference to -1\n                next[i].ref = -1;\n            }\n\n            long long next_cost = calc_cost(N, next, wh);\n            double delta = (double)next_cost - cur_cost;\n            \n            // Metropolis criterion with overflow protection\n            if (delta < 0 || (double)(rng() & 0xFFFFFF) / 0xFFFFFF < exp(max(-50.0, -delta / temp))) {\n                cur = next;\n                cur_cost = next_cost;\n                if (cur_cost < best_cost) {\n                    best_cost = cur_cost;\n                    best = cur;\n                }\n            }\n            \n            // Smooth exponential cooling\n            temp *= 0.99985;\n        }\n\n        // Ensure at least one rectangle is placed to avoid format edge cases\n        bool any_placed = false;\n        for(int i=0; i<N; ++i) if(!best[i].skip) any_placed = true;\n        if (!any_placed) best[0].skip = false;\n\n        // Output configuration\n        int n_place = 0;\n        for(int i = 0; i < N; ++i) if(!best[i].skip) n_place++;\n        \n        cout << n_place << \"\\n\";\n        for(int i = 0; i < N; ++i) {\n            if(!best[i].skip) {\n                cout << i << \" \" << best[i].rot << \" \" << best[i].dir << \" \" << best[i].ref << \"\\n\";\n            }\n        }\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc041":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <chrono>\n#include <random>\n#include <cstring>\n\nusing namespace std;\n\n#pragma GCC optimize(\"O3,unroll-loops\")\n\nconst int MAXN = 1005;\nconst int INF = 1e9;\n\nint dist_mat[MAXN][MAXN];\nint A[MAXN];\nvector<int> adj[MAXN];\nint N, M, H;\n\ninline long long compute_score(const vector<int>& d) {\n    long long score = 0;\n    for (int i = 0; i < N; ++i) {\n        int h = d[i];\n        if (h > H) return -1; // Invalid\n        score += (long long)(h + 1) * A[i];\n    }\n    return score;\n}\n\n// Incrementally update distances after root set changes\nvoid update_distances(vector<int>& d, const vector<int>& roots) {\n    // Reset distances for nodes whose closest root was removed/changed\n    // We do a full recomputation for simplicity and cache efficiency, \n    // optimized with early break on validity check\n    // Actually, full recomputation is O(N*|S|). With |S|~30, it's ~3e4 ops.\n    // For 50k iterations, 1.5e9 ops. Might be tight. \n    // We use a faster approach: maintain d, only recompute if needed.\n    // But given time limit, a highly optimized full recompute is safer against bugs.\n    \n    // Optimized full recompute:\n    for (int i = 0; i < N; ++i) d[i] = H + 1;\n    for (int r : roots) {\n        const int* dr = dist_mat[r];\n        for (int i = 0; i < N; ++i) {\n            if (dr[i] < d[i]) d[i] = dr[i];\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    auto start_time = chrono::steady_clock::now();\n    if (!(cin >> N >> M >> H)) return 0;\n\n    for (int i = 0; i < N; ++i) cin >> A[i];\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    for (int i = 0; i < N; ++i) { int x, y; cin >> x >> y; }\n\n    // APSP\n    memset(dist_mat, 0x3f, sizeof(dist_mat));\n    for (int i = 0; i < N; ++i) {\n        queue<int> q;\n        dist_mat[i][i] = 0;\n        q.push(i);\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            int nd = dist_mat[i][u] + 1;\n            for (int v : adj[u]) {\n                if (nd < dist_mat[i][v]) {\n                    dist_mat[i][v] = nd;\n                    q.push(v);\n                }\n            }\n        }\n    }\n\n    // Greedy Initialization\n    vector<int> d(N, INF);\n    vector<int> roots;\n    vector<bool> is_root(N, false);\n\n    // Find uncovered node with min beauty\n    while (true) {\n        int best_v = -1, min_A = INF;\n        bool all_covered = true;\n        for (int i = 0; i < N; ++i) {\n            if (d[i] > H) {\n                all_covered = false;\n                if (A[i] < min_A) {\n                    min_A = A[i];\n                    best_v = i;\n                }\n            }\n        }\n        if (all_covered) break;\n\n        // Candidate roots within H distance of best_v\n        vector<int> cands;\n        cands.reserve(N);\n        for (int r = 0; r < N; ++r) {\n            if (dist_mat[r][best_v] <= H) cands.push_back(r);\n        }\n        sort(cands.begin(), cands.end(), [](int a, int b) { return A[a] < A[b]; });\n\n        int K = min((int)cands.size(), 30);\n        int best_r = -1;\n        long long best_sc = -1;\n        \n        // Evaluate top candidates\n        for (int i = 0; i < K; ++i) {\n            int r = cands[i];\n            long long cur_sc = 0;\n            bool ok = true;\n            for (int u = 0; u < N; ++u) {\n                int nd = d[u];\n                int dr = dist_mat[r][u];\n                if (dr < nd) nd = dr;\n                if (nd > H) { ok = false; break; }\n                cur_sc += (long long)(nd + 1) * A[u];\n            }\n            if (ok && cur_sc > best_sc) {\n                best_sc = cur_sc;\n                best_r = r;\n            }\n        }\n\n        // Fallback: pick closest if none found\n        if (best_r == -1) {\n            int min_d = INF;\n            for (int r : cands) {\n                int mx_d = 0;\n                for (int u = 0; u < N; ++u) mx_d = max(mx_d, min(d[u], dist_mat[r][u]));\n                if (mx_d < min_d) { min_d = mx_d; best_r = r; }\n            }\n        }\n\n        roots.push_back(best_r);\n        is_root[best_r] = true;\n        for (int u = 0; u < N; ++u) {\n            int dr = dist_mat[best_r][u];\n            if (dr < d[u]) d[u] = dr;\n        }\n    }\n\n    // Local Search\n    mt19937 rng(42);\n    auto get_time = [&]() { return chrono::duration<double>(chrono::steady_clock::now() - start_time).count(); };\n    const double TIME_LIMIT = 1.85;\n\n    vector<int> cur_roots = roots;\n    vector<int> cur_d = d;\n    long long cur_score = compute_score(cur_d);\n    \n    vector<int> best_roots = cur_roots;\n    long long best_score = cur_score;\n\n    while (get_time() < TIME_LIMIT) {\n        bool improved = false;\n        \n        // Try Removing Roots\n        shuffle(cur_roots.begin(), cur_roots.end(), rng);\n        for (int i = 0; i < (int)cur_roots.size(); ++i) {\n            if (get_time() > TIME_LIMIT) goto end_search;\n            int r = cur_roots[i];\n            vector<int> tmp_roots = cur_roots;\n            tmp_roots.erase(tmp_roots.begin() + i);\n            \n            update_distances(cur_d, tmp_roots);\n            long long sc = compute_score(cur_d);\n            if (sc != -1 && sc >= cur_score) {\n                cur_roots = tmp_roots;\n                cur_score = sc;\n                improved = true;\n                if (cur_score > best_score) {\n                    best_score = cur_score;\n                    best_roots = cur_roots;\n                }\n                goto after_remove;\n            }\n        }\n        after_remove:;\n\n        if (!improved) {\n            // Try Moving Roots\n            shuffle(cur_roots.begin(), cur_roots.end(), rng);\n            for (int i = 0; i < (int)cur_roots.size(); ++i) {\n                if (get_time() > TIME_LIMIT) goto end_search;\n                int r = cur_roots[i];\n                shuffle(adj[r].begin(), adj[r].end(), rng);\n                for (int v : adj[r]) {\n                    if (is_root[v]) continue; // Don't merge roots\n                    \n                    vector<int> tmp_roots = cur_roots;\n                    tmp_roots[i] = v;\n                    \n                    update_distances(cur_d, tmp_roots);\n                    long long sc = compute_score(cur_d);\n                    if (sc != -1 && sc > cur_score) {\n                        is_root[r] = false;\n                        is_root[v] = true;\n                        cur_roots = tmp_roots;\n                        cur_score = sc;\n                        improved = true;\n                        if (cur_score > best_score) {\n                            best_score = cur_score;\n                            best_roots = cur_roots;\n                        }\n                        goto after_move;\n                    }\n                }\n            }\n            after_move:;\n        }\n\n        if (!improved) {\n            // Perturbation: move a random root to a random node to escape\n            if (!cur_roots.empty()) {\n                int idx = uniform_int_distribution<int>(0, cur_roots.size() - 1)(rng);\n                int r = cur_roots[idx];\n                int v = uniform_int_distribution<int>(0, N - 1)(rng);\n                if (!is_root[v]) {\n                    vector<int> tmp_roots = cur_roots;\n                    tmp_roots[idx] = v;\n                    update_distances(cur_d, tmp_roots);\n                    long long sc = compute_score(cur_d);\n                    if (sc != -1) {\n                        is_root[r] = false;\n                        is_root[v] = true;\n                        cur_roots = tmp_roots;\n                        cur_score = sc;\n                    }\n                }\n            }\n        }\n    }\n    end_search:;\n\n    // Use best found solution\n    update_distances(d, best_roots);\n    \n    // Construct output\n    vector<int> p(N, -1);\n    for (int i = 0; i < N; ++i) {\n        if (d[i] > 0) {\n            int target = d[i] - 1;\n            int par = -1;\n            for (int nb : adj[i]) {\n                if (d[nb] == target) {\n                    par = nb;\n                    break;\n                }\n            }\n            p[i] = par;\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << p[i] << (i == N - 1 ? \"\" : \" \");\n    }\n    cout << \"\\n\";\n\n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <utility>\n\nusing namespace std;\n\nint N;\nvector<string> board;\n\n// Apply a single shift operation to the board\nvoid apply_shift(char dir, int p) {\n    if (dir == 'U') {\n        for (int i = 0; i < N - 1; i++) board[i][p] = board[i + 1][p];\n        board[N - 1][p] = '.';\n    } else if (dir == 'D') {\n        for (int i = N - 1; i > 0; i--) board[i][p] = board[i - 1][p];\n        board[0][p] = '.';\n    } else if (dir == 'L') {\n        for (int j = 0; j < N - 1; j++) board[p][j] = board[p][j + 1];\n        board[p][N - 1] = '.';\n    } else if (dir == 'R') {\n        for (int j = N - 1; j > 0; j--) board[p][j] = board[p][j - 1];\n        board[p][0] = '.';\n    }\n}\n\n// Calculate heuristic: sum of minimum clear distances for all Oni\n// Returns 1e9 if any Oni is trapped (no clear direction)\nint calc_potential(const vector<string>& b) {\n    int sum = 0;\n    for(int i=0; i<N; i++) {\n        for(int j=0; j<N; j++) {\n            if(b[i][j] == 'x') {\n                int d = 1e9;\n                bool c = true;\n                for(int k=0; k<i; k++) if(b[k][j]=='o'){c=false;break;}\n                if(c) d = min(d, i+1);\n                c = true;\n                for(int k=i+1; k<N; k++) if(b[k][j]=='o'){c=false;break;}\n                if(c) d = min(d, N-i);\n                c = true;\n                for(int k=0; k<j; k++) if(b[i][k]=='o'){c=false;break;}\n                if(c) d = min(d, j+1);\n                c = true;\n                for(int k=j+1; k<N; k++) if(b[i][k]=='o'){c=false;break;}\n                if(c) d = min(d, N-j);\n                \n                if(d == 1e9) return 1e9; // Trapped\n                sum += d;\n            }\n        }\n    }\n    return sum;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> N)) return 0;\n    board.resize(N);\n    for (int i = 0; i < N; i++) cin >> board[i];\n\n    vector<pair<char, int>> ops;\n\n    while (true) {\n        int oni_count = 0;\n        for(int i=0; i<N; i++) for(int j=0; j<N; j++) if(board[i][j]=='x') oni_count++;\n        if(oni_count == 0) break;\n\n        int cur_pot = calc_potential(board);\n        \n        int best_score = 2e9;\n        int best_shifts = 1e9;\n        char best_dir = 0;\n        int best_r = -1, best_c = -1;\n        bool found_direct = false;\n\n        // Lookahead: Evaluate all possible direct removals\n        for(int i=0; i<N; i++) {\n            for(int j=0; j<N; j++) {\n                if(board[i][j] == 'x') {\n                    struct Move { char dir; int dist; int param; bool valid; } moves[4] = {\n                        {'U', i+1, j, true}, {'D', N-i, j, true}, {'L', j+1, i, true}, {'R', N-j, i, true}\n                    };\n                    // Validate directions\n                    for(auto& m : moves) {\n                        if(!m.valid) continue;\n                        bool clear = true;\n                        if(m.dir == 'U') { for(int k=0; k<i; k++) if(board[k][j]=='o') { clear=false; break; } }\n                        else if(m.dir == 'D') { for(int k=i+1; k<N; k++) if(board[k][j]=='o') { clear=false; break; } }\n                        else if(m.dir == 'L') { for(int k=0; k<j; k++) if(board[i][k]=='o') { clear=false; break; } }\n                        else if(m.dir == 'R') { for(int k=j+1; k<N; k++) if(board[i][k]=='o') { clear=false; break; } }\n                        m.valid = clear;\n                    }\n\n                    for(auto& m : moves) {\n                        if(!m.valid) continue;\n                        \n                        // Simulate shifts\n                        vector<string> sim_board = board;\n                        for(int k=0; k<m.dist; k++) {\n                            if(m.dir == 'U') {\n                                for(int r=0; r<N-1; r++) sim_board[r][m.param] = sim_board[r+1][m.param];\n                                sim_board[N-1][m.param] = '.';\n                            } else if(m.dir == 'D') {\n                                for(int r=N-1; r>0; r--) sim_board[r][m.param] = sim_board[r-1][m.param];\n                                sim_board[0][m.param] = '.';\n                            } else if(m.dir == 'L') {\n                                for(int c=0; c<N-1; c++) sim_board[m.param][c] = sim_board[m.param][c+1];\n                                sim_board[m.param][N-1] = '.';\n                            } else if(m.dir == 'R') {\n                                for(int c=N-1; c>0; c--) sim_board[m.param][c] = sim_board[m.param][c-1];\n                                sim_board[m.param][0] = '.';\n                            }\n                        }\n                        \n                        int new_pot = calc_potential(sim_board);\n                        int score = m.dist + (new_pot - cur_pot);\n                        if(new_pot >= 1e9) score += 1e8; // Heavy penalty for trapping pieces\n                        \n                        if(score < best_score || (score == best_score && m.dist < best_shifts)) {\n                            best_score = score;\n                            best_shifts = m.dist;\n                            best_dir = m.dir;\n                            best_r = i; best_c = j;\n                            found_direct = true;\n                        }\n                    }\n                }\n            }\n        }\n\n        // Fallback: If lookahead finds no good direct move, use safe greedy\n        if(!found_direct) {\n            int min_cost = 1e9;\n            bool direct_possible = false;\n            \n            // Check for any direct move\n            for(int i=0; i<N; i++) {\n                for(int j=0; j<N; j++) {\n                    if(board[i][j] == 'x') {\n                        bool c = true; for(int k=0; k<i; k++) if(board[k][j]=='o'){c=false;break;}\n                        if(c && (i+1) < min_cost) { min_cost = i+1; best_dir='U'; best_r=i; best_c=j; direct_possible=true; }\n                        c = true; for(int k=i+1; k<N; k++) if(board[k][j]=='o'){c=false;break;}\n                        if(c && (N-i) < min_cost) { min_cost = N-i; best_dir='D'; best_r=i; best_c=j; direct_possible=true; }\n                        c = true; for(int k=0; k<j; k++) if(board[i][k]=='o'){c=false;break;}\n                        if(c && (j+1) < min_cost) { min_cost = j+1; best_dir='L'; best_r=i; best_c=j; direct_possible=true; }\n                        c = true; for(int k=j+1; k<N; k++) if(board[i][k]=='o'){c=false;break;}\n                        if(c && (N-j) < min_cost) { min_cost = N-j; best_dir='R'; best_r=i; best_c=j; direct_possible=true; }\n                    }\n                }\n            }\n            \n            // If still nothing, use Push-Pull\n            if(!direct_possible) {\n                min_cost = 1e9;\n                for(int i=0; i<N; i++) {\n                    for(int j=0; j<N; j++) {\n                        if(board[i][j] == 'x') {\n                            bool c = true; for(int k=0; k<i; k++) if(board[k][j]=='o'){c=false;break;}\n                            if(c && (i+1)*2 < min_cost) { min_cost = (i+1)*2; best_dir='U'; best_r=i; best_c=j; }\n                            c = true; for(int k=i+1; k<N; k++) if(board[k][j]=='o'){c=false;break;}\n                            if(c && (N-i)*2 < min_cost) { min_cost = (N-i)*2; best_dir='D'; best_r=i; best_c=j; }\n                            c = true; for(int k=0; k<j; k++) if(board[i][k]=='o'){c=false;break;}\n                            if(c && (j+1)*2 < min_cost) { min_cost = (j+1)*2; best_dir='L'; best_r=i; best_c=j; }\n                            c = true; for(int k=j+1; k<N; k++) if(board[i][k]=='o'){c=false;break;}\n                            if(c && (N-j)*2 < min_cost) { min_cost = (N-j)*2; best_dir='R'; best_r=i; best_c=j; }\n                        }\n                    }\n                }\n                best_shifts = min_cost / 2;\n                int param = (best_dir == 'U' || best_dir == 'D') ? best_c : best_r;\n                for(int k=0; k<best_shifts; k++) {\n                    ops.push_back({best_dir, param});\n                    apply_shift(best_dir, param);\n                }\n                char pull = (best_dir=='U')?'D':(best_dir=='D')?'U':(best_dir=='L')?'R':'L';\n                for(int k=0; k<best_shifts; k++) {\n                    ops.push_back({pull, param});\n                    apply_shift(pull, param);\n                }\n                continue;\n            } else {\n                best_shifts = min_cost;\n                found_direct = true;\n            }\n        }\n\n        // Apply the chosen direct move\n        int param = (best_dir == 'U' || best_dir == 'D') ? best_c : best_r;\n        for(int k=0; k<best_shifts; k++) {\n            ops.push_back({best_dir, param});\n            apply_shift(best_dir, param);\n        }\n    }\n\n    for(const auto& op : ops) {\n        cout << op.first << \" \" << op.second << \"\\n\";\n    }\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Global variables to store input and best solution\nint N, L;\nint T[105];\nint best_a[105], best_b[105];\nlong long best_err = 2e18;\n\n// Simulation function\n// Computes the error and optionally stores the final counts in res_cnt\nlong long simulate(int* a, int* b, int* res_cnt) {\n    int cnt[105] = {0};\n    int cur = 0;\n    // Simulate L weeks\n    for(int w = 0; w < L; ++w) {\n        cnt[cur]++;\n        if(w == L - 1) break;\n        int t = cnt[cur];\n        // If t is odd, next is a[cur], else b[cur]\n        cur = (t & 1) ? a[cur] : b[cur];\n    }\n    \n    if(res_cnt) {\n        for(int i = 0; i < N; ++i) res_cnt[i] = cnt[i];\n    }\n    \n    long long err = 0;\n    for(int i = 0; i < N; ++i) {\n        err += abs(cnt[i] - T[i]);\n    }\n    return err;\n}\n\nint main() {\n    // Fast I/O\n    cin.tie(nullptr);\n    ios::sync_with_stdio(false);\n    \n    if(!(cin >> N >> L)) return 0;\n    for(int i = 0; i < N; ++i) cin >> T[i];\n\n    // Random number generator\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist(0, N - 1);\n    uniform_real_distribution<double> dist01(0.0, 1.0);\n\n    int cur_a[105], cur_b[105];\n    // Initialize with -1 to indicate undefined\n    for(int i = 0; i < N; ++i) cur_a[i] = cur_b[i] = -1;\n\n    // Greedy initialization to get a valid and decent starting solution\n    {\n        int g_cnt[105] = {0};\n        int cur = 0;\n        for(int w = 0; w < L; ++w) {\n            g_cnt[cur]++;\n            if(w == L - 1) break;\n            int t = g_cnt[cur];\n            int next = -1;\n            if(t & 1) { // Odd\n                if(cur_a[cur] != -1) {\n                    next = cur_a[cur];\n                } else {\n                    // Choose the employee with the largest deficit (T[i] - g_cnt[i])\n                    int best = 0, max_def = -1e9;\n                    for(int i = 0; i < N; ++i) {\n                        int def = T[i] - g_cnt[i];\n                        if(def > max_def) {\n                            max_def = def;\n                            best = i;\n                        }\n                    }\n                    cur_a[cur] = best;\n                    next = best;\n                }\n            } else { // Even\n                if(cur_b[cur] != -1) {\n                    next = cur_b[cur];\n                } else {\n                    int best = 0, max_def = -1e9;\n                    for(int i = 0; i < N; ++i) {\n                        int def = T[i] - g_cnt[i];\n                        if(def > max_def) {\n                            max_def = def;\n                            best = i;\n                        }\n                    }\n                    cur_b[cur] = best;\n                    next = best;\n                }\n            }\n            cur = next;\n        }\n        // Fill any remaining undefined transitions randomly\n        for(int i = 0; i < N; ++i) {\n            if(cur_a[i] == -1) cur_a[i] = dist(rng);\n            if(cur_b[i] == -1) cur_b[i] = dist(rng);\n        }\n    }\n\n    // Evaluate the initial solution\n    int current_cnt[105];\n    long long current_err = simulate(cur_a, cur_b, current_cnt);\n    best_err = current_err;\n    for(int i = 0; i < N; ++i) {\n        best_a[i] = cur_a[i];\n        best_b[i] = cur_b[i];\n    }\n\n    // Simulated Annealing\n    double temp = 50000.0;\n    auto start = chrono::steady_clock::now();\n\n    while(true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if(elapsed > 1.85) break; // Leave some margin for output\n\n        // Cooling schedule\n        temp *= 0.998;\n\n        // Perturbation: change one random transition\n        int idx = dist(rng);\n        bool change_a = (dist(rng) & 1);\n        int old_val = change_a ? cur_a[idx] : cur_b[idx];\n        int new_val = dist(rng);\n        \n        if(change_a) cur_a[idx] = new_val;\n        else cur_b[idx] = new_val;\n\n        long long next_err = simulate(cur_a, cur_b, current_cnt);\n\n        if(next_err < current_err) {\n            current_err = next_err;\n            if(next_err < best_err) {\n                best_err = next_err;\n                for(int i = 0; i < N; ++i) {\n                    best_a[i] = cur_a[i];\n                    best_b[i] = cur_b[i];\n                }\n            }\n        } else {\n            // Metropolis criterion\n            double prob = exp((current_err - next_err) / temp);\n            if(dist01(rng) < prob) {\n                current_err = next_err;\n            } else {\n                // Revert change\n                if(change_a) cur_a[idx] = old_val;\n                else cur_b[idx] = old_val;\n            }\n        }\n    }\n\n    // Output the best solution found\n    for(int i = 0; i < N; ++i) {\n        cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n    }\n\n    return 0;\n}","ahc045":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <tuple>\n\nusing namespace std;\n\n// Disjoint Set Union (Union-Find)\nstruct DSU {\n    vector<int> parent, rank;\n    DSU(int n) : parent(n), rank(n, 0) { iota(parent.begin(), parent.end(), 0); }\n    int find(int x) { return parent[x] == x ? x : parent[x] = find(parent[x]); }\n    bool unite(int x, int y) {\n        x = find(x); y = find(y);\n        if (x != y) {\n            if (rank[x] < rank[y]) swap(x, y);\n            parent[y] = x;\n            if (rank[x] == rank[y]) rank[x]++;\n            return true;\n        }\n        return false;\n    }\n};\n\n// Morton (Z-order) curve encoding for 2D spatial locality\ninline uint64_t morton_encode(uint32_t x, uint32_t y) {\n    uint64_t res = 0;\n    for (int i = 0; i < 16; ++i) {\n        res |= (uint64_t)(x & 1) << (2 * i);\n        res |= (uint64_t)(y & 1) << (2 * i + 1);\n        x >>= 1; y >>= 1;\n    }\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, Q, L, W;\n    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n    \n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    \n    vector<int> lx(N), rx(N), ly(N), ry(N);\n    vector<uint32_t> cx(N), cy(N); // Doubled centers for integer Morton encoding\n    for (int i = 0; i < N; ++i) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n        cx[i] = lx[i] + rx[i];\n        cy[i] = ly[i] + ry[i];\n    }\n\n    // Sort cities by Morton code for better 2D spatial clustering\n    vector<int> p(N);\n    iota(p.begin(), p.end(), 0);\n    sort(p.begin(), p.end(), [&](int a, int b) {\n        return morton_encode(cx[a], cy[a]) < morton_encode(cx[b], cy[b]);\n    });\n\n    // Partition sorted cities into groups of required sizes\n    vector<vector<int>> groups(M);\n    int idx = 0;\n    for (int i = 0; i < M; ++i) {\n        groups[i].resize(G[i]);\n        for (int j = 0; j < G[i]; ++j) {\n            groups[i][j] = p[idx++];\n        }\n    }\n\n    vector<vector<pair<int, int>>> exact_edges(M);\n    int q_cnt = 0;\n\n    // Query strategy: overlapping windows of stride L-1 to guarantee connectivity\n    for (int k = 0; k < M; ++k) {\n        int sz = groups[k].size();\n        if (sz <= 1) continue;\n        for (int start = 0; start < sz - 1 && q_cnt < Q; start += L - 1) {\n            int len = min(L, sz - start);\n            vector<int> subset(len);\n            for (int i = 0; i < len; ++i) subset[i] = groups[k][start + i];\n            sort(subset.begin(), subset.end()); // Lexicographical order for judge\n            \n            cout << \"? \" << len;\n            for (int city : subset) cout << \" \" << city;\n            cout << \"\\n\";\n            cout.flush();\n            q_cnt++;\n\n            for (int i = 0; i < len - 1; ++i) {\n                int u, v;\n                cin >> u >> v;\n                if (u > v) swap(u, v);\n                exact_edges[k].push_back({u, v});\n            }\n        }\n        if (q_cnt >= Q) break;\n    }\n\n    // Build final MST for each group\n    vector<vector<pair<int, int>>> final_edges(M);\n    for (int k = 0; k < M; ++k) {\n        int sz = groups[k].size();\n        if (sz <= 1) continue;\n\n        DSU dsu(N);\n        \n        // 1. Prioritize exact edges from queries\n        for (auto& e : exact_edges[k]) {\n            if (dsu.unite(e.first, e.second)) {\n                final_edges[k].push_back(e);\n            }\n        }\n        if ((int)final_edges[k].size() == sz - 1) continue;\n\n        // 2. Generate estimated candidates for remaining connections\n        vector<tuple<long long, int, int>> candidates;\n        candidates.reserve(sz * (sz - 1) / 2);\n        for (int i = 0; i < sz; ++i) {\n            for (int j = i + 1; j < sz; ++j) {\n                int u = groups[k][i], v = groups[k][j];\n                if (dsu.find(u) == dsu.find(v)) continue;\n                long long dx = cx[u] - cx[v];\n                long long dy = cy[u] - cy[v];\n                candidates.emplace_back(dx * dx + dy * dy, min(u, v), max(u, v));\n            }\n        }\n        // Sort by estimated squared distance, ties broken lexicographically\n        sort(candidates.begin(), candidates.end());\n\n        // 3. Complete MST using estimated edges\n        for (const auto& c : candidates) {\n            if ((int)final_edges[k].size() == sz - 1) break;\n            auto [w, u, v] = c;\n            if (dsu.unite(u, v)) {\n                final_edges[k].push_back({u, v});\n            }\n        }\n    }\n\n    // Output results\n    cout << \"!\\n\";\n    cout.flush();\n\n    for (int k = 0; k < M; ++k) {\n        for (size_t i = 0; i < groups[k].size(); ++i) {\n            if (i > 0) cout << \" \";\n            cout << groups[k][i];\n        }\n        cout << \"\\n\";\n        for (auto& e : final_edges[k]) {\n            cout << e.first << \" \" << e.second << \"\\n\";\n        }\n    }\n    cout.flush();\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n\n    int start_r, start_c;\n    cin >> start_r >> start_c;\n\n    // Read M-1 target squares\n    vector<pair<int, int>> targets(M - 1);\n    for (int k = 0; k < M - 1; ++k) {\n        cin >> targets[k].first >> targets[k].second;\n    }\n\n    int cur_r = start_r;\n    int cur_c = start_c;\n\n    // Grid state: true if a block is present\n    bool block[20][20] = {};\n    auto is_block = [&](int r, int c) {\n        if (r < 0 || r >= N || c < 0 || c >= N) return true; // Boundaries act as blocks\n        return block[r][c];\n    };\n\n    const int dr[] = {-1, 1, 0, 0};\n    const int dc[] = {0, 0, -1, 1};\n    const char d_name[] = {'U', 'D', 'L', 'R'};\n\n    int dist[20][20];\n    int parent_r[20][20], parent_c[20][20];\n    char act[20][20], dir[20][20];\n\n    struct Node {\n        int f, r, c, g;\n        bool operator>(const Node& other) const { return f > other.f; }\n    };\n\n    const int INF = 1e9;\n\n    for (auto [tr, tc] : targets) {\n        // Initialize distance matrix\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                dist[i][j] = INF;\n\n        priority_queue<Node, vector<Node>, greater<Node>> pq;\n        dist[cur_r][cur_c] = 0;\n        pq.push(Node{abs(cur_r - tr) + abs(cur_c - tc), cur_r, cur_c, 0});\n\n        // A* Search\n        while (!pq.empty()) {\n            auto [f, r, c, g] = pq.top(); pq.pop();\n            if (dist[r][c] < g) continue;\n            if (r == tr && c == tc) break;\n\n            // Try Move\n            for (int d = 0; d < 4; ++d) {\n                int nr = r + dr[d], nc = c + dc[d];\n                if (!is_block(nr, nc)) {\n                    if (dist[nr][nc] > g + 1) {\n                        dist[nr][nc] = g + 1;\n                        parent_r[nr][nc] = r; parent_c[nr][nc] = c;\n                        act[nr][nc] = 'M'; dir[nr][nc] = d_name[d];\n                        int nh = abs(nr - tr) + abs(nc - tc);\n                        pq.push(Node{dist[nr][nc] + nh, nr, nc, g + 1});\n                    }\n                }\n            }\n\n            // Try Slide\n            for (int d = 0; d < 4; ++d) {\n                int nr = r + dr[d], nc = c + dc[d];\n                while (!is_block(nr, nc)) {\n                    nr += dr[d]; nc += dc[d];\n                }\n                nr -= dr[d]; nc -= dc[d]; // Step back to last valid cell\n                if (nr == r && nc == c) continue; // Didn't move\n\n                if (dist[nr][nc] > g + 1) {\n                    dist[nr][nc] = g + 1;\n                    parent_r[nr][nc] = r; parent_c[nr][nc] = c;\n                    act[nr][nc] = 'S'; dir[nr][nc] = d_name[d];\n                    int nh = abs(nr - tr) + abs(nc - tc);\n                    pq.push(Node{dist[nr][nc] + nh, nr, nc, g + 1});\n                }\n            }\n        }\n\n        // Reconstruct path\n        vector<pair<char, char>> path;\n        int r = tr, c = tc;\n        while (r != cur_r || c != cur_c) {\n            path.emplace_back(act[r][c], dir[r][c]);\n            int pr = parent_r[r][c];\n            int pc = parent_c[r][c];\n            r = pr; c = pc;\n        }\n        reverse(path.begin(), path.end());\n\n        // Execute path\n        for (auto [a, d] : path) {\n            cout << a << ' ' << d << '\\n';\n            if (a == 'M') {\n                if (d == 'U') cur_r--;\n                else if (d == 'D') cur_r++;\n                else if (d == 'L') cur_c--;\n                else if (d == 'R') cur_c++;\n            } else if (a == 'S') {\n                if (d == 'U') while (true) { int nr = cur_r - 1; if (is_block(nr, cur_c)) break; cur_r = nr; }\n                else if (d == 'D') while (true) { int nr = cur_r + 1; if (is_block(nr, cur_c)) break; cur_r = nr; }\n                else if (d == 'L') while (true) { int nc = cur_c - 1; if (is_block(cur_r, nc)) break; cur_c = nc; }\n                else if (d == 'R') while (true) { int nc = cur_c + 1; if (is_block(cur_r, nc)) break; cur_c = nc; }\n            }\n        }\n    }\n\n    return 0;\n}"},"8":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <chrono>\n#include <random>\n#include <numeric>\n\nusing namespace std;\n\n#pragma GCC optimize(\"O3,unroll-loops\")\n\nstruct Rect { int x1, y1, x2, y2; };\nstruct Candidate { bool vertical; int k; int c; double err; };\n\nint N;\nvector<int> X, Y;\nvector<long long> R;\nvector<Rect> best_ans;\ndouble best_score = -1.0;\n\ninline double calc_score(const vector<Rect>& rects) {\n    double total = 0.0;\n    for (int i = 0; i < N; ++i) {\n        long long s = (long long)(rects[i].x2 - rects[i].x1) * (rects[i].y2 - rects[i].y1);\n        double ratio = min((long long)R[i], s) / (double)max((long long)R[i], s);\n        total += 1.0 - (1.0 - ratio) * (1.0 - ratio);\n    }\n    return total;\n}\n\ninline bool validate(const vector<Rect>& rects) {\n    for (int i = 0; i < N; ++i) {\n        if (rects[i].x1 < 0 || rects[i].x2 > 10000 || rects[i].y1 < 0 || rects[i].y2 > 10000) return false;\n        if (rects[i].x1 >= rects[i].x2 || rects[i].y1 >= rects[i].y2) return false;\n        // Point containment: (x_i+0.5, y_i+0.5) inside [x1, x2) x [y1, y2)\n        // implies x1 <= x_i < x2 and y1 <= y_i < y2\n        if (!(rects[i].x1 <= X[i] && X[i] < rects[i].x2 && rects[i].y1 <= Y[i] && Y[i] < rects[i].y2)) return false;\n    }\n    return true;\n}\n\nmt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nvoid solve(int x1, int y1, int x2, int y2, vector<int> ids, vector<Rect>& ans) {\n    if (ids.empty()) return;\n    if (ids.size() == 1) {\n        ans[ids[0]] = {x1, y1, x2, y2};\n        return;\n    }\n\n    vector<Candidate> candidates;\n    candidates.reserve(ids.size());\n\n    auto eval_axis = [&](bool vertical) {\n        vector<int> s = ids;\n        if (vertical) sort(s.begin(), s.end(), [&](int a, int b){ return X[a] < X[b]; });\n        else sort(s.begin(), s.end(), [&](int a, int b){ return Y[a] < Y[b]; });\n\n        long long cur_r = 0;\n        double len = vertical ? (x2 - x1) : (y2 - y1);\n        if (len <= 1) return; // Cannot cut if dimension is 1\n\n        int b1 = vertical ? x1 : y1;\n        int b2 = vertical ? x2 : y2;\n\n        for (int k = 0; k < (int)s.size() - 1; ++k) {\n            cur_r += R[s[k]];\n            double ideal = b1 + (double)cur_r / len;\n            \n            int p1 = vertical ? X[s[k]] : Y[s[k]];\n            int p2 = vertical ? X[s[k+1]] : Y[s[k+1]];\n            \n            if (p1 >= p2) continue; // Cannot separate points with same coordinate\n\n            // Valid range for cut c:\n            // 1. Separate points: p1 < c <= p2  => c >= p1 + 1\n            // 2. Positive area for children: b1 < c < b2 => c >= b1 + 1, c <= b2 - 1\n            int low = max(p1 + 1, b1 + 1);\n            int high = min(p2, b2 - 1);\n            \n            if (low > high) continue;\n\n            // Find integer c in [low, high] closest to ideal\n            int c;\n            int round_ideal = (int)std::round(ideal);\n            if (round_ideal < low) c = low;\n            else if (round_ideal > high) c = high;\n            else c = round_ideal;\n            \n            double err = std::abs(ideal - c);\n            candidates.push_back({vertical, k, c, err});\n        }\n    };\n\n    eval_axis(true);\n    eval_axis(false);\n\n    if (candidates.empty()) {\n        // Fallback: Split along longer dimension, ensuring separation\n        if (x2 - x1 >= y2 - y1) {\n            int c = (x1 + x2) / 2;\n            if (c <= x1) c = x1 + 1;\n            if (c >= x2) c = x2 - 1;\n            vector<int> L, R_vec;\n            for (int id : ids) {\n                if (X[id] < c) L.push_back(id);\n                else R_vec.push_back(id);\n            }\n            if (L.empty()) { L.push_back(ids[0]); R_vec.erase(R_vec.begin()); }\n            if (R_vec.empty()) { R_vec.push_back(ids.back()); L.pop_back(); }\n            solve(x1, y1, c, y2, L, ans);\n            solve(c, y1, x2, y2, R_vec, ans);\n        } else {\n            int c = (y1 + y2) / 2;\n            if (c <= y1) c = y1 + 1;\n            if (c >= y2) c = y2 - 1;\n            vector<int> B, T;\n            for (int id : ids) {\n                if (Y[id] < c) B.push_back(id);\n                else T.push_back(id);\n            }\n            if (B.empty()) { B.push_back(ids[0]); T.erase(T.begin()); }\n            if (T.empty()) { T.push_back(ids.back()); B.pop_back(); }\n            solve(x1, y1, x2, c, B, ans);\n            solve(x1, c, x2, y2, T, ans);\n        }\n        return;\n    }\n\n    sort(candidates.begin(), candidates.end(), [](const Candidate& a, const Candidate& b){\n        return a.err < b.err;\n    });\n\n    // Randomized selection from top candidates to explore different topologies\n    int K = min((int)candidates.size(), 5); \n    uniform_int_distribution<int> dist(0, K - 1);\n    int idx = dist(rng);\n    Candidate best = candidates[idx];\n\n    vector<int> s = ids;\n    if (best.vertical) sort(s.begin(), s.end(), [&](int a, int b){ return X[a] < X[b]; });\n    else sort(s.begin(), s.end(), [&](int a, int b){ return Y[a] < Y[b]; });\n\n    vector<int> left(s.begin(), s.begin() + best.k + 1);\n    vector<int> right(s.begin() + best.k + 1, s.end());\n\n    if (best.vertical) {\n        solve(x1, y1, best.c, y2, left, ans);\n        solve(best.c, y1, x2, y2, right, ans);\n    } else {\n        solve(x1, y1, x2, best.c, left, ans);\n        solve(x1, best.c, x2, y2, right, ans);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N)) return 0;\n    X.resize(N); Y.resize(N); R.resize(N);\n    for (int i = 0; i < N; ++i) cin >> X[i] >> Y[i] >> R[i];\n\n    best_ans.resize(N);\n    vector<int> ids(N);\n    iota(ids.begin(), ids.end(), 0);\n\n    auto start = chrono::steady_clock::now();\n    vector<Rect> current_ans(N);\n\n    // Multi-start loop\n    while (chrono::duration<double>(chrono::steady_clock::now() - start).count() < 4.85) {\n        solve(0, 0, 10000, 10000, ids, current_ans);\n\n        if (validate(current_ans)) {\n            double sc = calc_score(current_ans);\n            if (sc > best_score) {\n                best_score = sc;\n                best_ans = current_ans;\n            }\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << best_ans[i].x1 << \" \" << best_ans[i].y1 << \" \"\n             << best_ans[i].x2 << \" \" << best_ans[i].y2 << \"\\n\";\n    }\n    return 0;\n}","ahc002":"#pragma GCC optimize(\"Ofast,unroll-loops\")\n#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\nusing ll = long long;\n\nint main() {\n    cin.tie(nullptr);\n    ios::sync_with_stdio(false);\n\n    int si, sj;\n    if (!(cin >> si >> sj)) return 0;\n\n    int t[50][50], p[50][50];\n    int M = 0;\n    for (int i = 0; i < 50; ++i)\n        for (int j = 0; j < 50; ++j) {\n            cin >> t[i][j];\n            M = max(M, t[i][j] + 1);\n        }\n    for (int i = 0; i < 50; ++i)\n        for (int j = 0; j < 50; ++j)\n            cin >> p[i][j];\n\n    // Static BFS buffers\n    int bfs_vis[50][50];\n    int bfs_gen = 0;\n    int qr[250], qc[250]; // Queue sized for BFS limit\n    const int BFS_LIMIT = 100;\n    const double REACH_WEIGHT = 3.0;\n    const double DEG_WEIGHT = 12.0;\n    const double REACH_PENALTY_THRESH = 15;\n    const double REACH_PENALTY_VAL = -150.0;\n\n    // Visited tiles with generation token to avoid O(M) fill\n    int vis[2505];\n    uint32_t vis_token = 0;\n\n    vector<char> best_path;\n    ll best_score = -1;\n\n    const int dr[] = {-1, 1, 0, 0};\n    const int dc[] = {0, 0, -1, 1};\n    const char dirs[] = {'U', 'D', 'L', 'R'};\n\n    auto start_t = chrono::steady_clock::now();\n    auto elapsed = [&]() { return chrono::duration<double>(chrono::steady_clock::now() - start_t).count(); };\n    const double TIME_LIMIT = 1.85; // Conservative margin to avoid TLE\n    \n    mt19937_64 rng(42);\n    uniform_real_distribution<double> noise(0.0, 20.0);\n\n    auto get_reachability = [&](int r, int c) -> int {\n        int tile_id = t[r][c];\n        int count = 0;\n        int head = 0, tail = 0;\n        bfs_gen++;\n        \n        qr[tail] = r; qc[tail] = c; tail++;\n        bfs_vis[r][c] = bfs_gen;\n        count++;\n        \n        while(head < tail) {\n            int cr = qr[head];\n            int cc = qc[head];\n            head++;\n            if(count >= BFS_LIMIT) return BFS_LIMIT;\n            \n            for(int k=0; k<4; ++k) {\n                int nr = cr + dr[k];\n                int nc = cc + dc[k];\n                if(nr >= 0 && nr < 50 && nc >= 0 && nc < 50) {\n                    if(bfs_vis[nr][nc] == bfs_gen) continue;\n                    if(vis[t[nr][nc]] == vis_token) continue;\n                    if(t[nr][nc] == tile_id) continue;\n                    \n                    bfs_vis[nr][nc] = bfs_gen;\n                    qr[tail] = nr; qc[tail] = nc; tail++;\n                    count++;\n                    if(count >= BFS_LIMIT) return BFS_LIMIT;\n                }\n            }\n        }\n        return count;\n    };\n\n    auto extend = [&](vector<char>& path, int keep_len) -> ll {\n        vis_token++; // O(1) reset\n        int r = si, c = sj;\n        vis[t[r][c]] = vis_token;\n        ll score = p[r][c];\n\n        for (int i = 0; i < keep_len; ++i) {\n            char d = path[i];\n            if (d == 'U') r--; else if (d == 'D') r++; else if (d == 'L') c--; else c++;\n            vis[t[r][c]] = vis_token;\n            score += p[r][c];\n        }\n\n        while (true) {\n            double best_h = -1e18;\n            int best_k = -1, nr_best = 0, nc_best = 0;\n            \n            for (int k = 0; k < 4; ++k) {\n                int nr = r + dr[k], nc = c + dc[k];\n                if (nr >= 0 && nr < 50 && nc >= 0 && nc < 50) {\n                    int tid = t[nr][nc];\n                    if (vis[tid] != vis_token) {\n                        int deg = 0;\n                        for(int d=0; d<4; ++d) {\n                            int tr = nr + dr[d], tc = nc + dc[d];\n                            if(tr>=0 && tr<50 && tc>=0 && tc<50 && vis[t[tr][tc]] != vis_token && t[tr][tc] != tid) {\n                                deg++;\n                            }\n                        }\n                        \n                        double h = (double)p[nr][nc];\n                        if (deg > 0) {\n                            h += deg * DEG_WEIGHT;\n                            if (deg <= 2) {\n                                int reach = get_reachability(nr, nc);\n                                h += reach * REACH_WEIGHT;\n                                if (reach < REACH_PENALTY_THRESH) h += REACH_PENALTY_VAL;\n                            }\n                        }\n                        h += noise(rng);\n                        \n                        if (h > best_h) {\n                            best_h = h;\n                            best_k = k;\n                            nr_best = nr; nc_best = nc;\n                        }\n                    }\n                }\n            }\n            if (best_k == -1) break;\n            \n            path.push_back(dirs[best_k]);\n            r = nr_best; c = nc_best;\n            vis[t[r][c]] = vis_token;\n            score += p[r][c];\n        }\n        return score;\n    };\n\n    vector<char> cur_path; cur_path.reserve(2500);\n    vector<char> nxt_path; nxt_path.reserve(2500);\n    ll cur_score = extend(cur_path, 0);\n    best_path = cur_path; best_score = cur_score;\n\n    double T0 = 80.0, T_TARGET = 0.05;\n    int iter = 0, no_improve_iter = 0;\n    const int RESTART_THRESH = 60000;\n\n    while (true) {\n        if ((iter & 255) == 0) {\n            if (elapsed() > TIME_LIMIT) break;\n            if (no_improve_iter > RESTART_THRESH) {\n                cur_path.assign(best_path.begin(), best_path.end());\n                cur_score = best_score;\n                T0 = 80.0;\n                no_improve_iter = 0;\n                rng.discard(1000);\n            }\n        }\n        iter++; no_improve_iter++;\n\n        double prog = min(1.0, elapsed() / TIME_LIMIT);\n        double T = T0 * pow(T_TARGET / T0, prog);\n\n        int sz = cur_path.size();\n        int keep_len = (sz <= 4) ? 0 : (sz / 4 + (rng() % (sz * 3 / 4 + 1)));\n        \n        nxt_path.assign(cur_path.begin(), cur_path.begin() + keep_len);\n        ll nxt_score = extend(nxt_path, keep_len);\n\n        if (nxt_score > best_score) {\n            best_score = nxt_score;\n            best_path = nxt_path;\n            no_improve_iter = 0;\n        }\n\n        double delta = nxt_score - cur_score;\n        bool accept = false;\n        if (delta >= 0) accept = true;\n        else if (delta > -18.0 * T && exp(delta / T) > (double)(rng() & 0xFFFFFF) / 16777216.0) {\n            accept = true;\n        }\n\n        if (accept) {\n            cur_score = nxt_score;\n            cur_path = nxt_path;\n        }\n    }\n\n    for (char c : best_path) cout << c;\n    cout << \"\\n\";\n\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Use long double for high precision in weight accumulation\n// Dimensions: h[30][29] for horizontal edges, v[29][30] for vertical edges\nlong double h[30][29];\nlong double v[29][30];\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Initialize weights to the midpoint of the expected range [1000, 9000]\n    for(int i=0; i<30; ++i) for(int j=0; j<29; ++j) h[i][j] = 5000.0L;\n    for(int i=0; i<29; ++i) for(int j=0; j<30; ++j) v[i][j] = 5000.0L;\n\n    // Tuned parameters\n    // ALPHA: Learning rate. Increased slightly (0.15) to adapt faster to feedback,\n    //        which is crucial for the exponentially weighted score function.\n    const long double ALPHA = 0.15L;\n    \n    // BETA: Smoothing factor. Increased (0.20) to leverage spatial correlation more aggressively.\n    //       This helps generalize information from visited edges to unvisited neighbors,\n    //       reducing variance caused by measurement noise.\n    const long double BETA = 0.20L;\n    \n    // Bounds for weights based on problem constraints\n    const long double MIN_W = 1000.0L; \n    const long double MAX_W = 9000.0L; \n\n    int si, sj, ti, tj;\n    for(int k=0; k<1000; ++k) {\n        if(!(cin >> si >> sj >> ti >> tj)) break;\n\n        // Dijkstra's Algorithm\n        // Priority Queue stores {distance, r, c}\n        // Use long long for distance to prevent precision loss and overflow\n        priority_queue<tuple<long long, int, int>, vector<tuple<long long, int, int>>, greater<>> pq;\n        long long dist[30][30];\n        const long long INF = 4000000000000000000LL;\n        for(int i=0; i<30; ++i) fill(dist[i], dist[i]+30, INF);\n        \n        dist[si][sj] = 0;\n        pq.emplace(0, si, sj);\n\n        // Arrays to reconstruct path\n        int pi[30][30], pj[30][30];\n        char dir[30][30];\n\n        const int di[4] = {-1, 1, 0, 0};\n        const int dj[4] = {0, 0, -1, 1};\n        const char dc[4] = {'U', 'D', 'L', 'R'};\n\n        while(!pq.empty()){\n            auto [d, i, j] = pq.top(); pq.pop();\n            if(d > dist[i][j]) continue;\n            if(i == ti && j == tj) break;\n\n            for(int m=0; m<4; ++m){\n                int ni = i + di[m], nj = j + dj[m];\n                if(ni < 0 || ni >= 30 || nj < 0 || nj >= 30) continue;\n\n                // Get estimated weight for the edge\n                long long w;\n                if(m == 0)      w = (long long)(v[ni][nj] + 0.5L); // U: edge v[ni][nj]\n                else if(m == 1) w = (long long)(v[i][j] + 0.5L);   // D: edge v[i][j]\n                else if(m == 2) w = (long long)(h[i][nj] + 0.5L);  // L: edge h[i][nj]\n                else            w = (long long)(h[i][j] + 0.5L);   // R: edge h[i][j]\n\n                if(dist[i][j] + w < dist[ni][nj]){\n                    dist[ni][nj] = dist[i][j] + w;\n                    pi[ni][nj] = i;\n                    pj[ni][nj] = j;\n                    dir[ni][nj] = dc[m];\n                    pq.emplace(dist[ni][nj], ni, nj);\n                }\n            }\n        }\n\n        // Reconstruct path\n        string path; path.reserve(60);\n        int ci = ti, cj = tj;\n        while(!(ci == si && cj == sj)){\n            path += dir[ci][cj];\n            int ni = pi[ci][cj], nj = pj[ci][cj];\n            ci = ni; cj = nj;\n        }\n        reverse(path.begin(), path.end());\n        cout << path << \"\\n\" << flush;\n\n        // Read feedback\n        int L; cin >> L;\n\n        // Calculate estimated path length B using current weights\n        long double B = 0.0L;\n        ci = si; cj = sj;\n        for(char c : path){\n            if(c == 'U') { B += v[ci-1][cj]; ci--; }\n            else if(c == 'D') { B += v[ci][cj]; ci++; }\n            else if(c == 'L') { B += h[ci][cj-1]; cj--; }\n            else { B += h[ci][cj]; cj++; }\n        }\n\n        // Online gradient descent update\n        // Distribute error equally among edges on the path\n        long double delta = ALPHA * (L - B) / (long double)path.size();\n        ci = si; cj = sj;\n        for(char c : path){\n            if(c == 'U') { v[ci-1][cj] += delta; ci--; }\n            else if(c == 'D') { v[ci][cj] += delta; ci++; }\n            else if(c == 'L') { h[ci][cj-1] += delta; cj--; }\n            else { h[ci][cj] += delta; cj++; }\n        }\n\n        // Spatial Smoothing (Denoising & Generalization)\n        // Horizontal edges: smooth per row\n        // Calculate means first to ensure simultaneous updates\n        long double h_row_mean[30];\n        for(int i=0; i<30; ++i) {\n            long double sum = 0;\n            for(int j=0; j<29; ++j) sum += h[i][j];\n            h_row_mean[i] = sum / 29.0L;\n        }\n        for(int i=0; i<30; ++i) {\n            for(int j=0; j<29; ++j) \n                h[i][j] = h[i][j] * (1.0L - BETA) + h_row_mean[i] * BETA;\n        }\n\n        // Vertical edges: smooth per column\n        long double v_col_mean[30];\n        for(int j=0; j<30; ++j) {\n            long double sum = 0;\n            for(int i=0; i<29; ++i) sum += v[i][j];\n            v_col_mean[j] = sum / 29.0L;\n        }\n        for(int j=0; j<30; ++j) {\n            for(int i=0; i<29; ++i) \n                v[i][j] = v[i][j] * (1.0L - BETA) + v_col_mean[j] * BETA;\n        }\n\n        // Clamp weights to valid range to prevent noise divergence\n        for(int i=0; i<30; ++i) for(int j=0; j<29; ++j) \n            h[i][j] = max(MIN_W, min(MAX_W, h[i][j]));\n        for(int i=0; i<29; ++i) for(int j=0; j<30; ++j) \n            v[i][j] = max(MIN_W, min(MAX_W, v[i][j]));\n    }\n    return 0;\n}","ahc004":"#pragma GCC optimize(\"Ofast,unroll-loops,fast-math\")\n#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <chrono>\n#include <random>\n#include <algorithm>\n#include <cstring>\n#include <cstdint>\n\nusing namespace std;\n\nconst int N = 20;\nconst int MAX_M = 800;\nconst int MAX_PLACEMENTS = 800000;\n\nint M;\n\nstruct PlacementInfo {\n    int matches;\n    int len;\n    int str_id;\n};\n\n// Global array for placement info to improve cache locality and avoid reallocation overhead\nPlacementInfo p_infos[MAX_PLACEMENTS];\n\n// cell_placements[r][c][char_code] stores a list of placement_ids\n// that pass through cell (r, c) and expect the character ('A' + char_code).\n// This structure allows us to iterate only over relevant placements when a cell changes,\n// reducing the iteration size by approximately 8x compared to a flat list.\nvector<int> cell_placements[N][N][8]; \n\nint str_full_cnt[MAX_M];\nchar grid[N][N];\nchar best_grid[N][N];\nint total_score = 0;\nint best_score = -1;\n\nmt19937_64 rng;\n\n// Computes the change in score if grid[r][c] is changed from old_c to new_c.\n// Does not modify the state.\ninline int calc_diff(int r, int c, char new_c, char old_c) {\n    int diff = 0;\n    int old_idx = old_c - 'A';\n    int new_idx = new_c - 'A';\n    \n    // Check placements that will lose a match (those expecting old_c)\n    const vector<int>& old_links = cell_placements[r][c][old_idx];\n    const int* old_ptr = old_links.data();\n    int old_sz = old_links.size();\n    for (int i = 0; i < old_sz; ++i) {\n        int p = old_ptr[i];\n        const PlacementInfo& info = p_infos[p];\n        // If the placement is currently fully matched, losing a character might break it.\n        if (info.matches == info.len) {\n            // If this was the only fully matched placement for this string, the score decreases.\n            if (str_full_cnt[info.str_id] == 1) diff--;\n        }\n    }\n    \n    // Check placements that will gain a match (those expecting new_c)\n    const vector<int>& new_links = cell_placements[r][c][new_idx];\n    const int* new_ptr = new_links.data();\n    int new_sz = new_links.size();\n    for (int i = 0; i < new_sz; ++i) {\n        int p = new_ptr[i];\n        const PlacementInfo& info = p_infos[p];\n        // If the placement has len-1 matches, gaining a character might complete it.\n        if (info.matches == info.len - 1) {\n            // If no placement for this string is currently full, the score increases.\n            if (str_full_cnt[info.str_id] == 0) diff++;\n        }\n    }\n    \n    return diff;\n}\n\n// Applies the change to the state. Only called if the move is accepted.\ninline void apply_change(int r, int c, char new_c, char old_c, int diff) {\n    grid[r][c] = new_c;\n    total_score += diff;\n    int old_idx = old_c - 'A';\n    int new_idx = new_c - 'A';\n    \n    // Update placements that lose a match\n    const vector<int>& old_links = cell_placements[r][c][old_idx];\n    const int* old_ptr = old_links.data();\n    int old_sz = old_links.size();\n    for (int i = 0; i < old_sz; ++i) {\n        int p = old_ptr[i];\n        PlacementInfo& info = p_infos[p];\n        // If it was full, it is no longer full.\n        if (info.matches == info.len) {\n             str_full_cnt[info.str_id]--;\n        }\n        info.matches--;\n    }\n    \n    // Update placements that gain a match\n    const vector<int>& new_links = cell_placements[r][c][new_idx];\n    const int* new_ptr = new_links.data();\n    int new_sz = new_links.size();\n    for (int i = 0; i < new_sz; ++i) {\n        int p = new_ptr[i];\n        PlacementInfo& info = p_infos[p];\n        // If it was one short of full, it becomes full.\n        if (info.matches == info.len - 1) {\n             str_full_cnt[info.str_id]++;\n        }\n        info.matches++;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    rng.seed(chrono::steady_clock::now().time_since_epoch().count());\n\n    int N_in;\n    if (!(cin >> N_in >> M)) return 0;\n    vector<string> S(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> S[i];\n    }\n\n    // Pre-reserve memory for vectors to avoid reallocation overhead\n    for(int r=0; r<N; ++r)\n        for(int c=0; c<N; ++c)\n            for(int k=0; k<8; ++k)\n                cell_placements[r][c][k].reserve(2048);\n\n    int p_idx = 0;\n    for (int k = 0; k < M; ++k) {\n        int L = S[k].length();\n        const string& s = S[k];\n        // Horizontal placements\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                for (int p = 0; p < L; ++p) {\n                    int cc = (c + p) % N;\n                    cell_placements[r][cc][s[p] - 'A'].push_back(p_idx);\n                }\n                p_infos[p_idx].len = L;\n                p_infos[p_idx].str_id = k;\n                p_infos[p_idx].matches = 0;\n                p_idx++;\n            }\n        }\n        // Vertical placements\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                for (int pp = 0; pp < L; ++pp) {\n                    int rr = (r + pp) % N;\n                    cell_placements[rr][c][s[pp] - 'A'].push_back(p_idx);\n                }\n                p_infos[p_idx].len = L;\n                p_infos[p_idx].str_id = k;\n                p_infos[p_idx].matches = 0;\n                p_idx++;\n            }\n        }\n    }\n    // Free memory used by input strings\n    vector<string>().swap(S);\n\n    // Greedy initialization: for each cell, choose the character expected by the most placements\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            int best_c_idx = 0;\n            int max_v = -1;\n            // Check counts for each character\n            for (int k = 0; k < 8; ++k) {\n                int v = (int)cell_placements[r][c][k].size();\n                if (v > max_v) { \n                    max_v = v; \n                    best_c_idx = k; \n                }\n            }\n            grid[r][c] = 'A' + best_c_idx;\n        }\n    }\n\n    // Initialize placement matches based on the greedy grid\n    // We only iterate over placements that actually match the current grid character\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            int cidx = grid[r][c] - 'A';\n            const vector<int>& links = cell_placements[r][c][cidx];\n            for (int p : links) {\n                p_infos[p].matches++;\n            }\n        }\n    }\n\n    // Compute initial str_full_cnt and total_score\n    memset(str_full_cnt, 0, sizeof(str_full_cnt));\n    for (int p = 0; p < p_idx; ++p) {\n        if (p_infos[p].matches == p_infos[p].len) {\n            str_full_cnt[p_infos[p].str_id]++;\n        }\n    }\n\n    total_score = 0;\n    for (int k = 0; k < M; ++k) {\n        if (str_full_cnt[k] > 0) total_score++;\n    }\n\n    best_score = total_score;\n    memcpy(best_grid, grid, sizeof(grid));\n\n    // Simulated Annealing\n    auto start = chrono::steady_clock::now();\n    auto deadline = start + chrono::milliseconds(2800);\n    uniform_int_distribution<int> dist_rc(0, N-1);\n    uniform_int_distribution<int> dist_char(0, 7);\n    uniform_real_distribution<double> prob_dist(0.0, 1.0);\n\n    long long iter = 0;\n    while (true) {\n        iter++;\n        // Check time periodically\n        if (iter % 1024 == 0) {\n            if (chrono::steady_clock::now() >= deadline) break;\n        }\n\n        int r = dist_rc(rng);\n        int c = dist_rc(rng);\n        char old_c = grid[r][c];\n        char new_c = 'A' + dist_char(rng);\n        if (new_c == old_c) continue;\n\n        // Smooth cooling schedule\n        double T = 1.0 / (1.0 + 0.02 * (iter / 1024.0));\n        \n        int diff = calc_diff(r, c, new_c, old_c);\n        if (diff > 0 || prob_dist(rng) < exp(diff / T)) {\n            apply_change(r, c, new_c, old_c, diff);\n            if (total_score > best_score) {\n                best_score = total_score;\n                memcpy(best_grid, grid, sizeof(grid));\n                if (best_score == M) break;\n            }\n        }\n    }\n\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) cout << best_grid[r][c];\n        cout << '\\n';\n    }\n\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\n\nconst int INF = 1e9;\nconst int MAX_ROAD = 5000; // 69*69 = 4761\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, si, sj;\n    if (!(cin >> N >> si >> sj)) return 0;\n    vector<string> grid(N);\n    vector<vector<int>> idx(N, vector<int>(N, -1));\n    vector<pair<int, int>> road_cells;\n    int R = 0;\n    for (int i = 0; i < N; ++i) {\n        cin >> grid[i];\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] != '#') {\n                idx[i][j] = R++;\n                road_cells.emplace_back(i, j);\n            }\n        }\n    }\n    int start_idx = idx[si][sj];\n    auto t0 = chrono::high_resolution_clock::now();\n    auto get_time = [&]() { return chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - t0).count(); };\n\n    // 1. Extract Strategic Candidates (Junctions, Endpoints, Start)\n    struct Point { int r, c, id; };\n    vector<Point> cands;\n    vector<int> cand_to_global(R, -1);\n    int dirs[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};\n    \n    auto add_candidate = [&](int r, int c) {\n        int gid = idx[r][c];\n        if (cand_to_global[gid] == -1) {\n            cand_to_global[gid] = cands.size();\n            cands.push_back({r, c, gid});\n        }\n    };\n\n    add_candidate(si, sj);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] == '#') continue;\n            int road_neighbors = 0;\n            for (auto& d : dirs) {\n                int ni = i + d[0], nj = j + d[1];\n                if (ni >= 0 && ni < N && nj >= 0 && nj < N && grid[ni][nj] != '#') road_neighbors++;\n            }\n            // Junctions (>=3), Endpoints (1), or isolated (0, though graph is connected)\n            if (road_neighbors != 2) add_candidate(i, j);\n            // Also add midpoints of long straight segments to ensure good coverage\n            if (road_neighbors == 2 && (i == 0 || i == N-1 || j == 0 || j == N-1)) add_candidate(i, j);\n        }\n    }\n    int M = cands.size();\n\n    // 2. Precompute Coverage for each candidate\n    vector<bitset<MAX_ROAD>> cov(M);\n    for (int k = 0; k < M; ++k) {\n        int r = cands[k].r, c = cands[k].c;\n        // Horizontal\n        for (int j = c; j >= 0 && grid[r][j] != '#'; --j) cov[k][idx[r][j]] = 1;\n        for (int j = c + 1; j < N && grid[r][j] != '#'; ++j) cov[k][idx[r][j]] = 1;\n        // Vertical\n        for (int i = r - 1; i >= 0 && grid[i][c] != '#'; --i) cov[k][idx[i][c]] = 1;\n        for (int i = r + 1; i < N && grid[i][c] != '#'; ++i) cov[k][idx[i][c]] = 1;\n    }\n\n    // 3. Precompute Pairwise Distances\n    vector<vector<int>> dist(M, vector<int>(M, INF));\n    vector<int> d(N * N);\n    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;\n    \n    for (int i = 0; i < M; ++i) {\n        fill(d.begin(), d.end(), INF);\n        int sr = cands[i].r, sc = cands[i].c;\n        int u0 = sr * N + sc;\n        d[u0] = 0;\n        pq.emplace(0, u0);\n        dist[i][i] = 0;\n\n        while (!pq.empty()) {\n            auto [dst, u] = pq.top(); pq.pop();\n            if (dst > d[u]) continue;\n            int ur = u / N, uc = u % N;\n            if (idx[ur][uc] != -1 && dist[i][cand_to_global[idx[ur][uc]]] == INF)\n                dist[i][cand_to_global[idx[ur][uc]]] = dst;\n\n            for (auto& dr : dirs) {\n                int vr = ur + dr[0], vc = uc + dr[1];\n                if (vr < 0 || vr >= N || vc < 0 || vc >= N || grid[vr][vc] == '#') continue;\n                int v = vr * N + vc;\n                int w = grid[vr][vc] - '0';\n                if (d[u] + w < d[v]) { d[v] = d[u] + w; pq.emplace(d[v], v); }\n            }\n        }\n    }\n\n    // 4. Build Initial Tour (Greedy Coverage/Insertion)\n    vector<int> tour;\n    int start_cand = cand_to_global[start_idx];\n    tour.push_back(start_cand);\n    \n    bitset<MAX_ROAD> covered = cov[start_cand];\n    int uncovered_cnt = R - covered.count();\n    vector<bool> in_tour(M, false);\n    in_tour[start_cand] = true;\n\n    while (uncovered_cnt > 0 && get_time() < 2000) {\n        int best_k = -1, best_pos = 0;\n        double best_ratio = 0.0;\n        \n        for (int k = 0; k < M; ++k) {\n            if (in_tour[k]) continue;\n            bitset<MAX_ROAD> new_cov = cov[k] & ~covered;\n            int gain = new_cov.count();\n            if (gain == 0) continue;\n            \n            for (int i = 0; i < (int)tour.size(); ++i) {\n                int j = tour[(i + 1) % tour.size()];\n                int cost = dist[tour[i]][k] + dist[k][j] - dist[tour[i]][j];\n                if (cost <= 0) continue;\n                double ratio = (double)gain / cost;\n                if (ratio > best_ratio) {\n                    best_ratio = ratio;\n                    best_k = k;\n                    best_pos = i + 1;\n                }\n            }\n        }\n        if (best_k == -1) break;\n        \n        tour.insert(tour.begin() + best_pos, best_k);\n        in_tour[best_k] = true;\n        covered |= cov[best_k];\n        uncovered_cnt = R - covered.count();\n    }\n\n    // 5. Local Search Optimization (2-opt, Or-opt, Remove)\n    bool improved = true;\n    while (improved && get_time() < 2500) {\n        improved = false;\n        // 2-opt\n        for (int i = 0; i < (int)tour.size(); ++i) {\n            for (int j = i + 2; j < (int)tour.size(); ++j) {\n                if (j == (int)tour.size() - 1 && i == 0) continue;\n                int u1 = tour[i], v1 = tour[(i+1)%(int)tour.size()];\n                int u2 = tour[j], v2 = tour[(j+1)%(int)tour.size()];\n                if (dist[u1][v2] + dist[v1][u2] < dist[u1][v1] + dist[u2][v2]) {\n                    reverse(tour.begin() + i + 1, tour.begin() + j + 1);\n                    improved = true;\n                }\n            }\n        }\n        if (improved) continue;\n\n        // Or-opt (relocate 1 or 2 nodes)\n        for (int len = 1; len <= 2; ++len) {\n            for (int i = 0; i < (int)tour.size(); ++i) {\n                int next_i = (i + 1) % tour.size();\n                if (len == 2) next_i = (next_i + 1) % tour.size();\n                \n                int from = tour[i];\n                int to = tour[(next_i + 1) % tour.size()];\n                \n                for (int j = 0; j < (int)tour.size(); ++j) {\n                    if (j == i || j == (i-1+tour.size())%tour.size() || j == next_i) continue;\n                    int insert_pos = (j + 1) % tour.size();\n                    int cost_remove = dist[from][to];\n                    int cost_insert = dist[tour[j]][tour[(i+1)%tour.size()]];\n                    for(int l=0;l<len-1;++l) cost_insert += dist[tour[(i+1+l)%tour.size()]][tour[(i+2+l)%tour.size()]];\n                    cost_insert += dist[tour[(i+len)%tour.size()]][tour[insert_pos]] - dist[tour[j]][tour[insert_pos]];\n                    \n                    if (cost_insert < cost_remove) {\n                        // Perform relocation\n                        vector<int> moved;\n                        for(int l=0;l<len;++l) moved.push_back(tour[(i+1+l)%tour.size()]);\n                        tour.erase(tour.begin() + (i+1), tour.begin() + (i+1+len));\n                        // Handle wrap-around carefully\n                        int insert_idx = (j + 1);\n                        if (insert_idx > (int)tour.size()) insert_idx = tour.size();\n                        tour.insert(tour.begin() + insert_idx, moved.begin(), moved.end());\n                        improved = true;\n                        break;\n                    }\n                }\n                if (improved) break;\n            }\n            if (improved) break;\n        }\n        if (improved) continue;\n\n        // Remove Redundant Nodes\n        for (int i = (int)tour.size() - 1; i >= 0; --i) {\n            int node = tour[i];\n            tour.erase(tour.begin() + i);\n            bitset<MAX_ROAD> test_cov;\n            for (int x : tour) test_cov |= cov[x];\n            if (test_cov.count() == R) {\n                improved = true;\n            } else {\n                tour.insert(tour.begin() + i, node);\n            }\n        }\n    }\n\n    // 6. Path Reconstruction\n    string result = \"\";\n    result.reserve(tour.size() * 20);\n    vector<int> parent(N * N, -1);\n    vector<char> move_char(N * N);\n    char moves[4] = {'U', 'D', 'L', 'R'};\n\n    auto get_path = [&](int from_idx, int to_idx) {\n        if (from_idx == to_idx) return string(\"\");\n        auto [r1, c1] = road_cells[cands[from_idx].id];\n        auto [r2, c2] = road_cells[cands[to_idx].id];\n        if (r1 == r2 && c1 == c2) return string(\"\");\n        \n        fill(d.begin(), d.end(), INF);\n        fill(parent.begin(), parent.end(), -1);\n        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq2;\n        \n        int u0 = r1 * N + c1, target = r2 * N + c2;\n        d[u0] = 0;\n        pq2.emplace(0, u0);\n\n        while (!pq2.empty()) {\n            auto [dst, u] = pq2.top(); pq2.pop();\n            if (dst > d[u]) continue;\n            if (u == target) break;\n            int ur = u / N, uc = u % N;\n            for (int k = 0; k < 4; ++k) {\n                int vr = ur + dirs[k][0], vc = uc + dirs[k][1];\n                if (vr < 0 || vr >= N || vc < 0 || vc >= N || grid[vr][vc] == '#') continue;\n                int v = vr * N + vc;\n                int w = grid[vr][vc] - '0';\n                if (d[u] + w < d[v]) {\n                    d[v] = d[u] + w;\n                    parent[v] = u;\n                    move_char[v] = moves[k];\n                    pq2.emplace(d[v], v);\n                }\n            }\n        }\n        string path = \"\";\n        int curr = target;\n        while (curr != u0) { path += move_char[curr]; curr = parent[curr]; }\n        reverse(path.begin(), path.end());\n        return path;\n    };\n\n    for (int i = 0; i < (int)tour.size(); ++i) {\n        result += get_path(tour[i], tour[(i + 1) % tour.size()]);\n    }\n\n    cout << result << \"\\n\";\n    return 0;\n}","future-contest-2022-qual":"#pragma GCC optimize(\"Ofast,unroll-loops,fast-math\")\n#pragma GCC target(\"avx2,fma\")\n\n#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <cmath>\n\nusing namespace std;\n\n// Constants\nconst int MAXN = 1005;\nconst int MAXM = 25;\nconst int MAXK = 25;\n\nint N, M, K, R;\nint d[MAXN][MAXK];\nlong long sum_diff[MAXN];\nlong long rank_diff[MAXN]; // Criticality: longest path in terms of difficulty\nvector<int> adj[MAXN];\nint in_deg[MAXN];\n\ndouble est_s[MAXM][MAXK];\nint mem_task[MAXM];\nint mem_start[MAXM];\nint mem_done[MAXM];\n\n// Priority Queue Comparator: higher criticality first\nstruct TaskCmp {\n    bool operator()(int a, int b) const { return rank_diff[a] < rank_diff[b]; }\n};\n\npriority_queue<int, vector<int>, TaskCmp> pq;\n\nint free_list[MAXM];\npair<int, int> out_buf[MAXM];\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> K >> R)) return 0;\n\n    // Read task difficulties\n    for (int i = 0; i < N; ++i) {\n        sum_diff[i] = 0;\n        for (int j = 0; j < K; ++j) {\n            cin >> d[i][j];\n            sum_diff[i] += d[i][j];\n        }\n    }\n\n    // Read dependencies\n    for (int i = 0; i < R; ++i) {\n        int u, v; cin >> u >> v; --u; --v;\n        adj[u].push_back(v);\n        in_deg[v]++;\n    }\n\n    // Compute rank_diff: longest path from task to any leaf in terms of difficulty sum\n    // Since input guarantees u < v, tasks are naturally in topological order.\n    // We iterate backwards to compute ranks efficiently.\n    for (int i = N - 1; i >= 0; --i) {\n        long long max_child_rank = 0;\n        for (int v : adj[i]) {\n            if (rank_diff[v] > max_child_rank) max_child_rank = rank_diff[v];\n        }\n        rank_diff[i] = sum_diff[i] + max_child_rank;\n    }\n\n    // Initialize Priority Queue with ready tasks (in-degree 0)\n    for (int i = 0; i < N; ++i) {\n        if (in_deg[i] == 0) pq.push(i);\n    }\n\n    // Initialize member states and skill estimates\n    // Starting with 25.0 (mid-range of generation distribution)\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < K; ++j) est_s[i][j] = 25.0;\n        mem_task[i] = -1;\n        mem_start[i] = -1;\n        mem_done[i] = 0;\n    }\n\n    for (int day = 1; day <= 2000; ++day) {\n        // 1. Identify free members\n        int free_count = 0;\n        for (int m = 0; m < M; ++m) {\n            if (mem_task[m] == -1) free_list[free_count++] = m;\n        }\n\n        // 2. Greedy Assignment\n        int assign_count = 0;\n        while (!pq.empty() && free_count > 0) {\n            int t = pq.top();\n            pq.pop();\n\n            int best_m = -1;\n            int best_idx = -1;\n            double best_cost = 1e18;\n\n            for (int i = 0; i < free_count; ++i) {\n                int m = free_list[i];\n                double w = 0;\n                for (int k = 0; k < K; ++k) {\n                    double diff = d[t][k] - est_s[m][k];\n                    if (diff > 0) w += diff;\n                }\n                // Heuristic: expected completion time is max(1, w)\n                double cost = max(1.0, w);\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_m = m;\n                    best_idx = i;\n                }\n            }\n\n            if (best_m != -1) {\n                mem_task[best_m] = t;\n                mem_start[best_m] = day;\n                out_buf[assign_count++] = {best_m + 1, t + 1};\n                // O(1) removal from free pool\n                free_list[best_idx] = free_list[free_count - 1];\n                free_count--;\n            }\n        }\n\n        // 3. Output assignments\n        cout << assign_count;\n        for (int i = 0; i < assign_count; ++i) {\n            cout << \" \" << out_buf[i].first << \" \" << out_buf[i].second;\n        }\n        cout << \"\\n\" << flush;\n\n        // 4. Read completions\n        int nf;\n        if (!(cin >> nf)) break;\n        if (nf == -1) return 0;\n\n        // 5. Process completions and update state\n        for (int i = 0; i < nf; ++i) {\n            int f; cin >> f; --f;\n            int t = mem_task[f];\n            if (t == -1) continue;\n\n            int actual = day - mem_start[f] + 1;\n            mem_task[f] = -1;\n            mem_done[f]++;\n\n            double pred_w = 0;\n            int def = 0;\n            for (int k = 0; k < K; ++k) {\n                double diff = d[t][k] - est_s[f][k];\n                if (diff > 0) { pred_w += diff; def++; }\n            }\n\n            // Robust online skill update\n            if (def > 0) {\n                double expected = (pred_w > 1.0) ? pred_w : 1.0;\n                double err = actual - expected;\n                // Filter uniform noise r_i in [-3, 3]\n                if (abs(err) > 2.5) {\n                    double lr = 1.5 / (1.0 + 0.02 * mem_done[f]);\n                    double delta = err / def;\n                    delta = max(-4.0, min(4.0, delta));\n                    for (int k = 0; k < K; ++k) {\n                        if (d[t][k] > est_s[f][k]) {\n                            est_s[f][k] -= lr * delta;\n                            est_s[f][k] = max(0.0, min(80.0, est_s[f][k]));\n                        }\n                    }\n                }\n            } else if (actual > 1) {\n                // Overestimation detected: predicted 0 deficit, but took >1 day.\n                // Implies skills were overestimated. Decrease them conservatively.\n                double lr = 0.5 / (1.0 + 0.05 * mem_done[f]);\n                for (int k = 0; k < K; ++k) {\n                    est_s[f][k] -= lr;\n                    est_s[f][k] = max(0.0, est_s[f][k]);\n                }\n            }\n\n            // Release dependencies\n            for (int v : adj[t]) {\n                if (--in_deg[v] == 0) pq.push(v);\n            }\n        }\n    }\n\n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <chrono>\n#include <random>\n#include <numeric>\n#include <iomanip>\n\nusing namespace std;\n\n// ==================== Geometry & Helpers ====================\nstruct Pt { int x, y; };\ninline int dist(const Pt& a, const Pt& b) { return abs(a.x - b.x) + abs(a.y - b.y); }\n\nconst Pt BASE = {400, 400};\n\nstruct Order {\n    int id; // 1-based index\n    Pt p, d; // pickup, delivery\n};\n\nvector<Order> all_orders(1000);\nint sel_ids[50];          // Selected order indices (1-based)\nPt sp[50], sd[50];        // Selected pickup/delivery coordinates\nvector<int> route;        // Route stores 0..49 (pickup), 50..99 (delivery)\n\ninline Pt get_pt(int idx) {\n    return idx < 50 ? sp[idx] : sd[idx - 50];\n}\n\n// ==================== Core Functions ====================\nint calc_cost(const vector<int>& r) {\n    int c = dist(BASE, get_pt(r[0]));\n    for (int i = 0; i < 99; ++i) c += dist(get_pt(r[i]), get_pt(r[i+1]));\n    c += dist(get_pt(r[99]), BASE);\n    return c;\n}\n\nbool check_precedence(const vector<int>& r) {\n    int pos[50]; fill(pos, pos + 50, -1);\n    for (int i = 0; i < 100; ++i) {\n        if (r[i] < 50) pos[r[i]] = i;\n        else if (pos[r[i] - 50] == -1 || pos[r[i] - 50] >= i) return false;\n    }\n    return true;\n}\n\n// ==================== Phase 1: Greedy Construction ====================\nvoid build_initial_route() {\n    route.clear();\n    vector<bool> in_pickup(50, false), in_delivery(50, false);\n    int placed = 0;\n\n    while (placed < 100) {\n        int best_pos = -1, best_pt = -1;\n        int min_delta = 2e9;\n\n        // Try inserting any available pickup or valid delivery\n        for (int p = 0; p < 50; ++p) {\n            if (in_pickup[p] || in_delivery[p]) continue;\n            int pt = p; // pickup\n            for (int pos = 0; pos <= placed; ++pos) {\n                int delta;\n                if (placed == 0) delta = dist(BASE, get_pt(pt)) + dist(get_pt(pt), BASE) - dist(BASE, BASE);\n                else {\n                    Pt prev = (pos == 0) ? BASE : get_pt(route[pos - 1]);\n                    Pt next = (pos == placed) ? BASE : get_pt(route[pos]);\n                    delta = dist(prev, get_pt(pt)) + dist(get_pt(pt), next) - dist(prev, next);\n                }\n                if (delta < min_delta) { min_delta = delta; best_pos = pos; best_pt = pt; }\n            }\n        }\n        for (int p = 0; p < 50; ++p) {\n            if (!in_pickup[p] || in_delivery[p]) continue;\n            int pt = p + 50; // delivery\n            for (int pos = 0; pos <= placed; ++pos) {\n                int delta;\n                if (placed == 0) delta = dist(BASE, get_pt(pt)) + dist(get_pt(pt), BASE);\n                else {\n                    Pt prev = (pos == 0) ? BASE : get_pt(route[pos - 1]);\n                    Pt next = (pos == placed) ? BASE : get_pt(route[pos]);\n                    delta = dist(prev, get_pt(pt)) + dist(get_pt(pt), next) - dist(prev, next);\n                }\n                if (delta < min_delta) { min_delta = delta; best_pos = pos; best_pt = pt; }\n            }\n        }\n\n        route.insert(route.begin() + best_pos, best_pt);\n        if (best_pt < 50) in_pickup[best_pt] = true;\n        else in_delivery[best_pt - 50] = true;\n        placed++;\n    }\n}\n\n// ==================== Phase 2: Local Search (2-opt & Relocate) ====================\nauto start_time = chrono::steady_clock::now();\ninline double elapsed() {\n    return chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n}\n\nvoid run_local_search(double time_budget) {\n    bool improved = true;\n    double deadline = elapsed() + time_budget;\n    while (improved && elapsed() < deadline) {\n        improved = false;\n        \n        // 2-opt\n        for (int l = 0; l < 99 && elapsed() < deadline; ++l) {\n            for (int r = l + 1; r < 100; ++r) {\n                vector<int> tmp = route;\n                reverse(tmp.begin() + l, tmp.begin() + r + 1);\n                \n                int old_c = calc_cost(route);\n                int new_c = calc_cost(tmp);\n                \n                if (new_c < old_c && check_precedence(tmp)) {\n                    route = tmp;\n                    improved = true;\n                    goto next_iter;\n                }\n            }\n        }\n        \n        // Relocate\n        for (int i = 0; i < 100 && elapsed() < deadline; ++i) {\n            for (int j = 0; j < 100; ++j) {\n                if (i == j || i == j + 1) continue;\n                vector<int> tmp = route;\n                int pt = tmp[i];\n                tmp.erase(tmp.begin() + i);\n                tmp.insert(tmp.begin() + j, pt);\n                \n                int old_c = calc_cost(route);\n                int new_c = calc_cost(tmp);\n                \n                if (new_c < old_c && check_precedence(tmp)) {\n                    route = tmp;\n                    improved = true;\n                    goto next_iter;\n                }\n            }\n        }\n        next_iter:;\n    }\n}\n\n// ==================== Phase 3: Order Swapping ====================\nvoid run_order_swap(double time_budget) {\n    mt19937 rng(42);\n    double deadline = elapsed() + time_budget;\n    int best_cost = calc_cost(route);\n    \n    while (elapsed() < deadline) {\n        int in_idx = rng() % 50;\n        int out_idx;\n        do { out_idx = rng() % 1000; } while (find(sel_ids, sel_ids + 50, out_idx) != sel_ids + 50);\n        \n        // Try swapping\n        vector<int> old_route = route;\n        int old_id = sel_ids[in_idx];\n        sel_ids[in_idx] = out_idx + 1; // store 1-based\n        sp[in_idx] = all_orders[out_idx].p;\n        sd[in_idx] = all_orders[out_idx].d;\n        \n        // Remove old order points\n        route.erase(remove_if(route.begin(), route.end(), [&](int x) { return x == in_idx || x == in_idx + 50; }), route.end());\n        \n        // Insert new order points\n        vector<int> tmp = route;\n        // Insert pickup\n        int best_p_pos = -1, min_pd = 2e9;\n        for (int pos = 0; pos <= 98; ++pos) {\n            int delta = dist(pos == 0 ? BASE : get_pt(tmp[pos-1]), get_pt(in_idx)) +\n                        dist(get_pt(in_idx), pos == 98 ? BASE : get_pt(tmp[pos])) -\n                        dist(pos == 0 ? BASE : get_pt(tmp[pos-1]), pos == 98 ? BASE : get_pt(tmp[pos]));\n            if (delta < min_pd) { min_pd = delta; best_p_pos = pos; }\n        }\n        tmp.insert(tmp.begin() + best_p_pos, in_idx);\n        \n        // Insert delivery (must be after pickup)\n        int pickup_pos = best_p_pos;\n        int best_d_pos = -1, min_dd = 2e9;\n        for (int pos = pickup_pos + 1; pos <= 99; ++pos) {\n            int delta = dist(pos == 0 ? BASE : get_pt(tmp[pos-1]), get_pt(in_idx+50)) +\n                        dist(get_pt(in_idx+50), pos == 100 ? BASE : get_pt(tmp[pos])) -\n                        dist(pos == 0 ? BASE : get_pt(tmp[pos-1]), pos == 100 ? BASE : get_pt(tmp[pos]));\n            if (delta < min_dd) { min_dd = delta; best_d_pos = pos; }\n        }\n        tmp.insert(tmp.begin() + best_d_pos, in_idx + 50);\n        \n        int new_cost = calc_cost(tmp);\n        if (new_cost < best_cost) {\n            route = tmp;\n            best_cost = new_cost;\n            run_local_search(0.05); // Quick polish\n        } else {\n            // Revert\n            route = old_route;\n            sel_ids[in_idx] = old_id;\n            // Restore coordinates\n            for (int k = 0; k < 50; ++k) {\n                sp[k] = all_orders[sel_ids[k]-1].p;\n                sd[k] = all_orders[sel_ids[k]-1].d;\n            }\n        }\n    }\n}\n\n// ==================== Main ====================\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    for (int i = 0; i < 1000; ++i) {\n        cin >> all_orders[i].p.x >> all_orders[i].p.y >> all_orders[i].d.x >> all_orders[i].d.y;\n        all_orders[i].id = i + 1;\n    }\n    \n    // Initial Selection: 50 orders with pickups closest to base\n    vector<pair<int, int>> dists;\n    for (int i = 0; i < 1000; ++i) {\n        dists.emplace_back(dist(BASE, all_orders[i].p), i);\n    }\n    nth_element(dists.begin(), dists.begin() + 50, dists.end());\n    for (int i = 0; i < 50; ++i) {\n        int id = dists[i].second;\n        sel_ids[i] = all_orders[id].id;\n        sp[i] = all_orders[id].p;\n        sd[i] = all_orders[id].d;\n    }\n    \n    build_initial_route();\n    \n    // Phase 2: Intensive Route Optimization\n    run_local_search(0.8);\n    \n    // Phase 3: Order Set Optimization\n    run_order_swap(1.0);\n    \n    // Final Polish\n    run_local_search(0.2);\n    \n    // Output\n    cout << \"50\";\n    for (int i = 0; i < 50; ++i) cout << \" \" << sel_ids[i];\n    cout << \"\\n\";\n    \n    vector<Pt> out_path;\n    out_path.push_back(BASE);\n    for (int p : route) out_path.push_back(get_pt(p));\n    out_path.push_back(BASE);\n    \n    cout << out_path.size();\n    for (auto& p : out_path) cout << \" \" << p.x << \" \" << p.y;\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <utility>\n\nusing namespace std;\n\n// Disjoint Set Union (DSU) with path compression and union by rank\nstruct DSU {\n    vector<int> parent, rank;\n    DSU(int n) : parent(n), rank(n, 0) {\n        for (int i = 0; i < n; ++i) parent[i] = i;\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        i = find(i); j = find(j);\n        if (i != j) {\n            if (rank[i] < rank[j]) swap(i, j);\n            parent[j] = i;\n            if (rank[i] == rank[j]) rank[i]++;\n            return true;\n        }\n        return false;\n    }\n};\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 400;\n    const int M = 1995;\n\n    // 1. Read vertex coordinates\n    vector<pair<int, int>> coords(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n\n    // 2. Read edge endpoints and precompute base distances d_i\n    vector<pair<int, int>> edges(M);\n    vector<int> d(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> edges[i].first >> edges[i].second;\n        long long dx = coords[edges[i].first].first - coords[edges[i].second].first;\n        long long dy = coords[edges[i].first].second - coords[edges[i].second].second;\n        d[i] = static_cast<int>(round(sqrt(dx * dx + dy * dy)));\n    }\n\n    DSU dsu(N);\n    const int INF = 1e9;\n\n    // 3. Process edges online\n    for (int i = 0; i < M; ++i) {\n        int l;\n        cin >> l;\n\n        int u = edges[i].first;\n        int v = edges[i].second;\n        int ru = dsu.find(u);\n        int rv = dsu.find(v);\n\n        if (ru == rv) {\n            // Already connected, accepting would form a cycle.\n            cout << \"0\\n\";\n        } else {\n            // Lookahead: find the minimum base distance among future edges\n            // that cross the current cut (connect ru and rv).\n            // Also count how many edges achieve this minimum.\n            int min_d = INF;\n            int cnt = 0;\n            \n            for (int j = i + 1; j < M; ++j) {\n                int rju = dsu.find(edges[j].first);\n                int rjv = dsu.find(edges[j].second);\n                \n                if ((rju == ru && rjv == rv) || (rju == rv && rjv == ru)) {\n                    if (d[j] < min_d) {\n                        min_d = d[j];\n                        cnt = 1;\n                    } else if (d[j] == min_d) {\n                        cnt++;\n                    }\n                }\n            }\n\n            bool accept = false;\n            if (min_d == INF) {\n                // No future edge can connect these components.\n                // Must accept to maintain connectivity.\n                accept = true;\n            } else {\n                // Adaptive threshold with online bias correction:\n                // E[min of k uniforms on [d, 3d]] = d * (1 + 2/(k+1))\n                // We multiply by 1.06 to account for online path dependencies \n                // (future competitors may become irrelevant due to merges).\n                // Clamped to [1.5, 1.85] to prevent extreme decisions.\n                double factor = 1.0 + 2.0 / (cnt + 1);\n                factor *= 1.06;\n                if (factor < 1.50) factor = 1.50;\n                if (factor > 1.85) factor = 1.85;\n\n                if (l < min_d * factor) {\n                    accept = true;\n                }\n            }\n\n            if (accept) {\n                cout << \"1\\n\";\n                dsu.unite(ru, rv);\n            } else {\n                cout << \"0\\n\";\n            }\n        }\n        // Interactive requirement: flush output immediately\n        cout.flush();\n    }\n\n    return 0;\n}","ahc008":"#pragma GCC optimize(\"O3,unroll-loops\")\n#include <iostream>\n#include <vector>\n#include <string>\n#include <cstring>\n#include <cmath>\n#include <algorithm>\n#include <random>\n\nusing namespace std;\n\nconst int H = 30, W = 30;\nint grid[H][W];\nstruct Pos { int x, y; };\nvector<Pos> humans;\nvector<pair<int, int>> pets;\n\ninline bool in_bounds(int x, int y) { return x >= 0 && x < H && y >= 0 && y < W; }\n\nint dist_to_pet[H][W];\nvoid compute_pet_distances(const int g[H][W]) {\n    static int q[900];\n    int head = 0, tail = 0;\n    memset(dist_to_pet, 0x3f, sizeof(dist_to_pet));\n    for (auto& p : pets) {\n        if (g[p.first][p.second] == 0) {\n            dist_to_pet[p.first][p.second] = 0;\n            q[tail++] = (p.first << 5) | p.second;\n        }\n    }\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    while(head < tail) {\n        int cur = q[head++];\n        int cx = cur >> 5, cy = cur & 31;\n        int d = dist_to_pet[cx][cy];\n        for(int i=0; i<4; i++) {\n            int nx = cx + dx[i], ny = cy + dy[i];\n            if(in_bounds(nx, ny) && g[nx][ny] == 0 && dist_to_pet[nx][ny] > d + 1) {\n                dist_to_pet[nx][ny] = d + 1;\n                q[tail++] = (nx << 5) | ny;\n            }\n        }\n    }\n}\n\npair<int, int> bfs(int sx, int sy, const int g[H][W], const int pet_grid[H][W]) {\n    static int vis[H][W] = {0};\n    static int token = 0;\n    token++;\n    if(token > 1000000000) { memset(vis, 0, sizeof(vis)); token = 1; }\n\n    static int q[900];\n    int head = 0, tail = 0;\n    q[tail++] = (sx << 5) | sy;\n    vis[sx][sy] = token;\n    \n    int sz = 0, np = 0;\n    if(pet_grid[sx][sy]) np++;\n\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    while(head < tail) {\n        int cur = q[head++];\n        int cx = cur >> 5, cy = cur & 31;\n        sz++;\n        for(int i=0; i<4; i++) {\n            int nx = cx + dx[i], ny = cy + dy[i];\n            if(in_bounds(nx, ny) && vis[nx][ny] != token && g[nx][ny] == 0) {\n                vis[nx][ny] = token;\n                if(pet_grid[nx][ny]) np++;\n                q[tail++] = (nx << 5) | ny;\n            }\n        }\n    }\n    return {sz, np};\n}\n\nbool can_block_target(int tx, int ty, const int pet_grid[H][W]) {\n    if(!in_bounds(tx, ty)) return false;\n    if(grid[tx][ty] == 1) return false; // Already blocked\n    if(pet_grid[tx][ty]) return false;\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    for(int i=0; i<4; i++) {\n        int nx = tx + dx[i], ny = ty + dy[i];\n        if(in_bounds(nx, ny) && pet_grid[nx][ny]) return false;\n    }\n    for(const auto& h : humans) if(h.x == tx && h.y == ty) return false;\n    return true;\n}\n\nmt19937 rng(1337);\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    int N; cin >> N;\n    pets.resize(N);\n    int pet_grid[H][W] = {};\n    for(int i=0; i<N; i++) {\n        int pt; cin >> pets[i].first >> pets[i].second >> pt;\n        pets[i].first--; pets[i].second--;\n        pet_grid[pets[i].first][pets[i].second] = 1;\n    }\n    int M; cin >> M;\n    humans.resize(M);\n    for(int i=0; i<M; i++) { cin >> humans[i].x >> humans[i].y; humans[i].x--; humans[i].y--; }\n\n    memset(grid, 0, sizeof(grid));\n    const char acts[] = {'.', 'U', 'D', 'L', 'R', 'u', 'd', 'l', 'r'};\n    const int ddx[9] = {0, -1, 1, 0, 0, -1, 1, 0, 0};\n    const int ddy[9] = {0, 0, 0, -1, 1, 0, 0, -1, 1};\n    const bool is_block[9] = {0,0,0,0,0,1,1,1,1};\n\n    for(int turn=0; turn<300; turn++) {\n        compute_pet_distances(grid);\n        vector<char> my_acts(M, '.');\n        vector<int> current_np(M);\n        \n        // Phase 1: Independent Evaluation\n        for(int i=0; i<M; i++) {\n            current_np[i] = bfs(humans[i].x, humans[i].y, grid, pet_grid).second;\n            double best_val = -1.0;\n            char best_a = '.';\n\n            for(int a=0; a<9; a++) {\n                if(a == 0) {}\n                else {\n                    int tx = humans[i].x + ddx[a], ty = humans[i].y + ddy[a];\n                    if(!in_bounds(tx, ty)) continue;\n                    if(is_block[a]) { if(!can_block_target(tx, ty, pet_grid)) continue; }\n                    else { if(grid[tx][ty] != 0) continue; }\n                }\n\n                int sim_grid[H][W]; memcpy(sim_grid, grid, sizeof(sim_grid));\n                int sh = humans[i].x, sy = humans[i].y;\n                if(a != 0) {\n                    if(is_block[a]) {\n                        int tx = humans[i].x + ddx[a], ty = humans[i].y + ddy[a];\n                        if(sim_grid[tx][ty] == 0) sim_grid[tx][ty] = 1;\n                    } else {\n                        sh += ddx[a]; sy += ddy[a];\n                    }\n                }\n\n                auto [new_sz, new_np] = bfs(sh, sy, sim_grid, pet_grid);\n                double val = new_sz / (double)(1LL << new_np);\n                if (new_np < current_np[i]) val += new_sz * 2.0 * (current_np[i] - new_np);\n                if (in_bounds(sh, sy)) val += dist_to_pet[sh][sy] * 0.5;\n                val += (rng() % 1000) * 0.001;\n\n                if(val > best_val) { best_val = val; best_a = acts[a]; }\n            }\n            my_acts[i] = best_a;\n        }\n\n        // Phase 2: Global Block Simulation & Move Validation\n        int sim_grid[H][W]; memcpy(sim_grid, grid, sizeof(sim_grid));\n        for(int i=0; i<M; i++) {\n            int a_idx = -1; for(int k=0;k<9;k++) if(acts[k]==my_acts[i]) a_idx=k;\n            if(a_idx != -1 && is_block[a_idx]) {\n                int tx = humans[i].x + ddx[a_idx], ty = humans[i].y + ddy[a_idx];\n                if(in_bounds(tx, ty)) sim_grid[tx][ty] = 1;\n            }\n        }\n        for(int i=0; i<M; i++) {\n            int a_idx = -1; for(int k=0;k<9;k++) if(acts[k]==my_acts[i]) a_idx=k;\n            if(a_idx != -1 && !is_block[a_idx] && my_acts[i] != '.') {\n                int nx = humans[i].x + ddx[a_idx], ny = humans[i].y + ddy[a_idx];\n                if(!in_bounds(nx, ny) || sim_grid[nx][ny] != 0) {\n                    my_acts[i] = '.'; // Demote to stay if blocked\n                }\n            }\n        }\n\n        string res = \"\"; for(char c:my_acts) res+=c;\n        cout << res << \"\\n\"; cout.flush();\n\n        for(int i=0; i<N; i++) {\n            string mv; cin >> mv;\n            int cx = pets[i].first, cy = pets[i].second;\n            for(char c:mv) {\n                int nx=cx, ny=cy;\n                if(c=='U') nx--; else if(c=='D') nx++; else if(c=='L') ny--; else if(c=='R') ny++;\n                if(in_bounds(nx,ny) && grid[nx][ny]==0) { cx=nx; cy=ny; } else break;\n            }\n            pets[i] = {cx, cy};\n        }\n\n        memset(pet_grid, 0, sizeof(pet_grid));\n        for(auto& p:pets) pet_grid[p.first][p.second]=1;\n\n        // Phase 3: State Synchronization (Blocks first, then moves)\n        for(int i=0; i<M; i++) {\n            int a_idx=-1; for(int k=0;k<9;k++) if(acts[k]==my_acts[i]) a_idx=k;\n            if(a_idx!=-1 && is_block[a_idx]) {\n                int tx=humans[i].x+ddx[a_idx], ty=humans[i].y+ddy[a_idx];\n                if(in_bounds(tx,ty) && grid[tx][ty]==0) grid[tx][ty]=1;\n            }\n        }\n        for(int i=0; i<M; i++) {\n            int a_idx=-1; for(int k=0;k<9;k++) if(acts[k]==my_acts[i]) a_idx=k;\n            if(a_idx!=-1 && !is_block[a_idx] && my_acts[i]!='.') {\n                int nx=humans[i].x+ddx[a_idx], ny=humans[i].y+ddy[a_idx];\n                if(in_bounds(nx,ny) && grid[nx][ny]==0) humans[i]={nx,ny};\n            }\n        }\n    }\n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cstring>\n#include <queue>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n\n#pragma GCC optimize(\"O3,unroll-loops\")\n#pragma GCC target(\"sse4.2\")\n\nusing namespace std;\n\n// Global arrays for cache locality\nint nxt[400][4];\nbool blocked[400][4];\ndouble dp[201][400];\ndouble head_score[201];\ndouble cur_dp[201][400];\n\n// BFS initialization\nstring get_bfs_path(int s_i, int s_j, int t_i, int t_j, const vector<string>& h, const vector<string>& v) {\n    static int dist[20][20], pi[20][20], pj[20][20];\n    memset(dist, -1, sizeof(dist));\n    queue<pair<int,int>> q;\n    q.push({s_i, s_j});\n    dist[s_i][s_j] = 0;\n    int dr[] = {-1, 1, 0, 0};\n    int dc[] = {0, 0, -1, 1};\n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        if (r == t_i && c == t_j) break;\n        for (int k = 0; k < 4; ++k) {\n            int nr = r + dr[k], nc = c + dc[k];\n            if (nr < 0 || nr >= 20 || nc < 0 || nc >= 20) continue;\n            bool wall = false;\n            if (k == 0) wall = (v[r-1][c] == '1');\n            else if (k == 1) wall = (v[r][c] == '1');\n            else if (k == 2) wall = (h[r][c-1] == '1');\n            else if (k == 3) wall = (h[r][c] == '1');\n            if (!wall && dist[nr][nc] == -1) {\n                dist[nr][nc] = dist[r][c] + 1;\n                pi[nr][nc] = r; pj[nr][nc] = c;\n                q.push({nr, nc});\n            }\n        }\n    }\n    string path = \"\";\n    int r = t_i, c = t_j;\n    while (r != s_i || c != s_j) {\n        int pr = pi[r][c], pc = pj[r][c];\n        if (pr == r) path += (pc < c ? 'R' : 'L');\n        else path += (pr < r ? 'D' : 'U');\n        r = pr; c = pc;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n// Full DP evaluation (used for initialization & restart)\ndouble evaluate_full(const string& s, int start_idx, int target_idx, double p, double move_prob, double* hs) {\n    memset(dp, 0, sizeof(dp));\n    dp[0][start_idx] = 1.0;\n    double acc = 0.0;\n    hs[0] = 0.0;\n    for (int t = 0; t < 200; ++t) {\n        int d = (s[t] == 'U' ? 0 : s[t] == 'D' ? 1 : s[t] == 'L' ? 2 : 3);\n        double prev_target = dp[t][target_idx];\n        for (int idx = 0; idx < 400; ++idx) {\n            double prob = dp[t][idx];\n            if (prob < 1e-18) continue;\n            if (idx == target_idx) {\n                dp[t+1][target_idx] += prob;\n            } else {\n                dp[t+1][idx] += prob * p;\n                if (blocked[idx][d]) dp[t+1][idx] += prob * move_prob;\n                else dp[t+1][nxt[idx][d]] += prob * move_prob;\n            }\n        }\n        double reach = dp[t+1][target_idx] - prev_target;\n        acc += (400.0 - t) * reach;\n        hs[t+1] = acc;\n    }\n    return acc;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int s_i, s_j, t_i, t_j;\n    double p;\n    if (!(cin >> s_i >> s_j >> t_i >> t_j >> p)) return 0;\n\n    vector<string> h(20), v(19);\n    for (int i = 0; i < 20; ++i) cin >> h[i];\n    for (int i = 0; i < 19; ++i) cin >> v[i];\n\n    // Precompute transition tables\n    for (int r = 0; r < 20; ++r) {\n        for (int c = 0; c < 20; ++c) {\n            int idx = r * 20 + c;\n            if (r > 0 && v[r-1][c] == '0') { nxt[idx][0] = (r-1)*20+c; blocked[idx][0] = false; }\n            else { nxt[idx][0] = idx; blocked[idx][0] = true; }\n            if (r < 19 && v[r][c] == '0') { nxt[idx][1] = (r+1)*20+c; blocked[idx][1] = false; }\n            else { nxt[idx][1] = idx; blocked[idx][1] = true; }\n            if (c > 0 && h[r][c-1] == '0') { nxt[idx][2] = r*20+(c-1); blocked[idx][2] = false; }\n            else { nxt[idx][2] = idx; blocked[idx][2] = true; }\n            if (c < 19 && h[r][c] == '0') { nxt[idx][3] = r*20+(c+1); blocked[idx][3] = false; }\n            else { nxt[idx][3] = idx; blocked[idx][3] = true; }\n        }\n    }\n\n    int start_idx = s_i * 20 + s_j;\n    int target_idx = t_i * 20 + t_j;\n    double move_prob = 1.0 - p;\n\n    string path = get_bfs_path(s_i, s_j, t_i, t_j, h, v);\n    string s = \"\";\n    s.reserve(200);\n    int plen = path.empty() ? 1 : path.size();\n    for (int i = 0; i < 200; ++i) s += path[i % plen];\n\n    double best_score = evaluate_full(s, start_idx, target_idx, p, move_prob, head_score);\n    double cur_score = best_score;\n    string best_s = s;\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist_pos(0, 199);\n    uniform_int_distribution<int> dist_char(0, 3);\n    uniform_real_distribution<double> dist_uni(0.0, 1.0);\n    char dirs[] = {'U', 'D', 'L', 'R'};\n\n    // Calibrate Temperature based on initial mutation variance\n    double sum_abs_delta = 0;\n    string tmp_s = s;\n    for(int k=0; k<1000; ++k) {\n        int pos = dist_pos(rng);\n        char old = tmp_s[pos];\n        tmp_s[pos] = dirs[dist_char(rng)];\n        double tail_acc = 0;\n        memcpy(&cur_dp[pos][0], &dp[pos][0], sizeof(double)*400);\n        memset(&cur_dp[pos+1][0], 0, sizeof(double)*400*(200-pos));\n        for (int t = pos; t < 200; ++t) {\n            int d = (tmp_s[t] == 'U' ? 0 : tmp_s[t] == 'D' ? 1 : tmp_s[t] == 'L' ? 2 : 3);\n            double pt = cur_dp[t][target_idx];\n            for (int idx = 0; idx < 400; ++idx) {\n                double prob = cur_dp[t][idx];\n                if (prob < 1e-18) continue;\n                if (idx == target_idx) cur_dp[t+1][target_idx] += prob;\n                else {\n                    cur_dp[t+1][idx] += prob * p;\n                    if (blocked[idx][d]) cur_dp[t+1][idx] += prob * move_prob;\n                    else cur_dp[t+1][nxt[idx][d]] += prob * move_prob;\n                }\n            }\n            tail_acc += (400.0 - t) * (cur_dp[t+1][target_idx] - pt);\n        }\n        double sc = head_score[pos] + tail_acc;\n        sum_abs_delta += abs(sc - cur_score);\n        tmp_s[pos] = old;\n    }\n    double T = max(100.0, (sum_abs_delta / 1000.0) * 12.0);\n    double T_start = T;\n\n    auto start_time = chrono::steady_clock::now();\n    int iter = 0;\n    int improve_iter = 0;\n    const double TIME_LIMIT = 1.85;\n    const int STAGNATION_LIMIT = 15000;\n\n    while (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() < TIME_LIMIT) {\n        double progress = chrono::duration<double>(chrono::steady_clock::now() - start_time).count() / TIME_LIMIT;\n        T = T_start * pow(1.0 - progress, 2.5);\n        if (T < 0.1) T = 0.1;\n\n        int pos = dist_pos(rng);\n        char old_c = s[pos];\n        char new_c = dirs[dist_char(rng)];\n        if (new_c == old_c) { iter++; continue; }\n        s[pos] = new_c;\n\n        // Incremental DP from changed position\n        memcpy(&cur_dp[pos][0], &dp[pos][0], sizeof(double)*400);\n        memset(&cur_dp[pos+1][0], 0, sizeof(double)*400*(200-pos));\n        double tail_acc = 0;\n        for (int t = pos; t < 200; ++t) {\n            int d = (s[t] == 'U' ? 0 : s[t] == 'D' ? 1 : s[t] == 'L' ? 2 : 3);\n            double pt = cur_dp[t][target_idx];\n            for (int idx = 0; idx < 400; ++idx) {\n                double prob = cur_dp[t][idx];\n                if (prob < 1e-18) continue;\n                if (idx == target_idx) cur_dp[t+1][target_idx] += prob;\n                else {\n                    cur_dp[t+1][idx] += prob * p;\n                    if (blocked[idx][d]) cur_dp[t+1][idx] += prob * move_prob;\n                    else cur_dp[t+1][nxt[idx][d]] += prob * move_prob;\n                }\n            }\n            tail_acc += (400.0 - t) * (cur_dp[t+1][target_idx] - pt);\n        }\n        double total_new_score = head_score[pos] + tail_acc;\n        double delta = total_new_score - cur_score;\n\n        if (delta > 0 || dist_uni(rng) < exp(delta / T)) {\n            cur_score = total_new_score;\n            memcpy(&dp[pos+1][0], &cur_dp[pos+1][0], sizeof(double)*400*(200-pos));\n            \n            // Update head_score for consistency\n            double running = head_score[pos];\n            for (int t = pos; t < 200; ++t) {\n                double reach = dp[t+1][target_idx] - dp[t][target_idx];\n                running += (400.0 - t) * reach;\n                head_score[t+1] = running;\n            }\n            \n            if (total_new_score > best_score) {\n                best_score = total_new_score;\n                best_s = s;\n                improve_iter = iter;\n            }\n        } else {\n            s[pos] = old_c;\n        }\n        iter++;\n\n        // Stagnation restart\n        if (iter - improve_iter > STAGNATION_LIMIT) {\n            s = best_s;\n            cur_score = best_score;\n            // Mutate a portion of the string to explore new basins\n            for(int k=0; k<25; ++k) {\n                s[dist_pos(rng)] = dirs[dist_char(rng)];\n            }\n            best_score = evaluate_full(s, start_idx, target_idx, p, move_prob, head_score);\n            cur_score = best_score;\n            T = T_start * 0.4; // Partial reheat\n            improve_iter = iter;\n        }\n    }\n\n    cout << best_s << \"\\n\";\n    return 0;\n}","ahc010":"/*\n    Solution for AHC010\n    Optimized Heuristic-Guided Simulated Annealing with Periodic Score Checks\n    - Uses local connectivity heuristic for fast move evaluation.\n    - Periodically computes full score to track global optimum.\n    - Incremental updates for nxt table and heuristic values.\n    - Fast RNG and cache-friendly data structures.\n*/\n#pragma GCC optimize(\"O3,unroll-loops,fast-math\")\n#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <cstring>\n#include <cstdint>\n\nusing namespace std;\n\nconst int H = 30, W = 30, N = H * W, S = N * 4;\n\n// Directions: 0:L, 1:U, 2:R, 3:D\nconst int di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n\n// to_table[type][enter_dir] -> exit_dir. 255 means invalid.\nalignas(64) const uint8_t to_table[8][4] = {\n    {1, 0, 255, 255}, {3, 255, 255, 0}, {255, 255, 3, 2}, {255, 2, 1, 255},\n    {1, 0, 3, 2}, {3, 2, 1, 0}, {2, 255, 0, 255}, {255, 3, 255, 1}\n};\n\n// Paths for each type: pairs of directions {d1, d2}\nalignas(64) const uint8_t type_paths[8][2][2] = {\n    {{0, 1}, {255, 255}}, {{0, 3}, {255, 255}}, {{2, 3}, {255, 255}}, {{2, 1}, {255, 255}},\n    {{0, 1}, {2, 3}}, {{0, 3}, {1, 2}}, {{0, 2}, {255, 255}}, {{1, 3}, {255, 255}}\n};\n\nuint8_t grid[N];\nuint8_t initial_grid[N];\nuint8_t best_grid[N];\nlong long best_score = 0;\n\nint adj[N][4];\nuint8_t vm[N][4];\nuint8_t vm_cnt[N];\n\n// Direct transition table: nxt[state] -> next_state or S\nalignas(64) uint32_t nxt[S];\nalignas(64) uint16_t vis[S] = {0};\nalignas(64) uint16_t trace[S];\nalignas(64) uint16_t step[S];\nuint32_t gen = 0;\n\nint tile_heuristic[N];\n\n// Update nxt entries for a single tile\ninline void update_nxt(int idx) {\n    int base = idx << 2;\n    for (int d = 0; d < 4; ++d) {\n        int s = base + d;\n        int exit_d = to_table[grid[idx]][d];\n        if (exit_d == 255) { nxt[s] = S; continue; }\n        int ni = adj[idx][exit_d];\n        nxt[s] = (ni == -1) ? S : ((ni << 2) | (exit_d ^ 2));\n    }\n}\n\n// Calculate Heuristic for a tile\ninline int calc_tile_heuristic(int idx) {\n    int score = 0;\n    int t = grid[idx];\n    const auto& paths = type_paths[t];\n    \n    // Path 1\n    int d1_1 = paths[0][0];\n    int d1_2 = paths[0][1];\n    int n1 = adj[idx][d1_1];\n    if (n1 != -1 && to_table[grid[n1]][d1_1^2] != 255) score++;\n    int n2 = adj[idx][d1_2];\n    if (n2 != -1 && to_table[grid[n2]][d1_2^2] != 255) score++;\n    \n    // Path 2\n    int d2_1 = paths[1][0];\n    if (d2_1 != 255) {\n        int d2_2 = paths[1][1];\n        int n3 = adj[idx][d2_1];\n        if (n3 != -1 && to_table[grid[n3]][d2_1^2] != 255) score++;\n        int n4 = adj[idx][d2_2];\n        if (n4 != -1 && to_table[grid[n4]][d2_2^2] != 255) score++;\n    }\n    return score;\n}\n\n// Full score calculation\nlong long calc_score() {\n    if (++gen == 0) {\n        memset(vis, 0, sizeof(vis));\n        gen = 1;\n    }\n    uint16_t tid = 0;\n    long long m1 = 0, m2 = 0;\n    for (int s = 0; s < S; ++s) {\n        if (vis[s] == gen) continue;\n        tid++;\n        int cur = s;\n        int st = 0;\n        while (true) {\n            vis[cur] = gen;\n            trace[cur] = tid;\n            step[cur] = st++;\n            cur = nxt[cur];\n            if (cur == S) break;\n            if (vis[cur] == gen) {\n                if (trace[cur] == tid) {\n                    long long cyc = st - step[cur];\n                    if (cyc > m1) { m2 = m1; m1 = cyc; }\n                    else if (cyc > m2) m2 = cyc;\n                }\n                break;\n            }\n        }\n    }\n    return m1 * m2;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    char c;\n    for (int i = 0; i < H; ++i) {\n        for (int j = 0; j < W; ++j) {\n            cin >> c;\n            int idx = i * W + j;\n            initial_grid[idx] = c - '0';\n            grid[idx] = initial_grid[idx];\n            \n            for (int d = 0; d < 4; ++d) {\n                int ni = i + di[d], nj = j + dj[d];\n                adj[idx][d] = (ni >= 0 && ni < H && nj >= 0 && nj < W) ? (ni * W + nj) : -1;\n            }\n            \n            int t = initial_grid[idx];\n            vm_cnt[idx] = 0;\n            if (t <= 3) {\n                for (int m = 0; m < 4; ++m) vm[idx][vm_cnt[idx]++] = m;\n            } else if (t <= 5) {\n                vm[idx][0] = 4; vm[idx][1] = 5; vm_cnt[idx] = 2;\n            } else {\n                vm[idx][0] = 6; vm[idx][1] = 7; vm_cnt[idx] = 2;\n            }\n        }\n    }\n\n    // Initial setup\n    for (int idx = 0; idx < N; ++idx) update_nxt(idx);\n    for (int idx = 0; idx < N; ++idx) tile_heuristic[idx] = calc_tile_heuristic(idx);\n    \n    best_score = calc_score();\n    memcpy(best_grid, grid, sizeof(grid));\n\n    // Fast RNG\n    uint64_t rng_state = chrono::steady_clock::now().time_since_epoch().count();\n    auto rng = [&]() {\n        rng_state ^= rng_state >> 12;\n        rng_state ^= rng_state << 25;\n        rng_state ^= rng_state >> 27;\n        return rng_state * 2685821657736338717ULL;\n    };\n\n    auto start = chrono::high_resolution_clock::now();\n    const double time_limit = 1.95;\n    const int CHECK_INTERVAL = 100; \n    int check_counter = 0;\n\n    int neighbors[4];\n    int new_h_neighbors[4];\n\n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > time_limit) break;\n\n        double progress = elapsed / time_limit;\n        double T = 1.5 * (1.0 - progress);\n        if (T < 0.001) T = 0.001;\n\n        int idx = (int)(rng() % N);\n        int cnt = vm_cnt[idx];\n        int new_type = vm[idx][rng() % cnt];\n        int old_type = grid[idx];\n        \n        if (new_type == old_type) continue;\n\n        // Identify neighbors and sum old H\n        int n_count = 0;\n        long long sum_old_H = tile_heuristic[idx];\n        for(int d=0; d<4; ++d) {\n            int n = adj[idx][d];\n            if(n != -1) {\n                neighbors[n_count] = n;\n                sum_old_H += tile_heuristic[n];\n                n_count++;\n            }\n        }\n\n        // Apply move\n        grid[idx] = new_type;\n        update_nxt(idx);\n\n        // Compute new Heuristic\n        int new_h_idx = calc_tile_heuristic(idx);\n        long long sum_new_H = new_h_idx;\n        for(int k=0; k<n_count; ++k) {\n            new_h_neighbors[k] = calc_tile_heuristic(neighbors[k]);\n            sum_new_H += new_h_neighbors[k];\n        }\n\n        long long delta_H = sum_new_H - sum_old_H;\n\n        // SA Acceptance on H\n        bool accept = false;\n        if (delta_H >= 0) accept = true;\n        else {\n            double prob = exp((double)delta_H / T);\n            double r = (double)(rng() >> 11) * (1.0 / (1ULL << 53));\n            if (r < prob) accept = true;\n        }\n\n        if (accept) {\n            // Update H array\n            tile_heuristic[idx] = new_h_idx;\n            for(int k=0; k<n_count; ++k) {\n                tile_heuristic[neighbors[k]] = new_h_neighbors[k];\n            }\n        } else {\n            // Revert grid and nxt\n            grid[idx] = old_type;\n            update_nxt(idx);\n        }\n\n        check_counter++;\n        if (check_counter >= CHECK_INTERVAL) {\n            check_counter = 0;\n            long long s = calc_score();\n            if (s > best_score) {\n                best_score = s;\n                memcpy(best_grid, grid, sizeof(grid));\n            }\n        }\n    }\n\n    // Final check\n    long long s = calc_score();\n    if (s > best_score) {\n        best_score = s;\n        memcpy(best_grid, grid, sizeof(grid));\n    }\n\n    string res; res.reserve(N);\n    for (int i = 0; i < N; ++i) {\n        int r = 0;\n        int init = initial_grid[i], cur = best_grid[i];\n        if (init <= 3) r = (cur - init + 4) % 4;\n        else r = (cur != init);\n        res.push_back('0' + r);\n    }\n    cout << res << \"\\n\";\n    return 0;\n}","ahc011":"/*\n    AHC011 Solution\n    Strategy:\n    1. Find a target layout (tree) with correct parity and minimal Manhattan distance.\n       Uses time-bounded DFS with pruning, cycle detection, and candidate sorting.\n    2. Solve the sliding puzzle by moving tiles to their target positions in raster order.\n       Uses BFS to navigate the empty space to the exact \"push\" position.\n       Correctly maps tile movement directions to operation characters.\n*/\n#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <queue>\n#include <numeric>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\n#pragma GCC optimize(\"O3\")\n\nint N;\nlong long T;\nvector<int> tile_masks;\nvector<int> init_pos_r, init_pos_c;\nint initial_parity;\n\nvector<int> best_layout;\nlong long best_layout_cost = 1e18;\nbool found_any = false;\n\nauto start_time = chrono::steady_clock::now();\nconst int LAYOUT_TIME_MS = 2000;\n\nstruct UF {\n    vector<int> p;\n    UF(int n) : p(n, -1) {}\n    int find(int x) { return p[x] == -1 ? x : p[x] = find(p[x]); }\n    bool unite(int x, int y) {\n        x = find(x); y = find(y);\n        if (x != y) { p[y] = x; return true; }\n        return false;\n    }\n    bool same(int x, int y) { return find(x) == find(y); }\n    UF clone() const { UF r(0); r.p = p; return r; }\n};\n\nint calc_parity(const vector<int>& b, int empty_pos) {\n    vector<int> seq; seq.reserve(b.size());\n    for (int x : b) if (x != -1) seq.push_back(x);\n    int inv = 0;\n    for (size_t i = 0; i < seq.size(); ++i)\n        for (size_t j = i + 1; j < seq.size(); ++j)\n            if (seq[i] > seq[j]) inv++;\n    int empty_r = empty_pos / N;\n    if (N % 2 == 1) return inv % 2;\n    return (inv + (N - 1 - empty_r)) % 2;\n}\n\nvoid dfs(int pos, vector<int>& b, vector<bool>& used, UF uf, long long current_cost) {\n    if (found_any && current_cost >= best_layout_cost) return;\n    if (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() > LAYOUT_TIME_MS) return;\n\n    if (pos == N * N) {\n        int root = -1;\n        bool connected = true;\n        for (int i = 0; i < N * N; ++i) {\n            if (b[i] != -1) {\n                if (root == -1) root = uf.find(i);\n                else if (uf.find(i) != root) { connected = false; break; }\n            }\n        }\n        if (!connected) return;\n        if (calc_parity(b, N*N-1) != initial_parity) return;\n        \n        best_layout = b;\n        best_layout_cost = current_cost;\n        found_any = true;\n        return;\n    }\n\n    if (pos == N*N-1) {\n        b[pos] = -1;\n        dfs(pos+1, b, used, uf, current_cost);\n        b[pos] = -2;\n        return;\n    }\n\n    int r = pos / N, c = pos % N;\n    vector<pair<long long, int>> candidates;\n    for (int t = 0; t < N*N-1; ++t) {\n        if (used[t]) continue;\n        long long cost = abs(init_pos_r[t] - r) + abs(init_pos_c[t] - c);\n        candidates.emplace_back(cost, t);\n    }\n    sort(candidates.begin(), candidates.end());\n\n    for (auto [cost, t] : candidates) {\n        int m = tile_masks[t];\n        bool conn_up = false, conn_left = false;\n        if (r > 0 && b[pos-N] != -1) {\n            bool up_has_d = (tile_masks[b[pos-N]] & 8);\n            bool curr_has_u = (m & 2);\n            if (up_has_d && curr_has_u) conn_up = true;\n        }\n        if (c > 0 && b[pos-1] != -1) {\n            bool left_has_r = (tile_masks[b[pos-1]] & 4);\n            bool curr_has_l = (m & 1);\n            if (left_has_r && curr_has_l) conn_left = true;\n        }\n\n        UF next_uf = uf.clone();\n        bool cycle = false;\n        if (conn_up) {\n            if (next_uf.same(pos, pos-N)) cycle = true;\n            else next_uf.unite(pos, pos-N);\n        }\n        if (!cycle && conn_left) {\n            if (next_uf.same(pos, pos-1)) cycle = true;\n            else next_uf.unite(pos, pos-1);\n        }\n        if (cycle) continue;\n\n        b[pos] = t;\n        used[t] = true;\n        dfs(pos+1, b, used, next_uf, current_cost + cost);\n        if (found_any && best_layout_cost == 0) return;\n        used[t] = false;\n        b[pos] = -2;\n    }\n}\n\nstring bfs_empty(int start, int target, const vector<int>& board, const vector<bool>& locked) {\n    if (start == target) return \"\";\n    queue<int> q; q.push(start);\n    vector<int> par(N*N, -1);\n    vector<char> mv(N*N, 0);\n    par[start] = start;\n    \n    int dr[] = {-1, 1, 0, 0};\n    int dc[] = {0, 0, -1, 1};\n    char ops[] = {'U', 'D', 'L', 'R'};\n    \n    while(!q.empty()) {\n        int u = q.front(); q.pop();\n        if(u == target) break;\n        int r = u/N, c = u%N;\n        for(int i=0; i<4; ++i) {\n            int nr = r+dr[i], nc = c+dc[i];\n            if(nr<0||nr>=N||nc<0||nc>=N) continue;\n            int v = nr*N+nc;\n            if(par[v]!=-1 || locked[v]) continue;\n            par[v] = u;\n            mv[v] = ops[i];\n            q.push(v);\n        }\n    }\n    if(par[target] == -1) return \"\";\n    string path;\n    int cur = target;\n    while(cur != start) {\n        path += mv[cur];\n        cur = par[cur];\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nvoid apply(char op, vector<int>& board, int& empty, vector<int>& tile_pos) {\n    int r = empty/N, c_idx = empty%N;\n    int nr=r, nc=c_idx;\n    if(op=='U') nr--;      \n    else if(op=='D') nr++; \n    else if(op=='L') nc--; \n    else if(op=='R') nc++; \n    \n    int nxt = nr*N+nc;\n    int t = board[nxt];\n    board[empty] = t;\n    board[nxt] = -1;\n    tile_pos[t] = empty;\n    empty = nxt;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    if(!(cin >> N >> T)) return 0;\n    \n    vector<string> grid(N);\n    tile_masks.reserve(N*N-1);\n    init_pos_r.resize(N*N-1);\n    init_pos_c.resize(N*N-1);\n    vector<int> init_board(N*N);\n    int tile_cnt = 0, empty_pos = -1;\n    \n    for(int i=0; i<N; ++i) {\n        cin >> grid[i];\n        for(int j=0; j<N; ++j) {\n            char ch = grid[i][j];\n            int pos = i*N+j;\n            if(ch=='0') {\n                init_board[pos] = -1;\n                empty_pos = pos;\n            } else {\n                int val = (ch>='0'&&ch<='9') ? ch-'0' : ch-'a'+10;\n                tile_masks.push_back(val);\n                init_board[pos] = tile_cnt;\n                init_pos_r[tile_cnt] = i;\n                init_pos_c[tile_cnt] = j;\n                tile_cnt++;\n            }\n        }\n    }\n    \n    initial_parity = calc_parity(init_board, empty_pos);\n    \n    vector<int> board(N*N, -2);\n    vector<bool> used(N*N-1, false);\n    start_time = chrono::steady_clock::now();\n    \n    dfs(0, board, used, UF(N*N), 0);\n    \n    if(!found_any) {\n        best_layout.assign(N*N, -2);\n        for(int i=0; i<N*N-1; ++i) best_layout[i] = i;\n        best_layout[N*N-1] = -1;\n    }\n    \n    vector<int> cur_board = init_board;\n    int cur_empty = empty_pos;\n    vector<int> tile_pos(N*N-1);\n    for(int i=0; i<N*N; ++i) if(cur_board[i] != -1) tile_pos[cur_board[i]] = i;\n    \n    string moves;\n    vector<bool> locked(N*N, false);\n    \n    for(int P=0; P<N*N-1; ++P) {\n        if(moves.size() >= T) break;\n        int tid = best_layout[P];\n        if(tid == -1) continue;\n        if(cur_board[P] == tid) { locked[P] = true; continue; }\n        \n        int t_pos = tile_pos[tid];\n        int tr = t_pos/N, tc = t_pos%N;\n        int pr = P/N, pc = P%N;\n        \n        // Move horizontally first\n        while(tc != pc && moves.size() < T) {\n            int dir_c = (tc < pc) ? 1 : -1;\n            int er = tr, ec = tc + dir_c;\n            int target_empty = er*N+ec;\n            if(er<0||er>=N||ec<0||ec>=N || locked[target_empty]) break;\n            \n            if(cur_empty != target_empty) {\n                string path = bfs_empty(cur_empty, target_empty, cur_board, locked);\n                if(path.empty()) break;\n                for(char c : path) {\n                    if(moves.size()>=T) break;\n                    apply(c, cur_board, cur_empty, tile_pos); moves+=c;\n                }\n            }\n            if(cur_empty != target_empty) break;\n\n            // Correct mapping:\n            // dir_c = 1 (move tile Right) -> Empty is Right -> Slide Left Tile -> 'L'\n            // dir_c = -1 (move tile Left) -> Empty is Left -> Slide Right Tile -> 'R'\n            char op = (dir_c == 1) ? 'L' : 'R'; \n            \n            if(moves.size()<T) {\n                apply(op, cur_board, cur_empty, tile_pos); moves+=op;\n            }\n            tc += dir_c;\n            t_pos = tile_pos[tid]; tr=t_pos/N; tc=t_pos%N;\n        }\n        \n        // Move vertically\n        while(tr != pr && moves.size() < T) {\n            int dir_r = (tr > pr) ? -1 : 1;\n            int er = tr + dir_r, ec = tc;\n            int target_empty = er*N+ec;\n            if(er<0||er>=N||ec<0||ec>=N || locked[target_empty]) break;\n            \n            if(cur_empty != target_empty) {\n                string path = bfs_empty(cur_empty, target_empty, cur_board, locked);\n                if(path.empty()) break;\n                for(char c : path) {\n                    if(moves.size()>=T) break;\n                    apply(c, cur_board, cur_empty, tile_pos); moves+=c;\n                }\n            }\n            if(cur_empty != target_empty) break;\n\n            // Correct mapping:\n            // dir_r = -1 (move tile Up) -> Empty is Above -> Slide Down Tile -> 'D'\n            // dir_r = 1 (move tile Down) -> Empty is Below -> Slide Up Tile -> 'U'\n            char op = (dir_r == 1) ? 'U' : 'D'; \n            \n            if(moves.size()<T) {\n                apply(op, cur_board, cur_empty, tile_pos); moves+=op;\n            }\n            tr += dir_r;\n            t_pos = tile_pos[tid]; tr=t_pos/N; tc=t_pos%N;\n        }\n        \n        if(cur_board[P] == tid) locked[P] = true;\n    }\n    \n    if(moves.size() > T) moves.resize(T);\n    cout << moves << \"\\n\";\n    return 0;\n}","ahc012":"/*\n    Solution for AtCoder Heuristic Contest 012\n    Strategy: Greedy Randomized Local Search.\n    We maintain the current partition of strawberries (regions).\n    In each step, we try to find a random line that maximizes the score improvement.\n    A line splits regions into two parts. We only accept the line if it increases the score.\n    We track the number of pieces of each size (up to 10) to compute the score efficiently.\n    Lines that pass exactly through a strawberry are avoided.\n*/\n#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <tuple>\n#include <numeric>\n\nusing namespace std;\n\ntypedef long long ll;\n\nstruct Point {\n    ll x, y;\n};\n\nstruct Region {\n    vector<int> pts; // Indices of strawberries in this region\n};\n\nint main() {\n    // Fast IO\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, K;\n    if (!(cin >> N >> K)) return 0;\n\n    vector<int> a(11);\n    for (int i = 1; i <= 10; ++i) cin >> a[i];\n\n    vector<Point> pts(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> pts[i].x >> pts[i].y;\n    }\n\n    // Initial state: One region containing all strawberries\n    vector<Region> regions;\n    regions.reserve(K + 2);\n    Region start_reg;\n    start_reg.pts.reserve(N);\n    for (int i = 0; i < N; ++i) start_reg.pts.push_back(i);\n    regions.push_back(move(start_reg));\n\n    // b[d] stores count of pieces with exactly d strawberries (for d <= 10)\n    // We only track sizes <= 10 because demands a_d are only up to 10.\n    // Pieces with size > 10 contribute 0 to the score.\n    vector<int> b(11, 0);\n    if (N <= 10) b[N] = 1;\n\n    auto calc_score = [&](const vector<int>& counts) {\n        ll sc = 0;\n        for (int d = 1; d <= 10; ++d) {\n            sc += min((ll)a[d], (ll)counts[d]);\n        }\n        return sc;\n    };\n\n    ll current_score = calc_score(b);\n    vector<tuple<ll, ll, ll, ll>> final_lines;\n    final_lines.reserve(K);\n\n    mt19937_64 rng(12345); // Fixed seed for reproducibility, or random\n    // Range for line coordinates. Strawberries are in [-10000, 10000].\n    // We generate lines passing through points in a slightly larger box.\n    uniform_int_distribution<ll> dist(-25000, 25000);\n\n    auto start_time = chrono::steady_clock::now();\n    \n    // Parameters for search\n    // Higher TRIES_PER_STEP gives better lines but takes more time.\n    // 300 seems a good balance for N=5000, K=100 within 3s.\n    const int TRIES_PER_STEP = 300; \n\n    for (int step = 0; step < K; ++step) {\n        // Time check to ensure we finish within limit\n        auto now = chrono::steady_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 2800) break;\n\n        ll best_line_x1 = 0, best_line_y1 = 0, best_line_x2 = 0, best_line_y2 = 0;\n        ll best_score = current_score;\n        bool found_better = false;\n\n        for (int t = 0; t < TRIES_PER_STEP; ++t) {\n            // Generate random line defined by two points\n            ll x1 = dist(rng);\n            ll y1 = dist(rng);\n            ll x2 = dist(rng);\n            ll y2 = dist(rng);\n            \n            // Ensure distinct points\n            if (x1 == x2 && y1 == y2) continue;\n\n            // Precompute line coefficients for Ax + By + C = 0\n            // A = y1 - y2, B = x2 - x1, C = -A*x1 - B*y1\n            ll A = y1 - y2;\n            ll B = x2 - x1;\n            ll C = -A * x1 - B * y1;\n\n            // Check validity and calculate potential score\n            // We work on a copy of b to simulate the change\n            vector<int> temp_b = b;\n            bool possible = true;\n            \n            // Iterate over all current regions to see how they are split\n            for (const auto& reg : regions) {\n                int sz = (int)reg.pts.size();\n                if (sz <= 1) {\n                    // If size is 1, the line must not pass through the point\n                    int idx = reg.pts[0];\n                    ll val = A * pts[idx].x + B * pts[idx].y + C;\n                    if (val == 0) {\n                        possible = false; // Line cuts the strawberry\n                        break;\n                    }\n                    continue; // No split possible for single point (unless hit)\n                }\n\n                int pos_cnt = 0;\n                int neg_cnt = 0;\n                bool hit = false;\n                \n                // Check side of each point in the region\n                for (int idx : reg.pts) {\n                    ll val = A * pts[idx].x + B * pts[idx].y + C;\n                    if (val > 0) pos_cnt++;\n                    else if (val < 0) neg_cnt++;\n                    else {\n                        hit = true; // Line passes through a strawberry\n                        break;\n                    }\n                }\n                \n                if (hit) {\n                    possible = false;\n                    break;\n                }\n\n                // If the line splits the region into two non-empty sets\n                if (pos_cnt > 0 && neg_cnt > 0) {\n                    // Update the counts in temp_b\n                    // The old region of size 'sz' is removed\n                    if (sz <= 10) {\n                        temp_b[sz]--;\n                    }\n                    // Two new regions of sizes 'pos_cnt' and 'neg_cnt' are created\n                    if (pos_cnt <= 10) {\n                        temp_b[pos_cnt]++;\n                    }\n                    if (neg_cnt <= 10) {\n                        temp_b[neg_cnt]++;\n                    }\n                }\n            }\n\n            if (possible) {\n                ll sc = calc_score(temp_b);\n                if (sc > best_score) {\n                    best_score = sc;\n                    best_line_x1 = x1;\n                    best_line_y1 = y1;\n                    best_line_x2 = x2;\n                    best_line_y2 = y2;\n                    found_better = true;\n                }\n            }\n        }\n\n        if (found_better) {\n            current_score = best_score;\n            final_lines.push_back({best_line_x1, best_line_y1, best_line_x2, best_line_y2});\n            \n            // Apply the best line: Update regions and global counts b\n            ll A = best_line_y1 - best_line_y2;\n            ll B = best_line_x2 - best_line_x1;\n            ll C = -A * best_line_x1 - B * best_line_y1;\n\n            vector<Region> next_regions;\n            // Reserve memory to avoid reallocations. Max regions ~ K+1.\n            next_regions.reserve(regions.size() + 2);\n\n            for (auto& reg : regions) {\n                int sz = (int)reg.pts.size();\n                \n                // First pass: check if split is needed\n                int pos = 0;\n                int neg = 0;\n                for (int idx : reg.pts) {\n                    ll val = A * pts[idx].x + B * pts[idx].y + C;\n                    if (val > 0) pos++;\n                    else if (val < 0) neg++;\n                    // val == 0 should not happen for the selected best line\n                }\n\n                if (pos > 0 && neg > 0) {\n                    // Split occurred\n                    // Update global counts b\n                    if (sz <= 10) b[sz]--;\n                    if (pos <= 10) b[pos]++;\n                    if (neg <= 10) b[neg]++;\n\n                    // Create new regions\n                    Region r1, r2;\n                    r1.pts.reserve(pos);\n                    r2.pts.reserve(neg);\n                    \n                    for (int idx : reg.pts) {\n                        ll val = A * pts[idx].x + B * pts[idx].y + C;\n                        if (val > 0) r1.pts.push_back(idx);\n                        else if (val < 0) r2.pts.push_back(idx);\n                    }\n                    next_regions.push_back(move(r1));\n                    next_regions.push_back(move(r2));\n                } else {\n                    // No split, keep the region (move to avoid copy)\n                    next_regions.push_back(move(reg));\n                }\n            }\n            regions = move(next_regions);\n        } else {\n            // No improvement found with random lines, stop early\n            break;\n        }\n    }\n\n    // Output results\n    cout << final_lines.size() << \"\\n\";\n    for (const auto& line : final_lines) {\n        cout << get<0>(line) << \" \" << get<1>(line) << \" \" << get<2>(line) << \" \" << get<3>(line) << \"\\n\";\n    }\n\n    return 0;\n}","ahc014":"#pragma GCC optimize(\"O3,unroll-loops\")\n#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nbool has_dot[65][65];\n// used_edge[x][y][dir] tracks unit edges\n// dir 0: Right  (x,y) -> (x+1,y)\n// dir 1: Up     (x,y) -> (x,y+1)\n// dir 2: UR     (x,y) -> (x+1,y+1)\n// dir 3: DR     (x,y) -> (x+1,y-1)\nbool used_edge[65][65][4] = {}; \n\nvector<int> row_dots[65], col_dots[65], diag1[130], diag2[130];\nlong long weight[65][65];\n\nstruct Point { int x, y; };\nvector<Point> all_points;\nvector<tuple<Point, Point, Point, Point>> result;\n\n// Insert dot into all relevant sorted lists\nvoid add_dot(int x, int y) {\n    has_dot[x][y] = true;\n    row_dots[y].insert(lower_bound(row_dots[y].begin(), row_dots[y].end(), x), x);\n    col_dots[x].insert(lower_bound(col_dots[x].begin(), col_dots[x].end(), y), y);\n    diag1[y - x + 65].insert(lower_bound(diag1[y - x + 65].begin(), diag1[y - x + 65].end(), x), x);\n    diag2[y + x].insert(lower_bound(diag2[y + x].begin(), diag2[y + x].end(), x), x);\n}\n\n// Check if any dot exists strictly between (x1,y1) and (x2,y2)\nbool has_dot_on_segment(int x1, int y1, int x2, int y2) {\n    if (x1 == x2) {\n        int y_min = min(y1, y2), y_max = max(y1, y2);\n        auto it = upper_bound(col_dots[x1].begin(), col_dots[x1].end(), y_min);\n        return (it != col_dots[x1].end() && *it < y_max);\n    } else if (y1 == y2) {\n        int x_min = min(x1, x2), x_max = max(x1, x2);\n        auto it = upper_bound(row_dots[y1].begin(), row_dots[y1].end(), x_min);\n        return (it != row_dots[y1].end() && *it < x_max);\n    } else {\n        int x_min = min(x1, x2), x_max = max(x1, x2);\n        if ((x2 - x1) == (y2 - y1)) { // Up-Right\n            int d = y1 - x1 + 65;\n            auto it = upper_bound(diag1[d].begin(), diag1[d].end(), x_min);\n            return (it != diag1[d].end() && *it < x_max);\n        } else { // Down-Right\n            int d = y1 + x1;\n            auto it = upper_bound(diag2[d].begin(), diag2[d].end(), x_min);\n            return (it != diag2[d].end() && *it < x_max);\n        }\n    }\n    return false;\n}\n\n// Check if any unit edge on the segment is already used\nbool has_edge_collision(int x1, int y1, int x2, int y2) {\n    if (x1 > x2 || (x1 == x2 && y1 > y2)) { swap(x1, x2); swap(y1, y2); }\n    int dx = x2 - x1, dy = y2 - y1;\n    if (dx == 0) {\n        for (int y = y1; y < y2; ++y) if (used_edge[x1][y][1]) return true;\n    } else if (dy == 0) {\n        for (int x = x1; x < x2; ++x) if (used_edge[x][y1][0]) return true;\n    } else if (dy > 0) {\n        for (int x = x1; x < x2; ++x) if (used_edge[x][y1 + (x - x1)][2]) return true;\n    } else {\n        for (int x = x1; x < x2; ++x) if (used_edge[x][y1 - (x - x1)][3]) return true;\n    }\n    return false;\n}\n\n// Mark all unit edges on the segment as used\nvoid mark_edges(int x1, int y1, int x2, int y2) {\n    if (x1 > x2 || (x1 == x2 && y1 > y2)) { swap(x1, x2); swap(y1, y2); }\n    int dx = x2 - x1, dy = y2 - y1;\n    if (dx == 0) {\n        for (int y = y1; y < y2; ++y) used_edge[x1][y][1] = true;\n    } else if (dy == 0) {\n        for (int x = x1; x < x2; ++x) used_edge[x][y1][0] = true;\n    } else if (dy > 0) {\n        for (int x = x1; x < x2; ++x) used_edge[x][y1 + (x - x1)][2] = true;\n    } else {\n        for (int x = x1; x < x2; ++x) used_edge[x][y1 - (x - x1)][3] = true;\n    }\n}\n\n// Validate rectangle perimeter\nbool check_rect(const Point& p1, const Point& p2, const Point& p3, const Point& p4) {\n    const Point pts[4] = {p1, p2, p3, p4};\n    for (int i = 0; i < 4; ++i) {\n        if (has_dot_on_segment(pts[i].x, pts[i].y, pts[(i+1)%4].x, pts[(i+1)%4].y)) return false;\n        if (has_edge_collision(pts[i].x, pts[i].y, pts[(i+1)%4].x, pts[(i+1)%4].y)) return false;\n    }\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M)) return 0;\n    \n    int c = (N - 1) / 2;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            weight[i][j] = (long long)(i - c) * (i - c) + (j - c) * (j - c) + 1;\n            all_points.push_back({i, j});\n        }\n    }\n\n    for (int i = 0; i < M; ++i) {\n        int x, y; cin >> x >> y;\n        add_dot(x, y);\n    }\n\n    // Greedy: process highest weight points first\n    sort(all_points.begin(), all_points.end(), [](const Point& a, const Point& b) {\n        return weight[a.x][a.y] > weight[b.x][b.y];\n    });\n\n    clock_t start = clock();\n    const double TIME_LIMIT = 4.5;\n\n    for (const auto& p1 : all_points) {\n        if (has_dot[p1.x][p1.y]) continue;\n        if ((double)(clock() - start) / CLOCKS_PER_SEC > TIME_LIMIT) break;\n        \n        int px = p1.x, py = p1.y;\n        Point p2, p3, p4;\n        \n        // Lambda avoids goto and keeps variables localized\n        auto search = [&]() -> bool {\n            // 1. Axis-Aligned Rectangles\n            if (!row_dots[py].empty() && !col_dots[px].empty()) {\n                for (int x2 : row_dots[py]) {\n                    if (x2 == px) continue;\n                    for (int y2 : col_dots[px]) {\n                        if (y2 == py) continue;\n                        if (has_dot[x2][y2]) {\n                            p2 = {x2, py}; p4 = {px, y2}; p3 = {x2, y2};\n                            if (check_rect(p1, p2, p3, p4)) return true;\n                        }\n                    }\n                }\n            }\n\n            // 2. 45-Degree Rotated Rectangles\n            int d1_idx = py - px + 65; // Main diagonal index\n            int d2_idx = py + px;      // Anti-diagonal index\n            \n            // Case A: p2 on main diag, p4 on anti diag\n            for (int x2 : diag1[d1_idx]) {\n                if (x2 == px) continue;\n                int y2 = py + (x2 - px);\n                for (int x4 : diag2[d2_idx]) {\n                    if (x4 == px) continue;\n                    int y4 = py - (x4 - px);\n                    int p3x = x2 + x4 - px;\n                    int p3y = y2 + y4 - py;\n                    if (p3x < 0 || p3x >= N || p3y < 0 || p3y >= N) continue;\n                    if (has_dot[p3x][p3y]) {\n                        p2 = {x2, y2}; p4 = {x4, y4}; p3 = {p3x, p3y};\n                        if (check_rect(p1, p2, p3, p4)) return true;\n                    }\n                }\n            }\n            // Case B: p2 on anti diag, p4 on main diag\n            for (int x2 : diag2[d2_idx]) {\n                if (x2 == px) continue;\n                int y2 = py - (x2 - px);\n                for (int x4 : diag1[d1_idx]) {\n                    if (x4 == px) continue;\n                    int y4 = py + (x4 - px);\n                    int p3x = x2 + x4 - px;\n                    int p3y = y2 + y4 - py;\n                    if (p3x < 0 || p3x >= N || p3y < 0 || p3y >= N) continue;\n                    if (has_dot[p3x][p3y]) {\n                        p2 = {x2, y2}; p4 = {x4, y4}; p3 = {p3x, p3y};\n                        if (check_rect(p1, p2, p3, p4)) return true;\n                    }\n                }\n            }\n            return false;\n        };\n\n        if (search()) {\n            mark_edges(p1.x, p1.y, p2.x, p2.y);\n            mark_edges(p2.x, p2.y, p3.x, p3.y);\n            mark_edges(p3.x, p3.y, p4.x, p4.y);\n            mark_edges(p4.x, p4.y, p1.x, p1.y);\n            add_dot(px, py);\n            result.push_back({p1, p2, p3, p4});\n        }\n    }\n\n    cout << result.size() << \"\\n\";\n    for (const auto& op : result) {\n        const auto& [p1, p2, p3, p4] = op;\n        cout << p1.x << \" \" << p1.y << \" \"\n             << p2.x << \" \" << p2.y << \" \"\n             << p3.x << \" \" << p3.y << \" \"\n             << p4.x << \" \" << p4.y << \"\\n\";\n    }\n\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cstring>\n\nusing namespace std;\n\nint f[100];\n\n// Global buffers to avoid reallocation overhead\nint q_buf[100];\nbool visited_buf[100];\nint adj[100][4];\n\nvoid init_adj() {\n    int dr[] = {-1, 1, 0, 0};\n    int dc[] = {0, 0, -1, 1};\n    for (int r = 0; r < 10; ++r) {\n        for (int c = 0; c < 10; ++c) {\n            int u = r * 10 + c;\n            int idx = 0;\n            for (int k = 0; k < 4; ++k) {\n                int nr = r + dr[k];\n                int nc = c + dc[k];\n                if (nr >= 0 && nr < 10 && nc >= 0 && nc < 10) {\n                    adj[u][idx++] = nr * 10 + nc;\n                } else {\n                    adj[u][idx++] = -1;\n                }\n            }\n        }\n    }\n}\n\n// Calculate sum of squares of connected component sizes\nint calc_score(const int grid[100]) {\n    memset(visited_buf, 0, sizeof(visited_buf));\n    int total_score = 0;\n    \n    for (int i = 0; i < 100; ++i) {\n        if (grid[i] != 0 && !visited_buf[i]) {\n            int flavor = grid[i];\n            int sz = 0;\n            int head = 0;\n            int tail = 0;\n            \n            q_buf[tail++] = i;\n            visited_buf[i] = true;\n            \n            while(head < tail){\n                int curr = q_buf[head++];\n                sz++;\n                for(int k=0; k<4; ++k){\n                    int nidx = adj[curr][k];\n                    if(nidx != -1 && !visited_buf[nidx] && grid[nidx] == flavor){\n                        visited_buf[nidx] = true;\n                        q_buf[tail++] = nidx;\n                    }\n                }\n            }\n            total_score += sz * sz;\n        }\n    }\n    return total_score;\n}\n\n// Apply tilt to grid. dir: 0=F, 1=B, 2=L, 3=R\nvoid tilt(const int src[100], int dst[100], int dir) {\n    memset(dst, 0, sizeof(int) * 100);\n    if (dir == 2) { // L\n        for (int r = 0; r < 10; ++r) {\n            int idx = 0;\n            for (int c = 0; c < 10; ++c) {\n                int val = src[r * 10 + c];\n                if (val != 0) dst[r * 10 + idx++] = val;\n            }\n        }\n    } else if (dir == 3) { // R\n        for (int r = 0; r < 10; ++r) {\n            int idx = 9;\n            for (int c = 9; c >= 0; --c) {\n                int val = src[r * 10 + c];\n                if (val != 0) dst[r * 10 + idx--] = val;\n            }\n        }\n    } else if (dir == 0) { // F\n        for (int c = 0; c < 10; ++c) {\n            int idx = 0;\n            for (int r = 0; r < 10; ++r) {\n                int val = src[r * 10 + c];\n                if (val != 0) dst[idx * 10 + c] = val, idx++;\n            }\n        }\n    } else if (dir == 1) { // B\n        for (int c = 0; c < 10; ++c) {\n            int idx = 9;\n            for (int r = 9; r >= 0; --r) {\n                int val = src[r * 10 + c];\n                if (val != 0) dst[idx * 10 + c] = val, idx--;\n            }\n        }\n    }\n}\n\n// Recursive evaluation function\n// k: number of steps (placements) to look ahead\n// f_idx: index of the next candy to place\ndouble evaluate(const int grid[100], int k, int f_idx) {\n    int empty_count = 0;\n    int empty_cells[100];\n    for(int i=0; i<100; ++i) if(grid[i]==0) empty_cells[empty_count++] = i;\n    \n    // Base cases: grid full or no more lookahead steps\n    if(empty_count == 0 || k == 0) return (double)calc_score(grid);\n    \n    double sum_max = 0.0;\n    // Safety check, though logic ensures this is within bounds\n    if (f_idx >= 100) return (double)calc_score(grid);\n    \n    int flavor = f[f_idx];\n    \n    // Buffers\n    int temp_grid[100];\n    int tilted[100];\n    \n    for(int i=0; i<empty_count; ++i) {\n        int p = empty_cells[i];\n        memcpy(temp_grid, grid, sizeof(int)*100);\n        temp_grid[p] = flavor;\n        \n        double max_val = -1.0;\n        // Try all 4 tilts for this placement and pick the best\n        for(int d=0; d<4; ++d) {\n            tilt(temp_grid, tilted, d);\n            double val = evaluate(tilted, k-1, f_idx+1);\n            if(val > max_val) max_val = val;\n        }\n        sum_max += max_val;\n    }\n    return sum_max / empty_count;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    init_adj();\n\n    for (int i = 0; i < 100; ++i) {\n        if (!(cin >> f[i])) return 0;\n    }\n\n    int grid[100] = {0};\n    int g_tilted[100];\n    int g_temp[100];\n    int dirs[] = {0, 1, 2, 3}; // F, B, L, R\n\n    for (int t = 0; t < 100; ++t) {\n        int p;\n        if (!(cin >> p)) break;\n\n        int count = 0;\n        for (int i = 0; i < 100; ++i) {\n            if (grid[i] == 0) {\n                count++;\n                if (count == p) {\n                    grid[i] = f[t];\n                    break;\n                }\n            }\n        }\n\n        // For the 100th candy (t=99), the grid is full.\n        if (t == 99) break;\n\n        int empty_count = 0;\n        for(int i=0; i<100; ++i) if(grid[i]==0) empty_count++;\n        if (empty_count == 0) { cout << 'F' << endl; continue; }\n\n        int best_dir = 0;\n        double best_val = -1.0;\n\n        // Adaptive lookahead depth\n        // If few empty cells, we can afford deeper lookahead (2 steps)\n        // Otherwise, 1 step lookahead is sufficient and faster.\n        int k = (empty_count <= 15) ? 2 : 1;\n\n        for (int d : dirs) {\n            tilt(grid, g_tilted, d);\n            \n            // Evaluate the state after tilt d\n            // We look ahead k steps starting from the next candy f[t+1]\n            double val = evaluate(g_tilted, k, t+1);\n            \n            if (val > best_val) {\n                best_val = val;\n                best_dir = d;\n            }\n        }\n\n        // Apply the best tilt\n        tilt(grid, g_temp, best_dir);\n        memcpy(grid, g_temp, sizeof(int) * 100);\n        \n        char out_c = (best_dir == 0 ? 'F' : (best_dir == 1 ? 'B' : (best_dir == 2 ? 'L' : 'R')));\n        cout << out_c << endl;\n    }\n\n    return 0;\n}","ahc016":"/*\n * Solution for AHC016\n * \n * Strategy:\n * 1. Adaptive N: Balances score ceiling (1/N) with robustness.\n *    N = max(10, min(60, 12 + 0.2*M + 20*epsilon)).\n *    Lower N gives higher score, higher N gives better distinguishability.\n * 2. Graph Selection:\n *    Generates a pool of random graphs and uses Farthest Point Sampling (FPS)\n *    based on sorted eigenvalues to select M maximally distinct graphs.\n *    This ensures the codebook is optimized for the specific (M, epsilon) test case.\n * 3. Decoding:\n *    Matches noisy query to the closest graph in the selected set using\n *    Euclidean distance on sorted eigenvalues.\n * 4. Optimization:\n *    Adjusts pool size K based on N to keep execution time within limits.\n *    Uses Eigen library for efficient eigenvalue computation.\n */\n\n#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <Eigen/Dense>\n\nusing namespace std;\n\n// Helper to compute sorted eigenvalues of a symmetric matrix\n// Returns vector of eigenvalues in ascending order\nvector<double> get_eigenvalues(const Eigen::MatrixXd& mat) {\n    // SelfAdjointEigenSolver is optimized for symmetric matrices.\n    // EigenvaluesOnly avoids computing eigenvectors, saving time.\n    Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> solver(mat, Eigen::EigenvaluesOnly);\n    const auto& evals = solver.eigenvalues();\n    return {evals.data(), evals.data() + evals.size()};\n}\n\n// Squared Euclidean distance between two vectors\ndouble dist_sq(const vector<double>& a, const vector<double>& b) {\n    double d = 0.0;\n    for (size_t i = 0; i < a.size(); ++i) {\n        double diff = a[i] - b[i];\n        d += diff * diff;\n    }\n    return d;\n}\n\nint main() {\n    // Fast I/O\n    cin.tie(nullptr);\n    ios::sync_with_stdio(false);\n\n    int M;\n    double eps;\n    if (!(cin >> M >> eps)) return 0;\n\n    // Adaptive N selection:\n    // We want to minimize N to maximize score (1/N), but keep N high enough to distinguish M graphs under noise eps.\n    // Heuristic derived from analysis:\n    // Base N=12.\n    // Increase with M (need more capacity to separate M items).\n    // Increase with eps (need more signal-to-noise ratio).\n    // Cap at 60 to avoid excessive time/low score ceiling, floor at 10 to keep robustness.\n    double n_val = 12.0 + 0.2 * M + 20.0 * eps;\n    int N = max(10, min(60, (int)ceil(n_val)));\n    \n    cout << N << \"\\n\";\n\n    // Seed RNG based on problem parameters to ensure variability across tests\n    unsigned int seed = static_cast<unsigned int>(M * 100000 + eps * 100000 + 123456);\n    mt19937 rng(seed);\n    uniform_real_distribution<double> dist_p(0.05, 0.95);\n    uniform_real_distribution<double> dist_coin(0.0, 1.0);\n\n    // Determine pool size K based on N to manage runtime\n    // Larger N -> O(N^3) is expensive -> reduce K.\n    // Smaller N -> O(N^3) is cheap -> increase K for better selection.\n    int K;\n    if (N <= 25) K = 3000;\n    else if (N <= 40) K = 1500;\n    else if (N <= 50) K = 800;\n    else K = 500;\n    \n    // Ensure K is sufficient to select M graphs\n    K = max(K, M + 100);\n\n    vector<string> pool_graphs;\n    pool_graphs.reserve(K);\n    vector<vector<double>> pool_evals;\n    pool_evals.reserve(K);\n\n    // Pre-allocate matrix to avoid repeated allocations\n    Eigen::MatrixXd mat(N, N);\n\n    for (int k = 0; k < K; ++k) {\n        double p = dist_p(rng); // Random density for this graph\n        mat.setZero();\n        \n        string s;\n        s.reserve(N * (N - 1) / 2);\n        \n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                if (dist_coin(rng) < p) {\n                    mat(i, j) = mat(j, i) = 1.0;\n                    s += '1';\n                } else {\n                    mat(i, j) = mat(j, i) = 0.0;\n                    s += '0';\n                }\n            }\n        }\n        \n        pool_graphs.push_back(s);\n        pool_evals.push_back(get_eigenvalues(mat));\n    }\n\n    // Farthest Point Sampling (FPS) to select M graphs\n    // This maximizes the minimum distance between any pair of selected graphs,\n    // reducing the chance of collision under noise.\n    vector<int> selected_indices;\n    selected_indices.reserve(M);\n    vector<bool> selected(K, false);\n    vector<double> min_dists(K, 1e18); // Minimum distance to the set of selected graphs\n\n    // 1. Pick first graph randomly\n    int start_idx = rng() % K;\n    selected_indices.push_back(start_idx);\n    selected[start_idx] = true;\n\n    // 2. Initialize distances to the first selected graph\n    const auto& first_evals = pool_evals[start_idx];\n    for (int k = 0; k < K; ++k) {\n        if (k == start_idx) continue;\n        min_dists[k] = dist_sq(pool_evals[k], first_evals);\n    }\n\n    // 3. Select remaining M-1 graphs\n    for (int m = 1; m < M; ++m) {\n        int best_idx = -1;\n        double best_val = -1.0;\n\n        // Find unselected graph that is farthest from the current set\n        for (int k = 0; k < K; ++k) {\n            if (selected[k]) continue;\n            if (min_dists[k] > best_val) {\n                best_val = min_dists[k];\n                best_idx = k;\n            }\n        }\n\n        if (best_idx != -1) {\n            selected_indices.push_back(best_idx);\n            selected[best_idx] = true;\n            \n            // Update min_dists for all unselected graphs\n            const auto& new_evals = pool_evals[best_idx];\n            for (int k = 0; k < K; ++k) {\n                if (selected[k]) continue;\n                double d = dist_sq(pool_evals[k], new_evals);\n                if (d < min_dists[k]) {\n                    min_dists[k] = d;\n                }\n            }\n        } else {\n            break; \n        }\n    }\n\n    // Output selected graphs\n    vector<vector<double>> stored_evals;\n    stored_evals.reserve(M);\n    for (int idx : selected_indices) {\n        stored_evals.push_back(pool_evals[idx]);\n        cout << pool_graphs[idx] << \"\\n\";\n    }\n    cout.flush();\n\n    // Process 100 queries\n    Eigen::MatrixXd h_mat(N, N);\n    \n    for (int q = 0; q < 100; ++q) {\n        string h;\n        cin >> h;\n        \n        h_mat.setZero();\n        int idx = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                if (h[idx] == '1') {\n                    h_mat(i, j) = h_mat(j, i) = 1.0;\n                }\n                idx++;\n            }\n        }\n\n        // Compute eigenvalues for the query graph\n        vector<double> h_evals = get_eigenvalues(h_mat);\n\n        int best_k = 0;\n        double min_dist_val = 1e18;\n\n        // Find the closest match in our selected set\n        for (int k = 0; k < M; ++k) {\n            double d = dist_sq(h_evals, stored_evals[k]);\n            if (d < min_dist_val) {\n                min_dist_val = d;\n                best_k = k;\n            }\n        }\n        \n        cout << best_k << \"\\n\";\n        cout.flush();\n    }\n\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\n#pragma GCC optimize(\"O3,unroll-loops\")\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n\n    struct Edge { int u, v; int w; };\n    vector<Edge> edges(M);\n    vector<vector<pair<int, int>>> adj(N);\n\n    for (int i = 0; i < M; ++i) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        --u; --v;\n        edges[i] = {u, v, w};\n        adj[u].emplace_back(v, i);\n        adj[v].emplace_back(u, i);\n    }\n    for (int i = 0; i < N; ++i) { int x, y; cin >> x >> y; }\n\n    // 1. Compute Weighted Edge Betweenness Centrality\n    // This serves as a highly accurate proxy for the increase in all-pairs shortest paths\n    // when an edge is removed.\n    vector<double> eb(M, 0.0);\n    vector<int> dist(N);\n    vector<double> sigma(N), delta(N);\n    vector<int> nodes(N);\n    iota(nodes.begin(), nodes.end(), 0);\n    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;\n    const int INF = 2e9;\n\n    for (int s = 0; s < N; ++s) {\n        fill(dist.begin(), dist.end(), INF);\n        dist[s] = 0;\n        pq.emplace(0, s);\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u]) continue;\n            for (auto [v, id] : adj[u]) {\n                if (dist[v] > d + edges[id].w) {\n                    dist[v] = d + edges[id].w;\n                    pq.emplace(dist[v], v);\n                }\n            }\n        }\n\n        sort(nodes.begin(), nodes.end(), [&](int a, int b) { return dist[a] < dist[b]; });\n\n        fill(sigma.begin(), sigma.end(), 0.0);\n        sigma[s] = 1.0;\n        for (int u : nodes) {\n            if (u == s) continue;\n            double s_u = 0.0;\n            for (auto [p, id] : adj[u]) {\n                if (dist[p] + edges[id].w == dist[u]) s_u += sigma[p];\n            }\n            sigma[u] = s_u;\n        }\n\n        fill(delta.begin(), delta.end(), 0.0);\n        for (auto it = nodes.rbegin(); it != nodes.rend(); ++it) {\n            int u = *it;\n            if (sigma[u] == 0.0) continue;\n            double contrib = (1.0 + delta[u]) / sigma[u];\n            for (auto [p, id] : adj[u]) {\n                if (dist[p] + edges[id].w == dist[u]) {\n                    double val = sigma[p] * contrib;\n                    delta[p] += val;\n                    eb[id] += val;\n                }\n            }\n        }\n    }\n\n    // Fast PRNG\n    uint64_t rng_state = 88172645463325252ULL;\n    auto fast_rand = [&]() {\n        rng_state ^= rng_state >> 7;\n        rng_state ^= rng_state << 17;\n        rng_state ^= rng_state >> 13;\n        return rng_state;\n    };\n\n    // 2. Greedy Assignment\n    vector<int> assign(M);\n    vector<double> day_sum(D, 0.0);\n    \n    vector<int> sorted_idx(M);\n    iota(sorted_idx.begin(), sorted_idx.end(), 0);\n    sort(sorted_idx.begin(), sorted_idx.end(), [&](int a, int b) { return eb[a] > eb[b]; });\n\n    for (int idx : sorted_idx) {\n        int best_d = 0;\n        double min_s = day_sum[0];\n        for (int d = 1; d < D; ++d) {\n            if (day_sum[d] < min_s) { min_s = day_sum[d]; best_d = d; }\n        }\n        assign[idx] = best_d;\n        day_sum[best_d] += eb[idx];\n    }\n\n    // Prepare for Focused Simulated Annealing\n    // Maintain day_edges lists and position tracking for O(1) swaps\n    vector<vector<int>> day_edges(D);\n    vector<int> pos_in_day(M);\n    for (int i = 0; i < M; ++i) {\n        int d = assign[i];\n        pos_in_day[i] = day_edges[d].size();\n        day_edges[d].push_back(i);\n    }\n\n    auto start = chrono::steady_clock::now();\n    const int MAX_ITER = 12000000;\n    double T = 1e9;\n    const double COOLING = pow(100.0 / 1e9, 1.0 / MAX_ITER);\n    int iter = 0;\n\n    while (iter < MAX_ITER) {\n        if ((iter & 0xFFFFFF) == 0) {\n            if (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start).count() > 5400) break;\n        }\n        iter++;\n\n        // Find days with maximum and minimum betweenness sums\n        int u_max = 0, u_min = 0;\n        double s_max = day_sum[0], s_min = day_sum[0];\n        for (int d = 1; d < D; ++d) {\n            if (day_sum[d] > s_max) { s_max = day_sum[d]; u_max = d; }\n            if (day_sum[d] < s_min) { s_min = day_sum[d]; u_min = d; }\n        }\n        if (u_max == u_min) break;\n\n        // Randomly pick one edge from max day and one from min day\n        int i = day_edges[u_max][fast_rand() % day_edges[u_max].size()];\n        int j = day_edges[u_min][fast_rand() % day_edges[u_min].size()];\n        \n        double wi = eb[i], wj = eb[j];\n        double su = day_sum[u_max], sv = day_sum[u_min];\n        double delta_val = wj - wi;\n        // Change in sum of squares objective: 2 * delta_val * (su - sv + delta_val)\n        // We use half the change for simplicity in SA acceptance\n        double change = delta_val * (su - sv + delta_val);\n\n        if (change < 0.0) {\n            day_sum[u_max] += delta_val;\n            day_sum[u_min] -= delta_val;\n            swap(assign[i], assign[j]);\n            \n            // Update structures in O(1)\n            int pi = pos_in_day[i], pj = pos_in_day[j];\n            swap(day_edges[u_max][pi], day_edges[u_min][pj]);\n            pos_in_day[day_edges[u_max][pi]] = pi;\n            pos_in_day[day_edges[u_min][pj]] = pj;\n        } else {\n            double prob = exp(-change / T);\n            if ((fast_rand() & 0x7FFFFF) / 8388608.0 < prob) {\n                day_sum[u_max] += delta_val;\n                day_sum[u_min] -= delta_val;\n                swap(assign[i], assign[j]);\n                \n                int pi = pos_in_day[i], pj = pos_in_day[j];\n                swap(day_edges[u_max][pi], day_edges[u_min][pj]);\n                pos_in_day[day_edges[u_max][pi]] = pi;\n                pos_in_day[day_edges[u_min][pj]] = pj;\n            }\n        }\n        T *= COOLING;\n    }\n\n    for (int i = 0; i < M; ++i) {\n        cout << assign[i] + 1 << (i == M - 1 ? \"\\n\" : \" \");\n    }\n\n    return 0;\n}","ahc019":"/*\n    Solution for AHC019\n    Heuristic approach:\n    1. Identify valid regions (intersection of silhouettes).\n    2. Greedily find large shared blocks by growing shapes in Config 1 and checking fit in Config 2.\n    3. Fill remaining silhouette requirements with 1x1 blocks (shared if possible).\n*/\n#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\n\nint D;\nbool F[2][14][14], R[2][14][14];\nbool Valid[2][14][14][14];\nbool Used[2][14][14][14];\nint Sol[2][14][14][14];\n\nstruct Pt { int x, y, z; };\nvector<array<array<int,3>,3>> Rots;\nvector<Pt> free_cells[2];\n\nvoid gen_rots() {\n    vector<array<int,3>> basis = {\n        {1,0,0}, {-1,0,0}, {0,1,0}, {0,-1,0}, {0,0,1}, {0,0,-1}\n    };\n    for(const auto& r1 : basis) {\n        for(const auto& r2 : basis) {\n            if(r1[0]*r2[0] + r1[1]*r2[1] + r1[2]*r2[2] != 0) continue;\n            for(const auto& r3 : basis) {\n                if(r1[0]*r3[0] + r1[1]*r3[1] + r1[2]*r3[2] != 0) continue;\n                if(r2[0]*r3[0] + r2[1]*r3[1] + r2[2]*r3[2] != 0) continue;\n                \n                int det = r1[0]*(r2[1]*r3[2] - r2[2]*r3[1])\n                        - r1[1]*(r2[0]*r3[2] - r2[2]*r3[0])\n                        + r1[2]*(r2[0]*r3[1] - r2[1]*r3[0]);\n                \n                if(det == 1) {\n                    array<array<int,3>,3> m;\n                    m[0] = r1; m[1] = r2; m[2] = r3;\n                    bool dup = false;\n                    for(const auto& exist : Rots) {\n                        if(exist == m) { dup = true; break; }\n                    }\n                    if(!dup) Rots.push_back(m);\n                }\n            }\n        }\n    }\n}\n\nstruct Placement {\n    int dx, dy, dz, rot_idx;\n};\n\nbool is_valid(int k, int x, int y, int z) {\n    return x >= 0 && x < D && y >= 0 && y < D && z >= 0 && z < D && Valid[k][x][y][z] && !Used[k][x][y][z];\n}\n\nvoid mark_used(int k, int x, int y, int z) {\n    Used[k][x][y][z] = true;\n    auto& list = free_cells[k];\n    for(int i=0; i<(int)list.size(); i++) {\n        if(list[i].x == x && list[i].y == y && list[i].z == z) {\n            list[i] = list.back();\n            list.pop_back();\n            break;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(0); cin.tie(0);\n    if(!(cin >> D)) return 0;\n    \n    string s;\n    for(int k=0; k<2; k++) {\n        for(int z=0; z<D; z++) {\n            cin >> s;\n            for(int x=0; x<D; x++) F[k][z][x] = (s[x] == '1');\n        }\n        for(int z=0; z<D; z++) {\n            cin >> s;\n            for(int y=0; y<D; y++) R[k][z][y] = (s[y] == '1');\n        }\n        for(int x=0; x<D; x++)\n            for(int y=0; y<D; y++)\n                for(int z=0; z<D; z++) {\n                    Valid[k][x][y][z] = F[k][z][x] && R[k][z][y];\n                    if(Valid[k][x][y][z]) {\n                        free_cells[k].push_back({x,y,z});\n                    }\n                    Used[k][x][y][z] = false;\n                    Sol[k][x][y][z] = 0;\n                }\n    }\n    \n    gen_rots();\n    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n    for(int k=0; k<2; k++) shuffle(free_cells[k].begin(), free_cells[k].end(), rng);\n    \n    int block_id = 1;\n    int max_iters = 20000;\n    \n    while(max_iters-- > 0) {\n        Pt seed = {-1,-1,-1};\n        for(const auto& p : free_cells[0]) {\n            if(!Used[0][p.x][p.y][p.z]) {\n                seed = p;\n                break;\n            }\n        }\n        if(seed.x == -1) break;\n        \n        if(free_cells[1].empty()) break;\n        \n        vector<Pt> shape;\n        shape.push_back({0,0,0});\n        \n        vector<Placement> valid_placements;\n        valid_placements.reserve(free_cells[1].size());\n        for(const auto& p : free_cells[1]) {\n            valid_placements.push_back({p.x, p.y, p.z, 0});\n        }\n        \n        if(valid_placements.empty()) break;\n        \n        int growth_limit = 50;\n        bool grew = true;\n        int dirs[6][3] = {{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}};\n        \n        while(grew && (int)shape.size() < growth_limit) {\n            grew = false;\n            vector<Pt> candidates;\n            \n            for(const auto& rel : shape) {\n                int ax = seed.x + rel.x;\n                int ay = seed.y + rel.y;\n                int az = seed.z + rel.z;\n                for(auto& d : dirs) {\n                    int nx = ax + d[0];\n                    int ny = ay + d[1];\n                    int nz = az + d[2];\n                    if(is_valid(0, nx, ny, nz)) {\n                        Pt rel_n = {nx - seed.x, ny - seed.y, nz - seed.z};\n                        bool in_shape = false;\n                        for(const auto& s : shape) {\n                            if(s.x == rel_n.x && s.y == rel_n.y && s.z == rel_n.z) {\n                                in_shape = true; break;\n                            }\n                        }\n                        if(!in_shape) candidates.push_back(rel_n);\n                    }\n                }\n            }\n            \n            sort(candidates.begin(), candidates.end(), [](const Pt& a, const Pt& b){\n                if(a.x != b.x) return a.x < b.x;\n                if(a.y != b.y) return a.y < b.y;\n                return a.z < b.z;\n            });\n            candidates.erase(unique(candidates.begin(), candidates.end(), [](const Pt& a, const Pt& b){\n                return a.x==b.x && a.y==b.y && a.z==b.z;\n            }), candidates.end());\n            \n            shuffle(candidates.begin(), candidates.end(), rng);\n            \n            for(const auto& cand : candidates) {\n                vector<Placement> next_placements;\n                next_placements.reserve(valid_placements.size());\n                \n                for(const auto& pl : valid_placements) {\n                    const auto& rot = Rots[pl.rot_idx];\n                    int rx = rot[0][0]*cand.x + rot[0][1]*cand.y + rot[0][2]*cand.z;\n                    int ry = rot[1][0]*cand.x + rot[1][1]*cand.y + rot[1][2]*cand.z;\n                    int rz = rot[2][0]*cand.x + rot[2][1]*cand.y + rot[2][2]*cand.z;\n                    \n                    int ax = pl.dx + rx;\n                    int ay = pl.dy + ry;\n                    int az = pl.dz + rz;\n                    \n                    if(is_valid(1, ax, ay, az)) {\n                        next_placements.push_back(pl);\n                    }\n                }\n                \n                if(!next_placements.empty()) {\n                    shape.push_back(cand);\n                    valid_placements = next_placements;\n                    grew = true;\n                    break;\n                }\n            }\n        }\n        \n        if(!shape.empty()) {\n            Placement chosen = valid_placements[rng() % valid_placements.size()];\n            const auto& rot = Rots[chosen.rot_idx];\n            \n            for(const auto& rel : shape) {\n                mark_used(0, seed.x + rel.x, seed.y + rel.y, seed.z + rel.z);\n                Sol[0][seed.x + rel.x][seed.y + rel.y][seed.z + rel.z] = block_id;\n            }\n            \n            for(const auto& rel : shape) {\n                int rx = rot[0][0]*rel.x + rot[0][1]*rel.y + rot[0][2]*rel.z;\n                int ry = rot[1][0]*rel.x + rot[1][1]*rel.y + rot[1][2]*rel.z;\n                int rz = rot[2][0]*rel.x + rot[2][1]*rel.y + rot[2][2]*rel.z;\n                int ax = chosen.dx + rx;\n                int ay = chosen.dy + ry;\n                int az = chosen.dz + rz;\n                mark_used(1, ax, ay, az);\n                Sol[1][ax][ay][az] = block_id;\n            }\n            \n            block_id++;\n        }\n    }\n    \n    // Cover silhouettes\n    auto cover = [&](int k) {\n        for(int z=0; z<D; z++) {\n            for(int x=0; x<D; x++) {\n                if(F[k][z][x]) {\n                    bool covered = false;\n                    for(int y=0; y<D; y++) if(Sol[k][x][y][z] != 0) { covered = true; break; }\n                    if(!covered) {\n                        int best_y = -1;\n                        for(int y=0; y<D; y++) if(Valid[k][x][y][z] && !Used[k][x][y][z]) { best_y = y; break; }\n                        if(best_y != -1) {\n                            int share_x=-1, share_y=-1, share_z=-1;\n                            int other = 1-k;\n                            for(const auto& p : free_cells[other]) if(!Used[other][p.x][p.y][p.z]) { share_x=p.x; share_y=p.y; share_z=p.z; break; }\n                            if(share_x != -1) {\n                                mark_used(k, x, best_y, z); Sol[k][x][best_y][z] = block_id;\n                                mark_used(other, share_x, share_y, share_z); Sol[other][share_x][share_y][share_z] = block_id;\n                                block_id++;\n                            } else {\n                                mark_used(k, x, best_y, z); Sol[k][x][best_y][z] = block_id;\n                                block_id++;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        for(int z=0; z<D; z++) {\n            for(int y=0; y<D; y++) {\n                if(R[k][z][y]) {\n                    bool covered = false;\n                    for(int x=0; x<D; x++) if(Sol[k][x][y][z] != 0) { covered = true; break; }\n                    if(!covered) {\n                        int best_x = -1;\n                        for(int x=0; x<D; x++) if(Valid[k][x][y][z] && !Used[k][x][y][z]) { best_x = x; break; }\n                        if(best_x != -1) {\n                            int share_x=-1, share_y=-1, share_z=-1;\n                            int other = 1-k;\n                            for(const auto& p : free_cells[other]) if(!Used[other][p.x][p.y][p.z]) { share_x=p.x; share_y=p.y; share_z=p.z; break; }\n                            if(share_x != -1) {\n                                mark_used(k, best_x, y, z); Sol[k][best_x][y][z] = block_id;\n                                mark_used(other, share_x, share_y, share_z); Sol[other][share_x][share_y][share_z] = block_id;\n                                block_id++;\n                            } else {\n                                mark_used(k, best_x, y, z); Sol[k][best_x][y][z] = block_id;\n                                block_id++;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    };\n    \n    cover(0);\n    cover(1);\n    \n    cout << block_id - 1 << \"\\n\";\n    for(int k=0; k<2; k++) {\n        bool first = true;\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(!first) cout << \" \";\n                    cout << Sol[k][x][y][z];\n                    first = false;\n                }\n            }\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <chrono>\n#include <iomanip>\n\nusing namespace std;\n\n// Global variables\nint N, M, K;\nstruct Point { int x, y; };\nvector<Point> pts;\nvector<Point> residents;\n\nstruct Edge { int u, v; int w; };\nvector<Edge> edges;\n\n// Precomputed data\nvector<vector<double>> dists; \nvector<vector<int>> sorted_vertices; \n\n// Graph\nvector<vector<pair<int, int>>> adj; \nvector<int> sorted_edge_indices;\n\n// State\nvector<int> active; \nvector<int> assignment; \nvector<double> resident_dist; \nvector<vector<int>> residents_at; \nvector<double> max_radius; \n\n// Helper for MST\nvector<int> parent;\nint find_set(int v) {\n    if (v == parent[v]) return v;\n    return parent[v] = find_set(parent[v]);\n}\nbool union_sets(int a, int b) {\n    a = find_set(a); b = find_set(b);\n    if (a != b) { parent[b] = a; return true; }\n    return false;\n}\n\n// Connectivity buffers\nvector<int> q_bfs;\nvector<int> vis_token;\nint current_token = 0;\nint active_count = 0;\n\n// Check connectivity of active nodes (assuming active[0] is true)\nbool is_connected() {\n    if (active_count <= 1) return true; \n    \n    current_token++;\n    q_bfs.clear();\n    q_bfs.push_back(0);\n    vis_token[0] = current_token;\n    int count = 1;\n    \n    int head = 0;\n    while(head < (int)q_bfs.size()){\n        int u = q_bfs[head++];\n        for(auto& edge : adj[u]){\n            int v = edge.first;\n            if(active[v] && vis_token[v] != current_token){\n                vis_token[v] = current_token;\n                count++;\n                q_bfs.push_back(v);\n            }\n        }\n    }\n    return count == active_count;\n}\n\nlong long compute_mst() {\n    for(int i=0; i<N; ++i) parent[i] = i;\n    long long cost = 0;\n    int edges_used = 0;\n    if (active_count <= 1) return 0;\n    \n    for (int idx : sorted_edge_indices) {\n        const auto& e = edges[idx];\n        if (active[e.u] && active[e.v]) {\n            if (union_sets(e.u, e.v)) {\n                cost += e.w;\n                edges_used++;\n                if (edges_used == active_count - 1) break;\n            }\n        }\n    }\n    if (edges_used < active_count - 1) return -1; \n    return cost;\n}\n\nvoid update_max_radius(int u) {\n    double m = 0.0;\n    for(int k : residents_at[u]){\n        if(resident_dist[k] > m) m = resident_dist[k];\n    }\n    max_radius[u] = m;\n}\n\n// Move resident k to new_u. Updates state.\n// Expects k to be in residents_at[old_u] (usually).\nvoid move_resident(int k, int old_u, int new_u) {\n    if (old_u == new_u) return;\n    \n    // Remove from old\n    auto& old_list = residents_at[old_u];\n    bool found = false;\n    for (size_t i = 0; i < old_list.size(); ++i) {\n        if (old_list[i] == k) {\n            old_list[i] = old_list.back();\n            old_list.pop_back();\n            found = true;\n            break;\n        }\n    }\n    // If not found, it means it was already removed (e.g. via swap or logic).\n    // We proceed to add to new.\n    \n    // Add to new\n    residents_at[new_u].push_back(k);\n    \n    // Update assignment and dist\n    assignment[k] = new_u;\n    resident_dist[k] = dists[new_u][k];\n    \n    // Update max radii\n    update_max_radius(old_u);\n    update_max_radius(new_u);\n}\n\n// Reverse move\nvoid move_resident_back(int k, int new_u, int old_u) {\n    if (old_u == new_u) return;\n\n    // Remove from new\n    auto& new_list = residents_at[new_u];\n    for (size_t i = 0; i < new_list.size(); ++i) {\n        if (new_list[i] == k) {\n            new_list[i] = new_list.back();\n            new_list.pop_back();\n            break;\n        }\n    }\n    \n    // Add to old\n    residents_at[old_u].push_back(k);\n    \n    // Update assignment\n    assignment[k] = old_u;\n    resident_dist[k] = dists[old_u][k];\n    \n    update_max_radius(new_u);\n    update_max_radius(old_u);\n}\n\n// Calculate radii cost\ndouble compute_radii_cost() {\n    double cost = 0.0;\n    for(int i=0; i<N; ++i){\n        if(active[i]){\n            int p = (int)ceil(max_radius[i]);\n            if (p < 0) p = 0;\n            if (p > 5000) p = 5000;\n            cost += (double)p * p;\n        }\n    }\n    return cost;\n}\n\nstruct MoveRecord {\n    int k;\n    int old_u;\n};\n\n// Buffer to avoid allocations\nvector<int> buffer_residents;\nvector<MoveRecord> history;\n\nint main() {\n    cin.tie(nullptr)->sync_with_stdio(false);\n    mt19937_64 rng(chrono::high_resolution_clock::now().time_since_epoch().count());\n\n    if (!(cin >> N >> M >> K)) return 0;\n\n    pts.resize(N);\n    for (int i = 0; i < N; ++i) cin >> pts[i].x >> pts[i].y;\n\n    edges.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> edges[i].u >> edges[i].v >> edges[i].w;\n        --edges[i].u; --edges[i].v;\n    }\n\n    residents.resize(K);\n    for (int i = 0; i < K; ++i) cin >> residents[i].x >> residents[i].y;\n\n    dists.assign(N, vector<double>(K));\n    for (int i = 0; i < N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            dists[i][k] = hypot(pts[i].x - residents[k].x, pts[i].y - residents[k].y);\n        }\n    }\n\n    sorted_vertices.assign(K, vector<int>(N));\n    for (int k = 0; k < K; ++k) {\n        iota(sorted_vertices[k].begin(), sorted_vertices[k].end(), 0);\n        sort(sorted_vertices[k].begin(), sorted_vertices[k].end(), [&](int a, int b) {\n            return dists[a][k] < dists[b][k];\n        });\n    }\n\n    adj.assign(N, vector<pair<int, int>>());\n    for (int i = 0; i < M; ++i) {\n        adj[edges[i].u].push_back({edges[i].v, i});\n        adj[edges[i].v].push_back({edges[i].u, i});\n    }\n\n    sorted_edge_indices.resize(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) {\n        return edges[a].w < edges[b].w;\n    });\n\n    active.assign(N, 1); \n    active_count = N;\n    \n    assignment.assign(K, 0);\n    resident_dist.assign(K, 0.0);\n    residents_at.assign(N, vector<int>());\n    max_radius.assign(N, 0.0);\n\n    for (int k = 0; k < K; ++k) {\n        int best_u = 0;\n        double best_d = dists[0][k];\n        for (int u = 1; u < N; ++u) {\n            if (dists[u][k] < best_d) {\n                best_d = dists[u][k];\n                best_u = u;\n            }\n        }\n        assignment[k] = best_u;\n        resident_dist[k] = best_d;\n        residents_at[best_u].push_back(k);\n    }\n    \n    for (int u = 0; u < N; ++u) {\n        update_max_radius(u);\n    }\n\n    parent.resize(N);\n    long long cur_S_mst = compute_mst();\n    double cur_S_radii = compute_radii_cost();\n    double cur_S = cur_S_mst + cur_S_radii;\n    double best_S = cur_S;\n    \n    vector<int> best_active = active;\n\n    q_bfs.reserve(N);\n    vis_token.assign(N, 0);\n    \n    // SA Parameters\n    double temp = 1e6; \n    auto start_time = chrono::steady_clock::now();\n    \n    history.reserve(K);\n    buffer_residents.reserve(K);\n\n    uniform_int_distribution<int> dist_u(1, N-1); \n    uniform_real_distribution<double> dist_01(0.0, 1.0);\n\n    while (true) {\n        double elapsed = chrono::duration_cast<chrono::duration<double>>(chrono::steady_clock::now() - start_time).count();\n        if (elapsed > 1.90) break;\n\n        int u = dist_u(rng);\n        bool was_active = (active[u] == 1);\n        bool accepted = false;\n\n        history.clear();\n\n        if (was_active) {\n            // Try Remove u\n            active[u] = 0;\n            active_count--;\n            \n            if (!is_connected()) {\n                active[u] = 1;\n                active_count++;\n                continue;\n            }\n            \n            // Copy residents to move\n            buffer_residents = residents_at[u];\n            \n            bool possible = true;\n            \n            for (int k : buffer_residents) {\n                int best_v = -1;\n                double best_d = 1e18;\n                \n                const auto& cands = sorted_vertices[k];\n                for (int v : cands) {\n                    if (active[v]) { \n                        best_v = v;\n                        best_d = dists[v][k];\n                        break;\n                    }\n                }\n                \n                if (best_v == -1 || best_d > 5000.0 + 1e-7) {\n                    possible = false;\n                    break;\n                }\n                \n                move_resident(k, u, best_v);\n                history.push_back({k, u});\n            }\n            \n            if (possible) {\n                long long new_mst = compute_mst();\n                if (new_mst != -1) {\n                    double new_radii = compute_radii_cost();\n                    double new_S = new_mst + new_radii;\n                    double delta = new_S - cur_S;\n                    bool accept_move = false;\n                    if (delta < 0) accept_move = true;\n                    else {\n                        if (delta < 50.0 * temp) { \n                            if (dist_01(rng) < exp(-delta / temp)) accept_move = true;\n                        }\n                    }\n\n                    if (accept_move) {\n                        accepted = true;\n                        cur_S = new_S;\n                        cur_S_mst = new_mst;\n                        cur_S_radii = new_radii;\n                        if (new_S < best_S) {\n                            best_S = new_S;\n                            best_active = active;\n                        }\n                    }\n                }\n            }\n\n            if (!accepted) {\n                // Rollback\n                for (auto it = history.rbegin(); it != history.rend(); ++it) {\n                    int k = it->k;\n                    int current_u = assignment[k];\n                    move_resident_back(k, current_u, u);\n                }\n                \n                active[u] = 1;\n                active_count++;\n            }\n\n        } else {\n            // Try Add u\n            \n            // Pruning: Check if u can improve any resident's distance\n            bool improves = false;\n            for(int k=0; k<K; ++k) {\n                if(dists[u][k] < resident_dist[k]) {\n                    improves = true;\n                    break;\n                }\n            }\n            \n            if (!improves) {\n                continue; \n            }\n\n            active[u] = 1;\n            active_count++;\n            \n            for(int k=0; k<K; ++k) {\n                if(dists[u][k] < resident_dist[k]) {\n                    int old_u = assignment[k];\n                    move_resident(k, old_u, u);\n                    history.push_back({k, old_u});\n                }\n            }\n            \n            long long new_mst = compute_mst();\n            if (new_mst != -1) {\n                double new_radii = compute_radii_cost();\n                double new_S = new_mst + new_radii;\n                double delta = new_S - cur_S;\n                \n                bool accept_move = false;\n                if (delta < 0) accept_move = true;\n                else {\n                    if (delta < 50.0 * temp) {\n                        if (dist_01(rng) < exp(-delta / temp)) accept_move = true;\n                    }\n                }\n\n                if (accept_move) {\n                    accepted = true;\n                    cur_S = new_S;\n                    cur_S_mst = new_mst;\n                    cur_S_radii = new_radii;\n                    if (new_S < best_S) {\n                        best_S = new_S;\n                        best_active = active;\n                    }\n                }\n            }\n            \n            if (!accepted) {\n                for (auto it = history.rbegin(); it != history.rend(); ++it) {\n                    int k = it->k;\n                    int old_u = it->old_u;\n                    int current_u = assignment[k];\n                    move_resident_back(k, current_u, old_u);\n                }\n                active[u] = 0;\n                active_count--;\n            }\n        }\n        \n        temp *= 0.99995; \n        if (temp < 1e-9) temp = 1e-9;\n    }\n\n    // Restore best state\n    active = best_active;\n    active_count = 0;\n    for(int x : active) if(x) active_count++;\n    \n    for(int i=0; i<N; ++i) residents_at[i].clear();\n    \n    for (int k = 0; k < K; ++k) {\n        int best_u = -1;\n        double best_d = 1e18;\n        const auto& cands = sorted_vertices[k];\n        for (int v : cands) {\n            if (active[v]) {\n                best_u = v;\n                best_d = dists[v][k];\n                break;\n            }\n        }\n        assignment[k] = best_u;\n        resident_dist[k] = best_d;\n        residents_at[best_u].push_back(k);\n    }\n    for (int u = 0; u < N; ++u) update_max_radius(u);\n\n    for(int i=0; i<N; ++i) parent[i] = i;\n    vector<int> edge_used(M, 0);\n    \n    for (int idx : sorted_edge_indices) {\n        const auto& e = edges[idx];\n        if (active[e.u] && active[e.v]) {\n            if (union_sets(e.u, e.v)) {\n                edge_used[idx] = 1;\n            }\n        }\n    }\n    \n    cout << fixed << setprecision(0);\n    for (int i = 0; i < N; ++i) {\n        int p = 0;\n        if (active[i]) {\n            p = (int)ceil(max_radius[i]);\n            if (p < 0) p = 0;\n            if (p > 5000) p = 5000;\n        }\n        cout << p << (i == N-1 ? \"\" : \" \");\n    }\n    cout << \"\\n\";\n    \n    for (int i = 0; i < M; ++i) {\n        cout << edge_used[i] << (i == M-1 ? \"\" : \" \");\n    }\n    cout << \"\\n\";\n\n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <chrono>\n#include <random>\n#include <utility>\n\nusing namespace std;\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 30;\n    const int TOTAL = N * (N + 1) / 2;\n    vector<int> grid(TOTAL);\n    for (int i = 0; i < TOTAL; ++i) cin >> grid[i];\n\n    // Precompute (x, y) coordinates for each index\n    vector<int> x_coord(TOTAL), y_coord(TOTAL);\n    int idx = 0;\n    for (int x = 0; x < N; ++x)\n        for (int y = 0; y <= x; ++y)\n            x_coord[idx] = x, y_coord[idx] = y, idx++;\n\n    // Precompute children indices for O(1) access\n    vector<pair<int, int>> children(TOTAL, {-1, -1});\n    for (int i = 0; i < TOTAL; ++i) {\n        int x = x_coord[i], y = y_coord[i];\n        if (x + 1 < N) {\n            children[i] = {(x + 1) * (x + 2) / 2 + y, (x + 1) * (x + 2) / 2 + y + 1};\n        }\n    }\n\n    vector<pair<int, int>> best_ops;\n    best_ops.reserve(5000);\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    auto start = chrono::high_resolution_clock::now();\n\n    int trial = 0;\n    const int MAX_TRIALS = 5000;\n    \n    while (trial < MAX_TRIALS) {\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start).count() > 1850) break;\n\n        vector<int> g = grid;\n        vector<pair<int, int>> ops;\n        ops.reserve(5000);\n\n        // Strategy selection: 0=Baseline, 1=Value-Desc, 2+=Random\n        int strategy = (trial == 0) ? 0 : (rng() % 10 < 2 ? 1 : 2);\n\n        for (int x = N - 2; x >= 0; --x) {\n            int start_idx = x * (x + 1) / 2;\n            int count = x + 1;\n            int tier_nodes[30]; // Max nodes in a tier is 30\n            for (int i = 0; i < count; ++i) tier_nodes[i] = start_idx + i;\n\n            if (strategy == 1) {\n                // Sort by initial value descending: larger values sift down first\n                sort(tier_nodes, tier_nodes + count, [&](int a, int b) {\n                    return grid[a] > grid[b];\n                });\n            } else if (strategy >= 2) {\n                shuffle(tier_nodes, tier_nodes + count, rng);\n            }\n\n            for (int i = 0; i < count; ++i) {\n                int curr = tier_nodes[i];\n                while (true) {\n                    auto [c1, c2] = children[curr];\n                    if (c1 == -1) break; // Leaf node\n                    \n                    int target = (g[c1] < g[c2]) ? c1 : c2;\n                    if (g[curr] > g[target]) {\n                        swap(g[curr], g[target]);\n                        ops.emplace_back(curr, target);\n                        curr = target;\n                    } else {\n                        break;\n                    }\n                }\n            }\n        }\n\n        // Keep the sequence with the fewest operations\n        if ((best_ops.empty() || ops.size() < best_ops.size()) && ops.size() <= 9950) {\n            best_ops = move(ops);\n        }\n        trial++;\n    }\n\n    // Output results\n    cout << best_ops.size() << \"\\n\";\n    for (const auto& op : best_ops) {\n        cout << x_coord[op.first] << \" \" << y_coord[op.first] << \" \"\n             << x_coord[op.second] << \" \" << y_coord[op.second] << \"\\n\";\n    }\n\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\n#include <cmath>\nusing namespace std;\n\n// Global variables for grid and configuration\nint D, N;\nint grid[12][12]; // 0: empty, -1: obstacle, -2: entrance, -3: blocked (temp), >0: container (id+1)\nint er, ec; // Entrance coordinates\nint dr[4] = {-1, 1, 0, 0};\nint dc[4] = {0, 0, -1, 1};\npair<int, int> placed[100]; // Maps container ID to its position\n\n// Check if coordinates are within grid bounds\nbool valid(int r, int c) {\n    return r >= 0 && r < D && c >= 0 && c < D;\n}\n\n// BFS to count reachable empty cells from entrance\n// Traversable cells: 0 (Empty) and -2 (Entrance)\n// Non-traversable: -1 (Obstacle), -3 (Blocked), >0 (Container)\nint count_reachable_empty() {\n    int count = 0;\n    bool vis[12][12] = {};\n    queue<pair<int, int>> q;\n    q.push({er, ec});\n    vis[er][ec] = true;\n    \n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        if (grid[r][c] == 0) count++;\n        \n        for (int i = 0; i < 4; i++) {\n            int nr = r + dr[i], nc = c + dc[i];\n            if (valid(nr, nc) && !vis[nr][nc]) {\n                if (grid[nr][nc] == 0 || grid[nr][nc] == -2) {\n                    vis[nr][nc] = true;\n                    q.push({nr, nc});\n                }\n            }\n        }\n    }\n    return count;\n}\n\nint main() {\n    // Optimize I/O operations\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> D >> N)) return 0;\n    er = 0; ec = (D - 1) / 2;\n    \n    // Initialize grid\n    memset(grid, 0, sizeof(grid));\n    grid[er][ec] = -2; // Mark entrance\n    \n    for (int i = 0; i < N; i++) {\n        int r, c; cin >> r >> c;\n        grid[r][c] = -1; // Mark obstacle\n    }\n\n    int M = D * D - 1 - N; // Total containers to place\n\n    // Placement Phase\n    for (int d = 0; d < M; d++) {\n        int t; cin >> t;\n\n        // 1. Find Reachable Empty Squares (R) and their distances from entrance\n        vector<pair<int, int>> R;\n        vector<vector<int>> dist(D, vector<int>(D, -1));\n        bool vis[12][12] = {};\n        queue<pair<int, int>> q;\n        q.push({er, ec});\n        vis[er][ec] = true;\n        dist[er][ec] = 0;\n\n        while(!q.empty()){\n            auto [r, c] = q.front(); q.pop();\n            if(grid[r][c] == 0) R.push_back({r, c});\n            \n            for(int i=0; i<4; ++i){\n                int nr = r + dr[i], nc = c + dc[i];\n                if(valid(nr, nc) && !vis[nr][nc]){\n                    if(grid[nr][nc] == 0 || grid[nr][nc] == -2){\n                        vis[nr][nc] = true;\n                        dist[nr][nc] = dist[r][c] + 1;\n                        q.push({nr, nc});\n                    }\n                }\n            }\n        }\n\n        int total_empty = R.size();\n        \n        struct Candidate {\n            int r, c, dist, openness;\n        };\n        vector<Candidate> safe_candidates;\n        vector<Candidate> all_candidates;\n        safe_candidates.reserve(R.size());\n        all_candidates.reserve(R.size());\n\n        // Evaluate each reachable empty square\n        for(auto [r, c] : R){\n            // Calculate openness: number of adjacent empty squares\n            int en = 0;\n            for(int i=0; i<4; ++i){\n                int nr = r + dr[i], nc = c + dc[i];\n                if(valid(nr, nc) && grid[nr][nc] == 0) en++;\n            }\n            \n            Candidate cand = {r, c, dist[r][c], en};\n            all_candidates.push_back(cand);\n\n            // Safety Check: Does placing a container here disconnect other empty squares from the entrance?\n            grid[r][c] = -3; // Temporarily block\n            int reachable = count_reachable_empty();\n            grid[r][c] = 0; // Restore\n            \n            // If reachable count is exactly total_empty - 1, it's safe (didn't disconnect anything else)\n            if(reachable == total_empty - 1) {\n                safe_candidates.push_back(cand);\n            }\n        }\n        \n        // Use safe candidates if available. Fallback to all reachable if graph is highly constrained.\n        const vector<Candidate>& candidates = safe_candidates.empty() ? all_candidates : safe_candidates;\n        \n        // Sort candidates: prioritize closeness to entrance, then openness\n        vector<Candidate> sorted_candidates = candidates;\n        sort(sorted_candidates.begin(), sorted_candidates.end(), [](const Candidate& a, const Candidate& b){\n            if(a.dist != b.dist) return a.dist < b.dist;\n            return a.openness > b.openness;\n        });\n        \n        // Map container ID t to an index using a power function.\n        // This aggressively pushes small IDs (retrieved early) to the absolute best spots,\n        // and large IDs to the deepest/tightest spots.\n        int idx = 0;\n        if(sorted_candidates.size() > 1 && M > 1){\n            double ratio = (double)t / (M - 1);\n            double biased_ratio = pow(ratio, 0.5);\n            idx = (int)(biased_ratio * (sorted_candidates.size() - 1));\n        }\n        idx = max(0, min(idx, (int)sorted_candidates.size() - 1));\n        \n        auto chosen = sorted_candidates[idx];\n        grid[chosen.r][chosen.c] = t + 1;\n        placed[t] = {chosen.r, chosen.c};\n        cout << chosen.r << \" \" << chosen.c << \"\\n\" << flush;\n    }\n\n    // Retrieval Phase\n    // Strategy: 1-step lookahead. For each retrievable container, simulate removing it\n    // and check the smallest ID that would become retrievable next.\n    // Score = current_id + next_smallest_id. Pick the one with the lowest score.\n    vector<bool> retrieved(M, false);\n    for(int k=0; k<M; ++k){\n        // Find all empty squares reachable from the entrance\n        bool vis[12][12] = {};\n        queue<pair<int, int>> q;\n        q.push({er, ec});\n        vis[er][ec] = true;\n        vector<pair<int, int>> R;\n        while(!q.empty()){\n            auto [r, c] = q.front(); q.pop();\n            if(grid[r][c] == 0) R.push_back({r, c});\n            for(int i=0; i<4; ++i){\n                int nr = r + dr[i], nc = c + dc[i];\n                if(valid(nr, nc) && !vis[nr][nc]){\n                    if(grid[nr][nc] == 0 || grid[nr][nc] == -2){\n                        vis[nr][nc] = true;\n                        q.push({nr, nc});\n                    }\n                }\n            }\n        }\n        \n        // Mark reachable empty cells for fast lookup\n        bool in_R[12][12] = {};\n        for(auto [rr, cc] : R) in_R[rr][cc] = true;\n        \n        // Find currently retrievable containers\n        vector<int> S;\n        bool seen[100] = {};\n        \n        auto check = [&](int r, int c){\n            if(valid(r, c) && grid[r][c] > 0){\n                int id = grid[r][c] - 1;\n                if(!retrieved[id] && !seen[id]){\n                    seen[id] = true;\n                    S.push_back(id);\n                }\n            }\n        };\n        \n        for(int i=0; i<4; ++i) check(er+dr[i], ec+dc[i]);\n        for(auto [r, c] : R){\n            for(int i=0; i<4; ++i) check(r+dr[i], c+dc[i]);\n        }\n        \n        int best_x = -1;\n        double best_sc = 1e18;\n        \n        for(int x : S){\n            int r = placed[x].first, c = placed[x].second;\n            grid[r][c] = 0; // Temporarily remove\n            \n            // Find the smallest ID that would become retrievable next\n            int next_min = 1e9;\n            bool vis2[12][12] = {};\n            queue<pair<int, int>> q2;\n            q2.push({er, ec});\n            vis2[er][ec] = true;\n            \n            while(!q2.empty()){\n                auto [cr, cc] = q2.front(); q2.pop();\n                for(int i=0; i<4; ++i){\n                    int nr = cr + dr[i], nc = cc + dc[i];\n                    if(valid(nr, nc) && !vis2[nr][nc]){\n                        if(grid[nr][nc] == 0 || grid[nr][nc] == -2){\n                            vis2[nr][nc] = true;\n                            q2.push({nr, nc});\n                        } else if(grid[nr][nc] > 0){\n                            int id = grid[nr][nc] - 1;\n                            if(!retrieved[id] && id < next_min){\n                                next_min = id;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            double sc = x + (next_min == 1e9 ? 0 : next_min);\n            if(sc < best_sc || (abs(sc - best_sc) < 1e-9 && x < best_x)){\n                best_sc = sc;\n                best_x = x;\n            }\n            \n            grid[r][c] = x + 1; // Restore\n        }\n        \n        if(best_x != -1){\n            retrieved[best_x] = true;\n            auto [r, c] = placed[best_x];\n            grid[r][c] = 0; // Free up the square\n            cout << r << \" \" << c << \"\\n\" << flush;\n        }\n    }\n\n    return 0;\n}","ahc024":"/*\n    Problem: AHC024 - Map Reduction\n    Goal: Maximize number of 0 cells (E) while preserving:\n    1. Connectivity of all colors (including 0).\n    2. Adjacency relationships between all colors.\n    \n    Strategy:\n    - Start with the full map.\n    - Greedily remove cells (turn to 0) to increase E.\n    - Only consider cells adjacent to existing 0s (to maintain 0-connectivity).\n    - Use a Priority Queue to prioritize removing \"safe\" cells first.\n      Safety is defined by the number of same-color neighbors (degree in ward graph).\n      - Degree 1 (Leaf): Safe to remove (won't disconnect ward).\n      - Degree >= 2: Requires BFS connectivity check.\n    - Strictly maintain a 'contacts' matrix to enforce adjacency constraints.\n*/\n#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\n\nconst int MAXN = 54; // 50 + padding\nconst int MAXM = 105; // 100 + buffer\n\nint grid[MAXN][MAXN];\nint contacts[MAXM][MAXM] = {0};\nbool adj_target[MAXM][MAXM] = {false};\nint cnt[MAXM] = {0};\nint n, m;\n\nstruct Candidate {\n    int score; // Number of same-color neighbors\n    int r, c;\n    // Min-heap: lower score (fewer neighbors) is better/safer\n    bool operator>(const Candidate& other) const {\n        return score > other.score;\n    }\n};\n\n// Check if 'color' remains connected after removing (skip_r, skip_c)\nbool check_connect(int color, int skip_r, int skip_c) {\n    int target = cnt[color] - 1;\n    if (target <= 1) return true; // Single cell or empty is trivially connected\n    \n    int sr = -1, sc = -1;\n    int same_nb = 0;\n    const int dr[] = {0, 1, 0, -1};\n    const int dc[] = {1, 0, -1, 0};\n    \n    // Find a neighbor of (skip_r, skip_c) that has 'color' to start BFS\n    for (int k = 0; k < 4; ++k) {\n        int nr = skip_r + dr[k], nc = skip_c + dc[k];\n        if (grid[nr][nc] == color) {\n            same_nb++;\n            sr = nr; sc = nc;\n        }\n    }\n    \n    // If the cell to be removed is a leaf (degree 1), removing it is safe.\n    if (same_nb <= 1) return true;\n    \n    // If degree >= 2, it might be a cut vertex. BFS required.\n    if (sr == -1) return false; \n\n    static int q[MAXN * MAXN][2];\n    static bool vis[MAXN][MAXN];\n    memset(vis, 0, sizeof(vis));\n    \n    int head = 0, tail = 0;\n    q[tail][0] = sr; q[tail][1] = sc; tail++;\n    vis[sr][sc] = true;\n    int count = 0; \n    \n    while(head < tail) {\n        int cr = q[head][0], cc = q[head][1]; head++;\n        count++;\n        if (count == target) return true; \n        \n        for (int k = 0; k < 4; ++k) {\n            int nr = cr + dr[k], nc = cc + dc[k];\n            // Valid if color matches, not the skipped cell, and not visited\n            if (grid[nr][nc] == color && !(nr == skip_r && nc == skip_c) && !vis[nr][nc]) {\n                vis[nr][nc] = true;\n                q[tail][0] = nr; q[tail][1] = nc; tail++;\n            }\n        }\n    }\n    return count == target;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    auto start_time = chrono::steady_clock::now();\n\n    if (!(cin >> n >> m)) return 0;\n    \n    // Initialize grid with padding of 0s\n    memset(grid, 0, sizeof(grid));\n    for (int i = 1; i <= n; ++i)\n        for (int j = 1; j <= n; ++j)\n            cin >> grid[i][j];\n\n    const int dr[] = {0, 1, 0, -1};\n    const int dc[] = {1, 0, -1, 0};\n\n    // Compute initial contacts and target adjacencies\n    for (int i = 0; i <= n + 1; ++i) {\n        for (int j = 0; j <= n + 1; ++j) {\n            int dirs[2][2] = {{0, 1}, {1, 0}};\n            for(auto& d : dirs) {\n                int ni = i + d[0], nj = j + d[1];\n                if (ni <= n + 1 && nj <= n + 1) {\n                    int u = grid[i][j], v = grid[ni][nj];\n                    if (u != v) {\n                        if (u > v) swap(u, v);\n                        contacts[u][v]++;\n                        adj_target[u][v] = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // Count cells per color\n    for (int i = 1; i <= n; ++i)\n        for (int j = 1; j <= n; ++j)\n            if (grid[i][j] > 0) cnt[grid[i][j]]++;\n\n    // Priority Queue for candidates: {score, r, c}\n    priority_queue<Candidate, vector<Candidate>, greater<Candidate>> pq;\n    \n    // Initial candidates: cells adjacent to 0\n    for (int i = 1; i <= n; ++i) {\n        for (int j = 1; j <= n; ++j) {\n            if (grid[i][j] > 0) {\n                bool adj0 = false;\n                int same_nb = 0;\n                for (int k = 0; k < 4; ++k) {\n                    int ni = i + dr[k], nj = j + dc[k];\n                    if (grid[ni][nj] == 0) adj0 = true;\n                    if (grid[ni][nj] == grid[i][j]) same_nb++;\n                }\n                if (adj0) {\n                    pq.push({same_nb, i, j});\n                }\n            }\n        }\n    }\n\n    vector<pair<int, int>> dec_changes, inc_changes;\n    dec_changes.reserve(8);\n    inc_changes.reserve(8);\n\n    while (!pq.empty()) {\n        // Time limit check (2.0s limit, exit slightly earlier to be safe)\n        if (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() > 1850) break;\n\n        Candidate cand = pq.top();\n        pq.pop();\n\n        int r = cand.r, c = cand.c;\n        int col = grid[r][c];\n\n        if (col == 0) continue; // Already removed\n        \n        if (cnt[col] <= 1) continue; // Cannot remove last cell of a ward\n\n        // Calculate current degree in ward graph\n        int current_same_nb = 0;\n        for (int k = 0; k < 4; ++k) {\n            int nr = r + dr[k], nc = c + dc[k];\n            if (grid[nr][nc] == col) current_same_nb++;\n        }\n\n        // Connectivity Check\n        // Optimization: Leaf removal is always safe for connectivity\n        if (current_same_nb > 1) {\n            if (!check_connect(col, r, c)) continue;\n        }\n\n        // Adjacency Constraint Check\n        dec_changes.clear();\n        inc_changes.clear();\n        bool fail = false;\n\n        for (int k = 0; k < 4; ++k) {\n            int nr = r + dr[k], nc = c + dc[k];\n            int x = grid[nr][nc];\n            \n            if (x == col) {\n                // Case 1: Neighbor is same color.\n                // Edge (col, col) -> (0, col)\n                // (col, col) was not tracked. (0, col) is tracked.\n                int u = 0, v = col;\n                contacts[u][v]++;\n                inc_changes.push_back({u, v});\n                // Check if we created a forbidden adjacency with 0\n                if (contacts[u][v] == 1 && !adj_target[u][v]) {\n                    fail = true; break;\n                }\n            } else if (x == 0) {\n                // Case 2: Neighbor is 0.\n                // Edge (col, 0) -> (0, 0)\n                // (0, col) was tracked. (0, 0) is not.\n                int u = 0, v = col;\n                contacts[u][v]--;\n                dec_changes.push_back({u, v});\n                // Check if we broke a required adjacency with 0\n                if (contacts[u][v] == 0 && adj_target[u][v]) {\n                    fail = true; break;\n                }\n            } else {\n                // Case 3: Neighbor is different color x.\n                // Edge (col, x) -> (0, x)\n                \n                // Remove (col, x)\n                int u1 = min(col, x), v1 = max(col, x);\n                contacts[u1][v1]--;\n                dec_changes.push_back({u1, v1});\n                if (contacts[u1][v1] == 0 && adj_target[u1][v1]) {\n                    fail = true; break;\n                }\n                \n                // Add (0, x)\n                int u2 = 0, v2 = x;\n                contacts[u2][v2]++;\n                inc_changes.push_back({u2, v2});\n                if (contacts[u2][v2] == 1 && !adj_target[u2][v2]) {\n                    fail = true; break;\n                }\n            }\n        }\n\n        if (fail) {\n            // Rollback contacts\n            for (auto& p : inc_changes) contacts[p.first][p.second]--;\n            for (auto& p : dec_changes) contacts[p.first][p.second]++;\n            continue;\n        }\n\n        // All checks passed. Commit removal.\n        grid[r][c] = 0;\n        cnt[col]--;\n\n        // Add neighbors to PQ\n        // Neighbors that are not 0 are now adjacent to 0 (since (r,c) became 0).\n        // They might be new candidates or have updated scores.\n        for (int k = 0; k < 4; ++k) {\n            int nr = r + dr[k], nc = c + dc[k];\n            if (grid[nr][nc] != 0) {\n                int ncol = grid[nr][nc];\n                int same = 0;\n                for(int kk=0; kk<4; ++kk) {\n                    int nnr = nr + dr[kk], nnc = nc + dc[kk];\n                    if (grid[nnr][nnc] == ncol) same++;\n                }\n                pq.push({same, nr, nc});\n            }\n        }\n    }\n\n    // Output\n    for (int i = 1; i <= n; ++i) {\n        for (int j = 1; j <= n; ++j) {\n            cout << grid[i][j] << (j == n ? \"\\n\" : \" \");\n        }\n    }\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <string>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\n// Global array for Harmonic numbers\ndouble H[105];\n\n// Precompute Harmonic numbers H[k] = sum(1/i for i=1..k)\nvoid precompute_harmonic(int n) {\n    H[0] = 0.0;\n    for (int i = 1; i <= n; ++i) {\n        H[i] = H[i-1] + 1.0 / i;\n    }\n}\n\nint main() {\n    // Optimize I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, D, Q;\n    if (!(cin >> N >> D >> Q)) return 0;\n\n    // Precompute harmonic numbers for proxy weight calculation\n    precompute_harmonic(N);\n\n    // Permutation for sorting\n    vector<int> p(N);\n    iota(p.begin(), p.end(), 0);\n    // Accumulated scores (Dominance count)\n    vector<double> score(N, 0.0);\n\n    // Phase 1: Comb Sort (Fast convergence)\n    double gap = N;\n    while (gap > 1.0 && Q > 0) {\n        gap /= 1.3;\n        if (gap < 1.0) gap = 1.0;\n        int g = (int)gap;\n        \n        for (int i = 0; i < N - g && Q > 0; ++i) {\n            cout << \"1 1 \" << p[i] << \" \" << p[i+g] << \"\\n\";\n            cout.flush();\n            \n            string res;\n            cin >> res;\n            Q--;\n\n            // Update scores and order\n            // p[i] is Left, p[i+g] is Right\n            if (res == \"<\") { \n                // Left is lighter, Right is heavier. Swap to maintain heavy items at the start.\n                swap(p[i], p[i+g]);\n                // p[i] is now the heavier item\n                score[p[i]] += 1.0;\n                score[p[i+g]] -= 1.0;\n            } else if (res == \">\") {\n                // Left is heavier. No swap needed.\n                score[p[i]] += 1.0;\n                score[p[i+g]] -= 1.0;\n            } else {\n                score[p[i]] += 0.5;\n                score[p[i+g]] -= 0.5;\n            }\n        }\n    }\n\n    // Phase 2: Bubble Sort (Refinement with adjacent swaps)\n    while (Q > 0) {\n        for (int i = 0; i < N - 1 && Q > 0; ++i) {\n            cout << \"1 1 \" << p[i] << \" \" << p[i+1] << \"\\n\";\n            cout.flush();\n            \n            string res;\n            cin >> res;\n            Q--;\n\n            if (res == \"<\") {\n                swap(p[i], p[i+1]);\n                score[p[i]] += 1.0;\n                score[p[i+1]] -= 1.0;\n            } else if (res == \">\") {\n                score[p[i]] += 1.0;\n                score[p[i+1]] -= 1.0;\n            } else {\n                score[p[i]] += 0.5;\n                score[p[i+1]] -= 0.5;\n            }\n        }\n    }\n\n    // Sort original item indices by score descending (Heavy to Light)\n    // This determines the rank of each item\n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n    sort(items.begin(), items.end(), [&](int a, int b) {\n        return score[a] > score[b];\n    });\n\n    // Compute Proxy Weights based on Expected Value of Exponential Order Statistics\n    // If weights are Exp(lambda), the expected value of the k-th smallest is proportional to H_k.\n    // The expected value of the (N-r)-th smallest (which is the r-th largest, 0-indexed)\n    // is proportional to H_N - H_r.\n    // This proxy captures the heavy-tailed distribution effectively.\n    vector<double> proxy(N);\n    for (int r = 0; r < N; ++r) {\n        int item = items[r];\n        proxy[item] = H[N] - H[r];\n    }\n\n    // Initial Assignment (LPT - Longest Processing Time)\n    vector<int> assignment(N);\n    vector<double> bin_weights(D, 0.0);\n    vector<vector<int>> bins(D);\n\n    // Items are sorted heaviest first\n    for (int item : items) {\n        int best_d = 0;\n        double min_w = bin_weights[0];\n        for (int d = 1; d < D; ++d) {\n            if (bin_weights[d] < min_w) {\n                min_w = bin_weights[d];\n                best_d = d;\n            }\n        }\n        assignment[item] = best_d;\n        bin_weights[best_d] += proxy[item];\n        bins[best_d].push_back(item);\n    }\n\n    // Local Search (Steepest Descent)\n    auto start_time = chrono::high_resolution_clock::now();\n    double time_limit = 1.8; // Seconds\n\n    // Current cost (proxy for variance)\n    double current_cost = 0;\n    for (double w : bin_weights) current_cost += w * w;\n\n    double total_w = 0;\n    for (double w : bin_weights) total_w += w;\n    double mean_w = total_w / D;\n\n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > time_limit) break;\n\n        bool improved = false;\n        \n        // Best Move Candidate\n        int move_from = -1, move_to = -1, move_item = -1;\n        double min_move_delta = 0;\n\n        // Only try moving from heavier bins to lighter bins\n        for (int i = 0; i < D; ++i) {\n            if (bin_weights[i] <= mean_w) continue;\n            if (bins[i].empty()) continue;\n\n            for (int j = 0; j < D; ++j) {\n                if (i == j) continue;\n                if (bin_weights[j] >= mean_w) continue;\n\n                double diff_ij = bin_weights[i] - bin_weights[j];\n                \n                for (int u : bins[i]) {\n                    double w_u = proxy[u];\n                    // Moving u reduces Wi and increases Wj.\n                    // Improvement requires new Wi < old Wj + w_u (roughly)\n                    // Mathematically, delta < 0 iff w_u < diff_ij\n                    if (w_u < diff_ij) {\n                        double delta = 2.0 * w_u * (w_u - diff_ij);\n                        if (delta < min_move_delta) {\n                            min_move_delta = delta;\n                            move_from = i;\n                            move_to = j;\n                            move_item = u;\n                        }\n                    }\n                }\n            }\n        }\n\n        if (move_from != -1) {\n            // Execute Best Move\n            int u = move_item;\n            int i = move_from;\n            int j = move_to;\n            double w_u = proxy[u];\n\n            assignment[u] = j;\n            \n            // Remove u from bin i (O(1) using swap-with-back)\n            auto& vec_i = bins[i];\n            for(auto it = vec_i.begin(); it != vec_i.end(); ++it) {\n                if(*it == u) {\n                    *it = vec_i.back();\n                    vec_i.pop_back();\n                    break;\n                }\n            }\n            bins[j].push_back(u);\n            \n            bin_weights[i] -= w_u;\n            bin_weights[j] += w_u;\n            \n            current_cost += min_move_delta;\n            improved = true;\n            continue; \n        }\n\n        // Try Swaps\n        int swap_from = -1, swap_to = -1, swap_u = -1, swap_v = -1;\n        double min_swap_delta = 0;\n\n        for (int i = 0; i < D; ++i) {\n            if (bin_weights[i] <= mean_w) continue;\n            if (bins[i].empty()) continue;\n\n            for (int j = 0; j < D; ++j) {\n                if (i == j) continue;\n                if (bin_weights[j] >= mean_w) continue;\n\n                double diff_ij = bin_weights[i] - bin_weights[j];\n                \n                const auto& items_i = bins[i];\n                const auto& items_j = bins[j];\n\n                for (int u : items_i) {\n                    double w_u = proxy[u];\n                    for (int v : items_j) {\n                        double w_v = proxy[v];\n                        // We want to move weight from i to j, so w_u > w_v\n                        if (w_u > w_v) {\n                            double dw = w_u - w_v;\n                            // Improvement requires dw < diff_ij\n                            if (dw < diff_ij) {\n                                double delta = 2.0 * dw * (dw - diff_ij);\n                                if (delta < min_swap_delta) {\n                                    min_swap_delta = delta;\n                                    swap_from = i;\n                                    swap_to = j;\n                                    swap_u = u;\n                                    swap_v = v;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        if (swap_from != -1) {\n            // Execute Swap\n            int u = swap_u;\n            int v = swap_v;\n            int i = swap_from;\n            int j = swap_to;\n            double w_u = proxy[u];\n            double w_v = proxy[v];\n\n            assignment[u] = j;\n            assignment[v] = i;\n\n            // Swap in bins\n            // Remove u from i\n            auto& vec_i = bins[i];\n            for(auto it = vec_i.begin(); it != vec_i.end(); ++it) {\n                if(*it == u) {\n                    *it = vec_i.back();\n                    vec_i.pop_back();\n                    break;\n                }\n            }\n            vec_i.push_back(v);\n\n            // Remove v from j\n            auto& vec_j = bins[j];\n            for(auto it = vec_j.begin(); it != vec_j.end(); ++it) {\n                if(*it == v) {\n                    *it = vec_j.back();\n                    vec_j.pop_back();\n                    break;\n                }\n            }\n            vec_j.push_back(u);\n\n            bin_weights[i] = bin_weights[i] - w_u + w_v;\n            bin_weights[j] = bin_weights[j] - w_v + w_u;\n\n            current_cost += min_swap_delta;\n            improved = true;\n            continue;\n        }\n\n        if (!improved) break;\n    }\n\n    // Output final assignment\n    for (int i = 0; i < N; ++i) {\n        cout << assignment[i] << (i == N - 1 ? \"\" : \" \");\n    }\n    cout << \"\\n\";\n    cout.flush();\n\n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cstring>\n\nusing namespace std;\n\n// Constants matching problem constraints\nconst int MAX_N = 205;\nconst int MAX_M = 12;\n\nstruct State {\n    int n, m;\n    int stacks[MAX_M][MAX_N];\n    int stack_size[MAX_M];\n    int pos_stack[MAX_N];\n    int pos_idx[MAX_N];\n    long long energy;\n\n    void init(int n_in, int m_in, const vector<vector<int>>& input) {\n        n = n_in; m = m_in; energy = 0;\n        for(int i=0; i<m; ++i) {\n            stack_size[i] = (int)input[i].size();\n            for(int j=0; j<stack_size[i]; ++j) {\n                int box = input[i][j];\n                stacks[i][j] = box;\n                pos_stack[box] = i;\n                pos_idx[box] = j;\n            }\n        }\n    }\n    \n    // Fast copy using memory copy for arrays\n    void copy_from(const State& other) {\n        n = other.n; m = other.m; energy = other.energy;\n        for(int i=0; i<m; ++i) {\n            memcpy(stacks[i], other.stacks[i], sizeof(stacks[i]));\n            stack_size[i] = other.stack_size[i];\n        }\n        memcpy(pos_stack, other.pos_stack, sizeof(pos_stack));\n        memcpy(pos_idx, other.pos_idx, sizeof(pos_idx));\n    }\n\n    int get_top(int s) const {\n        if(stack_size[s] == 0) return n + 10000;\n        return stacks[s][stack_size[s]-1];\n    }\n};\n\n// Global storage for operations to output at the end\nvector<pair<int, int>> ops;\n\n// Simulation move: updates state without recording operations\nvoid sim_move(State& s, int box, int dest) {\n    int src = s.pos_stack[box];\n    int idx = s.pos_idx[box];\n    int cur_sz = s.stack_size[src];\n    if(src == -1 || idx < 0 || idx >= cur_sz || src == dest) return;\n\n    int count = cur_sz - idx;\n    s.energy += count + 1;\n\n    int dest_sz = s.stack_size[dest];\n    // Move boxes from src to dest\n    for(int k=0; k<count; ++k) {\n        int b = s.stacks[src][idx + k];\n        s.stacks[dest][dest_sz + k] = b;\n        s.pos_stack[b] = dest;\n        s.pos_idx[b] = dest_sz + k;\n    }\n    \n    s.stack_size[dest] += count;\n    s.stack_size[src] = idx;\n}\n\n// Simulation remove: updates state without recording operations\nvoid sim_remove(State& s, int box) {\n    int src = s.pos_stack[box];\n    int idx = s.pos_idx[box];\n    if(src == -1) return;\n    if(idx != s.stack_size[src] - 1) return; // Must be at top\n    \n    s.stack_size[src]--;\n    s.pos_stack[box] = -1;\n    s.pos_idx[box] = -1;\n}\n\n// Heuristic to evaluate a move destination\nint find_dest_heuristic(const State& s, int u, int src, int next_target) {\n    int best_dest = -1;\n    int best_score = -2000000000;\n    \n    for(int i=0; i<s.m; ++i) {\n        if(i == src) continue;\n        int top = s.get_top(i);\n        int score = 0;\n        \n        bool is_empty = (s.stack_size[i] == 0);\n        bool is_good = (!is_empty && top > u); // Good if top > u (decreasing order)\n        \n        if(is_empty) score += 2000000;\n        else if(is_good) score += 1000000;\n        else score -= 1000000;\n        \n        // Lookahead penalty: avoid covering near-future targets\n        for(int k=0; k<8; ++k) {\n            if(top == next_target + k) {\n                score -= (400000 - 40000 * k);\n                break;\n            }\n        }\n        \n        // Tie-breaking\n        if(is_good) score -= top; // Prefer smaller top to pack tightly\n        else if(!is_empty) score += top; // Prefer larger top to bury less critical numbers\n        \n        if(best_dest == -1 || score > best_score) {\n            best_dest = i;\n            best_score = score;\n        }\n    }\n    return best_dest;\n}\n\n// Actual move: updates state and records operation\nvoid apply_move(State& s, int box, int dest) {\n    int src = s.pos_stack[box];\n    int idx = s.pos_idx[box];\n    int cur_sz = s.stack_size[src];\n    if(src == -1 || idx < 0 || idx >= cur_sz || src == dest) return;\n\n    int count = cur_sz - idx;\n    s.energy += count + 1;\n    ops.push_back({box, dest + 1});\n\n    int dest_sz = s.stack_size[dest];\n    for(int k=0; k<count; ++k) {\n        int b = s.stacks[src][idx + k];\n        s.stacks[dest][dest_sz + k] = b;\n        s.pos_stack[b] = dest;\n        s.pos_idx[b] = dest_sz + k;\n    }\n    \n    s.stack_size[dest] += count;\n    s.stack_size[src] = idx;\n}\n\n// Actual remove: updates state and records operation\nvoid apply_remove(State& s, int box) {\n    int src = s.pos_stack[box];\n    int idx = s.pos_idx[box];\n    if(src == -1) return;\n    if(idx != s.stack_size[src] - 1) return;\n    \n    s.stack_size[src]--;\n    s.pos_stack[box] = -1;\n    s.pos_idx[box] = -1;\n    ops.push_back({box, 0});\n}\n\nint main() {\n    // Fast I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n, m;\n    if(!(cin >> n >> m)) return 0;\n    \n    vector<vector<int>> input_stacks(m);\n    for(int i=0; i<m; ++i) {\n        input_stacks[i].resize(n/m);\n        for(int j=0; j<n/m; ++j) {\n            cin >> input_stacks[i][j];\n        }\n    }\n\n    State S;\n    S.init(n, m, input_stacks);\n    \n    // Lookahead depth. 25 is a safe balance between quality and speed.\n    const int LOOKAHEAD = 25;\n\n    for(int v=1; v<=n; ++v) {\n        while(true) {\n            int src = S.pos_stack[v];\n            int idx = S.pos_idx[v];\n            \n            if(src == -1) break; // Box already removed\n            \n            // If v is at the top, remove it\n            if(idx == S.stack_size[src] - 1) {\n                apply_remove(S, v);\n                break;\n            } else {\n                // Identify blocker u (box directly above v)\n                int u = S.stacks[src][idx + 1];\n                \n                int best_dest = -1;\n                long long best_energy = -1;\n                bool first = true;\n                \n                // Iterate all candidate destination stacks\n                for(int dest=0; dest<m; ++dest) {\n                    if(dest == src) continue;\n                    \n                    // Simulation\n                    State sim;\n                    sim.copy_from(S);\n                    \n                    // Move u to dest in simulation\n                    sim_move(sim, u, dest);\n                    \n                    // Remove v (should now be at top of original src)\n                    int v_src = sim.pos_stack[v];\n                    if(v_src != -1 && sim.pos_idx[v] == sim.stack_size[v_src] - 1) {\n                        sim_remove(sim, v);\n                    }\n                    \n                    // Run lookahead to estimate future cost\n                    int resolved = 0;\n                    int target = v + 1;\n                    while(resolved < LOOKAHEAD && target <= n) {\n                        int t_src = sim.pos_stack[target];\n                        int t_idx = sim.pos_idx[target];\n                        \n                        if(t_src == -1) {\n                            target++;\n                            continue;\n                        }\n                        \n                        if(t_idx == sim.stack_size[t_src] - 1) {\n                            sim_remove(sim, target);\n                            resolved++;\n                            target++;\n                        } else {\n                            int blocker = sim.stacks[t_src][t_idx + 1];\n                            int d = find_dest_heuristic(sim, blocker, t_src, target + 1);\n                            sim_move(sim, blocker, d);\n                        }\n                    }\n                    \n                    // Update best choice\n                    if(first || sim.energy < best_energy) {\n                        best_energy = sim.energy;\n                        best_dest = dest;\n                        first = false;\n                    }\n                }\n                \n                // Apply the best move to the real state\n                apply_move(S, u, best_dest);\n            }\n        }\n    }\n\n    // Output the sequence of operations\n    for(const auto& p : ops) {\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\nvector<vector<int>> children;\nvector<bool> vis;\nvector<int> c, extra;\nstring res;\n\n// Check if move from (i,j) to (ni,nj) is valid (no wall)\nbool can_move(int i, int j, int ni, int nj) {\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    if (ni == i + 1 && nj == j) return h[i][j] == '0';\n    if (ni == i - 1 && nj == j) return h[ni][j] == '0';\n    if (ni == i && nj == j + 1) return v[i][j] == '0';\n    if (ni == i && nj == j - 1) return v[i][nj] == '0';\n    return false;\n}\n\n// Get move character\nchar get_dir(int r1, int c1, int r2, int c2) {\n    if (r1 < r2) return 'D';\n    if (r1 > r2) return 'U';\n    if (c1 < c2) return 'R';\n    if (c1 > c2) return 'L';\n    return 0;\n}\n\n// Build DFS spanning tree\nvoid build_tree(int u) {\n    vis[u] = true;\n    int ui = u / N, uj = u % N;\n    int dirs[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n    for (auto& dir : dirs) {\n        int ni = ui + dir[0], nj = uj + dir[1];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n            if (can_move(ui, uj, ni, nj)) {\n                int nxt = ni * N + nj;\n                if (!vis[nxt]) {\n                    children[u].push_back(nxt);\n                    build_tree(nxt);\n                }\n            }\n        }\n    }\n}\n\n// Generate route with extra loops\nvoid gen_route(int u, int p) {\n    for (int vtx : children[u]) {\n        int ui = u / N, uj = u % N;\n        int vi = vtx / N, vj = vtx % N;\n        char to_v = get_dir(ui, uj, vi, vj);\n        char to_u = get_dir(vi, vj, ui, uj);\n        // Insert extra out-and-back loops to child\n        for (int k = 0; k < extra[vtx]; ++k) {\n            res += to_v;\n            res += to_u;\n        }\n        // Normal traversal to child\n        res += to_v;\n        gen_route(vtx, u);\n        // Return to parent\n        res += to_u;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    h.resize(N-1);\n    for (int i = 0; i < N-1; ++i) cin >> h[i];\n    v.resize(N);\n    for (int i = 0; i < N; ++i) cin >> v[i];\n    d.assign(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> d[i][j];\n\n    // 1. Build Spanning Tree\n    children.assign(N*N, vector<int>());\n    vis.assign(N*N, false);\n    build_tree(0);\n\n    // 2. Compute base visit counts\n    // In DFS traversal, each node is visited deg_tree(node) times as a destination.\n    c.assign(N*N, 0);\n    for (int u = 0; u < N*N; ++u) {\n        c[u] = children[u].size();\n        if (u != 0) c[u] += 1; // +1 from parent edge\n    }\n\n    // 3. Greedily allocate extra visits\n    priority_queue<pair<double, int>> pq;\n    int L = 2 * (N*N - 1);\n    for (int u = 1; u < N*N; ++u) { // Skip root, its visit count is naturally high\n        double gain = (double)d[u/N][u%N] / (c[u] * (c[u] + 1.0));\n        pq.push({gain, u});\n    }\n\n    extra.assign(N*N, 0);\n    while (L + 2 <= 99000) {\n        auto top = pq.top(); pq.pop();\n        int u = top.second;\n        c[u]++;\n        extra[u]++;\n        L += 2;\n        double new_gain = (double)d[u/N][u%N] / (c[u] * (c[u] + 1.0));\n        pq.push({new_gain, u});\n    }\n\n    // 4. Construct final route\n    res.reserve(100005);\n    gen_route(0, -1);\n\n    cout << res << \"\\n\";\n    return 0;\n}","ahc028":"/*\n    Problem: Kakizome Taikai\n    Approach:\n    1. Precompute min_cost[k][r][c]: min cost to type string T[k] starting at (r,c).\n       Also store end_pos_r/c for the optimal path.\n    2. Simulated Annealing to find a good permutation of strings.\n       - Evaluation function uses precomputed costs (ignoring overlaps, acting as heuristic).\n       - Greedy initialization to start from a decent point.\n    3. Reconstruction with Lookahead.\n       - Follow SA order.\n       - Check for overlaps with current S.\n       - Use DP to find optimal path for the suffix of T[k].\n       - Lookahead: Minimize (Path Cost + min_cost[next_string][end_pos]).\n         This helps place the finger in a good position for the next string.\n       - Update S and covered status.\n    4. Output path.\n*/\n#include <bits/stdc++.h>\n#include <chrono>\n\nusing namespace std;\n\n// Optimization for speed\n#pragma GCC optimize(\"Ofast,unroll-loops\")\n\nstruct Point {\n    int r, c;\n};\n\nint main() {\n    // Fast IO\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n    int sr, sc;\n    cin >> sr >> sc;\n\n    vector<string> A(N);\n    for (int i = 0; i < N; i++) {\n        cin >> A[i];\n    }\n\n    vector<string> T(M);\n    for (int i = 0; i < M; i++) {\n        cin >> T[i];\n    }\n\n    // Map character positions\n    vector<vector<Point>> pos(26);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            pos[A[i][j] - 'A'].push_back({i, j});\n        }\n    }\n\n    // Precompute costs and end positions\n    // min_cost[k][r][c] = min cost to type T[k] starting from (r, c)\n    static int min_cost[200][15][15];\n    static uint8_t end_pos_r[200][15][15];\n    static uint8_t end_pos_c[200][15][15];\n\n    int prev_dp[250];\n    int curr_dp[250];\n\n    for (int k = 0; k < M; k++) {\n        const string& target = T[k];\n        const vector<Point>* layers[5];\n        int layer_sz[5];\n        \n        for (int l = 0; l < 5; l++) {\n            layers[l] = &pos[target[l] - 'A'];\n            layer_sz[l] = (int)layers[l]->size();\n        }\n\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                const auto& p0 = *layers[0];\n                int sz0 = layer_sz[0];\n                for (int u = 0; u < sz0; u++) {\n                    prev_dp[u] = abs(r - p0[u].r) + abs(c - p0[u].c) + 1;\n                }\n\n                for (int l = 1; l < 5; l++) {\n                    const auto& p_prev = *layers[l-1];\n                    const auto& p_curr = *layers[l];\n                    int sz_prev = layer_sz[l-1];\n                    int sz_curr = layer_sz[l];\n                    \n                    for (int u = 0; u < sz_curr; u++) {\n                        int ur = p_curr[u].r;\n                        int uc = p_curr[u].c;\n                        int mn = 2000000000;\n                        for (int v = 0; v < sz_prev; v++) {\n                            int dist = abs(p_prev[v].r - ur) + abs(p_prev[v].c - uc);\n                            int val = prev_dp[v] + dist + 1;\n                            if (val < mn) mn = val;\n                        }\n                        curr_dp[u] = mn;\n                    }\n                    for (int u = 0; u < sz_curr; u++) prev_dp[u] = curr_dp[u];\n                }\n\n                int sz_last = layer_sz[4];\n                int min_c = prev_dp[0];\n                int best_u = 0;\n                for (int u = 1; u < sz_last; u++) {\n                    if (prev_dp[u] < min_c) {\n                        min_c = prev_dp[u];\n                        best_u = u;\n                    }\n                }\n                min_cost[k][r][c] = min_c;\n                end_pos_r[k][r][c] = (uint8_t)(*layers[4])[best_u].r;\n                end_pos_c[k][r][c] = (uint8_t)(*layers[4])[best_u].c;\n            }\n        }\n    }\n\n    // Greedy Initialization\n    vector<int> order(M);\n    vector<bool> used(M, false);\n    int cr = sr, cc = sc;\n    for(int i=0; i<M; ++i){\n        int best_k = -1;\n        int best_val = 2000000000;\n        for(int k=0; k<M; ++k){\n            if(!used[k]){\n                if(min_cost[k][cr][cc] < best_val){\n                    best_val = min_cost[k][cr][cc];\n                    best_k = k;\n                }\n            }\n        }\n        if(best_k != -1){\n            used[best_k] = true;\n            order[i] = best_k;\n            cr = end_pos_r[best_k][cr][cc];\n            cc = end_pos_c[best_k][cr][cc];\n        }\n    }\n\n    // Simulated Annealing\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_real_distribution<double> dist(0.0, 1.0);\n    \n    auto evaluate = [&](const vector<int>& ord) -> int {\n        int cost = 0;\n        int cr_ev = sr, cc_ev = sc;\n        for (int k : ord) {\n            cost += min_cost[k][cr_ev][cc_ev];\n            int next_r = end_pos_r[k][cr_ev][cc_ev];\n            int next_c = end_pos_c[k][cr_ev][cc_ev];\n            cr_ev = next_r;\n            cc_ev = next_c;\n        }\n        return cost;\n    };\n\n    int best_cost = evaluate(order);\n    vector<int> best_order = order;\n    \n    double temp = 1000.0;\n    double cooling = 0.9995;\n    auto start_time = chrono::steady_clock::now();\n    double time_limit = 1.85;\n\n    while(true){\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if(elapsed > time_limit) break;\n\n        vector<int> new_order = order;\n        int type = rng() % 3;\n        if(type == 0){\n            int i = rng() % M;\n            int j = rng() % M;\n            swap(new_order[i], new_order[j]);\n        } else if(type == 1){\n            int i = rng() % M;\n            int j = rng() % M;\n            if(i > j) swap(i, j);\n            reverse(new_order.begin() + i, new_order.begin() + j + 1);\n        } else {\n            int i = rng() % M;\n            int j = rng() % M;\n            int val = new_order[i];\n            new_order.erase(new_order.begin() + i);\n            new_order.insert(new_order.begin() + j, val);\n        }\n\n        int new_cost = evaluate(new_order);\n        if(new_cost < best_cost || dist(rng) < exp(-(new_cost - best_cost) / temp)){\n            order = new_order;\n            if(new_cost < best_cost){\n                best_cost = new_cost;\n                best_order = order;\n            }\n        }\n        temp *= cooling;\n    }\n\n    // Reconstruction\n    vector<Point> ans;\n    ans.reserve(M * 5);\n    string S = \"\";\n    int cur_r = sr, cur_c = sc;\n    vector<bool> covered(M, false);\n    int covered_cnt = 0;\n\n    int dp_buf[250];\n    int next_dp_buf[250];\n    static int parent[5][250];\n\n    for(int k_idx = 0; k_idx < M; ++k_idx){\n        int k = best_order[k_idx];\n        if(covered[k]) continue;\n\n        if(S.find(T[k]) != string::npos){\n            covered[k] = true;\n            covered_cnt++;\n            continue;\n        }\n\n        int ov = 0;\n        int lim = min((int)S.size(), 4);\n        for(int o=lim; o>=1; --o){\n            bool match = true;\n            for(int p=0; p<o; ++p){\n                if(S[S.size()-o+p] != T[k][p]){\n                    match = false;\n                    break;\n                }\n            }\n            if(match){\n                ov = o;\n                break;\n            }\n        }\n        \n        if(ov >= 5){\n             covered[k] = true;\n             covered_cnt++;\n             continue;\n        }\n\n        int len = 5 - ov;\n        \n        const vector<Point>* layers_p[5];\n        int layers_sz[5];\n        \n        for(int l=0; l<len; ++l){\n            layers_p[l] = &pos[T[k][ov + l] - 'A'];\n            layers_sz[l] = (int)layers_p[l]->size();\n        }\n        \n        const auto& p0 = *layers_p[0];\n        int sz0 = layers_sz[0];\n        for(int u=0; u<sz0; ++u){\n            dp_buf[u] = abs(cur_r - p0[u].r) + abs(cur_c - p0[u].c) + 1;\n            parent[0][u] = -1;\n        }\n        \n        for(int l=1; l<len; ++l){\n            const auto& p_prev = *layers_p[l-1];\n            const auto& p_curr = *layers_p[l];\n            int sz_prev = layers_sz[l-1];\n            int sz_curr = layers_sz[l];\n            \n            for(int u=0; u<sz_curr; ++u){\n                int ur = p_curr[u].r;\n                int uc = p_curr[u].c;\n                int mn = 2000000000;\n                int best_v = -1;\n                for(int v=0; v<sz_prev; ++v){\n                    int dist = abs(p_prev[v].r - ur) + abs(p_prev[v].c - uc);\n                    int val = dp_buf[v] + dist + 1;\n                    if(val < mn){\n                        mn = val;\n                        best_v = v;\n                    }\n                }\n                next_dp_buf[u] = mn;\n                parent[l][u] = best_v;\n            }\n            for(int u=0; u<sz_curr; ++u) dp_buf[u] = next_dp_buf[u];\n        }\n        \n        // Lookahead\n        int next_k = -1;\n        for(int next_idx = k_idx + 1; next_idx < M; ++next_idx){\n            if(!covered[best_order[next_idx]]){\n                next_k = best_order[next_idx];\n                break;\n            }\n        }\n\n        int sz_last = layers_sz[len-1];\n        if(next_k != -1){\n            for(int u=0; u<sz_last; ++u){\n                int r_u = (*layers_p[len-1])[u].r;\n                int c_u = (*layers_p[len-1])[u].c;\n                dp_buf[u] += min_cost[next_k][r_u][c_u];\n            }\n        }\n\n        int min_c = dp_buf[0];\n        int best_u = 0;\n        for(int u=1; u<sz_last; ++u){\n            if(dp_buf[u] < min_c){\n                min_c = dp_buf[u];\n                best_u = u;\n            }\n        }\n        \n        vector<Point> path;\n        path.resize(len);\n        int u = best_u;\n        for(int l=len-1; l>=0; --l){\n            path[l] = (*layers_p[l])[u];\n            if(l > 0) u = parent[l][u];\n        }\n        \n        for(const auto& p : path){\n            ans.push_back(p);\n            S += A[p.r][p.c];\n            cur_r = p.r;\n            cur_c = p.c;\n        }\n        \n        covered[k] = true;\n        covered_cnt++;\n        \n        // Check coverage\n        int nS = (int)S.size();\n        int start_check = max(0, nS - len - 4);\n        int end_check = nS - 5;\n        \n        for(int s = start_check; s <= end_check; ++s){\n            for(int j=0; j<M; ++j){\n                if(!covered[j]){\n                    // Check if T[j] matches S[s...s+4]\n                    bool match = true;\n                    for(int c=0; c<5; ++c){\n                        if(S[s+c] != T[j][c]){\n                            match = false;\n                            break;\n                        }\n                    }\n                    if(match){\n                        covered[j] = true;\n                        covered_cnt++;\n                    }\n                }\n            }\n        }\n    }\n\n    for(const auto& p : ans){\n        cout << p.r << \" \" << p.c << \"\\n\";\n    }\n\n    return 0;\n}","ahc030":"#pragma GCC optimize(\"O3,unroll-loops\")\n#include <bits/stdc++.h>\nusing namespace std;\n\nvoid fast_io() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n}\n\nint N, M;\ndouble eps;\n\nstruct Shape { vector<pair<int, int>> cells; } shapes[20];\nint max_r[20], max_c[20];\n\nint grid_val[20][20];\nint target_val[20][20];\nbool is_observed[20][20];\nbool is_drilled[20][20];\n\nstruct ObsCell { int r, c, val; };\nvector<ObsCell> obs_list;\n\npair<int, int> cur_pos[20];\npair<int, int> best_pos[20];\n\nvector<double> est_row, est_col;\n\nmt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\nint rand_int(int l, int r) { return uniform_int_distribution<int>(l, r)(rng); }\n\nint compute_cost() {\n    int cost = 0;\n    for (const auto& o : obs_list) {\n        int diff = grid_val[o.r][o.c] - o.val;\n        cost += diff * diff;\n    }\n    for(int i=0; i<N; ++i) {\n        int s = 0;\n        for(int j=0; j<N; ++j) s += grid_val[i][j];\n        int diff = s - (int)round(est_row[i]);\n        cost += diff * diff / 2; // Weighted penalty for noisy row sums\n    }\n    for(int j=0; j<N; ++j) {\n        int s = 0;\n        for(int i=0; i<N; ++i) s += grid_val[i][j];\n        int diff = s - (int)round(est_col[j]);\n        cost += diff * diff / 2; // Weighted penalty for noisy col sums\n    }\n    return cost;\n}\n\nvoid apply_move(int k, int dr, int dc, int sign) {\n    for (const auto& cell : shapes[k].cells) {\n        grid_val[cell.first + dr][cell.second + dc] += sign;\n    }\n}\n\nvoid copy_positions(pair<int, int> src[20], pair<int, int> dst[20]) {\n    for(int i=0; i<M; ++i) dst[i] = src[i];\n}\n\nvoid run_sa(const vector<pair<int,int>>& init_pos) {\n    for (int k = 0; k < M; ++k) {\n        cur_pos[k] = !init_pos.empty() ? init_pos[k] : \n                     make_pair(rand_int(0, N - 1 - max_r[k]), rand_int(0, N - 1 - max_c[k]));\n    }\n    \n    for(int i=0; i<N; ++i) fill(grid_val[i], grid_val[i]+N, 0);\n    for (int k = 0; k < M; ++k) apply_move(k, cur_pos[k].first, cur_pos[k].second, 1);\n    \n    int current_cost = compute_cost();\n    int best_cost = current_cost;\n    copy_positions(cur_pos, best_pos);\n    \n    double T = 800.0;\n    int iterations = 5000;\n    uniform_real_distribution<double> dis(0, 1);\n    \n    for (int iter = 0; iter < iterations; ++iter) {\n        int k = rand_int(0, M - 1);\n        int dr = rand_int(-1, 1);\n        int dc = rand_int(-1, 1);\n        if (dr == 0 && dc == 0) continue;\n        \n        int nr = cur_pos[k].first + dr;\n        int nc = cur_pos[k].second + dc;\n        \n        if (nr < 0 || nr > N - 1 - max_r[k] || nc < 0 || nc > N - 1 - max_c[k]) continue;\n        \n        int old_r = cur_pos[k].first, old_c = cur_pos[k].second;\n        \n        // Apply move\n        apply_move(k, old_r, old_c, -1);\n        apply_move(k, nr, nc, 1);\n        cur_pos[k] = {nr, nc};\n        \n        int new_cost = compute_cost();\n        int delta = new_cost - current_cost;\n        \n        if (delta < 0 || dis(rng) < exp(-delta / T)) {\n            current_cost = new_cost;\n            if (current_cost < best_cost) {\n                best_cost = current_cost;\n                copy_positions(cur_pos, best_pos);\n            }\n        } else {\n            apply_move(k, nr, nc, -1);\n            apply_move(k, old_r, old_c, 1);\n            cur_pos[k] = {old_r, old_c};\n        }\n        \n        if (current_cost == 0) {\n            copy_positions(cur_pos, best_pos);\n            break;\n        }\n        T *= 0.9992;\n    }\n    \n    copy_positions(best_pos, cur_pos);\n    for(int i=0; i<N; ++i) fill(grid_val[i], grid_val[i]+N, 0);\n    for (int k = 0; k < M; ++k) apply_move(k, cur_pos[k].first, cur_pos[k].second, 1);\n}\n\nint main() {\n    fast_io();\n    if (!(cin >> N >> M >> eps)) return 0;\n    \n    for (int k = 0; k < M; ++k) {\n        int d; cin >> d;\n        for (int l = 0; l < d; ++l) {\n            int r, c; cin >> r >> c;\n            shapes[k].cells.push_back({r, c});\n            max_r[k] = max(max_r[k], r);\n            max_c[k] = max(max_c[k], c);\n        }\n    }\n    \n    memset(grid_val, 0, sizeof(grid_val));\n    memset(target_val, -1, sizeof(target_val));\n    memset(is_observed, 0, sizeof(is_observed));\n    memset(is_drilled, 0, sizeof(is_drilled));\n    \n    est_row.assign(N, 0);\n    est_col.assign(N, 0);\n    \n    int op_count = 0;\n    int limit = 2 * N * N;\n    \n    auto drill = [&](int r, int c) {\n        cout << \"q 1 \" << r << \" \" << c << \"\\n\";\n        cout.flush();\n        int v; cin >> v;\n        target_val[r][c] = v;\n        is_observed[r][c] = true;\n        is_drilled[r][c] = true;\n        obs_list.push_back({r, c, v});\n        op_count++;\n    };\n    \n    // Phase 1: Row/Column Divination (Very cheap, strong global constraints)\n    for(int i=0; i<N && op_count < limit; ++i) {\n        cout << \"q \" << N;\n        for(int j=0; j<N; ++j) cout << \" \" << i << \" \" << j;\n        cout << \"\\n\"; cout.flush();\n        int resp; cin >> resp; op_count++;\n        // Invert noise model: mu = k*eps + v*(1-2*eps) => v = (mu - k*eps) / (1-2*eps)\n        est_row[i] = max(0.0, (resp - N * eps) / (1 - 2 * eps));\n    }\n    for(int j=0; j<N && op_count < limit; ++j) {\n        cout << \"q \" << N;\n        for(int i=0; i<N; ++i) cout << \" \" << i << \" \" << j;\n        cout << \"\\n\"; cout.flush();\n        int resp; cin >> resp; op_count++;\n        est_col[j] = max(0.0, (resp - N * eps) / (1 - 2 * eps));\n    }\n    \n    // Phase 2: Initial Drills\n    int init_drills = min(40, N * N);\n    for (int i = 0; i < init_drills && op_count < limit; ++i) {\n        int r = rand_int(0, N-1);\n        int c = rand_int(0, N-1);\n        if (!is_drilled[r][c]) drill(r, c);\n        else i--;\n    }\n    \n    vector<pair<int,int>> current_best_pos(M, {0,0});\n    auto start_time = chrono::steady_clock::now();\n\n    // Main Loop\n    while (true) {\n        auto elapsed = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count();\n        if (elapsed > 2800) break;\n        if (op_count >= limit) break;\n        \n        run_sa(current_best_pos);\n        for(int k=0; k<M; k++) current_best_pos[k] = cur_pos[k];\n        \n        // Construct guess\n        bool guessed_arr[20][20] = {};\n        vector<pair<int,int>> guess_cells;\n        \n        // 1. Mandatory: Include all drilled cells with oil\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                if (is_drilled[r][c] && target_val[r][c] > 0) {\n                    guessed_arr[r][c] = true;\n                    guess_cells.push_back({r, c});\n                }\n            }\n        }\n        \n        // 2. Add model-predicted cells\n        for (int k = 0; k < M; ++k) {\n            for (const auto& cell : shapes[k].cells) {\n                int r = cell.first + cur_pos[k].first;\n                int c = cell.second + cur_pos[k].second;\n                if (is_drilled[r][c] && target_val[r][c] == 0) continue;\n                if (!guessed_arr[r][c]) {\n                    guessed_arr[r][c] = true;\n                    guess_cells.push_back({r, c});\n                }\n            }\n        }\n        \n        if (op_count < limit) {\n            cout << \"a \" << guess_cells.size();\n            for (const auto& p : guess_cells) cout << \" \" << p.first << \" \" << p.second;\n            cout << \"\\n\"; cout.flush();\n            op_count++;\n            int res; cin >> res;\n            if (res == 1) return 0;\n        }\n        \n        if (op_count >= limit) break;\n        \n        // Phase 3: Adaptive drilling (prioritize model zeros)\n        int budget = limit - op_count - 1;\n        if (budget > 0) {\n            int drills_needed = min(10, budget);\n            vector<pair<int,int>> zero_pred, others;\n            for (int r = 0; r < N; ++r) {\n                for (int c = 0; c < N; ++c) {\n                    if (!is_drilled[r][c]) {\n                        if (grid_val[r][c] == 0) zero_pred.push_back({r, c});\n                        else others.push_back({r, c});\n                    }\n                }\n            }\n            shuffle(zero_pred.begin(), zero_pred.end(), rng);\n            shuffle(others.begin(), others.end(), rng);\n            \n            int count = 0;\n            for (const auto& p : zero_pred) {\n                if (count >= drills_needed) break;\n                drill(p.first, p.second);\n                count++;\n            }\n            for (const auto& p : others) {\n                if (count >= drills_needed) break;\n                drill(p.first, p.second);\n                count++;\n            }\n        }\n    }\n    \n    // Final guess before termination\n    if (op_count < limit) {\n        run_sa(current_best_pos);\n        bool guessed_arr[20][20] = {};\n        vector<pair<int,int>> guess_cells;\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                if (is_drilled[r][c] && target_val[r][c] > 0) {\n                    guessed_arr[r][c] = true;\n                    guess_cells.push_back({r, c});\n                }\n            }\n        }\n        for (int k = 0; k < M; ++k) {\n            for (const auto& cell : shapes[k].cells) {\n                int r = cell.first + cur_pos[k].first;\n                int c = cell.second + cur_pos[k].second;\n                if (is_drilled[r][c] && target_val[r][c] == 0) continue;\n                if (!guessed_arr[r][c]) {\n                    guessed_arr[r][c] = true;\n                    guess_cells.push_back({r, c});\n                }\n            }\n        }\n        cout << \"a \" << guess_cells.size();\n        for (const auto& p : guess_cells) cout << \" \" << p.first << \" \" << p.second;\n        cout << \"\\n\"; cout.flush();\n    }\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\n#include <chrono>\n#pragma GCC optimize(\"O3,unroll-loops\")\nusing namespace std;\n\nconst int W_IN = 1000;\nconst int MAX_D = 55;\nconst int MAX_N = 55;\n\nint D_in, N_in;\nlong long A[MAX_D][MAX_N];\n\nstruct Rect {\n    int x1, y1, x2, y2;\n    long long area() const { return 1LL * (x2 - x1) * (y2 - y1); }\n};\n\nRect rects[MAX_D][MAX_N];\nRect best_rects[MAX_D][MAX_N];\n\n// H_cnt[d][y][x]: horizontal segment at row y, between x and x+1\n// V_cnt[d][x][y]: vertical segment at col x, between y and y+1\n// Transposed V for cache locality\nuint8_t H_cnt[MAX_D][W_IN + 2][W_IN + 2];\nuint8_t V_cnt[MAX_D][W_IN + 2][W_IN + 2];\n\nlong long area_pen[MAX_D][MAX_N];\nlong long total_cost = 0;\nlong long best_cost = 1LL << 60;\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\ninline long long calc_pen(const Rect& r, long long req) {\n    long long a = r.area();\n    return (req > a) ? 100LL * (req - a) : 0;\n}\n\ninline bool overlap(int d, int k, const Rect& r) {\n    for (int i = 0; i < N_in; ++i) {\n        if (i == k) continue;\n        if (rects[d][i].x1 < r.x2 && rects[d][i].x2 > r.x1 &&\n            rects[d][i].y1 < r.y2 && rects[d][i].y2 > r.y1)\n            return true;\n    }\n    return false;\n}\n\n// Calculate change in partition cost if H/V at (d, y, x) changes to new_val\ninline long long seg_delta(int d, int y, int x, bool is_h, bool new_val) {\n    bool old_val = is_h ? (H_cnt[d][y][x] > 0) : (V_cnt[d][x][y] > 0);\n    if (old_val == new_val) return 0;\n    long long delta = 0;\n    \n    // Contribution to L_d (transition d-1 -> d)\n    // This term is H_d ^ H_{d-1}. Changing H_d affects this.\n    // Valid only if d > 0.\n    if (d > 0) {\n        bool prev = is_h ? (H_cnt[d-1][y][x] > 0) : (V_cnt[d-1][x][y] > 0);\n        delta += (new_val != prev) - (old_val != prev);\n    }\n    \n    // Contribution to L_{d+1} (transition d -> d+1)\n    // This term is H_{d+1} ^ H_d. Changing H_d affects this.\n    // Valid only if d < D_in - 1.\n    if (d < D_in - 1) {\n        bool next = is_h ? (H_cnt[d+1][y][x] > 0) : (V_cnt[d+1][x][y] > 0);\n        delta += (next != new_val) - (next != old_val);\n    }\n    \n    return delta;\n}\n\nvoid pack_initial() {\n    // Grid partitioning to ensure valid initial state\n    for (int d = 0; d < D_in; ++d) {\n        int R = ceil(sqrt(N_in));\n        int C = (N_in + R - 1) / R;\n        int block_h = W_IN / R;\n        int block_w = W_IN / C;\n        int rem_h = W_IN % R;\n        int rem_w = W_IN % C;\n        \n        int cy = 0;\n        for (int r = 0; r < R; ++r) {\n            int cur_h = block_h + (r < rem_h ? 1 : 0);\n            int cx = 0;\n            for (int c = 0; c < C; ++c) {\n                int idx = r * C + c;\n                if (idx >= N_in) break;\n                int cur_w = block_w + (c < rem_w ? 1 : 0);\n                rects[d][idx] = {cx, cy, cx + cur_w, cy + cur_h};\n                cx += cur_w;\n            }\n            cy += cur_h;\n        }\n    }\n\n    memset(H_cnt, 0, sizeof(H_cnt));\n    memset(V_cnt, 0, sizeof(V_cnt));\n    total_cost = 0;\n    for (int d = 0; d < D_in; ++d) {\n        for (int k = 0; k < N_in; ++k) {\n            area_pen[d][k] = calc_pen(rects[d][k], A[d][k]);\n            total_cost += area_pen[d][k];\n            \n            // Add to grids\n            int y_vals[2] = {rects[d][k].y1, rects[d][k].y2};\n            for (int edge = 0; edge < 2; ++edge) {\n                int y = y_vals[edge];\n                if (y >= 1 && y < W_IN) {\n                    for (int x = rects[d][k].x1; x < rects[d][k].x2; ++x) {\n                        H_cnt[d][y][x]++;\n                    }\n                }\n            }\n            int x_vals[2] = {rects[d][k].x1, rects[d][k].x2};\n            for (int edge = 0; edge < 2; ++edge) {\n                int x = x_vals[edge];\n                if (x >= 1 && x < W_IN) {\n                    for (int y = rects[d][k].y1; y < rects[d][k].y2; ++y) {\n                        V_cnt[d][x][y]++;\n                    }\n                }\n            }\n        }\n    }\n    // Compute initial partition cost\n    for (int d = 1; d < D_in; ++d) {\n        for (int y = 1; y < W_IN; ++y) {\n            for (int x = 0; x < W_IN; ++x) {\n                if ((H_cnt[d][y][x] > 0) != (H_cnt[d-1][y][x] > 0)) total_cost++;\n            }\n            for (int x = 1; x < W_IN; ++x) {\n                if ((V_cnt[d][x][y] > 0) != (V_cnt[d-1][x][y] > 0)) total_cost++;\n            }\n        }\n        for (int x = 1; x < W_IN; ++x) {\n            if ((V_cnt[d][x][W_IN-1] > 0) != (V_cnt[d-1][x][W_IN-1] > 0)) total_cost++;\n        }\n    }\n}\n\n// Generate a candidate move using a mix of perturbation and snapping\nRect generate_move(int d, int k) {\n    Rect old_r = rects[d][k];\n    Rect new_r;\n    \n    // Strategy: 20% Snap, 80% Perturb\n    int strategy = rng() % 100;\n    \n    if (strategy < 20 && D_in > 1) {\n        // Snap strategy: try to align with a wall from a neighbor day\n        int nd = -1;\n        if (d > 0 && d < D_in - 1) nd = (rng() % 2 == 0) ? d - 1 : d + 1;\n        else if (d > 0) nd = d - 1;\n        else if (d < D_in - 1) nd = d + 1;\n        \n        if (nd != -1) {\n            int nk = rng() % N_in;\n            Rect& nr = rects[nd][nk];\n            int snap_type = rng() % 4; // 0:x1, 1:x2, 2:y1, 3:y2\n            \n            new_r = old_r;\n            if (snap_type == 0) { // Snap x1\n                new_r.x1 = (rng() % 2 == 0) ? nr.x1 : nr.x2;\n                new_r.x2 = new_r.x1 + (old_r.x2 - old_r.x1);\n                if (new_r.x2 > W_IN) new_r.x2 = W_IN;\n            } else if (snap_type == 1) { // Snap x2\n                new_r.x2 = (rng() % 2 == 0) ? nr.x1 : nr.x2;\n                new_r.x1 = new_r.x2 - (old_r.x2 - old_r.x1);\n                if (new_r.x1 < 0) new_r.x1 = 0;\n            } else if (snap_type == 2) { // Snap y1\n                new_r.y1 = (rng() % 2 == 0) ? nr.y1 : nr.y2;\n                new_r.y2 = new_r.y1 + (old_r.y2 - old_r.y1);\n                if (new_r.y2 > W_IN) new_r.y2 = W_IN;\n            } else { // Snap y2\n                new_r.y2 = (rng() % 2 == 0) ? nr.y1 : nr.y2;\n                new_r.y1 = new_r.y2 - (old_r.y2 - old_r.y1);\n                if (new_r.y1 < 0) new_r.y1 = 0;\n            }\n            \n            // Validity checks\n            if (new_r.x1 >= new_r.x2 || new_r.y1 >= new_r.y2) return old_r;\n            if (overlap(d, k, new_r)) return old_r;\n            return new_r;\n        }\n    }\n    \n    // Perturb strategy\n    uniform_int_distribution<int> dist_dx(-5, 5);\n    uniform_int_distribution<int> dist_dw(-3, 3);\n    \n    int dx = dist_dx(rng);\n    int dy = dist_dx(rng);\n    int dw = dist_dw(rng);\n    int dh = dist_dw(rng);\n    \n    new_r.x1 = max(0, min(W_IN - 1, old_r.x1 + dx));\n    new_r.y1 = max(0, min(W_IN - 1, old_r.y1 + dy));\n    new_r.x2 = max(new_r.x1 + 1, min(W_IN, old_r.x2 + dw));\n    new_r.y2 = max(new_r.y1 + 1, min(W_IN, old_r.y2 + dh));\n    \n    long long cur_area = new_r.area();\n    if (cur_area < A[d][k]) {\n        long long needed = A[d][k];\n        int h = new_r.y2 - new_r.y1;\n        int add_w = max(0, (int)((needed + h - 1) / h) - (new_r.x2 - new_r.x1));\n        if (new_r.x2 + add_w <= W_IN) new_r.x2 += add_w;\n        else {\n            int w = new_r.x2 - new_r.x1;\n            int add_h = max(0, (int)((needed + w - 1) / w) - h);\n            if (new_r.y2 + add_h <= W_IN) new_r.y2 += add_h;\n            else return old_r;\n        }\n    }\n    \n    if (overlap(d, k, new_r)) return old_r;\n    return new_r;\n}\n\nvoid run_sa() {\n    auto start = chrono::high_resolution_clock::now();\n    double temp = 10000.0;\n    const double initial_temp = temp;\n    const double total_time = 2800.0;\n    \n    while (true) {\n        double elapsed = chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start).count();\n        if (elapsed >= total_time) break;\n        temp = initial_temp * exp(-3.0 * elapsed / total_time); // Cooling\n\n        int d = rng() % D_in;\n        int k = rng() % N_in;\n        Rect old_r = rects[d][k];\n        \n        Rect new_r = generate_move(d, k);\n        \n        // Check if move is identity\n        if (new_r.x1 == old_r.x1 && new_r.y1 == old_r.y1 && \n            new_r.x2 == old_r.x2 && new_r.y2 == old_r.y2) continue;\n\n        // Redundant check but fast\n        if (overlap(d, k, new_r)) continue; \n\n        long long delta = calc_pen(new_r, A[d][k]) - area_pen[d][k];\n        \n        // Partition delta calculation\n        // Remove old edges\n        int y_vals[2] = {old_r.y1, old_r.y2};\n        for (int edge = 0; edge < 2; ++edge) {\n            int y = y_vals[edge];\n            if (y >= 1 && y < W_IN) {\n                for (int x = old_r.x1; x < old_r.x2; ++x) {\n                    if (H_cnt[d][y][x] == 1) delta += seg_delta(d, y, x, true, false);\n                }\n            }\n        }\n        int x_vals[2] = {old_r.x1, old_r.x2};\n        for (int edge = 0; edge < 2; ++edge) {\n            int x = x_vals[edge];\n            if (x >= 1 && x < W_IN) {\n                for (int y = old_r.y1; y < old_r.y2; ++y) {\n                    if (V_cnt[d][x][y] == 1) delta += seg_delta(d, y, x, false, false);\n                }\n            }\n        }\n\n        // Add new edges\n        int ny_vals[2] = {new_r.y1, new_r.y2};\n        for (int edge = 0; edge < 2; ++edge) {\n            int y = ny_vals[edge];\n            if (y >= 1 && y < W_IN) {\n                for (int x = new_r.x1; x < new_r.x2; ++x) {\n                    if (H_cnt[d][y][x] == 0) delta += seg_delta(d, y, x, true, true);\n                }\n            }\n        }\n        int nx_vals[2] = {new_r.x1, new_r.x2};\n        for (int edge = 0; edge < 2; ++edge) {\n            int x = nx_vals[edge];\n            if (x >= 1 && x < W_IN) {\n                for (int y = new_r.y1; y < new_r.y2; ++y) {\n                    if (V_cnt[d][x][y] == 0) delta += seg_delta(d, y, x, false, true);\n                }\n            }\n        }\n\n        if (delta < 0 || (double)rng() / 4294967296.0 < exp(-delta / temp)) {\n            // Apply removal\n            for (int edge = 0; edge < 2; ++edge) {\n                int y = y_vals[edge];\n                if (y >= 1 && y < W_IN) for (int x = old_r.x1; x < old_r.x2; ++x) H_cnt[d][y][x]--;\n            }\n            for (int edge = 0; edge < 2; ++edge) {\n                int x = x_vals[edge];\n                if (x >= 1 && x < W_IN) for (int y = old_r.y1; y < old_r.y2; ++y) V_cnt[d][x][y]--;\n            }\n            // Apply addition\n            for (int edge = 0; edge < 2; ++edge) {\n                int y = ny_vals[edge];\n                if (y >= 1 && y < W_IN) for (int x = new_r.x1; x < new_r.x2; ++x) H_cnt[d][y][x]++;\n            }\n            for (int edge = 0; edge < 2; ++edge) {\n                int x = nx_vals[edge];\n                if (x >= 1 && x < W_IN) for (int y = new_r.y1; y < new_r.y2; ++y) V_cnt[d][x][y]++;\n            }\n            \n            rects[d][k] = new_r;\n            area_pen[d][k] = calc_pen(new_r, A[d][k]);\n            total_cost += delta;\n            if (total_cost < best_cost) {\n                best_cost = total_cost;\n                memcpy(best_rects, rects, sizeof(rects));\n            }\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int W_temp;\n    if (!(cin >> W_temp >> D_in >> N_in)) return 0;\n    \n    for (int d = 0; d < D_in; ++d)\n        for (int k = 0; k < N_in; ++k)\n            cin >> A[d][k];\n\n    pack_initial();\n    best_cost = total_cost;\n    memcpy(best_rects, rects, sizeof(rects));\n    \n    run_sa();\n\n    for (int d = 0; d < D_in; ++d) {\n        for (int k = 0; k < N_in; ++k) {\n            Rect& r = best_rects[d][k];\n            // Safety clamp\n            r.x1 = max(0, min(W_IN - 1, r.x1));\n            r.y1 = max(0, min(W_IN - 1, r.y1));\n            r.x2 = max(r.x1 + 1, min(W_IN, r.x2));\n            r.y2 = max(r.y1 + 1, min(W_IN, r.y2));\n            cout << r.y1 << \" \" << r.x1 << \" \" << r.y2 << \" \" << r.x2 << \"\\n\";\n        }\n    }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\n#pragma GCC optimize(\"O3,unroll-loops\")\n\nusing namespace std;\nusing ll = long long;\n\nconst ll MOD = 998244353;\nconstexpr int MAX_N = 9;\nconstexpr int MAX_M = 20;\nconstexpr int MAX_K = 81;\n\nll initial_board[MAX_N][MAX_N];\nll board_mod[MAX_N][MAX_N];\nll stamps[MAX_M][3][3];\n\nstruct Op { int m, p, q; };\nvector<Op> ops(MAX_K);\nvector<Op> best_ops;\nll current_score = 0;\nll best_score = 0;\n\n// Fast Xorshift RNG\nuint64_t rng_state;\ninline uint64_t my_rand() {\n    uint64_t x = rng_state;\n    x ^= x >> 12; x ^= x << 25; x ^= x >> 27;\n    return x * 0x2545F4914F6CDD1D;\n}\ninline int rand_int(int max) { return my_rand() % max; }\n\n// Calculate score change if we add stamp m at (p, q)\ninline ll calc_delta(int m, int p, int q) {\n    ll d = 0;\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            ll old_val = board_mod[p + i][q + j];\n            ll new_val = old_val + stamps[m][i][j];\n            if (new_val >= MOD) new_val -= MOD;\n            d += new_val - old_val;\n        }\n    }\n    return d;\n}\n\n// Calculate score change if we remove stamp m at (p, q)\ninline ll calc_remove_delta(int m, int p, int q) {\n    ll d = 0;\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            ll old_val = board_mod[p + i][q + j];\n            ll new_val = old_val - stamps[m][i][j];\n            if (new_val < 0) new_val += MOD;\n            d += new_val - old_val;\n        }\n    }\n    return d;\n}\n\ninline void apply(int m, int p, int q) {\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            board_mod[p + i][q + j] += stamps[m][i][j];\n            if (board_mod[p + i][q + j] >= MOD) board_mod[p + i][q + j] -= MOD;\n        }\n    }\n}\n\ninline void revert(int m, int p, int q) {\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            board_mod[p + i][q + j] -= stamps[m][i][j];\n            if (board_mod[p + i][q + j] < 0) board_mod[p + i][q + j] += MOD;\n        }\n    }\n}\n\ninline ll compute_score() {\n    ll s = 0;\n    for (int i = 0; i < MAX_N; ++i) \n        for (int j = 0; j < MAX_N; ++j) \n            s += board_mod[i][j];\n    return s;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n\n    for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) {\n        cin >> initial_board[i][j];\n        board_mod[i][j] = initial_board[i][j] % MOD;\n    }\n    for (int m = 0; m < M; ++m) for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) {\n        cin >> stamps[m][i][j];\n    }\n\n    rng_state = chrono::steady_clock::now().time_since_epoch().count();\n\n    // 1. Greedy Initialization\n    for (int k = 0; k < K; ++k) {\n        int best_m = -1, best_p = -1, best_q = -1;\n        ll best_d = -1e18; \n        for (int m = 0; m < M; ++m) {\n            for (int p = 0; p <= N - 3; ++p) {\n                for (int q = 0; q <= N - 3; ++q) {\n                    ll d = calc_delta(m, p, q);\n                    if (d > best_d) {\n                        best_d = d; best_m = m; best_p = p; best_q = q;\n                    }\n                }\n            }\n        }\n        ops[k] = {best_m, best_p, best_q};\n        apply(best_m, best_p, best_q);\n    }\n    \n    current_score = compute_score();\n    best_score = current_score;\n    best_ops = ops;\n\n    // 2. Simulated Annealing\n    double T = 2e9;\n    const double T_end = 100;\n    const int MAX_ITER = 30000000;\n    const double decay = pow(T_end / T, 1.0 / MAX_ITER);\n    \n    const int max_m = M;\n    const int max_pq = N - 2;\n\n    auto start_time = chrono::steady_clock::now();\n    \n    for (int step = 0; step < MAX_ITER; ++step) {\n        // Soft time limit check\n        if (step % 500000 == 0) {\n            auto now = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 1900) break;\n        }\n\n        int idx = rand_int(K);\n        int m = rand_int(max_m);\n        int p = rand_int(max_pq);\n        int q = rand_int(max_pq);\n\n        ll d_remove = calc_remove_delta(ops[idx].m, ops[idx].p, ops[idx].q);\n        revert(ops[idx].m, ops[idx].p, ops[idx].q);\n        ll d_add = calc_delta(m, p, q);\n        ll delta = d_remove + d_add;\n        \n        bool accept = false;\n        if (delta > 0) {\n            accept = true;\n        } else {\n            // Metropolis criterion with underflow protection\n            if (delta > -20.0 * T) {\n                double prob = exp(delta / T);\n                // Fast probability comparison using upper 32 bits\n                if ((double)(my_rand() & 0xFFFFFFFF) / 4294967296.0 < prob) {\n                    accept = true;\n                }\n            }\n        }\n\n        if (accept) {\n            apply(m, p, q);\n            ops[idx] = {m, p, q};\n            current_score += delta;\n            if (current_score > best_score) {\n                best_score = current_score;\n                best_ops = ops;\n            }\n        } else {\n            apply(ops[idx].m, ops[idx].p, ops[idx].q);\n        }\n        T *= decay;\n    }\n\n    // 3. Post-Processing: Greedy Removal\n    for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) {\n        board_mod[i][j] = initial_board[i][j] % MOD;\n    }\n    for (const auto& op : best_ops) apply(op.m, op.p, op.q);\n    current_score = compute_score();\n\n    bool improved = true;\n    while (improved && !best_ops.empty()) {\n        improved = false;\n        int best_remove_idx = -1;\n        ll max_d_remove = 0;\n\n        for (size_t i = 0; i < best_ops.size(); ++i) {\n            ll d = calc_remove_delta(best_ops[i].m, best_ops[i].p, best_ops[i].q);\n            if (d > max_d_remove) {\n                max_d_remove = d;\n                best_remove_idx = i;\n            }\n        }\n\n        if (best_remove_idx != -1) {\n            revert(best_ops[best_remove_idx].m, best_ops[best_remove_idx].p, best_ops[best_remove_idx].q);\n            current_score += max_d_remove;\n            best_ops.erase(best_ops.begin() + best_remove_idx);\n            best_score = current_score;\n            improved = true;\n        }\n    }\n\n    cout << best_ops.size() << \"\\n\";\n    for (const auto& op : best_ops) {\n        cout << op.m << \" \" << op.p << \" \" << op.q << \"\\n\";\n    }\n\n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <tuple>\n#include <cstring>\n#include <algorithm>\n\nusing namespace std;\n\n// Constants\nconst int N = 5;\nconst int INF = 1e9;\n\n// State\nint grid[N][N]; // -1 if empty\nint crane_r[5], crane_c[5];\nint crane_hold[5]; // -1 if empty\nbool is_large[5];\n\nint dnext[5]; // Next expected container for row i\nint rptr[5];  // Next receiving index for row i\n\n// To store moves\nstring moves[5];\n\n// Helper to check valid coordinates\nbool valid(int r, int c) {\n    return r >= 0 && r < N && c >= 0 && c < N;\n}\n\n// BFS Pathfinding with Sequential MAPF\n// Returns {next_r, next_c} of the first step.\n// Uses temp_grid for container obstacles.\n// Uses planned_pos for higher priority cranes, current_pos for lower priority.\npair<int, int> get_first_step(int start_r, int start_c, int target_r, int target_c, \n                              int k, bool holding, bool large,\n                              int planned_r[], int planned_c[], \n                              int current_r[], int current_c[],\n                              int temp_grid[][N]) {\n    if (start_r == target_r && start_c == target_c) return {-1, -1};\n\n    queue<tuple<int, int, int>> q; // r, c, dist\n    q.push({start_r, start_c, 0});\n    \n    int dist[N][N];\n    int pr[N][N], pc[N][N]; // parent\n    for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) {\n        dist[i][j] = INF;\n        pr[i][j] = pc[i][j] = -1;\n    }\n    dist[start_r][start_c] = 0;\n    \n    int dr[4] = {-1, 1, 0, 0};\n    int dc[4] = {0, 0, -1, 1};\n    \n    while(!q.empty()) {\n        auto [r, c, d] = q.front(); q.pop();\n        \n        // If we reached the target, reconstruct path\n        if (r == target_r && c == target_c) {\n            int curr_r = r, curr_c = c;\n            // Trace back until we hit the start\n            while (pr[curr_r][curr_c] != start_r || pc[curr_r][curr_c] != start_c) {\n                int tr = pr[curr_r][curr_c];\n                int tc = pc[curr_r][curr_c];\n                if (tr == -1) return {-1, -1}; // Should not happen if target reached\n                curr_r = tr; curr_c = tc;\n            }\n            return {curr_r, curr_c};\n        }\n\n        for(int i=0; i<4; ++i) {\n            int nr = r + dr[i];\n            int nc = c + dc[i];\n            \n            if (!valid(nr, nc)) continue;\n            if (dist[nr][nc] != INF) continue;\n            \n            // Check obstacles\n            // 1. Grid Container (only if small crane holding)\n            // We use temp_grid to account for intra-turn changes\n            if (!large && holding && temp_grid[nr][nc] != -1) continue;\n            \n            // 2. Cranes (MAPF Logic)\n            bool blocked = false;\n            for (int j = 0; j < 5; ++j) {\n                if (j == k) continue;\n                // For higher priority (j < k), use planned position\n                // For lower priority (j > k), use current position\n                int obs_r = (j < k) ? planned_r[j] : current_r[j];\n                int obs_c = (j < k) ? planned_c[j] : current_c[j];\n                \n                if (nr == obs_r && nc == obs_c) {\n                    blocked = true; \n                    break;\n                }\n            }\n            if (blocked) continue;\n            \n            dist[nr][nc] = d + 1;\n            pr[nr][nc] = r;\n            pc[nr][nc] = c;\n            q.push({nr, nc, d + 1});\n        }\n    }\n    return {-1, -1};\n}\n\nint main() {\n    // Fast I/O\n    cin.tie(nullptr); ios::sync_with_stdio(false);\n\n    int input_N;\n    if (!(cin >> input_N)) return 0;\n    \n    // Initialize Grid\n    memset(grid, -1, sizeof(grid));\n    \n    // Read Input\n    // A[i][j] is the j-th container brought into gate i.\n    // We don't need to store the whole matrix, but we need the receiving order.\n    // The input gives the full sequence.\n    vector<vector<int>> A(N, vector<int>(N));\n    for(int i=0; i<N; ++i)\n        for(int j=0; j<N; ++j)\n            cin >> A[i][j];\n\n    // Initial Crane State\n    for(int i=0; i<5; ++i) {\n        crane_r[i] = i;\n        crane_c[i] = 0;\n        crane_hold[i] = -1;\n        is_large[i] = (i == 0);\n    }\n    \n    // Dispatch and Receiving State\n    for(int i=0; i<5; ++i) {\n        dnext[i] = i * 5;\n        rptr[i] = 0;\n    }\n    \n    // Main Loop\n    for(int turn=1; turn<=10000; ++turn) {\n        \n        // --- Step 1: Receiving ---\n        for(int i=0; i<N; ++i) {\n            if (rptr[i] < N) {\n                // Check if receiving is blocked\n                bool blocked = false;\n                // 1. Container at (i, 0)?\n                if (grid[i][0] != -1) blocked = true;\n                // 2. Crane at (i, 0) holding container?\n                if (!blocked) {\n                    for(int k=0; k<5; ++k) {\n                        if (crane_r[k] == i && crane_c[k] == 0 && crane_hold[k] != -1) {\n                            blocked = true;\n                            break;\n                        }\n                    }\n                }\n                \n                if (!blocked) {\n                    grid[i][0] = A[i][rptr[i]];\n                    rptr[i]++;\n                }\n            }\n        }\n\n        // --- Step 2: Planning ---\n        char acts[5];\n        int planned_r[5], planned_c[5];\n        int current_r[5], current_c[5];\n        \n        for(int i=0; i<5; ++i) {\n            current_r[i] = crane_r[i];\n            current_c[i] = crane_c[i];\n            planned_r[i] = crane_r[i];\n            planned_c[i] = crane_c[i];\n            acts[i] = '.';\n        }\n\n        // Temp grid for simulation during planning\n        int temp_grid[N][N];\n        memcpy(temp_grid, grid, sizeof(grid));\n\n        // Priority: Large (0) -> Small (1..4)\n        int order[5] = {0, 1, 2, 3, 4};\n\n        for(int idx=0; idx<5; ++idx) {\n            int k = order[idx];\n            int r = current_r[k];\n            int c = current_c[k];\n            bool hold = (crane_hold[k] != -1);\n            bool large = is_large[k];\n            \n            int target_r = -1, target_c = -1;\n            char best_act = '.';\n            bool action_found = false;\n\n            // --- Priority 1: Unblock Receiving ---\n            // If at Col 0 and holding, MUST move away.\n            if (c == 0 && hold) {\n                // Try to move to Col 1.\n                target_r = r; target_c = 1;\n                // If Col 1 is blocked, BFS might fail. \n                // We rely on BFS to find *a* path out, but (r,1) is the target.\n                // If BFS fails to (r,1), we might need to try Up/Down.\n                // But for now, aiming for (r,1) is standard.\n            }\n\n            // --- Priority 2: Dispatch ---\n            if (!action_found && hold) {\n                int cid = crane_hold[k];\n                int target_row = cid / 5;\n                bool is_next = (cid == dnext[target_row]);\n                \n                if (r == target_row && c == 4) {\n                    // Already at dispatch gate. Drop if correct item.\n                    // Q action: valid if square empty of containers (checked by temp_grid)\n                    if (temp_grid[r][c] == -1) {\n                        best_act = 'Q';\n                        action_found = true;\n                        // Update temp_grid for subsequent agents\n                        temp_grid[r][c] = cid;\n                    }\n                } else {\n                    // Not at gate.\n                    if (is_next) {\n                        target_r = target_row; target_c = 4;\n                    } else {\n                        target_r = target_row; target_c = 3; // Buffer\n                    }\n                }\n            }\n\n            // --- Priority 3: Pickup ---\n            if (!action_found && !hold) {\n                // Pick up if standing on container\n                if (temp_grid[r][c] != -1) {\n                    best_act = 'P';\n                    action_found = true;\n                    temp_grid[r][c] = -1; // Remove from grid\n                } else {\n                    // Find nearest useful container\n                    int best_score = INF;\n                    int best_tr = -1, best_tc = -1;\n                    \n                    for(int rr=0; rr<N; ++rr) {\n                        for(int cc=0; cc<N; ++cc) {\n                            if (temp_grid[rr][cc] == -1) continue;\n                            int cid = temp_grid[rr][cc];\n                            \n                            // Check if held by anyone else (in reality)\n                            // Since temp_grid is updated, if it's here, it's not held.\n                            \n                            int row = cid / 5;\n                            bool is_next = (cid == dnext[row]);\n                            \n                            int dist = abs(r - rr) + abs(c - cc);\n                            int score = dist - (is_next ? 500 : 0); // Bonus for needed item\n                            \n                            if (score < best_score) {\n                                best_score = score;\n                                best_tr = rr;\n                                best_tc = cc;\n                            }\n                        }\n                    }\n                    \n                    if (best_tr != -1) {\n                        target_r = best_tr;\n                        target_c = best_tc;\n                    }\n                }\n            }\n\n            // --- Priority 4: Move to Target ---\n            if (!action_found && target_r != -1) {\n                pair<int, int> res = get_first_step(r, c, target_r, target_c, k, hold, large,\n                                                    planned_r, planned_c, current_r, current_c, temp_grid);\n                if (res.first != -1) {\n                    int nr = res.first;\n                    int nc = res.second;\n                    \n                    if (nr < r) best_act = 'U';\n                    else if (nr > r) best_act = 'D';\n                    else if (nc < c) best_act = 'L';\n                    else if (nc > c) best_act = 'R';\n                    \n                    planned_r[k] = nr;\n                    planned_c[k] = nc;\n                    action_found = true;\n                }\n            }\n\n            // --- Priority 5: Drop to Unblock (Fallback) ---\n            // If stuck and holding, and not at Col 0 (blocking receiving)\n            if (!action_found && hold) {\n                if (temp_grid[r][c] == -1 && c != 0) {\n                    best_act = 'Q';\n                    action_found = true;\n                    temp_grid[r][c] = crane_hold[k];\n                }\n            }\n            \n            acts[k] = best_act;\n            // planned_r/c already updated if moved\n        }\n\n        // --- Execute ---\n        // Move\n        for(int k=0; k<5; ++k) {\n            if (acts[k] != 'P' && acts[k] != 'Q') {\n                crane_r[k] = planned_r[k];\n                crane_c[k] = planned_c[k];\n            }\n        }\n        \n        // Pick / Drop\n        for(int k=0; k<5; ++k) {\n            if (acts[k] == 'P') {\n                if (crane_hold[k] == -1 && grid[crane_r[k]][crane_c[k]] != -1) {\n                    crane_hold[k] = grid[crane_r[k]][crane_c[k]];\n                    grid[crane_r[k]][crane_c[k]] = -1;\n                }\n            } else if (acts[k] == 'Q') {\n                if (crane_hold[k] != -1 && grid[crane_r[k]][crane_c[k]] == -1) {\n                    grid[crane_r[k]][crane_c[k]] = crane_hold[k];\n                    crane_hold[k] = -1;\n                }\n            }\n        }\n\n        // Record moves\n        for(int k=0; k<5; ++k) moves[k] += acts[k];\n\n        // --- Step 3: Dispatch ---\n        bool all_done = true;\n        for(int i=0; i<N; ++i) {\n            if (grid[i][4] != -1) {\n                int cid = grid[i][4];\n                grid[i][4] = -1; // Remove\n                if (cid == dnext[i]) {\n                    dnext[i]++;\n                }\n            }\n            if (dnext[i] != i*5 + 5) all_done = false;\n        }\n        \n        if (all_done) break;\n    }\n\n    for(int i=0; i<5; ++i) cout << moves[i] << \"\\n\";\n    \n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n#pragma GCC optimize(\"O3,unroll-loops\")\n\nint N;\nint grid[20][20];\nint cur_r = 0, cur_c = 0;\nlong long load = 0;\nint turns = 0;\n\ninline int manhattan(int r1, int c1, int r2, int c2) {\n    return abs(r1 - r2) + abs(c1 - c2);\n}\n\nvoid output_move(char dir) {\n    cout << dir << \"\\n\";\n    turns++;\n    if (dir == 'U') cur_r--;\n    else if (dir == 'D') cur_r++;\n    else if (dir == 'L') cur_c--;\n    else if (dir == 'R') cur_c++;\n}\n\nvoid move_to(int tr, int tc) {\n    while (cur_r != tr) output_move(cur_r < tr ? 'D' : 'U');\n    while (cur_c != tc) output_move(cur_c < tc ? 'R' : 'L');\n}\n\nvoid do_load() {\n    if (grid[cur_r][cur_c] <= 0) return;\n    int d = grid[cur_r][cur_c];\n    cout << \"+\" << d << \"\\n\";\n    load += d;\n    grid[cur_r][cur_c] = 0;\n    turns++;\n}\n\nvoid do_unload() {\n    if (load <= 0) return;\n    int d = (int)min((long long)-grid[cur_r][cur_c], load);\n    cout << \"-\" << d << \"\\n\";\n    load -= d;\n    grid[cur_r][cur_c] += d;\n    turns++;\n}\n\nbool is_flat() {\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (grid[i][j] != 0) return false;\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N)) return 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> grid[i][j];\n\n    // Penalty per unit of remaining load after step 1.\n    // Balances immediate movement cost vs future load-carrying penalty.\n    const long long LOAD_PENALTY = 110;\n    const int TOP_K = 60;\n\n    // Pre-allocated candidate storage\n    struct Candidate {\n        int r, c, amt;\n        long long cost1;\n    };\n    vector<Candidate> cands;\n    cands.reserve(400);\n\n    while (!is_flat() && turns < 99000) {\n        cands.clear();\n\n        // 1. Collect all valid immediate targets\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (grid[i][j] == 0) continue;\n                if (load == 0 && grid[i][j] < 0) continue;\n                if (load > 0 && grid[i][j] > 0) continue;\n\n                int d = manhattan(cur_r, cur_c, i, j);\n                int amt = (load == 0) ? grid[i][j] : (int)min((long long)-grid[i][j], load);\n                long long cost1 = (long long)d * (100LL + load);\n                cands.push_back({i, j, amt, cost1});\n            }\n        }\n\n        if (cands.empty()) break;\n\n        // 2. Sort by immediate cost to process most promising first\n        sort(cands.begin(), cands.end(), [](const Candidate& a, const Candidate& b) {\n            return a.cost1 < b.cost1;\n        });\n        if (cands.size() > TOP_K) cands.resize(TOP_K);\n\n        // 3. Depth-2 Lookahead with Load Penalty\n        long long best_score = -1;\n        int best_r = -1, best_c = -1, best_amt = 0;\n\n        for (const auto& cand : cands) {\n            long long sim_load = (load == 0) ? load + cand.amt : load - cand.amt;\n            \n            // Simulate state change (backtracking avoids memcpy)\n            int orig_val = grid[cand.r][cand.c];\n            grid[cand.r][cand.c] = (load == 0) ? orig_val - cand.amt : orig_val + cand.amt;\n\n            // Find minimum cost for step 2 from the new state\n            long long min_cost2 = 2000000000000000000LL;\n            bool found_next = false;\n\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    if (grid[i][j] == 0) continue;\n                    if (sim_load == 0 && grid[i][j] < 0) continue;\n                    if (sim_load > 0 && grid[i][j] > 0) continue;\n\n                    int d2 = manhattan(cand.r, cand.c, i, j);\n                    long long cost2 = (long long)d2 * (100LL + sim_load);\n                    if (cost2 < min_cost2) {\n                        min_cost2 = cost2;\n                        found_next = true;\n                    }\n                }\n            }\n\n            long long step2_cost = found_next ? min_cost2 : 0;\n            long long total_score = cand.cost1 + step2_cost + LOAD_PENALTY * sim_load;\n\n            // Update best candidate\n            if (best_score == -1 || total_score < best_score || \n               (total_score == best_score && cand.amt > best_amt)) {\n                best_score = total_score;\n                best_r = cand.r;\n                best_c = cand.c;\n                best_amt = cand.amt;\n            }\n\n            // Backtrack simulation\n            grid[cand.r][cand.c] = orig_val;\n        }\n\n        // 4. Execute optimal move\n        move_to(best_r, best_c);\n        if (load == 0) do_load();\n        else do_unload();\n    }\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <cstring>\n#include <numeric>\n\n#pragma GCC optimize(\"O3,unroll-loops,fast-math\")\n\nusing namespace std;\n\n// Constants\nconst int MAX_SEEDS = 60;\nconst int MAX_M = 15;\nconst int GRID_SIZE = 36;\n\n// Global Data\nint N, M, T, SEED_COUNT;\nint X[MAX_SEEDS][MAX_M];\nint V[MAX_SEEDS], max_c[MAX_SEEDS];\nint L1_dist[MAX_SEEDS][MAX_SEEDS]; // Precomputed L1 distances\n\n// Grid\nint adj[GRID_SIZE][4], deg[GRID_SIZE];\nint P[GRID_SIZE]; \n\n// Buffers\nint selected_indices[36];\ndouble scores[MAX_SEEDS];\nint indices[MAX_SEEDS];\nbool pos_filled[GRID_SIZE];\nint grid_seed[GRID_SIZE];\nbool selected_used[36];\n\n// RNG\nmt19937 rng(42);\n\n// Helper to compute L1 distance\ninline int compute_l1_fast(int u, int v) {\n    int s = 0;\n    const int* xu = X[u];\n    const int* xv = X[v];\n    #pragma GCC ivdep\n    for (int l = 0; l < M; ++l) {\n        int d = xu[l] - xv[l];\n        s += (d < 0) ? -d : d;\n    }\n    return s;\n}\n\nvoid precompute_grid() {\n    memset(deg, 0, sizeof(deg));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int u = i * N + j;\n            if (j + 1 < N) {\n                int v = i * N + (j + 1);\n                adj[u][deg[u]++] = v;\n                adj[v][deg[v]++] = u;\n            }\n            if (i + 1 < N) {\n                int v = (i + 1) * N + j;\n                adj[u][deg[u]++] = v;\n                adj[v][deg[v]++] = u;\n            }\n        }\n    }\n}\n\nvoid precompute_distances() {\n    for (int i = 0; i < SEED_COUNT; ++i) {\n        L1_dist[i][i] = 0;\n        for (int j = i + 1; j < SEED_COUNT; ++j) {\n            int d = compute_l1_fast(i, j);\n            L1_dist[i][j] = L1_dist[j][i] = d;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> T)) return 0;\n    SEED_COUNT = 2 * N * (N - 1);\n    \n    // Read initial seeds\n    for (int i = 0; i < SEED_COUNT; ++i) {\n        V[i] = 0; max_c[i] = 0;\n        for (int j = 0; j < M; ++j) {\n            cin >> X[i][j];\n            V[i] += X[i][j];\n            if (X[i][j] > max_c[i]) max_c[i] = X[i][j];\n        }\n    }\n\n    precompute_grid();\n    \n    // Positions sorted by degree (high degree first for greedy initialization)\n    vector<int> pos_by_degree(GRID_SIZE);\n    iota(pos_by_degree.begin(), pos_by_degree.end(), 0);\n    sort(pos_by_degree.begin(), pos_by_degree.end(), [&](int a, int b) {\n        return deg[a] > deg[b];\n    });\n    \n    iota(indices, indices + SEED_COUNT, 0);\n    uniform_int_distribution<int> pos_dist(0, 35);\n    const double INV_MAX = 1.0 / rng.max();\n\n    // Dynamic Parameters\n    // alpha: bonus for seeds with high max coordinate (preserves specialists)\n    // lambda: weight for diversity in placement objective (encourages complementary pairing)\n    const double alphas[10]   = {60.0, 50.0, 40.0, 30.0, 25.0, 20.0, 15.0, 10.0, 5.0, 2.0};\n    const double lambdas[10]  = {1.5, 1.4, 1.3, 1.2, 1.1, 1.0, 0.9, 0.8, 0.7, 0.6};\n    // Iterations per round (balanced for 2.0s time limit)\n    const int iters[10]       = {450000, 450000, 400000, 350000, 300000, 300000, 250000, 250000, 200000, 150000};\n\n    for (int t = 0; t < T; ++t) {\n        double alpha = alphas[t];\n        double lambda = lambdas[t];\n        int MAX_ITER = iters[t];\n\n        precompute_distances();\n\n        // 1. Selection: Top 36 seeds by V + alpha * max_coordinate\n        for (int i = 0; i < SEED_COUNT; ++i) {\n            scores[i] = V[i] + alpha * max_c[i];\n        }\n        nth_element(indices, indices + 36, indices + SEED_COUNT, [&](int a, int b) {\n            return scores[a] > scores[b];\n        });\n        for (int i = 0; i < 36; ++i) selected_indices[i] = indices[i];\n\n        // 2. Greedy Initialization: Fill high-degree positions first\n        memset(pos_filled, 0, sizeof(pos_filled)); \n        memset(selected_used, 0, sizeof(selected_used)); \n        \n        for (int k = 0; k < 36; ++k) {\n            int pos = pos_by_degree[k];\n            \n            // Collect already placed neighbors\n            int occ_seeds[4];\n            int num_occ = 0;\n            for (int d = 0; d < deg[pos]; ++d) {\n                int nb = adj[pos][d];\n                if (pos_filled[nb]) occ_seeds[num_occ++] = grid_seed[nb];\n            }\n            \n            int best_seed_idx = -1; \n            double best_score = -1e18;\n            \n            // Find best unused seed for this position\n            for (int i = 0; i < 36; ++i) {\n                if (selected_used[i]) continue;\n                \n                int seed_id = selected_indices[i];\n                double current_score = 0.0;\n                \n                if (num_occ == 0) {\n                    current_score = V[seed_id] + alpha * max_c[seed_id];\n                } else {\n                    // Maximize sum of edge scores with placed neighbors\n                    current_score = num_occ * V[seed_id]; \n                    for (int n = 0; n < num_occ; ++n) {\n                        current_score += lambda * L1_dist[seed_id][occ_seeds[n]];\n                    }\n                }\n                \n                if (current_score > best_score) {\n                    best_score = current_score;\n                    best_seed_idx = i;\n                }\n            }\n            \n            if (best_seed_idx != -1) {\n                selected_used[best_seed_idx] = true;\n                grid_seed[pos] = selected_indices[best_seed_idx];\n                pos_filled[pos] = true;\n            }\n        }\n        \n        for(int i = 0; i < 36; ++i) P[i] = grid_seed[i];\n\n        // 3. Simulated Annealing\n        double temp = 1000.0;\n        const double cool_factor = 0.99996; \n        \n        for (int iter = 0; iter < MAX_ITER; ++iter) {\n            temp *= cool_factor;\n            if (temp < 0.01) temp = 0.01; \n\n            int p1 = pos_dist(rng);\n            int p2 = pos_dist(rng);\n            if (p1 == p2) continue;\n\n            int u1 = P[p1], u2 = P[p2];\n            int v_diff = V[u2] - V[u1];\n            double delta = 0.0;\n            \n            // Delta for edges incident to p1\n            for (int k = 0; k < deg[p1]; ++k) {\n                int nb = adj[p1][k];\n                if (nb == p2) continue; \n                int nb_seed = P[nb];\n                delta += v_diff + lambda * (L1_dist[u2][nb_seed] - L1_dist[u1][nb_seed]);\n            }\n            // Delta for edges incident to p2\n            for (int k = 0; k < deg[p2]; ++k) {\n                int nb = adj[p2][k];\n                if (nb == p1) continue;\n                int nb_seed = P[nb];\n                delta += -v_diff + lambda * (L1_dist[u1][nb_seed] - L1_dist[u2][nb_seed]);\n            }\n\n            // Metropolis criterion\n            if (delta > 0.0 || std::exp(delta / temp) > rng() * INV_MAX) {\n                P[p1] = u2;\n                P[p2] = u1;\n            }\n        }\n\n        // 4. Output\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                cout << P[i * N + j] << (j == N - 1 ? \"\" : \" \");\n            }\n            cout << \"\\n\";\n        }\n        cout.flush();\n\n        // 5. Read next generation\n        if (t < T - 1) {\n            for (int i = 0; i < SEED_COUNT; ++i) {\n                V[i] = 0; max_c[i] = 0;\n                for (int j = 0; j < M; ++j) {\n                    cin >> X[i][j];\n                    V[i] += X[i][j];\n                    if (X[i][j] > max_c[i]) max_c[i] = X[i][j];\n                }\n            }\n        }\n    }\n\n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n\nusing namespace std;\n\n// Global variables\nint N, M, V;\nvector<string> T_grid;\nvector<vector<int>> grid;\nint finger_dir[20]; \nbool holding[20];   \n\n// Directions: 0:R, 1:D, 2:L, 3:U\nconst int dx[4] = {0, 1, 0, -1};\nconst int dy[4] = {1, 0, -1, 0};\n\nint dist[35][35];\nint par_r[35][35];\nint par_c[35][35];\n\nstruct Pos { int r, c; };\n\n// Check if (r, c) is a valid root position given current carried count\n// A root position is valid if it has a neighbor that allows an action compatible with carried\ninline bool is_valid_root(int r, int c, int carried) {\n    bool need_p = (carried < V - 1);\n    bool need_d = (carried > 0);\n    for (int d = 0; d < 4; ++d) {\n        int nr = r + dx[d], nc = c + dy[d];\n        if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n            // Pickup: grid has item, target does not (misplaced item)\n            if (need_p && grid[nr][nc] == 1 && T_grid[nr][nc] == '0') return true;\n            // Drop: grid empty, target needs item\n            if (need_d && grid[nr][nc] == 0 && T_grid[nr][nc] == '1') return true;\n        }\n    }\n    return false;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> V)) return 0;\n    T_grid.resize(N); \n    grid.assign(N, vector<int>(N, 0));\n    \n    string s_row;\n    for (int i = 0; i < N; ++i) {\n        cin >> s_row;\n        for (int j = 0; j < N; ++j) {\n            if (s_row[j] == '1') grid[i][j] = 1;\n        }\n    }\n    for (int i = 0; i < N; ++i) cin >> T_grid[i];\n\n    // Output tree design: Star graph with root 0 and leaves 1..V-1\n    cout << V << \"\\n\";\n    for (int i = 1; i < V; ++i) cout << \"0 1\\n\";\n    cout << \"0 0\\n\"; \n    int rx = 0, ry = 0;\n\n    // Initialize fingers\n    for (int i = 0; i < V; ++i) {\n        finger_dir[i] = 0; // Point Right initially\n        holding[i] = false;\n    }\n\n    int turn = 0;\n    while (turn < 100000) {\n        // Count currently held items\n        int carried = 0;\n        for(int i=0; i<V; ++i) if(holding[i]) carried++;\n\n        // Check if all items are in target positions\n        bool done = true;\n        if (carried == 0) {\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    if (grid[i][j] != (T_grid[i][j] - '0')) {\n                        done = false;\n                        break;\n                    }\n                }\n                if (!done) break;\n            }\n        } else {\n            done = false;\n        }\n        \n        if (done) break;\n\n        // BFS to find nearest valid root position\n        for (int i = 0; i < N; ++i) {\n            fill(dist[i], dist[i] + N, -1);\n        }\n        queue<Pos> q;\n        q.push({rx, ry});\n        dist[rx][ry] = 0;\n        par_r[rx][ry] = -1; par_c[rx][ry] = -1;\n        \n        Pos target = {rx, ry};\n        bool found = false;\n\n        // Check if current position is valid\n        if (is_valid_root(rx, ry, carried)) {\n            found = true;\n        } else {\n            while (!q.empty()) {\n                Pos u = q.front(); q.pop();\n                \n                // If this position allows an action, it's a valid target\n                if (is_valid_root(u.r, u.c, carried)) {\n                    target = u;\n                    found = true;\n                    break;\n                }\n                \n                int d_u = dist[u.r][u.c];\n                for (int d = 0; d < 4; ++d) {\n                    int nr = u.r + dx[d], nc = u.c + dy[d];\n                    if (nr >= 0 && nr < N && nc >= 0 && nc < N && dist[nr][nc] == -1) {\n                        dist[nr][nc] = d_u + 1;\n                        par_r[nr][nc] = u.r;\n                        par_c[nr][nc] = u.c;\n                        q.push({nr, nc});\n                    }\n                }\n            }\n        }\n        \n        // Move Root 1 step towards target\n        char move_cmd = '.';\n        if (found) {\n            if (target.r != rx || target.c != ry) {\n                // Reconstruct path to find first step\n                Pos curr = target;\n                while (dist[curr.r][curr.c] > 1) {\n                    curr = {par_r[curr.r][curr.c], par_c[curr.r][curr.c]};\n                }\n                int dr = curr.r - rx;\n                int dc = curr.c - ry;\n                if (dr == 1) move_cmd = 'D';\n                else if (dr == -1) move_cmd = 'U';\n                else if (dc == 1) move_cmd = 'R';\n                else if (dc == -1) move_cmd = 'L';\n                rx = curr.r; ry = curr.c;\n            }\n        }\n\n        string cmd(2 * V, '.');\n        cmd[0] = move_cmd;\n        \n        // Recompute carried for sequential finger processing\n        int current_carried = 0;\n        for(int i=0; i<V; ++i) if(holding[i]) current_carried++;\n\n        // Process fingertips sequentially (1 to V-1)\n        for (int f = 1; f < V; ++f) {\n            struct Cand { int d; bool is_drop; int cost; };\n            vector<Cand> cands;\n            cands.reserve(4);\n            \n            for (int d = 0; d < 4; ++d) {\n                int nr = rx + dx[d], nc = ry + dy[d];\n                if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n                \n                // Check capacity constraints\n                bool can_pick = (!holding[f] && current_carried < V - 1);\n                bool can_drop = (holding[f] && current_carried > 0);\n                \n                // Check grid state\n                bool is_source = (grid[nr][nc] == 1 && T_grid[nr][nc] == '0');\n                bool is_sink = (grid[nr][nc] == 0 && T_grid[nr][nc] == '1');\n                \n                if (can_pick && is_source) {\n                    int diff = (d - finger_dir[f] + 4) % 4;\n                    int cost = min(diff, 4 - diff);\n                    cands.push_back({d, false, cost});\n                }\n                if (can_drop && is_sink) {\n                    int diff = (d - finger_dir[f] + 4) % 4;\n                    int cost = min(diff, 4 - diff);\n                    cands.push_back({d, true, cost});\n                }\n            }\n            \n            if (cands.empty()) {\n                cmd[f] = '.';\n                cmd[V + f] = '.';\n                continue;\n            }\n            \n            // Sort candidates: prefer lower rotation cost, then prefer drops\n            sort(cands.begin(), cands.end(), [](const Cand& a, const Cand& b) {\n                if (a.cost != b.cost) return a.cost < b.cost;\n                return a.is_drop > b.is_drop;\n            });\n            \n            Cand best = cands[0];\n            int diff = (best.d - finger_dir[f] + 4) % 4;\n            char rot = '.';\n            // Determine rotation command\n            if (diff == 1) rot = 'R';\n            else if (diff == 2) rot = 'R'; // 180 deg, rotate 90 CW\n            else if (diff == 3) rot = 'L';\n            \n            cmd[f] = rot;\n            \n            // Simulate new direction after rotation\n            int new_dir = finger_dir[f];\n            if (rot == 'R') new_dir = (new_dir + 1) % 4;\n            else if (rot == 'L') new_dir = (new_dir + 3) % 4;\n            \n            // Action is possible if finger ends up pointing to target direction\n            // This is true if diff != 2 (i.e., 0, 1, or 3)\n            bool can_act = (diff != 2);\n            \n            if (can_act) {\n                cmd[V + f] = 'P';\n                if (best.is_drop) {\n                    grid[rx + dx[best.d]][ry + dy[best.d]] = 1;\n                    holding[f] = false;\n                    current_carried--;\n                } else {\n                    grid[rx + dx[best.d]][ry + dy[best.d]] = 0;\n                    holding[f] = true;\n                    current_carried++;\n                }\n                finger_dir[f] = best.d; // Update to target direction\n            } else {\n                finger_dir[f] = new_dir; // Updated to intermediate direction\n            }\n        }\n        \n        cout << cmd << \"\\n\";\n        turn++;\n    }\n\n    return 0;\n}","ahc039":"#include <iostream>\n#include <vector>\n#include <random>\n#include <cmath>\n#include <algorithm>\n#include <map>\n#include <queue>\n\nusing namespace std;\n\nstruct Pt {\n    int x, y;\n    bool operator==(const Pt& o) const { return x == o.x && y == o.y; }\n    bool operator!=(const Pt& o) const { return !(*this == o); }\n    bool operator<(const Pt& o) const { return x != o.x ? x < o.x : y < o.y; }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    if (!(cin >> N)) return 0;\n    vector<Pt> mack(N), sard(N);\n    for (int i = 0; i < N; ++i) cin >> mack[i].x >> mack[i].y;\n    for (int i = 0; i < N; ++i) cin >> sard[i].x >> sard[i].y;\n\n    // Grid parameters: D=400 balances resolution and convergence speed\n    const int D = 400;\n    const int G = 100000 / D + 2;\n    vector<vector<int>> grid(G, vector<int>(G, 0));\n\n    auto add_points = [&](const vector<Pt>& pts, int val) {\n        for (auto& p : pts) {\n            int cx = p.x / D, cy = p.y / D;\n            if (cx >= 0 && cx < G && cy >= 0 && cy < G) {\n                grid[cy][cx] += val;\n            }\n        }\n    };\n    add_points(mack, 1);\n    add_points(sard, -1);\n\n    mt19937 rng(42);\n    double T = 80.0;\n    int iters = 600000;\n\n    // Initialize with the highest-weight single cell\n    int best_r = 0, best_c = 0, best_w = -1e9;\n    for (int r = 0; r < G; ++r) {\n        for (int c = 0; c < G; ++c) {\n            if (grid[r][c] > best_w) {\n                best_w = grid[r][c]; best_r = r; best_c = c;\n            }\n        }\n    }\n\n    vector<vector<bool>> sel(G, vector<bool>(G, false));\n    if (best_w > 0) sel[best_r][best_c] = true;\n\n    const int dr[4] = {-1, 1, 0, 0};\n    const int dc[4] = {0, 0, -1, 1};\n\n    // Simulated Annealing\n    for (int it = 0; it < iters; ++it) {\n        T *= 0.999985;\n        if (T < 0.05) T = 0.05;\n\n        int r = rng() % G;\n        int c = rng() % G;\n\n        bool is_sel = sel[r][c];\n        bool can_move = false;\n\n        if (!is_sel) {\n            // Can only add if adjacent to selected region\n            for (int i = 0; i < 4; ++i) {\n                int nr = r + dr[i], nc = c + dc[i];\n                if (nr >= 0 && nr < G && nc >= 0 && nc < G && sel[nr][nc]) {\n                    can_move = true; break;\n                }\n            }\n        } else {\n            // Can only remove if on boundary\n            for (int i = 0; i < 4; ++i) {\n                int nr = r + dr[i], nc = c + dc[i];\n                if (nr < 0 || nr >= G || nc < 0 || nc >= G || !sel[nr][nc]) {\n                    can_move = true; break;\n                }\n            }\n        }\n\n        if (!can_move) continue;\n\n        int delta = is_sel ? -grid[r][c] : grid[r][c];\n        double prob = 0.0;\n        if (delta > 0) prob = 1.0;\n        else {\n            double val = delta / T;\n            if (val < -50.0) val = -50.0;\n            if (val > 50.0) val = 50.0;\n            prob = exp(val);\n        }\n\n        uniform_real_distribution<double> dist(0.0, 1.0);\n        if (dist(rng) < prob) {\n            sel[r][c] = !is_sel;\n        }\n    }\n\n    // Post-processing 1: Keep largest 4-connected component\n    vector<vector<bool>> final_sel(G, vector<bool>(G, false));\n    vector<vector<bool>> visited(G, vector<bool>(G, false));\n    int sr = -1, sc = -1;\n    for (int r = 0; r < G; ++r) {\n        for (int c = 0; c < G; ++c) {\n            if (sel[r][c]) { sr = r; sc = c; r = G; break; }\n        }\n    }\n\n    if (sr != -1) {\n        queue<pair<int, int>> q;\n        q.emplace(sr, sc);\n        visited[sr][sc] = true;\n        while (!q.empty()) {\n            auto [r, c] = q.front(); q.pop();\n            final_sel[r][c] = true;\n            for (int i = 0; i < 4; ++i) {\n                int nr = r + dr[i], nc = c + dc[i];\n                if (nr >= 0 && nr < G && nc >= 0 && nc < G && sel[nr][nc] && !visited[nr][nc]) {\n                    visited[nr][nc] = true;\n                    q.emplace(nr, nc);\n                }\n            }\n        }\n    }\n\n    // Post-processing 2: Fill internal holes via outside flood-fill\n    vector<vector<bool>> outside(G, vector<bool>(G, false));\n    queue<pair<int, int>> q_out;\n    for (int c = 0; c < G; ++c) {\n        if (!final_sel[0][c]) { outside[0][c] = true; q_out.emplace(0, c); }\n        if (!final_sel[G-1][c]) { outside[G-1][c] = true; q_out.emplace(G-1, c); }\n    }\n    for (int r = 0; r < G; ++r) {\n        if (!final_sel[r][0]) { outside[r][0] = true; q_out.emplace(r, 0); }\n        if (!final_sel[r][G-1]) { outside[r][G-1] = true; q_out.emplace(r, G-1); }\n    }\n    while (!q_out.empty()) {\n        auto [r, c] = q_out.front(); q_out.pop();\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i], nc = c + dc[i];\n            if (nr >= 0 && nr < G && nc >= 0 && nc < G && !final_sel[nr][nc] && !outside[nr][nc]) {\n                outside[nr][nc] = true;\n                q_out.emplace(nr, nc);\n            }\n        }\n    }\n    for (int r = 0; r < G; ++r) {\n        for (int c = 0; c < G; ++c) {\n            if (!final_sel[r][c] && !outside[r][c]) {\n                final_sel[r][c] = true;\n            }\n        }\n    }\n\n    // Edge extraction: interior edges cancel out, boundary edges remain\n    map<pair<Pt, Pt>, int> edge_cnt;\n    auto add_edge = [&](Pt u, Pt v) {\n        if (u.x > v.x || (u.x == v.x && u.y > v.y)) swap(u, v);\n        edge_cnt[{u, v}]++;\n    };\n\n    for (int r = 0; r < G; ++r) {\n        for (int c = 0; c < G; ++c) {\n            if (final_sel[r][c]) {\n                Pt p1 = {c * D, r * D};\n                Pt p2 = {min((c + 1) * D, 100000), r * D};\n                Pt p3 = {min((c + 1) * D, 100000), min((r + 1) * D, 100000)};\n                Pt p4 = {c * D, min((r + 1) * D, 100000)};\n                add_edge(p1, p2); add_edge(p2, p3);\n                add_edge(p3, p4); add_edge(p4, p1);\n            }\n        }\n    }\n\n    // Build adjacency graph for tracing\n    map<Pt, vector<Pt>> adj;\n    for (auto& [e, cnt] : edge_cnt) {\n        if (cnt % 2 == 1) {\n            adj[e.first].push_back(e.second);\n            adj[e.second].push_back(e.first);\n        }\n    }\n\n    // Trace the polygon boundary\n    vector<Pt> poly;\n    if (!adj.empty()) {\n        Pt curr = adj.begin()->first;\n        Pt prev = {-1, -1};\n        int steps = 0;\n        while (steps < 100000) {\n            poly.push_back(curr);\n            Pt next = {-1, -1};\n            for (auto& nb : adj[curr]) {\n                if (nb != prev) {\n                    next = nb;\n                    break;\n                }\n            }\n            prev = curr;\n            curr = next;\n            if (curr == poly[0] || curr.x < 0) break;\n            steps++;\n        }\n    }\n\n    // Remove collinear vertices\n    vector<Pt> simplified;\n    int m = poly.size();\n    if (m >= 3) {\n        for (int i = 0; i < m; ++i) {\n            Pt prev = poly[(i - 1 + m) % m];\n            Pt curr = poly[i];\n            Pt next = poly[(i + 1) % m];\n            long long dx1 = curr.x - prev.x;\n            long long dy1 = curr.y - prev.y;\n            long long dx2 = next.x - curr.x;\n            long long dy2 = next.y - curr.y;\n            if (dx1 * dy2 != dx2 * dy1) {\n                if (simplified.empty() || !(curr == simplified.back())) {\n                    simplified.push_back(curr);\n                }\n            }\n        }\n    }\n    if (simplified.empty() && !poly.empty()) simplified = poly;\n\n    // Final deduplication and formatting\n    vector<Pt> final_poly;\n    for (auto& p : simplified) {\n        if (final_poly.empty() || !(p == final_poly.back())) {\n            final_poly.push_back(p);\n        }\n    }\n    if (final_poly.size() > 1 && final_poly.front() == final_poly.back()) {\n        final_poly.pop_back();\n    }\n\n    // Ensure minimum vertex count and valid bounds\n    if (final_poly.size() < 4) {\n        final_poly = {{0, 0}, {D, 0}, {D, D}, {0, D}};\n    }\n\n    cout << final_poly.size() << \"\\n\";\n    for (auto& p : final_poly) {\n        cout << p.x << \" \" << p.y << \"\\n\";\n    }\n\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n#pragma GCC optimize(\"O3,unroll-loops\")\n\nconstexpr int MAXN = 105;\n// Use long long for coordinates and dimensions to prevent overflow\nlong long W_obs[MAXN], H_obs[MAXN];\nbool skipped[MAXN], rot[MAXN];\nchar dir[MAXN]; \nint ref_idx[MAXN]; \n\nlong long px[MAXN], py[MAXN], pw[MAXN], ph[MAXN];\n\n// Best config storage\nlong long best_cost = -1;\nbool best_skipped[MAXN], best_rot[MAXN];\nchar best_dir[MAXN];\nint best_ref[MAXN];\n\nmt19937_64 rng(42);\n\n// Fast deterministic simulation\n// Logic:\n// - 'U': Aligns x with ref's right edge (or 0). Moves Up (decreasing y) until \n//   it hits y=0 or the bottom edge of an overlapping rectangle.\n//   Stopping at bottom edge (py[j] + ph[j]) means placing the new rectangle BELOW it.\n// - 'L': Aligns y with ref's bottom edge (or 0). Moves Left (decreasing x) until\n//   it hits x=0 or the right edge of an overlapping rectangle.\n//   Stopping at right edge (px[j] + pw[j]) means placing the new rectangle to the RIGHT of it.\nlong long evaluate(int N, long long& skip_pen) {\n    long long max_x = 0, max_y = 0;\n    skip_pen = 0;\n    for (int i = 0; i < N; ++i) {\n        if (skipped[i]) {\n            skip_pen += W_obs[i] + H_obs[i];\n            px[i] = py[i] = pw[i] = ph[i] = 0;\n            continue;\n        }\n        \n        // Set dimensions\n        if (rot[i]) { pw[i] = H_obs[i]; ph[i] = W_obs[i]; }\n        else { pw[i] = W_obs[i]; ph[i] = H_obs[i]; }\n        \n        long long x = 0, y = 0;\n        int r = ref_idx[i];\n        // Check if ref is valid (index < i and not skipped)\n        // If invalid, treat as -1 (alignment with 0)\n        bool ref_valid = (r != -1 && r < i && !skipped[r]);\n        \n        if (ref_valid) {\n            if (dir[i] == 'U') x = px[r] + pw[r];\n            else y = py[r] + ph[r];\n        }\n        \n        long long final_x = x, final_y = y;\n        \n        if (dir[i] == 'U') {\n            // x is fixed. Find lowest valid y (closest to 0).\n            // Blocked by bottom edges of overlapping rects.\n            long long limit = 0;\n            for (int j = 0; j < i; ++j) {\n                if (skipped[j]) continue;\n                // Check x overlap: [final_x, final_x + pw[i]) vs [px[j], px[j] + pw[j])\n                if (final_x < px[j] + pw[j] && px[j] < final_x + pw[i]) {\n                    long long bot = py[j] + ph[j];\n                    if (bot > limit) limit = bot;\n                }\n            }\n            final_y = limit;\n        } else { // 'L'\n            // y is fixed. Find leftmost valid x (closest to 0).\n            // Blocked by right edges of overlapping rects.\n            long long limit = 0;\n            for (int j = 0; j < i; ++j) {\n                if (skipped[j]) continue;\n                // Check y overlap: [final_y, final_y + ph[i]) vs [py[j], py[j] + ph[j])\n                if (final_y < py[j] + ph[j] && py[j] < final_y + ph[i]) {\n                    long long right = px[j] + pw[j];\n                    if (right > limit) limit = right;\n                }\n            }\n            final_x = limit;\n        }\n        \n        px[i] = final_x;\n        py[i] = final_y;\n        \n        if (px[i] + pw[i] > max_x) max_x = px[i] + pw[i];\n        if (py[i] + ph[i] > max_y) max_y = py[i] + ph[i];\n    }\n    return max_x + max_y + skip_pen;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    int N, T, sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n    \n    for (int i = 0; i < N; ++i) {\n        cin >> W_obs[i] >> H_obs[i];\n        skipped[i] = false; // Start with all placed\n        rot[i] = (rng() & 1);\n        dir[i] = (rng() & 1) ? 'U' : 'L';\n        ref_idx[i] = (i > 0 && rng() % 3 != 0) ? (rng() % i) : -1;\n    }\n\n    long long skip_pen;\n    long long cur_cost = evaluate(N, skip_pen);\n    best_cost = cur_cost;\n    \n    // Save initial best\n    memcpy(best_skipped, skipped, N);\n    memcpy(best_rot, rot, N);\n    memcpy(best_dir, dir, N);\n    memcpy(best_ref, ref_idx, N * sizeof(int));\n\n    auto start = chrono::steady_clock::now();\n    int iter = 0;\n    double temp = 8000.0;\n\n    for (int turn = 0; turn < T; ++turn) {\n        if (turn > 0) { int w, h; cin >> w >> h; } // Read feedback (ignored due to noise)\n        \n        // Check time\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double, std::milli>(now - start).count();\n        \n        // Run SA if time permits\n        if (elapsed < 2700.0) {\n            while (true) {\n                iter++;\n                // Check time periodically to reduce overhead\n                if ((iter & 255) == 0) {\n                    now = chrono::steady_clock::now();\n                    elapsed = chrono::duration<double, std::milli>(now - start).count();\n                    if (elapsed > 2700.0) break;\n                }\n    \n                int i = rng() % N;\n                // Backup state for rollback\n                bool b_sk = skipped[i], b_ro = rot[i];\n                char b_di = dir[i];\n                int b_re = ref_idx[i];\n    \n                int mt = rng() % 100;\n                if (mt < 20) skipped[i] ^= 1;\n                else if (mt < 40) rot[i] ^= 1;\n                else if (mt < 60) dir[i] = (dir[i] == 'U' ? 'L' : 'U');\n                else if (mt < 90) {\n                    if (i > 0) ref_idx[i] = rng() % i;\n                    else ref_idx[i] = -1;\n                } else ref_idx[i] = -1;\n    \n                // Note: ref_idx might point to a skipped rectangle or be out of bounds (unlikely with rng%i)\n                // The evaluate function handles invalid refs by treating them as -1.\n                // We don't modify ref_idx array here to allow restoring invalid states if rejected.\n    \n                long long next_cost = evaluate(N, skip_pen);\n                double delta = (double)next_cost - cur_cost;\n                \n                // Metropolis acceptance\n                bool accept = false;\n                if (delta < 0) accept = true;\n                else {\n                    double prob = exp(max(-50.0, -delta / temp));\n                    if ((double)(rng() & 0xFFFFFF) / 0xFFFFFF < prob) accept = true;\n                }\n    \n                if (accept) {\n                    cur_cost = next_cost;\n                    if (cur_cost < best_cost) {\n                        best_cost = cur_cost;\n                        memcpy(best_skipped, skipped, N);\n                        memcpy(best_rot, rot, N);\n                        memcpy(best_dir, dir, N);\n                        memcpy(best_ref, ref_idx, N * sizeof(int));\n                    }\n                } else {\n                    // Revert\n                    skipped[i] = b_sk; rot[i] = b_ro; dir[i] = b_di; ref_idx[i] = b_re;\n                }\n                \n                // Smooth cooling\n                temp *= 0.99995;\n            }\n        }\n        \n        // Restore best config for output\n        memcpy(skipped, best_skipped, N);\n        memcpy(rot, best_rot, N);\n        memcpy(dir, best_dir, N);\n        memcpy(ref_idx, best_ref, N * sizeof(int));\n        \n        // Sanitize references for output:\n        // Must point to a previously placed rectangle (index < i and not skipped)\n        for(int i = 0; i < N; ++i) {\n            if (!skipped[i]) {\n                if (ref_idx[i] != -1) {\n                    if (ref_idx[i] >= i || skipped[ref_idx[i]]) {\n                        ref_idx[i] = -1;\n                    }\n                }\n            }\n        }\n        \n        int n_place = 0;\n        for(int i = 0; i < N; ++i) if(!skipped[i]) n_place++;\n        \n        // Safety fallback if all skipped\n        if (n_place == 0) {\n            skipped[0] = false; \n            ref_idx[0] = -1;\n            dir[0] = 'U';\n            rot[0] = false;\n            n_place = 1;\n        }\n        \n        cout << n_place << \"\\n\";\n        for(int i = 0; i < N; ++i) {\n            if(!skipped[i]) {\n                cout << i << \" \" << rot[i] << \" \" << dir[i] << \" \" << ref_idx[i] << \"\\n\";\n            }\n        }\n        cout.flush();\n    }\n    return 0;\n}","ahc041":"#pragma GCC optimize(\"O3,unroll-loops\")\n#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <chrono>\n#include <random>\n#include <cstring>\n\nusing namespace std;\n\nconst int MAXN = 1005;\nconst int INF = 1e9;\n\nint dist_mat[MAXN][MAXN];\nint A[MAXN];\nvector<int> adj[MAXN];\nint N, M, H;\n\nint d1[MAXN], d2[MAXN], r1[MAXN], d_buf[MAXN];\nint roots_arr[MAXN];\nint num_roots = 0;\nbool is_root_arr[MAXN] = {false};\n\nint best_roots_arr[MAXN];\nint best_num_roots = 0;\nlong long global_best_score = -1;\n\n// Evaluate from scratch (used in initialization and final output)\nlong long evaluate(int* d, const int* r_arr, int n_r) {\n    for (int i = 0; i < N; ++i) d[i] = H + 1;\n    for (int i = 0; i < n_r; ++i) {\n        int r = r_arr[i];\n        const int* dr = dist_mat[r];\n        for (int j = 0; j < N; ++j) {\n            if (dr[j] < d[j]) d[j] = dr[j];\n        }\n    }\n    long long score = 0;\n    for (int i = 0; i < N; ++i) {\n        if (d[i] > H) return -1;\n        score += (long long)(d[i] + 1) * A[i];\n    }\n    return score;\n}\n\n// Maintain 1st and 2nd closest roots for fast evaluation\nvoid compute_d1_d2() {\n    for (int i = 0; i < N; ++i) {\n        d1[i] = INF; d2[i] = INF; r1[i] = -1;\n    }\n    for (int i = 0; i < num_roots; ++i) {\n        int r = roots_arr[i];\n        const int* dr = dist_mat[r];\n        for (int u = 0; u < N; ++u) {\n            int d = dr[u];\n            if (d < d1[u]) {\n                d2[u] = d1[u];\n                d1[u] = d;\n                r1[u] = r;\n            } else if (d < d2[u]) {\n                d2[u] = d;\n            }\n        }\n    }\n}\n\n// Evaluate if root r is removed\ninline long long evaluate_fast_remove(int r) {\n    long long score = 0;\n    for (int u = 0; u < N; ++u) {\n        int new_d = (r1[u] == r) ? d2[u] : d1[u];\n        if (new_d > H) return -1;\n        score += (long long)(new_d + 1) * A[u];\n    }\n    return score;\n}\n\n// Evaluate if root old_r is moved to new_r\ninline long long evaluate_fast_move(int old_r, int new_r) {\n    long long score = 0;\n    const int* d_new = dist_mat[new_r];\n    for (int u = 0; u < N; ++u) {\n        int best_other = (r1[u] == old_r) ? d2[u] : d1[u];\n        int new_d = best_other;\n        if (d_new[u] < new_d) new_d = d_new[u];\n        if (new_d > H) return -1;\n        score += (long long)(new_d + 1) * A[u];\n    }\n    return score;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    auto start_time = chrono::steady_clock::now();\n    if (!(cin >> N >> M >> H)) return 0;\n\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); adj[v].push_back(u);\n    }\n    for (int i = 0; i < N; ++i) { int x, y; cin >> x >> y; }\n\n    // APSP using BFS\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) dist_mat[i][j] = INF;\n        queue<int> q;\n        dist_mat[i][i] = 0;\n        q.push(i);\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            int nd = dist_mat[i][u] + 1;\n            for (int v : adj[u]) {\n                if (nd < dist_mat[i][v]) {\n                    dist_mat[i][v] = nd;\n                    q.push(v);\n                }\n            }\n        }\n    }\n\n    mt19937 rng(42);\n    auto get_time = [&]() { return chrono::duration<double>(chrono::steady_clock::now() - start_time).count(); };\n    const double TIME_LIMIT = 1.85;\n\n    // Greedy Initialization\n    vector<int> d(N, INF);\n    while (true) {\n        if (get_time() > 1.0) break;\n        int best_v = -1, min_A = INF;\n        bool all_covered = true;\n        for (int i = 0; i < N; ++i) {\n            if (d[i] > H) {\n                all_covered = false;\n                if (A[i] < min_A) { min_A = A[i]; best_v = i; }\n            }\n        }\n        if (all_covered) break;\n\n        int cands[MAXN];\n        int num_cands = 0;\n        for (int r = 0; r < N; ++r) {\n            if (dist_mat[r][best_v] <= H) cands[num_cands++] = r;\n            if (num_cands >= 30) break;\n        }\n        sort(cands, cands + num_cands, [](int a, int b) { return A[a] < A[b]; });\n\n        int K = min(num_cands, 20);\n        int best_r = -1;\n        long long best_sc = -1;\n        \n        vector<int> tmp_d(N);\n        for (int i = 0; i < K; ++i) {\n            int r = cands[i];\n            long long sc = 0;\n            bool ok = true;\n            for (int u = 0; u < N; ++u) {\n                int nd = d[u];\n                if (dist_mat[r][u] < nd) nd = dist_mat[r][u];\n                if (nd > H) { ok = false; break; }\n                sc += (long long)(nd + 1) * A[u];\n            }\n            if (ok && sc > best_sc) { best_sc = sc; best_r = r; }\n        }\n\n        if (best_r != -1) {\n            roots_arr[num_roots++] = best_r;\n            is_root_arr[best_r] = true;\n            for (int u = 0; u < N; ++u) {\n                int nd = d[u];\n                if (dist_mat[best_r][u] < nd) nd = dist_mat[best_r][u];\n                d[u] = nd;\n            }\n        } else {\n            for (int i = 0; i < num_cands; ++i) {\n                int r = cands[i];\n                roots_arr[num_roots++] = r;\n                is_root_arr[r] = true;\n                for (int u = 0; u < N; ++u) {\n                    int nd = d[u];\n                    if (dist_mat[r][u] < nd) nd = dist_mat[r][u];\n                    d[u] = nd;\n                }\n                break;\n            }\n        }\n    }\n\n    global_best_score = evaluate(d_buf, roots_arr, num_roots);\n    best_num_roots = num_roots;\n    memcpy(best_roots_arr, roots_arr, num_roots * sizeof(int));\n    compute_d1_d2();\n\n    long long cur_score = global_best_score;\n    int order[MAXN];\n    int tmp_nb[MAXN];\n    \n    // Local Search\n    while (get_time() < TIME_LIMIT) {\n        bool improved = false;\n        \n        for(int i=0; i<num_roots; ++i) order[i] = i;\n        shuffle(order, order + num_roots, rng);\n\n        for (int k = 0; k < num_roots; ++k) {\n            int idx = order[k];\n            int r = roots_arr[idx];\n            \n            // Try Remove\n            if (num_roots > 1) {\n                long long sc = evaluate_fast_remove(r);\n                if (sc > cur_score) {\n                    roots_arr[idx] = roots_arr[num_roots-1];\n                    num_roots--;\n                    is_root_arr[r] = false;\n                    cur_score = sc;\n                    improved = true;\n                    if (cur_score > global_best_score) {\n                        global_best_score = cur_score;\n                        best_num_roots = num_roots;\n                        memcpy(best_roots_arr, roots_arr, num_roots * sizeof(int));\n                    }\n                    compute_d1_d2();\n                    goto next_iter;\n                }\n            }\n\n            // Try Move\n            int deg = 0;\n            for(int nb : adj[r]) tmp_nb[deg++] = nb;\n            shuffle(tmp_nb, tmp_nb + deg, rng);\n            \n            for(int i=0; i<deg; ++i) {\n                int v = tmp_nb[i];\n                if (is_root_arr[v]) continue;\n                long long sc = evaluate_fast_move(r, v);\n                if (sc > cur_score) {\n                    is_root_arr[r] = false;\n                    is_root_arr[v] = true;\n                    roots_arr[idx] = v;\n                    cur_score = sc;\n                    improved = true;\n                    if (cur_score > global_best_score) {\n                        global_best_score = cur_score;\n                        best_num_roots = num_roots;\n                        memcpy(best_roots_arr, roots_arr, num_roots * sizeof(int));\n                    }\n                    compute_d1_d2();\n                    goto next_iter;\n                }\n            }\n        }\n\n        // Perturbation\n        if (!improved && num_roots > 0) {\n            int idx = uniform_int_distribution<int>(0, num_roots - 1)(rng);\n            int r = roots_arr[idx];\n            int v = uniform_int_distribution<int>(0, N - 1)(rng);\n            if (!is_root_arr[v] && r != v) {\n                long long sc = evaluate_fast_move(r, v);\n                if (sc != -1) {\n                    is_root_arr[r] = false;\n                    is_root_arr[v] = true;\n                    roots_arr[idx] = v;\n                    cur_score = sc;\n                    compute_d1_d2();\n                }\n            }\n        }\n        next_iter:;\n    }\n\n    // Construct and Output\n    evaluate(d_buf, best_roots_arr, best_num_roots);\n    vector<int> p(N, -1);\n    for (int i = 0; i < N; ++i) {\n        if (d_buf[i] > 0) {\n            int target = d_buf[i] - 1;\n            for (int nb : adj[i]) {\n                if (d_buf[nb] == target) {\n                    p[i] = nb;\n                    break;\n                }\n            }\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << p[i] << (i == N - 1 ? \"\" : \" \");\n    }\n    cout << \"\\n\";\n\n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <utility>\n\nusing namespace std;\n\nint N;\nvector<string> board;\n\n// Apply a single shift operation to the board\nvoid apply_shift(char dir, int p) {\n    if (dir == 'U') {\n        for (int i = 0; i < N - 1; i++) board[i][p] = board[i + 1][p];\n        board[N - 1][p] = '.';\n    } else if (dir == 'D') {\n        for (int i = N - 1; i > 0; i--) board[i][p] = board[i - 1][p];\n        board[0][p] = '.';\n    } else if (dir == 'L') {\n        for (int j = 0; j < N - 1; j++) board[p][j] = board[p][j + 1];\n        board[p][N - 1] = '.';\n    } else if (dir == 'R') {\n        for (int j = N - 1; j > 0; j--) board[p][j] = board[p][j - 1];\n        board[p][0] = '.';\n    }\n}\n\n// Calculate heuristic: sum of minimum clear distances for all Oni\n// Returns 1e9 if any Oni is trapped (no clear direction)\nint calc_potential(const vector<string>& b) {\n    int sum = 0;\n    for(int i=0; i<N; i++) {\n        for(int j=0; j<N; j++) {\n            if(b[i][j] == 'x') {\n                int d = 1e9;\n                bool c = true;\n                for(int k=0; k<i; k++) if(b[k][j]=='o'){c=false;break;}\n                if(c) d = min(d, i+1);\n                c = true;\n                for(int k=i+1; k<N; k++) if(b[k][j]=='o'){c=false;break;}\n                if(c) d = min(d, N-i);\n                c = true;\n                for(int k=0; k<j; k++) if(b[i][k]=='o'){c=false;break;}\n                if(c) d = min(d, j+1);\n                c = true;\n                for(int k=j+1; k<N; k++) if(b[i][k]=='o'){c=false;break;}\n                if(c) d = min(d, N-j);\n                \n                if(d == 1e9) return 1e9; // Trapped\n                sum += d;\n            }\n        }\n    }\n    return sum;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> N)) return 0;\n    board.resize(N);\n    for (int i = 0; i < N; i++) cin >> board[i];\n\n    vector<pair<char, int>> ops;\n\n    while (true) {\n        int oni_count = 0;\n        for(int i=0; i<N; i++) for(int j=0; j<N; j++) if(board[i][j]=='x') oni_count++;\n        if(oni_count == 0) break;\n\n        int cur_pot = calc_potential(board);\n        \n        int best_score = 2e9;\n        int best_shifts = 1e9;\n        char best_dir = 0;\n        int best_r = -1, best_c = -1;\n        bool found_direct = false;\n\n        // Lookahead: Evaluate all possible direct removals\n        for(int i=0; i<N; i++) {\n            for(int j=0; j<N; j++) {\n                if(board[i][j] == 'x') {\n                    struct Move { char dir; int dist; int param; bool valid; } moves[4] = {\n                        {'U', i+1, j, true}, {'D', N-i, j, true}, {'L', j+1, i, true}, {'R', N-j, i, true}\n                    };\n                    // Validate directions\n                    for(auto& m : moves) {\n                        if(!m.valid) continue;\n                        bool clear = true;\n                        if(m.dir == 'U') { for(int k=0; k<i; k++) if(board[k][j]=='o') { clear=false; break; } }\n                        else if(m.dir == 'D') { for(int k=i+1; k<N; k++) if(board[k][j]=='o') { clear=false; break; } }\n                        else if(m.dir == 'L') { for(int k=0; k<j; k++) if(board[i][k]=='o') { clear=false; break; } }\n                        else if(m.dir == 'R') { for(int k=j+1; k<N; k++) if(board[i][k]=='o') { clear=false; break; } }\n                        m.valid = clear;\n                    }\n\n                    for(auto& m : moves) {\n                        if(!m.valid) continue;\n                        \n                        // Simulate shifts\n                        vector<string> sim_board = board;\n                        for(int k=0; k<m.dist; k++) {\n                            if(m.dir == 'U') {\n                                for(int r=0; r<N-1; r++) sim_board[r][m.param] = sim_board[r+1][m.param];\n                                sim_board[N-1][m.param] = '.';\n                            } else if(m.dir == 'D') {\n                                for(int r=N-1; r>0; r--) sim_board[r][m.param] = sim_board[r-1][m.param];\n                                sim_board[0][m.param] = '.';\n                            } else if(m.dir == 'L') {\n                                for(int c=0; c<N-1; c++) sim_board[m.param][c] = sim_board[m.param][c+1];\n                                sim_board[m.param][N-1] = '.';\n                            } else if(m.dir == 'R') {\n                                for(int c=N-1; c>0; c--) sim_board[m.param][c] = sim_board[m.param][c-1];\n                                sim_board[m.param][0] = '.';\n                            }\n                        }\n                        \n                        int new_pot = calc_potential(sim_board);\n                        int score = m.dist + (new_pot - cur_pot);\n                        if(new_pot >= 1e9) score += 1e8; // Heavy penalty for trapping pieces\n                        \n                        if(score < best_score || (score == best_score && m.dist < best_shifts)) {\n                            best_score = score;\n                            best_shifts = m.dist;\n                            best_dir = m.dir;\n                            best_r = i; best_c = j;\n                            found_direct = true;\n                        }\n                    }\n                }\n            }\n        }\n\n        // Fallback: If lookahead finds no good direct move, use safe greedy\n        if(!found_direct) {\n            int min_cost = 1e9;\n            bool direct_possible = false;\n            \n            // Check for any direct move\n            for(int i=0; i<N; i++) {\n                for(int j=0; j<N; j++) {\n                    if(board[i][j] == 'x') {\n                        bool c = true; for(int k=0; k<i; k++) if(board[k][j]=='o'){c=false;break;}\n                        if(c && (i+1) < min_cost) { min_cost = i+1; best_dir='U'; best_r=i; best_c=j; direct_possible=true; }\n                        c = true; for(int k=i+1; k<N; k++) if(board[k][j]=='o'){c=false;break;}\n                        if(c && (N-i) < min_cost) { min_cost = N-i; best_dir='D'; best_r=i; best_c=j; direct_possible=true; }\n                        c = true; for(int k=0; k<j; k++) if(board[i][k]=='o'){c=false;break;}\n                        if(c && (j+1) < min_cost) { min_cost = j+1; best_dir='L'; best_r=i; best_c=j; direct_possible=true; }\n                        c = true; for(int k=j+1; k<N; k++) if(board[i][k]=='o'){c=false;break;}\n                        if(c && (N-j) < min_cost) { min_cost = N-j; best_dir='R'; best_r=i; best_c=j; direct_possible=true; }\n                    }\n                }\n            }\n            \n            // If still nothing, use Push-Pull\n            if(!direct_possible) {\n                min_cost = 1e9;\n                for(int i=0; i<N; i++) {\n                    for(int j=0; j<N; j++) {\n                        if(board[i][j] == 'x') {\n                            bool c = true; for(int k=0; k<i; k++) if(board[k][j]=='o'){c=false;break;}\n                            if(c && (i+1)*2 < min_cost) { min_cost = (i+1)*2; best_dir='U'; best_r=i; best_c=j; }\n                            c = true; for(int k=i+1; k<N; k++) if(board[k][j]=='o'){c=false;break;}\n                            if(c && (N-i)*2 < min_cost) { min_cost = (N-i)*2; best_dir='D'; best_r=i; best_c=j; }\n                            c = true; for(int k=0; k<j; k++) if(board[i][k]=='o'){c=false;break;}\n                            if(c && (j+1)*2 < min_cost) { min_cost = (j+1)*2; best_dir='L'; best_r=i; best_c=j; }\n                            c = true; for(int k=j+1; k<N; k++) if(board[i][k]=='o'){c=false;break;}\n                            if(c && (N-j)*2 < min_cost) { min_cost = (N-j)*2; best_dir='R'; best_r=i; best_c=j; }\n                        }\n                    }\n                }\n                best_shifts = min_cost / 2;\n                int param = (best_dir == 'U' || best_dir == 'D') ? best_c : best_r;\n                for(int k=0; k<best_shifts; k++) {\n                    ops.push_back({best_dir, param});\n                    apply_shift(best_dir, param);\n                }\n                char pull = (best_dir=='U')?'D':(best_dir=='D')?'U':(best_dir=='L')?'R':'L';\n                for(int k=0; k<best_shifts; k++) {\n                    ops.push_back({pull, param});\n                    apply_shift(pull, param);\n                }\n                continue;\n            } else {\n                best_shifts = min_cost;\n                found_direct = true;\n            }\n        }\n\n        // Apply the chosen direct move\n        int param = (best_dir == 'U' || best_dir == 'D') ? best_c : best_r;\n        for(int k=0; k<best_shifts; k++) {\n            ops.push_back({best_dir, param});\n            apply_shift(best_dir, param);\n        }\n    }\n\n    for(const auto& op : ops) {\n        cout << op.first << \" \" << op.second << \"\\n\";\n    }\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\n#pragma GCC optimize(\"Ofast,unroll-loops\")\nusing namespace std;\n\nint N, L;\nint T[105];\nint A[105], B[105];\nint bestA[105], bestB[105];\nlong long bestErr, curErr;\nint cnt[105];\n\n// Extremely tight simulation matching problem rules exactly\ninline long long simulate() {\n    for(int i = 0; i < N; ++i) cnt[i] = 0;\n    int cur = 0;\n    // L is fixed to 500000, unroll-friendly loop\n    for(int w = 0; w < L; ++w) {\n        cnt[cur]++;\n        // Branchless transition: odd visits -> A, even -> B\n        cur = (cnt[cur] & 1) ? A[cur] : B[cur];\n    }\n    \n    long long err = 0;\n    for(int i = 0; i < N; ++i) {\n        int d = cnt[i] - T[i];\n        err += (d < 0 ? -d : d);\n    }\n    return err;\n}\n\nint main() {\n    cin.tie(nullptr);\n    ios::sync_with_stdio(false);\n    \n    if(!(cin >> N >> L)) return 0;\n    for(int i = 0; i < N; ++i) cin >> T[i];\n\n    // Deterministic seed for reproducibility, can be changed to time for variety\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist(0, N - 1);\n    uniform_real_distribution<double> dist01(0.0, 1.0);\n\n    // Initialize randomly\n    for(int i = 0; i < N; ++i) {\n        A[i] = dist(rng);\n        B[i] = dist(rng);\n    }\n\n    curErr = simulate();\n    bestErr = curErr;\n    memcpy(bestA, A, sizeof(A));\n    memcpy(bestB, B, sizeof(B));\n\n    double temp = 8000.0;\n    const int MAX_ITER = 1200; // Tuned for 2.0s limit\n    auto start = chrono::high_resolution_clock::now();\n\n    for(int iter = 0; iter < MAX_ITER; ++iter) {\n        // Time check every 128 iterations to minimize overhead\n        if((iter & 127) == 0) {\n            double elapsed = chrono::duration<double>(chrono::high_resolution_clock::now() - start).count();\n            if(elapsed > 1.85) break; // Safe margin\n            temp *= 0.96; // Smooth cooling\n        }\n        if(curErr == 0) break; // Optimal solution found\n\n        int idx = dist(rng);\n        bool flip = dist(rng) & 1;\n        int old_val = flip ? A[idx] : B[idx];\n        int new_val = dist(rng);\n\n        if(flip) A[idx] = new_val; else B[idx] = new_val;\n        \n        long long nextErr = simulate();\n\n        if(nextErr < curErr) {\n            curErr = nextErr;\n            if(curErr < bestErr) {\n                bestErr = curErr;\n                memcpy(bestA, A, sizeof(A));\n                memcpy(bestB, B, sizeof(B));\n            }\n        } else {\n            // Metropolis criterion\n            double delta = curErr - nextErr;\n            // Fast rejection for very bad moves to skip exp()\n            if(delta > -40000.0) {\n                if(dist01(rng) < exp(delta / temp)) {\n                    curErr = nextErr;\n                } else {\n                    if(flip) A[idx] = old_val; else B[idx] = old_val;\n                }\n            } else {\n                if(flip) A[idx] = old_val; else B[idx] = old_val;\n            }\n        }\n    }\n\n    for(int i = 0; i < N; ++i) {\n        cout << bestA[i] << \" \" << bestB[i] << \"\\n\";\n    }\n    return 0;\n}","ahc045":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <tuple>\n\nusing namespace std;\n\n// Disjoint Set Union (Union-Find)\nstruct DSU {\n    vector<int> parent, rank;\n    DSU(int n) : parent(n), rank(n, 0) { iota(parent.begin(), parent.end(), 0); }\n    int find(int x) { return parent[x] == x ? x : parent[x] = find(parent[x]); }\n    bool unite(int x, int y) {\n        x = find(x); y = find(y);\n        if (x != y) {\n            if (rank[x] < rank[y]) swap(x, y);\n            parent[y] = x;\n            if (rank[x] == rank[y]) rank[x]++;\n            return true;\n        }\n        return false;\n    }\n};\n\n// Morton (Z-order) curve encoding for 2D spatial locality\ninline uint64_t morton_encode(uint32_t x, uint32_t y) {\n    uint64_t res = 0;\n    for (int i = 0; i < 16; ++i) {\n        res |= (uint64_t)(x & 1) << (2 * i);\n        res |= (uint64_t)(y & 1) << (2 * i + 1);\n        x >>= 1; y >>= 1;\n    }\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, Q, L, W;\n    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n    \n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    \n    vector<int> lx(N), rx(N), ly(N), ry(N);\n    vector<uint32_t> cx(N), cy(N); // Doubled centers for integer Morton encoding\n    for (int i = 0; i < N; ++i) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n        cx[i] = lx[i] + rx[i];\n        cy[i] = ly[i] + ry[i];\n    }\n\n    // Sort cities by Morton code for better 2D spatial clustering\n    vector<int> p(N);\n    iota(p.begin(), p.end(), 0);\n    sort(p.begin(), p.end(), [&](int a, int b) {\n        return morton_encode(cx[a], cy[a]) < morton_encode(cx[b], cy[b]);\n    });\n\n    // Partition sorted cities into groups of required sizes\n    vector<vector<int>> groups(M);\n    int idx = 0;\n    for (int i = 0; i < M; ++i) {\n        groups[i].resize(G[i]);\n        for (int j = 0; j < G[i]; ++j) {\n            groups[i][j] = p[idx++];\n        }\n    }\n\n    vector<vector<pair<int, int>>> exact_edges(M);\n    int q_cnt = 0;\n\n    // Query strategy: overlapping windows of stride L-1 to guarantee connectivity\n    for (int k = 0; k < M; ++k) {\n        int sz = groups[k].size();\n        if (sz <= 1) continue;\n        for (int start = 0; start < sz - 1 && q_cnt < Q; start += L - 1) {\n            int len = min(L, sz - start);\n            vector<int> subset(len);\n            for (int i = 0; i < len; ++i) subset[i] = groups[k][start + i];\n            sort(subset.begin(), subset.end()); // Lexicographical order for judge\n            \n            cout << \"? \" << len;\n            for (int city : subset) cout << \" \" << city;\n            cout << \"\\n\";\n            cout.flush();\n            q_cnt++;\n\n            for (int i = 0; i < len - 1; ++i) {\n                int u, v;\n                cin >> u >> v;\n                if (u > v) swap(u, v);\n                exact_edges[k].push_back({u, v});\n            }\n        }\n        if (q_cnt >= Q) break;\n    }\n\n    // Build final MST for each group\n    vector<vector<pair<int, int>>> final_edges(M);\n    for (int k = 0; k < M; ++k) {\n        int sz = groups[k].size();\n        if (sz <= 1) continue;\n\n        DSU dsu(N);\n        \n        // 1. Prioritize exact edges from queries\n        for (auto& e : exact_edges[k]) {\n            if (dsu.unite(e.first, e.second)) {\n                final_edges[k].push_back(e);\n            }\n        }\n        if ((int)final_edges[k].size() == sz - 1) continue;\n\n        // 2. Generate estimated candidates for remaining connections\n        vector<tuple<long long, int, int>> candidates;\n        candidates.reserve(sz * (sz - 1) / 2);\n        for (int i = 0; i < sz; ++i) {\n            for (int j = i + 1; j < sz; ++j) {\n                int u = groups[k][i], v = groups[k][j];\n                if (dsu.find(u) == dsu.find(v)) continue;\n                long long dx = cx[u] - cx[v];\n                long long dy = cy[u] - cy[v];\n                candidates.emplace_back(dx * dx + dy * dy, min(u, v), max(u, v));\n            }\n        }\n        // Sort by estimated squared distance, ties broken lexicographically\n        sort(candidates.begin(), candidates.end());\n\n        // 3. Complete MST using estimated edges\n        for (const auto& c : candidates) {\n            if ((int)final_edges[k].size() == sz - 1) break;\n            auto [w, u, v] = c;\n            if (dsu.unite(u, v)) {\n                final_edges[k].push_back({u, v});\n            }\n        }\n    }\n\n    // Output results\n    cout << \"!\\n\";\n    cout.flush();\n\n    for (int k = 0; k < M; ++k) {\n        for (size_t i = 0; i < groups[k].size(); ++i) {\n            if (i > 0) cout << \" \";\n            cout << groups[k][i];\n        }\n        cout << \"\\n\";\n        for (auto& e : final_edges[k]) {\n            cout << e.first << \" \" << e.second << \"\\n\";\n        }\n    }\n    cout.flush();\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n\n    int start_r, start_c;\n    cin >> start_r >> start_c;\n\n    // Read M-1 target squares\n    vector<pair<int, int>> targets(M - 1);\n    for (int k = 0; k < M - 1; ++k) {\n        cin >> targets[k].first >> targets[k].second;\n    }\n\n    int cur_r = start_r;\n    int cur_c = start_c;\n\n    // Grid state: true if a block is present\n    bool block[20][20] = {};\n    auto is_block = [&](int r, int c) {\n        if (r < 0 || r >= N || c < 0 || c >= N) return true; // Boundaries act as blocks\n        return block[r][c];\n    };\n\n    const int dr[] = {-1, 1, 0, 0};\n    const int dc[] = {0, 0, -1, 1};\n    const char d_name[] = {'U', 'D', 'L', 'R'};\n\n    int dist[20][20];\n    int parent_r[20][20], parent_c[20][20];\n    char act[20][20], dir[20][20];\n\n    struct Node {\n        int f, r, c, g;\n        bool operator>(const Node& other) const { return f > other.f; }\n    };\n\n    const int INF = 1e9;\n\n    for (auto [tr, tc] : targets) {\n        // Initialize distance matrix\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                dist[i][j] = INF;\n\n        priority_queue<Node, vector<Node>, greater<Node>> pq;\n        dist[cur_r][cur_c] = 0;\n        pq.push(Node{abs(cur_r - tr) + abs(cur_c - tc), cur_r, cur_c, 0});\n\n        // A* Search\n        while (!pq.empty()) {\n            auto [f, r, c, g] = pq.top(); pq.pop();\n            if (dist[r][c] < g) continue;\n            if (r == tr && c == tc) break;\n\n            // Try Move\n            for (int d = 0; d < 4; ++d) {\n                int nr = r + dr[d], nc = c + dc[d];\n                if (!is_block(nr, nc)) {\n                    if (dist[nr][nc] > g + 1) {\n                        dist[nr][nc] = g + 1;\n                        parent_r[nr][nc] = r; parent_c[nr][nc] = c;\n                        act[nr][nc] = 'M'; dir[nr][nc] = d_name[d];\n                        int nh = abs(nr - tr) + abs(nc - tc);\n                        pq.push(Node{dist[nr][nc] + nh, nr, nc, g + 1});\n                    }\n                }\n            }\n\n            // Try Slide\n            for (int d = 0; d < 4; ++d) {\n                int nr = r + dr[d], nc = c + dc[d];\n                while (!is_block(nr, nc)) {\n                    nr += dr[d]; nc += dc[d];\n                }\n                nr -= dr[d]; nc -= dc[d]; // Step back to last valid cell\n                if (nr == r && nc == c) continue; // Didn't move\n\n                if (dist[nr][nc] > g + 1) {\n                    dist[nr][nc] = g + 1;\n                    parent_r[nr][nc] = r; parent_c[nr][nc] = c;\n                    act[nr][nc] = 'S'; dir[nr][nc] = d_name[d];\n                    int nh = abs(nr - tr) + abs(nc - tc);\n                    pq.push(Node{dist[nr][nc] + nh, nr, nc, g + 1});\n                }\n            }\n        }\n\n        // Reconstruct path\n        vector<pair<char, char>> path;\n        int r = tr, c = tc;\n        while (r != cur_r || c != cur_c) {\n            path.emplace_back(act[r][c], dir[r][c]);\n            int pr = parent_r[r][c];\n            int pc = parent_c[r][c];\n            r = pr; c = pc;\n        }\n        reverse(path.begin(), path.end());\n\n        // Execute path\n        for (auto [a, d] : path) {\n            cout << a << ' ' << d << '\\n';\n            if (a == 'M') {\n                if (d == 'U') cur_r--;\n                else if (d == 'D') cur_r++;\n                else if (d == 'L') cur_c--;\n                else if (d == 'R') cur_c++;\n            } else if (a == 'S') {\n                if (d == 'U') while (true) { int nr = cur_r - 1; if (is_block(nr, cur_c)) break; cur_r = nr; }\n                else if (d == 'D') while (true) { int nr = cur_r + 1; if (is_block(nr, cur_c)) break; cur_r = nr; }\n                else if (d == 'L') while (true) { int nc = cur_c - 1; if (is_block(cur_r, nc)) break; cur_c = nc; }\n                else if (d == 'R') while (true) { int nc = cur_c + 1; if (is_block(cur_r, nc)) break; cur_c = nc; }\n            }\n        }\n    }\n\n    return 0;\n}"},"16":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <chrono>\n#include <random>\n#include <numeric>\n\nusing namespace std;\n\n// Optimization pragmas\n#pragma GCC optimize(\"O3,unroll-loops,fast-math\")\n#pragma GCC target(\"avx2,bmi2,popcnt\")\n\nstruct Node {\n    int x1, y1, x2, y2;\n    bool vertical = false;\n    int cut_pos = 0;\n    Node *left = nullptr, *right = nullptr;\n    int leaf_idx = -1;\n    \n    // Static bounds based on point distribution (constant after build)\n    int static_cut_low = 0, static_cut_high = 0;\n    long long subtree_r_sum = 0;\n    \n    // Point bounds for this subtree\n    int min_x = 10000, max_x = 0, min_y = 10000, max_y = 0;\n    \n    bool is_leaf() const { return left == nullptr && right == nullptr; }\n};\n\nint N;\nvector<int> X, Y;\nvector<long long> R;\nvector<int> best_ans_x1, best_ans_y1, best_ans_x2, best_ans_y2;\ndouble global_best_score = -1.0;\n\nmt19937_64 rng_main(chrono::steady_clock::now().time_since_epoch().count());\nchrono::steady_clock::time_point global_start;\n\n// Calculate score for the subtree rooted at node\n// Assumes coordinates are up to date\ndouble calc_subtree_score(Node* node) {\n    // Check validity\n    if (node->x1 >= node->x2 || node->y1 >= node->y2) return -1.0;\n    \n    if (node->is_leaf()) {\n        long long w = node->x2 - node->x1;\n        long long h = node->y2 - node->y1;\n        long long area = w * h;\n        long long r = R[node->leaf_idx];\n        double ratio = min((long long)r, area) / (double)max((long long)r, area);\n        return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n    }\n    \n    double s_left = calc_subtree_score(node->left);\n    if (s_left < 0) return -1.0;\n    double s_right = calc_subtree_score(node->right);\n    if (s_right < 0) return -1.0;\n    return s_left + s_right;\n}\n\n// Update coordinates of all descendants\nvoid update_coords(Node* node) {\n    if (node->is_leaf()) return;\n    if (node->vertical) {\n        node->left->x1 = node->x1; node->left->y1 = node->y1;\n        node->left->x2 = node->cut_pos; node->left->y2 = node->y2;\n        node->right->x1 = node->cut_pos; node->right->y1 = node->y1;\n        node->right->x2 = node->x2; node->right->y2 = node->y2;\n    } else {\n        node->left->x1 = node->x1; node->left->y1 = node->y1;\n        node->left->x2 = node->x2; node->left->y2 = node->cut_pos;\n        node->right->x1 = node->x1; node->right->y1 = node->cut_pos;\n        node->right->x2 = node->x2; node->right->y2 = node->y2;\n    }\n    update_coords(node->left);\n    update_coords(node->right);\n}\n\nvoid collect_nodes(Node* node, vector<Node*>& nodes) {\n    if (!node || node->is_leaf()) return;\n    nodes.push_back(node);\n    collect_nodes(node->left, nodes);\n    collect_nodes(node->right, nodes);\n}\n\nstruct Cand { bool vertical; int k; int c; double err; };\n\nvoid build_tree(int x1, int y1, int x2, int y2, const vector<int>& ids, Node*& node) {\n    node = new Node();\n    node->x1 = x1; node->y1 = y1; node->x2 = x2; node->y2 = y2;\n    node->min_x = 10000; node->max_x = 0; node->min_y = 10000; node->max_y = 0;\n    node->subtree_r_sum = 0;\n    for (int id : ids) {\n        node->min_x = min(node->min_x, X[id]);\n        node->max_x = max(node->max_x, X[id]);\n        node->min_y = min(node->min_y, Y[id]);\n        node->max_y = max(node->max_y, Y[id]);\n        node->subtree_r_sum += R[id];\n    }\n\n    if (ids.size() == 1) {\n        node->leaf_idx = ids[0];\n        return;\n    }\n\n    vector<Cand> cands;\n    cands.reserve(ids.size());\n    \n    auto eval = [&](bool v) {\n        vector<int> s = ids;\n        if (v) sort(s.begin(), s.end(), [&](int a, int b){ return X[a] < X[b]; });\n        else sort(s.begin(), s.end(), [&](int a, int b){ return Y[a] < Y[b]; });\n        long long cur = 0;\n        double len = v ? (x2 - x1) : (y2 - y1);\n        if (len <= 1) return;\n        int b1 = v ? x1 : y1, b2 = v ? x2 : y2;\n        \n        for (int k = 0; k < (int)s.size() - 1; ++k) {\n            cur += R[s[k]];\n            double ideal = b1 + (double)cur / len;\n            int p1 = v ? X[s[k]] : Y[s[k]];\n            int p2 = v ? X[s[k+1]] : Y[s[k+1]];\n            \n            int low = p1 + 1;\n            int high = p2;\n            low = max(low, b1 + 1);\n            high = min(high, b2 - 1);\n            \n            if (low > high) continue;\n            int c = (int)std::round(ideal);\n            if (c < low) c = low;\n            if (c > high) c = high;\n            \n            double err = std::abs(ideal - c);\n            cands.push_back({v, k, c, err});\n        }\n    };\n    eval(true); eval(false);\n\n    // Fallback if no valid cut found (should not happen for distinct points in valid box)\n    if (cands.empty()) {\n        node->leaf_idx = ids[0];\n        return;\n    }\n    \n    sort(cands.begin(), cands.end(), [](const Cand& a, const Cand& b){ return a.err < b.err; });\n    \n    // Randomized selection from top candidates to explore diverse topologies\n    int pool = min((int)cands.size(), 10);\n    uniform_int_distribution<int> dist(0, pool - 1);\n    Cand best = cands[dist(rng_main)];\n    \n    node->vertical = best.vertical;\n    node->cut_pos = best.c;\n    \n    vector<int> s = ids;\n    if (best.vertical) sort(s.begin(), s.end(), [&](int a, int b){ return X[a] < X[b]; });\n    else sort(s.begin(), s.end(), [&](int a, int b){ return Y[a] < Y[b]; });\n    \n    vector<int> L(s.begin(), s.begin() + best.k + 1);\n    vector<int> R_vec(s.begin() + best.k + 1, s.end());\n    \n    if (best.vertical) {\n        build_tree(x1, y1, best.c, y2, L, node->left);\n        build_tree(best.c, y1, x2, y2, R_vec, node->right);\n    } else {\n        build_tree(x1, y1, x2, best.c, L, node->left);\n        build_tree(x1, best.c, x2, y2, R_vec, node->right);\n    }\n    \n    // Compute static bounds based on children's points\n    if (node->vertical) {\n        node->static_cut_low = node->left->max_x + 1;\n        node->static_cut_high = node->right->min_x;\n    } else {\n        node->static_cut_low = node->left->max_y + 1;\n        node->static_cut_high = node->right->min_y;\n    }\n}\n\nvoid delete_tree(Node* node) {\n    if (node) { delete_tree(node->left); delete_tree(node->right); delete node; }\n}\n\nvoid save_best(Node* root) {\n    vector<Node*> st;\n    st.push_back(root);\n    while(!st.empty()){\n        Node* n = st.back(); st.pop_back();\n        if(n->is_leaf()){\n            if(n->leaf_idx != -1){\n                best_ans_x1[n->leaf_idx] = n->x1;\n                best_ans_y1[n->leaf_idx] = n->y1;\n                best_ans_x2[n->leaf_idx] = n->x2;\n                best_ans_y2[n->leaf_idx] = n->y2;\n            }\n        } else {\n            st.push_back(n->left);\n            st.push_back(n->right);\n        }\n    }\n}\n\nvoid optimize_tree(Node* root) {\n    vector<Node*> nodes;\n    collect_nodes(root, nodes);\n    \n    // Initial score\n    double current_score = calc_subtree_score(root);\n    if (current_score > global_best_score) {\n        global_best_score = current_score;\n        save_best(root);\n    }\n    \n    int passes = 0;\n    // Run optimization passes until time limit\n    while (passes < 1000) { \n        if (chrono::duration<double>(chrono::steady_clock::now() - global_start).count() > 4.9) break;\n        \n        bool improved_pass = false;\n        \n        // Process nodes Top-Down (order from collect_nodes)\n        for (Node* node : nodes) {\n            // Determine valid range for cut\n            // Must respect static bounds (points) and current box boundaries\n            int l = max(node->static_cut_low, (node->vertical ? node->x1 : node->y1) + 1);\n            int r = min(node->static_cut_high, (node->vertical ? node->x2 : node->y2) - 1);\n            \n            if (l >= r) continue;\n            \n            int current_c = node->cut_pos;\n            double old_sub_score = calc_subtree_score(node);\n            int best_c = current_c;\n            double best_s = old_sub_score;\n            \n            // Ternary Search for optimal cut position\n            int tl = l, tr = r;\n            int steps = 0;\n            while (tr - tl > 3 && steps < 20) {\n                int m1 = tl + (tr - tl) / 3;\n                int m2 = tr - (tr - tl) / 3;\n                \n                // Test m1\n                node->cut_pos = m1;\n                update_coords(node);\n                double s1 = calc_subtree_score(node);\n                \n                // Test m2\n                node->cut_pos = m2;\n                update_coords(node);\n                double s2 = calc_subtree_score(node);\n                \n                if (s1 > best_s) { best_s = s1; best_c = m1; }\n                if (s2 > best_s) { best_s = s2; best_c = m2; }\n                \n                if (s1 < s2) tl = m1;\n                else tr = m2;\n                \n                steps++;\n            }\n            \n            // Exhaustive check in small remaining range\n            for (int c = tl; c <= tr; ++c) {\n                if (c == current_c) continue; \n                node->cut_pos = c;\n                update_coords(node);\n                double s = calc_subtree_score(node);\n                if (s > best_s) {\n                    best_s = s;\n                    best_c = c;\n                }\n            }\n            \n            // Apply best cut found\n            if (best_c != current_c) {\n                node->cut_pos = best_c;\n                update_coords(node);\n                current_score += (best_s - old_sub_score);\n                improved_pass = true;\n                \n                if (current_score > global_best_score) {\n                    global_best_score = current_score;\n                    save_best(root);\n                }\n            } else {\n                // Ensure state is restored if we moved during checks\n                // (Though update_coords with best_c which == current_c should be idempotent for coords)\n                // Just in case:\n                node->cut_pos = best_c;\n                update_coords(node);\n            }\n        }\n        if (!improved_pass) break;\n        passes++;\n    }\n}\n\nint main() {\n    global_start = chrono::steady_clock::now();\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    if (!(cin >> N)) return 0;\n    X.resize(N); Y.resize(N); R.resize(N);\n    for (int i = 0; i < N; ++i) cin >> X[i] >> Y[i] >> R[i];\n\n    best_ans_x1.resize(N); best_ans_y1.resize(N); best_ans_x2.resize(N); best_ans_y2.resize(N);\n    vector<int> ids(N);\n    iota(ids.begin(), ids.end(), 0);\n\n    Node* root = nullptr;\n\n    // Multi-start exploration\n    while (chrono::duration<double>(chrono::steady_clock::now() - global_start).count() < 4.95) {\n        delete_tree(root);\n        root = nullptr;\n        \n        shuffle(ids.begin(), ids.end(), rng_main);\n        build_tree(0, 0, 10000, 10000, ids, root);\n        \n        // Check initial score\n        double sc = calc_subtree_score(root);\n        if (sc > global_best_score) {\n            global_best_score = sc;\n            save_best(root);\n        }\n        \n        // Optimize if time permits\n        if (chrono::duration<double>(chrono::steady_clock::now() - global_start).count() < 4.8) {\n            optimize_tree(root);\n        }\n    }\n    delete_tree(root);\n\n    for (int i = 0; i < N; ++i) {\n        cout << best_ans_x1[i] << \" \" << best_ans_y1[i] << \" \"\n             << best_ans_x2[i] << \" \" << best_ans_y2[i] << \"\\n\";\n    }\n    return 0;\n}","ahc002":"/*\n    Problem: Heuristic Pathfinding on 50x50 Grid\n    Strategy: Multi-Restart Simulated Annealing with Tile-Aware BFS and Randomized Heuristics.\n    \n    Improvements in this version:\n    1. Increased penalty weights for \"loss\" and \"reachability\" to avoid dead ends and high-value traps.\n    2. Optimized BFS limit to 150 for speed while retaining trap detection capability.\n    3. Increased reachability threshold to 40 to be more conservative about entering bottlenecks.\n    4. Adjusted temperature schedule slightly to allow more exploration.\n    5. Optimized path update using swap to preserve vector capacity and avoid reallocation.\n*/\n#pragma GCC optimize(\"Ofast,unroll-loops\")\n#include <bits/stdc++.h>\n#include <chrono>\n\nusing namespace std;\nusing ll = long long;\n\n// Global Data\nint t[50][50], p[50][50];\nint M = 0;\nint si, sj;\nconst int dr[] = {-1, 1, 0, 0};\nconst int dc[] = {0, 0, -1, 1};\nconst char dirs[] = {'U', 'D', 'L', 'R'};\n\n// Visited State (Tile-based)\n// Using a token allows O(1) reset of the visited array\nint vis[2505];\nint vis_token = 0;\n\n// BFS State\n// We track visited tiles to handle 1x2 tiles correctly.\nint bfs_vis_tiles[2505];\nint bfs_tile_gen = 0;\n\n// Queue for BFS\nint qr[600], qc[600]; \n\n// Precomputed loss for each square (value of the other square in the same tile)\nint square_loss[50][50];\n\nll global_best_score = -1;\nvector<char> global_best_path;\n\nauto start_t = chrono::steady_clock::now();\nconst double TIME_LIMIT = 1.92; \n\ninline double elapsed() {\n    return chrono::duration<double>(chrono::steady_clock::now() - start_t).count();\n}\n\n// BFS to count reachable unvisited TILES from (r, c)\n// Assumes we are currently at (r,c) and the tile 'tile_id' has just been visited.\n// Returns the number of reachable tiles (including tile_id itself).\ninline int get_reachability(int r, int c, int tile_id) {\n    int count = 0;\n    int head = 0, tail = 0;\n    bfs_tile_gen++;\n    \n    // Mark the current tile as visited in this BFS search\n    bfs_vis_tiles[tile_id] = bfs_tile_gen;\n    qr[tail] = r; qc[tail] = c; tail++;\n    count++;\n    \n    while(head < tail) {\n        int cr = qr[head];\n        int cc = qc[head];\n        head++;\n        \n        // Check 4 neighbors\n        // U\n        int nr = cr - 1, nc = cc;\n        if (nr >= 0) {\n            int tid = t[nr][nc];\n            // Check if tile is not visited in main path AND not visited in this BFS\n            if (vis[tid] != vis_token && bfs_vis_tiles[tid] != bfs_tile_gen) {\n                bfs_vis_tiles[tid] = bfs_tile_gen;\n                qr[tail] = nr; qc[tail] = nc; tail++;\n                count++;\n                if (count >= 150) return 150; // Limit to 150 tiles for speed\n            }\n        }\n        // D\n        nr = cr + 1; nc = cc;\n        if (nr < 50) {\n            int tid = t[nr][nc];\n            if (vis[tid] != vis_token && bfs_vis_tiles[tid] != bfs_tile_gen) {\n                bfs_vis_tiles[tid] = bfs_tile_gen;\n                qr[tail] = nr; qc[tail] = nc; tail++;\n                count++;\n                if (count >= 150) return 150;\n            }\n        }\n        // L\n        nr = cr; nc = cc - 1;\n        if (nc >= 0) {\n            int tid = t[nr][nc];\n            if (vis[tid] != vis_token && bfs_vis_tiles[tid] != bfs_tile_gen) {\n                bfs_vis_tiles[tid] = bfs_tile_gen;\n                qr[tail] = nr; qc[tail] = nc; tail++;\n                count++;\n                if (count >= 150) return 150;\n            }\n        }\n        // R\n        nc = cc + 1;\n        if (nc < 50) {\n            int tid = t[nr][nc];\n            if (vis[tid] != vis_token && bfs_vis_tiles[tid] != bfs_tile_gen) {\n                bfs_vis_tiles[tid] = bfs_tile_gen;\n                qr[tail] = nr; qc[tail] = nc; tail++;\n                count++;\n                if (count >= 150) return 150;\n            }\n        }\n    }\n    return count;\n}\n\nint main() {\n    cin.tie(nullptr);\n    ios::sync_with_stdio(false);\n\n    if (!(cin >> si >> sj)) return 0;\n    for (int i = 0; i < 50; ++i)\n        for (int j = 0; j < 50; ++j) {\n            cin >> t[i][j];\n            M = max(M, t[i][j] + 1);\n        }\n    for (int i = 0; i < 50; ++i)\n        for (int j = 0; j < 50; ++j)\n            cin >> p[i][j];\n\n    // Precompute square_loss\n    // Identify 1x2 tiles. A square belongs to a 1x2 tile if a neighbor has the same tile ID.\n    fill(&square_loss[0][0], &square_loss[0][0] + 2500, 0);\n    for(int i=0; i<50; ++i) {\n        for(int j=0; j<50; ++j) {\n            int tid = t[i][j];\n            for(int d=0; d<4; ++d) {\n                int ni = i + dr[d];\n                int nj = j + dc[d];\n                if(ni>=0 && ni<50 && nj>=0 && nj<50 && t[ni][nj] == tid) {\n                    square_loss[i][j] = p[ni][nj];\n                    break; \n                }\n            }\n        }\n    }\n\n    mt19937_64 seed_gen(42);\n    vector<char> cur_path;\n    vector<char> nxt_path;\n    cur_path.reserve(2500);\n    nxt_path.reserve(2500);\n\n    // Multi-Restart Loop\n    while (elapsed() < TIME_LIMIT) {\n        mt19937_64 rng(seed_gen());\n        \n        // Randomize Heuristic Weights\n        // Increased ranges for better trap avoidance and loss aversion\n        double W_deg = 5.0 + (rng() % 1000) * 0.01;      // [5.0, 15.0]\n        double W_reach = 15.0 + (rng() % 3500) * 0.01;   // [15.0, 50.0]\n        double W_loss = (rng() % 150) * 0.01;            // [0.0, 1.5]\n        \n        const int REACH_THRESH = 40; \n        const double REACH_PENALTY = -600.0;\n\n        // 1. Greedy Construction\n        cur_path.clear();\n        vis_token++;\n        int r = si, c = sj;\n        vis[t[r][c]] = vis_token;\n        ll cur_score = p[r][c];\n        \n        while (true) {\n            double best_h = -1e18;\n            int best_k = -1, nr_best = 0, nc_best = 0;\n            \n            // Check 4 neighbors\n            // U\n            {\n                int nr = r - 1, nc = c;\n                if (nr >= 0) {\n                    int tid = t[nr][nc];\n                    if (vis[tid] != vis_token) {\n                        int deg = 0;\n                        for(int d=0; d<4; ++d) {\n                            int tr = nr + dr[d], tc = nc + dc[d];\n                            if(tr>=0 && tr<50 && tc>=0 && tc<50 && vis[t[tr][tc]] != vis_token && t[tr][tc] != tid) deg++;\n                        }\n                        \n                        double h = (double)p[nr][nc];\n                        h += deg * W_deg;\n                        \n                        if (deg == 0) {\n                            h += REACH_PENALTY;\n                        } else if (deg <= 2) {\n                            int reach = get_reachability(nr, nc, tid);\n                            h += reach * W_reach;\n                            if (reach < REACH_THRESH) h += REACH_PENALTY;\n                        }\n                        \n                        h -= W_loss * square_loss[nr][nc];\n                        h += (double)(rng() & 0x1FFF) * 0.002442;\n                        \n                        if (h > best_h) { best_h = h; best_k = 0; nr_best = nr; nc_best = nc; }\n                    }\n                }\n            }\n            // D\n            {\n                int nr = r + 1, nc = c;\n                if (nr < 50) {\n                    int tid = t[nr][nc];\n                    if (vis[tid] != vis_token) {\n                        int deg = 0;\n                        for(int d=0; d<4; ++d) {\n                            int tr = nr + dr[d], tc = nc + dc[d];\n                            if(tr>=0 && tr<50 && tc>=0 && tc<50 && vis[t[tr][tc]] != vis_token && t[tr][tc] != tid) deg++;\n                        }\n                        \n                        double h = (double)p[nr][nc];\n                        h += deg * W_deg;\n                        \n                        if (deg == 0) {\n                            h += REACH_PENALTY;\n                        } else if (deg <= 2) {\n                            int reach = get_reachability(nr, nc, tid);\n                            h += reach * W_reach;\n                            if (reach < REACH_THRESH) h += REACH_PENALTY;\n                        }\n                        \n                        h -= W_loss * square_loss[nr][nc];\n                        h += (double)(rng() & 0x1FFF) * 0.002442;\n                        \n                        if (h > best_h) { best_h = h; best_k = 1; nr_best = nr; nc_best = nc; }\n                    }\n                }\n            }\n            // L\n            {\n                int nr = r, nc = c - 1;\n                if (nc >= 0) {\n                    int tid = t[nr][nc];\n                    if (vis[tid] != vis_token) {\n                        int deg = 0;\n                        for(int d=0; d<4; ++d) {\n                            int tr = nr + dr[d], tc = nc + dc[d];\n                            if(tr>=0 && tr<50 && tc>=0 && tc<50 && vis[t[tr][tc]] != vis_token && t[tr][tc] != tid) deg++;\n                        }\n                        \n                        double h = (double)p[nr][nc];\n                        h += deg * W_deg;\n                        \n                        if (deg == 0) {\n                            h += REACH_PENALTY;\n                        } else if (deg <= 2) {\n                            int reach = get_reachability(nr, nc, tid);\n                            h += reach * W_reach;\n                            if (reach < REACH_THRESH) h += REACH_PENALTY;\n                        }\n                        \n                        h -= W_loss * square_loss[nr][nc];\n                        h += (double)(rng() & 0x1FFF) * 0.002442;\n                        \n                        if (h > best_h) { best_h = h; best_k = 2; nr_best = nr; nc_best = nc; }\n                    }\n                }\n            }\n            // R\n            {\n                int nr = r, nc = c + 1;\n                if (nc < 50) {\n                    int tid = t[nr][nc];\n                    if (vis[tid] != vis_token) {\n                        int deg = 0;\n                        for(int d=0; d<4; ++d) {\n                            int tr = nr + dr[d], tc = nc + dc[d];\n                            if(tr>=0 && tr<50 && tc>=0 && tc<50 && vis[t[tr][tc]] != vis_token && t[tr][tc] != tid) deg++;\n                        }\n                        \n                        double h = (double)p[nr][nc];\n                        h += deg * W_deg;\n                        \n                        if (deg == 0) {\n                            h += REACH_PENALTY;\n                        } else if (deg <= 2) {\n                            int reach = get_reachability(nr, nc, tid);\n                            h += reach * W_reach;\n                            if (reach < REACH_THRESH) h += REACH_PENALTY;\n                        }\n                        \n                        h -= W_loss * square_loss[nr][nc];\n                        h += (double)(rng() & 0x1FFF) * 0.002442;\n                        \n                        if (h > best_h) { best_h = h; best_k = 3; nr_best = nr; nc_best = nc; }\n                    }\n                }\n            }\n            \n            if (best_k == -1) break;\n            \n            cur_path.push_back(dirs[best_k]);\n            r = nr_best; c = nc_best;\n            vis[t[r][c]] = vis_token;\n            cur_score += p[r][c];\n        }\n        \n        if (cur_score > global_best_score) {\n            global_best_score = cur_score;\n            global_best_path = cur_path;\n        }\n        \n        // 2. SA Loop\n        double run_deadline = elapsed() + 0.12; \n        double T = 100.0;\n        int iter = 0;\n        \n        while (elapsed() < run_deadline && elapsed() < TIME_LIMIT - 0.02) {\n            int sz = cur_path.size();\n            // Biased truncation: keep 25% to 100% of the path\n            int keep_len = (sz <= 5) ? 0 : (sz / 4 + (rng() % (3 * sz / 4 + 1)));\n            \n            nxt_path.assign(cur_path.begin(), cur_path.begin() + keep_len);\n            \n            vis_token++;\n            int rr = si, cc = sj;\n            vis[t[rr][cc]] = vis_token;\n            ll next_score = p[rr][cc];\n            \n            for (int i = 0; i < keep_len; ++i) {\n                char d = nxt_path[i];\n                if (d == 'U') rr--; else if (d == 'D') rr++; else if (d == 'L') cc--; else cc++;\n                vis[t[rr][cc]] = vis_token;\n                next_score += p[rr][cc];\n            }\n            \n            // Extend\n            while (true) {\n                double best_h = -1e18;\n                int best_k = -1, nr_best = 0, nc_best = 0;\n                \n                // U\n                {\n                    int nr = rr - 1, nc = cc;\n                    if (nr >= 0) {\n                        int tid = t[nr][nc];\n                        if (vis[tid] != vis_token) {\n                            int deg = 0;\n                            for(int d=0; d<4; ++d) {\n                                int tr = nr + dr[d], tc = nc + dc[d];\n                                if(tr>=0 && tr<50 && tc>=0 && tc<50 && vis[t[tr][tc]] != vis_token && t[tr][tc] != tid) deg++;\n                            }\n                            \n                            double h = (double)p[nr][nc];\n                            h += deg * W_deg;\n                            \n                            if (deg == 0) {\n                                h += REACH_PENALTY;\n                            } else if (deg <= 2) {\n                                int reach = get_reachability(nr, nc, tid);\n                                h += reach * W_reach;\n                                if (reach < REACH_THRESH) h += REACH_PENALTY;\n                            }\n                            \n                            h -= W_loss * square_loss[nr][nc];\n                            h += (double)(rng() & 0x1FFF) * 0.002442;\n                            \n                            if (h > best_h) { best_h = h; best_k = 0; nr_best = nr; nc_best = nc; }\n                        }\n                    }\n                }\n                // D\n                {\n                    int nr = rr + 1, nc = cc;\n                    if (nr < 50) {\n                        int tid = t[nr][nc];\n                        if (vis[tid] != vis_token) {\n                            int deg = 0;\n                            for(int d=0; d<4; ++d) {\n                                int tr = nr + dr[d], tc = nc + dc[d];\n                                if(tr>=0 && tr<50 && tc>=0 && tc<50 && vis[t[tr][tc]] != vis_token && t[tr][tc] != tid) deg++;\n                            }\n                            \n                            double h = (double)p[nr][nc];\n                            h += deg * W_deg;\n                            \n                            if (deg == 0) {\n                                h += REACH_PENALTY;\n                            } else if (deg <= 2) {\n                                int reach = get_reachability(nr, nc, tid);\n                                h += reach * W_reach;\n                                if (reach < REACH_THRESH) h += REACH_PENALTY;\n                            }\n                            \n                            h -= W_loss * square_loss[nr][nc];\n                            h += (double)(rng() & 0x1FFF) * 0.002442;\n                            \n                            if (h > best_h) { best_h = h; best_k = 1; nr_best = nr; nc_best = nc; }\n                        }\n                    }\n                }\n                // L\n                {\n                    int nr = rr, nc = cc - 1;\n                    if (nc >= 0) {\n                        int tid = t[nr][nc];\n                        if (vis[tid] != vis_token) {\n                            int deg = 0;\n                            for(int d=0; d<4; ++d) {\n                                int tr = nr + dr[d], tc = nc + dc[d];\n                                if(tr>=0 && tr<50 && tc>=0 && tc<50 && vis[t[tr][tc]] != vis_token && t[tr][tc] != tid) deg++;\n                            }\n                            \n                            double h = (double)p[nr][nc];\n                            h += deg * W_deg;\n                            \n                            if (deg == 0) {\n                                h += REACH_PENALTY;\n                            } else if (deg <= 2) {\n                                int reach = get_reachability(nr, nc, tid);\n                                h += reach * W_reach;\n                                if (reach < REACH_THRESH) h += REACH_PENALTY;\n                            }\n                            \n                            h -= W_loss * square_loss[nr][nc];\n                            h += (double)(rng() & 0x1FFF) * 0.002442;\n                            \n                            if (h > best_h) { best_h = h; best_k = 2; nr_best = nr; nc_best = nc; }\n                        }\n                    }\n                }\n                // R\n                {\n                    int nr = rr, nc = cc + 1;\n                    if (nc < 50) {\n                        int tid = t[nr][nc];\n                        if (vis[tid] != vis_token) {\n                            int deg = 0;\n                            for(int d=0; d<4; ++d) {\n                                int tr = nr + dr[d], tc = nc + dc[d];\n                                if(tr>=0 && tr<50 && tc>=0 && tc<50 && vis[t[tr][tc]] != vis_token && t[tr][tc] != tid) deg++;\n                            }\n                            \n                            double h = (double)p[nr][nc];\n                            h += deg * W_deg;\n                            \n                            if (deg == 0) {\n                                h += REACH_PENALTY;\n                            } else if (deg <= 2) {\n                                int reach = get_reachability(nr, nc, tid);\n                                h += reach * W_reach;\n                                if (reach < REACH_THRESH) h += REACH_PENALTY;\n                            }\n                            \n                            h -= W_loss * square_loss[nr][nc];\n                            h += (double)(rng() & 0x1FFF) * 0.002442;\n                            \n                            if (h > best_h) { best_h = h; best_k = 3; nr_best = nr; nc_best = nc; }\n                        }\n                    }\n                }\n                \n                if (best_k == -1) break;\n                \n                nxt_path.push_back(dirs[best_k]);\n                rr = nr_best; cc = nc_best;\n                vis[t[rr][cc]] = vis_token;\n                next_score += p[rr][cc];\n            }\n            \n            if (next_score > global_best_score) {\n                global_best_score = next_score;\n                global_best_path = nxt_path;\n            }\n            \n            double delta = next_score - cur_score;\n            bool accept = false;\n            if (delta >= 0) accept = true;\n            else {\n                double prob = exp(delta / T);\n                if (prob > (double)(rng() & 0xFFFFFF) / 16777216.0) accept = true;\n            }\n            \n            if (accept) {\n                cur_score = next_score;\n                cur_path.swap(nxt_path); // Efficient swap preserving capacity\n            }\n            \n            iter++;\n            // Slower cooling\n            if (iter % 1000 == 0) T *= 0.998;\n        }\n    }\n\n    for (char c : global_best_path) cout << c;\n    cout << \"\\n\";\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nlong double h[30][29];\nlong double v[29][30];\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Initialize weights to the midpoint of the expected range [1000, 9000]\n    for(int i=0; i<30; ++i) for(int j=0; j<29; ++j) h[i][j] = 5000.0L;\n    for(int i=0; i<29; ++i) for(int j=0; j<30; ++j) v[i][j] = 5000.0L;\n\n    // Tuned parameters\n    const long double ALPHA = 0.18L;           // High learning rate for tail-weighted scoring\n    const long double VAR_THRESHOLD = 300000.0L; // Variance threshold to detect splits/high noise\n    const long double BETA_HIGH_VAR = 0.02L;   // Conservative smoothing for high variance\n    const long double BETA_LOW_VAR = 0.25L;    // Aggressive smoothing for low variance\n    \n    const long double MIN_W = 1000.0L; \n    const long double MAX_W = 9000.0L; \n\n    int si, sj, ti, tj;\n    for(int k=0; k<1000; ++k) {\n        if(!(cin >> si >> sj >> ti >> tj)) break;\n\n        // Dijkstra's Algorithm\n        priority_queue<tuple<long long, int, int>, vector<tuple<long long, int, int>>, greater<>> pq;\n        long long dist[30][30];\n        const long long INF = 4000000000000000000LL;\n        for(int i=0; i<30; ++i) fill(dist[i], dist[i]+30, INF);\n        \n        dist[si][sj] = 0;\n        pq.emplace(0, si, sj);\n\n        int pi[30][30], pj[30][30];\n        char dir[30][30];\n\n        const int di[4] = {-1, 1, 0, 0};\n        const int dj[4] = {0, 0, -1, 1};\n        const char dc[4] = {'U', 'D', 'L', 'R'};\n\n        while(!pq.empty()){\n            auto [d, i, j] = pq.top(); pq.pop();\n            if(d > dist[i][j]) continue;\n            if(i == ti && j == tj) break;\n\n            for(int m=0; m<4; ++m){\n                int ni = i + di[m], nj = j + dj[m];\n                if(ni < 0 || ni >= 30 || nj < 0 || nj >= 30) continue;\n\n                long long w;\n                if(m == 0)      w = (long long)(v[ni][nj] + 0.5L);\n                else if(m == 1) w = (long long)(v[i][j] + 0.5L);\n                else if(m == 2) w = (long long)(h[i][nj] + 0.5L);\n                else            w = (long long)(h[i][j] + 0.5L);\n\n                // Deterministic perturbation to break ties and encourage exploration\n                // Range: [-2, 2]. Depends on query index k to vary over time.\n                long long pert = (long long)((i * 127 + j * 43 + m * 11 + k * 7) % 5) - 2;\n                \n                if(dist[i][j] + w + pert < dist[ni][nj]){\n                    dist[ni][nj] = dist[i][j] + w + pert;\n                    pi[ni][nj] = i;\n                    pj[ni][nj] = j;\n                    dir[ni][nj] = dc[m];\n                    pq.emplace(dist[ni][nj], ni, nj);\n                }\n            }\n        }\n\n        // Reconstruct path\n        string path; path.reserve(60);\n        int ci = ti, cj = tj;\n        while(!(ci == si && cj == sj)){\n            path += dir[ci][cj];\n            int ni = pi[ci][cj], nj = pj[ci][cj];\n            ci = ni; cj = nj;\n        }\n        reverse(path.begin(), path.end());\n        cout << path << \"\\n\" << flush;\n\n        // Read feedback\n        int L; cin >> L;\n\n        // Calculate estimated path length B using current weights\n        long double B = 0.0L;\n        ci = si; cj = sj;\n        for(char c : path){\n            if(c == 'U') { B += v[ci-1][cj]; ci--; }\n            else if(c == 'D') { B += v[ci][cj]; ci++; }\n            else if(c == 'L') { B += h[ci][cj-1]; cj--; }\n            else { B += h[ci][cj]; cj++; }\n        }\n\n        // Online gradient descent update\n        long double delta = ALPHA * (L - B) / (long double)path.size();\n        ci = si; cj = sj;\n        for(char c : path){\n            if(c == 'U') { v[ci-1][cj] += delta; ci--; }\n            else if(c == 'D') { v[ci][cj] += delta; ci++; }\n            else if(c == 'L') { h[ci][cj-1] += delta; cj--; }\n            else { h[ci][cj] += delta; cj++; }\n        }\n\n        // Adaptive Spatial Smoothing\n        // Horizontal edges: smooth per row\n        for(int i=0; i<30; ++i) {\n            long double sum = 0;\n            long double sum_sq = 0;\n            for(int j=0; j<29; ++j) {\n                sum += h[i][j];\n                sum_sq += h[i][j] * h[i][j];\n            }\n            long double mean = sum / 29.0L;\n            long double var = sum_sq / 29.0L - mean * mean;\n            \n            long double beta = (var > VAR_THRESHOLD) ? BETA_HIGH_VAR : BETA_LOW_VAR;\n            for(int j=0; j<29; ++j) \n                h[i][j] = h[i][j] * (1.0L - beta) + mean * beta;\n        }\n\n        // Vertical edges: smooth per column\n        for(int j=0; j<30; ++j) {\n            long double sum = 0;\n            long double sum_sq = 0;\n            for(int i=0; i<29; ++i) {\n                sum += v[i][j];\n                sum_sq += v[i][j] * v[i][j];\n            }\n            long double mean = sum / 29.0L;\n            long double var = sum_sq / 29.0L - mean * mean;\n            \n            long double beta = (var > VAR_THRESHOLD) ? BETA_HIGH_VAR : BETA_LOW_VAR;\n            for(int i=0; i<29; ++i) \n                v[i][j] = v[i][j] * (1.0L - beta) + mean * beta;\n        }\n\n        // Clamp weights to valid range\n        for(int i=0; i<30; ++i) for(int j=0; j<29; ++j) \n            h[i][j] = max(MIN_W, min(MAX_W, h[i][j]));\n        for(int i=0; i<29; ++i) for(int j=0; j<30; ++j) \n            v[i][j] = max(MIN_W, min(MAX_W, v[i][j]));\n    }\n    return 0;\n}","ahc004":"#pragma GCC optimize(\"Ofast,unroll-loops,fast-math\")\n#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <chrono>\n#include <random>\n#include <cstring>\n#include <algorithm>\n\nusing namespace std;\n\nconst int N = 20;\nconst int MAX_M = 800;\nconst int MAX_PLACEMENTS = 700000; \nconst int MAX_LINKS = 9000000;\n\nint M;\n// Structure of Arrays for placement data to improve cache locality\nint p_matches[MAX_PLACEMENTS];\nint p_len[MAX_PLACEMENTS];\nint p_str_id[MAX_PLACEMENTS];\n\n// Flat arrays for links: g_links stores placement IDs\n// g_link_start and g_link_count allow O(1) access to the range of links for a cell/char\nint g_links[MAX_LINKS];\nint g_link_start[N][N][8];\nint g_link_count[N][N][8];\nint g_link_curr[N][N][8];\n\nint str_full_cnt[MAX_M];\nchar grid[N][N];\nchar best_grid[N][N];\nint total_score = 0;\nint best_score = -1;\n\nmt19937_64 rng;\n\n// Auxiliary arrays for calculating score changes efficiently\nint string_delta[MAX_M];\nint touched_list[MAX_M];\n\n// Computes the change in score if we switch cell (r,c) from old_char_idx to new_char_idx.\n// This function correctly handles cases where a single string loses a full match\n// and gains a full match simultaneously (swapping).\ninline int calc_diff(int r, int c, int new_idx, int old_idx) {\n    int touched_count = 0;\n    \n    // Process Loss (removing old_idx)\n    // Check placements that will lose a match\n    int start_old = g_link_start[r][c][old_idx];\n    int count_old = g_link_count[r][c][old_idx];\n    const int* ptr_old = g_links + start_old;\n    for (int i = 0; i < count_old; ++i) {\n        int p = ptr_old[i];\n        // If a placement is currently full, losing a match might make it not full\n        if (p_matches[p] == p_len[p]) {\n            int k = p_str_id[p];\n            if (string_delta[k] == 0) {\n                touched_list[touched_count++] = k;\n            }\n            string_delta[k]--;\n        }\n    }\n    \n    // Process Gain (adding new_idx)\n    // Check placements that will gain a match\n    int start_new = g_link_start[r][c][new_idx];\n    int count_new = g_link_count[r][c][new_idx];\n    const int* ptr_new = g_links + start_new;\n    for (int i = 0; i < count_new; ++i) {\n        int p = ptr_new[i];\n        // If a placement is one short of full, gaining a match might make it full\n        if (p_matches[p] == p_len[p] - 1) {\n            int k = p_str_id[p];\n            if (string_delta[k] == 0) {\n                touched_list[touched_count++] = k;\n            }\n            string_delta[k]++;\n        }\n    }\n    \n    // Calculate net score change based on affected strings\n    int diff = 0;\n    for (int i = 0; i < touched_count; ++i) {\n        int k = touched_list[i];\n        int s_full = str_full_cnt[k];\n        int s_new = s_full + string_delta[k];\n        // If string was satisfied but no longer is\n        if (s_full > 0 && s_new == 0) diff--;\n        // If string was not satisfied but now is\n        else if (s_full == 0 && s_new > 0) diff++;\n        \n        // Reset delta for next step\n        string_delta[k] = 0; \n    }\n    return diff;\n}\n\n// Applies the change to the state. Assumes the move is accepted.\ninline void apply_change(int r, int c, int new_idx, int old_idx, int diff) {\n    grid[r][c] = 'A' + new_idx;\n    total_score += diff;\n    \n    // Update matches for old_idx (decrement)\n    int start_old = g_link_start[r][c][old_idx];\n    int count_old = g_link_count[r][c][old_idx];\n    const int* ptr_old = g_links + start_old;\n    for (int i = 0; i < count_old; ++i) {\n        int p = ptr_old[i];\n        // If it was full, it is no longer full\n        if (p_matches[p] == p_len[p]) {\n            str_full_cnt[p_str_id[p]]--;\n        }\n        p_matches[p]--;\n    }\n    \n    // Update matches for new_idx (increment)\n    int start_new = g_link_start[r][c][new_idx];\n    int count_new = g_link_count[r][c][new_idx];\n    const int* ptr_new = g_links + start_new;\n    for (int i = 0; i < count_new; ++i) {\n        int p = ptr_new[i];\n        // If it was one short of full, it becomes full\n        if (p_matches[p] == p_len[p] - 1) {\n            str_full_cnt[p_str_id[p]]++;\n        }\n        p_matches[p]++;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    rng.seed(chrono::steady_clock::now().time_since_epoch().count());\n\n    int N_in;\n    if (!(cin >> N_in >> M)) return 0;\n    vector<string> S(M);\n    for (int i = 0; i < M; ++i) cin >> S[i];\n\n    // First pass: Count links to determine offsets\n    memset(g_link_count, 0, sizeof(g_link_count));\n    int p_idx = 0;\n    for (int k = 0; k < M; ++k) {\n        int L = S[k].length();\n        // Horizontal\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                for (int p = 0; p < L; ++p) {\n                    int cc = (c + p) % N;\n                    g_link_count[r][cc][S[k][p] - 'A']++;\n                }\n                p_idx++;\n            }\n        }\n        // Vertical\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                for (int pp = 0; pp < L; ++pp) {\n                    int rr = (r + pp) % N;\n                    g_link_count[rr][c][S[k][pp] - 'A']++;\n                }\n                p_idx++;\n            }\n        }\n    }\n    \n    // Compute start offsets\n    int current_offset = 0;\n    for(int r=0; r<N; ++r) {\n        for(int c=0; c<N; ++c) {\n            for(int k=0; k<8; ++k) {\n                g_link_start[r][c][k] = current_offset;\n                current_offset += g_link_count[r][c][k];\n            }\n        }\n    }\n    // Initialize current pointers for filling\n    for(int r=0; r<N; ++r)\n        for(int c=0; c<N; ++c)\n            for(int k=0; k<8; ++k)\n                g_link_curr[r][c][k] = g_link_start[r][c][k];\n\n    // Second pass: Fill links\n    p_idx = 0;\n    for (int k = 0; k < M; ++k) {\n        int L = S[k].length();\n        // Horizontal\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                p_len[p_idx] = L;\n                p_str_id[p_idx] = k;\n                p_matches[p_idx] = 0;\n                for (int p = 0; p < L; ++p) {\n                    int cc = (c + p) % N;\n                    int char_idx = S[k][p] - 'A';\n                    g_links[g_link_curr[r][cc][char_idx]++] = p_idx;\n                }\n                p_idx++;\n            }\n        }\n        // Vertical\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                p_len[p_idx] = L;\n                p_str_id[p_idx] = k;\n                p_matches[p_idx] = 0;\n                for (int pp = 0; pp < L; ++pp) {\n                    int rr = (r + pp) % N;\n                    int char_idx = S[k][pp] - 'A';\n                    g_links[g_link_curr[rr][c][char_idx]++] = p_idx;\n                }\n                p_idx++;\n            }\n        }\n    }\n    vector<string>().swap(S);\n\n    // Greedy initialization\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            int best_c_idx = 0, max_v = -1;\n            for (int k = 0; k < 8; ++k) {\n                if (g_link_count[r][c][k] > max_v) {\n                    max_v = g_link_count[r][c][k];\n                    best_c_idx = k;\n                }\n            }\n            grid[r][c] = 'A' + best_c_idx;\n        }\n    }\n\n    // Initialize state (matches)\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            int cidx = grid[r][c] - 'A';\n            int start = g_link_start[r][c][cidx];\n            int count = g_link_count[r][c][cidx];\n            const int* ptr = g_links + start;\n            for (int i = 0; i < count; ++i) {\n                p_matches[ptr[i]]++;\n            }\n        }\n    }\n\n    // Initialize full counts and total score\n    memset(str_full_cnt, 0, sizeof(str_full_cnt));\n    memset(string_delta, 0, sizeof(string_delta));\n    for (int p = 0; p < MAX_PLACEMENTS; ++p) {\n        if (p_len[p] == 0) break;\n        if (p_matches[p] == p_len[p]) str_full_cnt[p_str_id[p]]++;\n    }\n    for (int k = 0; k < M; ++k) if (str_full_cnt[k] > 0) total_score++;\n\n    best_score = total_score;\n    memcpy(best_grid, grid, sizeof(grid));\n\n    // Simulated Annealing\n    auto start = chrono::steady_clock::now();\n    uniform_int_distribution<int> dist_rc(0, N-1);\n    uniform_int_distribution<int> dist_char(0, 7);\n    uniform_real_distribution<double> dist_prob(0.0, 1.0);\n\n    long long iter = 0;\n    while (true) {\n        if (++iter % 4096 == 0) {\n            if (chrono::steady_clock::now() >= start + chrono::milliseconds(2850)) break;\n        }\n\n        int r = dist_rc(rng);\n        int c = dist_rc(rng);\n        int old_idx = grid[r][c] - 'A';\n        int new_idx = dist_char(rng);\n        if (new_idx == old_idx) continue;\n\n        int diff = calc_diff(r, c, new_idx, old_idx);\n        \n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start).count();\n        double T = 0.8 / (1.0 + 2.5 * elapsed);\n        if (T < 0.005) T = 0.005;\n        \n        bool accept = false;\n        if (diff > 0) accept = true;\n        else if (dist_prob(rng) < exp((double)diff / T)) accept = true;\n\n        if (accept) {\n            apply_change(r, c, new_idx, old_idx, diff);\n            if (total_score > best_score) {\n                best_score = total_score;\n                memcpy(best_grid, grid, sizeof(grid));\n                if (best_score == M) break;\n            }\n        }\n    }\n\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) cout << best_grid[r][c];\n        cout << '\\n';\n    }\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\n\nconst int INF = 1e9;\nconst int MAX_ROAD = 5000;\n\nstruct Point { int r, c; };\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, si, sj;\n    if (!(cin >> N >> si >> sj)) return 0;\n    vector<string> grid(N);\n    vector<vector<int>> road_id(N, vector<int>(N, -1));\n    vector<Point> road_cells;\n    int R = 0;\n    for (int i = 0; i < N; ++i) {\n        cin >> grid[i];\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] != '#') {\n                road_id[i][j] = R++;\n                road_cells.push_back({i, j});\n            }\n        }\n    }\n\n    // 1. Candidate Selection\n    struct Cand { int r, c; };\n    vector<Cand> cands;\n    vector<vector<int>> cand_map(N, vector<int>(N, -1));\n    \n    auto add_cand = [&](int r, int c) {\n        if (cand_map[r][c] != -1) return;\n        cand_map[r][c] = cands.size();\n        cands.push_back({r, c});\n    };\n\n    // Start point\n    add_cand(si, sj);\n    int dr[] = {-1, 1, 0, 0};\n    int dc[] = {0, 0, -1, 1};\n\n    // Junctions & Endpoints\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] == '#') continue;\n            int deg = 0;\n            for (int k = 0; k < 4; ++k) {\n                int ni = i + dr[k], nj = j + dc[k];\n                if (ni >= 0 && ni < N && nj >= 0 && nj < N && grid[ni][nj] != '#') deg++;\n            }\n            if (deg != 2) add_cand(i, j);\n        }\n    }\n\n    // Midpoints of long segments\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] != '#') {\n                int start = j;\n                while (j < N && grid[i][j] != '#') j++;\n                int end = j - 1;\n                if (end - start + 1 > 10) add_cand(i, (start + end) / 2);\n            }\n        }\n    }\n    for (int j = 0; j < N; ++j) {\n        for (int i = 0; i < N; ++i) {\n            if (grid[i][j] != '#') {\n                int start = i;\n                while (i < N && grid[i][j] != '#') i++;\n                int end = i - 1;\n                if (end - start + 1 > 10) add_cand((start + end) / 2, j);\n            }\n        }\n    }\n\n    int M = cands.size();\n    vector<vector<int>> dist_mat(M, vector<int>(M, INF));\n    vector<int> d(N * N);\n    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;\n\n    // 2. Distance Matrix (APSP)\n    for (int i = 0; i < M; ++i) {\n        int sr = cands[i].r, sc = cands[i].c;\n        int u0 = sr * N + sc;\n        fill(d.begin(), d.end(), INF);\n        d[u0] = 0;\n        pq.emplace(0, u0);\n        dist_mat[i][i] = 0;\n\n        while (!pq.empty()) {\n            auto [dst, u] = pq.top(); pq.pop();\n            if (dst > d[u]) continue;\n            int ur = u / N, uc = u % N;\n            if (cand_map[ur][uc] != -1) dist_mat[i][cand_map[ur][uc]] = dst;\n            for (int k = 0; k < 4; ++k) {\n                int vr = ur + dr[k], vc = uc + dc[k];\n                if (vr < 0 || vr >= N || vc < 0 || vc >= N || grid[vr][vc] == '#') continue;\n                int v = vr * N + vc;\n                int w = grid[vr][vc] - '0';\n                if (d[u] + w < d[v]) { d[v] = d[u] + w; pq.emplace(d[v], v); }\n            }\n        }\n    }\n\n    // 3. Coverage Precomputation\n    vector<bitset<MAX_ROAD>> cov(M);\n    for (int i = 0; i < M; ++i) {\n        int r = cands[i].r, c = cands[i].c;\n        for (int j = c; j >= 0 && grid[r][j] != '#'; --j) cov[i][road_id[r][j]] = 1;\n        for (int j = c + 1; j < N && grid[r][j] != '#'; ++j) cov[i][road_id[r][j]] = 1;\n        for (int k = r - 1; k >= 0 && grid[k][c] != '#'; --k) cov[i][road_id[k][c]] = 1;\n        for (int k = r + 1; k < N && grid[k][c] != '#'; ++k) cov[i][road_id[k][c]] = 1;\n    }\n\n    int start_cand = cand_map[si][sj];\n    if (start_cand == -1) start_cand = 0;\n\n    vector<int> tour;\n    tour.push_back(start_cand);\n    vector<bool> in_tour(M, false);\n    in_tour[start_cand] = true;\n    \n    vector<int> cover_cnt(R, 0);\n    int uncovered = R;\n    bitset<MAX_ROAD> covered_global;\n\n    auto update_coverage = [&](int idx, int delta) {\n        for (size_t bit = 0; bit < R; ++bit) {\n            if (cov[idx][bit]) {\n                cover_cnt[bit] += delta;\n                if (delta > 0 && cover_cnt[bit] == 1) { uncovered--; covered_global[bit] = 1; }\n                if (delta < 0 && cover_cnt[bit] == 0) { uncovered++; covered_global[bit] = 0; }\n            }\n        }\n    };\n    update_coverage(start_cand, 1);\n\n    auto t0 = chrono::high_resolution_clock::now();\n    auto get_time = [&]() { return chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - t0).count(); };\n\n    // 4. Greedy Construction (Strictly prioritizes coverage)\n    while (uncovered > 0 && get_time() < 2500) {\n        int best_k = -1, best_pos = 0;\n        double best_ratio = 0.0;\n        int sz = tour.size();\n        \n        // Precompute min insertion cost for each candidate\n        vector<int> min_cost(M, INF);\n        for (int k = 0; k < M; ++k) {\n            if (in_tour[k]) continue;\n            int mc = INF;\n            for (int i = 0; i < sz; ++i) {\n                int u = tour[i], v = tour[(i+1)%sz];\n                if (dist_mat[u][k] == INF || dist_mat[k][v] == INF || dist_mat[u][v] == INF) continue;\n                int c = dist_mat[u][k] + dist_mat[k][v] - dist_mat[u][v];\n                if (c < mc) mc = c;\n            }\n            min_cost[k] = mc;\n        }\n\n        for (int k = 0; k < M; ++k) {\n            if (in_tour[k] || min_cost[k] == INF || min_cost[k] == 0) continue;\n            \n            // Efficient gain calculation\n            bitset<MAX_ROAD> temp = cov[k];\n            temp &= ~covered_global;\n            int gain = temp.count();\n            \n            if (gain > 0) {\n                double ratio = (double)gain / min_cost[k];\n                if (ratio > best_ratio) {\n                    best_ratio = ratio;\n                    best_k = k;\n                    int best_c = INF;\n                    for (int i = 0; i < sz; ++i) {\n                        int u = tour[i], v = tour[(i+1)%sz];\n                        int c = dist_mat[u][k] + dist_mat[k][v] - dist_mat[u][v];\n                        if (c < best_c) { best_c = c; best_pos = i + 1; }\n                    }\n                }\n            }\n        }\n\n        if (best_k == -1) break; // All visible or disconnected\n        tour.insert(tour.begin() + best_pos, best_k);\n        in_tour[best_k] = true;\n        update_coverage(best_k, 1);\n    }\n\n    // Safety: If still uncovered, force add uncovered cells as candidates\n    if (uncovered > 0) {\n        for (int i = 0; i < R; ++i) {\n            if (cover_cnt[i] == 0) {\n                int r = road_cells[i].r, c = road_cells[i].c;\n                if (cand_map[r][c] == -1) {\n                    add_cand(r, c);\n                    int new_idx = cands.size() - 1;\n                    M++;\n                    dist_mat.emplace_back(M, INF);\n                    for(auto& row : dist_mat) if(row.size() < M) row.push_back(INF);\n                    \n                    // Quick Dijkstra for new candidate\n                    int sr = r, sc = c, u0 = sr * N + sc;\n                    fill(d.begin(), d.end(), INF);\n                    d[u0] = 0;\n                    pq.emplace(0, u0);\n                    dist_mat[new_idx][new_idx] = 0;\n                    while(!pq.empty()){\n                        auto [dst, u] = pq.top(); pq.pop();\n                        if(dst > d[u]) continue;\n                        int ur = u/N, uc = u%N;\n                        if(cand_map[ur][uc] != -1) dist_mat[new_idx][cand_map[ur][uc]] = dst;\n                        for(int k=0;k<4;++k){\n                            int vr = ur+dr[k], vc = uc+dc[k];\n                            if(vr<0||vr>=N||vc<0||vc>=N||grid[vr][vc]=='#') continue;\n                            int v = vr*N+vc, w = grid[vr][vc]-'0';\n                            if(d[u]+w < d[v]) { d[v]=d[u]+w; pq.emplace(d[v],v); }\n                        }\n                    }\n                    // Update coverage\n                    for(int k=0;k<M;++k) dist_mat[k][new_idx] = dist_mat[new_idx][k];\n                    for (int j = c; j >= 0 && grid[r][j] != '#'; --j) cov[new_idx][road_id[r][j]] = 1;\n                    for (int j = c + 1; j < N && grid[r][j] != '#'; ++j) cov[new_idx][road_id[r][j]] = 1;\n                    for (int k = r - 1; k >= 0 && grid[k][c] != '#'; --k) cov[new_idx][road_id[k][c]] = 1;\n                    for (int k = r + 1; k < N && grid[k][c] != '#'; ++k) cov[new_idx][road_id[k][c]] = 1;\n                    \n                    tour.push_back(new_idx);\n                    update_coverage(new_idx, 1);\n                }\n            }\n        }\n    }\n\n    // 5. Redundancy Removal\n    bool improved_red = true;\n    while (improved_red) {\n        improved_red = false;\n        for (int i = (int)tour.size() - 1; i >= 0; --i) {\n            int node = tour[i];\n            if (node == start_cand) continue;\n            update_coverage(node, -1);\n            if (uncovered == 0) {\n                tour.erase(tour.begin() + i);\n                in_tour[node] = false;\n                improved_red = true;\n            } else {\n                update_coverage(node, 1);\n            }\n        }\n    }\n\n    // 6. 2-opt Optimization\n    improved_red = true;\n    while (improved_red && get_time() < 2800) {\n        improved_red = false;\n        int sz = tour.size();\n        for (int i = 0; i < sz; ++i) {\n            for (int j = i + 2; j < sz; ++j) {\n                if (i == 0 && j == sz - 1) continue;\n                int u1 = tour[i], v1 = tour[(i + 1) % sz];\n                int u2 = tour[j], v2 = tour[(j + 1) % sz];\n                if (dist_mat[u1][u2] != INF && dist_mat[v1][v2] != INF &&\n                    dist_mat[u1][v1] != INF && dist_mat[u2][v2] != INF) {\n                    if (dist_mat[u1][u2] + dist_mat[v1][v2] < dist_mat[u1][v1] + dist_mat[u2][v2]) {\n                        reverse(tour.begin() + i + 1, tour.begin() + j + 1);\n                        improved_red = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // 7. Path Reconstruction\n    string result = \"\";\n    result.reserve(tour.size() * 50);\n    vector<int> parent(N * N, -1);\n    vector<char> move_char(N * N);\n    char moves[4] = {'U', 'D', 'L', 'R'};\n\n    auto get_path = [&](int from_cand, int to_cand) {\n        if (from_cand == to_cand) return string(\"\");\n        int r1 = cands[from_cand].r, c1 = cands[from_cand].c;\n        int r2 = cands[to_cand].r, c2 = cands[to_cand].c;\n        if (r1 == r2 && c1 == c2) return string(\"\");\n        \n        fill(d.begin(), d.end(), INF);\n        fill(parent.begin(), parent.end(), -1);\n        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq2;\n        \n        int u0 = r1 * N + c1, target = r2 * N + c2;\n        d[u0] = 0;\n        pq2.emplace(0, u0);\n\n        while (!pq2.empty()) {\n            auto [dst, u] = pq2.top(); pq2.pop();\n            if (dst > d[u]) continue;\n            if (u == target) break;\n            int ur = u / N, uc = u % N;\n            for (int k = 0; k < 4; ++k) {\n                int vr = ur + dr[k], vc = uc + dc[k];\n                if (vr < 0 || vr >= N || vc < 0 || vc >= N || grid[vr][vc] == '#') continue;\n                int v = vr * N + vc;\n                int w = grid[vr][vc] - '0';\n                if (d[u] + w < d[v]) {\n                    d[v] = d[u] + w;\n                    parent[v] = u;\n                    move_char[v] = moves[k];\n                    pq2.emplace(d[v], v);\n                }\n            }\n        }\n        \n        string path = \"\";\n        int curr = target;\n        if (parent[curr] == -1 && curr != u0) return string(\"\");\n        while (curr != u0) {\n            path += move_char[curr];\n            curr = parent[curr];\n        }\n        reverse(path.begin(), path.end());\n        return path;\n    };\n\n    for (size_t i = 0; i < tour.size(); ++i) {\n        result += get_path(tour[i], tour[(i + 1) % tour.size()]);\n    }\n\n    cout << result << \"\\n\";\n    return 0;\n}","future-contest-2022-qual":"#pragma GCC optimize(\"Ofast,unroll-loops,fast-math\")\n#pragma GCC target(\"avx2,fma\")\n\n#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <cmath>\n\nusing namespace std;\n\n// Constants\nconst int MAXN = 1005;\nconst int MAXM = 25;\nconst int MAXK = 25;\n\nint N, M, K, R;\nint d[MAXN][MAXK];\nlong long sum_diff[MAXN];\nlong long rank_diff[MAXN]; // Criticality: longest path in DAG weighted by difficulty\nvector<int> adj[MAXN];\nint in_deg[MAXN];\n\ndouble est_s[MAXM][MAXK];\ndouble sum_est_s[MAXM]; // Heuristic: total skill level of member\nint mem_task[MAXM];\nint mem_start[MAXM];\nint mem_done[MAXM];\n\n// Priority Queue Comparator: higher rank_diff first\nstruct TaskCmp {\n    bool operator()(int a, int b) const { return rank_diff[a] < rank_diff[b]; }\n};\n\npriority_queue<int, vector<int>, TaskCmp> pq;\n\nint free_list[MAXM];\npair<int, int> out_buf[MAXM];\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> K >> R)) return 0;\n\n    // Read task difficulties\n    for (int i = 0; i < N; ++i) {\n        sum_diff[i] = 0;\n        for (int j = 0; j < K; ++j) {\n            cin >> d[i][j];\n            sum_diff[i] += d[i][j];\n        }\n    }\n\n    // Read dependencies\n    for (int i = 0; i < R; ++i) {\n        int u, v; cin >> u >> v; --u; --v;\n        adj[u].push_back(v);\n        in_deg[v]++;\n    }\n\n    // Compute rank_diff (longest path from task to end)\n    // Since input guarantees u < v, tasks are in topological order.\n    // We iterate backwards to compute ranks efficiently.\n    for (int i = N - 1; i >= 0; --i) {\n        long long max_child = 0;\n        for (int v : adj[i]) {\n            if (rank_diff[v] > max_child) max_child = rank_diff[v];\n        }\n        rank_diff[i] = sum_diff[i] + max_child;\n    }\n\n    // Initialize Priority Queue with ready tasks\n    for (int i = 0; i < N; ++i) {\n        if (in_deg[i] == 0) pq.push(i);\n    }\n\n    // Initialize member states and skill estimates\n    // Conservative initialization (5.0) ensures we slightly underestimate skills.\n    // This is safe for scheduling (predict longer times -> finish early)\n    // and allows gradient updates for a wider range of tasks.\n    for (int i = 0; i < M; ++i) {\n        sum_est_s[i] = 0.0;\n        for (int j = 0; j < K; ++j) {\n            est_s[i][j] = 5.0; \n            sum_est_s[i] += 5.0;\n        }\n        mem_task[i] = -1;\n        mem_start[i] = -1;\n        mem_done[i] = 0;\n    }\n\n    for (int day = 1; day <= 2000; ++day) {\n        // 1. Identify free members\n        int free_count = 0;\n        for (int m = 0; m < M; ++m) {\n            if (mem_task[m] == -1) free_list[free_count++] = m;\n        }\n\n        // 2. Greedy Assignment\n        int assign_count = 0;\n        while (!pq.empty() && free_count > 0) {\n            int t = pq.top();\n            pq.pop();\n\n            int best_m = -1;\n            int best_idx = -1;\n            double best_cost = 1e18;\n            double best_skill_sum = 1e18; \n\n            // Find best member for task t\n            for (int i = 0; i < free_count; ++i) {\n                int m = free_list[i];\n                double w = 0;\n                for (int k = 0; k < K; ++k) {\n                    double diff = d[t][k] - est_s[m][k];\n                    if (diff > 0) w += diff;\n                }\n                // Expected completion time heuristic\n                double cost = max(1.0, w);\n                \n                // Check if better\n                if (cost < best_cost - 1e-9) {\n                    best_cost = cost;\n                    best_m = m;\n                    best_idx = i;\n                    best_skill_sum = sum_est_s[m];\n                } else if (abs(cost - best_cost) < 1e-9) {\n                    // Tie: prefer member with lower total skill (save experts)\n                    if (sum_est_s[m] < best_skill_sum) {\n                        best_cost = cost;\n                        best_m = m;\n                        best_idx = i;\n                        best_skill_sum = sum_est_s[m];\n                    }\n                }\n            }\n\n            if (best_m != -1) {\n                mem_task[best_m] = t;\n                mem_start[best_m] = day;\n                out_buf[assign_count++] = {best_m + 1, t + 1};\n                // Remove member from free list in O(1) by swapping with last\n                free_list[best_idx] = free_list[free_count - 1];\n                free_count--;\n            }\n        }\n\n        // 3. Output assignments\n        cout << assign_count;\n        for (int i = 0; i < assign_count; ++i) {\n            cout << \" \" << out_buf[i].first << \" \" << out_buf[i].second;\n        }\n        cout << \"\\n\" << flush;\n\n        // 4. Read completions\n        int nf;\n        if (!(cin >> nf)) break;\n        if (nf == -1) return 0;\n\n        // 5. Process completions and update skill estimates\n        for (int i = 0; i < nf; ++i) {\n            int f; cin >> f; --f;\n            int t = mem_task[f];\n            if (t == -1) continue;\n\n            int actual = day - mem_start[f] + 1;\n            mem_task[f] = -1;\n            mem_done[f]++;\n\n            // Analyze prediction vs actual\n            double pred_w = 0;\n            int def = 0; // Count of deficient skills based on estimate\n            \n            for (int k = 0; k < K; ++k) {\n                double diff = d[t][k] - est_s[f][k];\n                if (diff > 0) {\n                    pred_w += diff;\n                    def++;\n                }\n            }\n\n            // Robust skill update based on noise range [-3, 3]\n            // t = max(1, w_true + r). r in [-3, 3].\n            // Valid range for w_true given t:\n            // If t=1: w_true in [0, 4)\n            // If t>1: w_true in [t-3, t+3]\n            \n            // We use a threshold of 3.5 to account for float errors and be safe.\n            \n            double lr = 1.0 / (1.0 + 0.01 * mem_done[f]);\n\n            // Check if pred_w is too low (Underestimated deficit -> Overestimated skills)\n            // Condition: pred_w < lower_bound of valid range\n            // lower_bound is approx actual - 3.\n            // We check actual > pred_w + 3.5\n            if (actual > pred_w + 3.5) {\n                // We need to decrease skills.\n                // If pred_w is near 0 (def=0), we decrease blindly.\n                // If pred_w > 0, we decrease deficient skills.\n                \n                // Error magnitude to correct\n                double err = actual - pred_w; \n                // Cap error to avoid overshooting due to rare large noise streaks\n                if (err > 10.0) err = 10.0;\n\n                if (def > 0) {\n                    double unit_err = err / def;\n                    if (unit_err > 5.0) unit_err = 5.0; // Cap per-skill update\n                    for (int k = 0; k < K; ++k) {\n                        if (d[t][k] > est_s[f][k]) {\n                            double val = est_s[f][k] - lr * unit_err;\n                            if (val < 0.0) val = 0.0;\n                            est_s[f][k] = val;\n                        }\n                    }\n                } else {\n                    // Blind decrease: pred_w is 0, but actual is high.\n                    // Means true deficit exists, so skills are overestimated.\n                    int cnt_req = 0;\n                    for(int k=0; k<K; ++k) if(d[t][k] > 0) cnt_req++;\n                    \n                    if (cnt_req > 0) {\n                        double unit_err = err / cnt_req;\n                        if (unit_err > 5.0) unit_err = 5.0;\n                        for (int k = 0; k < K; ++k) {\n                            if (d[t][k] > 0) { \n                                double val = est_s[f][k] - lr * unit_err;\n                                if (val < 0.0) val = 0.0;\n                                est_s[f][k] = val;\n                            }\n                        }\n                    }\n                }\n            }\n            // Check if pred_w is too high (Overestimated deficit -> Underestimated skills)\n            // Condition: pred_w > upper_bound of valid range\n            // upper_bound is approx actual + 3.\n            // We check pred_w > actual + 3.5\n            // Note: We removed \"actual > 1\" check here because even if actual=1,\n            // a high pred_w (e.g. 5) is inconsistent (since w_true would have to be <= 4).\n            else if (pred_w > actual + 3.5) {\n                // We need to increase skills.\n                // Since pred_w > actual + 3.5 >= 4.5, pred_w is definitely > 0.\n                // So def > 0 is guaranteed.\n                \n                double err = pred_w - actual;\n                if (err > 10.0) err = 10.0;\n\n                if (def > 0) {\n                    double unit_err = err / def;\n                    if (unit_err > 5.0) unit_err = 5.0;\n                    for (int k = 0; k < K; ++k) {\n                        if (d[t][k] > est_s[f][k]) {\n                            double val = est_s[f][k] + lr * unit_err;\n                            if (val > 80.0) val = 80.0;\n                            est_s[f][k] = val;\n                        }\n                    }\n                }\n            }\n            \n            // Recalculate sum_est_s for next day's tie-breaking\n            double s_sum = 0;\n            for(int k=0; k<K; ++k) s_sum += est_s[f][k];\n            sum_est_s[f] = s_sum;\n\n            // Release dependencies\n            for (int v : adj[t]) {\n                if (--in_deg[v] == 0) pq.push(v);\n            }\n        }\n    }\n\n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <chrono>\n#include <random>\n\nusing namespace std;\n\nstruct Pt { int x, y; };\ninline int dist(const Pt& a, const Pt& b) { return abs(a.x - b.x) + abs(a.y - b.y); }\nconst Pt BASE = {400, 400};\n\nstruct Order { int id; Pt p, d; };\nstruct Stop { int order_idx; bool is_delivery; };\n\nvector<Order> all_orders;\nvector<Order> sel_orders;\nvector<Stop> route;\n\nPt get_pt(const Stop& s) {\n    const Order& o = sel_orders[s.order_idx];\n    return s.is_delivery ? o.d : o.p;\n}\n\nint calc_cost() {\n    if (route.empty()) return 0;\n    int c = dist(BASE, get_pt(route[0]));\n    for (size_t i = 0; i + 1 < route.size(); ++i) {\n        c += dist(get_pt(route[i]), get_pt(route[i+1]));\n    }\n    c += dist(get_pt(route.back()), BASE);\n    return c;\n}\n\nbool check_validity() {\n    if (route.size() != 100) return false;\n    bool picked[50] = {false};\n    int counts[50] = {0};\n    for (const auto& s : route) {\n        if (s.order_idx < 0 || s.order_idx >= 50) return false;\n        if (s.is_delivery) {\n            if (!picked[s.order_idx]) return false;\n            if (++counts[s.order_idx] > 1) return false;\n        } else {\n            if (++counts[s.order_idx] > 1) return false;\n            picked[s.order_idx] = true;\n        }\n    }\n    for (int i = 0; i < 50; ++i) {\n        if (counts[i] != 2) return false;\n    }\n    return true;\n}\n\nauto start_time = chrono::steady_clock::now();\ninline double elapsed() { return chrono::duration<double>(chrono::steady_clock::now() - start_time).count(); }\n\nvoid build_initial_route() {\n    route.clear(); route.reserve(100);\n    vector<bool> in_p(50, false), in_d(50, false);\n    int placed = 0;\n    while (placed < 100) {\n        int best_pos = -1, best_idx = -1;\n        bool best_is_del = false;\n        int min_d = 2e9;\n        bool found = false;\n\n        for (int i = 0; i < 50; ++i) {\n            if (!in_p[i]) {\n                found = true;\n                Stop s = {i, false};\n                Pt pt = get_pt(s);\n                for (int pos = 0; pos <= placed; ++pos) {\n                    Pt prev = (pos == 0) ? BASE : get_pt(route[pos-1]);\n                    Pt next = (pos == placed) ? BASE : get_pt(route[pos]);\n                    int delta = dist(prev, pt) + dist(pt, next) - dist(prev, next);\n                    if (delta < min_d) { min_d = delta; best_pos = pos; best_idx = i; best_is_del = false; }\n                }\n            }\n            if (in_p[i] && !in_d[i]) {\n                found = true;\n                Stop s = {i, true};\n                Pt pt = get_pt(s);\n                for (int pos = 0; pos <= placed; ++pos) {\n                    Pt prev = (pos == 0) ? BASE : get_pt(route[pos-1]);\n                    Pt next = (pos == placed) ? BASE : get_pt(route[pos]);\n                    int delta = dist(prev, pt) + dist(pt, next) - dist(prev, next);\n                    if (delta < min_d) { min_d = delta; best_pos = pos; best_idx = i; best_is_del = true; }\n                }\n            }\n        }\n        if (!found || best_pos == -1) break;\n\n        route.insert(route.begin() + best_pos, {best_idx, best_is_del});\n        if (!best_is_del) in_p[best_idx] = true;\n        else in_d[best_idx] = true;\n        placed++;\n    }\n}\n\nvoid run_local_search(double budget) {\n    double end_t = elapsed() + budget;\n    int current_cost = calc_cost();\n    bool improved = true;\n    while (improved && elapsed() < end_t) {\n        improved = false;\n        int n = route.size();\n        // 2-opt\n        for (int l = 0; l < n - 1 && elapsed() < end_t; ++l) {\n            for (int r = l + 1; r < n; ++r) {\n                vector<Stop> tmp = route;\n                reverse(tmp.begin() + l, tmp.begin() + r + 1);\n                \n                bool valid = true;\n                bool p_seen[50] = {false}; int cnt[50] = {0};\n                for (const auto& s : tmp) {\n                    if (s.is_delivery) { if (!p_seen[s.order_idx] || ++cnt[s.order_idx] > 1) { valid = false; break; } }\n                    else { if (++cnt[s.order_idx] > 1) { valid = false; break; } p_seen[s.order_idx] = true; }\n                }\n                if (valid) for(int k=0; k<50; ++k) if(cnt[k]!=2) { valid=false; break; }\n                \n                if (valid) {\n                    int nc = dist(BASE, get_pt(tmp[0]));\n                    for(int i=0; i<n-1; ++i) nc += dist(get_pt(tmp[i]), get_pt(tmp[i+1]));\n                    nc += dist(get_pt(tmp[n-1]), BASE);\n                    if (nc < current_cost) {\n                        route = tmp; current_cost = nc; improved = true; goto next_ls;\n                    }\n                }\n            }\n        }\n        // Relocate\n        for (int i = 0; i < n && elapsed() < end_t; ++i) {\n            Stop s = route[i];\n            vector<Stop> tmp = route;\n            tmp.erase(tmp.begin() + i);\n            for (int k = 0; k < n; ++k) {\n                if (k == i) continue;\n                vector<Stop> cand = tmp;\n                cand.insert(cand.begin() + k, s);\n                \n                bool valid = true;\n                bool p_seen[50] = {false}; int cnt[50] = {0};\n                for (const auto& st : cand) {\n                    if (st.is_delivery) { if (!p_seen[st.order_idx] || ++cnt[st.order_idx] > 1) { valid = false; break; } }\n                    else { if (++cnt[st.order_idx] > 1) { valid = false; break; } p_seen[st.order_idx] = true; }\n                }\n                if (valid) for(int kk=0; kk<50; ++kk) if(cnt[kk]!=2) { valid=false; break; }\n                \n                if (valid) {\n                    int nc = dist(BASE, get_pt(cand[0]));\n                    for(int j=0; j<n-1; ++j) nc += dist(get_pt(cand[j]), get_pt(cand[j+1]));\n                    nc += dist(get_pt(cand[n-1]), BASE);\n                    if (nc < current_cost) {\n                        route = cand; current_cost = nc; improved = true; goto next_ls;\n                    }\n                }\n            }\n        }\n        next_ls:;\n    }\n}\n\nvoid run_order_swap(double budget) {\n    mt19937 rng(42);\n    uniform_int_distribution<int> dist_id(1, 1000);\n    double end_t = elapsed() + budget;\n    int best_c = calc_cost();\n    \n    while (elapsed() < end_t) {\n        int idx = rng() % 50;\n        int out_id;\n        do { out_id = dist_id(rng); } while (find_if(sel_orders.begin(), sel_orders.end(), [&](const Order& o){ return o.id == out_id; }) != sel_orders.end());\n        \n        vector<Stop> old_r = route;\n        Order old_ord = sel_orders[idx];\n        \n        sel_orders[idx].id = out_id;\n        sel_orders[idx].p = all_orders[out_id-1].p;\n        sel_orders[idx].d = all_orders[out_id-1].d;\n        \n        vector<Stop> tmp_r; tmp_r.reserve(100);\n        for (const auto& s : route) if (s.order_idx != idx) tmp_r.push_back(s);\n        \n        int sz1 = tmp_r.size();\n        int bp = 0, bd = 2e9;\n        Stop ps = {idx, false}; Pt pp_pt = get_pt(ps);\n        for (int pos = 0; pos <= sz1; ++pos) {\n            Pt prev = (pos == 0) ? BASE : get_pt(tmp_r[pos-1]);\n            Pt next = (pos == sz1) ? BASE : get_pt(tmp_r[pos]);\n            int d = dist(prev, pp_pt) + dist(pp_pt, next) - dist(prev, next);\n            if (d < bd) { bd = d; bp = pos; }\n        }\n        tmp_r.insert(tmp_r.begin() + bp, ps);\n        int pp = bp;\n        \n        int sz2 = tmp_r.size();\n        int bp2 = pp + 1, bd2 = 2e9;\n        Stop ds = {idx, true}; Pt dp_pt = get_pt(ds);\n        for (int pos = pp + 1; pos <= sz2; ++pos) {\n            Pt prev = (pos == 0) ? BASE : get_pt(tmp_r[pos-1]);\n            Pt next = (pos == sz2) ? BASE : get_pt(tmp_r[pos]);\n            int d = dist(prev, dp_pt) + dist(dp_pt, next) - dist(prev, next);\n            if (d < bd2) { bd2 = d; bp2 = pos; }\n        }\n        tmp_r.insert(tmp_r.begin() + bp2, ds);\n        \n        bool valid = true; bool p_seen[50]={0}; int cnt[50]={0};\n        for(const auto& s:tmp_r) {\n            if(s.is_delivery){if(!p_seen[s.order_idx]||++cnt[s.order_idx]>1){valid=false;break;}}\n            else{if(++cnt[s.order_idx]>1){valid=false;break;} p_seen[s.order_idx]=true;}\n        }\n        if(valid) for(int k=0;k<50;++k) if(cnt[k]!=2) valid=false;\n        \n        if (valid) {\n            int nc = dist(BASE, get_pt(tmp_r[0]));\n            for(int i=0; i<99; ++i) nc += dist(get_pt(tmp_r[i]), get_pt(tmp_r[i+1]));\n            nc += dist(get_pt(tmp_r[99]), BASE);\n            \n            if (nc < best_c) {\n                route = tmp_r; best_c = nc;\n                if (elapsed() < end_t - 0.05) run_local_search(0.05);\n                best_c = calc_cost();\n            } else {\n                route = old_r; sel_orders[idx] = old_ord;\n            }\n        } else {\n            route = old_r; sel_orders[idx] = old_ord;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    all_orders.resize(1000);\n    for (int i = 0; i < 1000; ++i) {\n        cin >> all_orders[i].p.x >> all_orders[i].p.y >> all_orders[i].d.x >> all_orders[i].d.y;\n        all_orders[i].id = i + 1;\n    }\n    \n    vector<pair<int,int>> dists(1000);\n    for (int i = 0; i < 1000; ++i) dists[i] = {dist(BASE, all_orders[i].p), i};\n    nth_element(dists.begin(), dists.begin() + 50, dists.end());\n    \n    sel_orders.resize(50);\n    for (int i = 0; i < 50; ++i) sel_orders[i] = all_orders[dists[i].second];\n    \n    build_initial_route();\n    if (!check_validity()) { build_initial_route(); }\n\n    run_local_search(1.2);\n    run_order_swap(0.6);\n    run_local_search(0.2);\n    \n    if (!check_validity()) {\n        route.clear(); route.reserve(100);\n        for(int i=0;i<50;++i) route.push_back({i,false});\n        for(int i=0;i<50;++i) route.push_back({i,true});\n    }\n\n    vector<int> ids; ids.reserve(50);\n    for (const auto& o : sel_orders) ids.push_back(o.id);\n    sort(ids.begin(), ids.end());\n\n    cout << \"50\";\n    for (int id : ids) cout << \" \" << id;\n    cout << \"\\n\";\n    \n    cout << \"102\";\n    cout << \" \" << BASE.x << \" \" << BASE.y;\n    for (const auto& s : route) cout << \" \" << get_pt(s).x << \" \" << get_pt(s).y;\n    cout << \" \" << BASE.x << \" \" << BASE.y << \"\\n\";\n    \n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <utility>\n\nusing namespace std;\n\n// Disjoint Set Union (DSU) with path compression and union by rank\nstruct DSU {\n    vector<int> parent, rank;\n    DSU(int n) : parent(n), rank(n, 0) {\n        for (int i = 0; i < n; ++i) parent[i] = i;\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        i = find(i); j = find(j);\n        if (i != j) {\n            if (rank[i] < rank[j]) swap(i, j);\n            parent[j] = i;\n            if (rank[i] == rank[j]) rank[i]++;\n            return true;\n        }\n        return false;\n    }\n};\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 400;\n    const int M = 1995;\n\n    // 1. Read vertex coordinates\n    vector<pair<int, int>> coords(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n\n    // 2. Read edge endpoints and precompute base distances d_i\n    vector<pair<int, int>> edges(M);\n    vector<int> d(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> edges[i].first >> edges[i].second;\n        long long dx = coords[edges[i].first].first - coords[edges[i].second].first;\n        long long dy = coords[edges[i].first].second - coords[edges[i].second].second;\n        // Euclidean distance rounded to nearest integer\n        d[i] = static_cast<int>(round(sqrt(dx * dx + dy * dy)));\n    }\n\n    DSU dsu(N);\n    const int INF = 1e9;\n\n    // 3. Process edges online\n    for (int i = 0; i < M; ++i) {\n        int l;\n        cin >> l;\n\n        int u = edges[i].first;\n        int v = edges[i].second;\n        int ru = dsu.find(u);\n        int rv = dsu.find(v);\n\n        if (ru == rv) {\n            // Already connected, accepting would form a cycle.\n            cout << \"0\\n\";\n        } else {\n            // Lookahead: find the minimum base distance among future edges\n            // that connect the current components ru and rv.\n            // Also count how many future edges achieve this minimum.\n            int min_d = INF;\n            int k = 0;\n            \n            for (int j = i + 1; j < M; ++j) {\n                int rju = dsu.find(edges[j].first);\n                int rjv = dsu.find(edges[j].second);\n                \n                if ((rju == ru && rjv == rv) || (rju == rv && rjv == ru)) {\n                    if (d[j] < min_d) {\n                        min_d = d[j];\n                        k = 1;\n                    } else if (d[j] == min_d) {\n                        k++;\n                    }\n                }\n            }\n\n            bool accept = false;\n            if (min_d == INF) {\n                // No future edge can connect these components.\n                // Must accept to maintain connectivity.\n                accept = true;\n            } else if (l < min_d) {\n                // Current edge is cheaper than the absolute minimum possible cost \n                // of any future competitor. Strictly optimal to accept.\n                accept = true;\n            } else {\n                // Adaptive threshold based on expected minimum of k uniform variables.\n                // E[min of k ~ U[d, 3d]] approx d * (1 + 2/(k+1)).\n                // We apply a bias of 1.15 to account for online path dependencies \n                // and the high cost of rejecting direct edges.\n                // This bias makes us slightly more aggressive (higher threshold).\n                double factor = 1.0 + 2.0 / (k + 1.0);\n                factor *= 1.15; \n                \n                // Clamp the factor to [1.60, 1.90].\n                // Floor 1.60 prevents excessive conservatism when k is large.\n                // Cap 1.90 prevents excessive risk when k is small (e.g., k=1).\n                if (factor < 1.60) factor = 1.60;\n                if (factor > 1.90) factor = 1.90;\n\n                if (l < min_d * factor) {\n                    accept = true;\n                }\n            }\n\n            if (accept) {\n                cout << \"1\\n\";\n                dsu.unite(ru, rv);\n            } else {\n                cout << \"0\\n\";\n            }\n        }\n        // Interactive requirement: flush output immediately\n        cout.flush();\n    }\n\n    return 0;\n}","ahc008":"#pragma GCC optimize(\"O3,unroll-loops\")\n#include <iostream>\n#include <vector>\n#include <string>\n#include <cstring>\n#include <cmath>\n#include <algorithm>\n#include <random>\n\nusing namespace std;\n\nconst int H = 30, W = 30;\nint grid[H][W];\nstruct Pos { int x, y; };\nvector<Pos> humans;\nvector<pair<int, int>> pets;\n\ninline bool in_bounds(int x, int y) { return x >= 0 && x < H && y >= 0 && y < W; }\n\nint dist_to_pet[H][W];\nvoid compute_pet_distances(const int g[H][W]) {\n    static int q[900];\n    int head = 0, tail = 0;\n    memset(dist_to_pet, 0x3f, sizeof(dist_to_pet));\n    for (auto& p : pets) {\n        if (g[p.first][p.second] == 0) {\n            dist_to_pet[p.first][p.second] = 0;\n            q[tail++] = (p.first << 5) | p.second;\n        }\n    }\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    while(head < tail) {\n        int cur = q[head++];\n        int cx = cur >> 5, cy = cur & 31;\n        int d = dist_to_pet[cx][cy];\n        for(int i=0; i<4; i++) {\n            int nx = cx + dx[i], ny = cy + dy[i];\n            if(in_bounds(nx, ny) && g[nx][ny] == 0 && dist_to_pet[nx][ny] > d + 1) {\n                dist_to_pet[nx][ny] = d + 1;\n                q[tail++] = (nx << 5) | ny;\n            }\n        }\n    }\n}\n\npair<int, int> bfs(int sx, int sy, const int g[H][W], const int pet_grid[H][W]) {\n    static int vis[H][W] = {0};\n    static int token = 0;\n    token++;\n    if(token > 1000000000) { memset(vis, 0, sizeof(vis)); token = 1; }\n\n    static int q[900];\n    int head = 0, tail = 0;\n    q[tail++] = (sx << 5) | sy;\n    vis[sx][sy] = token;\n    \n    int sz = 0, np = 0;\n    if(pet_grid[sx][sy]) np++;\n\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    while(head < tail) {\n        int cur = q[head++];\n        int cx = cur >> 5, cy = cur & 31;\n        sz++;\n        for(int i=0; i<4; i++) {\n            int nx = cx + dx[i], ny = cy + dy[i];\n            if(in_bounds(nx, ny) && vis[nx][ny] != token && g[nx][ny] == 0) {\n                vis[nx][ny] = token;\n                if(pet_grid[nx][ny]) np++;\n                q[tail++] = (nx << 5) | ny;\n            }\n        }\n    }\n    return {sz, np};\n}\n\nbool can_block_target(int tx, int ty, const int pet_grid[H][W]) {\n    if(!in_bounds(tx, ty)) return false;\n    if(grid[tx][ty] == 1) return false; // Already blocked\n    if(pet_grid[tx][ty]) return false;\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    for(int i=0; i<4; i++) {\n        int nx = tx + dx[i], ny = ty + dy[i];\n        if(in_bounds(nx, ny) && pet_grid[nx][ny]) return false;\n    }\n    for(const auto& h : humans) if(h.x == tx && h.y == ty) return false;\n    return true;\n}\n\nmt19937 rng(1337);\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    int N; cin >> N;\n    pets.resize(N);\n    int pet_grid[H][W] = {};\n    for(int i=0; i<N; i++) {\n        int pt; cin >> pets[i].first >> pets[i].second >> pt;\n        pets[i].first--; pets[i].second--;\n        pet_grid[pets[i].first][pets[i].second] = 1;\n    }\n    int M; cin >> M;\n    humans.resize(M);\n    for(int i=0; i<M; i++) { cin >> humans[i].x >> humans[i].y; humans[i].x--; humans[i].y--; }\n\n    memset(grid, 0, sizeof(grid));\n    const char acts[] = {'.', 'U', 'D', 'L', 'R', 'u', 'd', 'l', 'r'};\n    const int ddx[9] = {0, -1, 1, 0, 0, -1, 1, 0, 0};\n    const int ddy[9] = {0, 0, 0, -1, 1, 0, 0, -1, 1};\n    const bool is_block[9] = {0,0,0,0,0,1,1,1,1};\n\n    for(int turn=0; turn<300; turn++) {\n        compute_pet_distances(grid);\n        vector<char> my_acts(M, '.');\n        vector<int> current_np(M);\n        \n        // Phase 1: Independent Evaluation\n        for(int i=0; i<M; i++) {\n            current_np[i] = bfs(humans[i].x, humans[i].y, grid, pet_grid).second;\n            double best_val = -1.0;\n            char best_a = '.';\n\n            for(int a=0; a<9; a++) {\n                if(a == 0) {}\n                else {\n                    int tx = humans[i].x + ddx[a], ty = humans[i].y + ddy[a];\n                    if(!in_bounds(tx, ty)) continue;\n                    if(is_block[a]) { if(!can_block_target(tx, ty, pet_grid)) continue; }\n                    else { if(grid[tx][ty] != 0) continue; }\n                }\n\n                int sim_grid[H][W]; memcpy(sim_grid, grid, sizeof(sim_grid));\n                int sh = humans[i].x, sy = humans[i].y;\n                if(a != 0) {\n                    if(is_block[a]) {\n                        int tx = humans[i].x + ddx[a], ty = humans[i].y + ddy[a];\n                        if(sim_grid[tx][ty] == 0) sim_grid[tx][ty] = 1;\n                    } else {\n                        sh += ddx[a]; sy += ddy[a];\n                    }\n                }\n\n                auto [new_sz, new_np] = bfs(sh, sy, sim_grid, pet_grid);\n                double val = new_sz / (double)(1LL << new_np);\n                if (new_np < current_np[i]) val += new_sz * 2.0 * (current_np[i] - new_np);\n                if (in_bounds(sh, sy)) val += dist_to_pet[sh][sy] * 0.5;\n                val += (rng() % 1000) * 0.001;\n\n                if(val > best_val) { best_val = val; best_a = acts[a]; }\n            }\n            my_acts[i] = best_a;\n        }\n\n        // Phase 2: Global Block Simulation & Move Validation\n        int sim_grid[H][W]; memcpy(sim_grid, grid, sizeof(sim_grid));\n        for(int i=0; i<M; i++) {\n            int a_idx = -1; for(int k=0;k<9;k++) if(acts[k]==my_acts[i]) a_idx=k;\n            if(a_idx != -1 && is_block[a_idx]) {\n                int tx = humans[i].x + ddx[a_idx], ty = humans[i].y + ddy[a_idx];\n                if(in_bounds(tx, ty)) sim_grid[tx][ty] = 1;\n            }\n        }\n        for(int i=0; i<M; i++) {\n            int a_idx = -1; for(int k=0;k<9;k++) if(acts[k]==my_acts[i]) a_idx=k;\n            if(a_idx != -1 && !is_block[a_idx] && my_acts[i] != '.') {\n                int nx = humans[i].x + ddx[a_idx], ny = humans[i].y + ddy[a_idx];\n                if(!in_bounds(nx, ny) || sim_grid[nx][ny] != 0) {\n                    my_acts[i] = '.'; // Demote to stay if blocked\n                }\n            }\n        }\n\n        string res = \"\"; for(char c:my_acts) res+=c;\n        cout << res << \"\\n\"; cout.flush();\n\n        for(int i=0; i<N; i++) {\n            string mv; cin >> mv;\n            int cx = pets[i].first, cy = pets[i].second;\n            for(char c:mv) {\n                int nx=cx, ny=cy;\n                if(c=='U') nx--; else if(c=='D') nx++; else if(c=='L') ny--; else if(c=='R') ny++;\n                if(in_bounds(nx,ny) && grid[nx][ny]==0) { cx=nx; cy=ny; } else break;\n            }\n            pets[i] = {cx, cy};\n        }\n\n        memset(pet_grid, 0, sizeof(pet_grid));\n        for(auto& p:pets) pet_grid[p.first][p.second]=1;\n\n        // Phase 3: State Synchronization (Blocks first, then moves)\n        for(int i=0; i<M; i++) {\n            int a_idx=-1; for(int k=0;k<9;k++) if(acts[k]==my_acts[i]) a_idx=k;\n            if(a_idx!=-1 && is_block[a_idx]) {\n                int tx=humans[i].x+ddx[a_idx], ty=humans[i].y+ddy[a_idx];\n                if(in_bounds(tx,ty) && grid[tx][ty]==0) grid[tx][ty]=1;\n            }\n        }\n        for(int i=0; i<M; i++) {\n            int a_idx=-1; for(int k=0;k<9;k++) if(acts[k]==my_acts[i]) a_idx=k;\n            if(a_idx!=-1 && !is_block[a_idx] && my_acts[i]!='.') {\n                int nx=humans[i].x+ddx[a_idx], ny=humans[i].y+ddy[a_idx];\n                if(in_bounds(nx,ny) && grid[nx][ny]==0) humans[i]={nx,ny};\n            }\n        }\n    }\n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cstring>\n#include <queue>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n\n#pragma GCC optimize(\"O3,unroll-loops\")\n#pragma GCC target(\"sse4.2\")\n\nusing namespace std;\n\n// Global arrays for cache locality\nalignas(64) int nxt[400][4];\nalignas(64) bool blocked[400][4];\nalignas(64) double dp[201][400];\nalignas(64) double head_score[201];\nalignas(64) double cur_dp[201][400];\nalignas(64) double W[201][400]; \nalignas(64) double P[400];      \nalignas(64) double P_next[400]; \n\n// BFS shortest path\nstring get_shortest_path(int sr, int sc, int tr, int tc, const vector<string>& h, const vector<string>& v) {\n    static int d[20][20], pi[20][20], pj[20][20], q[405];\n    memset(d, -1, sizeof(d));\n    int head = 0, tail = 0;\n    q[tail++] = sr * 20 + sc;\n    d[sr][sc] = 0;\n    int dr[] = {-1, 1, 0, 0};\n    int dc[] = {0, 0, -1, 1};\n    int target = tr * 20 + tc;\n    bool found = false;\n    while(head < tail) {\n        int u = q[head++];\n        int r = u / 20, c = u % 20;\n        if (u == target) { found = true; break; }\n        for (int k = 0; k < 4; ++k) {\n            int nr = r + dr[k], nc = c + dc[k];\n            if (nr < 0 || nr >= 20 || nc < 0 || nc >= 20) continue;\n            bool wall = false;\n            if (k == 0) wall = (v[r-1][c] == '1');\n            else if (k == 1) wall = (v[r][c] == '1');\n            else if (k == 2) wall = (h[r][c-1] == '1');\n            else if (k == 3) wall = (h[r][c] == '1');\n            if (!wall && d[nr][nc] == -1) {\n                d[nr][nc] = d[r][c] + 1;\n                pi[nr][nc] = r; pj[nr][nc] = c;\n                q[tail++] = nr * 20 + nc;\n            }\n        }\n    }\n    if (!found) return \"\";\n    string path = \"\";\n    int r = tr, c = tc;\n    while (r != sr || c != sc) {\n        int pr = pi[r][c], pc = pj[r][c];\n        if (pr == r) path += (pc < c ? 'R' : 'L');\n        else path += (pr < r ? 'D' : 'U');\n        r = pr; c = pc;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n// Full DP evaluation\ndouble evaluate_full(const string& s, int start_idx, int target_idx, double p, double move_prob) {\n    memset(dp, 0, sizeof(dp)); \n    dp[0][start_idx] = 1.0;\n    double acc = 0.0;\n    head_score[0] = 0.0;\n    for (int t = 0; t < 200; ++t) {\n        int d_char = (s[t] == 'U' ? 0 : s[t] == 'D' ? 1 : s[t] == 'L' ? 2 : 3);\n        double* dp_t = dp[t];\n        double* dp_tp1 = dp[t+1];\n        double prev_target = dp_t[target_idx];\n        for (int idx = 0; idx < 400; ++idx) {\n            double prob = dp_t[idx];\n            if (prob < 1e-12) continue;\n            if (idx == target_idx) dp_tp1[target_idx] += prob;\n            else {\n                dp_tp1[idx] += prob * p;\n                if (blocked[idx][d_char]) dp_tp1[idx] += prob * move_prob;\n                else dp_tp1[nxt[idx][d_char]] += prob * move_prob;\n            }\n        }\n        double reach = dp_tp1[target_idx] - prev_target;\n        acc += (400.0 - t) * reach;\n        head_score[t+1] = acc;\n    }\n    return acc;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int s_i, s_j, t_i, t_j;\n    double p;\n    if (!(cin >> s_i >> s_j >> t_i >> t_j >> p)) return 0;\n\n    vector<string> h(20), v(19);\n    for (int i = 0; i < 20; ++i) cin >> h[i];\n    for (int i = 0; i < 19; ++i) cin >> v[i];\n\n    int start_idx = s_i * 20 + s_j;\n    int target_idx = t_i * 20 + t_j;\n    double move_prob = 1.0 - p;\n\n    // Precompute transitions\n    for (int r = 0; r < 20; ++r) {\n        for (int c = 0; c < 20; ++c) {\n            int idx = r * 20 + c;\n            // U: 0\n            if (r > 0 && v[r-1][c] == '0') { nxt[idx][0] = (r-1)*20+c; blocked[idx][0] = false; }\n            else { nxt[idx][0] = idx; blocked[idx][0] = true; }\n            // D: 1\n            if (r < 19 && v[r][c] == '0') { nxt[idx][1] = (r+1)*20+c; blocked[idx][1] = false; }\n            else { nxt[idx][1] = idx; blocked[idx][1] = true; }\n            // L: 2\n            if (c > 0 && h[r][c-1] == '0') { nxt[idx][2] = r*20+(c-1); blocked[idx][2] = false; }\n            else { nxt[idx][2] = idx; blocked[idx][2] = true; }\n            // R: 3\n            if (c < 19 && h[r][c] == '0') { nxt[idx][3] = r*20+(c+1); blocked[idx][3] = false; }\n            else { nxt[idx][3] = idx; blocked[idx][3] = true; }\n        }\n    }\n\n    // Initial solution\n    string path = get_shortest_path(s_i, s_j, t_i, t_j, h, v);\n    string s = \"\";\n    s.reserve(200);\n    int plen = path.empty() ? 1 : path.size();\n    for (int i = 0; i < 200; ++i) s += path[i % plen];\n\n    double best_score = evaluate_full(s, start_idx, target_idx, p, move_prob);\n    double cur_score = best_score;\n    string best_s = s;\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist_pos(0, 199);\n    uniform_int_distribution<int> dist_char(0, 3);\n    uniform_int_distribution<int> dist_len(1, 5);\n    uniform_real_distribution<double> dist_uni(0.0, 1.0);\n    char dirs[] = {'U', 'D', 'L', 'R'};\n\n    // Temperature calibration\n    double sum_abs_delta = 0;\n    string tmp_s = s;\n    for(int k=0; k<200; ++k) {\n        int pos = dist_pos(rng);\n        char old = tmp_s[pos];\n        tmp_s[pos] = dirs[dist_char(rng)];\n        double sc = evaluate_full(tmp_s, start_idx, target_idx, p, move_prob);\n        sum_abs_delta += abs(sc - best_score);\n        tmp_s[pos] = old;\n    }\n    evaluate_full(s, start_idx, target_idx, p, move_prob); // Restore state\n    double T_start = max(5000.0, (sum_abs_delta / 200.0) * 15.0);\n    double T = T_start;\n\n    auto start_time = chrono::steady_clock::now();\n    int iter = 0;\n    int improve_iter = 0;\n    const double TIME_LIMIT_SA = 1.3;\n    const double TIME_LIMIT_TOTAL = 1.95;\n\n    // SA Loop\n    while (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() < TIME_LIMIT_SA) {\n        double progress = chrono::duration<double>(chrono::steady_clock::now() - start_time).count() / TIME_LIMIT_SA;\n        T = T_start * pow(1.0 - progress, 2.0); // Slower cooling\n        if (T < 2.0) T = 2.0;\n\n        // Stagnation check\n        if (iter - improve_iter > 20000) {\n            s = best_s;\n            // Random perturb\n            int num_mutations = 20 + dist_len(rng) * 5;\n            for(int k=0; k<num_mutations; ++k) {\n                s[dist_pos(rng)] = dirs[dist_char(rng)];\n            }\n            cur_score = evaluate_full(s, start_idx, target_idx, p, move_prob);\n            T = T_start * 0.6;\n            improve_iter = iter;\n        }\n\n        // Path Repair heuristic (every 5000 iterations)\n        bool repair = (iter % 5000 == 0 && iter > 0);\n        if (repair) {\n            int t_rep = dist_pos(rng);\n            int best_u = -1; \n            double max_p = -1;\n            // Find mode\n            for(int u=0; u<400; ++u) {\n                if (dp[t_rep][u] > max_p) { \n                    max_p = dp[t_rep][u]; \n                    best_u = u; \n                }\n            }\n            if (max_p > 1e-8 && best_u != -1) {\n                int r = best_u / 20;\n                int c = best_u % 20;\n                string patch = get_shortest_path(r, c, t_i, t_j, h, v);\n                if (!patch.empty()) {\n                    string old_s = s;\n                    int limit = min((int)patch.size(), 200 - t_rep);\n                    for (int i = 0; i < limit; ++i) s[t_rep+i] = patch[i];\n                    double new_sc = evaluate_full(s, start_idx, target_idx, p, move_prob);\n                    if (new_sc > cur_score) {\n                        cur_score = new_sc;\n                        if (new_sc > best_score) { best_score = new_sc; best_s = s; improve_iter = iter; }\n                    } else {\n                        s = old_s;\n                    }\n                    iter++;\n                    continue;\n                }\n            }\n        }\n\n        // Standard SA Mutation\n        int pos = dist_pos(rng);\n        int len = 1;\n        if (dist_uni(rng) < 0.3) len = dist_len(rng);\n        int limit = pos + len;\n        if (limit > 200) limit = 200;\n        \n        char old_block[10];\n        int save_len = limit - pos;\n        for(int i=0; i<save_len; ++i) old_block[i] = s[pos+i];\n        \n        for (int i = pos; i < limit; ++i) s[i] = dirs[dist_char(rng)];\n\n        // Incremental DP\n        memcpy(&cur_dp[pos][0], &dp[pos][0], sizeof(double)*400);\n        memset(&cur_dp[pos+1][0], 0, sizeof(double)*400*(200-pos));\n        \n        double tail_acc = 0;\n        for (int t = pos; t < 200; ++t) {\n            int d_char = (s[t] == 'U' ? 0 : s[t] == 'D' ? 1 : s[t] == 'L' ? 2 : 3);\n            double pt = cur_dp[t][target_idx];\n            for (int idx = 0; idx < 400; ++idx) {\n                double prob = cur_dp[t][idx];\n                if (prob < 1e-12) continue;\n                if (idx == target_idx) cur_dp[t+1][target_idx] += prob;\n                else {\n                    cur_dp[t+1][idx] += prob * p;\n                    if (blocked[idx][d_char]) cur_dp[t+1][idx] += prob * move_prob;\n                    else cur_dp[t+1][nxt[idx][d_char]] += prob * move_prob;\n                }\n            }\n            tail_acc += (400.0 - t) * (cur_dp[t+1][target_idx] - pt);\n        }\n        double total_new = head_score[pos] + tail_acc;\n        double delta = total_new - cur_score;\n\n        if (delta > 0 || dist_uni(rng) < exp(delta / T)) {\n            cur_score = total_new;\n            memcpy(&dp[pos+1][0], &cur_dp[pos+1][0], sizeof(double)*400*(200-pos));\n            double running = head_score[pos];\n            for (int t = pos; t < 200; ++t) {\n                double reach = dp[t+1][target_idx] - dp[t][target_idx];\n                running += (400.0 - t) * reach;\n                head_score[t+1] = running;\n            }\n            if (total_new > best_score) {\n                best_score = total_new;\n                best_s = s;\n                improve_iter = iter;\n            }\n        } else {\n            for(int i=0; i<save_len; ++i) s[pos+i] = old_block[i];\n        }\n        iter++;\n    }\n\n    // Greedy Improvement Phase\n    s = best_s;\n    cur_score = evaluate_full(s, start_idx, target_idx, p, move_prob);\n    best_score = cur_score; \n    \n    while (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() < TIME_LIMIT_TOTAL) {\n        // 1. Backward DP for W\n        // W[k][u] is expected future score from time k (state u) following s[k...]\n        memset(W, 0, sizeof(W)); \n        \n        for (int k = 199; k >= 0; --k) {\n            int d_char = (s[k] == 'U' ? 0 : s[k] == 'D' ? 1 : s[k] == 'L' ? 2 : 3);\n            double* W_k = W[k];\n            double* W_kp1 = W[k+1];\n            \n            for (int u = 0; u < 400; ++u) {\n                if (u == target_idx) {\n                    W_k[u] = 0; \n                    continue;\n                }\n                // Stay (prob p) -> state u at k+1\n                double val = p * W_kp1[u];\n                \n                // Move (prob 1-p)\n                int v = nxt[u][d_char];\n                if (blocked[u][d_char]) v = u;\n                \n                double move_val = (1.0 - p) * W_kp1[v];\n                if (v == target_idx && u != target_idx) { \n                    move_val += (1.0 - p) * (400.0 - k);\n                }\n                W_k[u] = val + move_val;\n            }\n        }\n\n        // 2. Sweep\n        memset(P, 0, sizeof(P));\n        P[start_idx] = 1.0;\n        \n        bool changed = false;\n        for (int t = 0; t < 200; ++t) {\n            // Compute contribution for each direction\n            double dir_val[4] = {0, 0, 0, 0};\n            double move_prob_term = 1.0 - p;\n            double* W_next = W[t+1];\n            double bonus = 400.0 - t;\n            \n            // Unrolled loop for 400 states\n            for (int u = 0; u < 400; ++u) {\n                double prob = P[u];\n                if (prob < 1e-15 || u == target_idx) continue;\n                \n                double weight = prob * move_prob_term;\n                \n                // Direction 0: U\n                int v0 = nxt[u][0];\n                double val0 = W_next[v0];\n                if (v0 == target_idx) val0 += bonus;\n                dir_val[0] += weight * val0;\n                \n                // Direction 1: D\n                int v1 = nxt[u][1];\n                double val1 = W_next[v1];\n                if (v1 == target_idx) val1 += bonus;\n                dir_val[1] += weight * val1;\n                \n                // Direction 2: L\n                int v2 = nxt[u][2];\n                double val2 = W_next[v2];\n                if (v2 == target_idx) val2 += bonus;\n                dir_val[2] += weight * val2;\n                \n                // Direction 3: R\n                int v3 = nxt[u][3];\n                double val3 = W_next[v3];\n                if (v3 == target_idx) val3 += bonus;\n                dir_val[3] += weight * val3;\n            }\n            \n            // Find max\n            int best_dir = 0;\n            double max_val = dir_val[0];\n            if(dir_val[1] > max_val) { max_val = dir_val[1]; best_dir = 1; }\n            if(dir_val[2] > max_val) { max_val = dir_val[2]; best_dir = 2; }\n            if(dir_val[3] > max_val) { max_val = dir_val[3]; best_dir = 3; }\n            \n            // Update string\n            char new_c = dirs[best_dir];\n            if (new_c != s[t]) {\n                s[t] = new_c;\n                changed = true;\n            }\n            \n            // Update P for next step\n            int d_char = (s[t] == 'U' ? 0 : s[t] == 'D' ? 1 : s[t] == 'L' ? 2 : 3);\n            memset(P_next, 0, sizeof(P_next));\n            for (int u = 0; u < 400; ++u) {\n                double prob = P[u];\n                if (prob < 1e-15) continue;\n                if (u == target_idx) {\n                    P_next[target_idx] += prob;\n                } else {\n                    P_next[u] += prob * p;\n                    if (blocked[u][d_char]) P_next[u] += prob * move_prob_term;\n                    else P_next[nxt[u][d_char]] += prob * move_prob_term;\n                }\n            }\n            memcpy(P, P_next, sizeof(P));\n        }\n        \n        if (!changed) break; // Converged\n    }\n    \n    // Final evaluation\n    double final_score = evaluate_full(s, start_idx, target_idx, p, move_prob);\n    if (final_score > best_score) {\n        best_score = final_score;\n        best_s = s;\n    }\n\n    cout << best_s << \"\\n\";\n    return 0;\n}","ahc010":"/*\n    Solution for AHC010\n    Optimized Heuristic-Guided Simulated Annealing with Periodic Score Checks\n    - Uses local connectivity heuristic for fast move evaluation.\n    - Periodically computes full score to track global optimum.\n    - Incremental updates for nxt table and heuristic values.\n    - Fast RNG and cache-friendly data structures.\n*/\n#pragma GCC optimize(\"O3,unroll-loops,fast-math\")\n#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <cstring>\n#include <cstdint>\n\nusing namespace std;\n\nconst int H = 30, W = 30, N = H * W, S = N * 4;\n\n// Directions: 0:L, 1:U, 2:R, 3:D\nconst int di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n\n// to_table[type][enter_dir] -> exit_dir. 255 means invalid.\nalignas(64) const uint8_t to_table[8][4] = {\n    {1, 0, 255, 255}, {3, 255, 255, 0}, {255, 255, 3, 2}, {255, 2, 1, 255},\n    {1, 0, 3, 2}, {3, 2, 1, 0}, {2, 255, 0, 255}, {255, 3, 255, 1}\n};\n\n// Paths for each type: pairs of directions {d1, d2}\nalignas(64) const uint8_t type_paths[8][2][2] = {\n    {{0, 1}, {255, 255}}, {{0, 3}, {255, 255}}, {{2, 3}, {255, 255}}, {{2, 1}, {255, 255}},\n    {{0, 1}, {2, 3}}, {{0, 3}, {1, 2}}, {{0, 2}, {255, 255}}, {{1, 3}, {255, 255}}\n};\n\nuint8_t grid[N];\nuint8_t initial_grid[N];\nuint8_t best_grid[N];\nlong long best_score = 0;\n\nint adj[N][4];\nuint8_t vm[N][4];\nuint8_t vm_cnt[N];\n\n// Direct transition table: nxt[state] -> next_state or S\nalignas(64) uint32_t nxt[S];\nalignas(64) uint16_t vis[S] = {0};\nalignas(64) uint16_t trace[S];\nalignas(64) uint16_t step[S];\nuint32_t gen = 0;\n\nint tile_heuristic[N];\n\n// Update nxt entries for a single tile\ninline void update_nxt(int idx) {\n    int base = idx << 2;\n    for (int d = 0; d < 4; ++d) {\n        int s = base + d;\n        int exit_d = to_table[grid[idx]][d];\n        if (exit_d == 255) { nxt[s] = S; continue; }\n        int ni = adj[idx][exit_d];\n        nxt[s] = (ni == -1) ? S : ((ni << 2) | (exit_d ^ 2));\n    }\n}\n\n// Calculate Heuristic for a tile\ninline int calc_tile_heuristic(int idx) {\n    int score = 0;\n    int t = grid[idx];\n    const auto& paths = type_paths[t];\n    \n    // Path 1\n    int d1_1 = paths[0][0];\n    int d1_2 = paths[0][1];\n    int n1 = adj[idx][d1_1];\n    if (n1 != -1 && to_table[grid[n1]][d1_1^2] != 255) score++;\n    int n2 = adj[idx][d1_2];\n    if (n2 != -1 && to_table[grid[n2]][d1_2^2] != 255) score++;\n    \n    // Path 2\n    int d2_1 = paths[1][0];\n    if (d2_1 != 255) {\n        int d2_2 = paths[1][1];\n        int n3 = adj[idx][d2_1];\n        if (n3 != -1 && to_table[grid[n3]][d2_1^2] != 255) score++;\n        int n4 = adj[idx][d2_2];\n        if (n4 != -1 && to_table[grid[n4]][d2_2^2] != 255) score++;\n    }\n    return score;\n}\n\n// Full score calculation\nlong long calc_score() {\n    if (++gen == 0) {\n        memset(vis, 0, sizeof(vis));\n        gen = 1;\n    }\n    uint16_t tid = 0;\n    long long m1 = 0, m2 = 0;\n    for (int s = 0; s < S; ++s) {\n        if (vis[s] == gen) continue;\n        tid++;\n        int cur = s;\n        int st = 0;\n        while (true) {\n            vis[cur] = gen;\n            trace[cur] = tid;\n            step[cur] = st++;\n            cur = nxt[cur];\n            if (cur == S) break;\n            if (vis[cur] == gen) {\n                if (trace[cur] == tid) {\n                    long long cyc = st - step[cur];\n                    if (cyc > m1) { m2 = m1; m1 = cyc; }\n                    else if (cyc > m2) m2 = cyc;\n                }\n                break;\n            }\n        }\n    }\n    return m1 * m2;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    char c;\n    for (int i = 0; i < H; ++i) {\n        for (int j = 0; j < W; ++j) {\n            cin >> c;\n            int idx = i * W + j;\n            initial_grid[idx] = c - '0';\n            grid[idx] = initial_grid[idx];\n            \n            for (int d = 0; d < 4; ++d) {\n                int ni = i + di[d], nj = j + dj[d];\n                adj[idx][d] = (ni >= 0 && ni < H && nj >= 0 && nj < W) ? (ni * W + nj) : -1;\n            }\n            \n            int t = initial_grid[idx];\n            vm_cnt[idx] = 0;\n            if (t <= 3) {\n                for (int m = 0; m < 4; ++m) vm[idx][vm_cnt[idx]++] = m;\n            } else if (t <= 5) {\n                vm[idx][0] = 4; vm[idx][1] = 5; vm_cnt[idx] = 2;\n            } else {\n                vm[idx][0] = 6; vm[idx][1] = 7; vm_cnt[idx] = 2;\n            }\n        }\n    }\n\n    // Initial setup\n    for (int idx = 0; idx < N; ++idx) update_nxt(idx);\n    for (int idx = 0; idx < N; ++idx) tile_heuristic[idx] = calc_tile_heuristic(idx);\n    \n    best_score = calc_score();\n    memcpy(best_grid, grid, sizeof(grid));\n\n    // Fast RNG\n    uint64_t rng_state = chrono::steady_clock::now().time_since_epoch().count();\n    auto rng = [&]() {\n        rng_state ^= rng_state >> 12;\n        rng_state ^= rng_state << 25;\n        rng_state ^= rng_state >> 27;\n        return rng_state * 2685821657736338717ULL;\n    };\n\n    auto start = chrono::high_resolution_clock::now();\n    const double time_limit = 1.95;\n    const int CHECK_INTERVAL = 100; \n    int check_counter = 0;\n\n    int neighbors[4];\n    int new_h_neighbors[4];\n\n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > time_limit) break;\n\n        double progress = elapsed / time_limit;\n        double T = 1.5 * (1.0 - progress);\n        if (T < 0.001) T = 0.001;\n\n        int idx = (int)(rng() % N);\n        int cnt = vm_cnt[idx];\n        int new_type = vm[idx][rng() % cnt];\n        int old_type = grid[idx];\n        \n        if (new_type == old_type) continue;\n\n        // Identify neighbors and sum old H\n        int n_count = 0;\n        long long sum_old_H = tile_heuristic[idx];\n        for(int d=0; d<4; ++d) {\n            int n = adj[idx][d];\n            if(n != -1) {\n                neighbors[n_count] = n;\n                sum_old_H += tile_heuristic[n];\n                n_count++;\n            }\n        }\n\n        // Apply move\n        grid[idx] = new_type;\n        update_nxt(idx);\n\n        // Compute new Heuristic\n        int new_h_idx = calc_tile_heuristic(idx);\n        long long sum_new_H = new_h_idx;\n        for(int k=0; k<n_count; ++k) {\n            new_h_neighbors[k] = calc_tile_heuristic(neighbors[k]);\n            sum_new_H += new_h_neighbors[k];\n        }\n\n        long long delta_H = sum_new_H - sum_old_H;\n\n        // SA Acceptance on H\n        bool accept = false;\n        if (delta_H >= 0) accept = true;\n        else {\n            double prob = exp((double)delta_H / T);\n            double r = (double)(rng() >> 11) * (1.0 / (1ULL << 53));\n            if (r < prob) accept = true;\n        }\n\n        if (accept) {\n            // Update H array\n            tile_heuristic[idx] = new_h_idx;\n            for(int k=0; k<n_count; ++k) {\n                tile_heuristic[neighbors[k]] = new_h_neighbors[k];\n            }\n        } else {\n            // Revert grid and nxt\n            grid[idx] = old_type;\n            update_nxt(idx);\n        }\n\n        check_counter++;\n        if (check_counter >= CHECK_INTERVAL) {\n            check_counter = 0;\n            long long s = calc_score();\n            if (s > best_score) {\n                best_score = s;\n                memcpy(best_grid, grid, sizeof(grid));\n            }\n        }\n    }\n\n    // Final check\n    long long s = calc_score();\n    if (s > best_score) {\n        best_score = s;\n        memcpy(best_grid, grid, sizeof(grid));\n    }\n\n    string res; res.reserve(N);\n    for (int i = 0; i < N; ++i) {\n        int r = 0;\n        int init = initial_grid[i], cur = best_grid[i];\n        if (init <= 3) r = (cur - init + 4) % 4;\n        else r = (cur != init);\n        res.push_back('0' + r);\n    }\n    cout << res << \"\\n\";\n    return 0;\n}","ahc011":"/*\n    AHC011 Solution\n    Strategy:\n    1. Find a target layout (tree) with correct parity and minimal Manhattan distance.\n       Uses time-bounded DFS with pruning, cycle detection, and candidate sorting.\n    2. Solve the sliding puzzle by moving tiles to their target positions in raster order.\n       Uses BFS to navigate the empty space to the exact \"push\" position.\n       Correctly maps tile movement directions to operation characters.\n*/\n#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <queue>\n#include <numeric>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\n#pragma GCC optimize(\"O3\")\n\nint N;\nlong long T;\nvector<int> tile_masks;\nvector<int> init_pos_r, init_pos_c;\nint initial_parity;\n\nvector<int> best_layout;\nlong long best_layout_cost = 1e18;\nbool found_any = false;\n\nauto start_time = chrono::steady_clock::now();\nconst int LAYOUT_TIME_MS = 2000;\n\nstruct UF {\n    vector<int> p;\n    UF(int n) : p(n, -1) {}\n    int find(int x) { return p[x] == -1 ? x : p[x] = find(p[x]); }\n    bool unite(int x, int y) {\n        x = find(x); y = find(y);\n        if (x != y) { p[y] = x; return true; }\n        return false;\n    }\n    bool same(int x, int y) { return find(x) == find(y); }\n    UF clone() const { UF r(0); r.p = p; return r; }\n};\n\nint calc_parity(const vector<int>& b, int empty_pos) {\n    vector<int> seq; seq.reserve(b.size());\n    for (int x : b) if (x != -1) seq.push_back(x);\n    int inv = 0;\n    for (size_t i = 0; i < seq.size(); ++i)\n        for (size_t j = i + 1; j < seq.size(); ++j)\n            if (seq[i] > seq[j]) inv++;\n    int empty_r = empty_pos / N;\n    if (N % 2 == 1) return inv % 2;\n    return (inv + (N - 1 - empty_r)) % 2;\n}\n\nvoid dfs(int pos, vector<int>& b, vector<bool>& used, UF uf, long long current_cost) {\n    if (found_any && current_cost >= best_layout_cost) return;\n    if (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() > LAYOUT_TIME_MS) return;\n\n    if (pos == N * N) {\n        int root = -1;\n        bool connected = true;\n        for (int i = 0; i < N * N; ++i) {\n            if (b[i] != -1) {\n                if (root == -1) root = uf.find(i);\n                else if (uf.find(i) != root) { connected = false; break; }\n            }\n        }\n        if (!connected) return;\n        if (calc_parity(b, N*N-1) != initial_parity) return;\n        \n        best_layout = b;\n        best_layout_cost = current_cost;\n        found_any = true;\n        return;\n    }\n\n    if (pos == N*N-1) {\n        b[pos] = -1;\n        dfs(pos+1, b, used, uf, current_cost);\n        b[pos] = -2;\n        return;\n    }\n\n    int r = pos / N, c = pos % N;\n    vector<pair<long long, int>> candidates;\n    for (int t = 0; t < N*N-1; ++t) {\n        if (used[t]) continue;\n        long long cost = abs(init_pos_r[t] - r) + abs(init_pos_c[t] - c);\n        candidates.emplace_back(cost, t);\n    }\n    sort(candidates.begin(), candidates.end());\n\n    for (auto [cost, t] : candidates) {\n        int m = tile_masks[t];\n        bool conn_up = false, conn_left = false;\n        if (r > 0 && b[pos-N] != -1) {\n            bool up_has_d = (tile_masks[b[pos-N]] & 8);\n            bool curr_has_u = (m & 2);\n            if (up_has_d && curr_has_u) conn_up = true;\n        }\n        if (c > 0 && b[pos-1] != -1) {\n            bool left_has_r = (tile_masks[b[pos-1]] & 4);\n            bool curr_has_l = (m & 1);\n            if (left_has_r && curr_has_l) conn_left = true;\n        }\n\n        UF next_uf = uf.clone();\n        bool cycle = false;\n        if (conn_up) {\n            if (next_uf.same(pos, pos-N)) cycle = true;\n            else next_uf.unite(pos, pos-N);\n        }\n        if (!cycle && conn_left) {\n            if (next_uf.same(pos, pos-1)) cycle = true;\n            else next_uf.unite(pos, pos-1);\n        }\n        if (cycle) continue;\n\n        b[pos] = t;\n        used[t] = true;\n        dfs(pos+1, b, used, next_uf, current_cost + cost);\n        if (found_any && best_layout_cost == 0) return;\n        used[t] = false;\n        b[pos] = -2;\n    }\n}\n\nstring bfs_empty(int start, int target, const vector<int>& board, const vector<bool>& locked) {\n    if (start == target) return \"\";\n    queue<int> q; q.push(start);\n    vector<int> par(N*N, -1);\n    vector<char> mv(N*N, 0);\n    par[start] = start;\n    \n    int dr[] = {-1, 1, 0, 0};\n    int dc[] = {0, 0, -1, 1};\n    char ops[] = {'U', 'D', 'L', 'R'};\n    \n    while(!q.empty()) {\n        int u = q.front(); q.pop();\n        if(u == target) break;\n        int r = u/N, c = u%N;\n        for(int i=0; i<4; ++i) {\n            int nr = r+dr[i], nc = c+dc[i];\n            if(nr<0||nr>=N||nc<0||nc>=N) continue;\n            int v = nr*N+nc;\n            if(par[v]!=-1 || locked[v]) continue;\n            par[v] = u;\n            mv[v] = ops[i];\n            q.push(v);\n        }\n    }\n    if(par[target] == -1) return \"\";\n    string path;\n    int cur = target;\n    while(cur != start) {\n        path += mv[cur];\n        cur = par[cur];\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nvoid apply(char op, vector<int>& board, int& empty, vector<int>& tile_pos) {\n    int r = empty/N, c_idx = empty%N;\n    int nr=r, nc=c_idx;\n    if(op=='U') nr--;      \n    else if(op=='D') nr++; \n    else if(op=='L') nc--; \n    else if(op=='R') nc++; \n    \n    int nxt = nr*N+nc;\n    int t = board[nxt];\n    board[empty] = t;\n    board[nxt] = -1;\n    tile_pos[t] = empty;\n    empty = nxt;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    if(!(cin >> N >> T)) return 0;\n    \n    vector<string> grid(N);\n    tile_masks.reserve(N*N-1);\n    init_pos_r.resize(N*N-1);\n    init_pos_c.resize(N*N-1);\n    vector<int> init_board(N*N);\n    int tile_cnt = 0, empty_pos = -1;\n    \n    for(int i=0; i<N; ++i) {\n        cin >> grid[i];\n        for(int j=0; j<N; ++j) {\n            char ch = grid[i][j];\n            int pos = i*N+j;\n            if(ch=='0') {\n                init_board[pos] = -1;\n                empty_pos = pos;\n            } else {\n                int val = (ch>='0'&&ch<='9') ? ch-'0' : ch-'a'+10;\n                tile_masks.push_back(val);\n                init_board[pos] = tile_cnt;\n                init_pos_r[tile_cnt] = i;\n                init_pos_c[tile_cnt] = j;\n                tile_cnt++;\n            }\n        }\n    }\n    \n    initial_parity = calc_parity(init_board, empty_pos);\n    \n    vector<int> board(N*N, -2);\n    vector<bool> used(N*N-1, false);\n    start_time = chrono::steady_clock::now();\n    \n    dfs(0, board, used, UF(N*N), 0);\n    \n    if(!found_any) {\n        best_layout.assign(N*N, -2);\n        for(int i=0; i<N*N-1; ++i) best_layout[i] = i;\n        best_layout[N*N-1] = -1;\n    }\n    \n    vector<int> cur_board = init_board;\n    int cur_empty = empty_pos;\n    vector<int> tile_pos(N*N-1);\n    for(int i=0; i<N*N; ++i) if(cur_board[i] != -1) tile_pos[cur_board[i]] = i;\n    \n    string moves;\n    vector<bool> locked(N*N, false);\n    \n    for(int P=0; P<N*N-1; ++P) {\n        if(moves.size() >= T) break;\n        int tid = best_layout[P];\n        if(tid == -1) continue;\n        if(cur_board[P] == tid) { locked[P] = true; continue; }\n        \n        int t_pos = tile_pos[tid];\n        int tr = t_pos/N, tc = t_pos%N;\n        int pr = P/N, pc = P%N;\n        \n        // Move horizontally first\n        while(tc != pc && moves.size() < T) {\n            int dir_c = (tc < pc) ? 1 : -1;\n            int er = tr, ec = tc + dir_c;\n            int target_empty = er*N+ec;\n            if(er<0||er>=N||ec<0||ec>=N || locked[target_empty]) break;\n            \n            if(cur_empty != target_empty) {\n                string path = bfs_empty(cur_empty, target_empty, cur_board, locked);\n                if(path.empty()) break;\n                for(char c : path) {\n                    if(moves.size()>=T) break;\n                    apply(c, cur_board, cur_empty, tile_pos); moves+=c;\n                }\n            }\n            if(cur_empty != target_empty) break;\n\n            // Correct mapping:\n            // dir_c = 1 (move tile Right) -> Empty is Right -> Slide Left Tile -> 'L'\n            // dir_c = -1 (move tile Left) -> Empty is Left -> Slide Right Tile -> 'R'\n            char op = (dir_c == 1) ? 'L' : 'R'; \n            \n            if(moves.size()<T) {\n                apply(op, cur_board, cur_empty, tile_pos); moves+=op;\n            }\n            tc += dir_c;\n            t_pos = tile_pos[tid]; tr=t_pos/N; tc=t_pos%N;\n        }\n        \n        // Move vertically\n        while(tr != pr && moves.size() < T) {\n            int dir_r = (tr > pr) ? -1 : 1;\n            int er = tr + dir_r, ec = tc;\n            int target_empty = er*N+ec;\n            if(er<0||er>=N||ec<0||ec>=N || locked[target_empty]) break;\n            \n            if(cur_empty != target_empty) {\n                string path = bfs_empty(cur_empty, target_empty, cur_board, locked);\n                if(path.empty()) break;\n                for(char c : path) {\n                    if(moves.size()>=T) break;\n                    apply(c, cur_board, cur_empty, tile_pos); moves+=c;\n                }\n            }\n            if(cur_empty != target_empty) break;\n\n            // Correct mapping:\n            // dir_r = -1 (move tile Up) -> Empty is Above -> Slide Down Tile -> 'D'\n            // dir_r = 1 (move tile Down) -> Empty is Below -> Slide Up Tile -> 'U'\n            char op = (dir_r == 1) ? 'U' : 'D'; \n            \n            if(moves.size()<T) {\n                apply(op, cur_board, cur_empty, tile_pos); moves+=op;\n            }\n            tr += dir_r;\n            t_pos = tile_pos[tid]; tr=t_pos/N; tc=t_pos%N;\n        }\n        \n        if(cur_board[P] == tid) locked[P] = true;\n    }\n    \n    if(moves.size() > T) moves.resize(T);\n    cout << moves << \"\\n\";\n    return 0;\n}","ahc012":"/*\n    Solution for AtCoder Heuristic Contest 012\n    Strategy: Greedy Randomized Local Search.\n    We maintain the current partition of strawberries (regions).\n    In each step, we try to find a random line that maximizes the score improvement.\n    A line splits regions into two parts. We only accept the line if it increases the score.\n    We track the number of pieces of each size (up to 10) to compute the score efficiently.\n    Lines that pass exactly through a strawberry are avoided.\n*/\n#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <tuple>\n#include <numeric>\n\nusing namespace std;\n\ntypedef long long ll;\n\nstruct Point {\n    ll x, y;\n};\n\nstruct Region {\n    vector<int> pts; // Indices of strawberries in this region\n};\n\nint main() {\n    // Fast IO\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N, K;\n    if (!(cin >> N >> K)) return 0;\n\n    vector<int> a(11);\n    for (int i = 1; i <= 10; ++i) cin >> a[i];\n\n    vector<Point> pts(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> pts[i].x >> pts[i].y;\n    }\n\n    // Initial state: One region containing all strawberries\n    vector<Region> regions;\n    regions.reserve(K + 2);\n    Region start_reg;\n    start_reg.pts.reserve(N);\n    for (int i = 0; i < N; ++i) start_reg.pts.push_back(i);\n    regions.push_back(move(start_reg));\n\n    // b[d] stores count of pieces with exactly d strawberries (for d <= 10)\n    // We only track sizes <= 10 because demands a_d are only up to 10.\n    // Pieces with size > 10 contribute 0 to the score.\n    vector<int> b(11, 0);\n    if (N <= 10) b[N] = 1;\n\n    auto calc_score = [&](const vector<int>& counts) {\n        ll sc = 0;\n        for (int d = 1; d <= 10; ++d) {\n            sc += min((ll)a[d], (ll)counts[d]);\n        }\n        return sc;\n    };\n\n    ll current_score = calc_score(b);\n    vector<tuple<ll, ll, ll, ll>> final_lines;\n    final_lines.reserve(K);\n\n    mt19937_64 rng(12345); // Fixed seed for reproducibility, or random\n    // Range for line coordinates. Strawberries are in [-10000, 10000].\n    // We generate lines passing through points in a slightly larger box.\n    uniform_int_distribution<ll> dist(-25000, 25000);\n\n    auto start_time = chrono::steady_clock::now();\n    \n    // Parameters for search\n    // Higher TRIES_PER_STEP gives better lines but takes more time.\n    // 300 seems a good balance for N=5000, K=100 within 3s.\n    const int TRIES_PER_STEP = 300; \n\n    for (int step = 0; step < K; ++step) {\n        // Time check to ensure we finish within limit\n        auto now = chrono::steady_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 2800) break;\n\n        ll best_line_x1 = 0, best_line_y1 = 0, best_line_x2 = 0, best_line_y2 = 0;\n        ll best_score = current_score;\n        bool found_better = false;\n\n        for (int t = 0; t < TRIES_PER_STEP; ++t) {\n            // Generate random line defined by two points\n            ll x1 = dist(rng);\n            ll y1 = dist(rng);\n            ll x2 = dist(rng);\n            ll y2 = dist(rng);\n            \n            // Ensure distinct points\n            if (x1 == x2 && y1 == y2) continue;\n\n            // Precompute line coefficients for Ax + By + C = 0\n            // A = y1 - y2, B = x2 - x1, C = -A*x1 - B*y1\n            ll A = y1 - y2;\n            ll B = x2 - x1;\n            ll C = -A * x1 - B * y1;\n\n            // Check validity and calculate potential score\n            // We work on a copy of b to simulate the change\n            vector<int> temp_b = b;\n            bool possible = true;\n            \n            // Iterate over all current regions to see how they are split\n            for (const auto& reg : regions) {\n                int sz = (int)reg.pts.size();\n                if (sz <= 1) {\n                    // If size is 1, the line must not pass through the point\n                    int idx = reg.pts[0];\n                    ll val = A * pts[idx].x + B * pts[idx].y + C;\n                    if (val == 0) {\n                        possible = false; // Line cuts the strawberry\n                        break;\n                    }\n                    continue; // No split possible for single point (unless hit)\n                }\n\n                int pos_cnt = 0;\n                int neg_cnt = 0;\n                bool hit = false;\n                \n                // Check side of each point in the region\n                for (int idx : reg.pts) {\n                    ll val = A * pts[idx].x + B * pts[idx].y + C;\n                    if (val > 0) pos_cnt++;\n                    else if (val < 0) neg_cnt++;\n                    else {\n                        hit = true; // Line passes through a strawberry\n                        break;\n                    }\n                }\n                \n                if (hit) {\n                    possible = false;\n                    break;\n                }\n\n                // If the line splits the region into two non-empty sets\n                if (pos_cnt > 0 && neg_cnt > 0) {\n                    // Update the counts in temp_b\n                    // The old region of size 'sz' is removed\n                    if (sz <= 10) {\n                        temp_b[sz]--;\n                    }\n                    // Two new regions of sizes 'pos_cnt' and 'neg_cnt' are created\n                    if (pos_cnt <= 10) {\n                        temp_b[pos_cnt]++;\n                    }\n                    if (neg_cnt <= 10) {\n                        temp_b[neg_cnt]++;\n                    }\n                }\n            }\n\n            if (possible) {\n                ll sc = calc_score(temp_b);\n                if (sc > best_score) {\n                    best_score = sc;\n                    best_line_x1 = x1;\n                    best_line_y1 = y1;\n                    best_line_x2 = x2;\n                    best_line_y2 = y2;\n                    found_better = true;\n                }\n            }\n        }\n\n        if (found_better) {\n            current_score = best_score;\n            final_lines.push_back({best_line_x1, best_line_y1, best_line_x2, best_line_y2});\n            \n            // Apply the best line: Update regions and global counts b\n            ll A = best_line_y1 - best_line_y2;\n            ll B = best_line_x2 - best_line_x1;\n            ll C = -A * best_line_x1 - B * best_line_y1;\n\n            vector<Region> next_regions;\n            // Reserve memory to avoid reallocations. Max regions ~ K+1.\n            next_regions.reserve(regions.size() + 2);\n\n            for (auto& reg : regions) {\n                int sz = (int)reg.pts.size();\n                \n                // First pass: check if split is needed\n                int pos = 0;\n                int neg = 0;\n                for (int idx : reg.pts) {\n                    ll val = A * pts[idx].x + B * pts[idx].y + C;\n                    if (val > 0) pos++;\n                    else if (val < 0) neg++;\n                    // val == 0 should not happen for the selected best line\n                }\n\n                if (pos > 0 && neg > 0) {\n                    // Split occurred\n                    // Update global counts b\n                    if (sz <= 10) b[sz]--;\n                    if (pos <= 10) b[pos]++;\n                    if (neg <= 10) b[neg]++;\n\n                    // Create new regions\n                    Region r1, r2;\n                    r1.pts.reserve(pos);\n                    r2.pts.reserve(neg);\n                    \n                    for (int idx : reg.pts) {\n                        ll val = A * pts[idx].x + B * pts[idx].y + C;\n                        if (val > 0) r1.pts.push_back(idx);\n                        else if (val < 0) r2.pts.push_back(idx);\n                    }\n                    next_regions.push_back(move(r1));\n                    next_regions.push_back(move(r2));\n                } else {\n                    // No split, keep the region (move to avoid copy)\n                    next_regions.push_back(move(reg));\n                }\n            }\n            regions = move(next_regions);\n        } else {\n            // No improvement found with random lines, stop early\n            break;\n        }\n    }\n\n    // Output results\n    cout << final_lines.size() << \"\\n\";\n    for (const auto& line : final_lines) {\n        cout << get<0>(line) << \" \" << get<1>(line) << \" \" << get<2>(line) << \" \" << get<3>(line) << \"\\n\";\n    }\n\n    return 0;\n}","ahc014":"#pragma GCC optimize(\"O3,unroll-loops\")\n#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nbool has_dot[65][65] = {};\n// used_edge[x][y][dir]: 0:Right, 1:Up, 2:UR, 3:DR\n// Canonical: x1 <= x2, and if x1==x2 then y1 <= y2.\nbool used_edge[65][65][4] = {}; \n\nstruct Point { int x, y; };\nlong long weight[65][65];\nvector<Point> all_points;\nvector<tuple<Point, Point, Point, Point>> result;\n\nvector<Point> row_dots[65], col_dots[65], diag1[130], diag2[130];\n\nvoid add_dot(Point p) {\n    if (p.x < 0 || p.x >= N || p.y < 0 || p.y >= N || has_dot[p.x][p.y]) return;\n    has_dot[p.x][p.y] = true;\n    row_dots[p.y].push_back(p);\n    col_dots[p.x].push_back(p);\n    diag1[p.y - p.x + 65].push_back(p);\n    diag2[p.x + p.y].push_back(p);\n}\n\nbool has_dot_on_segment(Point p1, Point p2) {\n    int dx = (p2.x > p1.x) - (p2.x < p1.x);\n    int dy = (p2.y > p1.y) - (p2.y < p1.y);\n    int cx = p1.x + dx, cy = p1.y + dy;\n    while (cx != p2.x || cy != p2.y) {\n        if (has_dot[cx][cy]) return true;\n        cx += dx; cy += dy;\n    }\n    return false;\n}\n\nbool has_edge_collision(Point p1, Point p2) {\n    int x1 = p1.x, y1 = p1.y, x2 = p2.x, y2 = p2.y;\n    if (x1 > x2 || (x1 == x2 && y1 > y2)) swap(x1, x2), swap(y1, y2);\n    int dx = x2 - x1, dy = y2 - y1;\n    if (dx == 0) { // Vertical\n        for (int y = y1; y < y2; ++y) if (used_edge[x1][y][1]) return true;\n    } else if (dy == 0) { // Horizontal\n        for (int x = x1; x < x2; ++x) if (used_edge[x][y1][0]) return true;\n    } else if (dy > 0) { // UR\n        for (int x = x1; x < x2; ++x) if (used_edge[x][y1 + x - x1][2]) return true;\n    } else { // DR\n        for (int x = x1; x < x2; ++x) if (used_edge[x][y1 - (x - x1)][3]) return true;\n    }\n    return false;\n}\n\nvoid mark_edges(Point p1, Point p2) {\n    int x1 = p1.x, y1 = p1.y, x2 = p2.x, y2 = p2.y;\n    if (x1 > x2 || (x1 == x2 && y1 > y2)) swap(x1, x2), swap(y1, y2);\n    int dx = x2 - x1, dy = y2 - y1;\n    if (dx == 0) {\n        for (int y = y1; y < y2; ++y) used_edge[x1][y][1] = true;\n    } else if (dy == 0) {\n        for (int x = x1; x < x2; ++x) used_edge[x][y1][0] = true;\n    } else if (dy > 0) {\n        for (int x = x1; x < x2; ++x) used_edge[x][y1 + x - x1][2] = true;\n    } else {\n        for (int x = x1; x < x2; ++x) used_edge[x][y1 - (x - x1)][3] = true;\n    }\n}\n\nbool check_rect(Point p1, Point p2, Point p3, Point p4) {\n    Point pts[4] = {p1, p2, p3, p4};\n    for (int i = 0; i < 4; ++i) {\n        if (has_dot_on_segment(pts[i], pts[(i+1)%4])) return false;\n        if (has_edge_collision(pts[i], pts[(i+1)%4])) return false;\n    }\n    return true;\n}\n\nint get_perimeter(Point p1, Point p2, Point p3, Point p4) {\n    auto len = [](Point a, Point b) { return max(abs(a.x - b.x), abs(a.y - b.y)); };\n    return len(p1, p2) + len(p2, p3) + len(p3, p4) + len(p4, p1);\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    if (!(cin >> N >> M)) return 0;\n    int c = (N - 1) / 2;\n    for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) {\n        weight[i][j] = (long long)(i - c) * (i - c) + (j - c) * (j - c) + 1;\n        all_points.push_back({i, j});\n    }\n    for (int i = 0; i < M; ++i) { int x, y; cin >> x >> y; add_dot({x, y}); }\n    \n    sort(all_points.begin(), all_points.end(), [](const Point& a, const Point& b) {\n        return weight[a.x][a.y] > weight[b.x][b.y];\n    });\n\n    clock_t start = clock();\n    for (const auto& p1 : all_points) {\n        if (has_dot[p1.x][p1.y]) continue;\n        if ((double)(clock() - start) / CLOCKS_PER_SEC > 4.5) break;\n        \n        int px = p1.x, py = p1.y;\n        int best_cost = 1e9;\n        tuple<Point, Point, Point, Point> best_rect;\n        bool found = false;\n\n        auto search = [&]() {\n            // Axis-aligned\n            for (const auto& p2 : row_dots[py]) {\n                if (p2.x == px) continue;\n                for (const auto& p4 : col_dots[px]) {\n                    if (p4.y == py) continue;\n                    Point p3 = {p2.x, p4.y};\n                    if (has_dot[p3.x][p3.y] && check_rect(p1, p2, p3, p4)) {\n                        int cost = get_perimeter(p1, p2, p3, p4);\n                        if (cost < best_cost) { best_cost = cost; best_rect = {p1, p2, p3, p4}; found = true; }\n                    }\n                }\n            }\n            // 45-deg\n            int d1 = py - px + 65, d2 = py + px;\n            if (d1 >= 0 && d1 < 130 && d2 >= 0 && d2 < 130) {\n                for (const auto& p2 : diag1[d1]) {\n                    if (p2.x == px && p2.y == py) continue;\n                    for (const auto& p4 : diag2[d2]) {\n                        if (p4.x == px && p4.y == py) continue;\n                        Point p3 = {p2.x + p4.x - px, p2.y + p4.y - py};\n                        if (p3.x >= 0 && p3.x < N && p3.y >= 0 && p3.y < N && has_dot[p3.x][p3.y]) {\n                            if (check_rect(p1, p2, p3, p4)) {\n                                int cost = get_perimeter(p1, p2, p3, p4);\n                                if (cost < best_cost) { best_cost = cost; best_rect = {p1, p2, p3, p4}; found = true; }\n                            }\n                        }\n                    }\n                }\n            }\n        };\n        \n        search();\n        if (found) {\n            auto [bp1, bp2, bp3, bp4] = best_rect;\n            // Safety check\n            if (check_rect(bp1, bp2, bp3, bp4)) {\n                mark_edges(bp1, bp2); mark_edges(bp2, bp3);\n                mark_edges(bp3, bp4); mark_edges(bp4, bp1);\n                add_dot(bp1); \n                result.push_back(best_rect);\n            }\n        }\n    }\n    \n    cout << result.size() << \"\\n\";\n    for (auto& t : result) {\n        auto [p1, p2, p3, p4] = t;\n        cout << p1.x << \" \" << p1.y << \" \" << p2.x << \" \" << p2.y << \" \" \n             << p3.x << \" \" << p3.y << \" \" << p4.x << \" \" << p4.y << \"\\n\";\n    }\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cstring>\n#include <cmath>\n#include <cstdlib>\n\nusing namespace std;\n\n// Global buffers to avoid reallocation\nint f[100];\nint adj[100][4];\nint q[100];\nbool vis[100];\nint comp_id[100];\nint comp_size[100];\n\n// Precompute adjacency list for the 10x10 grid\nvoid init_adj() {\n    int dr[] = {-1, 1, 0, 0};\n    int dc[] = {0, 0, -1, 1};\n    for(int r=0; r<10; ++r) {\n        for(int c=0; c<10; ++c) {\n            int u = r*10+c;\n            int k=0;\n            for(int d=0; d<4; ++d) {\n                int nr=r+dr[d], nc=c+dc[d];\n                adj[u][k++] = (nr>=0 && nr<10 && nc>=0 && nc<10) ? nr*10+nc : -1;\n            }\n        }\n    }\n}\n\n// Analyze grid: computes score and populates comp_id, comp_size\nint analyze_grid(const vector<int>& grid) {\n    memset(vis, 0, sizeof(vis));\n    memset(comp_id, -1, sizeof(comp_id));\n    int score = 0;\n    int num_comp = 0;\n    \n    for(int i=0; i<100; ++i) {\n        if(grid[i] != 0 && !vis[i]) {\n            int flav = grid[i];\n            int sz = 0;\n            int h = 0, t = 0;\n            q[t++] = i;\n            vis[i] = true;\n            comp_id[i] = num_comp;\n            \n            while(h < t) {\n                int u = q[h++];\n                sz++;\n                for(int k=0; k<4; ++k) {\n                    int v = adj[u][k];\n                    if(v != -1 && !vis[v] && grid[v] == flav) {\n                        vis[v] = true;\n                        comp_id[v] = num_comp;\n                        q[t++] = v;\n                    }\n                }\n            }\n            comp_size[num_comp] = sz;\n            score += sz * sz;\n            num_comp++;\n        }\n    }\n    return score;\n}\n\n// Calculate expected gain if we place a candy of `flavor` in a random empty cell\n// Assumes analyze_grid has been run on the current grid state.\ndouble calc_expected_gain(const vector<int>& grid, int flavor, int empty_count) {\n    if (empty_count <= 0) return 0.0;\n    long long total_gain = 0;\n    for(int i=0; i<100; ++i) {\n        if(grid[i] == 0) {\n            int neighbors[4];\n            int n_count = 0;\n            for(int k=0; k<4; ++k){\n                int nidx = adj[i][k];\n                if(nidx != -1 && grid[nidx] == flavor) {\n                    int id = comp_id[nidx];\n                    if(id != -1) {\n                        bool found = false;\n                        for(int j=0; j<n_count; ++j) if(neighbors[j] == id) { found = true; break; }\n                        if(!found) neighbors[n_count++] = id;\n                    }\n                }\n            }\n            if(n_count > 0) {\n                int sum_s = 0, sum_sq = 0;\n                for(int j=0; j<n_count; ++j) {\n                    int s = comp_size[neighbors[j]];\n                    sum_s += s;\n                    sum_sq += s * s;\n                }\n                total_gain += (long long)(sum_s + 1) * (sum_s + 1) - sum_sq;\n            } else {\n                total_gain += 1;\n            }\n        }\n    }\n    return (double)total_gain / empty_count;\n}\n\n// Apply tilt. dir: 0=F, 1=B, 2=L, 3=R\nvoid tilt(const vector<int>& src, vector<int>& dst, int dir) {\n    memset(dst.data(), 0, 100 * sizeof(int));\n    if(dir == 2) { // L\n        for(int r=0; r<10; ++r) { int k=0; for(int c=0; c<10; ++c) { int v=src[r*10+c]; if(v) dst[r*10+k++]=v; } }\n    } else if(dir == 3) { // R\n        for(int r=0; r<10; ++r) { int k=9; for(int c=9; c>=0; --c) { int v=src[r*10+c]; if(v) dst[r*10+k--]=v; } }\n    } else if(dir == 0) { // F\n        for(int c=0; c<10; ++c) { int k=0; for(int r=0; r<10; ++r) { int v=src[r*10+c]; if(v) dst[k*10+c]=v, k++; } }\n    } else { // B\n        for(int c=0; c<10; ++c) { int k=9; for(int r=9; r>=0; --r) { int v=src[r*10+c]; if(v) dst[k*10+c]=v, k--; } }\n    }\n}\n\n// Lookahead parameters\nconst int MAX_DEPTH = 2;\nconst int SAMPLE_K = 6;\n\n// Recursive evaluation function (Expectimax with sampling)\n// grid: current state (after some tilts)\n// depth: number of (Place + Tilt) steps to look ahead\n// f_idx: index of the next candy to be placed\ndouble evaluate(const vector<int>& grid, int depth, int f_idx) {\n    // Find empty cells\n    vector<int> empties;\n    empties.reserve(100);\n    for(int i=0; i<100; ++i) if(grid[i] == 0) empties.push_back(i);\n    int ec = empties.size();\n    \n    // Base case: no more lookahead or grid full or no more candies\n    if (depth == 0 || ec == 0 || f_idx >= 100) {\n        int score = analyze_grid(grid);\n        // Add heuristic for the next candy to estimate future potential\n        if (ec > 0 && f_idx < 100) {\n            score += calc_expected_gain(grid, f[f_idx], ec);\n        }\n        return (double)score;\n    }\n    \n    // Determine samples (random subset of empty cells if too many)\n    vector<int> samples;\n    int num_samples = 0;\n    if (ec <= SAMPLE_K) {\n        samples = empties;\n        num_samples = ec;\n    } else {\n        num_samples = SAMPLE_K;\n        samples.reserve(SAMPLE_K);\n        // Random sampling without replacement (partial shuffle)\n        for(int i=0; i<SAMPLE_K; ++i) {\n            int j = i + (rand() % (ec - i));\n            swap(empties[i], empties[j]);\n            samples.push_back(empties[i]);\n        }\n    }\n    \n    double sum_max = 0.0;\n    int flavor = f[f_idx];\n    vector<int> temp_grid(100);\n    vector<int> tilted_grid(100);\n    \n    // Expectation over possible placements of the next candy\n    for (int pos : samples) {\n        // Place candy\n        temp_grid = grid;\n        temp_grid[pos] = flavor;\n        \n        double max_val = -1.0;\n        \n        // Maximization over possible tilts after placement\n        for (int d = 0; d < 4; ++d) {\n            tilt(temp_grid, tilted_grid, d);\n            double val = evaluate(tilted_grid, depth - 1, f_idx + 1);\n            if (val > max_val) max_val = val;\n        }\n        sum_max += max_val;\n    }\n    \n    return sum_max / num_samples;\n}\n\nint main() {\n    // Optimize I/O\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    srand(12345); // Fixed seed for reproducibility\n    init_adj();\n    \n    for(int i=0; i<100; ++i) {\n        if (!(cin >> f[i])) return 0;\n    }\n    \n    vector<int> grid(100, 0);\n    vector<int> g_tilted(100);\n    vector<int> g_next(100);\n    const char dirs[] = \"FBLR\";\n    \n    for(int t=0; t<100; ++t) {\n        int p;\n        if (!(cin >> p)) break;\n        \n        // Place current candy f[t] at p-th empty cell\n        int cnt = 0;\n        for(int i=0; i<100; ++i) {\n            if(grid[i] == 0) {\n                if(++cnt == p) {\n                    grid[i] = f[t];\n                    break;\n                }\n            }\n        }\n        \n        // For the 100th candy, grid is full, no tilt needed\n        if(t == 99) break;\n        \n        int best_d = 0;\n        double best_val = -1.0;\n        \n        // Evaluate 4 possible tilts\n        for(int d=0; d<4; ++d) {\n            tilt(grid, g_tilted, d);\n            \n            // Lookahead: simulate next 2 candies (placement + tilt)\n            double val = evaluate(g_tilted, 2, t+1);\n            \n            if(val > best_val) {\n                best_val = val;\n                best_d = d;\n            }\n        }\n        \n        // Apply best tilt\n        tilt(grid, g_next, best_d);\n        grid = g_next;\n        \n        cout << dirs[best_d] << endl;\n    }\n    \n    return 0;\n}","ahc016":"#pragma GCC optimize(\"O3,unroll-loops\")\n#include <bits/stdc++.h>\n#include <Eigen/Dense>\nusing namespace std;\n\nint main() {\n    // Optimize I/O operations for speed\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M;\n    double eps;\n    if (!(cin >> M >> eps)) return 0;\n\n    // Adaptive N selection:\n    // Balances the score penalty (1/N) with the need for robustness against noise.\n    // Base 10, scales with M (more graphs to separate) and eps (more noise to overcome).\n    // Clamped to [12, 80] to ensure reasonable performance and score ceiling.\n    int N = max(12, min(80, (int)ceil(10.0 + 0.2 * M + 30.0 * eps)));\n    cout << N << \"\\n\";\n\n    // Dynamic pool size K:\n    // Eigenvalue decomposition is O(N^3). We limit total ops to ~6e7 to stay safely within 5s.\n    // Ensures K is large enough for good graph separation but small enough for speed.\n    int K = max(400, min(1500, (int)(6e7 / ((double)N * N * N))));\n\n    // Deterministic seed based on test case parameters for variety across runs\n    unsigned int seed = static_cast<unsigned int>(M * 100007 + eps * 100009 + 42);\n    mt19937 rng(seed);\n    uniform_real_distribution<double> dist_p(0.05, 0.95);\n    uniform_real_distribution<double> dist_u(0.0, 1.0);\n\n    vector<string> pool_s;\n    pool_s.reserve(K);\n    vector<vector<double>> pool_eig;\n    pool_eig.reserve(K);\n\n    // Re-use matrix to avoid allocation overhead\n    Eigen::MatrixXd A(N, N);\n\n    // Generate candidate graphs and compute their spectral signatures\n    for (int k = 0; k < K; ++k) {\n        double p = dist_p(rng);\n        A.setZero();\n        string s; \n        s.reserve(N * (N - 1) / 2);\n        \n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                bool edge = dist_u(rng) < p;\n                if (edge) A(i, j) = A(j, i) = 1.0;\n                s += (edge ? '1' : '0');\n            }\n        }\n        pool_s.push_back(move(s));\n        \n        // Compute sorted eigenvalues (ascending order)\n        Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es(A, Eigen::EigenvaluesOnly);\n        const auto& evals = es.eigenvalues();\n        vector<double> eigs(N);\n        for (int i = 0; i < N; ++i) eigs[i] = evals(i);\n        pool_eig.push_back(move(eigs));\n    }\n\n    // Farthest Point Sampling (FPS) to select M maximally distinct graphs\n    vector<int> sel; \n    sel.reserve(M);\n    vector<bool> used(K, false);\n    vector<double> min_d(K, 1e18);\n\n    // Pick first graph randomly\n    int start = rng() % K;\n    sel.push_back(start); \n    used[start] = true;\n    \n    // Initialize distances to the first selected graph\n    const auto& ref = pool_eig[start];\n    for (int k = 0; k < K; ++k) {\n        if (!used[k]) {\n            double d = 0;\n            for (int i = 0; i < N; ++i) { \n                double t = pool_eig[k][i] - ref[i]; \n                d += t * t; \n            }\n            min_d[k] = d;\n        }\n    }\n\n    // Greedily select remaining M-1 graphs\n    for (int m = 1; m < M; ++m) {\n        int best = -1; \n        double best_v = -1.0;\n        for (int k = 0; k < K; ++k) {\n            if (!used[k] && min_d[k] > best_v) { \n                best_v = min_d[k]; \n                best = k; \n            }\n        }\n        if (best == -1) break;\n        \n        sel.push_back(best); \n        used[best] = true;\n        \n        // Update minimum distances for unselected graphs\n        const auto& nw = pool_eig[best];\n        for (int k = 0; k < K; ++k) {\n            if (!used[k]) {\n                double d = 0;\n                for (int i = 0; i < N; ++i) { \n                    double t = pool_eig[k][i] - nw[i]; \n                    d += t * t; \n                }\n                if (d < min_d[k]) min_d[k] = d;\n            }\n        }\n    }\n    \n    // Fallback if selection stopped early\n    if ((int)sel.size() < M) {\n        for (int k = 0; k < K && (int)sel.size() < M; ++k) {\n            if (!used[k]) sel.push_back(k);\n        }\n    }\n\n    // Precompute expected eigenvalues under the noise model\n    // E[A_noisy] = (1 - 2*eps)*A + eps*(J - I)\n    // The largest eigenvalue shifts by +eps*(N-1), others shift by -eps and scale by (1-2*eps)\n    vector<vector<double>> exp_eigs(M, vector<double>(N));\n    double s1 = 1.0 - 2.0 * eps;\n    for (int m = 0; m < M; ++m) {\n        const auto& e = pool_eig[sel[m]];\n        for (int i = 0; i < N - 1; ++i) exp_eigs[m][i] = s1 * e[i] - eps;\n        exp_eigs[m][N - 1] = s1 * e[N - 1] + eps * (N - 1);\n    }\n\n    // Output selected graphs\n    for (int m = 0; m < M; ++m) {\n        cout << pool_s[sel[m]] << \"\\n\";\n    }\n    cout.flush();\n\n    // Process 100 queries\n    for (int q = 0; q < 100; ++q) {\n        string h; \n        cin >> h;\n        A.setZero();\n        int idx = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                if (h[idx] == '1') A(i, j) = A(j, i) = 1.0;\n                ++idx;\n            }\n        }\n\n        // Compute eigenvalues of the noisy query\n        Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es(A, Eigen::EigenvaluesOnly);\n        const auto& evals = es.eigenvalues();\n\n        int best_m = 0; \n        double best_d = 1e18;\n        \n        // Match against expected eigenvalues of candidates\n        for (int m = 0; m < M; ++m) {\n            double d = 0;\n            for (int i = 0; i < N; ++i) { \n                double t = evals(i) - exp_eigs[m][i]; \n                d += t * t; \n            }\n            if (d < best_d) { \n                best_d = d; \n                best_m = m; \n            }\n        }\n        cout << best_m << \"\\n\";\n        cout.flush();\n    }\n\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\n#pragma GCC optimize(\"O3,unroll-loops\")\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n\n    struct Edge { int u, v; int w; };\n    vector<Edge> edges(M);\n    vector<vector<pair<int, int>>> adj(N);\n\n    for (int i = 0; i < M; ++i) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        --u; --v;\n        edges[i] = {u, v, w};\n        adj[u].emplace_back(v, i);\n        adj[v].emplace_back(u, i);\n    }\n    for (int i = 0; i < N; ++i) { int x, y; cin >> x >> y; }\n\n    // 1. Compute Weighted Edge Betweenness Centrality\n    // This serves as a highly accurate proxy for the increase in all-pairs shortest paths\n    // when an edge is removed.\n    vector<double> eb(M, 0.0);\n    vector<int> dist(N);\n    vector<double> sigma(N), delta(N);\n    vector<int> nodes(N);\n    iota(nodes.begin(), nodes.end(), 0);\n    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;\n    const int INF = 2e9;\n\n    for (int s = 0; s < N; ++s) {\n        fill(dist.begin(), dist.end(), INF);\n        dist[s] = 0;\n        pq.emplace(0, s);\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u]) continue;\n            for (auto [v, id] : adj[u]) {\n                if (dist[v] > d + edges[id].w) {\n                    dist[v] = d + edges[id].w;\n                    pq.emplace(dist[v], v);\n                }\n            }\n        }\n\n        sort(nodes.begin(), nodes.end(), [&](int a, int b) { return dist[a] < dist[b]; });\n\n        fill(sigma.begin(), sigma.end(), 0.0);\n        sigma[s] = 1.0;\n        for (int u : nodes) {\n            if (u == s) continue;\n            double s_u = 0.0;\n            for (auto [p, id] : adj[u]) {\n                if (dist[p] + edges[id].w == dist[u]) s_u += sigma[p];\n            }\n            sigma[u] = s_u;\n        }\n\n        fill(delta.begin(), delta.end(), 0.0);\n        for (auto it = nodes.rbegin(); it != nodes.rend(); ++it) {\n            int u = *it;\n            if (sigma[u] == 0.0) continue;\n            double contrib = (1.0 + delta[u]) / sigma[u];\n            for (auto [p, id] : adj[u]) {\n                if (dist[p] + edges[id].w == dist[u]) {\n                    double val = sigma[p] * contrib;\n                    delta[p] += val;\n                    eb[id] += val;\n                }\n            }\n        }\n    }\n\n    // Fast PRNG\n    uint64_t rng_state = 88172645463325252ULL;\n    auto fast_rand = [&]() {\n        rng_state ^= rng_state >> 7;\n        rng_state ^= rng_state << 17;\n        rng_state ^= rng_state >> 13;\n        return rng_state;\n    };\n\n    // 2. Greedy Assignment\n    vector<int> assign(M);\n    vector<double> day_sum(D, 0.0);\n    \n    vector<int> sorted_idx(M);\n    iota(sorted_idx.begin(), sorted_idx.end(), 0);\n    sort(sorted_idx.begin(), sorted_idx.end(), [&](int a, int b) { return eb[a] > eb[b]; });\n\n    for (int idx : sorted_idx) {\n        int best_d = 0;\n        double min_s = day_sum[0];\n        for (int d = 1; d < D; ++d) {\n            if (day_sum[d] < min_s) { min_s = day_sum[d]; best_d = d; }\n        }\n        assign[idx] = best_d;\n        day_sum[best_d] += eb[idx];\n    }\n\n    // Prepare for Focused Simulated Annealing\n    // Maintain day_edges lists and position tracking for O(1) swaps\n    vector<vector<int>> day_edges(D);\n    vector<int> pos_in_day(M);\n    for (int i = 0; i < M; ++i) {\n        int d = assign[i];\n        pos_in_day[i] = day_edges[d].size();\n        day_edges[d].push_back(i);\n    }\n\n    auto start = chrono::steady_clock::now();\n    const int MAX_ITER = 12000000;\n    double T = 1e9;\n    const double COOLING = pow(100.0 / 1e9, 1.0 / MAX_ITER);\n    int iter = 0;\n\n    while (iter < MAX_ITER) {\n        if ((iter & 0xFFFFFF) == 0) {\n            if (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start).count() > 5400) break;\n        }\n        iter++;\n\n        // Find days with maximum and minimum betweenness sums\n        int u_max = 0, u_min = 0;\n        double s_max = day_sum[0], s_min = day_sum[0];\n        for (int d = 1; d < D; ++d) {\n            if (day_sum[d] > s_max) { s_max = day_sum[d]; u_max = d; }\n            if (day_sum[d] < s_min) { s_min = day_sum[d]; u_min = d; }\n        }\n        if (u_max == u_min) break;\n\n        // Randomly pick one edge from max day and one from min day\n        int i = day_edges[u_max][fast_rand() % day_edges[u_max].size()];\n        int j = day_edges[u_min][fast_rand() % day_edges[u_min].size()];\n        \n        double wi = eb[i], wj = eb[j];\n        double su = day_sum[u_max], sv = day_sum[u_min];\n        double delta_val = wj - wi;\n        // Change in sum of squares objective: 2 * delta_val * (su - sv + delta_val)\n        // We use half the change for simplicity in SA acceptance\n        double change = delta_val * (su - sv + delta_val);\n\n        if (change < 0.0) {\n            day_sum[u_max] += delta_val;\n            day_sum[u_min] -= delta_val;\n            swap(assign[i], assign[j]);\n            \n            // Update structures in O(1)\n            int pi = pos_in_day[i], pj = pos_in_day[j];\n            swap(day_edges[u_max][pi], day_edges[u_min][pj]);\n            pos_in_day[day_edges[u_max][pi]] = pi;\n            pos_in_day[day_edges[u_min][pj]] = pj;\n        } else {\n            double prob = exp(-change / T);\n            if ((fast_rand() & 0x7FFFFF) / 8388608.0 < prob) {\n                day_sum[u_max] += delta_val;\n                day_sum[u_min] -= delta_val;\n                swap(assign[i], assign[j]);\n                \n                int pi = pos_in_day[i], pj = pos_in_day[j];\n                swap(day_edges[u_max][pi], day_edges[u_min][pj]);\n                pos_in_day[day_edges[u_max][pi]] = pi;\n                pos_in_day[day_edges[u_min][pj]] = pj;\n            }\n        }\n        T *= COOLING;\n    }\n\n    for (int i = 0; i < M; ++i) {\n        cout << assign[i] + 1 << (i == M - 1 ? \"\\n\" : \" \");\n    }\n\n    return 0;\n}","ahc019":"/*\n    Solution for AHC019\n    Heuristic approach:\n    1. Identify valid regions (intersection of silhouettes).\n    2. Greedily find large shared blocks by growing shapes in Config 1 and checking fit in Config 2.\n    3. Fill remaining silhouette requirements with 1x1 blocks (shared if possible).\n*/\n#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\n\nint D;\nbool F[2][14][14], R[2][14][14];\nbool Valid[2][14][14][14];\nbool Used[2][14][14][14];\nint Sol[2][14][14][14];\n\nstruct Pt { int x, y, z; };\nvector<array<array<int,3>,3>> Rots;\nvector<Pt> free_cells[2];\n\nvoid gen_rots() {\n    vector<array<int,3>> basis = {\n        {1,0,0}, {-1,0,0}, {0,1,0}, {0,-1,0}, {0,0,1}, {0,0,-1}\n    };\n    for(const auto& r1 : basis) {\n        for(const auto& r2 : basis) {\n            if(r1[0]*r2[0] + r1[1]*r2[1] + r1[2]*r2[2] != 0) continue;\n            for(const auto& r3 : basis) {\n                if(r1[0]*r3[0] + r1[1]*r3[1] + r1[2]*r3[2] != 0) continue;\n                if(r2[0]*r3[0] + r2[1]*r3[1] + r2[2]*r3[2] != 0) continue;\n                \n                int det = r1[0]*(r2[1]*r3[2] - r2[2]*r3[1])\n                        - r1[1]*(r2[0]*r3[2] - r2[2]*r3[0])\n                        + r1[2]*(r2[0]*r3[1] - r2[1]*r3[0]);\n                \n                if(det == 1) {\n                    array<array<int,3>,3> m;\n                    m[0] = r1; m[1] = r2; m[2] = r3;\n                    bool dup = false;\n                    for(const auto& exist : Rots) {\n                        if(exist == m) { dup = true; break; }\n                    }\n                    if(!dup) Rots.push_back(m);\n                }\n            }\n        }\n    }\n}\n\nstruct Placement {\n    int dx, dy, dz, rot_idx;\n};\n\nbool is_valid(int k, int x, int y, int z) {\n    return x >= 0 && x < D && y >= 0 && y < D && z >= 0 && z < D && Valid[k][x][y][z] && !Used[k][x][y][z];\n}\n\nvoid mark_used(int k, int x, int y, int z) {\n    Used[k][x][y][z] = true;\n    auto& list = free_cells[k];\n    for(int i=0; i<(int)list.size(); i++) {\n        if(list[i].x == x && list[i].y == y && list[i].z == z) {\n            list[i] = list.back();\n            list.pop_back();\n            break;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(0); cin.tie(0);\n    if(!(cin >> D)) return 0;\n    \n    string s;\n    for(int k=0; k<2; k++) {\n        for(int z=0; z<D; z++) {\n            cin >> s;\n            for(int x=0; x<D; x++) F[k][z][x] = (s[x] == '1');\n        }\n        for(int z=0; z<D; z++) {\n            cin >> s;\n            for(int y=0; y<D; y++) R[k][z][y] = (s[y] == '1');\n        }\n        for(int x=0; x<D; x++)\n            for(int y=0; y<D; y++)\n                for(int z=0; z<D; z++) {\n                    Valid[k][x][y][z] = F[k][z][x] && R[k][z][y];\n                    if(Valid[k][x][y][z]) {\n                        free_cells[k].push_back({x,y,z});\n                    }\n                    Used[k][x][y][z] = false;\n                    Sol[k][x][y][z] = 0;\n                }\n    }\n    \n    gen_rots();\n    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n    for(int k=0; k<2; k++) shuffle(free_cells[k].begin(), free_cells[k].end(), rng);\n    \n    int block_id = 1;\n    int max_iters = 20000;\n    \n    while(max_iters-- > 0) {\n        Pt seed = {-1,-1,-1};\n        for(const auto& p : free_cells[0]) {\n            if(!Used[0][p.x][p.y][p.z]) {\n                seed = p;\n                break;\n            }\n        }\n        if(seed.x == -1) break;\n        \n        if(free_cells[1].empty()) break;\n        \n        vector<Pt> shape;\n        shape.push_back({0,0,0});\n        \n        vector<Placement> valid_placements;\n        valid_placements.reserve(free_cells[1].size());\n        for(const auto& p : free_cells[1]) {\n            valid_placements.push_back({p.x, p.y, p.z, 0});\n        }\n        \n        if(valid_placements.empty()) break;\n        \n        int growth_limit = 50;\n        bool grew = true;\n        int dirs[6][3] = {{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}};\n        \n        while(grew && (int)shape.size() < growth_limit) {\n            grew = false;\n            vector<Pt> candidates;\n            \n            for(const auto& rel : shape) {\n                int ax = seed.x + rel.x;\n                int ay = seed.y + rel.y;\n                int az = seed.z + rel.z;\n                for(auto& d : dirs) {\n                    int nx = ax + d[0];\n                    int ny = ay + d[1];\n                    int nz = az + d[2];\n                    if(is_valid(0, nx, ny, nz)) {\n                        Pt rel_n = {nx - seed.x, ny - seed.y, nz - seed.z};\n                        bool in_shape = false;\n                        for(const auto& s : shape) {\n                            if(s.x == rel_n.x && s.y == rel_n.y && s.z == rel_n.z) {\n                                in_shape = true; break;\n                            }\n                        }\n                        if(!in_shape) candidates.push_back(rel_n);\n                    }\n                }\n            }\n            \n            sort(candidates.begin(), candidates.end(), [](const Pt& a, const Pt& b){\n                if(a.x != b.x) return a.x < b.x;\n                if(a.y != b.y) return a.y < b.y;\n                return a.z < b.z;\n            });\n            candidates.erase(unique(candidates.begin(), candidates.end(), [](const Pt& a, const Pt& b){\n                return a.x==b.x && a.y==b.y && a.z==b.z;\n            }), candidates.end());\n            \n            shuffle(candidates.begin(), candidates.end(), rng);\n            \n            for(const auto& cand : candidates) {\n                vector<Placement> next_placements;\n                next_placements.reserve(valid_placements.size());\n                \n                for(const auto& pl : valid_placements) {\n                    const auto& rot = Rots[pl.rot_idx];\n                    int rx = rot[0][0]*cand.x + rot[0][1]*cand.y + rot[0][2]*cand.z;\n                    int ry = rot[1][0]*cand.x + rot[1][1]*cand.y + rot[1][2]*cand.z;\n                    int rz = rot[2][0]*cand.x + rot[2][1]*cand.y + rot[2][2]*cand.z;\n                    \n                    int ax = pl.dx + rx;\n                    int ay = pl.dy + ry;\n                    int az = pl.dz + rz;\n                    \n                    if(is_valid(1, ax, ay, az)) {\n                        next_placements.push_back(pl);\n                    }\n                }\n                \n                if(!next_placements.empty()) {\n                    shape.push_back(cand);\n                    valid_placements = next_placements;\n                    grew = true;\n                    break;\n                }\n            }\n        }\n        \n        if(!shape.empty()) {\n            Placement chosen = valid_placements[rng() % valid_placements.size()];\n            const auto& rot = Rots[chosen.rot_idx];\n            \n            for(const auto& rel : shape) {\n                mark_used(0, seed.x + rel.x, seed.y + rel.y, seed.z + rel.z);\n                Sol[0][seed.x + rel.x][seed.y + rel.y][seed.z + rel.z] = block_id;\n            }\n            \n            for(const auto& rel : shape) {\n                int rx = rot[0][0]*rel.x + rot[0][1]*rel.y + rot[0][2]*rel.z;\n                int ry = rot[1][0]*rel.x + rot[1][1]*rel.y + rot[1][2]*rel.z;\n                int rz = rot[2][0]*rel.x + rot[2][1]*rel.y + rot[2][2]*rel.z;\n                int ax = chosen.dx + rx;\n                int ay = chosen.dy + ry;\n                int az = chosen.dz + rz;\n                mark_used(1, ax, ay, az);\n                Sol[1][ax][ay][az] = block_id;\n            }\n            \n            block_id++;\n        }\n    }\n    \n    // Cover silhouettes\n    auto cover = [&](int k) {\n        for(int z=0; z<D; z++) {\n            for(int x=0; x<D; x++) {\n                if(F[k][z][x]) {\n                    bool covered = false;\n                    for(int y=0; y<D; y++) if(Sol[k][x][y][z] != 0) { covered = true; break; }\n                    if(!covered) {\n                        int best_y = -1;\n                        for(int y=0; y<D; y++) if(Valid[k][x][y][z] && !Used[k][x][y][z]) { best_y = y; break; }\n                        if(best_y != -1) {\n                            int share_x=-1, share_y=-1, share_z=-1;\n                            int other = 1-k;\n                            for(const auto& p : free_cells[other]) if(!Used[other][p.x][p.y][p.z]) { share_x=p.x; share_y=p.y; share_z=p.z; break; }\n                            if(share_x != -1) {\n                                mark_used(k, x, best_y, z); Sol[k][x][best_y][z] = block_id;\n                                mark_used(other, share_x, share_y, share_z); Sol[other][share_x][share_y][share_z] = block_id;\n                                block_id++;\n                            } else {\n                                mark_used(k, x, best_y, z); Sol[k][x][best_y][z] = block_id;\n                                block_id++;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        for(int z=0; z<D; z++) {\n            for(int y=0; y<D; y++) {\n                if(R[k][z][y]) {\n                    bool covered = false;\n                    for(int x=0; x<D; x++) if(Sol[k][x][y][z] != 0) { covered = true; break; }\n                    if(!covered) {\n                        int best_x = -1;\n                        for(int x=0; x<D; x++) if(Valid[k][x][y][z] && !Used[k][x][y][z]) { best_x = x; break; }\n                        if(best_x != -1) {\n                            int share_x=-1, share_y=-1, share_z=-1;\n                            int other = 1-k;\n                            for(const auto& p : free_cells[other]) if(!Used[other][p.x][p.y][p.z]) { share_x=p.x; share_y=p.y; share_z=p.z; break; }\n                            if(share_x != -1) {\n                                mark_used(k, best_x, y, z); Sol[k][best_x][y][z] = block_id;\n                                mark_used(other, share_x, share_y, share_z); Sol[other][share_x][share_y][share_z] = block_id;\n                                block_id++;\n                            } else {\n                                mark_used(k, best_x, y, z); Sol[k][best_x][y][z] = block_id;\n                                block_id++;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    };\n    \n    cover(0);\n    cover(1);\n    \n    cout << block_id - 1 << \"\\n\";\n    for(int k=0; k<2; k++) {\n        bool first = true;\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(!first) cout << \" \";\n                    cout << Sol[k][x][y][z];\n                    first = false;\n                }\n            }\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc020":"/*\n * Optimized Solution for AHC020\n * - Fast SA with incremental updates and O(1) resident removal\n * - Post-SA local search for refinement\n * - Robust constraint handling\n */\n#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <chrono>\n#include <iomanip>\n\nusing namespace std;\n\n#pragma GCC optimize(\"O3,unroll-loops\")\n\nconst int MAX_N = 105;\nconst int MAX_K = 5005;\nconst int MAX_M = 305;\n\nstruct Point { int x, y; };\nstruct Edge { int u, v; int w; int id; };\n\nPoint pts[MAX_N];\nPoint residents[MAX_K];\nEdge edges[MAX_M];\n\ndouble dists[MAX_N][MAX_K];\nint sorted_vertices[MAX_K][MAX_N]; \n\nstruct AdjEdge { int to; int id; };\nvector<AdjEdge> adj[MAX_N];\nint sorted_edge_indices[MAX_M];\n\n// State\nint active[MAX_N]; \nint assignment[MAX_K]; \ndouble resident_dist[MAX_K]; \nint resident_pos[MAX_K]; \nvector<int> residents_at[MAX_N]; \ndouble max_radius[MAX_N]; \n\n// MST Helper\nint parent[MAX_N];\nint find_set(int v) { return v == parent[v] ? v : parent[v] = find_set(parent[v]); }\nbool union_sets(int a, int b) {\n    a = find_set(a); b = find_set(b);\n    if (a != b) { parent[b] = a; return true; }\n    return false;\n}\n\n// Connectivity\nint q_bfs[MAX_N];\nbool vis_bfs[MAX_N];\nint N, M, K;\n\nbool is_connected() {\n    int active_cnt = 0;\n    for(int i=0; i<N; ++i) if(active[i]) active_cnt++;\n    if (active_cnt <= 1) return true; \n    \n    int head = 0, tail = 0;\n    for(int i=0; i<N; ++i) vis_bfs[i] = false;\n    \n    q_bfs[tail++] = 0;\n    vis_bfs[0] = true;\n    int count = 1;\n    \n    while(head < tail){\n        int u = q_bfs[head++];\n        for(auto& edge : adj[u]){\n            int v = edge.to;\n            if(active[v] && !vis_bfs[v]){\n                vis_bfs[v] = true;\n                count++;\n                q_bfs[tail++] = v;\n            }\n        }\n    }\n    return count == active_cnt;\n}\n\nlong long compute_mst() {\n    for(int i=0; i<N; ++i) parent[i] = i;\n    long long cost = 0;\n    int edges_used = 0;\n    int local_active = 0;\n    for(int i=0; i<N; ++i) if(active[i]) local_active++;\n    \n    if (local_active <= 1) return 0;\n    for (int i = 0; i < M; ++i) {\n        int idx = sorted_edge_indices[i];\n        const auto& e = edges[idx];\n        if (active[e.u] && active[e.v]) {\n            if (union_sets(e.u, e.v)) {\n                cost += e.w;\n                edges_used++;\n                if (edges_used == local_active - 1) break;\n            }\n        }\n    }\n    return (edges_used == local_active - 1) ? cost : -1; \n}\n\nvoid recompute_max_radius(int u) {\n    double m = 0.0;\n    for(int k : residents_at[u]) if(resident_dist[k] > m) m = resident_dist[k];\n    max_radius[u] = m;\n}\n\nvoid move_resident(int k, int old_u, int new_u) {\n    if (old_u == new_u) return;\n    \n    auto& old_list = residents_at[old_u];\n    int idx = resident_pos[k];\n    int last_k = old_list.back();\n    \n    old_list[idx] = last_k;\n    resident_pos[last_k] = idx;\n    old_list.pop_back();\n    \n    if (dists[old_u][k] >= max_radius[old_u] - 1e-9) {\n        recompute_max_radius(old_u);\n    }\n    \n    residents_at[new_u].push_back(k);\n    resident_pos[k] = (int)residents_at[new_u].size() - 1;\n    assignment[k] = new_u;\n    resident_dist[k] = dists[new_u][k];\n    \n    if (dists[new_u][k] > max_radius[new_u]) {\n        max_radius[new_u] = dists[new_u][k];\n    }\n}\n\ndouble compute_radii_cost() {\n    double cost = 0.0;\n    for(int i=0; i<N; ++i){\n        if(active[i]){\n            double r = max_radius[i];\n            if (r > 5000.0) r = 5000.0;\n            int p = (int)ceil(r - 1e-9);\n            if (p < 0) p = 0;\n            if (p > 5000) p = 5000;\n            cost += (double)p * p;\n        }\n    }\n    return cost;\n}\n\nstruct StateSnapshot {\n    vector<int> active;\n    vector<int> assignment;\n    vector<double> resident_dist;\n    vector<int> resident_pos;\n    vector<vector<int>> residents_at;\n    vector<double> max_radius;\n    double cost;\n};\n\nStateSnapshot snapshot_state() {\n    StateSnapshot s;\n    s.active.assign(active, active + N);\n    s.assignment.assign(assignment, assignment + K);\n    s.resident_dist.assign(resident_dist, resident_dist + K);\n    s.resident_pos.assign(resident_pos, resident_pos + K);\n    s.residents_at.assign(residents_at, residents_at + N);\n    s.max_radius.assign(max_radius, max_radius + N);\n    s.cost = compute_mst() + compute_radii_cost();\n    return s;\n}\n\nvoid apply_state(const StateSnapshot& s) {\n    copy(s.active.begin(), s.active.end(), active);\n    copy(s.assignment.begin(), s.assignment.end(), assignment);\n    copy(s.resident_dist.begin(), s.resident_dist.end(), resident_dist);\n    copy(s.resident_pos.begin(), s.resident_pos.end(), resident_pos);\n    for(int i=0; i<N; ++i) residents_at[i] = s.residents_at[i];\n    copy(s.max_radius.begin(), s.max_radius.end(), max_radius);\n}\n\nvoid local_search(double& cur_cost) {\n    bool improved = true;\n    while(improved) {\n        improved = false;\n        // Try removing stations\n        vector<int> stations;\n        for(int i=0; i<N; ++i) if(active[i] && i != 0) stations.push_back(i);\n        shuffle(stations.begin(), stations.end(), mt19937_64(random_device{}()));\n        \n        for(int u : stations) {\n            if (!active[u]) continue;\n            StateSnapshot backup = snapshot_state();\n            \n            active[u] = 0;\n            if (!is_connected()) {\n                active[u] = 1;\n                continue;\n            }\n            \n            vector<int> to_move;\n            for(int k : residents_at[u]) to_move.push_back(k);\n            bool ok = true;\n            vector<int> new_pos;\n            \n            for(int k : to_move) {\n                int best_v = -1;\n                double best_d = 1e18;\n                for(int j=0; j<N; ++j){\n                    int v = sorted_vertices[k][j];\n                    if(active[v]){ best_v = v; best_d = dists[v][k]; break; }\n                }\n                if(best_v == -1 || best_d > 5000.0) { ok = false; break; }\n                move_resident(k, u, best_v);\n                new_pos.push_back(best_v);\n            }\n            \n            if(ok) {\n                long long mst = compute_mst();\n                if(mst != -1) {\n                    double radii = compute_radii_cost();\n                    double new_cost = mst + radii;\n                    if(new_cost < cur_cost - 1e-6) {\n                        cur_cost = new_cost;\n                        improved = true;\n                        continue;\n                    }\n                }\n            }\n            apply_state(backup);\n        }\n        \n        // Try adding stations\n        for(int u=0; u<N; ++u) {\n            if(active[u]) continue;\n            bool helps = false;\n            for(int k=0; k<K; ++k) if(dists[u][k] < resident_dist[k]) { helps = true; break; }\n            if(!helps) continue;\n            \n            StateSnapshot backup = snapshot_state();\n            active[u] = 1;\n            vector<int> moved_k;\n            vector<int> moved_from;\n            \n            for(int k=0; k<K; ++k) {\n                if(dists[u][k] < resident_dist[k]) {\n                    move_resident(k, assignment[k], u);\n                    moved_k.push_back(k);\n                    moved_from.push_back(assignment[k]);\n                }\n            }\n            \n            long long mst = compute_mst();\n            if(mst != -1) {\n                double radii = compute_radii_cost();\n                double new_cost = mst + radii;\n                if(new_cost < cur_cost - 1e-6) {\n                    cur_cost = new_cost;\n                    improved = true;\n                    continue;\n                }\n            }\n            apply_state(backup);\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    mt19937_64 rng(chrono::high_resolution_clock::now().time_since_epoch().count());\n\n    if (!(cin >> N >> M >> K)) return 0;\n    for (int i = 0; i < N; ++i) cin >> pts[i].x >> pts[i].y;\n    for (int i = 0; i < M; ++i) {\n        cin >> edges[i].u >> edges[i].v >> edges[i].w;\n        --edges[i].u; --edges[i].v;\n        edges[i].id = i;\n    }\n    for (int i = 0; i < K; ++i) cin >> residents[i].x >> residents[i].y;\n\n    for (int i = 0; i < N; ++i)\n        for (int k = 0; k < K; ++k)\n            dists[i][k] = hypot(pts[i].x - residents[k].x, pts[i].y - residents[k].y);\n\n    int indices[MAX_N];\n    for (int k = 0; k < K; ++k) {\n        for (int i = 0; i < N; ++i) indices[i] = i;\n        sort(indices, indices + N, [&](int a, int b) { return dists[a][k] < dists[b][k]; });\n        for (int i = 0; i < N; ++i) sorted_vertices[k][i] = indices[i];\n    }\n\n    for (int i = 0; i < M; ++i) {\n        adj[edges[i].u].push_back({edges[i].v, i});\n        adj[edges[i].v].push_back({edges[i].u, i});\n    }\n\n    for (int i = 0; i < M; ++i) sorted_edge_indices[i] = i;\n    sort(sorted_edge_indices, sorted_edge_indices + M, [&](int a, int b) { return edges[a].w < edges[b].w; });\n\n    fill(active, active + N, 1);\n    active[0] = 1;\n\n    for (int k = 0; k < K; ++k) {\n        int best_u = sorted_vertices[k][0];\n        assignment[k] = best_u;\n        resident_dist[k] = dists[best_u][k];\n        residents_at[best_u].push_back(k);\n        resident_pos[k] = (int)residents_at[best_u].size() - 1;\n    }\n    for (int u = 0; u < N; ++u) recompute_max_radius(u);\n\n    long long cur_S_mst = compute_mst();\n    double cur_S_radii = compute_radii_cost();\n    double cur_S = cur_S_mst + cur_S_radii;\n    double best_S = cur_S;\n\n    vector<int> best_active(N);\n    copy(active, active + N, best_active.begin());\n    vector<int> best_assignment(K);\n    copy(assignment, assignment + K, best_assignment.begin());\n\n    auto save_best = [&]() {\n        best_S = cur_S;\n        copy(active, active + N, best_active.begin());\n        copy(assignment, assignment + K, best_assignment.begin());\n    };\n\n    uniform_int_distribution<int> dist_u(1, N-1);\n    uniform_real_distribution<double> dist_01(0.0, 1.0);\n    double temp = 1e6;\n    auto start_time = chrono::steady_clock::now();\n\n    vector<int> buffer_k; buffer_k.reserve(K);\n    vector<int> history_target; history_target.reserve(K);\n    vector<int> history_old_u; history_old_u.reserve(K);\n\n    while (true) {\n        double elapsed = chrono::duration_cast<chrono::duration<double>>(chrono::steady_clock::now() - start_time).count();\n        if (elapsed > 1.85) break;\n\n        int u = dist_u(rng);\n        bool was_active = (active[u] == 1);\n        bool accepted = false;\n        buffer_k.clear();\n        history_target.clear();\n        history_old_u.clear();\n\n        if (was_active) {\n            active[u] = 0;\n            if (!is_connected()) { \n                active[u] = 1; \n                continue; \n            }\n\n            const auto& u_list = residents_at[u];\n            for(int k : u_list) buffer_k.push_back(k);\n            \n            bool possible = true;\n            for (int k : buffer_k) {\n                int best_v = -1;\n                double best_d = 1e18;\n                for(int j=0; j<N; ++j){\n                    int v = sorted_vertices[k][j];\n                    if(active[v]){ best_v = v; best_d = dists[v][k]; break; }\n                }\n                if (best_v == -1 || best_d > 5000.0) { possible = false; break; }\n                move_resident(k, u, best_v);\n                history_target.push_back(best_v);\n                history_old_u.push_back(u);\n            }\n\n            if (possible) {\n                long long new_mst = compute_mst();\n                if (new_mst != -1) {\n                    double new_radii = compute_radii_cost();\n                    double new_S = new_mst + new_radii;\n                    double delta = new_S - cur_S;\n                    bool accept = (delta < 0);\n                    if (!accept && delta < 100.0 * temp) accept = dist_01(rng) < exp(-delta / temp);\n                    \n                    if (accept) {\n                        accepted = true;\n                        cur_S = new_S; cur_S_mst = new_mst; cur_S_radii = new_radii;\n                        if (new_S < best_S) save_best();\n                    }\n                }\n            }\n\n            if (!accepted) {\n                int moved = history_target.size();\n                for (int i = moved - 1; i >= 0; --i) {\n                    move_resident(buffer_k[i], history_target[i], history_old_u[i]);\n                }\n                active[u] = 1;\n                cur_S_radii = compute_radii_cost();\n                cur_S = cur_S_mst + cur_S_radii;\n            }\n        } else {\n            bool improves = false;\n            for(int k=0; k<K; ++k) if(dists[u][k] < resident_dist[k]) { improves = true; break; }\n            if (!improves) continue;\n\n            active[u] = 1;\n            for(int k=0; k<K; ++k) {\n                if(dists[u][k] < resident_dist[k]) {\n                    int old_u = assignment[k];\n                    move_resident(k, old_u, u);\n                    buffer_k.push_back(k);\n                    history_target.push_back(old_u); \n                    history_old_u.push_back(u);\n                }\n            }\n            \n            long long new_mst = compute_mst();\n            if (new_mst != -1) {\n                double new_radii = compute_radii_cost();\n                double new_S = new_mst + new_radii;\n                double delta = new_S - cur_S;\n                bool accept = (delta < 0);\n                if (!accept && delta < 100.0 * temp) accept = dist_01(rng) < exp(-delta / temp);\n                \n                if (accept) {\n                    accepted = true;\n                    cur_S = new_S; cur_S_mst = new_mst; cur_S_radii = new_radii;\n                    if (new_S < best_S) save_best();\n                }\n            }\n            \n            if (!accepted) {\n                int moved = history_target.size();\n                for (int i = moved - 1; i >= 0; --i) {\n                    move_resident(buffer_k[i], u, history_target[i]);\n                }\n                active[u] = 0;\n                cur_S_radii = compute_radii_cost();\n                cur_S = cur_S_mst + cur_S_radii;\n            }\n        }\n        temp *= 0.99995;\n        if (temp < 1e-9) temp = 1e-9;\n    }\n\n    // Restore best state\n    copy(best_active.begin(), best_active.end(), active);\n    copy(best_assignment.begin(), best_assignment.end(), assignment);\n    for(int k=0; k<K; ++k) resident_dist[k] = dists[assignment[k]][k];\n    \n    for(int i=0; i<N; ++i) residents_at[i].clear();\n    for (int k = 0; k < K; ++k) {\n        residents_at[assignment[k]].push_back(k);\n        resident_pos[k] = (int)residents_at[assignment[k]].size() - 1;\n    }\n    for (int u = 0; u < N; ++u) recompute_max_radius(u);\n    cur_S_mst = compute_mst();\n    cur_S_radii = compute_radii_cost();\n    best_S = cur_S_mst + cur_S_radii;\n\n    // Local search refinement\n    local_search(best_S);\n    \n    // Final reconstruction\n    for(int i=0; i<N; ++i) parent[i] = i;\n    vector<int> edge_used(M, 0);\n    for (int i = 0; i < M; ++i) {\n        int idx = sorted_edge_indices[i];\n        const auto& e = edges[idx];\n        if (active[e.u] && active[e.v])\n            if (union_sets(e.u, e.v)) edge_used[idx] = 1;\n    }\n    \n    cout << fixed << setprecision(0);\n    for (int i = 0; i < N; ++i) {\n        int p = 0;\n        if (active[i]) {\n            double r = max_radius[i];\n            if (r > 5000.0) r = 5000.0;\n            p = (int)ceil(r - 1e-9);\n            if (p < 0) p = 0;\n            if (p > 5000) p = 5000;\n        }\n        cout << p << (i == N-1 ? \"\" : \" \");\n    }\n    cout << \"\\n\";\n    for (int i = 0; i < M; ++i) cout << edge_used[i] << (i == M-1 ? \"\" : \" \");\n    cout << \"\\n\";\n\n    return 0;\n}","ahc021":"#pragma GCC optimize(\"O3,unroll-loops,fast-math\")\n#include <iostream>\n#include <algorithm>\n#include <chrono>\n#include <cstring>\n#include <vector>\n#include <cmath>\n\nusing namespace std;\n\n// Constants\nconst int N = 30;\nconst int TOTAL = 465;\n\n// Global arrays\nint init_grid[TOTAL];\nint x_coord[TOTAL];\nint y_coord[TOTAL];\nint child1_idx[TOTAL];\nint level_nodes[N][N];\nint level_counts[N];\n\n// Permutation: perm[x] stores the order of processing nodes at level x.\nint perm[30][30]; \n\n// Cache for grid states\n// cache[k] stores the grid state AFTER processing level k.\n// cache[N-1] is the initial state (before processing any level).\nint cache[31][TOTAL];\n\n// Cost cache\n// cost_cache[k] stores accumulated cost of sifting levels N-2 down to k.\nint cost_cache[31];\n\n// Best solution\nint best_score = 100000;\nint best_perm[30][30];\n\n// RNG\nunsigned int rng_s[4] = {1, 2, 3, 4};\ninline unsigned int fast_rand() {\n    unsigned int result = (rng_s[0] + rng_s[3]);\n    result = (result << 7) | (result >> 25);\n    result += rng_s[0];\n    unsigned int t = rng_s[1] << 9;\n    rng_s[2] ^= rng_s[0]; rng_s[3] ^= rng_s[1];\n    rng_s[1] ^= rng_s[2]; rng_s[0] ^= rng_s[3];\n    rng_s[2] ^= t;\n    rng_s[3] = (rng_s[3] << 11) | (rng_s[3] >> 21);\n    return result;\n}\n\n// Sift down a single node\ninline int sift_node(int* grid, int node_idx, int level) {\n    int curr = node_idx;\n    int curr_level = level;\n    int swaps = 0;\n    while (curr_level < N - 1) {\n        int c1 = child1_idx[curr];\n        int c2 = c1 + 1;\n        int v1 = grid[c1];\n        int v2 = grid[c2];\n        int target = (v1 < v2) ? c1 : c2;\n        int v_target = (v1 < v2) ? v1 : v2;\n        \n        if (grid[curr] > v_target) {\n            int temp = grid[curr];\n            grid[curr] = v_target;\n            grid[target] = temp;\n            swaps++;\n            curr = target;\n            curr_level++;\n        } else {\n            break;\n        }\n    }\n    return swaps;\n}\n\n// Process a single level\ninline int process_level(int* grid, int x) {\n    int count = level_counts[x];\n    int* p = perm[x];\n    int level_swaps = 0;\n    for (int i = 0; i < count; ++i) {\n        level_swaps += sift_node(grid, p[i], x);\n    }\n    return level_swaps;\n}\n\n// Run full heapify to initialize cache\nint run_full_heapify() {\n    memcpy(cache[N-1], init_grid, sizeof(init_grid));\n    cost_cache[N-1] = 0;\n    \n    int total_swaps = 0;\n    for (int x = N - 2; x >= 0; --x) {\n        memcpy(cache[x], cache[x+1], sizeof(init_grid));\n        int swaps = process_level(cache[x], x);\n        cost_cache[x] = cost_cache[x+1] + swaps;\n        total_swaps += swaps;\n    }\n    return cost_cache[0];\n}\n\n// Evaluate a move (swap i, j in perm[L])\n// Returns new score. Does not modify global state permanently.\nint evaluate_move(int L, int i, int j) {\n    int temp_grid[TOTAL];\n    // Start from the state after level L+1 (which is valid in cache)\n    memcpy(temp_grid, cache[L+1], sizeof(init_grid));\n    \n    int current_cost = cost_cache[L+1];\n    \n    // Temporarily swap in perm\n    int tmp = perm[L][i];\n    perm[L][i] = perm[L][j];\n    perm[L][j] = tmp;\n    \n    // Process level L with new order\n    current_cost += process_level(temp_grid, L);\n    \n    // Process lower levels (L-1 down to 0)\n    for (int x = L - 1; x >= 0; --x) {\n        current_cost += process_level(temp_grid, x);\n    }\n    \n    // Restore swap\n    tmp = perm[L][i];\n    perm[L][i] = perm[L][j];\n    perm[L][j] = tmp;\n    \n    return current_cost;\n}\n\n// Update cache after accepting a move at level L\n// Assumes perm[L] has already been updated by caller.\nvoid update_cache(int L) {\n    // Recompute from L down to 0\n    memcpy(cache[L], cache[L+1], sizeof(init_grid));\n    int swaps = process_level(cache[L], L);\n    cost_cache[L] = cost_cache[L+1] + swaps;\n    \n    for (int x = L - 1; x >= 0; --x) {\n        memcpy(cache[x], cache[x+1], sizeof(init_grid));\n        swaps = process_level(cache[x], x);\n        cost_cache[x] = cost_cache[x+1] + swaps;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Seed RNG\n    auto seed = chrono::steady_clock::now().time_since_epoch().count();\n    rng_s[0] = (unsigned int)seed;\n    rng_s[1] = (unsigned int)(seed >> 32) ^ 0x9e3779b9;\n    rng_s[2] = 0x3c6ef372;\n    rng_s[3] = 0x79e262eb;\n\n    int idx = 0;\n    for (int x = 0; x < N; ++x) {\n        for (int y = 0; y <= x; ++y) {\n            cin >> init_grid[idx];\n            x_coord[idx] = x;\n            y_coord[idx] = y;\n            if (x + 1 < N) child1_idx[idx] = (x + 1) * (x + 2) / 2 + y;\n            idx++;\n        }\n    }\n\n    idx = 0;\n    for (int x = 0; x < N; ++x) {\n        level_counts[x] = x + 1;\n        for (int y = 0; y <= x; ++y) {\n            level_nodes[x][y] = idx;\n            perm[x][y] = idx; // Default order\n            idx++;\n        }\n    }\n\n    // Heuristic initialization: Value Descending (process larger values first)\n    int temp_nodes[30];\n    for (int x = 0; x < N; ++x) {\n        int count = level_counts[x];\n        for(int k=0; k<count; ++k) temp_nodes[k] = level_nodes[x][k];\n        sort(temp_nodes, temp_nodes + count, [](int a, int b) { return init_grid[a] > init_grid[b]; });\n        for(int k=0; k<count; ++k) perm[x][k] = temp_nodes[k];\n    }\n\n    // Initialize cache and baseline score\n    best_score = run_full_heapify();\n    memcpy(best_perm, perm, sizeof(perm));\n\n    // Simulated Annealing\n    auto start_time = chrono::steady_clock::now();\n    auto end_time = start_time + std::chrono::milliseconds(1900);\n    \n    double temperature = 100.0;\n    double cooling_rate = 0.99995;\n    \n    while (chrono::steady_clock::now() < end_time) {\n        // Pick random level L (0 to N-2)\n        int L = fast_rand() % (N - 1);\n        int count = level_counts[L];\n        if (count < 2) continue; // Cannot swap if only 1 node\n\n        // Pick two distinct indices\n        int i = fast_rand() % count;\n        int j = fast_rand() % count;\n        while (i == j) j = fast_rand() % count;\n\n        // Evaluate move\n        int new_score = evaluate_move(L, i, j);\n        int current_score = cost_cache[0];\n        int delta = new_score - current_score;\n\n        if (delta < 0) {\n            // Accept improvement\n            int tmp = perm[L][i];\n            perm[L][i] = perm[L][j];\n            perm[L][j] = tmp;\n            update_cache(L);\n            if (new_score < best_score) {\n                best_score = new_score;\n                memcpy(best_perm, perm, sizeof(perm));\n            }\n        } else {\n            // Accept worse with probability\n            if (temperature > 0.01) {\n                double prob = exp(-delta / temperature);\n                if ((double)fast_rand() / 4294967295.0 < prob) {\n                    int tmp = perm[L][i];\n                    perm[L][i] = perm[L][j];\n                    perm[L][j] = tmp;\n                    update_cache(L);\n                }\n            }\n        }\n        temperature *= cooling_rate;\n    }\n\n    // Replay best solution to generate output\n    int replay_grid[TOTAL];\n    memcpy(replay_grid, init_grid, sizeof(init_grid));\n    vector<pair<int, int>> ops;\n    ops.reserve(10000);\n\n    for (int x = N - 2; x >= 0; --x) {\n        int count = level_counts[x];\n        int* p = best_perm[x];\n        for (int i = 0; i < count; ++i) {\n            int curr = p[i];\n            int curr_level = x;\n            while (curr_level < N - 1) {\n                int c1 = child1_idx[curr];\n                int c2 = c1 + 1;\n                int v1 = replay_grid[c1];\n                int v2 = replay_grid[c2];\n                int target = (v1 < v2) ? c1 : c2;\n                int v_target = (v1 < v2) ? v1 : v2;\n                \n                if (replay_grid[curr] > v_target) {\n                    if (ops.size() < 10000) {\n                        ops.push_back({curr, target});\n                    }\n                    int temp = replay_grid[curr];\n                    replay_grid[curr] = v_target;\n                    replay_grid[target] = temp;\n                    curr = target;\n                    curr_level++;\n                } else {\n                    break;\n                }\n            }\n        }\n    }\n\n    cout << ops.size() << \"\\n\";\n    for (const auto& op : ops) {\n        cout << x_coord[op.first] << \" \" << y_coord[op.first] << \" \" \n             << x_coord[op.second] << \" \" << y_coord[op.second] << \"\\n\";\n    }\n\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\n#include <cmath>\nusing namespace std;\n\n// Global variables\nint D, N;\nint grid[12][12]; // 0: empty, -1: obstacle, -2: entrance, -3: blocked (temp), >0: container (id+1)\nint er, ec;\nint dr[4] = {-1, 1, 0, 0};\nint dc[4] = {0, 0, -1, 1};\npair<int, int> placed[100];\n\nbool valid(int r, int c) { return r >= 0 && r < D && c >= 0 && c < D; }\n\n// BFS to count reachable empty cells from entrance\nint count_reachable_empty() {\n    int count = 0;\n    bool vis[12][12] = {};\n    queue<pair<int, int>> q;\n    q.push({er, ec});\n    vis[er][ec] = true;\n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        if (grid[r][c] == 0) count++;\n        for (int i = 0; i < 4; i++) {\n            int nr = r + dr[i], nc = c + dc[i];\n            if (valid(nr, nc) && !vis[nr][nc] && (grid[nr][nc] == 0 || grid[nr][nc] == -2)) {\n                vis[nr][nc] = true;\n                q.push({nr, nc});\n            }\n        }\n    }\n    return count;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> D >> N)) return 0;\n    er = 0; ec = (D - 1) / 2;\n    memset(grid, 0, sizeof(grid));\n    grid[er][ec] = -2;\n    for (int i = 0; i < N; i++) { int r, c; cin >> r >> c; grid[r][c] = -1; }\n    int M = D * D - 1 - N;\n\n    // Placement Phase\n    for (int d = 0; d < M; d++) {\n        int t; cin >> t;\n\n        // Find reachable empty squares and distances\n        vector<pair<int, int>> R;\n        vector<vector<int>> dist(D, vector<int>(D, -1));\n        bool vis[12][12] = {};\n        queue<pair<int, int>> q;\n        q.push({er, ec}); vis[er][ec] = true; dist[er][ec] = 0;\n        while(!q.empty()){\n            auto [r, c] = q.front(); q.pop();\n            if(grid[r][c] == 0) R.push_back({r, c});\n            for(int i=0; i<4; ++i){\n                int nr = r + dr[i], nc = c + dc[i];\n                if(valid(nr, nc) && !vis[nr][nc] && (grid[nr][nc] == 0 || grid[nr][nc] == -2)){\n                    vis[nr][nc] = true; dist[nr][nc] = dist[r][c] + 1; q.push({nr, nc});\n                }\n            }\n        }\n\n        int total_empty = R.size();\n        struct Cand { int r, c, dist, openness; };\n        vector<Cand> safe, all;\n        safe.reserve(R.size()); all.reserve(R.size());\n\n        for(auto [r, c] : R){\n            int en = 0;\n            for(int i=0; i<4; ++i) if(valid(r+dr[i], c+dc[i]) && grid[r+dr[i]][c+dc[i]] == 0) en++;\n            Cand cand = {r, c, dist[r][c], en};\n            all.push_back(cand);\n\n            grid[r][c] = -3;\n            if(count_reachable_empty() == total_empty - 1) safe.push_back(cand);\n            grid[r][c] = 0;\n        }\n        \n        const vector<Cand>& cands = safe.empty() ? all : safe;\n        vector<Cand> sorted_cands = cands;\n        sort(sorted_cands.begin(), sorted_cands.end(), [](const Cand& a, const Cand& b){\n            if(a.dist != b.dist) return a.dist < b.dist;\n            return a.openness > b.openness;\n        });\n        \n        // Map container ID to position using power bias\n        int idx = 0;\n        if(sorted_cands.size() > 1 && M > 1) idx = (int)(pow((double)t / (M - 1), 0.5) * (sorted_cands.size() - 1));\n        idx = max(0, min(idx, (int)sorted_cands.size() - 1));\n        \n        auto chosen = sorted_cands[idx];\n        grid[chosen.r][chosen.c] = t + 1;\n        placed[t] = {chosen.r, chosen.c};\n        cout << chosen.r << \" \" << chosen.c << \"\\n\" << flush;\n    }\n\n    // Retrieval Phase with 1-step lookahead heuristic\n    vector<bool> retrieved(M, false);\n    for(int k=0; k<M; ++k){\n        // Find reachable empty squares\n        bool vis[12][12] = {};\n        queue<pair<int, int>> q;\n        q.push({er, ec}); vis[er][ec] = true;\n        vector<pair<int, int>> R;\n        while(!q.empty()){\n            auto [r, c] = q.front(); q.pop();\n            if(grid[r][c] == 0) R.push_back({r, c});\n            for(int i=0; i<4; ++i){\n                int nr = r + dr[i], nc = c + dc[i];\n                if(valid(nr, nc) && !vis[nr][nc] && (grid[nr][nc] == 0 || grid[nr][nc] == -2)){\n                    vis[nr][nc] = true; q.push({nr, nc});\n                }\n            }\n        }\n        \n        // Identify currently retrievable containers\n        vector<int> S; bool seen[100] = {};\n        auto check = [&](int r, int c){\n            if(valid(r, c) && grid[r][c] > 0){\n                int id = grid[r][c] - 1;\n                if(!retrieved[id] && !seen[id]){ seen[id]=true; S.push_back(id); }\n            }\n        };\n        for(int i=0; i<4; ++i) check(er+dr[i], ec+dc[i]);\n        for(auto [r, c] : R) for(int i=0; i<4; ++i) check(r+dr[i], c+dc[i]);\n        \n        int best_x = -1;\n        double best_sc = 1e18;\n        \n        // Evaluate each retrievable container\n        for(int x : S){\n            int r = placed[x].first, c = placed[x].second;\n            grid[r][c] = 0; // Simulate removal\n            \n            // Find the smallest ID reachable in the next state\n            // This includes items that were already reachable (except x) and newly unlocked items\n            int next_min = 1e9;\n            bool vis2[12][12] = {};\n            queue<pair<int, int>> q2;\n            q2.push({er, ec}); vis2[er][ec] = true;\n            while(!q2.empty()){\n                auto [cr, cc] = q2.front(); q2.pop();\n                for(int i=0; i<4; ++i){\n                    int nr = cr + dr[i], nc = cc + dc[i];\n                    if(valid(nr, nc) && !vis2[nr][nc]){\n                        if(grid[nr][nc] == 0 || grid[nr][nc] == -2){\n                            vis2[nr][nc] = true; q2.push({nr, nc});\n                        } else if(grid[nr][nc] > 0){\n                            int id = grid[nr][nc] - 1;\n                            if(!retrieved[id] && id < next_min){\n                                next_min = id;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            // Heuristic: Score = current_id + 0.9 * smallest_reachable_in_next_state\n            // This balances the cost of picking x now with the benefit of having a small item available next.\n            double sc = x + (next_min == 1e9 ? 0 : next_min * 0.9);\n            \n            // Pick best candidate: minimize score, then minimize ID for ties\n            if(sc < best_sc - 1e-9 || (abs(sc - best_sc) <= 1e-9 && x < best_x)){\n                best_sc = sc; best_x = x;\n            }\n            grid[r][c] = x + 1; // Restore\n        }\n        \n        if(best_x != -1){\n            retrieved[best_x] = true;\n            auto [r, c] = placed[best_x];\n            grid[r][c] = 0;\n            cout << r << \" \" << c << \"\\n\" << flush;\n        }\n    }\n    return 0;\n}","ahc024":"/*\n    Problem: AHC024 - Map Reduction\n    Goal: Maximize number of 0 cells (E) while preserving connectivity and adjacencies.\n    Strategy: Multi-Start Greedy Search with Dynamic Heuristic & Fast Rollback.\n    \n    Key Fixes from previous failure:\n    1. Ensure 'vis' array is cleared before every BFS call in check_connect.\n    2. Use explicit struct for Candidates to avoid packing errors.\n    3. Verify rollback logic for contacts matrix.\n*/\n#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\n\n// Constants\nconst int MAXN = 54; // 50 + 2 padding\nconst int MAXM = 105;\n\n// Global State\nint grid[MAXN][MAXN];\nint initial_grid[MAXN][MAXN];\nint best_grid[MAXN][MAXN];\nint contacts[MAXM][MAXM];\nbool adj_target[MAXM][MAXM];\nint cnt[MAXM];\nint n, m;\n\n// Directions\nconst int dr[] = {0, 1, 0, -1};\nconst int dc[] = {1, 0, -1, 0};\n\nstruct Candidate {\n    int r, c, color, score;\n};\n\nstruct Change {\n    int u, v, delta;\n};\n\n// Connectivity Check\n// Checks if 'color' remains connected after removing (r,c).\n// Assumes grid[r][c] is tentatively 0.\nbool check_connect(int color, int r, int c) {\n    int target = cnt[color] - 1;\n    if (target <= 1) return true;\n    \n    // Find a starting neighbor of the same color\n    int sr = -1, sc = -1;\n    for (int k = 0; k < 4; ++k) {\n        int nr = r + dr[k], nc = c + dc[k];\n        if (grid[nr][nc] == color) {\n            sr = nr; sc = nc;\n            break;\n        }\n    }\n    if (sr == -1) return false;\n\n    // BFS\n    static int q_r[MAXN * MAXN], q_c[MAXN * MAXN];\n    static bool vis[MAXN][MAXN];\n    // FIX: Clear visited array every time to prevent stale data\n    memset(vis, 0, sizeof(vis));\n    \n    int head = 0, tail = 0;\n    q_r[tail] = sr; q_c[tail] = sc; tail++;\n    vis[sr][sc] = true;\n    int reached = 0;\n    \n    while(head < tail) {\n        int cr = q_r[head], cc = q_c[head]; head++;\n        reached++;\n        if (reached == target) return true;\n        \n        for (int k = 0; k < 4; ++k) {\n            int nr = cr + dr[k], nc = cc + dc[k];\n            // Valid if color matches, not the removed cell, and not visited\n            if (grid[nr][nc] == color && !(nr == r && nc == c) && !vis[nr][nc]) {\n                vis[nr][nc] = true;\n                q_r[tail] = nr; q_c[tail] = nc; tail++;\n            }\n        }\n    }\n    return false;\n}\n\n// Reset state to initial configuration\nvoid init_state() {\n    memcpy(grid, initial_grid, sizeof(initial_grid));\n    memset(contacts, 0, sizeof(contacts));\n    memset(cnt, 0, sizeof(cnt));\n    \n    for (int i = 1; i <= n; ++i)\n        for (int j = 1; j <= n; ++j)\n            if (grid[i][j] > 0) cnt[grid[i][j]]++;\n            \n    // Compute contacts on padded grid\n    for (int i = 0; i <= n + 1; ++i) {\n        for (int j = 0; j <= n + 1; ++j) {\n            int dirs[2][2] = {{0, 1}, {1, 0}};\n            for(auto& d : dirs) {\n                int ni = i + d[0], nj = j + d[1];\n                if (ni <= n + 1 && nj <= n + 1) {\n                    int u = grid[i][j], v = grid[ni][nj];\n                    if (u != v) {\n                        if (u > v) swap(u, v);\n                        contacts[u][v]++;\n                    }\n                }\n            }\n        }\n    }\n}\n\nint solve_greedy(mt19937 &rng) {\n    init_state();\n    \n    vector<Candidate> candidates;\n    candidates.reserve(2500);\n    bool changed = true;\n    \n    Change changes[10];\n    \n    while (changed) {\n        changed = false;\n        candidates.clear();\n        \n        // Scan for candidates\n        for (int i = 1; i <= n; ++i) {\n            for (int j = 1; j <= n; ++j) {\n                int col = grid[i][j];\n                if (col == 0) continue;\n                if (cnt[col] <= 1) continue;\n                \n                bool adj0 = false;\n                int same_nb = 0;\n                int unlock = 0;\n                int crit = 0;\n                \n                for (int k = 0; k < 4; ++k) {\n                    int ni = i + dr[k], nj = j + dc[k];\n                    int x = grid[ni][nj];\n                    if (x == 0) adj0 = true;\n                    if (x == col) {\n                        same_nb++;\n                        // Check if neighbor is \"locked\" (no other 0 neighbors)\n                        bool locked = true;\n                        for (int kk = 0; kk < 4; ++kk) {\n                            int nni = ni + dr[kk], nnj = nj + dc[kk];\n                            if (grid[nni][nnj] == 0) { locked = false; break; }\n                        }\n                        if (locked) unlock++;\n                    }\n                }\n                \n                if (!adj0) continue;\n                \n                // Check critical adjacencies\n                for (int k = 0; k < 4; ++k) {\n                    int ni = i + dr[k], nj = j + dc[k];\n                    int x = grid[ni][nj];\n                    if (x == 0) {\n                        if (contacts[0][col] == 1) crit++;\n                    } else if (x != col) {\n                        int u = min(col, x), v = max(col, x);\n                        if (contacts[u][v] == 1) crit++;\n                    }\n                }\n                \n                // Heuristic Score\n                int score = 0;\n                if (same_nb == 1) score += 2000; // Leaf (safe)\n                else if (same_nb == 2) score += 500;\n                \n                score += unlock * 500; // Unlocking potential\n                score -= crit * 5000;  // Penalize breaking critical links\n                score += (int)(rng() % 100); // Random noise\n                \n                candidates.push_back({i, j, col, score});\n            }\n        }\n        \n        if (candidates.empty()) break;\n        \n        // Sort candidates by score descending\n        sort(candidates.begin(), candidates.end(), [](const Candidate& a, const Candidate& b) {\n            return a.score > b.score;\n        });\n        \n        // Try best candidate\n        bool success = false;\n        for (const auto& cand : candidates) {\n            int r = cand.r, c = cand.c, col = cand.color;\n            \n            // Re-validate\n            if (grid[r][c] != col || cnt[col] <= 1) continue;\n            \n            // Connectivity Check\n            int s_nb = 0;\n            for(int k=0; k<4; ++k) if(grid[r+dr[k]][c+dc[k]] == col) s_nb++;\n            \n            grid[r][c] = 0; // Tentative removal\n            bool conn_ok = false;\n            if (s_nb <= 1) conn_ok = true;\n            else conn_ok = check_connect(col, r, c);\n            \n            if (!conn_ok) {\n                grid[r][c] = col; // Restore\n                continue;\n            }\n            \n            // Adjacency Check with Atomic Rollback\n            int ch_cnt = 0;\n            bool fail = false;\n            \n            for (int k = 0; k < 4; ++k) {\n                int nr = r + dr[k], nc = c + dc[k];\n                int x = grid[nr][nc];\n                \n                if (x == col) {\n                    // (col, col) -> (0, col)\n                    contacts[0][col]++;\n                    changes[ch_cnt++] = {0, col, 1};\n                    if (contacts[0][col] == 1 && !adj_target[0][col]) { fail = true; break; }\n                } else if (x == 0) {\n                    // (col, 0) -> (0, 0)\n                    contacts[0][col]--;\n                    changes[ch_cnt++] = {0, col, -1};\n                    if (contacts[0][col] == 0 && adj_target[0][col]) { fail = true; break; }\n                } else {\n                    // (col, x) -> (0, x)\n                    int u1 = min(col, x), v1 = max(col, x);\n                    contacts[u1][v1]--;\n                    changes[ch_cnt++] = {u1, v1, -1};\n                    if (contacts[u1][v1] == 0 && adj_target[u1][v1]) { fail = true; break; }\n                    \n                    contacts[0][x]++;\n                    changes[ch_cnt++] = {0, x, 1};\n                    if (contacts[0][x] == 1 && !adj_target[0][x]) { fail = true; break; }\n                }\n            }\n            \n            if (fail) {\n                // Rollback\n                grid[r][c] = col;\n                for (int i = ch_cnt - 1; i >= 0; --i) {\n                    contacts[changes[i].u][changes[i].v] -= changes[i].delta;\n                }\n                continue;\n            }\n            \n            // Success: Commit changes\n            cnt[col]--;\n            changed = true;\n            success = true;\n            break; \n        }\n        // If no move was made despite candidates, break\n        if (!success) break;\n    }\n    \n    int score = 0;\n    for (int i = 1; i <= n; ++i)\n        for (int j = 1; j <= n; ++j)\n            if (grid[i][j] == 0) score++;\n    return score;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    auto start_time = chrono::steady_clock::now();\n    \n    if (!(cin >> n >> m)) return 0;\n    \n    // Initialize padded grid\n    memset(initial_grid, 0, sizeof(initial_grid));\n    for (int i = 1; i <= n; ++i)\n        for (int j = 1; j <= n; ++j)\n            cin >> initial_grid[i][j];\n            \n    // Precompute target adjacencies\n    memset(adj_target, 0, sizeof(adj_target));\n    for (int i = 0; i <= n + 1; ++i) {\n        for (int j = 0; j <= n + 1; ++j) {\n            int dirs[2][2] = {{0, 1}, {1, 0}};\n            for(auto& d : dirs) {\n                int ni = i + d[0], nj = j + d[1];\n                if (ni <= n + 1 && nj <= n + 1) {\n                    int u = initial_grid[i][j], v = initial_grid[ni][nj];\n                    if (u != v) {\n                        if (u > v) swap(u, v);\n                        adj_target[u][v] = true;\n                    }\n                }\n            }\n        }\n    }\n    \n    int best_score = 0;\n    memcpy(best_grid, initial_grid, sizeof(initial_grid));\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    // Multi-start loop\n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() < 1900) {\n        int sc = solve_greedy(rng);\n        if (sc > best_score) {\n            best_score = sc;\n            memcpy(best_grid, grid, sizeof(grid));\n        }\n    }\n    \n    for (int i = 1; i <= n; ++i) {\n        for (int j = 1; j <= n; ++j) {\n            cout << best_grid[i][j] << (j == n ? \"\\n\" : \" \");\n        }\n    }\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <string>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\n// Global array for Harmonic numbers\ndouble H[105];\n\n// Precompute Harmonic numbers H[k] = sum(1/i for i=1..k)\nvoid precompute_harmonic(int n) {\n    H[0] = 0.0;\n    for (int i = 1; i <= n; ++i) {\n        H[i] = H[i-1] + 1.0 / i;\n    }\n}\n\nint main() {\n    // Optimize I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, D, Q;\n    if (!(cin >> N >> D >> Q)) return 0;\n\n    // Precompute harmonic numbers for proxy weight calculation\n    precompute_harmonic(N);\n\n    // Permutation for sorting\n    vector<int> p(N);\n    iota(p.begin(), p.end(), 0);\n    // Accumulated scores (Dominance count)\n    vector<double> score(N, 0.0);\n\n    // Phase 1: Comb Sort (Fast convergence)\n    double gap = N;\n    while (gap > 1.0 && Q > 0) {\n        gap /= 1.3;\n        if (gap < 1.0) gap = 1.0;\n        int g = (int)gap;\n        \n        for (int i = 0; i < N - g && Q > 0; ++i) {\n            cout << \"1 1 \" << p[i] << \" \" << p[i+g] << \"\\n\";\n            cout.flush();\n            \n            string res;\n            cin >> res;\n            Q--;\n\n            // Update scores and order\n            // p[i] is Left, p[i+g] is Right\n            if (res == \"<\") { \n                // Left is lighter, Right is heavier. Swap to maintain heavy items at the start.\n                swap(p[i], p[i+g]);\n                // p[i] is now the heavier item\n                score[p[i]] += 1.0;\n                score[p[i+g]] -= 1.0;\n            } else if (res == \">\") {\n                // Left is heavier. No swap needed.\n                score[p[i]] += 1.0;\n                score[p[i+g]] -= 1.0;\n            } else {\n                score[p[i]] += 0.5;\n                score[p[i+g]] -= 0.5;\n            }\n        }\n    }\n\n    // Phase 2: Bubble Sort (Refinement with adjacent swaps)\n    while (Q > 0) {\n        for (int i = 0; i < N - 1 && Q > 0; ++i) {\n            cout << \"1 1 \" << p[i] << \" \" << p[i+1] << \"\\n\";\n            cout.flush();\n            \n            string res;\n            cin >> res;\n            Q--;\n\n            if (res == \"<\") {\n                swap(p[i], p[i+1]);\n                score[p[i]] += 1.0;\n                score[p[i+1]] -= 1.0;\n            } else if (res == \">\") {\n                score[p[i]] += 1.0;\n                score[p[i+1]] -= 1.0;\n            } else {\n                score[p[i]] += 0.5;\n                score[p[i+1]] -= 0.5;\n            }\n        }\n    }\n\n    // Sort original item indices by score descending (Heavy to Light)\n    // This determines the rank of each item\n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n    sort(items.begin(), items.end(), [&](int a, int b) {\n        return score[a] > score[b];\n    });\n\n    // Compute Proxy Weights based on Expected Value of Exponential Order Statistics\n    // If weights are Exp(lambda), the expected value of the k-th smallest is proportional to H_k.\n    // The expected value of the (N-r)-th smallest (which is the r-th largest, 0-indexed)\n    // is proportional to H_N - H_r.\n    // This proxy captures the heavy-tailed distribution effectively.\n    vector<double> proxy(N);\n    for (int r = 0; r < N; ++r) {\n        int item = items[r];\n        proxy[item] = H[N] - H[r];\n    }\n\n    // Initial Assignment (LPT - Longest Processing Time)\n    vector<int> assignment(N);\n    vector<double> bin_weights(D, 0.0);\n    vector<vector<int>> bins(D);\n\n    // Items are sorted heaviest first\n    for (int item : items) {\n        int best_d = 0;\n        double min_w = bin_weights[0];\n        for (int d = 1; d < D; ++d) {\n            if (bin_weights[d] < min_w) {\n                min_w = bin_weights[d];\n                best_d = d;\n            }\n        }\n        assignment[item] = best_d;\n        bin_weights[best_d] += proxy[item];\n        bins[best_d].push_back(item);\n    }\n\n    // Local Search (Steepest Descent)\n    auto start_time = chrono::high_resolution_clock::now();\n    double time_limit = 1.8; // Seconds\n\n    // Current cost (proxy for variance)\n    double current_cost = 0;\n    for (double w : bin_weights) current_cost += w * w;\n\n    double total_w = 0;\n    for (double w : bin_weights) total_w += w;\n    double mean_w = total_w / D;\n\n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > time_limit) break;\n\n        bool improved = false;\n        \n        // Best Move Candidate\n        int move_from = -1, move_to = -1, move_item = -1;\n        double min_move_delta = 0;\n\n        // Only try moving from heavier bins to lighter bins\n        for (int i = 0; i < D; ++i) {\n            if (bin_weights[i] <= mean_w) continue;\n            if (bins[i].empty()) continue;\n\n            for (int j = 0; j < D; ++j) {\n                if (i == j) continue;\n                if (bin_weights[j] >= mean_w) continue;\n\n                double diff_ij = bin_weights[i] - bin_weights[j];\n                \n                for (int u : bins[i]) {\n                    double w_u = proxy[u];\n                    // Moving u reduces Wi and increases Wj.\n                    // Improvement requires new Wi < old Wj + w_u (roughly)\n                    // Mathematically, delta < 0 iff w_u < diff_ij\n                    if (w_u < diff_ij) {\n                        double delta = 2.0 * w_u * (w_u - diff_ij);\n                        if (delta < min_move_delta) {\n                            min_move_delta = delta;\n                            move_from = i;\n                            move_to = j;\n                            move_item = u;\n                        }\n                    }\n                }\n            }\n        }\n\n        if (move_from != -1) {\n            // Execute Best Move\n            int u = move_item;\n            int i = move_from;\n            int j = move_to;\n            double w_u = proxy[u];\n\n            assignment[u] = j;\n            \n            // Remove u from bin i (O(1) using swap-with-back)\n            auto& vec_i = bins[i];\n            for(auto it = vec_i.begin(); it != vec_i.end(); ++it) {\n                if(*it == u) {\n                    *it = vec_i.back();\n                    vec_i.pop_back();\n                    break;\n                }\n            }\n            bins[j].push_back(u);\n            \n            bin_weights[i] -= w_u;\n            bin_weights[j] += w_u;\n            \n            current_cost += min_move_delta;\n            improved = true;\n            continue; \n        }\n\n        // Try Swaps\n        int swap_from = -1, swap_to = -1, swap_u = -1, swap_v = -1;\n        double min_swap_delta = 0;\n\n        for (int i = 0; i < D; ++i) {\n            if (bin_weights[i] <= mean_w) continue;\n            if (bins[i].empty()) continue;\n\n            for (int j = 0; j < D; ++j) {\n                if (i == j) continue;\n                if (bin_weights[j] >= mean_w) continue;\n\n                double diff_ij = bin_weights[i] - bin_weights[j];\n                \n                const auto& items_i = bins[i];\n                const auto& items_j = bins[j];\n\n                for (int u : items_i) {\n                    double w_u = proxy[u];\n                    for (int v : items_j) {\n                        double w_v = proxy[v];\n                        // We want to move weight from i to j, so w_u > w_v\n                        if (w_u > w_v) {\n                            double dw = w_u - w_v;\n                            // Improvement requires dw < diff_ij\n                            if (dw < diff_ij) {\n                                double delta = 2.0 * dw * (dw - diff_ij);\n                                if (delta < min_swap_delta) {\n                                    min_swap_delta = delta;\n                                    swap_from = i;\n                                    swap_to = j;\n                                    swap_u = u;\n                                    swap_v = v;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        if (swap_from != -1) {\n            // Execute Swap\n            int u = swap_u;\n            int v = swap_v;\n            int i = swap_from;\n            int j = swap_to;\n            double w_u = proxy[u];\n            double w_v = proxy[v];\n\n            assignment[u] = j;\n            assignment[v] = i;\n\n            // Swap in bins\n            // Remove u from i\n            auto& vec_i = bins[i];\n            for(auto it = vec_i.begin(); it != vec_i.end(); ++it) {\n                if(*it == u) {\n                    *it = vec_i.back();\n                    vec_i.pop_back();\n                    break;\n                }\n            }\n            vec_i.push_back(v);\n\n            // Remove v from j\n            auto& vec_j = bins[j];\n            for(auto it = vec_j.begin(); it != vec_j.end(); ++it) {\n                if(*it == v) {\n                    *it = vec_j.back();\n                    vec_j.pop_back();\n                    break;\n                }\n            }\n            vec_j.push_back(u);\n\n            bin_weights[i] = bin_weights[i] - w_u + w_v;\n            bin_weights[j] = bin_weights[j] - w_v + w_u;\n\n            current_cost += min_swap_delta;\n            improved = true;\n            continue;\n        }\n\n        if (!improved) break;\n    }\n\n    // Output final assignment\n    for (int i = 0; i < N; ++i) {\n        cout << assignment[i] << (i == N - 1 ? \"\" : \" \");\n    }\n    cout << \"\\n\";\n    cout.flush();\n\n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cstring>\n\nusing namespace std;\n\n// Constants matching problem constraints\nconst int MAX_N = 205;\nconst int MAX_M = 12;\n\n// State structure optimized for fast copying using fixed arrays\nstruct State {\n    int n, m;\n    int stacks[MAX_M][MAX_N];\n    int stack_size[MAX_M];\n    int pos_stack[MAX_N];\n    int pos_idx[MAX_N];\n    long long energy;\n\n    void init(int n_in, int m_in, const vector<vector<int>>& input) {\n        n = n_in; m = m_in; energy = 0;\n        for(int i=0; i<m; ++i) {\n            stack_size[i] = (int)input[i].size();\n            for(int j=0; j<stack_size[i]; ++j) {\n                int box = input[i][j];\n                stacks[i][j] = box;\n                pos_stack[box] = i;\n                pos_idx[box] = j;\n            }\n        }\n    }\n    \n    // Fast copy using memory copy for arrays\n    void copy_from(const State& other) {\n        n = other.n; m = other.m; energy = other.energy;\n        for(int i=0; i<m; ++i) {\n            memcpy(stacks[i], other.stacks[i], sizeof(stacks[i]));\n            stack_size[i] = other.stack_size[i];\n        }\n        memcpy(pos_stack, other.pos_stack, sizeof(pos_stack));\n        memcpy(pos_idx, other.pos_idx, sizeof(pos_idx));\n    }\n\n    int get_top(int s) const {\n        if(stack_size[s] == 0) return 1000000; // Represents empty (infinity)\n        return stacks[s][stack_size[s]-1];\n    }\n};\n\n// Global storage for operations to output at the end\nvector<pair<int, int>> ops;\n\n// Simulation move: updates state without recording operations\nvoid sim_move(State& s, int box, int dest) {\n    int src = s.pos_stack[box];\n    int idx = s.pos_idx[box];\n    int cur_sz = s.stack_size[src];\n    // Check validity\n    if(src == -1 || idx < 0 || idx >= cur_sz || src == dest) return;\n\n    int count = cur_sz - idx;\n    s.energy += count + 1;\n\n    int dest_sz = s.stack_size[dest];\n    // Move boxes from src to dest\n    for(int k=0; k<count; ++k) {\n        int b = s.stacks[src][idx + k];\n        s.stacks[dest][dest_sz + k] = b;\n        s.pos_stack[b] = dest;\n        s.pos_idx[b] = dest_sz + k;\n    }\n    \n    s.stack_size[dest] += count;\n    s.stack_size[src] = idx; \n}\n\n// Simulation remove: updates state without recording operations\nvoid sim_remove(State& s, int box) {\n    int src = s.pos_stack[box];\n    int idx = s.pos_idx[box];\n    if(src == -1) return;\n    // Must be at top\n    if(idx != s.stack_size[src] - 1) return; \n    \n    s.stack_size[src]--;\n    s.pos_stack[box] = -1;\n    s.pos_idx[box] = -1;\n}\n\n// Heuristic to evaluate a move destination for the simulation\nint find_dest_heuristic(const State& s, int u, int src, int next_target) {\n    int best_dest = -1;\n    int best_score = -2147483648;\n    \n    for(int i=0; i<s.m; ++i) {\n        if(i == src) continue;\n        int top = s.get_top(i);\n        int score = 0;\n        \n        bool is_empty = (s.stack_size[i] == 0);\n        bool is_good = (!is_empty && top > u); // Valid if top > u (maintains decreasing order)\n        \n        if(is_empty) {\n            score += 3000000; // High priority for empty stacks\n        } else if(is_good) {\n            score += 1000000; // Good order\n            // Prefer smaller top to cover.\n            // Rationale: Covering a smaller top exposes it later when u is moved.\n            // A smaller top is more useful (needed sooner) than a larger top.\n            // So we want the box below u to be small. Thus we place u on a small top.\n            score -= top;     \n        } else {\n            score -= 1000000; // Bad order\n            // Prefer larger top to cover.\n            // Rationale: If we must break order, burying a large number (needed later)\n            // is better than burying a small number (needed sooner).\n            score += top;     \n        }\n        \n        // Lookahead penalty: penalize covering near-future targets\n        // If top is a target we need soon, covering it is very bad.\n        // O(1) check\n        if (top >= next_target && top < next_target + 100) {\n            int k = top - next_target;\n            // Penalty starts high and decreases.\n            // If top == next_target (k=0), penalty is 3,000,000.\n            // This makes covering the immediate target worse than most other moves.\n            int penalty = 3000000 - 100000 * k;\n            if (penalty < 0) penalty = 0;\n            score -= penalty;\n        }\n\n        if(best_dest == -1 || score > best_score) {\n            best_dest = i;\n            best_score = score;\n        }\n    }\n    return best_dest;\n}\n\n// Actual move: updates state and records operation\nvoid apply_move(State& s, int box, int dest) {\n    int src = s.pos_stack[box];\n    int idx = s.pos_idx[box];\n    int cur_sz = s.stack_size[src];\n    if(src == -1 || idx < 0 || idx >= cur_sz || src == dest) return;\n\n    int count = cur_sz - idx;\n    s.energy += count + 1;\n    ops.push_back({box, dest + 1});\n\n    int dest_sz = s.stack_size[dest];\n    for(int k=0; k<count; ++k) {\n        int b = s.stacks[src][idx + k];\n        s.stacks[dest][dest_sz + k] = b;\n        s.pos_stack[b] = dest;\n        s.pos_idx[b] = dest_sz + k;\n    }\n    \n    s.stack_size[dest] += count;\n    s.stack_size[src] = idx;\n}\n\n// Actual remove: updates state and records operation\nvoid apply_remove(State& s, int box) {\n    int src = s.pos_stack[box];\n    int idx = s.pos_idx[box];\n    if(src == -1) return;\n    if(idx != s.stack_size[src] - 1) return;\n    \n    s.stack_size[src]--;\n    s.pos_stack[box] = -1;\n    s.pos_idx[box] = -1;\n    ops.push_back({box, 0});\n}\n\nint main() {\n    // Fast I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n, m;\n    if(!(cin >> n >> m)) return 0;\n    \n    vector<vector<int>> input_stacks(m);\n    for(int i=0; i<m; ++i) {\n        input_stacks[i].resize(n/m);\n        for(int j=0; j<n/m; ++j) {\n            cin >> input_stacks[i][j];\n        }\n    }\n\n    State S;\n    S.init(n, m, input_stacks);\n    ops.reserve(5000);\n    \n    // Lookahead depth for simulation.\n    // 40 provides a good balance between decision quality and speed.\n    const int LOOKAHEAD = 40;\n\n    for(int v=1; v<=n; ++v) {\n        while(true) {\n            int src = S.pos_stack[v];\n            int idx = S.pos_idx[v];\n            \n            if(src == -1) break; // Box already removed\n            \n            // If v is at the top, remove it\n            if(idx == S.stack_size[src] - 1) {\n                apply_remove(S, v);\n                break;\n            } else {\n                // Identify blocker u (box directly above v)\n                int u = S.stacks[src][idx + 1];\n                \n                int best_dest = -1;\n                long long best_energy = -1;\n                bool first = true;\n                \n                // Iterate all candidate destination stacks\n                for(int dest=0; dest<m; ++dest) {\n                    if(dest == src) continue;\n                    \n                    // Simulation\n                    State sim;\n                    sim.copy_from(S);\n                    \n                    // Move u to dest in simulation\n                    sim_move(sim, u, dest);\n                    \n                    // Remove v (should now be at top of original src)\n                    int v_src = sim.pos_stack[v];\n                    if(v_src != -1 && sim.pos_idx[v] == sim.stack_size[v_src] - 1) {\n                        sim_remove(sim, v);\n                    }\n                    \n                    bool is_worse = false;\n                    // Run lookahead to estimate future cost\n                    int resolved = 0;\n                    int target = v + 1;\n                    while(resolved < LOOKAHEAD && target <= n) {\n                        // Pruning: if current energy already exceeds best found, stop\n                        if (!first && sim.energy >= best_energy) {\n                            is_worse = true;\n                            break;\n                        }\n\n                        int t_src = sim.pos_stack[target];\n                        int t_idx = sim.pos_idx[target];\n                        \n                        if(t_src == -1) {\n                            target++;\n                            continue;\n                        }\n                        \n                        if(t_idx == sim.stack_size[t_src] - 1) {\n                            sim_remove(sim, target);\n                            resolved++;\n                            target++;\n                        } else {\n                            int blocker = sim.stacks[t_src][t_idx + 1];\n                            int d = find_dest_heuristic(sim, blocker, t_src, target + 1);\n                            if (d != -1) {\n                                sim_move(sim, blocker, d);\n                            } else {\n                                is_worse = true; \n                                break;\n                            }\n                        }\n                    }\n                    \n                    if (!is_worse) {\n                        if (first || sim.energy < best_energy) {\n                            best_energy = sim.energy;\n                            best_dest = dest;\n                            first = false;\n                        }\n                    }\n                }\n                \n                // Apply the best move to the real state\n                if (best_dest == -1) {\n                    // Fallback: move to first available stack that isn't src\n                    for(int i=0; i<m; ++i) if(i != src) { best_dest = i; break; }\n                }\n                apply_move(S, u, best_dest);\n            }\n        }\n    }\n\n    // Output the sequence of operations\n    for(const auto& p : ops) {\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n\n    return 0;\n}","ahc027":"/*\n    Solution for AHC027 (Takahashi-kun cleaner No.2)\n    \n    Algorithm:\n    1. Build a DFS Spanning Tree starting from (0,0).\n       We use an iterative DFS to avoid potential stack overflow issues and ensure robustness.\n       The tree guarantees that every reachable cell is visited.\n    2. Calculate base visit counts for each cell based on the tree structure.\n       In a DFS traversal, a node is visited once when entered from its parent, \n       and once for each return from its children.\n    3. Greedily allocate extra visits (out-and-back loops) to cells with the highest dirt-to-visit-coupling ratio.\n       We maximize the reduction in average dirtiness by targeting cells where an extra visit yields the most benefit.\n       Budget is strictly limited to 98,000 moves to ensure validity and leave margin for the return path.\n    4. Generate the final route iteratively using a stack, inserting extra loops on the fly.\n       This guarantees the route starts at (0,0), visits all nodes, and returns to (0,0).\n*/\n#include <bits/stdc++.h>\nusing namespace std;\n\n// Optimization for speed\n#pragma GCC optimize(\"O3,unroll-loops\")\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\nvector<vector<int>> children;\nvector<bool> vis;\nvector<int> c, extra;\n\n// Check wall existence between adjacent cells\nbool can_move(int i, int j, int ni, int nj) {\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    // Check Horizontal walls (h) between (i, j) and (i+1, j)\n    if (ni == i + 1 && nj == j) return h[i][j] == '0';\n    // h[ni][j] is wall below (ni, j) i.e. between (ni, j) and (ni+1, j) -> (i-1, j) and (i, j)\n    if (ni == i - 1 && nj == j) return h[ni][j] == '0';\n    // Check Vertical walls (v) between (i, j) and (i, j+1)\n    if (ni == i && nj == j + 1) return v[i][j] == '0';\n    // v[i][nj] is wall right of (i, nj) i.e. between (i, nj) and (i, nj+1) -> (i, j-1) and (i, j)\n    if (ni == i && nj == j - 1) return v[i][nj] == '0';\n    return false;\n}\n\n// Get movement character\nchar get_dir(int r1, int c1, int r2, int c2) {\n    if (r1 < r2) return 'D';\n    if (r1 > r2) return 'U';\n    if (c1 < c2) return 'R';\n    if (c1 > c2) return 'L';\n    return 0;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N)) return 0;\n    h.resize(N - 1);\n    for (int i = 0; i < N - 1; ++i) cin >> h[i];\n    v.resize(N);\n    for (int i = 0; i < N; ++i) cin >> v[i];\n    \n    int N2 = N * N;\n    d.assign(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> d[i][j];\n\n    children.assign(N2, vector<int>());\n    vis.assign(N2, false);\n    vector<int> dir_idx(N2, 0);\n\n    // Iterative DFS to build spanning tree\n    // This avoids recursion depth issues and ensures a valid spanning tree\n    vector<int> st;\n    st.reserve(N2);\n    st.push_back(0);\n    vis[0] = true;\n    \n    const int di[4] = {-1, 1, 0, 0};\n    const int dj[4] = {0, 0, -1, 1};\n    \n    while (!st.empty()) {\n        int u = st.back();\n        int ui = u / N, uj = u % N;\n        bool pushed = false;\n        \n        // Continue scanning from last checked direction to find unvisited neighbors\n        for (int k = dir_idx[u]; k < 4; ++k) {\n            dir_idx[u] = k + 1; // Mark direction as checked\n            int ni = ui + di[k], nj = uj + dj[k];\n            if (ni >= 0 && ni < N && nj >= 0 && nj < N && can_move(ui, uj, ni, nj)) {\n                int nxt = ni * N + nj;\n                if (!vis[nxt]) {\n                    vis[nxt] = true;\n                    children[u].push_back(nxt);\n                    st.push_back(nxt);\n                    pushed = true;\n                    break; // Go deeper immediately\n                }\n            }\n        }\n        \n        if (!pushed) {\n            st.pop_back();\n        }\n    }\n\n    // Compute base visit counts\n    // Root 0 is cleaned each time we return from a child\n    // Other nodes u are cleaned when entered from parent + returned from children\n    c.assign(N2, 0);\n    for (int u = 0; u < N2; ++u) {\n        if (u == 0) c[u] = (int)children[u].size();\n        else c[u] = 1 + (int)children[u].size();\n    }\n\n    // Greedily allocate extra visits to minimize average dirtiness\n    // We use a Priority Queue to pick the node that gives max reduction in dirtiness.\n    // The reduction is proportional to d_u / (c_u * (c_u + 1)).\n    // Each extra visit costs 2 moves (out-and-back loop).\n    priority_queue<pair<double, int>> pq;\n    int L = 2 * (N2 - 1); // Base length of DFS traversal (down and up every edge)\n    \n    for (int u = 1; u < N2; ++u) { \n        if (c[u] > 0) {\n            double gain = (double)d[u/N][u%N] / (c[u] * (c[u] + 1.0));\n            pq.push({gain, u});\n        }\n    }\n\n    extra.assign(N2, 0);\n    // Strict budget: 98000 leaves safe margin for return path to (0,0)\n    while (L + 2 <= 98000 && !pq.empty()) {\n        auto top = pq.top(); pq.pop();\n        int u = top.second;\n        c[u]++;\n        extra[u]++;\n        L += 2;\n        double new_gain = (double)d[u/N][u%N] / (c[u] * (c[u] + 1.0));\n        pq.push({new_gain, u});\n    }\n\n    // Generate route iteratively\n    // This guarantees robustness and exact (0,0) termination\n    string res;\n    res.reserve(L + 100);\n    \n    vector<int> gen_st;\n    gen_st.reserve(N2);\n    gen_st.push_back(0);\n    vector<int> gen_idx(N2, 0);\n    \n    while (!gen_st.empty()) {\n        int u = gen_st.back();\n        int ci = gen_idx[u];\n        \n        if (ci < (int)children[u].size()) {\n            int vtx = children[u][ci];\n            gen_idx[u]++; // Move to next child for next time we visit u\n            \n            int ui = u / N, uj = u % N;\n            int vi = vtx / N, vj = vtx % N;\n            char to_v = get_dir(ui, uj, vi, vj);\n            char to_u = get_dir(vi, vj, ui, uj);\n            \n            // Insert extra loops (out-and-back) to child\n            // Each loop cleans the child (and current node) one extra time.\n            int loops = extra[vtx];\n            while (loops--) {\n                res += to_v;\n                res += to_u;\n            }\n            \n            // Move to child (part of the main DFS path)\n            res += to_v;\n            gen_st.push_back(vtx);\n        } else {\n            // All children of u visited, backtrack to parent\n            gen_st.pop_back();\n            if (!gen_st.empty()) {\n                int parent = gen_st.back();\n                int ui = u / N, uj = u % N;\n                int pi = parent / N, pj = parent % N;\n                char move_back = get_dir(ui, uj, pi, pj);\n                res += move_back;\n            }\n        }\n    }\n\n    // Safety check (should not trigger due to strict budgeting)\n    if ((int)res.length() > 100000) res.resize(100000);\n    \n    cout << res << \"\\n\";\n    return 0;\n}","ahc028":"/*\n    Problem: Kakizome Taikai (AHC028)\n    Solution: Precomputed DP + Simulated Annealing + Hill Climbing + Exact Lookahead Reconstruction\n    \n    Key Improvements:\n    1. Increased Overlap Weight in Heuristic (12) to better reflect savings.\n       Overlap saves typing costs and movement costs. A multiplier of 12 approximates \n       the average saving per overlapping character (1 type + ~11 movement cost).\n    2. Added Hill Climbing (Local Search) phase after SA to refine the permutation.\n       Runs for the remaining time budget (until 1.95s), performing random swaps \n       and accepting improvements. This fine-tunes the solution found by SA.\n    3. Optimized Local Search to swap in-place to reduce memory allocation overhead.\n    4. Exact Lookahead using suffix_cost during reconstruction to optimally choose \n       the endpoint of the current string based on the exact cost to complete the next string.\n*/\n#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\n\n#pragma GCC optimize(\"Ofast,unroll-loops\")\n\nstruct Point { int r, c; };\n\nstruct FastRNG {\n    uint64_t s;\n    FastRNG(uint64_t seed) : s(seed) {}\n    uint64_t next() {\n        uint64_t x = s;\n        x ^= x << 13; x ^= x >> 7; x ^= x << 17;\n        return s = x;\n    }\n    int operator()(int n) { return next() % n; }\n    double operator()() { return (next() >> 11) * (1.0 / 9007199254740992.0); }\n};\n\nint N, M, sr, sc;\nvector<string> A;\nvector<string> T;\nvector<vector<Point>> pos(26);\n\n// min_cost[k][r][c] = min cost to type T[k] starting from (r,c)\nint min_cost[205][15][15];\nuint8_t end_pos_r[205][15][15];\nuint8_t end_pos_c[205][15][15];\nint overlap[205][205];\nint prev_dp[256], curr_dp[256];\nint dp_buf[256], next_dp_buf[256], parent[5][256];\n\n// suffix_cost[k][idx][u] = min cost to type T[k][idx...4] \n// given we are at the u-th occurrence of T[k][idx-1].\n// idx ranges from 1 to 5. (idx=5 cost is 0).\nint suffix_cost[205][6][256]; \n\n// Heuristic multiplier for overlap savings\nconst int OVERLAP_WEIGHT = 12; \n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M)) return 0;\n    cin >> sr >> sc;\n\n    A.resize(N);\n    for (int i = 0; i < N; i++) cin >> A[i];\n\n    T.resize(M);\n    for (int i = 0; i < M; i++) cin >> T[i];\n\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            pos[A[i][j] - 'A'].push_back({i, j});\n\n    // Precompute min_cost and end positions\n    for (int k = 0; k < M; k++) {\n        const vector<Point>* layers[5];\n        int layer_sz[5];\n        for (int l = 0; l < 5; l++) {\n            layers[l] = &pos[T[k][l] - 'A'];\n            layer_sz[l] = (int)layers[l]->size();\n        }\n\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                const auto& p0 = *layers[0];\n                int sz0 = layer_sz[0];\n                for (int u = 0; u < sz0; u++)\n                    prev_dp[u] = abs(r - p0[u].r) + abs(c - p0[u].c) + 1;\n\n                for (int l = 1; l < 5; l++) {\n                    const auto& p_prev = *layers[l-1];\n                    const auto& p_curr = *layers[l];\n                    int sz_prev = layer_sz[l-1], sz_curr = layer_sz[l];\n                    for (int u = 0; u < sz_curr; u++) {\n                        int ur = p_curr[u].r, uc = p_curr[u].c;\n                        int mn = 1e9;\n                        for (int v = 0; v < sz_prev; v++) {\n                            int val = prev_dp[v] + abs(p_prev[v].r - ur) + abs(p_prev[v].c - uc) + 1;\n                            if (val < mn) mn = val;\n                        }\n                        curr_dp[u] = mn;\n                    }\n                    for (int u = 0; u < sz_curr; u++) prev_dp[u] = curr_dp[u];\n                }\n\n                int sz_last = layer_sz[4];\n                int min_c = prev_dp[0], best_u = 0;\n                for (int u = 1; u < sz_last; u++)\n                    if (prev_dp[u] < min_c) min_c = prev_dp[u], best_u = u;\n\n                min_cost[k][r][c] = min_c;\n                end_pos_r[k][r][c] = (uint8_t)(*layers[4])[best_u].r;\n                end_pos_c[k][r][c] = (uint8_t)(*layers[4])[best_u].c;\n            }\n        }\n    }\n\n    // Precompute overlaps\n    for (int i = 0; i < M; i++) {\n        for (int j = 0; j < M; j++) {\n            for (int l = 4; l >= 1; l--) {\n                bool match = true;\n                for (int k = 0; k < l; k++)\n                    if (T[i][5 - l + k] != T[j][k]) { match = false; break; }\n                if (match) { overlap[i][j] = l; break; }\n            }\n        }\n    }\n\n    // Precompute suffix_cost\n    // Global array is 0-initialized, so suffix_cost[k][5][u] is 0.\n    for (int k = 0; k < M; k++) {\n        for (int idx = 4; idx >= 1; idx--) {\n            const auto& prev_pos = pos[T[k][idx-1] - 'A'];\n            const auto& curr_pos = pos[T[k][idx] - 'A'];\n            int prev_sz = prev_pos.size();\n            int curr_sz = curr_pos.size();\n            \n            for (int u = 0; u < prev_sz; u++) {\n                int pr = prev_pos[u].r;\n                int pc = prev_pos[u].c;\n                int mn = 1e9;\n                for (int v = 0; v < curr_sz; v++) {\n                    int dist = abs(pr - curr_pos[v].r) + abs(pc - curr_pos[v].c);\n                    // cost = move + type(1) + cost to type rest\n                    int val = dist + 1 + suffix_cost[k][idx+1][v];\n                    if (val < mn) mn = val;\n                }\n                suffix_cost[k][idx][u] = mn;\n            }\n        }\n    }\n\n    // Greedy initialization\n    vector<int> order(M);\n    vector<bool> used(M, false);\n    int cr = sr, cc = sc;\n    int last_k = -1; \n\n    for (int i = 0; i < M; i++) {\n        int best_k = -1;\n        int best_val = 2e9;\n\n        for (int k = 0; k < M; k++) {\n            if (!used[k]) {\n                int cost = min_cost[k][cr][cc];\n                if (last_k != -1) {\n                    int ov = overlap[last_k][k];\n                    if (ov > 0) cost -= ov * OVERLAP_WEIGHT;\n                }\n                if (cost < best_val) {\n                    best_val = cost;\n                    best_k = k;\n                }\n            }\n        }\n        \n        if (best_k != -1) {\n            used[best_k] = true;\n            order[i] = best_k;\n            last_k = best_k;\n            cr = end_pos_r[best_k][cr][cc];\n            cc = end_pos_c[best_k][cr][cc];\n        } else {\n            break; \n        }\n    }\n\n    // Simulated Annealing\n    FastRNG rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    auto evaluate = [&](const vector<int>& ord) -> int {\n        int cost = 0;\n        int er = sr, ec = sc;\n        int prev = -1;\n        for (int k : ord) {\n            int c = min_cost[k][er][ec];\n            if (prev != -1) c -= overlap[prev][k] * OVERLAP_WEIGHT;\n            cost += max(0, c);\n            int nr = end_pos_r[k][er][ec];\n            int nc = end_pos_c[k][er][ec];\n            er = nr; ec = nc;\n            prev = k;\n        }\n        return cost;\n    };\n\n    int best_cost = evaluate(order);\n    vector<int> best_order = order;\n    vector<int> current_order = order;\n    \n    double temp = 4000.0;\n    double cooling = 0.99996;\n    auto start_time = chrono::steady_clock::now();\n    double limit_sa = 1.70; // Reduced to allow local search\n\n    while (true) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        if (elapsed > limit_sa) break;\n\n        vector<int> new_order = current_order;\n        int t = rng(3);\n        if (t == 0) { // Swap\n            int i = rng(M), j = rng(M);\n            swap(new_order[i], new_order[j]);\n        } else if (t == 1) { // Reverse\n            int i = rng(M), j = rng(M);\n            if (i > j) swap(i, j);\n            reverse(new_order.begin() + i, new_order.begin() + j + 1);\n        } else { // Insert\n            int i = rng(M), j = rng(M);\n            while (i == j) j = rng(M); \n            int val = new_order[i];\n            new_order.erase(new_order.begin() + i);\n            if (j > i) j--;\n            new_order.insert(new_order.begin() + j, val);\n        }\n\n        int new_cost = evaluate(new_order);\n        if (new_cost < best_cost || rng() < exp(-(double)(new_cost - best_cost) / temp)) {\n            current_order = new_order;\n            if (new_cost < best_cost) {\n                best_cost = new_cost;\n                best_order = new_order;\n            }\n        }\n        temp *= cooling;\n    }\n\n    // Local Search (Hill Climbing) with Swaps\n    // Refines the best solution found by SA\n    double limit_ls = 1.95;\n    while (true) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        if (elapsed > limit_ls) break;\n\n        // Swap in-place to avoid allocation\n        int i = rng(M), j = rng(M);\n        swap(best_order[i], best_order[j]);\n\n        int new_cost = evaluate(best_order);\n        if (new_cost < best_cost) {\n            best_cost = new_cost;\n        } else {\n            // Revert swap\n            swap(best_order[i], best_order[j]);\n        }\n    }\n\n    // Reconstruction\n    vector<Point> ans;\n    ans.reserve(M * 5);\n    string S = \"\";\n    int cur_r = sr, cur_c = sc;\n    vector<bool> covered(M, false);\n    int covered_cnt = 0;\n    \n    for (int k_idx = 0; k_idx < M; k_idx++) {\n        int k = best_order[k_idx];\n        if (covered[k]) continue;\n        \n        if (S.size() >= 5 && S.find(T[k]) != string::npos) {\n            covered[k] = true;\n            covered_cnt++;\n            continue;\n        }\n\n        int ov = 0;\n        int lim = min((int)S.size(), 4);\n        for (int o = lim; o >= 1; o--) {\n            bool match = true;\n            for (int p = 0; p < o; p++) {\n                if (S[S.size() - o + p] != T[k][p]) { match = false; break; }\n            }\n            if (match) { ov = o; break; }\n        }\n\n        int len = 5 - ov;\n        if (len <= 0) { covered[k] = true; covered_cnt++; continue; }\n\n        const vector<Point>* layers_p[5];\n        int layers_sz[5];\n        for (int l = 0; l < len; l++) {\n            layers_p[l] = &pos[T[k][ov + l] - 'A'];\n            layers_sz[l] = (int)layers_p[l]->size();\n        }\n\n        const auto& p0 = *layers_p[0];\n        int sz0 = layers_sz[0];\n        for (int u = 0; u < sz0; u++) {\n            dp_buf[u] = abs(cur_r - p0[u].r) + abs(cur_c - p0[u].c) + 1;\n            parent[0][u] = -1;\n        }\n\n        for (int l = 1; l < len; l++) {\n            const auto& p_prev = *layers_p[l-1];\n            const auto& p_curr = *layers_p[l];\n            int sz_prev = layers_sz[l-1], sz_curr = layers_sz[l];\n            for (int u = 0; u < sz_curr; u++) {\n                int ur = p_curr[u].r, uc = p_curr[u].c;\n                int mn = 1e9, best_v = -1;\n                for (int v = 0; v < sz_prev; v++) {\n                    int val = dp_buf[v] + abs(p_prev[v].r - ur) + abs(p_prev[v].c - uc) + 1;\n                    if (val < mn) { mn = val; best_v = v; }\n                }\n                next_dp_buf[u] = mn;\n                parent[l][u] = best_v;\n            }\n            for (int u = 0; u < sz_curr; u++) dp_buf[u] = next_dp_buf[u];\n        }\n\n        // Lookahead using exact suffix cost\n        int next_k = -1;\n        for (int j = k_idx + 1; j < M; j++) {\n            int candidate = best_order[j];\n            if (!covered[candidate]) {\n                next_k = candidate;\n                break;\n            }\n        }\n        \n        int sz_last = layers_sz[len-1];\n        int best_u = 0;\n        \n        if (next_k != -1) {\n            int min_val = 2e9;\n            int ov_next = overlap[k][next_k];\n            \n            if (ov_next > 0 && ov_next < 5) {\n                // Exact cost calculation using precomputed suffix costs\n                for (int u = 0; u < sz_last; u++) {\n                    int val = dp_buf[u] + suffix_cost[next_k][ov_next][u];\n                    if (val < min_val) { min_val = val; best_u = u; }\n                }\n            } else if (ov_next >= 5) {\n                // Next string is fully covered\n                for (int u = 0; u < sz_last; u++) {\n                    if (dp_buf[u] < min_val) { min_val = dp_buf[u]; best_u = u; }\n                }\n            } else {\n                // No overlap, use standard min_cost\n                for (int u = 0; u < sz_last; u++) {\n                    int r = (*layers_p[len-1])[u].r;\n                    int c = (*layers_p[len-1])[u].c;\n                    int val = dp_buf[u] + min_cost[next_k][r][c];\n                    if (val < min_val) { min_val = val; best_u = u; }\n                }\n            }\n        } else {\n            int min_val = dp_buf[0];\n            for (int u = 1; u < sz_last; u++) {\n                if (dp_buf[u] < min_val) { min_val = dp_buf[u]; best_u = u; }\n            }\n        }\n\n        vector<Point> path(len);\n        int u = best_u;\n        for (int l = len-1; l >= 0; l--) {\n            path[l] = (*layers_p[l])[u];\n            if (l > 0) u = parent[l][u];\n        }\n\n        int old_len = S.size();\n        for (int l = 0; l < len; l++) {\n            ans.push_back(path[l]);\n            S += A[path[l].r][path[l].c];\n            cur_r = path[l].r; cur_c = path[l].c;\n        }\n\n        covered[k] = true; covered_cnt++;\n        \n        // Efficient localized coverage update\n        if ((int)S.size() >= 5) {\n            int start_s = max(0, old_len - 4);\n            int end_s = (int)S.size() - 5;\n            for (int s = start_s; s <= end_s; s++) {\n                for (int j = 0; j < M; j++) {\n                    if (!covered[j]) {\n                        bool match = true;\n                        for (int kk = 0; kk < 5; kk++) {\n                            if (S[s + kk] != T[j][kk]) { match = false; break; }\n                        }\n                        if (match) { covered[j] = true; covered_cnt++; }\n                    }\n                }\n            }\n        }\n    }\n\n    for (const auto& p : ans) cout << p.r << \" \" << p.c << \"\\n\";\n    return 0;\n}","ahc030":"#pragma GCC optimize(\"O3,unroll-loops\")\n#include <bits/stdc++.h>\nusing namespace std;\n\n// Fast I/O\nvoid fast_io() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n}\n\nint N, M;\ndouble eps;\n\nstruct Shape {\n    vector<pair<int, int>> cells;\n} shapes[25];\n\nint max_r[25], max_c[25];\n\n// Model State\nint grid_val[25][25]; \nint target_val[25][25]; // -1 if not drilled\nbool is_drilled[25][25];\n\n// Row/Col Estimates\ndouble est_row[25], est_col[25];\ndouble row_col_weight;\n\n// Current Position of Shapes\npair<int, int> cur_pos[25];\npair<int, int> best_pos[25];\n\n// Aggregated Sums and Cost\nint row_sums[25];\nint col_sums[25];\ndouble global_drill_cost;\n\nmt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\nint rand_int(int l, int r) { return uniform_int_distribution<int>(l, r)(rng); }\ndouble rand_double() { return uniform_real_distribution<double>(0, 1)(rng); }\n\n// Compute RC cost\ndouble compute_rc_cost() {\n    double cost = 0;\n    for(int r=0; r<N; ++r) {\n        double diff = row_sums[r] - est_row[r];\n        cost += diff * diff * row_col_weight;\n    }\n    for(int c=0; c<N; ++c) {\n        double diff = col_sums[c] - est_col[c];\n        cost += diff * diff * row_col_weight;\n    }\n    return cost;\n}\n\n// Initialize globals from cur_pos\nvoid init_model() {\n    memset(grid_val, 0, sizeof(grid_val));\n    memset(row_sums, 0, sizeof(row_sums));\n    memset(col_sums, 0, sizeof(col_sums));\n    global_drill_cost = 0;\n    \n    for (int k = 0; k < M; ++k) {\n        int r = cur_pos[k].first, c = cur_pos[k].second;\n        for (const auto& cell : shapes[k].cells) {\n            int cr = r + cell.first, cc = c + cell.second;\n            grid_val[cr][cc]++;\n            row_sums[cr]++;\n            col_sums[cc]++;\n        }\n    }\n    \n    for(int r=0; r<N; ++r) {\n        for(int c=0; c<N; ++c) {\n            if (is_drilled[r][c]) {\n                double diff = grid_val[r][c] - target_val[r][c];\n                global_drill_cost += diff * diff;\n            }\n        }\n    }\n}\n\nvoid copy_pos(pair<int, int> src[25], pair<int, int> dst[25]) {\n    for(int i=0; i<M; ++i) dst[i] = src[i];\n}\n\nvoid run_sa(const vector<pair<int,int>>& init_pos, int iterations) {\n    for (int k = 0; k < M; ++k) {\n        cur_pos[k] = !init_pos.empty() ? init_pos[k] : \n                     make_pair(rand_int(0, N - 1 - max_r[k]), rand_int(0, N - 1 - max_c[k]));\n    }\n    \n    init_model();\n    \n    double current_drill_cost = global_drill_cost;\n    double current_rc_cost = compute_rc_cost();\n    double current_cost = current_drill_cost + current_rc_cost;\n    \n    double best_cost = current_cost;\n    copy_pos(cur_pos, best_pos);\n    \n    double T = 1000.0;\n    double cooling = 0.99995; \n    uniform_real_distribution<double> dis(0, 1);\n    \n    // Buffers for fast revert\n    int backup_row_sums[25];\n    int backup_col_sums[25];\n    int saved_grid[25][25]; \n    \n    // Modified cells tracking - max shape size is N^2 <= 400\n    static int mod_r[1000], mod_c[1000];\n    int mod_count = 0;\n\n    for (int iter = 0; iter < iterations; ++iter) {\n        int k = rand_int(0, M - 1);\n        int dr = rand_int(-2, 2); \n        int dc = rand_int(-2, 2);\n        if (dr == 0 && dc == 0) continue;\n        \n        int nr = cur_pos[k].first + dr;\n        int nc = cur_pos[k].second + dc;\n        \n        if (nr < 0 || nr > N - 1 - max_r[k] || nc < 0 || nc > N - 1 - max_c[k]) continue;\n        \n        // Validity Check: No shape part on a cell known to have 0 oil\n        bool invalid = false;\n        for (const auto& cell : shapes[k].cells) {\n            int r = nr + cell.first;\n            int c = nc + cell.second;\n            if (is_drilled[r][c] && target_val[r][c] == 0) {\n                invalid = true;\n                break;\n            }\n        }\n        if (invalid) continue;\n        \n        // Identify modified cells\n        mod_count = 0;\n        auto add_mod = [&](int r, int c) {\n            for (int i=0; i<mod_count; ++i) {\n                if (mod_r[i] == r && mod_c[i] == c) return;\n            }\n            mod_r[mod_count] = r;\n            mod_c[mod_count] = c;\n            mod_count++;\n        };\n\n        for (const auto& cell : shapes[k].cells) {\n            int r_o = cur_pos[k].first + cell.first;\n            int c_o = cur_pos[k].second + cell.second;\n            int r_n = nr + cell.first;\n            int c_n = nc + cell.second;\n            \n            if (r_o != r_n || c_o != c_n) {\n                add_mod(r_o, c_o);\n                add_mod(r_n, c_n);\n            }\n        }\n        \n        // Backup sums\n        memcpy(backup_row_sums, row_sums, sizeof(row_sums));\n        memcpy(backup_col_sums, col_sums, sizeof(col_sums));\n        \n        // Save grid values\n        for (int i=0; i<mod_count; ++i) {\n            saved_grid[mod_r[i]][mod_c[i]] = grid_val[mod_r[i]][mod_c[i]];\n        }\n        \n        // Apply changes\n        for (const auto& cell : shapes[k].cells) {\n            int r_o = cur_pos[k].first + cell.first;\n            int c_o = cur_pos[k].second + cell.second;\n            int r_n = nr + cell.first;\n            int c_n = nc + cell.second;\n            \n            if (r_o != r_n || c_o != c_n) {\n                grid_val[r_o][c_o]--;\n                row_sums[r_o]--;\n                col_sums[c_o]--;\n                \n                grid_val[r_n][c_n]++;\n                row_sums[r_n]++;\n                col_sums[c_n]++;\n            }\n        }\n        \n        // Compute Delta Drill Cost\n        double delta_drill = 0;\n        for (int i=0; i<mod_count; ++i) {\n            int r = mod_r[i], c = mod_c[i];\n            if (is_drilled[r][c]) {\n                int old_v = saved_grid[r][c];\n                int new_v = grid_val[r][c];\n                int t = target_val[r][c];\n                delta_drill += (double)(new_v - t) * (new_v - t) - (double)(old_v - t) * (old_v - t);\n            }\n        }\n        \n        // Compute New RC Cost\n        double new_rc_cost = 0;\n        for(int r=0; r<N; ++r) {\n            double diff = row_sums[r] - est_row[r];\n            new_rc_cost += diff * diff * row_col_weight;\n        }\n        for(int c=0; c<N; ++c) {\n            double diff = col_sums[c] - est_col[c];\n            new_rc_cost += diff * diff * row_col_weight;\n        }\n        \n        double total_delta = delta_drill + (new_rc_cost - current_rc_cost);\n        \n        if (total_delta < 0 || dis(rng) < exp(-total_delta / T)) {\n            current_drill_cost += delta_drill;\n            current_rc_cost = new_rc_cost;\n            current_cost = current_drill_cost + current_rc_cost;\n            \n            cur_pos[k] = {nr, nc};\n            if (current_cost < best_cost) {\n                best_cost = current_cost;\n                copy_pos(cur_pos, best_pos);\n            }\n        } else {\n            // Revert\n            for (int i=0; i<mod_count; ++i) {\n                grid_val[mod_r[i]][mod_c[i]] = saved_grid[mod_r[i]][mod_c[i]];\n            }\n            memcpy(row_sums, backup_row_sums, sizeof(row_sums));\n            memcpy(col_sums, backup_col_sums, sizeof(col_sums));\n        }\n        \n        if (current_cost < 1e-9) { \n            copy_pos(cur_pos, best_pos);\n            break;\n        }\n        \n        T *= cooling;\n    }\n    \n    // Restore best state globally\n    copy_pos(best_pos, cur_pos);\n    init_model(); \n}\n\nint main() {\n    fast_io();\n    if (!(cin >> N >> M >> eps)) return 0;\n    \n    for (int k = 0; k < M; ++k) {\n        int d; cin >> d;\n        for (int l = 0; l < d; ++l) {\n            int r, c; cin >> r >> c;\n            shapes[k].cells.push_back({r, c});\n            max_r[k] = max(max_r[k], r);\n            max_c[k] = max(max_c[k], c);\n        }\n    }\n    \n    memset(grid_val, 0, sizeof(grid_val));\n    memset(target_val, -1, sizeof(target_val));\n    memset(is_drilled, 0, sizeof(is_drilled));\n    memset(est_row, 0, sizeof(est_row));\n    memset(est_col, 0, sizeof(est_col));\n    \n    int op_count = 0;\n    int limit = 2 * N * N;\n    \n    // Phase 1: Row/Column Divination\n    for(int i=0; i<N && op_count < limit; ++i) {\n        cout << \"q \" << N;\n        for(int j=0; j<N; ++j) cout << \" \" << i << \" \" << j;\n        cout << \"\\n\"; cout.flush();\n        int resp; cin >> resp; op_count++;\n        est_row[i] = max(0.0, (resp - N * eps) / (1 - 2 * eps));\n    }\n    for(int j=0; j<N && op_count < limit; ++j) {\n        cout << \"q \" << N;\n        for(int i=0; i<N; ++i) cout << \" \" << i << \" \" << j;\n        cout << \"\\n\"; cout.flush();\n        int resp; cin >> resp; op_count++;\n        est_col[j] = max(0.0, (resp - N * eps) / (1 - 2 * eps));\n    }\n    \n    // Dynamic weight based on inverse variance\n    double var_est = (N * eps * (1 - eps)) / pow(1 - 2 * eps, 2);\n    row_col_weight = max(0.05, 1.0 / var_est);\n    row_col_weight = min(5.0, row_col_weight);\n    \n    // Greedy Initialization\n    double heat[25][25];\n    for(int r=0; r<N; ++r) for(int c=0; c<N; ++c) heat[r][c] = est_row[r] + est_col[c];\n    \n    vector<pair<int,int>> init_pos(M);\n    for(int k=0; k<M; ++k) {\n        double max_score = -1e18;\n        pair<int,int> best_p = {0,0};\n        for(int r=0; r <= N - 1 - max_r[k]; ++r) {\n            for(int c=0; c <= N - 1 - max_c[k]; ++c) {\n                double score = 0;\n                for(const auto& cell : shapes[k].cells) score += heat[r + cell.first][c + cell.second];\n                if(score > max_score) { max_score = score; best_p = {r, c}; }\n            }\n        }\n        init_pos[k] = best_p;\n        for(const auto& cell : shapes[k].cells) heat[init_pos[k].first + cell.first][init_pos[k].second + cell.second] -= 1.5;\n    }\n    \n    run_sa(init_pos, 100000);\n    \n    auto start_time = chrono::steady_clock::now();\n    vector<pair<int,int>> current_best_pos(M);\n    for(int k=0; k<M; ++k) current_best_pos[k] = cur_pos[k];\n    \n    // Main Loop\n    while (true) {\n        auto elapsed = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count();\n        if (elapsed > 2700) break; \n        if (op_count >= limit) break;\n        \n        int iters = (elapsed < 1000) ? 100000 : 40000;\n        run_sa(current_best_pos, iters);\n        for(int k=0; k<M; k++) current_best_pos[k] = cur_pos[k];\n        \n        double row_err[25], col_err[25];\n        for(int r=0; r<N; ++r) row_err[r] = est_row[r] - row_sums[r];\n        for(int c=0; c<N; ++c) col_err[c] = est_col[c] - col_sums[c];\n        \n        // Cost check\n        // global_drill_cost is maintained incrementally in main, but recomputed in init_model inside run_sa\n        // It reflects the cost of the current best model.\n        double rc_cost = compute_rc_cost();\n        double c = global_drill_cost + rc_cost;\n        \n        // Stricter condition for guessing: must have perfect fit on drilled cells\n        bool force_guess = (elapsed > 2600 || op_count >= limit - 2);\n        bool confident = (global_drill_cost < 1e-9);\n        \n        if (confident || force_guess) {\n            if (op_count < limit) {\n                vector<pair<int,int>> guess_cells;\n                bool guessed[25][25] = {};\n                // 1. Mandatory: Include all drilled cells with oil\n                for(int r=0; r<N; ++r) for(int c_val=0; c_val<N; ++c_val) {\n                    if (is_drilled[r][c_val] && target_val[r][c_val] > 0) {\n                        guessed[r][c_val] = true; guess_cells.push_back({r, c_val});\n                    }\n                }\n                // 2. Add model-predicted cells\n                for(int k=0; k<M; ++k) {\n                    for(const auto& cell : shapes[k].cells) {\n                        int r = cell.first + cur_pos[k].first, c_val = cell.second + cur_pos[k].second;\n                        // Skip known empty cells\n                        if (is_drilled[r][c_val] && target_val[r][c_val] == 0) continue;\n                        if (!guessed[r][c_val]) { guessed[r][c_val] = true; guess_cells.push_back({r, c_val}); }\n                    }\n                }\n                \n                cout << \"a \" << guess_cells.size();\n                for (const auto& p : guess_cells) cout << \" \" << p.first << \" \" << p.second;\n                cout << \"\\n\"; cout.flush(); op_count++;\n                int res; cin >> res;\n                if (res == 1) return 0;\n            }\n        }\n        \n        if (op_count >= limit) break;\n        \n        // Smart Drilling\n        int budget = limit - op_count - 1;\n        if (budget > 0) {\n            int drills = min(10, budget);\n            struct CellInfo { int r, c; double priority; };\n            static CellInfo candidates[500]; \n            int cand_count = 0;\n            \n            for(int r=0; r<N; ++r) for(int c_val=0; c_val<N; ++c_val) {\n                if (!is_drilled[r][c_val]) {\n                    double p = 0.0;\n                    // Prioritize cells where model says 0 but constraints say > 0 (Missing Oil)\n                    if (grid_val[r][c_val] == 0) {\n                        if (row_err[r] > 0) p += row_err[r];\n                        if (col_err[c_val] > 0) p += col_err[c_val];\n                    } \n                    // Also check Phantom Oil (Model > 0 but constraints < 0? No, constraints are sums)\n                    // If Model > 0, we might want to check if it's actually 0.\n                    // But row_err < 0 means sum is lower than expected.\n                    else {\n                        if (row_err[r] < 0) p -= row_err[r];\n                        if (col_err[c_val] < 0) p -= col_err[c_val];\n                    }\n                    p += rand_double() * 0.01;\n                    candidates[cand_count++] = {r, c_val, p};\n                }\n            }\n            sort(candidates, candidates + cand_count, [](const CellInfo& a, const CellInfo& b) { return a.priority > b.priority; });\n            \n            int count = 0;\n            for(int i=0; i<cand_count; ++i) {\n                if (count >= drills) break;\n                cout << \"q 1 \" << candidates[i].r << \" \" << candidates[i].c << \"\\n\"; cout.flush();\n                int v; cin >> v; op_count++;\n                target_val[candidates[i].r][candidates[i].c] = v;\n                is_drilled[candidates[i].r][candidates[i].c] = true;\n                \n                // Update global drill cost\n                double diff = grid_val[candidates[i].r][candidates[i].c] - v;\n                global_drill_cost += diff * diff;\n                count++;\n            }\n        }\n    }\n    \n    // Final Guess\n    if (op_count < limit) {\n        run_sa(current_best_pos, 50000);\n        vector<pair<int,int>> guess_cells;\n        bool guessed[25][25] = {};\n        for(int r=0; r<N; ++r) for(int c_val=0; c_val<N; ++c_val) {\n            if (is_drilled[r][c_val] && target_val[r][c_val] > 0) {\n                guessed[r][c_val] = true; guess_cells.push_back({r, c_val});\n            }\n        }\n        for(int k=0; k<M; ++k) {\n            for(const auto& cell : shapes[k].cells) {\n                int r = cell.first + cur_pos[k].first, c_val = cell.second + cur_pos[k].second;\n                if (is_drilled[r][c_val] && target_val[r][c_val] == 0) continue;\n                if (!guessed[r][c_val]) { guessed[r][c_val] = true; guess_cells.push_back({r, c_val}); }\n            }\n        }\n        cout << \"a \" << guess_cells.size();\n        for (const auto& p : guess_cells) cout << \" \" << p.first << \" \" << p.second;\n        cout << \"\\n\"; cout.flush();\n    }\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\n#include <chrono>\n#pragma GCC optimize(\"O3,unroll-loops\")\nusing namespace std;\n\nconst int W_IN = 1000;\nconst int MAX_D = 55;\nconst int MAX_N = 55;\n\nint D_in, N_in;\nlong long A[MAX_D][MAX_N];\n\nstruct Rect {\n    int x1, y1, x2, y2;\n    long long area() const { return 1LL * (x2 - x1) * (y2 - y1); }\n};\n\nRect rects[MAX_D][MAX_N];\nRect best_rects[MAX_D][MAX_N];\n\n// H_cnt[d][y][x]: horizontal segment at row y, between x and x+1\n// V_cnt[d][x][y]: vertical segment at col x, between y and y+1\n// Transposed V for cache locality\nuint8_t H_cnt[MAX_D][W_IN + 2][W_IN + 2];\nuint8_t V_cnt[MAX_D][W_IN + 2][W_IN + 2];\n\nlong long area_pen[MAX_D][MAX_N];\nlong long total_cost = 0;\nlong long best_cost = 1LL << 60;\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\ninline long long calc_pen(const Rect& r, long long req) {\n    long long a = r.area();\n    return (req > a) ? 100LL * (req - a) : 0;\n}\n\ninline bool overlap(int d, int k, const Rect& r) {\n    for (int i = 0; i < N_in; ++i) {\n        if (i == k) continue;\n        if (rects[d][i].x1 < r.x2 && rects[d][i].x2 > r.x1 &&\n            rects[d][i].y1 < r.y2 && rects[d][i].y2 > r.y1)\n            return true;\n    }\n    return false;\n}\n\n// Calculate change in partition cost if H/V at (d, y, x) changes to new_val\ninline long long seg_delta(int d, int y, int x, bool is_h, bool new_val) {\n    bool old_val = is_h ? (H_cnt[d][y][x] > 0) : (V_cnt[d][x][y] > 0);\n    if (old_val == new_val) return 0;\n    long long delta = 0;\n    \n    // Contribution to L_d (transition d-1 -> d)\n    // This term is H_d ^ H_{d-1}. Changing H_d affects this.\n    // Valid only if d > 0.\n    if (d > 0) {\n        bool prev = is_h ? (H_cnt[d-1][y][x] > 0) : (V_cnt[d-1][x][y] > 0);\n        delta += (new_val != prev) - (old_val != prev);\n    }\n    \n    // Contribution to L_{d+1} (transition d -> d+1)\n    // This term is H_{d+1} ^ H_d. Changing H_d affects this.\n    // Valid only if d < D_in - 1.\n    if (d < D_in - 1) {\n        bool next = is_h ? (H_cnt[d+1][y][x] > 0) : (V_cnt[d+1][x][y] > 0);\n        delta += (next != new_val) - (next != old_val);\n    }\n    \n    return delta;\n}\n\nvoid pack_initial() {\n    // Grid partitioning to ensure valid initial state\n    for (int d = 0; d < D_in; ++d) {\n        int R = ceil(sqrt(N_in));\n        int C = (N_in + R - 1) / R;\n        int block_h = W_IN / R;\n        int block_w = W_IN / C;\n        int rem_h = W_IN % R;\n        int rem_w = W_IN % C;\n        \n        int cy = 0;\n        for (int r = 0; r < R; ++r) {\n            int cur_h = block_h + (r < rem_h ? 1 : 0);\n            int cx = 0;\n            for (int c = 0; c < C; ++c) {\n                int idx = r * C + c;\n                if (idx >= N_in) break;\n                int cur_w = block_w + (c < rem_w ? 1 : 0);\n                rects[d][idx] = {cx, cy, cx + cur_w, cy + cur_h};\n                cx += cur_w;\n            }\n            cy += cur_h;\n        }\n    }\n\n    memset(H_cnt, 0, sizeof(H_cnt));\n    memset(V_cnt, 0, sizeof(V_cnt));\n    total_cost = 0;\n    for (int d = 0; d < D_in; ++d) {\n        for (int k = 0; k < N_in; ++k) {\n            area_pen[d][k] = calc_pen(rects[d][k], A[d][k]);\n            total_cost += area_pen[d][k];\n            \n            // Add to grids\n            int y_vals[2] = {rects[d][k].y1, rects[d][k].y2};\n            for (int edge = 0; edge < 2; ++edge) {\n                int y = y_vals[edge];\n                if (y >= 1 && y < W_IN) {\n                    for (int x = rects[d][k].x1; x < rects[d][k].x2; ++x) {\n                        H_cnt[d][y][x]++;\n                    }\n                }\n            }\n            int x_vals[2] = {rects[d][k].x1, rects[d][k].x2};\n            for (int edge = 0; edge < 2; ++edge) {\n                int x = x_vals[edge];\n                if (x >= 1 && x < W_IN) {\n                    for (int y = rects[d][k].y1; y < rects[d][k].y2; ++y) {\n                        V_cnt[d][x][y]++;\n                    }\n                }\n            }\n        }\n    }\n    // Compute initial partition cost\n    for (int d = 1; d < D_in; ++d) {\n        for (int y = 1; y < W_IN; ++y) {\n            for (int x = 0; x < W_IN; ++x) {\n                if ((H_cnt[d][y][x] > 0) != (H_cnt[d-1][y][x] > 0)) total_cost++;\n            }\n            for (int x = 1; x < W_IN; ++x) {\n                if ((V_cnt[d][x][y] > 0) != (V_cnt[d-1][x][y] > 0)) total_cost++;\n            }\n        }\n        for (int x = 1; x < W_IN; ++x) {\n            if ((V_cnt[d][x][W_IN-1] > 0) != (V_cnt[d-1][x][W_IN-1] > 0)) total_cost++;\n        }\n    }\n}\n\n// Generate a candidate move using a mix of perturbation and snapping\nRect generate_move(int d, int k) {\n    Rect old_r = rects[d][k];\n    Rect new_r;\n    \n    // Strategy: 20% Snap, 80% Perturb\n    int strategy = rng() % 100;\n    \n    if (strategy < 20 && D_in > 1) {\n        // Snap strategy: try to align with a wall from a neighbor day\n        int nd = -1;\n        if (d > 0 && d < D_in - 1) nd = (rng() % 2 == 0) ? d - 1 : d + 1;\n        else if (d > 0) nd = d - 1;\n        else if (d < D_in - 1) nd = d + 1;\n        \n        if (nd != -1) {\n            int nk = rng() % N_in;\n            Rect& nr = rects[nd][nk];\n            int snap_type = rng() % 4; // 0:x1, 1:x2, 2:y1, 3:y2\n            \n            new_r = old_r;\n            if (snap_type == 0) { // Snap x1\n                new_r.x1 = (rng() % 2 == 0) ? nr.x1 : nr.x2;\n                new_r.x2 = new_r.x1 + (old_r.x2 - old_r.x1);\n                if (new_r.x2 > W_IN) new_r.x2 = W_IN;\n            } else if (snap_type == 1) { // Snap x2\n                new_r.x2 = (rng() % 2 == 0) ? nr.x1 : nr.x2;\n                new_r.x1 = new_r.x2 - (old_r.x2 - old_r.x1);\n                if (new_r.x1 < 0) new_r.x1 = 0;\n            } else if (snap_type == 2) { // Snap y1\n                new_r.y1 = (rng() % 2 == 0) ? nr.y1 : nr.y2;\n                new_r.y2 = new_r.y1 + (old_r.y2 - old_r.y1);\n                if (new_r.y2 > W_IN) new_r.y2 = W_IN;\n            } else { // Snap y2\n                new_r.y2 = (rng() % 2 == 0) ? nr.y1 : nr.y2;\n                new_r.y1 = new_r.y2 - (old_r.y2 - old_r.y1);\n                if (new_r.y1 < 0) new_r.y1 = 0;\n            }\n            \n            // Validity checks\n            if (new_r.x1 >= new_r.x2 || new_r.y1 >= new_r.y2) return old_r;\n            if (overlap(d, k, new_r)) return old_r;\n            return new_r;\n        }\n    }\n    \n    // Perturb strategy\n    uniform_int_distribution<int> dist_dx(-5, 5);\n    uniform_int_distribution<int> dist_dw(-3, 3);\n    \n    int dx = dist_dx(rng);\n    int dy = dist_dx(rng);\n    int dw = dist_dw(rng);\n    int dh = dist_dw(rng);\n    \n    new_r.x1 = max(0, min(W_IN - 1, old_r.x1 + dx));\n    new_r.y1 = max(0, min(W_IN - 1, old_r.y1 + dy));\n    new_r.x2 = max(new_r.x1 + 1, min(W_IN, old_r.x2 + dw));\n    new_r.y2 = max(new_r.y1 + 1, min(W_IN, old_r.y2 + dh));\n    \n    long long cur_area = new_r.area();\n    if (cur_area < A[d][k]) {\n        long long needed = A[d][k];\n        int h = new_r.y2 - new_r.y1;\n        int add_w = max(0, (int)((needed + h - 1) / h) - (new_r.x2 - new_r.x1));\n        if (new_r.x2 + add_w <= W_IN) new_r.x2 += add_w;\n        else {\n            int w = new_r.x2 - new_r.x1;\n            int add_h = max(0, (int)((needed + w - 1) / w) - h);\n            if (new_r.y2 + add_h <= W_IN) new_r.y2 += add_h;\n            else return old_r;\n        }\n    }\n    \n    if (overlap(d, k, new_r)) return old_r;\n    return new_r;\n}\n\nvoid run_sa() {\n    auto start = chrono::high_resolution_clock::now();\n    double temp = 10000.0;\n    const double initial_temp = temp;\n    const double total_time = 2800.0;\n    \n    while (true) {\n        double elapsed = chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start).count();\n        if (elapsed >= total_time) break;\n        temp = initial_temp * exp(-3.0 * elapsed / total_time); // Cooling\n\n        int d = rng() % D_in;\n        int k = rng() % N_in;\n        Rect old_r = rects[d][k];\n        \n        Rect new_r = generate_move(d, k);\n        \n        // Check if move is identity\n        if (new_r.x1 == old_r.x1 && new_r.y1 == old_r.y1 && \n            new_r.x2 == old_r.x2 && new_r.y2 == old_r.y2) continue;\n\n        // Redundant check but fast\n        if (overlap(d, k, new_r)) continue; \n\n        long long delta = calc_pen(new_r, A[d][k]) - area_pen[d][k];\n        \n        // Partition delta calculation\n        // Remove old edges\n        int y_vals[2] = {old_r.y1, old_r.y2};\n        for (int edge = 0; edge < 2; ++edge) {\n            int y = y_vals[edge];\n            if (y >= 1 && y < W_IN) {\n                for (int x = old_r.x1; x < old_r.x2; ++x) {\n                    if (H_cnt[d][y][x] == 1) delta += seg_delta(d, y, x, true, false);\n                }\n            }\n        }\n        int x_vals[2] = {old_r.x1, old_r.x2};\n        for (int edge = 0; edge < 2; ++edge) {\n            int x = x_vals[edge];\n            if (x >= 1 && x < W_IN) {\n                for (int y = old_r.y1; y < old_r.y2; ++y) {\n                    if (V_cnt[d][x][y] == 1) delta += seg_delta(d, y, x, false, false);\n                }\n            }\n        }\n\n        // Add new edges\n        int ny_vals[2] = {new_r.y1, new_r.y2};\n        for (int edge = 0; edge < 2; ++edge) {\n            int y = ny_vals[edge];\n            if (y >= 1 && y < W_IN) {\n                for (int x = new_r.x1; x < new_r.x2; ++x) {\n                    if (H_cnt[d][y][x] == 0) delta += seg_delta(d, y, x, true, true);\n                }\n            }\n        }\n        int nx_vals[2] = {new_r.x1, new_r.x2};\n        for (int edge = 0; edge < 2; ++edge) {\n            int x = nx_vals[edge];\n            if (x >= 1 && x < W_IN) {\n                for (int y = new_r.y1; y < new_r.y2; ++y) {\n                    if (V_cnt[d][x][y] == 0) delta += seg_delta(d, y, x, false, true);\n                }\n            }\n        }\n\n        if (delta < 0 || (double)rng() / 4294967296.0 < exp(-delta / temp)) {\n            // Apply removal\n            for (int edge = 0; edge < 2; ++edge) {\n                int y = y_vals[edge];\n                if (y >= 1 && y < W_IN) for (int x = old_r.x1; x < old_r.x2; ++x) H_cnt[d][y][x]--;\n            }\n            for (int edge = 0; edge < 2; ++edge) {\n                int x = x_vals[edge];\n                if (x >= 1 && x < W_IN) for (int y = old_r.y1; y < old_r.y2; ++y) V_cnt[d][x][y]--;\n            }\n            // Apply addition\n            for (int edge = 0; edge < 2; ++edge) {\n                int y = ny_vals[edge];\n                if (y >= 1 && y < W_IN) for (int x = new_r.x1; x < new_r.x2; ++x) H_cnt[d][y][x]++;\n            }\n            for (int edge = 0; edge < 2; ++edge) {\n                int x = nx_vals[edge];\n                if (x >= 1 && x < W_IN) for (int y = new_r.y1; y < new_r.y2; ++y) V_cnt[d][x][y]++;\n            }\n            \n            rects[d][k] = new_r;\n            area_pen[d][k] = calc_pen(new_r, A[d][k]);\n            total_cost += delta;\n            if (total_cost < best_cost) {\n                best_cost = total_cost;\n                memcpy(best_rects, rects, sizeof(rects));\n            }\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int W_temp;\n    if (!(cin >> W_temp >> D_in >> N_in)) return 0;\n    \n    for (int d = 0; d < D_in; ++d)\n        for (int k = 0; k < N_in; ++k)\n            cin >> A[d][k];\n\n    pack_initial();\n    best_cost = total_cost;\n    memcpy(best_rects, rects, sizeof(rects));\n    \n    run_sa();\n\n    for (int d = 0; d < D_in; ++d) {\n        for (int k = 0; k < N_in; ++k) {\n            Rect& r = best_rects[d][k];\n            // Safety clamp\n            r.x1 = max(0, min(W_IN - 1, r.x1));\n            r.y1 = max(0, min(W_IN - 1, r.y1));\n            r.x2 = max(r.x1 + 1, min(W_IN, r.x2));\n            r.y2 = max(r.y1 + 1, min(W_IN, r.y2));\n            cout << r.y1 << \" \" << r.x1 << \" \" << r.y2 << \" \" << r.x2 << \"\\n\";\n        }\n    }\n    return 0;\n}","ahc032":"/*\n    Solution for Heuristic Problem (N=9, M=20, K=81)\n    Algorithm: Simulated Annealing with Local Stamp Optimization & Targeted Moves\n    \n    Key Features:\n    1. Greedy Initialization: Fills board with locally optimal moves.\n    2. Local Search on Stamps: For a chosen position, iterates all stamps to find the best one.\n    3. Targeted Moves: 50% of the time, targets the cell with the minimum value to fix it.\n    4. Reheating: Restarts temperature if stuck in a local optimum.\n    5. Efficient Modulo Arithmetic: Uses conditional subtraction/addition.\n*/\n\n#include <bits/stdc++.h>\n#pragma GCC optimize(\"O3,unroll-loops\")\n\nusing namespace std;\nusing ll = long long;\n\nconst int N = 9;\nconst int M = 20;\nconst int K = 81;\nconst int MOD = 998244353;\n\nint init_board[N][N];\nint board_mod[N][N];\nint stamps[M][3][3];\n\nstruct Op { uint8_t m, p, q; };\nOp ops[K], best_ops[K];\nll current_score = 0;\nll best_score = -1;\n\n// Fast RNG\nuint64_t rng_state;\ninline uint64_t my_rand() {\n    uint64_t x = rng_state;\n    x ^= x << 13; x ^= x >> 7; x ^= x << 17;\n    return rng_state = x;\n}\ninline int rand_int(int n) { return (int)(my_rand() % n); }\n\n// Calculate score change if we ADD stamp m at (p, q)\ninline ll calc_delta(int m, int p, int q) {\n    ll d = 0;\n    const int* s0 = stamps[m][0];\n    const int* s1 = stamps[m][1];\n    const int* s2 = stamps[m][2];\n    \n    const int* r0 = &board_mod[p][0];\n    const int* r1 = &board_mod[p+1][0];\n    const int* r2 = &board_mod[p+2][0];\n    \n    int offset = q;\n    int v;\n    \n    v = r0[offset] + s0[0]; if (v >= MOD) v -= MOD; d += v - r0[offset];\n    v = r0[offset+1] + s0[1]; if (v >= MOD) v -= MOD; d += v - r0[offset+1];\n    v = r0[offset+2] + s0[2]; if (v >= MOD) v -= MOD; d += v - r0[offset+2];\n    \n    v = r1[offset] + s1[0]; if (v >= MOD) v -= MOD; d += v - r1[offset];\n    v = r1[offset+1] + s1[1]; if (v >= MOD) v -= MOD; d += v - r1[offset+1];\n    v = r1[offset+2] + s1[2]; if (v >= MOD) v -= MOD; d += v - r1[offset+2];\n    \n    v = r2[offset] + s2[0]; if (v >= MOD) v -= MOD; d += v - r2[offset];\n    v = r2[offset+1] + s2[1]; if (v >= MOD) v -= MOD; d += v - r2[offset+1];\n    v = r2[offset+2] + s2[2]; if (v >= MOD) v -= MOD; d += v - r2[offset+2];\n    \n    return d;\n}\n\n// Calculate score change if we REMOVE stamp m at (p, q)\ninline ll calc_remove_delta(int m, int p, int q) {\n    ll d = 0;\n    const int* s0 = stamps[m][0];\n    const int* s1 = stamps[m][1];\n    const int* s2 = stamps[m][2];\n    \n    const int* r0 = &board_mod[p][0];\n    const int* r1 = &board_mod[p+1][0];\n    const int* r2 = &board_mod[p+2][0];\n    \n    int offset = q;\n    int v;\n    \n    v = r0[offset] - s0[0]; if (v < 0) v += MOD; d += v - r0[offset];\n    v = r0[offset+1] - s0[1]; if (v < 0) v += MOD; d += v - r0[offset+1];\n    v = r0[offset+2] - s0[2]; if (v < 0) v += MOD; d += v - r0[offset+2];\n    \n    v = r1[offset] - s1[0]; if (v < 0) v += MOD; d += v - r1[offset];\n    v = r1[offset+1] - s1[1]; if (v < 0) v += MOD; d += v - r1[offset+1];\n    v = r1[offset+2] - s1[2]; if (v < 0) v += MOD; d += v - r1[offset+2];\n    \n    v = r2[offset] - s2[0]; if (v < 0) v += MOD; d += v - r2[offset];\n    v = r2[offset+1] - s2[1]; if (v < 0) v += MOD; d += v - r2[offset+1];\n    v = r2[offset+2] - s2[2]; if (v < 0) v += MOD; d += v - r2[offset+2];\n    \n    return d;\n}\n\ninline void apply(int m, int p, int q) {\n    const int* s0 = stamps[m][0];\n    const int* s1 = stamps[m][1];\n    const int* s2 = stamps[m][2];\n    \n    int* r0 = &board_mod[p][0];\n    int* r1 = &board_mod[p+1][0];\n    int* r2 = &board_mod[p+2][0];\n    \n    int offset = q;\n    int v;\n    \n    v = r0[offset] + s0[0]; if (v >= MOD) v -= MOD; r0[offset] = v;\n    v = r0[offset+1] + s0[1]; if (v >= MOD) v -= MOD; r0[offset+1] = v;\n    v = r0[offset+2] + s0[2]; if (v >= MOD) v -= MOD; r0[offset+2] = v;\n    \n    v = r1[offset] + s1[0]; if (v >= MOD) v -= MOD; r1[offset] = v;\n    v = r1[offset+1] + s1[1]; if (v >= MOD) v -= MOD; r1[offset+1] = v;\n    v = r1[offset+2] + s1[2]; if (v >= MOD) v -= MOD; r1[offset+2] = v;\n    \n    v = r2[offset] + s2[0]; if (v >= MOD) v -= MOD; r2[offset] = v;\n    v = r2[offset+1] + s2[1]; if (v >= MOD) v -= MOD; r2[offset+1] = v;\n    v = r2[offset+2] + s2[2]; if (v >= MOD) v -= MOD; r2[offset+2] = v;\n}\n\ninline void revert(int m, int p, int q) {\n    const int* s0 = stamps[m][0];\n    const int* s1 = stamps[m][1];\n    const int* s2 = stamps[m][2];\n    \n    int* r0 = &board_mod[p][0];\n    int* r1 = &board_mod[p+1][0];\n    int* r2 = &board_mod[p+2][0];\n    \n    int offset = q;\n    int v;\n    \n    v = r0[offset] - s0[0]; if (v < 0) v += MOD; r0[offset] = v;\n    v = r0[offset+1] - s0[1]; if (v < 0) v += MOD; r0[offset+1] = v;\n    v = r0[offset+2] - s0[2]; if (v < 0) v += MOD; r0[offset+2] = v;\n    \n    v = r1[offset] - s1[0]; if (v < 0) v += MOD; r1[offset] = v;\n    v = r1[offset+1] - s1[1]; if (v < 0) v += MOD; r1[offset+1] = v;\n    v = r1[offset+2] - s1[2]; if (v < 0) v += MOD; r1[offset+2] = v;\n    \n    v = r2[offset] - s2[0]; if (v < 0) v += MOD; r2[offset] = v;\n    v = r2[offset+1] - s2[1]; if (v < 0) v += MOD; r2[offset+1] = v;\n    v = r2[offset+2] - s2[2]; if (v < 0) v += MOD; r2[offset+2] = v;\n}\n\nvoid greedy_init() {\n    for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) board_mod[i][j] = init_board[i][j];\n    \n    for(int k=0; k<K; ++k) {\n        int best_m = -1, best_p = -1, best_q = -1;\n        ll best_d = -4000000000000000000LL;\n        \n        for(int m=0; m<M; ++m) {\n            const int* s0 = stamps[m][0];\n            const int* s1 = stamps[m][1];\n            const int* s2 = stamps[m][2];\n            \n            for(int p=0; p<=N-3; ++p) {\n                const int* r0 = &board_mod[p][0];\n                const int* r1 = &board_mod[p+1][0];\n                const int* r2 = &board_mod[p+2][0];\n                \n                for(int q=0; q<=N-3; ++q) {\n                    ll d = 0;\n                    int v;\n                    int offset = q;\n                    \n                    v = r0[offset] + s0[0]; if (v >= MOD) v -= MOD; d += v - r0[offset];\n                    v = r0[offset+1] + s0[1]; if (v >= MOD) v -= MOD; d += v - r0[offset+1];\n                    v = r0[offset+2] + s0[2]; if (v >= MOD) v -= MOD; d += v - r0[offset+2];\n                    v = r1[offset] + s1[0]; if (v >= MOD) v -= MOD; d += v - r1[offset];\n                    v = r1[offset+1] + s1[1]; if (v >= MOD) v -= MOD; d += v - r1[offset+1];\n                    v = r1[offset+2] + s1[2]; if (v >= MOD) v -= MOD; d += v - r1[offset+2];\n                    v = r2[offset] + s2[0]; if (v >= MOD) v -= MOD; d += v - r2[offset];\n                    v = r2[offset+1] + s2[1]; if (v >= MOD) v -= MOD; d += v - r2[offset+1];\n                    v = r2[offset+2] + s2[2]; if (v >= MOD) v -= MOD; d += v - r2[offset+2];\n                    \n                    if(d > best_d) {\n                        best_d = d; best_m = m; best_p = p; best_q = q;\n                    }\n                }\n            }\n        }\n        \n        if (best_m != -1) {\n            ops[k] = {(uint8_t)best_m, (uint8_t)best_p, (uint8_t)best_q};\n            apply(best_m, best_p, best_q);\n        } else {\n            ops[k] = {0, 0, 0};\n        }\n    }\n    current_score = 0;\n    for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) current_score += board_mod[i][j];\n}\n\n// Find cell with minimum value\ninline void find_min_cell(int &r, int &c) {\n    int min_val = MOD;\n    r = 0; c = 0;\n    for(int i=0; i<N; ++i) {\n        const int* row = board_mod[i];\n        for(int j=0; j<N; ++j) {\n            if(row[j] < min_val) {\n                min_val = row[j];\n                r = i;\n                c = j;\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N_in, M_in, K_in;\n    if(!(cin >> N_in >> M_in >> K_in)) return 0;\n    \n    for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) { \n        cin >> init_board[i][j]; \n        board_mod[i][j] = init_board[i][j] % MOD; \n    }\n    for(int m=0; m<M; ++m) for(int i=0; i<3; ++i) for(int j=0; j<3; ++j) { \n        cin >> stamps[m][i][j]; \n        stamps[m][i][j] %= MOD;\n    }\n\n    rng_state = chrono::steady_clock::now().time_since_epoch().count();\n    auto t_start = chrono::steady_clock::now();\n    const double TIME_LIMIT = 1.92;\n\n    greedy_init();\n    best_score = current_score;\n    memcpy(best_ops, ops, sizeof(Op)*K);\n\n    double T = 2e9;\n    const double T_END = 0.5;\n    double log_ratio = log(T_END / T);\n    \n    const int MAX_PQ = N - 2; \n    const int MAX_PQ_IDX = N - 3; \n    \n    int steps = 0;\n    const int CHECK_INTERVAL = 500;\n    int stagnation_steps = 0;\n    const int REHEAT_THRESHOLD = 40000;\n\n    while(true) {\n        steps++;\n        if(steps % CHECK_INTERVAL == 0) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - t_start).count();\n            if(elapsed > TIME_LIMIT) break;\n            \n            double progress = elapsed / TIME_LIMIT;\n            if(progress >= 1.0) progress = 1.0;\n            \n            T = 2e9 * exp(progress * log_ratio);\n            if(T < T_END) T = T_END;\n            \n            if(stagnation_steps > REHEAT_THRESHOLD) {\n                T = max(T, 1e6); \n                stagnation_steps = 0;\n            }\n        }\n\n        int idx = rand_int(K);\n        Op old_op = ops[idx];\n        ll d_rem = calc_remove_delta(old_op.m, old_op.p, old_op.q);\n        revert(old_op.m, old_op.p, old_op.q);\n        \n        int target_p, target_q;\n        // 50% Random Position, 50% Targeted (Min Cell)\n        if ((my_rand() & 1) == 0) {\n            target_p = rand_int(MAX_PQ);\n            target_q = rand_int(MAX_PQ);\n        } else {\n            int r_min, c_min;\n            find_min_cell(r_min, c_min);\n            int p_min = r_min - 2; if (p_min < 0) p_min = 0;\n            int p_max = r_min; if (p_max > MAX_PQ_IDX) p_max = MAX_PQ_IDX;\n            int q_min = c_min - 2; if (q_min < 0) q_min = 0;\n            int q_max = c_min; if (q_max > MAX_PQ_IDX) q_max = MAX_PQ_IDX;\n            \n            // Fallback just in case\n            if (p_min > p_max) { p_min = 0; p_max = MAX_PQ_IDX; }\n            if (q_min > q_max) { q_min = 0; q_max = MAX_PQ_IDX; }\n            \n            target_p = p_min + rand_int(p_max - p_min + 1);\n            target_q = q_min + rand_int(q_max - q_min + 1);\n        }\n        \n        int best_m = -1;\n        ll best_d_add = -4000000000000000000LL;\n        \n        // Local Search: Find best stamp for the chosen position\n        for(int m=0; m<M; ++m) {\n            ll d = 0;\n            const int* s0 = stamps[m][0];\n            const int* s1 = stamps[m][1];\n            const int* s2 = stamps[m][2];\n            \n            const int* r0 = &board_mod[target_p][0];\n            const int* r1 = &board_mod[target_p+1][0];\n            const int* r2 = &board_mod[target_p+2][0];\n            \n            int offset = target_q;\n            int v;\n            \n            v = r0[offset] + s0[0]; if (v >= MOD) v -= MOD; d += v - r0[offset];\n            v = r0[offset+1] + s0[1]; if (v >= MOD) v -= MOD; d += v - r0[offset+1];\n            v = r0[offset+2] + s0[2]; if (v >= MOD) v -= MOD; d += v - r0[offset+2];\n            v = r1[offset] + s1[0]; if (v >= MOD) v -= MOD; d += v - r1[offset];\n            v = r1[offset+1] + s1[1]; if (v >= MOD) v -= MOD; d += v - r1[offset+1];\n            v = r1[offset+2] + s1[2]; if (v >= MOD) v -= MOD; d += v - r1[offset+2];\n            v = r2[offset] + s2[0]; if (v >= MOD) v -= MOD; d += v - r2[offset];\n            v = r2[offset+1] + s2[1]; if (v >= MOD) v -= MOD; d += v - r2[offset+1];\n            v = r2[offset+2] + s2[2]; if (v >= MOD) v -= MOD; d += v - r2[offset+2];\n            \n            if(d > best_d_add) {\n                best_d_add = d;\n                best_m = m;\n            }\n        }\n        \n        ll total_delta = d_rem + best_d_add;\n        bool accept = false;\n        if(total_delta > 0) accept = true;\n        else if(T > T_END && total_delta > -30.0 * T) {\n            double prob = exp((double)total_delta / T);\n            if((double)(my_rand() & 0xFFFFFFFF) / 4294967296.0 < prob) accept = true;\n        }\n        \n        bool improved_global = false;\n        if(accept) {\n            apply(best_m, target_p, target_q);\n            ops[idx] = {(uint8_t)best_m, (uint8_t)target_p, (uint8_t)target_q};\n            current_score += total_delta;\n            if(current_score > best_score) {\n                best_score = current_score;\n                memcpy(best_ops, ops, sizeof(Op)*K);\n                improved_global = true;\n            }\n        } else {\n            apply(old_op.m, old_op.p, old_op.q);\n        }\n        \n        if(improved_global) stagnation_steps = 0;\n        else stagnation_steps++;\n    }\n\n    for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) board_mod[i][j] = init_board[i][j];\n    int L = K;\n    for(int k=0; k<L; ++k) apply(best_ops[k].m, best_ops[k].p, best_ops[k].q);\n    \n    bool improved = true;\n    while(improved && L > 0) {\n        improved = false;\n        int best_idx = -1; \n        ll max_d = 0;\n        \n        for(int k=0; k<L; ++k) {\n            ll d = calc_remove_delta(best_ops[k].m, best_ops[k].p, best_ops[k].q);\n            if(d > max_d) { \n                max_d = d; \n                best_idx = k; \n            }\n        }\n        \n        if(best_idx != -1) {\n            revert(best_ops[best_idx].m, best_ops[best_idx].p, best_ops[best_idx].q);\n            for(int k=best_idx; k<L-1; ++k) best_ops[k] = best_ops[k+1];\n            L--;\n            improved = true;\n        }\n    }\n\n    cout << L << \"\\n\";\n    for(int k=0; k<L; ++k) {\n        cout << (int)best_ops[k].m << \" \" << (int)best_ops[k].p << \" \" << (int)best_ops[k].q << \"\\n\";\n    }\n    \n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <tuple>\n#include <cstring>\n#include <algorithm>\n\nusing namespace std;\n\n// Constants\nconst int N = 5;\nconst int INF = 1e9;\n\n// State\nint grid[N][N]; // -1 if empty\nint crane_r[5], crane_c[5];\nint crane_hold[5]; // -1 if empty\nbool is_large[5];\n\nint dnext[5]; // Next expected container for row i\nint rptr[5];  // Next receiving index for row i\n\n// To store moves\nstring moves[5];\n\n// Helper to check valid coordinates\nbool valid(int r, int c) {\n    return r >= 0 && r < N && c >= 0 && c < N;\n}\n\n// BFS Pathfinding with Sequential MAPF\n// Returns {next_r, next_c} of the first step.\n// Uses temp_grid for container obstacles.\n// Uses planned_pos for higher priority cranes, current_pos for lower priority.\npair<int, int> get_first_step(int start_r, int start_c, int target_r, int target_c, \n                              int k, bool holding, bool large,\n                              int planned_r[], int planned_c[], \n                              int current_r[], int current_c[],\n                              int temp_grid[][N]) {\n    if (start_r == target_r && start_c == target_c) return {-1, -1};\n\n    queue<tuple<int, int, int>> q; // r, c, dist\n    q.push({start_r, start_c, 0});\n    \n    int dist[N][N];\n    int pr[N][N], pc[N][N]; // parent\n    for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) {\n        dist[i][j] = INF;\n        pr[i][j] = pc[i][j] = -1;\n    }\n    dist[start_r][start_c] = 0;\n    \n    int dr[4] = {-1, 1, 0, 0};\n    int dc[4] = {0, 0, -1, 1};\n    \n    while(!q.empty()) {\n        auto [r, c, d] = q.front(); q.pop();\n        \n        // If we reached the target, reconstruct path\n        if (r == target_r && c == target_c) {\n            int curr_r = r, curr_c = c;\n            // Trace back until we hit the start\n            while (pr[curr_r][curr_c] != start_r || pc[curr_r][curr_c] != start_c) {\n                int tr = pr[curr_r][curr_c];\n                int tc = pc[curr_r][curr_c];\n                if (tr == -1) return {-1, -1}; // Should not happen if target reached\n                curr_r = tr; curr_c = tc;\n            }\n            return {curr_r, curr_c};\n        }\n\n        for(int i=0; i<4; ++i) {\n            int nr = r + dr[i];\n            int nc = c + dc[i];\n            \n            if (!valid(nr, nc)) continue;\n            if (dist[nr][nc] != INF) continue;\n            \n            // Check obstacles\n            // 1. Grid Container (only if small crane holding)\n            // We use temp_grid to account for intra-turn changes\n            if (!large && holding && temp_grid[nr][nc] != -1) continue;\n            \n            // 2. Cranes (MAPF Logic)\n            bool blocked = false;\n            for (int j = 0; j < 5; ++j) {\n                if (j == k) continue;\n                // For higher priority (j < k), use planned position\n                // For lower priority (j > k), use current position\n                int obs_r = (j < k) ? planned_r[j] : current_r[j];\n                int obs_c = (j < k) ? planned_c[j] : current_c[j];\n                \n                if (nr == obs_r && nc == obs_c) {\n                    blocked = true; \n                    break;\n                }\n            }\n            if (blocked) continue;\n            \n            dist[nr][nc] = d + 1;\n            pr[nr][nc] = r;\n            pc[nr][nc] = c;\n            q.push({nr, nc, d + 1});\n        }\n    }\n    return {-1, -1};\n}\n\nint main() {\n    // Fast I/O\n    cin.tie(nullptr); ios::sync_with_stdio(false);\n\n    int input_N;\n    if (!(cin >> input_N)) return 0;\n    \n    // Initialize Grid\n    memset(grid, -1, sizeof(grid));\n    \n    // Read Input\n    // A[i][j] is the j-th container brought into gate i.\n    // We don't need to store the whole matrix, but we need the receiving order.\n    // The input gives the full sequence.\n    vector<vector<int>> A(N, vector<int>(N));\n    for(int i=0; i<N; ++i)\n        for(int j=0; j<N; ++j)\n            cin >> A[i][j];\n\n    // Initial Crane State\n    for(int i=0; i<5; ++i) {\n        crane_r[i] = i;\n        crane_c[i] = 0;\n        crane_hold[i] = -1;\n        is_large[i] = (i == 0);\n    }\n    \n    // Dispatch and Receiving State\n    for(int i=0; i<5; ++i) {\n        dnext[i] = i * 5;\n        rptr[i] = 0;\n    }\n    \n    // Main Loop\n    for(int turn=1; turn<=10000; ++turn) {\n        \n        // --- Step 1: Receiving ---\n        for(int i=0; i<N; ++i) {\n            if (rptr[i] < N) {\n                // Check if receiving is blocked\n                bool blocked = false;\n                // 1. Container at (i, 0)?\n                if (grid[i][0] != -1) blocked = true;\n                // 2. Crane at (i, 0) holding container?\n                if (!blocked) {\n                    for(int k=0; k<5; ++k) {\n                        if (crane_r[k] == i && crane_c[k] == 0 && crane_hold[k] != -1) {\n                            blocked = true;\n                            break;\n                        }\n                    }\n                }\n                \n                if (!blocked) {\n                    grid[i][0] = A[i][rptr[i]];\n                    rptr[i]++;\n                }\n            }\n        }\n\n        // --- Step 2: Planning ---\n        char acts[5];\n        int planned_r[5], planned_c[5];\n        int current_r[5], current_c[5];\n        \n        for(int i=0; i<5; ++i) {\n            current_r[i] = crane_r[i];\n            current_c[i] = crane_c[i];\n            planned_r[i] = crane_r[i];\n            planned_c[i] = crane_c[i];\n            acts[i] = '.';\n        }\n\n        // Temp grid for simulation during planning\n        int temp_grid[N][N];\n        memcpy(temp_grid, grid, sizeof(grid));\n\n        // Priority: Large (0) -> Small (1..4)\n        int order[5] = {0, 1, 2, 3, 4};\n\n        for(int idx=0; idx<5; ++idx) {\n            int k = order[idx];\n            int r = current_r[k];\n            int c = current_c[k];\n            bool hold = (crane_hold[k] != -1);\n            bool large = is_large[k];\n            \n            int target_r = -1, target_c = -1;\n            char best_act = '.';\n            bool action_found = false;\n\n            // --- Priority 1: Unblock Receiving ---\n            // If at Col 0 and holding, MUST move away.\n            if (c == 0 && hold) {\n                // Try to move to Col 1.\n                target_r = r; target_c = 1;\n                // If Col 1 is blocked, BFS might fail. \n                // We rely on BFS to find *a* path out, but (r,1) is the target.\n                // If BFS fails to (r,1), we might need to try Up/Down.\n                // But for now, aiming for (r,1) is standard.\n            }\n\n            // --- Priority 2: Dispatch ---\n            if (!action_found && hold) {\n                int cid = crane_hold[k];\n                int target_row = cid / 5;\n                bool is_next = (cid == dnext[target_row]);\n                \n                if (r == target_row && c == 4) {\n                    // Already at dispatch gate. Drop if correct item.\n                    // Q action: valid if square empty of containers (checked by temp_grid)\n                    if (temp_grid[r][c] == -1) {\n                        best_act = 'Q';\n                        action_found = true;\n                        // Update temp_grid for subsequent agents\n                        temp_grid[r][c] = cid;\n                    }\n                } else {\n                    // Not at gate.\n                    if (is_next) {\n                        target_r = target_row; target_c = 4;\n                    } else {\n                        target_r = target_row; target_c = 3; // Buffer\n                    }\n                }\n            }\n\n            // --- Priority 3: Pickup ---\n            if (!action_found && !hold) {\n                // Pick up if standing on container\n                if (temp_grid[r][c] != -1) {\n                    best_act = 'P';\n                    action_found = true;\n                    temp_grid[r][c] = -1; // Remove from grid\n                } else {\n                    // Find nearest useful container\n                    int best_score = INF;\n                    int best_tr = -1, best_tc = -1;\n                    \n                    for(int rr=0; rr<N; ++rr) {\n                        for(int cc=0; cc<N; ++cc) {\n                            if (temp_grid[rr][cc] == -1) continue;\n                            int cid = temp_grid[rr][cc];\n                            \n                            // Check if held by anyone else (in reality)\n                            // Since temp_grid is updated, if it's here, it's not held.\n                            \n                            int row = cid / 5;\n                            bool is_next = (cid == dnext[row]);\n                            \n                            int dist = abs(r - rr) + abs(c - cc);\n                            int score = dist - (is_next ? 500 : 0); // Bonus for needed item\n                            \n                            if (score < best_score) {\n                                best_score = score;\n                                best_tr = rr;\n                                best_tc = cc;\n                            }\n                        }\n                    }\n                    \n                    if (best_tr != -1) {\n                        target_r = best_tr;\n                        target_c = best_tc;\n                    }\n                }\n            }\n\n            // --- Priority 4: Move to Target ---\n            if (!action_found && target_r != -1) {\n                pair<int, int> res = get_first_step(r, c, target_r, target_c, k, hold, large,\n                                                    planned_r, planned_c, current_r, current_c, temp_grid);\n                if (res.first != -1) {\n                    int nr = res.first;\n                    int nc = res.second;\n                    \n                    if (nr < r) best_act = 'U';\n                    else if (nr > r) best_act = 'D';\n                    else if (nc < c) best_act = 'L';\n                    else if (nc > c) best_act = 'R';\n                    \n                    planned_r[k] = nr;\n                    planned_c[k] = nc;\n                    action_found = true;\n                }\n            }\n\n            // --- Priority 5: Drop to Unblock (Fallback) ---\n            // If stuck and holding, and not at Col 0 (blocking receiving)\n            if (!action_found && hold) {\n                if (temp_grid[r][c] == -1 && c != 0) {\n                    best_act = 'Q';\n                    action_found = true;\n                    temp_grid[r][c] = crane_hold[k];\n                }\n            }\n            \n            acts[k] = best_act;\n            // planned_r/c already updated if moved\n        }\n\n        // --- Execute ---\n        // Move\n        for(int k=0; k<5; ++k) {\n            if (acts[k] != 'P' && acts[k] != 'Q') {\n                crane_r[k] = planned_r[k];\n                crane_c[k] = planned_c[k];\n            }\n        }\n        \n        // Pick / Drop\n        for(int k=0; k<5; ++k) {\n            if (acts[k] == 'P') {\n                if (crane_hold[k] == -1 && grid[crane_r[k]][crane_c[k]] != -1) {\n                    crane_hold[k] = grid[crane_r[k]][crane_c[k]];\n                    grid[crane_r[k]][crane_c[k]] = -1;\n                }\n            } else if (acts[k] == 'Q') {\n                if (crane_hold[k] != -1 && grid[crane_r[k]][crane_c[k]] == -1) {\n                    grid[crane_r[k]][crane_c[k]] = crane_hold[k];\n                    crane_hold[k] = -1;\n                }\n            }\n        }\n\n        // Record moves\n        for(int k=0; k<5; ++k) moves[k] += acts[k];\n\n        // --- Step 3: Dispatch ---\n        bool all_done = true;\n        for(int i=0; i<N; ++i) {\n            if (grid[i][4] != -1) {\n                int cid = grid[i][4];\n                grid[i][4] = -1; // Remove\n                if (cid == dnext[i]) {\n                    dnext[i]++;\n                }\n            }\n            if (dnext[i] != i*5 + 5) all_done = false;\n        }\n        \n        if (all_done) break;\n    }\n\n    for(int i=0; i<5; ++i) cout << moves[i] << \"\\n\";\n    \n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n#pragma GCC optimize(\"O3,unroll-loops\")\n\nint N;\nint grid[20][20];\nint cur_r = 0, cur_c = 0;\nlong long load = 0;\nint turns = 0;\n\ninline int manhattan(int r1, int c1, int r2, int c2) {\n    return abs(r1 - r2) + abs(c1 - c2);\n}\n\nvoid output_move(char dir) {\n    cout << dir << \"\\n\";\n    turns++;\n    if (dir == 'U') cur_r--;\n    else if (dir == 'D') cur_r++;\n    else if (dir == 'L') cur_c--;\n    else if (dir == 'R') cur_c++;\n}\n\nvoid move_to(int tr, int tc) {\n    while (cur_r != tr) output_move(cur_r < tr ? 'D' : 'U');\n    while (cur_c != tc) output_move(cur_c < tc ? 'R' : 'L');\n}\n\nvoid do_load() {\n    if (grid[cur_r][cur_c] <= 0) return;\n    int d = grid[cur_r][cur_c];\n    cout << \"+\" << d << \"\\n\";\n    load += d;\n    grid[cur_r][cur_c] = 0;\n    turns++;\n}\n\nvoid do_unload() {\n    if (load <= 0) return;\n    int d = (int)min((long long)-grid[cur_r][cur_c], load);\n    cout << \"-\" << d << \"\\n\";\n    load -= d;\n    grid[cur_r][cur_c] += d;\n    turns++;\n}\n\nbool is_flat() {\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (grid[i][j] != 0) return false;\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N)) return 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> grid[i][j];\n\n    // Penalty per unit of remaining load after step 1.\n    // Balances immediate movement cost vs future load-carrying penalty.\n    const long long LOAD_PENALTY = 110;\n    const int TOP_K = 60;\n\n    // Pre-allocated candidate storage\n    struct Candidate {\n        int r, c, amt;\n        long long cost1;\n    };\n    vector<Candidate> cands;\n    cands.reserve(400);\n\n    while (!is_flat() && turns < 99000) {\n        cands.clear();\n\n        // 1. Collect all valid immediate targets\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (grid[i][j] == 0) continue;\n                if (load == 0 && grid[i][j] < 0) continue;\n                if (load > 0 && grid[i][j] > 0) continue;\n\n                int d = manhattan(cur_r, cur_c, i, j);\n                int amt = (load == 0) ? grid[i][j] : (int)min((long long)-grid[i][j], load);\n                long long cost1 = (long long)d * (100LL + load);\n                cands.push_back({i, j, amt, cost1});\n            }\n        }\n\n        if (cands.empty()) break;\n\n        // 2. Sort by immediate cost to process most promising first\n        sort(cands.begin(), cands.end(), [](const Candidate& a, const Candidate& b) {\n            return a.cost1 < b.cost1;\n        });\n        if (cands.size() > TOP_K) cands.resize(TOP_K);\n\n        // 3. Depth-2 Lookahead with Load Penalty\n        long long best_score = -1;\n        int best_r = -1, best_c = -1, best_amt = 0;\n\n        for (const auto& cand : cands) {\n            long long sim_load = (load == 0) ? load + cand.amt : load - cand.amt;\n            \n            // Simulate state change (backtracking avoids memcpy)\n            int orig_val = grid[cand.r][cand.c];\n            grid[cand.r][cand.c] = (load == 0) ? orig_val - cand.amt : orig_val + cand.amt;\n\n            // Find minimum cost for step 2 from the new state\n            long long min_cost2 = 2000000000000000000LL;\n            bool found_next = false;\n\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    if (grid[i][j] == 0) continue;\n                    if (sim_load == 0 && grid[i][j] < 0) continue;\n                    if (sim_load > 0 && grid[i][j] > 0) continue;\n\n                    int d2 = manhattan(cand.r, cand.c, i, j);\n                    long long cost2 = (long long)d2 * (100LL + sim_load);\n                    if (cost2 < min_cost2) {\n                        min_cost2 = cost2;\n                        found_next = true;\n                    }\n                }\n            }\n\n            long long step2_cost = found_next ? min_cost2 : 0;\n            long long total_score = cand.cost1 + step2_cost + LOAD_PENALTY * sim_load;\n\n            // Update best candidate\n            if (best_score == -1 || total_score < best_score || \n               (total_score == best_score && cand.amt > best_amt)) {\n                best_score = total_score;\n                best_r = cand.r;\n                best_c = cand.c;\n                best_amt = cand.amt;\n            }\n\n            // Backtrack simulation\n            grid[cand.r][cand.c] = orig_val;\n        }\n\n        // 4. Execute optimal move\n        move_to(best_r, best_c);\n        if (load == 0) do_load();\n        else do_unload();\n    }\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <cstring>\n#include <numeric>\n\n#pragma GCC optimize(\"O3,unroll-loops,fast-math\")\n\nusing namespace std;\n\n// Constants\nconst int MAX_SEEDS = 60;\nconst int MAX_M = 15;\nconst int GRID_SIZE = 36;\n\n// Global Data\nint N, M, T, SEED_COUNT;\nint X[MAX_SEEDS][MAX_M];\nint V[MAX_SEEDS], max_c[MAX_SEEDS];\nint L1_dist[MAX_SEEDS][MAX_SEEDS]; \n\n// Grid\nint adj[GRID_SIZE][4], deg[GRID_SIZE];\nint P[GRID_SIZE];       // Current placement\nint P_best[GRID_SIZE];  // Best placement found\n\n// Buffers\nint selected_indices[36];\ndouble scores[MAX_SEEDS];\nint indices[MAX_SEEDS];\nbool pos_filled[GRID_SIZE];\nbool seed_used[36];\nint pos_by_degree[GRID_SIZE];\n\nstruct Candidate {\n    double score;\n    int seed_idx_in_sel; // Index in sel_indices (0..35)\n    int seed_id;         // Actual seed ID\n};\nCandidate candidates[36];\n\n// RNG\nmt19937 rng(42);\n\n// Helper to compute L1 distance\ninline int compute_l1_fast(int u, int v) {\n    int s = 0;\n    const int* xu = X[u];\n    const int* xv = X[v];\n    #pragma GCC ivdep\n    for (int l = 0; l < M; ++l) {\n        int d = xu[l] - xv[l];\n        s += (d < 0) ? -d : d;\n    }\n    return s;\n}\n\nvoid precompute_grid() {\n    memset(deg, 0, sizeof(deg));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int u = i * N + j;\n            if (j + 1 < N) {\n                int v = i * N + (j + 1);\n                adj[u][deg[u]++] = v;\n                adj[v][deg[v]++] = u;\n            }\n            if (i + 1 < N) {\n                int v = (i + 1) * N + j;\n                adj[u][deg[u]++] = v;\n                adj[v][deg[v]++] = u;\n            }\n        }\n    }\n}\n\nvoid init_pos_order() {\n    iota(pos_by_degree, pos_by_degree + GRID_SIZE, 0);\n    sort(pos_by_degree, pos_by_degree + GRID_SIZE, [](int a, int b) {\n        return deg[a] > deg[b];\n    });\n}\n\nvoid precompute_distances() {\n    for (int i = 0; i < SEED_COUNT; ++i) {\n        L1_dist[i][i] = 0;\n        for (int j = i + 1; j < SEED_COUNT; ++j) {\n            int d = compute_l1_fast(i, j);\n            L1_dist[i][j] = L1_dist[j][i] = d;\n        }\n    }\n}\n\n// Calculate the objective score of the current placement\ndouble calculate_score(int* P_grid, double lambda) {\n    double total_score = 0.0;\n    for (int u = 0; u < GRID_SIZE; ++u) {\n        int seed_u = P_grid[u];\n        // Sum over unique edges\n        for (int k = 0; k < deg[u]; ++k) {\n            int v = adj[u][k];\n            if (u < v) { \n                int seed_v = P_grid[v];\n                total_score += V[seed_u] + V[seed_v] + lambda * L1_dist[seed_u][seed_v];\n            }\n        }\n    }\n    return total_score;\n}\n\n// Deterministic Greedy Initialization\nvoid greedy_init(int* P_grid, bool* used, int* sel_indices, double alpha, double lambda) {\n    memset(pos_filled, 0, sizeof(pos_filled)); \n    for (int k = 0; k < 36; ++k) {\n        int pos = pos_by_degree[k];\n        int occ_seeds[4], num_occ = 0;\n        for (int d = 0; d < deg[pos]; ++d) {\n            int nb = adj[pos][d];\n            if (pos_filled[nb]) occ_seeds[num_occ++] = P_grid[nb];\n        }\n        \n        int best_idx = -1; double best_score = -1e18;\n        for (int i = 0; i < 36; ++i) {\n            if (used[i]) continue;\n            int seed_id = sel_indices[i];\n            double score = num_occ == 0 ? V[seed_id] + alpha * max_c[seed_id] : num_occ * V[seed_id];\n            for (int n = 0; n < num_occ; ++n) score += lambda * L1_dist[seed_id][occ_seeds[n]];\n            if (score > best_score) { best_score = score; best_idx = i; }\n        }\n        if (best_idx != -1) { used[best_idx] = true; P_grid[pos] = sel_indices[best_idx]; pos_filled[pos] = true; }\n    }\n}\n\n// Stochastic Greedy Initialization\nvoid stochastic_greedy_init(int* P_grid, bool* used, int* sel_indices, double alpha, double lambda) {\n    memset(pos_filled, 0, sizeof(pos_filled)); \n    for (int k = 0; k < 36; ++k) {\n        int pos = pos_by_degree[k];\n        int occ_seeds[4], num_occ = 0;\n        for (int d = 0; d < deg[pos]; ++d) {\n            int nb = adj[pos][d];\n            if (pos_filled[nb]) occ_seeds[num_occ++] = P_grid[nb];\n        }\n        \n        int num_cands = 0;\n        for (int i = 0; i < 36; ++i) {\n            if (used[i]) continue;\n            int seed_id = sel_indices[i];\n            double score = num_occ == 0 ? V[seed_id] + alpha * max_c[seed_id] : num_occ * V[seed_id];\n            for (int n = 0; n < num_occ; ++n) score += lambda * L1_dist[seed_id][occ_seeds[n]];\n            candidates[num_cands++] = {score, i, seed_id};\n        }\n        \n        sort(candidates, candidates + num_cands, [](const Candidate& a, const Candidate& b) {\n            return a.score > b.score;\n        });\n        \n        int K = 8, limit = (K < num_cands) ? K : num_cands;\n        int pick = rng() % limit;\n        used[candidates[pick].seed_idx_in_sel] = true;\n        P_grid[pos] = candidates[pick].seed_id;\n        pos_filled[pos] = true;\n    }\n}\n\n// Random Initialization\nvoid random_init(int* P_grid, bool* used, int* sel_indices) {\n    int temp[36];\n    for(int i=0; i<36; ++i) temp[i] = sel_indices[i];\n    // Fisher-Yates shuffle\n    for (int i = 35; i > 0; --i) {\n        int j = rng() % (i + 1);\n        swap(temp[i], temp[j]);\n    }\n    for(int i=0; i<36; ++i) P_grid[i] = temp[i];\n    memset(used, 0, sizeof(bool)*36); // Mark all as used since we assigned all\n    for(int i=0; i<36; ++i) used[i] = true; \n}\n\n// Simulated Annealing\nvoid run_sa(int* P_grid, double lambda, int max_iter, double start_temp, double cool_factor) {\n    double temp = start_temp;\n    for (int iter = 0; iter < max_iter; ++iter) {\n        temp *= cool_factor;\n        int p1 = rng() % 36, p2 = rng() % 36;\n        if (p1 == p2) continue;\n\n        int u1 = P_grid[p1], u2 = P_grid[p2];\n        int v_diff = V[u2] - V[u1];\n        double delta = 0.0;\n        \n        for (int k = 0; k < deg[p1]; ++k) {\n            int nb = adj[p1][k]; if (nb == p2) continue; \n            delta += v_diff + lambda * (L1_dist[u2][P_grid[nb]] - L1_dist[u1][P_grid[nb]]);\n        }\n        for (int k = 0; k < deg[p2]; ++k) {\n            int nb = adj[p2][k]; if (nb == p1) continue;\n            delta += -v_diff + lambda * (L1_dist[u1][P_grid[nb]] - L1_dist[u2][P_grid[nb]]);\n        }\n\n        if (delta > 0.0 || (temp > 1e-6 && (double)rng() < std::exp(delta / temp) * 4294967296.0)) {\n            P_grid[p1] = u2; P_grid[p2] = u1;\n        }\n    }\n}\n\n// Greedy Descent (Polishing)\nvoid polish(int* P_grid, double lambda) {\n    bool improved = true; int pass = 0;\n    while (improved && pass < 5) {\n        improved = false; pass++;\n        double best_delta = 0.0; int best_p1 = -1, best_p2 = -1;\n        for (int p1 = 0; p1 < 36; ++p1) {\n            for (int p2 = p1 + 1; p2 < 36; ++p2) {\n                int u1 = P_grid[p1], u2 = P_grid[p2];\n                int v_diff = V[u2] - V[u1]; double delta = 0.0;\n                for (int k = 0; k < deg[p1]; ++k) {\n                    int nb = adj[p1][k]; if (nb == p2) continue; \n                    delta += v_diff + lambda * (L1_dist[u2][P_grid[nb]] - L1_dist[u1][P_grid[nb]]);\n                }\n                for (int k = 0; k < deg[p2]; ++k) {\n                    int nb = adj[p2][k]; if (nb == p1) continue;\n                    delta += -v_diff + lambda * (L1_dist[u1][P_grid[nb]] - L1_dist[u2][P_grid[nb]]);\n                }\n                if (delta > best_delta) { best_delta = delta; best_p1 = p1; best_p2 = p2; }\n            }\n        }\n        if (best_p1 != -1) {\n            int u1 = P_grid[best_p1], u2 = P_grid[best_p2];\n            P_grid[best_p1] = u2; P_grid[best_p2] = u1;\n            improved = true;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    if (!(cin >> N >> M >> T)) return 0;\n    SEED_COUNT = 2 * N * (N - 1);\n    for (int i = 0; i < SEED_COUNT; ++i) {\n        V[i] = 0; max_c[i] = 0;\n        for (int j = 0; j < M; ++j) {\n            cin >> X[i][j]; V[i] += X[i][j]; if (X[i][j] > max_c[i]) max_c[i] = X[i][j];\n        }\n    }\n\n    precompute_grid(); init_pos_order();\n    iota(indices, indices + SEED_COUNT, 0);\n\n    const double alphas[10]   = {40.0, 35.0, 25.0, 15.0, 10.0, 5.0, 3.0, 2.0, 1.0, 0.5};\n    const double lambdas[10]  = {1.5, 1.3, 1.1, 1.0, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4};\n    const int iters[10]       = {600000, 600000, 500000, 500000, 400000, 400000, 300000, 300000, 200000, 150000};\n    const int num_restarts = 5;\n\n    for (int t = 0; t < T; ++t) {\n        double alpha = alphas[t];\n        double lambda = lambdas[t];\n        int iter_per_run = iters[t];\n        precompute_distances();\n\n        for (int i = 0; i < SEED_COUNT; ++i) scores[i] = V[i] + alpha * max_c[i];\n        nth_element(indices, indices + 36, indices + SEED_COUNT, [&](int a, int b) { return scores[a] > scores[b]; });\n        for (int i = 0; i < 36; ++i) selected_indices[i] = indices[i];\n\n        double best_score_found = -1e18;\n        bool best_init_valid = false;\n\n        for (int r = 0; r < num_restarts; ++r) {\n            memset(seed_used, 0, sizeof(seed_used));\n            if (r == 0) greedy_init(P, seed_used, selected_indices, alpha, lambda);\n            else if (r == 1) stochastic_greedy_init(P, seed_used, selected_indices, alpha, lambda);\n            else random_init(P, seed_used, selected_indices);\n\n            run_sa(P, lambda, iter_per_run, 2000.0, 0.99996);\n            polish(P, lambda);\n\n            double score = calculate_score(P, lambda);\n            if (score > best_score_found) {\n                memcpy(P_best, P, sizeof(P));\n                best_score_found = score;\n                best_init_valid = true;\n            }\n        }\n        \n        // Fallback if something went wrong (highly unlikely)\n        if (!best_init_valid) { memcpy(P_best, P, sizeof(P)); }\n\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) cout << P_best[i * N + j] << (j == N - 1 ? \"\" : \" \");\n            cout << \"\\n\";\n        }\n        cout.flush();\n\n        if (t < T - 1) {\n            for (int i = 0; i < SEED_COUNT; ++i) {\n                V[i] = 0; max_c[i] = 0;\n                for (int j = 0; j < M; ++j) {\n                    cin >> X[i][j]; V[i] += X[i][j]; if (X[i][j] > max_c[i]) max_c[i] = X[i][j];\n                }\n            }\n        }\n    }\n    return 0;\n}","ahc038":"/*\n    Solution for AHC038\n    Approach:\n    1. Star graph topology with root at (0,0) and leaves 1..V-1 connected with length 1.\n    2. Heuristic-based pathfinding using BFS to compute distance to nearest valid action site.\n    3. Lookahead simulation to evaluate the 5 possible root moves (Stay, U, D, L, R).\n       - Score = (Simulated Actions * Weight) - Distance to nearest valid site.\n       - Simulates finger actions sequentially to account for capacity and grid state changes.\n    4. Execution of the best move and corresponding finger actions.\n    5. Idle fingers rotate towards movement direction to maintain alignment.\n*/\n#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n#include <climits>\n\nusing namespace std;\n\n// Global State\nint N, M, V;\nvector<string> T_grid;\nvector<vector<int>> grid;\nint finger_dir[20];\nbool holding[20];\n\n// Directions: 0:R, 1:D, 2:L, 3:U\nconst int dx[4] = {0, 1, 0, -1};\nconst int dy[4] = {1, 0, -1, 0};\n\nint dist_map[35][35];\n\ninline int rot_cost(int cur, int target) {\n    int diff = (target - cur + 4) % 4;\n    return min(diff, 4 - diff);\n}\n\n// Simulate actions for a candidate root position (rx, ry)\n// Returns the number of successful actions (pickups + drops)\nint simulate_actions(int rx, int ry) {\n    // Snapshot of the 4 neighbors\n    int local_grid[4];\n    for(int d=0; d<4; ++d) {\n        int nr = rx + dx[d], nc = ry + dy[d];\n        if(nr >= 0 && nr < N && nc >= 0 && nc < N) local_grid[d] = grid[nr][nc];\n        else local_grid[d] = -1;\n    }\n\n    int current_carried = 0;\n    bool local_holding[20];\n    int local_fdir[20];\n    \n    for(int i=0; i<V; ++i) {\n        local_holding[i] = holding[i];\n        local_fdir[i] = finger_dir[i];\n        if(holding[i]) current_carried++;\n    }\n    \n    int actions = 0;\n    \n    // Sequential finger processing\n    for(int f=1; f<V; ++f) {\n        int best_cost = 100;\n        int best_dir = -1;\n        bool best_drop = false;\n        \n        // Check neighbors\n        for(int d=0; d<4; ++d) {\n            int val = local_grid[d];\n            if(val == -1) continue; // Out of bounds\n            \n            bool is_drop = (local_holding[f] && current_carried > 0 && val == 0 && T_grid[rx+dx[d]][ry+dy[d]] == '1');\n            bool is_pick = (!local_holding[f] && current_carried < V - 1 && val == 1 && T_grid[rx+dx[d]][ry+dy[d]] == '0');\n            \n            if(is_drop || is_pick) {\n                int cost = rot_cost(local_fdir[f], d);\n                // Only count actions that can be completed in this turn (rotation cost <= 1)\n                if(cost <= 1) {\n                    // Prefer lower cost, then Drops (to free capacity)\n                    if(cost < best_cost || (cost == best_cost && is_drop)) {\n                        best_cost = cost;\n                        best_dir = d;\n                        best_drop = is_drop;\n                    }\n                }\n            }\n        }\n        \n        if(best_dir != -1) {\n            // Execute rotation\n            int diff = (best_dir - local_fdir[f] + 4) % 4;\n            if(diff == 1) local_fdir[f] = (local_fdir[f] + 1) % 4;\n            else if(diff == 3) local_fdir[f] = (local_fdir[f] + 3) % 4;\n            else if(diff == 2) local_fdir[f] = (local_fdir[f] + 1) % 4; // 180 -> 90 CW\n            \n            // If aligned, perform action\n            if(local_fdir[f] == best_dir) {\n                actions++;\n                if(best_drop) {\n                    local_grid[best_dir] = 1;\n                    local_holding[f] = false;\n                    current_carried--;\n                } else {\n                    local_grid[best_dir] = 0;\n                    local_holding[f] = true;\n                    current_carried++;\n                }\n            }\n        }\n    }\n    return actions;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> V)) return 0;\n    T_grid.resize(N);\n    grid.assign(N, vector<int>(N, 0));\n\n    string s_row;\n    for (int i = 0; i < N; ++i) {\n        cin >> s_row;\n        for (int j = 0; j < N; ++j) {\n            if (s_row[j] == '1') grid[i][j] = 1;\n        }\n    }\n    for (int i = 0; i < N; ++i) cin >> T_grid[i];\n\n    // Output tree design: Star graph\n    cout << V << \"\\n\";\n    for (int i = 1; i < V; ++i) cout << \"0 1\\n\";\n    cout << \"0 0\\n\";\n    int rx = 0, ry = 0;\n\n    for (int i = 0; i < V; ++i) {\n        finger_dir[i] = 0;\n        holding[i] = false;\n    }\n\n    int turn = 0;\n    const int MAX_TURNS = 100000;\n    \n    // Movement options: Stay, R, D, L, U\n    int m_dx[] = {0, 0, 1, 0, -1};\n    int m_dy[] = {0, 1, 0, -1, 0};\n    char m_char[] = {'.', 'R', 'D', 'L', 'U'};\n\n    while (turn < MAX_TURNS) {\n        int carried = 0;\n        for(int i=0; i<V; ++i) if(holding[i]) carried++;\n        \n        // Check completion\n        bool done = true;\n        if (carried == 0) {\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    if (grid[i][j] != (T_grid[i][j] - '0')) {\n                        done = false;\n                        break;\n                    }\n                }\n                if (!done) break;\n            }\n        } else {\n            done = false;\n        }\n        if (done) break;\n\n        // BFS to compute distance to nearest valid root position\n        bool can_pick = (carried < V - 1);\n        bool can_drop = (carried > 0);\n        \n        for(int r=0; r<N; ++r) for(int c=0; c<N; ++c) dist_map[r][c] = INT_MAX;\n        queue<pair<int,int>> q;\n        \n        for(int r=0; r<N; ++r) {\n            for(int c=0; c<N; ++c) {\n                bool valid = false;\n                for(int d=0; d<4; ++d) {\n                    int nr = r + dx[d], nc = c + dy[d];\n                    if(nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                        if(can_pick && grid[nr][nc] == 1 && T_grid[nr][nc] == '0') valid = true;\n                        if(can_drop && grid[nr][nc] == 0 && T_grid[nr][nc] == '1') valid = true;\n                        if(valid) break;\n                    }\n                }\n                if(valid) {\n                    dist_map[r][c] = 0;\n                    q.push({r, c});\n                }\n            }\n        }\n        \n        while(!q.empty()) {\n            auto [r, c] = q.front(); q.pop();\n            int d = dist_map[r][c];\n            for(int k=0; k<4; ++k) {\n                int nr = r + dx[k], nc = c + dy[k];\n                if(nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                    if(dist_map[nr][nc] == INT_MAX) {\n                        dist_map[nr][nc] = d + 1;\n                        q.push({nr, nc});\n                    }\n                }\n            }\n        }\n\n        // Evaluate moves\n        int best_move_idx = 0;\n        int best_score = -1000000000;\n        int best_h = INT_MAX;\n\n        for(int m=0; m<5; ++m) {\n            int nr = rx + m_dx[m];\n            int nc = ry + m_dy[m];\n            \n            if(nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n            \n            int acts = simulate_actions(nr, nc);\n            int h = dist_map[nr][nc];\n            \n            // Heuristic: Maximize actions, then minimize distance\n            int score = acts * 10000 - h;\n            \n            if (score > best_score) {\n                best_score = score;\n                best_move_idx = m;\n                best_h = h;\n            } else if (score == best_score) {\n                if (h < best_h) {\n                    best_h = h;\n                    best_move_idx = m;\n                }\n            }\n        }\n\n        // Execute Move\n        char move_c = m_char[best_move_idx];\n        rx += m_dx[best_move_idx];\n        ry += m_dy[best_move_idx];\n\n        // Generate Command and Update State\n        string cmd(2 * V, '.');\n        cmd[0] = move_c;\n        \n        int current_carried = carried;\n        int local_grid_vals[4];\n        for(int d=0; d<4; ++d) {\n            int nr = rx + dx[d], nc = ry + dy[d];\n            if(nr >= 0 && nr < N && nc >= 0 && nc < N) local_grid_vals[d] = grid[nr][nc];\n            else local_grid_vals[d] = -1;\n        }\n\n        for(int f=1; f<V; ++f) {\n            int best_cost = 100;\n            int best_dir = -1;\n            bool best_drop = false;\n            \n            for(int d=0; d<4; ++d) {\n                int val = local_grid_vals[d];\n                if(val == -1) continue;\n                \n                bool is_drop = (holding[f] && current_carried > 0 && val == 0 && T_grid[rx+dx[d]][ry+dy[d]] == '1');\n                bool is_pick = (!holding[f] && current_carried < V - 1 && val == 1 && T_grid[rx+dx[d]][ry+dy[d]] == '0');\n                \n                if(is_drop || is_pick) {\n                    int cost = rot_cost(finger_dir[f], d);\n                    if(cost <= 1) {\n                        if(cost < best_cost || (cost == best_cost && is_drop)) {\n                            best_cost = cost;\n                            best_dir = d;\n                            best_drop = is_drop;\n                        }\n                    }\n                }\n            }\n            \n            char rot = '.';\n            bool acted = false;\n            \n            if(best_dir != -1) {\n                int diff = (best_dir - finger_dir[f] + 4) % 4;\n                if(diff == 1) rot = 'R';\n                else if(diff == 2) rot = 'R';\n                else if(diff == 3) rot = 'L';\n                \n                cmd[f] = rot;\n                \n                if(rot == 'R') finger_dir[f] = (finger_dir[f] + 1) % 4;\n                else if(rot == 'L') finger_dir[f] = (finger_dir[f] + 3) % 4;\n                \n                if(finger_dir[f] == best_dir) {\n                    cmd[V + f] = 'P';\n                    int nr = rx + dx[best_dir], nc = ry + dy[best_dir];\n                    if(best_drop) {\n                        grid[nr][nc] = 1;\n                        holding[f] = false;\n                        current_carried--;\n                        local_grid_vals[best_dir] = 1;\n                    } else {\n                        grid[nr][nc] = 0;\n                        holding[f] = true;\n                        current_carried++;\n                        local_grid_vals[best_dir] = 0;\n                    }\n                    acted = true;\n                }\n            }\n            \n            if(!acted) {\n                // Idle rotation towards movement direction\n                int target_dir = 0;\n                if(best_move_idx == 1) target_dir = 0;\n                else if(best_move_idx == 2) target_dir = 1;\n                else if(best_move_idx == 3) target_dir = 2;\n                else if(best_move_idx == 4) target_dir = 3;\n                \n                int diff = (target_dir - finger_dir[f] + 4) % 4;\n                if(diff != 0) {\n                    rot = (diff == 1 || diff == 2) ? 'R' : 'L';\n                    cmd[f] = rot;\n                    if(rot == 'R') finger_dir[f] = (finger_dir[f] + 1) % 4;\n                    else finger_dir[f] = (finger_dir[f] + 3) % 4;\n                }\n            }\n        }\n        \n        cout << cmd << \"\\n\";\n        turn++;\n    }\n    return 0;\n}","ahc039":"#include <iostream>\n#include <vector>\n#include <random>\n#include <cmath>\n#include <algorithm>\n#include <map>\n#include <queue>\n\nusing namespace std;\n\nstruct Pt {\n    int x, y;\n    bool operator==(const Pt& o) const { return x == o.x && y == o.y; }\n    bool operator!=(const Pt& o) const { return !(*this == o); }\n    bool operator<(const Pt& o) const { return x != o.x ? x < o.x : y < o.y; }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    if (!(cin >> N)) return 0;\n    vector<Pt> mack(N), sard(N);\n    for (int i = 0; i < N; ++i) cin >> mack[i].x >> mack[i].y;\n    for (int i = 0; i < N; ++i) cin >> sard[i].x >> sard[i].y;\n\n    // Grid parameters: D=400 balances resolution and convergence speed\n    const int D = 400;\n    const int G = 100000 / D + 2;\n    vector<vector<int>> grid(G, vector<int>(G, 0));\n\n    auto add_points = [&](const vector<Pt>& pts, int val) {\n        for (auto& p : pts) {\n            int cx = p.x / D, cy = p.y / D;\n            if (cx >= 0 && cx < G && cy >= 0 && cy < G) {\n                grid[cy][cx] += val;\n            }\n        }\n    };\n    add_points(mack, 1);\n    add_points(sard, -1);\n\n    mt19937 rng(42);\n    double T = 80.0;\n    int iters = 600000;\n\n    // Initialize with the highest-weight single cell\n    int best_r = 0, best_c = 0, best_w = -1e9;\n    for (int r = 0; r < G; ++r) {\n        for (int c = 0; c < G; ++c) {\n            if (grid[r][c] > best_w) {\n                best_w = grid[r][c]; best_r = r; best_c = c;\n            }\n        }\n    }\n\n    vector<vector<bool>> sel(G, vector<bool>(G, false));\n    if (best_w > 0) sel[best_r][best_c] = true;\n\n    const int dr[4] = {-1, 1, 0, 0};\n    const int dc[4] = {0, 0, -1, 1};\n\n    // Simulated Annealing\n    for (int it = 0; it < iters; ++it) {\n        T *= 0.999985;\n        if (T < 0.05) T = 0.05;\n\n        int r = rng() % G;\n        int c = rng() % G;\n\n        bool is_sel = sel[r][c];\n        bool can_move = false;\n\n        if (!is_sel) {\n            // Can only add if adjacent to selected region\n            for (int i = 0; i < 4; ++i) {\n                int nr = r + dr[i], nc = c + dc[i];\n                if (nr >= 0 && nr < G && nc >= 0 && nc < G && sel[nr][nc]) {\n                    can_move = true; break;\n                }\n            }\n        } else {\n            // Can only remove if on boundary\n            for (int i = 0; i < 4; ++i) {\n                int nr = r + dr[i], nc = c + dc[i];\n                if (nr < 0 || nr >= G || nc < 0 || nc >= G || !sel[nr][nc]) {\n                    can_move = true; break;\n                }\n            }\n        }\n\n        if (!can_move) continue;\n\n        int delta = is_sel ? -grid[r][c] : grid[r][c];\n        double prob = 0.0;\n        if (delta > 0) prob = 1.0;\n        else {\n            double val = delta / T;\n            if (val < -50.0) val = -50.0;\n            if (val > 50.0) val = 50.0;\n            prob = exp(val);\n        }\n\n        uniform_real_distribution<double> dist(0.0, 1.0);\n        if (dist(rng) < prob) {\n            sel[r][c] = !is_sel;\n        }\n    }\n\n    // Post-processing 1: Keep largest 4-connected component\n    vector<vector<bool>> final_sel(G, vector<bool>(G, false));\n    vector<vector<bool>> visited(G, vector<bool>(G, false));\n    int sr = -1, sc = -1;\n    for (int r = 0; r < G; ++r) {\n        for (int c = 0; c < G; ++c) {\n            if (sel[r][c]) { sr = r; sc = c; r = G; break; }\n        }\n    }\n\n    if (sr != -1) {\n        queue<pair<int, int>> q;\n        q.emplace(sr, sc);\n        visited[sr][sc] = true;\n        while (!q.empty()) {\n            auto [r, c] = q.front(); q.pop();\n            final_sel[r][c] = true;\n            for (int i = 0; i < 4; ++i) {\n                int nr = r + dr[i], nc = c + dc[i];\n                if (nr >= 0 && nr < G && nc >= 0 && nc < G && sel[nr][nc] && !visited[nr][nc]) {\n                    visited[nr][nc] = true;\n                    q.emplace(nr, nc);\n                }\n            }\n        }\n    }\n\n    // Post-processing 2: Fill internal holes via outside flood-fill\n    vector<vector<bool>> outside(G, vector<bool>(G, false));\n    queue<pair<int, int>> q_out;\n    for (int c = 0; c < G; ++c) {\n        if (!final_sel[0][c]) { outside[0][c] = true; q_out.emplace(0, c); }\n        if (!final_sel[G-1][c]) { outside[G-1][c] = true; q_out.emplace(G-1, c); }\n    }\n    for (int r = 0; r < G; ++r) {\n        if (!final_sel[r][0]) { outside[r][0] = true; q_out.emplace(r, 0); }\n        if (!final_sel[r][G-1]) { outside[r][G-1] = true; q_out.emplace(r, G-1); }\n    }\n    while (!q_out.empty()) {\n        auto [r, c] = q_out.front(); q_out.pop();\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i], nc = c + dc[i];\n            if (nr >= 0 && nr < G && nc >= 0 && nc < G && !final_sel[nr][nc] && !outside[nr][nc]) {\n                outside[nr][nc] = true;\n                q_out.emplace(nr, nc);\n            }\n        }\n    }\n    for (int r = 0; r < G; ++r) {\n        for (int c = 0; c < G; ++c) {\n            if (!final_sel[r][c] && !outside[r][c]) {\n                final_sel[r][c] = true;\n            }\n        }\n    }\n\n    // Edge extraction: interior edges cancel out, boundary edges remain\n    map<pair<Pt, Pt>, int> edge_cnt;\n    auto add_edge = [&](Pt u, Pt v) {\n        if (u.x > v.x || (u.x == v.x && u.y > v.y)) swap(u, v);\n        edge_cnt[{u, v}]++;\n    };\n\n    for (int r = 0; r < G; ++r) {\n        for (int c = 0; c < G; ++c) {\n            if (final_sel[r][c]) {\n                Pt p1 = {c * D, r * D};\n                Pt p2 = {min((c + 1) * D, 100000), r * D};\n                Pt p3 = {min((c + 1) * D, 100000), min((r + 1) * D, 100000)};\n                Pt p4 = {c * D, min((r + 1) * D, 100000)};\n                add_edge(p1, p2); add_edge(p2, p3);\n                add_edge(p3, p4); add_edge(p4, p1);\n            }\n        }\n    }\n\n    // Build adjacency graph for tracing\n    map<Pt, vector<Pt>> adj;\n    for (auto& [e, cnt] : edge_cnt) {\n        if (cnt % 2 == 1) {\n            adj[e.first].push_back(e.second);\n            adj[e.second].push_back(e.first);\n        }\n    }\n\n    // Trace the polygon boundary\n    vector<Pt> poly;\n    if (!adj.empty()) {\n        Pt curr = adj.begin()->first;\n        Pt prev = {-1, -1};\n        int steps = 0;\n        while (steps < 100000) {\n            poly.push_back(curr);\n            Pt next = {-1, -1};\n            for (auto& nb : adj[curr]) {\n                if (nb != prev) {\n                    next = nb;\n                    break;\n                }\n            }\n            prev = curr;\n            curr = next;\n            if (curr == poly[0] || curr.x < 0) break;\n            steps++;\n        }\n    }\n\n    // Remove collinear vertices\n    vector<Pt> simplified;\n    int m = poly.size();\n    if (m >= 3) {\n        for (int i = 0; i < m; ++i) {\n            Pt prev = poly[(i - 1 + m) % m];\n            Pt curr = poly[i];\n            Pt next = poly[(i + 1) % m];\n            long long dx1 = curr.x - prev.x;\n            long long dy1 = curr.y - prev.y;\n            long long dx2 = next.x - curr.x;\n            long long dy2 = next.y - curr.y;\n            if (dx1 * dy2 != dx2 * dy1) {\n                if (simplified.empty() || !(curr == simplified.back())) {\n                    simplified.push_back(curr);\n                }\n            }\n        }\n    }\n    if (simplified.empty() && !poly.empty()) simplified = poly;\n\n    // Final deduplication and formatting\n    vector<Pt> final_poly;\n    for (auto& p : simplified) {\n        if (final_poly.empty() || !(p == final_poly.back())) {\n            final_poly.push_back(p);\n        }\n    }\n    if (final_poly.size() > 1 && final_poly.front() == final_poly.back()) {\n        final_poly.pop_back();\n    }\n\n    // Ensure minimum vertex count and valid bounds\n    if (final_poly.size() < 4) {\n        final_poly = {{0, 0}, {D, 0}, {D, D}, {0, D}};\n    }\n\n    cout << final_poly.size() << \"\\n\";\n    for (auto& p : final_poly) {\n        cout << p.x << \" \" << p.y << \"\\n\";\n    }\n\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n#pragma GCC optimize(\"O3,unroll-loops\")\n\nconstexpr int MAXN = 105;\n// Use long long for coordinates and dimensions to prevent overflow\nlong long W_obs[MAXN], H_obs[MAXN];\nbool skipped[MAXN], rot[MAXN];\nchar dir[MAXN]; \nint ref_idx[MAXN]; \n\nlong long px[MAXN], py[MAXN], pw[MAXN], ph[MAXN];\n\n// Best config storage\nlong long best_cost = -1;\nbool best_skipped[MAXN], best_rot[MAXN];\nchar best_dir[MAXN];\nint best_ref[MAXN];\n\nmt19937_64 rng(42);\n\n// Fast deterministic simulation\n// Logic:\n// - 'U': Aligns x with ref's right edge (or 0). Moves Up (decreasing y) until \n//   it hits y=0 or the bottom edge of an overlapping rectangle.\n//   Stopping at bottom edge (py[j] + ph[j]) means placing the new rectangle BELOW it.\n// - 'L': Aligns y with ref's bottom edge (or 0). Moves Left (decreasing x) until\n//   it hits x=0 or the right edge of an overlapping rectangle.\n//   Stopping at right edge (px[j] + pw[j]) means placing the new rectangle to the RIGHT of it.\nlong long evaluate(int N, long long& skip_pen) {\n    long long max_x = 0, max_y = 0;\n    skip_pen = 0;\n    for (int i = 0; i < N; ++i) {\n        if (skipped[i]) {\n            skip_pen += W_obs[i] + H_obs[i];\n            px[i] = py[i] = pw[i] = ph[i] = 0;\n            continue;\n        }\n        \n        // Set dimensions\n        if (rot[i]) { pw[i] = H_obs[i]; ph[i] = W_obs[i]; }\n        else { pw[i] = W_obs[i]; ph[i] = H_obs[i]; }\n        \n        long long x = 0, y = 0;\n        int r = ref_idx[i];\n        // Check if ref is valid (index < i and not skipped)\n        // If invalid, treat as -1 (alignment with 0)\n        bool ref_valid = (r != -1 && r < i && !skipped[r]);\n        \n        if (ref_valid) {\n            if (dir[i] == 'U') x = px[r] + pw[r];\n            else y = py[r] + ph[r];\n        }\n        \n        long long final_x = x, final_y = y;\n        \n        if (dir[i] == 'U') {\n            // x is fixed. Find lowest valid y (closest to 0).\n            // Blocked by bottom edges of overlapping rects.\n            long long limit = 0;\n            for (int j = 0; j < i; ++j) {\n                if (skipped[j]) continue;\n                // Check x overlap: [final_x, final_x + pw[i]) vs [px[j], px[j] + pw[j])\n                if (final_x < px[j] + pw[j] && px[j] < final_x + pw[i]) {\n                    long long bot = py[j] + ph[j];\n                    if (bot > limit) limit = bot;\n                }\n            }\n            final_y = limit;\n        } else { // 'L'\n            // y is fixed. Find leftmost valid x (closest to 0).\n            // Blocked by right edges of overlapping rects.\n            long long limit = 0;\n            for (int j = 0; j < i; ++j) {\n                if (skipped[j]) continue;\n                // Check y overlap: [final_y, final_y + ph[i]) vs [py[j], py[j] + ph[j])\n                if (final_y < py[j] + ph[j] && py[j] < final_y + ph[i]) {\n                    long long right = px[j] + pw[j];\n                    if (right > limit) limit = right;\n                }\n            }\n            final_x = limit;\n        }\n        \n        px[i] = final_x;\n        py[i] = final_y;\n        \n        if (px[i] + pw[i] > max_x) max_x = px[i] + pw[i];\n        if (py[i] + ph[i] > max_y) max_y = py[i] + ph[i];\n    }\n    return max_x + max_y + skip_pen;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    int N, T, sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n    \n    for (int i = 0; i < N; ++i) {\n        cin >> W_obs[i] >> H_obs[i];\n        skipped[i] = false; // Start with all placed\n        rot[i] = (rng() & 1);\n        dir[i] = (rng() & 1) ? 'U' : 'L';\n        ref_idx[i] = (i > 0 && rng() % 3 != 0) ? (rng() % i) : -1;\n    }\n\n    long long skip_pen;\n    long long cur_cost = evaluate(N, skip_pen);\n    best_cost = cur_cost;\n    \n    // Save initial best\n    memcpy(best_skipped, skipped, N);\n    memcpy(best_rot, rot, N);\n    memcpy(best_dir, dir, N);\n    memcpy(best_ref, ref_idx, N * sizeof(int));\n\n    auto start = chrono::steady_clock::now();\n    int iter = 0;\n    double temp = 8000.0;\n\n    for (int turn = 0; turn < T; ++turn) {\n        if (turn > 0) { int w, h; cin >> w >> h; } // Read feedback (ignored due to noise)\n        \n        // Check time\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double, std::milli>(now - start).count();\n        \n        // Run SA if time permits\n        if (elapsed < 2700.0) {\n            while (true) {\n                iter++;\n                // Check time periodically to reduce overhead\n                if ((iter & 255) == 0) {\n                    now = chrono::steady_clock::now();\n                    elapsed = chrono::duration<double, std::milli>(now - start).count();\n                    if (elapsed > 2700.0) break;\n                }\n    \n                int i = rng() % N;\n                // Backup state for rollback\n                bool b_sk = skipped[i], b_ro = rot[i];\n                char b_di = dir[i];\n                int b_re = ref_idx[i];\n    \n                int mt = rng() % 100;\n                if (mt < 20) skipped[i] ^= 1;\n                else if (mt < 40) rot[i] ^= 1;\n                else if (mt < 60) dir[i] = (dir[i] == 'U' ? 'L' : 'U');\n                else if (mt < 90) {\n                    if (i > 0) ref_idx[i] = rng() % i;\n                    else ref_idx[i] = -1;\n                } else ref_idx[i] = -1;\n    \n                // Note: ref_idx might point to a skipped rectangle or be out of bounds (unlikely with rng%i)\n                // The evaluate function handles invalid refs by treating them as -1.\n                // We don't modify ref_idx array here to allow restoring invalid states if rejected.\n    \n                long long next_cost = evaluate(N, skip_pen);\n                double delta = (double)next_cost - cur_cost;\n                \n                // Metropolis acceptance\n                bool accept = false;\n                if (delta < 0) accept = true;\n                else {\n                    double prob = exp(max(-50.0, -delta / temp));\n                    if ((double)(rng() & 0xFFFFFF) / 0xFFFFFF < prob) accept = true;\n                }\n    \n                if (accept) {\n                    cur_cost = next_cost;\n                    if (cur_cost < best_cost) {\n                        best_cost = cur_cost;\n                        memcpy(best_skipped, skipped, N);\n                        memcpy(best_rot, rot, N);\n                        memcpy(best_dir, dir, N);\n                        memcpy(best_ref, ref_idx, N * sizeof(int));\n                    }\n                } else {\n                    // Revert\n                    skipped[i] = b_sk; rot[i] = b_ro; dir[i] = b_di; ref_idx[i] = b_re;\n                }\n                \n                // Smooth cooling\n                temp *= 0.99995;\n            }\n        }\n        \n        // Restore best config for output\n        memcpy(skipped, best_skipped, N);\n        memcpy(rot, best_rot, N);\n        memcpy(dir, best_dir, N);\n        memcpy(ref_idx, best_ref, N * sizeof(int));\n        \n        // Sanitize references for output:\n        // Must point to a previously placed rectangle (index < i and not skipped)\n        for(int i = 0; i < N; ++i) {\n            if (!skipped[i]) {\n                if (ref_idx[i] != -1) {\n                    if (ref_idx[i] >= i || skipped[ref_idx[i]]) {\n                        ref_idx[i] = -1;\n                    }\n                }\n            }\n        }\n        \n        int n_place = 0;\n        for(int i = 0; i < N; ++i) if(!skipped[i]) n_place++;\n        \n        // Safety fallback if all skipped\n        if (n_place == 0) {\n            skipped[0] = false; \n            ref_idx[0] = -1;\n            dir[0] = 'U';\n            rot[0] = false;\n            n_place = 1;\n        }\n        \n        cout << n_place << \"\\n\";\n        for(int i = 0; i < N; ++i) {\n            if(!skipped[i]) {\n                cout << i << \" \" << rot[i] << \" \" << dir[i] << \" \" << ref_idx[i] << \"\\n\";\n            }\n        }\n        cout.flush();\n    }\n    return 0;\n}","ahc041":"#pragma GCC optimize(\"O3,unroll-loops\")\n#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <chrono>\n#include <random>\n#include <cstring>\n\nusing namespace std;\n\nconst int MAXN = 1005;\nconst int INF = 1e9;\n\nint dist_mat[MAXN][MAXN];\nint A[MAXN];\nvector<int> adj[MAXN];\nint N, M, H;\n\nint d1[MAXN], d2[MAXN], r1[MAXN], d_buf[MAXN];\nint roots_arr[MAXN];\nint num_roots = 0;\nbool is_root_arr[MAXN] = {false};\n\nint best_roots_arr[MAXN];\nint best_num_roots = 0;\nlong long global_best_score = -1;\n\n// Evaluate from scratch (used in initialization and final output)\nlong long evaluate(int* d, const int* r_arr, int n_r) {\n    for (int i = 0; i < N; ++i) d[i] = H + 1;\n    for (int i = 0; i < n_r; ++i) {\n        int r = r_arr[i];\n        const int* dr = dist_mat[r];\n        for (int j = 0; j < N; ++j) {\n            if (dr[j] < d[j]) d[j] = dr[j];\n        }\n    }\n    long long score = 0;\n    for (int i = 0; i < N; ++i) {\n        if (d[i] > H) return -1;\n        score += (long long)(d[i] + 1) * A[i];\n    }\n    return score;\n}\n\n// Maintain 1st and 2nd closest roots for fast evaluation\nvoid compute_d1_d2() {\n    for (int i = 0; i < N; ++i) {\n        d1[i] = INF; d2[i] = INF; r1[i] = -1;\n    }\n    for (int i = 0; i < num_roots; ++i) {\n        int r = roots_arr[i];\n        const int* dr = dist_mat[r];\n        for (int u = 0; u < N; ++u) {\n            int d = dr[u];\n            if (d < d1[u]) {\n                d2[u] = d1[u];\n                d1[u] = d;\n                r1[u] = r;\n            } else if (d < d2[u]) {\n                d2[u] = d;\n            }\n        }\n    }\n}\n\n// Evaluate if root r is removed\ninline long long evaluate_fast_remove(int r) {\n    long long score = 0;\n    for (int u = 0; u < N; ++u) {\n        int new_d = (r1[u] == r) ? d2[u] : d1[u];\n        if (new_d > H) return -1;\n        score += (long long)(new_d + 1) * A[u];\n    }\n    return score;\n}\n\n// Evaluate if root old_r is moved to new_r\ninline long long evaluate_fast_move(int old_r, int new_r) {\n    long long score = 0;\n    const int* d_new = dist_mat[new_r];\n    for (int u = 0; u < N; ++u) {\n        int best_other = (r1[u] == old_r) ? d2[u] : d1[u];\n        int new_d = best_other;\n        if (d_new[u] < new_d) new_d = d_new[u];\n        if (new_d > H) return -1;\n        score += (long long)(new_d + 1) * A[u];\n    }\n    return score;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    auto start_time = chrono::steady_clock::now();\n    if (!(cin >> N >> M >> H)) return 0;\n\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); adj[v].push_back(u);\n    }\n    for (int i = 0; i < N; ++i) { int x, y; cin >> x >> y; }\n\n    // APSP using BFS\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) dist_mat[i][j] = INF;\n        queue<int> q;\n        dist_mat[i][i] = 0;\n        q.push(i);\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            int nd = dist_mat[i][u] + 1;\n            for (int v : adj[u]) {\n                if (nd < dist_mat[i][v]) {\n                    dist_mat[i][v] = nd;\n                    q.push(v);\n                }\n            }\n        }\n    }\n\n    mt19937 rng(42);\n    auto get_time = [&]() { return chrono::duration<double>(chrono::steady_clock::now() - start_time).count(); };\n    const double TIME_LIMIT = 1.85;\n\n    // Greedy Initialization\n    vector<int> d(N, INF);\n    while (true) {\n        if (get_time() > 1.0) break;\n        int best_v = -1, min_A = INF;\n        bool all_covered = true;\n        for (int i = 0; i < N; ++i) {\n            if (d[i] > H) {\n                all_covered = false;\n                if (A[i] < min_A) { min_A = A[i]; best_v = i; }\n            }\n        }\n        if (all_covered) break;\n\n        int cands[MAXN];\n        int num_cands = 0;\n        for (int r = 0; r < N; ++r) {\n            if (dist_mat[r][best_v] <= H) cands[num_cands++] = r;\n            if (num_cands >= 30) break;\n        }\n        sort(cands, cands + num_cands, [](int a, int b) { return A[a] < A[b]; });\n\n        int K = min(num_cands, 20);\n        int best_r = -1;\n        long long best_sc = -1;\n        \n        vector<int> tmp_d(N);\n        for (int i = 0; i < K; ++i) {\n            int r = cands[i];\n            long long sc = 0;\n            bool ok = true;\n            for (int u = 0; u < N; ++u) {\n                int nd = d[u];\n                if (dist_mat[r][u] < nd) nd = dist_mat[r][u];\n                if (nd > H) { ok = false; break; }\n                sc += (long long)(nd + 1) * A[u];\n            }\n            if (ok && sc > best_sc) { best_sc = sc; best_r = r; }\n        }\n\n        if (best_r != -1) {\n            roots_arr[num_roots++] = best_r;\n            is_root_arr[best_r] = true;\n            for (int u = 0; u < N; ++u) {\n                int nd = d[u];\n                if (dist_mat[best_r][u] < nd) nd = dist_mat[best_r][u];\n                d[u] = nd;\n            }\n        } else {\n            for (int i = 0; i < num_cands; ++i) {\n                int r = cands[i];\n                roots_arr[num_roots++] = r;\n                is_root_arr[r] = true;\n                for (int u = 0; u < N; ++u) {\n                    int nd = d[u];\n                    if (dist_mat[r][u] < nd) nd = dist_mat[r][u];\n                    d[u] = nd;\n                }\n                break;\n            }\n        }\n    }\n\n    global_best_score = evaluate(d_buf, roots_arr, num_roots);\n    best_num_roots = num_roots;\n    memcpy(best_roots_arr, roots_arr, num_roots * sizeof(int));\n    compute_d1_d2();\n\n    long long cur_score = global_best_score;\n    int order[MAXN];\n    int tmp_nb[MAXN];\n    \n    // Local Search\n    while (get_time() < TIME_LIMIT) {\n        bool improved = false;\n        \n        for(int i=0; i<num_roots; ++i) order[i] = i;\n        shuffle(order, order + num_roots, rng);\n\n        for (int k = 0; k < num_roots; ++k) {\n            int idx = order[k];\n            int r = roots_arr[idx];\n            \n            // Try Remove\n            if (num_roots > 1) {\n                long long sc = evaluate_fast_remove(r);\n                if (sc > cur_score) {\n                    roots_arr[idx] = roots_arr[num_roots-1];\n                    num_roots--;\n                    is_root_arr[r] = false;\n                    cur_score = sc;\n                    improved = true;\n                    if (cur_score > global_best_score) {\n                        global_best_score = cur_score;\n                        best_num_roots = num_roots;\n                        memcpy(best_roots_arr, roots_arr, num_roots * sizeof(int));\n                    }\n                    compute_d1_d2();\n                    goto next_iter;\n                }\n            }\n\n            // Try Move\n            int deg = 0;\n            for(int nb : adj[r]) tmp_nb[deg++] = nb;\n            shuffle(tmp_nb, tmp_nb + deg, rng);\n            \n            for(int i=0; i<deg; ++i) {\n                int v = tmp_nb[i];\n                if (is_root_arr[v]) continue;\n                long long sc = evaluate_fast_move(r, v);\n                if (sc > cur_score) {\n                    is_root_arr[r] = false;\n                    is_root_arr[v] = true;\n                    roots_arr[idx] = v;\n                    cur_score = sc;\n                    improved = true;\n                    if (cur_score > global_best_score) {\n                        global_best_score = cur_score;\n                        best_num_roots = num_roots;\n                        memcpy(best_roots_arr, roots_arr, num_roots * sizeof(int));\n                    }\n                    compute_d1_d2();\n                    goto next_iter;\n                }\n            }\n        }\n\n        // Perturbation\n        if (!improved && num_roots > 0) {\n            int idx = uniform_int_distribution<int>(0, num_roots - 1)(rng);\n            int r = roots_arr[idx];\n            int v = uniform_int_distribution<int>(0, N - 1)(rng);\n            if (!is_root_arr[v] && r != v) {\n                long long sc = evaluate_fast_move(r, v);\n                if (sc != -1) {\n                    is_root_arr[r] = false;\n                    is_root_arr[v] = true;\n                    roots_arr[idx] = v;\n                    cur_score = sc;\n                    compute_d1_d2();\n                }\n            }\n        }\n        next_iter:;\n    }\n\n    // Construct and Output\n    evaluate(d_buf, best_roots_arr, best_num_roots);\n    vector<int> p(N, -1);\n    for (int i = 0; i < N; ++i) {\n        if (d_buf[i] > 0) {\n            int target = d_buf[i] - 1;\n            for (int nb : adj[i]) {\n                if (d_buf[nb] == target) {\n                    p[i] = nb;\n                    break;\n                }\n            }\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << p[i] << (i == N - 1 ? \"\" : \" \");\n    }\n    cout << \"\\n\";\n\n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <utility>\n\nusing namespace std;\n\nint N;\nvector<string> board;\n\n// Apply a single shift operation to the board\nvoid apply_shift(char dir, int p) {\n    if (dir == 'U') {\n        for (int i = 0; i < N - 1; i++) board[i][p] = board[i + 1][p];\n        board[N - 1][p] = '.';\n    } else if (dir == 'D') {\n        for (int i = N - 1; i > 0; i--) board[i][p] = board[i - 1][p];\n        board[0][p] = '.';\n    } else if (dir == 'L') {\n        for (int j = 0; j < N - 1; j++) board[p][j] = board[p][j + 1];\n        board[p][N - 1] = '.';\n    } else if (dir == 'R') {\n        for (int j = N - 1; j > 0; j--) board[p][j] = board[p][j - 1];\n        board[p][0] = '.';\n    }\n}\n\n// Calculate heuristic: sum of minimum clear distances for all Oni\n// Returns 1e9 if any Oni is trapped (no clear direction)\nint calc_potential(const vector<string>& b) {\n    int sum = 0;\n    for(int i=0; i<N; i++) {\n        for(int j=0; j<N; j++) {\n            if(b[i][j] == 'x') {\n                int d = 1e9;\n                bool c = true;\n                for(int k=0; k<i; k++) if(b[k][j]=='o'){c=false;break;}\n                if(c) d = min(d, i+1);\n                c = true;\n                for(int k=i+1; k<N; k++) if(b[k][j]=='o'){c=false;break;}\n                if(c) d = min(d, N-i);\n                c = true;\n                for(int k=0; k<j; k++) if(b[i][k]=='o'){c=false;break;}\n                if(c) d = min(d, j+1);\n                c = true;\n                for(int k=j+1; k<N; k++) if(b[i][k]=='o'){c=false;break;}\n                if(c) d = min(d, N-j);\n                \n                if(d == 1e9) return 1e9; // Trapped\n                sum += d;\n            }\n        }\n    }\n    return sum;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> N)) return 0;\n    board.resize(N);\n    for (int i = 0; i < N; i++) cin >> board[i];\n\n    vector<pair<char, int>> ops;\n\n    while (true) {\n        int oni_count = 0;\n        for(int i=0; i<N; i++) for(int j=0; j<N; j++) if(board[i][j]=='x') oni_count++;\n        if(oni_count == 0) break;\n\n        int cur_pot = calc_potential(board);\n        \n        int best_score = 2e9;\n        int best_shifts = 1e9;\n        char best_dir = 0;\n        int best_r = -1, best_c = -1;\n        bool found_direct = false;\n\n        // Lookahead: Evaluate all possible direct removals\n        for(int i=0; i<N; i++) {\n            for(int j=0; j<N; j++) {\n                if(board[i][j] == 'x') {\n                    struct Move { char dir; int dist; int param; bool valid; } moves[4] = {\n                        {'U', i+1, j, true}, {'D', N-i, j, true}, {'L', j+1, i, true}, {'R', N-j, i, true}\n                    };\n                    // Validate directions\n                    for(auto& m : moves) {\n                        if(!m.valid) continue;\n                        bool clear = true;\n                        if(m.dir == 'U') { for(int k=0; k<i; k++) if(board[k][j]=='o') { clear=false; break; } }\n                        else if(m.dir == 'D') { for(int k=i+1; k<N; k++) if(board[k][j]=='o') { clear=false; break; } }\n                        else if(m.dir == 'L') { for(int k=0; k<j; k++) if(board[i][k]=='o') { clear=false; break; } }\n                        else if(m.dir == 'R') { for(int k=j+1; k<N; k++) if(board[i][k]=='o') { clear=false; break; } }\n                        m.valid = clear;\n                    }\n\n                    for(auto& m : moves) {\n                        if(!m.valid) continue;\n                        \n                        // Simulate shifts\n                        vector<string> sim_board = board;\n                        for(int k=0; k<m.dist; k++) {\n                            if(m.dir == 'U') {\n                                for(int r=0; r<N-1; r++) sim_board[r][m.param] = sim_board[r+1][m.param];\n                                sim_board[N-1][m.param] = '.';\n                            } else if(m.dir == 'D') {\n                                for(int r=N-1; r>0; r--) sim_board[r][m.param] = sim_board[r-1][m.param];\n                                sim_board[0][m.param] = '.';\n                            } else if(m.dir == 'L') {\n                                for(int c=0; c<N-1; c++) sim_board[m.param][c] = sim_board[m.param][c+1];\n                                sim_board[m.param][N-1] = '.';\n                            } else if(m.dir == 'R') {\n                                for(int c=N-1; c>0; c--) sim_board[m.param][c] = sim_board[m.param][c-1];\n                                sim_board[m.param][0] = '.';\n                            }\n                        }\n                        \n                        int new_pot = calc_potential(sim_board);\n                        int score = m.dist + (new_pot - cur_pot);\n                        if(new_pot >= 1e9) score += 1e8; // Heavy penalty for trapping pieces\n                        \n                        if(score < best_score || (score == best_score && m.dist < best_shifts)) {\n                            best_score = score;\n                            best_shifts = m.dist;\n                            best_dir = m.dir;\n                            best_r = i; best_c = j;\n                            found_direct = true;\n                        }\n                    }\n                }\n            }\n        }\n\n        // Fallback: If lookahead finds no good direct move, use safe greedy\n        if(!found_direct) {\n            int min_cost = 1e9;\n            bool direct_possible = false;\n            \n            // Check for any direct move\n            for(int i=0; i<N; i++) {\n                for(int j=0; j<N; j++) {\n                    if(board[i][j] == 'x') {\n                        bool c = true; for(int k=0; k<i; k++) if(board[k][j]=='o'){c=false;break;}\n                        if(c && (i+1) < min_cost) { min_cost = i+1; best_dir='U'; best_r=i; best_c=j; direct_possible=true; }\n                        c = true; for(int k=i+1; k<N; k++) if(board[k][j]=='o'){c=false;break;}\n                        if(c && (N-i) < min_cost) { min_cost = N-i; best_dir='D'; best_r=i; best_c=j; direct_possible=true; }\n                        c = true; for(int k=0; k<j; k++) if(board[i][k]=='o'){c=false;break;}\n                        if(c && (j+1) < min_cost) { min_cost = j+1; best_dir='L'; best_r=i; best_c=j; direct_possible=true; }\n                        c = true; for(int k=j+1; k<N; k++) if(board[i][k]=='o'){c=false;break;}\n                        if(c && (N-j) < min_cost) { min_cost = N-j; best_dir='R'; best_r=i; best_c=j; direct_possible=true; }\n                    }\n                }\n            }\n            \n            // If still nothing, use Push-Pull\n            if(!direct_possible) {\n                min_cost = 1e9;\n                for(int i=0; i<N; i++) {\n                    for(int j=0; j<N; j++) {\n                        if(board[i][j] == 'x') {\n                            bool c = true; for(int k=0; k<i; k++) if(board[k][j]=='o'){c=false;break;}\n                            if(c && (i+1)*2 < min_cost) { min_cost = (i+1)*2; best_dir='U'; best_r=i; best_c=j; }\n                            c = true; for(int k=i+1; k<N; k++) if(board[k][j]=='o'){c=false;break;}\n                            if(c && (N-i)*2 < min_cost) { min_cost = (N-i)*2; best_dir='D'; best_r=i; best_c=j; }\n                            c = true; for(int k=0; k<j; k++) if(board[i][k]=='o'){c=false;break;}\n                            if(c && (j+1)*2 < min_cost) { min_cost = (j+1)*2; best_dir='L'; best_r=i; best_c=j; }\n                            c = true; for(int k=j+1; k<N; k++) if(board[i][k]=='o'){c=false;break;}\n                            if(c && (N-j)*2 < min_cost) { min_cost = (N-j)*2; best_dir='R'; best_r=i; best_c=j; }\n                        }\n                    }\n                }\n                best_shifts = min_cost / 2;\n                int param = (best_dir == 'U' || best_dir == 'D') ? best_c : best_r;\n                for(int k=0; k<best_shifts; k++) {\n                    ops.push_back({best_dir, param});\n                    apply_shift(best_dir, param);\n                }\n                char pull = (best_dir=='U')?'D':(best_dir=='D')?'U':(best_dir=='L')?'R':'L';\n                for(int k=0; k<best_shifts; k++) {\n                    ops.push_back({pull, param});\n                    apply_shift(pull, param);\n                }\n                continue;\n            } else {\n                best_shifts = min_cost;\n                found_direct = true;\n            }\n        }\n\n        // Apply the chosen direct move\n        int param = (best_dir == 'U' || best_dir == 'D') ? best_c : best_r;\n        for(int k=0; k<best_shifts; k++) {\n            ops.push_back({best_dir, param});\n            apply_shift(best_dir, param);\n        }\n    }\n\n    for(const auto& op : ops) {\n        cout << op.first << \" \" << op.second << \"\\n\";\n    }\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\n#pragma GCC optimize(\"O3,unroll-loops,fast-math\")\nusing namespace std;\n\nconst int MAXN = 105;\n\n// Global variables to minimize stack allocation and reuse memory\nint N, L;\nint T[MAXN];\nint A[MAXN], B[MAXN];\nint bestA[MAXN], bestB[MAXN];\nlong long bestErr = 4e18, curErr = 4e18;\nint cnt[MAXN], sim_cnt[MAXN];\n\n// Fast XorShift RNG\n// Faster than std::mt19937 and avoids overhead of <random>\nstruct FastRNG {\n    uint64_t s;\n    FastRNG(uint64_t seed) : s(seed | 1) {}\n    uint64_t next() {\n        s ^= s << 13; s ^= s >> 7; s ^= s << 17; return s;\n    }\n    // Correct uniform random integer in [0, n-1]\n    int next_int(int n) { \n        return (int)(next() % n); \n    }\n};\n\n// Simulation function\n// Simulates the process for L weeks and calculates the error.\n// Updates the global sim_cnt array with the visit counts.\ninline long long simulate() {\n    // Reset counts\n    for(int i = 0; i < N; ++i) sim_cnt[i] = 0;\n    \n    int cur = 0;\n    // Simulate L weeks\n    for(int w = 0; w < L; ++w) {\n        sim_cnt[cur]++;\n        // Determine next employee based on parity of visits\n        // Odd visits (1st, 3rd...) -> A[cur]\n        // Even visits (2nd, 4th...) -> B[cur]\n        if(sim_cnt[cur] & 1) cur = A[cur];\n        else cur = B[cur];\n    }\n    \n    // Calculate error: sum of absolute differences between actual and target\n    long long err = 0;\n    for(int i = 0; i < N; ++i) {\n        int d = sim_cnt[i] - T[i];\n        err += (d < 0 ? -d : d);\n    }\n    return err;\n}\n\nint main() {\n    // Fast I/O\n    ios::sync_with_stdio(0); cin.tie(0);\n    \n    if(!(cin >> N >> L)) return 0;\n    for(int i = 0; i < N; ++i) cin >> T[i];\n\n    // Initialize RNG with high resolution clock\n    FastRNG rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    // --- Greedy Initialization ---\n    // Build a valid solution by routing transitions to nodes with the highest deficit.\n    // This provides a high-quality starting point.\n    for(int i = 0; i < N; ++i) { A[i] = B[i] = -1; }\n    \n    int build_cnt[MAXN] = {0};\n    int cur = 0;\n    \n    for(int w = 0; w < L; ++w) {\n        build_cnt[cur]++;\n        if(w == L - 1) break; // No transition needed after the last week\n        \n        int t = build_cnt[cur];\n        int nxt;\n        \n        // Determine transition based on parity of current visit count\n        if(t & 1) { // Odd visit count: use A\n            if(A[cur] != -1) {\n                nxt = A[cur];\n            } else {\n                // Pick node with max deficit (T[i] - current_count)\n                int best = 0, mx = -2000000; \n                for(int i = 0; i < N; ++i) {\n                    int def = T[i] - build_cnt[i];\n                    if(def > mx) { mx = def; best = i; }\n                }\n                A[cur] = best;\n                nxt = best;\n            }\n        } else { // Even visit count: use B\n            if(B[cur] != -1) {\n                nxt = B[cur];\n            } else {\n                int best = 0, mx = -2000000;\n                for(int i = 0; i < N; ++i) {\n                    int def = T[i] - build_cnt[i];\n                    if(def > mx) { mx = def; best = i; }\n                }\n                B[cur] = best;\n                nxt = best;\n            }\n        }\n        cur = nxt;\n    }\n\n    // Fill any remaining undefined transitions randomly\n    for(int i = 0; i < N; ++i) {\n        if(A[i] == -1) A[i] = rng.next_int(N);\n        if(B[i] == -1) B[i] = rng.next_int(N);\n    }\n\n    // Evaluate initial solution\n    curErr = simulate();\n    bestErr = curErr;\n    memcpy(bestA, A, sizeof(A));\n    memcpy(bestB, B, sizeof(B));\n    memcpy(cnt, sim_cnt, sizeof(cnt)); // Sync counts for SA heuristic\n\n    // --- Simulated Annealing ---\n    double temp = 50000.0;\n    auto t_start = chrono::steady_clock::now();\n    int iter = 0;\n    \n    // Run iterations until time limit is reached\n    while(true) {\n        // Check time every 32 iterations to minimize overhead\n        if(iter % 32 == 0) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - t_start).count();\n            if(elapsed > 1.85) break; // Strict time limit with safe margin\n            temp *= 0.92; // Smooth cooling schedule\n        }\n        iter++;\n        if(curErr == 0) break; // Optimal solution found\n\n        // Perturbation\n        int u = rng.next_int(N);\n        int v;\n        \n        // Hybrid move: 50% exploitation, 50% exploration\n        if(rng.next() & 1) {\n            // Exploitation: target node with highest deficit\n            int mx = -2000000; v = 0;\n            for(int i = 0; i < N; ++i) {\n                int def = T[i] - cnt[i];\n                if(def > mx) { mx = def; v = i; }\n            }\n        } else {\n            // Exploration: random target\n            v = rng.next_int(N);\n        }\n\n        int old_a = A[u], old_b = B[u];\n        // Randomly change A[u] or B[u]\n        if(rng.next() & 1) A[u] = v;\n        else B[u] = v;\n\n        long long newErr = simulate();\n\n        if(newErr < curErr) {\n            curErr = newErr;\n            // Accept improvement: update state\n            memcpy(cnt, sim_cnt, sizeof(cnt));\n            if(curErr < bestErr) {\n                bestErr = curErr;\n                memcpy(bestA, A, sizeof(A));\n                memcpy(bestB, B, sizeof(B));\n            }\n        } else {\n            // Metropolis criterion\n            double delta = curErr - newErr;\n            if(delta > -50000.0) {\n                double prob = exp(delta / temp);\n                // Fast random double in [0, 1)\n                double r = (rng.next() & 0xFFFFF) / 1048576.0;\n                if(r < prob) {\n                    curErr = newErr;\n                    // Accept worsening: update state\n                    memcpy(cnt, sim_cnt, sizeof(cnt));\n                } else {\n                    // Revert change\n                    A[u] = old_a; B[u] = old_b;\n                }\n            } else {\n                // Revert change\n                A[u] = old_a; B[u] = old_b;\n            }\n        }\n    }\n\n    // Output best solution found\n    for(int i = 0; i < N; ++i) {\n        cout << bestA[i] << \" \" << bestB[i] << \"\\n\";\n    }\n\n    return 0;\n}","ahc045":"/*\n    Final Refined Solution for AHC045\n    Strategy:\n    1. Spatial Partitioning: Sort cities by Morton (Z-order) code to ensure 2D spatial locality.\n       This minimizes intra-group distances before queries.\n    2. Query Strategy:\n       - Phase 1: Overlapping sliding windows (stride L-1) guarantee connectivity of the \n         queried subgraph and build a baseline backbone of verified MST edges.\n       - Phase 2: Random subset queries utilize the remaining query budget (Q=400) to \n         gather diverse verified edges, significantly improving MST accuracy.\n    3. Distance Estimation & Constraints:\n       - RMS Distance: Accounts for bounding box variance, providing a conservative estimate \n         that penalizes edges with high positional uncertainty.\n       - Geometric LB: Hard lower bound based on minimum rectangle-to-rectangle distance.\n       - MST Path Constraint (bottleneck property): Propagates lower bounds from queried MSTs.\n    4. MST Construction: Kruskal's algorithm with edge weight = max(RMS, GeomLB, QueryLB).\n       Verified edges are prioritized in tie-breaking to respect oracle feedback.\n*/\n#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <tuple>\n#include <cmath>\n#include <random>\n\nusing namespace std;\n\n// Disjoint Set Union (Union-Find)\nstruct DSU {\n    vector<int> parent, rank;\n    DSU(int n) : parent(n), rank(n, 0) { iota(parent.begin(), parent.end(), 0); }\n    int find(int x) { return parent[x] == x ? x : parent[x] = find(parent[x]); }\n    bool unite(int x, int y) {\n        x = find(x); y = find(y);\n        if (x != y) {\n            if (rank[x] < rank[y]) swap(x, y);\n            parent[y] = x;\n            if (rank[x] == rank[y]) rank[x]++;\n            return true;\n        }\n        return false;\n    }\n};\n\n// Morton (Z-order) curve encoding for spatial locality\ninline uint64_t morton_encode(uint32_t x, uint32_t y) {\n    uint64_t res = 0;\n    for (int i = 0; i < 16; ++i) {\n        res |= (uint64_t)(x & 1) << (2 * i);\n        res |= (uint64_t)(y & 1) << (2 * i + 1);\n        x >>= 1; y >>= 1;\n    }\n    return res;\n}\n\n// Geometric lower bound: minimum possible distance between two rectangles\nint geom_lb(int u, int v, const vector<int>& lx, const vector<int>& rx, \n            const vector<int>& ly, const vector<int>& ry) {\n    long long dx = 0, dy = 0;\n    if (lx[u] > rx[v]) dx = lx[u] - rx[v];\n    else if (lx[v] > rx[u]) dx = lx[v] - rx[u];\n    if (ly[u] > ry[v]) dy = ly[u] - ry[v];\n    else if (ly[v] > ry[u]) dy = ly[v] - ry[u];\n    return (int)floor(sqrt((double)dx*dx + (double)dy*dy) + 1e-9);\n}\n\n// RMS distance estimation: sqrt(E[D^2]) accounting for bounding box variance\nint rms_dist(int u, int v, const vector<long long>& cx, const vector<long long>& cy,\n             const vector<int>& lx, const vector<int>& rx, const vector<int>& ly, const vector<int>& ry) {\n    long long dx = cx[u] - cx[v];\n    long long dy = cy[u] - cy[v];\n    double d2 = (dx * dx + dy * dy) / 4.0; // cx, cy are 2*center\n    double w_u = rx[u] - lx[u], h_u = ry[u] - ly[u];\n    double w_v = rx[v] - lx[v], h_v = ry[v] - ly[v];\n    double var = (w_u*w_u + h_u*h_u + w_v*w_v + h_v*h_v) / 12.0;\n    return (int)floor(sqrt(d2 + var) + 1e-9);\n}\n\n// Execute a single query and update constraints\nvoid execute_query(const vector<int>& subset, const vector<long long>& cx, const vector<long long>& cy,\n                   const vector<int>& lx, const vector<int>& rx, const vector<int>& ly, const vector<int>& ry,\n                   vector<vector<int>>& lb, vector<vector<char>>& is_verified, int& q_cnt, int Q) {\n    if (subset.size() < 2 || q_cnt >= Q) return;\n    \n    vector<int> sorted_subset = subset;\n    sort(sorted_subset.begin(), sorted_subset.end());\n    \n    cout << \"? \" << sorted_subset.size();\n    for (int city : sorted_subset) cout << \" \" << city;\n    cout << \"\\n\";\n    cout.flush();\n    q_cnt++;\n\n    int len = subset.size();\n    // Local index mapping for O(1) lookup within the subset\n    // City indices are 0..N-1, so size N is sufficient\n    int N = lb.size();\n    vector<int> global_to_local(N, -1);\n    for (int i = 0; i < len; ++i) global_to_local[subset[i]] = i;\n    \n    vector<vector<pair<int, int>>> tree_adj(len);\n    \n    for (int i = 0; i < len - 1; ++i) {\n        int u, v;\n        if (!(cin >> u >> v)) return;\n        if (u > v) swap(u, v);\n        is_verified[u][v] = 1; // Store in upper triangle\n        \n        int u_idx = global_to_local[u];\n        int v_idx = global_to_local[v];\n        int est = rms_dist(u, v, cx, cy, lx, rx, ly, ry);\n        \n        tree_adj[u_idx].push_back({v_idx, est});\n        tree_adj[v_idx].push_back({u_idx, est});\n        \n        // Update bottleneck constraint for the edge itself\n        lb[u][v] = max(lb[u][v], est);\n        lb[v][u] = max(lb[v][u], est);\n    }\n\n    // Propagate MST path constraints (bottleneck property)\n    // For every pair (root, u) in the subset, the direct edge weight must be \n    // >= the max edge weight on the unique path between them in the MST.\n    for (int root = 0; root < len; ++root) {\n        vector<tuple<int, int, int>> stack;\n        stack.reserve(len);\n        stack.emplace_back(root, -1, 0);\n        \n        while (!stack.empty()) {\n            auto [u, p, cur_max] = stack.back();\n            stack.pop_back();\n            \n            int u_city = subset[u];\n            int root_city = subset[root];\n            \n            lb[root_city][u_city] = max(lb[root_city][u_city], cur_max);\n            lb[u_city][root_city] = max(lb[u_city][root_city], cur_max);\n\n            for (auto& edge : tree_adj[u]) {\n                int v = edge.first;\n                int w = edge.second;\n                if (v != p) stack.emplace_back(v, u, max(cur_max, w));\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, Q, L, W;\n    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n    \n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    \n    vector<int> lx(N), rx(N), ly(N), ry(N);\n    vector<long long> cx(N), cy(N); \n    for (int i = 0; i < N; ++i) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n        cx[i] = lx[i] + rx[i];\n        cy[i] = ly[i] + ry[i];\n    }\n\n    // Sort cities by Morton code for 2D spatial clustering\n    vector<int> p(N);\n    iota(p.begin(), p.end(), 0);\n    sort(p.begin(), p.end(), [&](int a, int b) {\n        return morton_encode((uint32_t)cx[a], (uint32_t)cy[a]) < morton_encode((uint32_t)cx[b], (uint32_t)cy[b]);\n    });\n\n    // Partition into groups of required sizes\n    vector<vector<int>> groups(M);\n    int idx = 0;\n    for (int i = 0; i < M; ++i) {\n        groups[i].resize(G[i]);\n        for (int j = 0; j < G[i]; ++j) groups[i][j] = p[idx++];\n    }\n\n    // lb[u][v] stores heuristic lower bound from MST path constraints\n    vector<vector<int>> lb(N, vector<int>(N, 0));\n    // is_verified[u][v] tracks edges returned by the oracle (upper triangle)\n    vector<vector<char>> is_verified(N, vector<char>(N, 0));\n    int q_cnt = 0;\n\n    // Prioritize larger groups for queries (higher impact on score)\n    vector<int> group_indices(M);\n    iota(group_indices.begin(), group_indices.end(), 0);\n    sort(group_indices.begin(), group_indices.end(), [&](int a, int b) {\n        return groups[a].size() > groups[b].size();\n    });\n\n    // Phase 1: Overlapping Sliding Windows (Guarantees connectivity)\n    for (int k_idx : group_indices) {\n        int sz = groups[k_idx].size();\n        if (sz <= 1) continue;\n        for (int start = 0; start < sz - 1; start += L - 1) {\n            if (q_cnt >= Q) goto phase2;\n            int len = min(L, sz - start);\n            vector<int> subset(len);\n            for (int i = 0; i < len; ++i) subset[i] = groups[k_idx][start + i];\n            execute_query(subset, cx, cy, lx, rx, ly, ry, lb, is_verified, q_cnt, Q);\n        }\n    }\n\nphase2:;\n    // Phase 2: Random Queries (Maximize verified edge diversity)\n    mt19937 rng(42);\n    while (q_cnt < Q) {\n        int k_idx = group_indices[rng() % group_indices.size()];\n        int sz = groups[k_idx].size();\n        if (sz < 2) continue;\n        \n        vector<int> indices(sz);\n        iota(indices.begin(), indices.end(), 0);\n        shuffle(indices.begin(), indices.end(), rng);\n        \n        vector<int> subset;\n        subset.reserve(min(sz, L));\n        for (int i = 0; i < min(sz, L); ++i) subset.push_back(groups[k_idx][indices[i]]);\n        execute_query(subset, cx, cy, lx, rx, ly, ry, lb, is_verified, q_cnt, Q);\n    }\n\n    // Build final MST for each group using Kruskal's algorithm\n    vector<vector<pair<int, int>>> final_edges(M);\n    for (int k = 0; k < M; ++k) {\n        int sz = groups[k].size();\n        if (sz <= 1) continue;\n\n        DSU dsu(N);\n        // Tuple: (weight, is_not_verified, u, v)\n        // weight = max(geom_lb, rms_dist, query_lb)\n        vector<tuple<int, int, int, int>> candidates; \n        candidates.reserve(sz * (sz - 1) / 2);\n\n        for (int i = 0; i < sz; ++i) {\n            for (int j = i + 1; j < sz; ++j) {\n                int u_raw = groups[k][i], v_raw = groups[k][j];\n                int u = min(u_raw, v_raw);\n                int v = max(u_raw, v_raw);\n                \n                int g = geom_lb(u, v, lx, rx, ly, ry);\n                int e = rms_dist(u, v, cx, cy, lx, rx, ly, ry);\n                int q = lb[u][v];\n                int weight = max({g, e, q});\n                \n                char verified = is_verified[u][v];\n                candidates.emplace_back(weight, verified ? 0 : 1, u, v);\n            }\n        }\n        \n        // Sort by weight (asc), then verified (0 before 1), then lexicographical (u, v)\n        sort(candidates.begin(), candidates.end());\n\n        for (const auto& c : candidates) {\n            auto [w, inv, u, v] = c; \n            if (dsu.unite(u, v)) final_edges[k].emplace_back(u, v);\n        }\n    }\n\n    // Output results\n    cout << \"!\\n\";\n    cout.flush();\n    for (int k = 0; k < M; ++k) {\n        for (size_t i = 0; i < groups[k].size(); ++i) {\n            if (i > 0) cout << \" \";\n            cout << groups[k][i];\n        }\n        cout << \"\\n\";\n        for (auto& e : final_edges[k]) cout << e.first << \" \" << e.second << \"\\n\";\n    }\n    cout.flush();\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n\n    int start_r, start_c;\n    cin >> start_r >> start_c;\n\n    // Read M-1 target squares\n    vector<pair<int, int>> targets(M - 1);\n    for (int k = 0; k < M - 1; ++k) {\n        cin >> targets[k].first >> targets[k].second;\n    }\n\n    int cur_r = start_r;\n    int cur_c = start_c;\n\n    // Grid state: true if a block is present\n    bool block[20][20] = {};\n    auto is_block = [&](int r, int c) {\n        if (r < 0 || r >= N || c < 0 || c >= N) return true; // Boundaries act as blocks\n        return block[r][c];\n    };\n\n    const int dr[] = {-1, 1, 0, 0};\n    const int dc[] = {0, 0, -1, 1};\n    const char d_name[] = {'U', 'D', 'L', 'R'};\n\n    int dist[20][20];\n    int parent_r[20][20], parent_c[20][20];\n    char act[20][20], dir[20][20];\n\n    struct Node {\n        int f, r, c, g;\n        bool operator>(const Node& other) const { return f > other.f; }\n    };\n\n    const int INF = 1e9;\n\n    for (auto [tr, tc] : targets) {\n        // Initialize distance matrix\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                dist[i][j] = INF;\n\n        priority_queue<Node, vector<Node>, greater<Node>> pq;\n        dist[cur_r][cur_c] = 0;\n        pq.push(Node{abs(cur_r - tr) + abs(cur_c - tc), cur_r, cur_c, 0});\n\n        // A* Search\n        while (!pq.empty()) {\n            auto [f, r, c, g] = pq.top(); pq.pop();\n            if (dist[r][c] < g) continue;\n            if (r == tr && c == tc) break;\n\n            // Try Move\n            for (int d = 0; d < 4; ++d) {\n                int nr = r + dr[d], nc = c + dc[d];\n                if (!is_block(nr, nc)) {\n                    if (dist[nr][nc] > g + 1) {\n                        dist[nr][nc] = g + 1;\n                        parent_r[nr][nc] = r; parent_c[nr][nc] = c;\n                        act[nr][nc] = 'M'; dir[nr][nc] = d_name[d];\n                        int nh = abs(nr - tr) + abs(nc - tc);\n                        pq.push(Node{dist[nr][nc] + nh, nr, nc, g + 1});\n                    }\n                }\n            }\n\n            // Try Slide\n            for (int d = 0; d < 4; ++d) {\n                int nr = r + dr[d], nc = c + dc[d];\n                while (!is_block(nr, nc)) {\n                    nr += dr[d]; nc += dc[d];\n                }\n                nr -= dr[d]; nc -= dc[d]; // Step back to last valid cell\n                if (nr == r && nc == c) continue; // Didn't move\n\n                if (dist[nr][nc] > g + 1) {\n                    dist[nr][nc] = g + 1;\n                    parent_r[nr][nc] = r; parent_c[nr][nc] = c;\n                    act[nr][nc] = 'S'; dir[nr][nc] = d_name[d];\n                    int nh = abs(nr - tr) + abs(nc - tc);\n                    pq.push(Node{dist[nr][nc] + nh, nr, nc, g + 1});\n                }\n            }\n        }\n\n        // Reconstruct path\n        vector<pair<char, char>> path;\n        int r = tr, c = tc;\n        while (r != cur_r || c != cur_c) {\n            path.emplace_back(act[r][c], dir[r][c]);\n            int pr = parent_r[r][c];\n            int pc = parent_c[r][c];\n            r = pr; c = pc;\n        }\n        reverse(path.begin(), path.end());\n\n        // Execute path\n        for (auto [a, d] : path) {\n            cout << a << ' ' << d << '\\n';\n            if (a == 'M') {\n                if (d == 'U') cur_r--;\n                else if (d == 'D') cur_r++;\n                else if (d == 'L') cur_c--;\n                else if (d == 'R') cur_c++;\n            } else if (a == 'S') {\n                if (d == 'U') while (true) { int nr = cur_r - 1; if (is_block(nr, cur_c)) break; cur_r = nr; }\n                else if (d == 'D') while (true) { int nr = cur_r + 1; if (is_block(nr, cur_c)) break; cur_r = nr; }\n                else if (d == 'L') while (true) { int nc = cur_c - 1; if (is_block(cur_r, nc)) break; cur_c = nc; }\n                else if (d == 'R') while (true) { int nc = cur_c + 1; if (is_block(cur_r, nc)) break; cur_c = nc; }\n            }\n        }\n    }\n\n    return 0;\n}"}}}