{"model_name":"glm-5-turbo","codes":{"1":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Company { int x, y, r, id; };\nstruct Rect { int a, b, c, d; };\n\nvoid solve(Rect region, vector<int> ids, vector<Company>& C, vector<Rect>& res) {\n    if (ids.empty()) return;\n    if (ids.size() == 1) { res[ids[0]] = region; return; }\n    \n    int w = region.c - region.a, h = region.d - region.b;\n    long long totalA = 0;\n    for (int id : ids) totalA += C[id].r;\n    \n    auto trySplits = [&](bool vert) -> tuple<long long,int,vector<int>,vector<int>> {\n        sort(ids.begin(), ids.end(), [&](int a, int b) {\n            return vert ? C[a].x < C[b].x : C[a].y < C[b].y;\n        });\n        long long bestD = LLONG_MAX; int bestS = -1, bestI = -1;\n        long long acc = 0;\n        for (int i = 0; i < (int)ids.size()-1; i++) {\n            acc += C[ids[i]].r;\n            int c1 = vert ? C[ids[i]].x : C[ids[i]].y;\n            int c2 = vert ? C[ids[i+1]].x : C[ids[i+1]].y;\n            if (c1 == c2) continue;\n            int lo, hi;\n            if (vert) { lo = max(region.a+1, c1+1); hi = min(region.c-1, c2); }\n            else { lo = max(region.b+1, c1+1); hi = min(region.d-1, c2); }\n            if (lo > hi) continue;\n            long long lA = acc, rA = totalA - acc;\n            auto calc = [&](int s) {\n                long long lC = vert ? (long long)(s-region.a)*h : (long long)w*(s-region.b);\n                long long rC = vert ? (long long)(region.c-s)*h : (long long)w*(region.d-s);\n                return max(0LL,lA-lC)*10 + lC-lA + max(0LL,rA-rC)*10 + rC-rA;\n            };\n            vector<int> cands = {lo, hi};\n            long long opt = vert ? region.a+(lA+h-1)/h : region.b+(lA+w-1)/w;\n            cands.push_back(max(lo, min(hi, (int)clamp(opt,0LL,10000LL))));\n            opt = vert ? region.c-(rA+h-1)/h : region.d-(rA+w-1)/w;\n            cands.push_back(max(lo, min(hi, (int)clamp(opt,0LL,10000LL))));\n            for (int s : cands) { long long d = calc(s); if (d < bestD) { bestD=d; bestS=s; bestI=i; } }\n        }\n        if (bestI == -1) return {LLONG_MAX,-1,{},{}};\n        return {bestD, bestS, vector<int>(ids.begin(),ids.begin()+bestI+1), vector<int>(ids.begin()+bestI+1,ids.end())};\n    };\n    \n    auto [vd,vs,vl,vr] = trySplits(true);\n    auto [hd,hs,hl,hr] = trySplits(false);\n    \n    if (vs == -1 && hs == -1) {\n        for (int id : ids) res[id] = {C[id].x, C[id].y, C[id].x+1, C[id].y+1};\n        return;\n    }\n    bool useV = (hs == -1) || (vs != -1 && vd <= hd);\n    if (useV) {\n        solve({region.a,region.b,vs,region.d}, vl, C, res);\n        solve({vs,region.b,region.c,region.d}, vr, C, res);\n    } else {\n        solve({region.a,region.b,region.c,hs}, hl, C, res);\n        solve({region.a,hs,region.c,region.d}, hr, C, res);\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(nullptr);\n    int n; cin >> n;\n    vector<Company> C(n);\n    for (int i = 0; i < n; i++) { cin >> C[i].x >> C[i].y >> C[i].r; C[i].id = i; }\n    vector<Rect> res(n);\n    vector<int> ids(n); iota(ids.begin(), ids.end(), 0);\n    solve({0,0,10000,10000}, ids, C, res);\n    for (int i = 0; i < n; i++) cout << res[i].a << \" \" << res[i].b << \" \" << res[i].c << \" \" << res[i].d << \"\\n\";\n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <chrono>\n#include <cstring>\n\nusing namespace std;\n\nconst int DEPTH_LIMIT = 150;\nconst int MAX_TILES = 2500;\nconst int MAX_DEG = 8;\n\nint adj[MAX_TILES][MAX_DEG];\nint deg[MAX_TILES];\nbool vis[MAX_TILES];\n\nint temp_vis[MAX_TILES];\nint temp_depth[MAX_TILES];\nint dfs_stack[MAX_TILES];\nint current_stamp = 0;\n\nint cell_to_tile[50][50];\nint p_val[50][50];\n\nint limited_dfs(int start, int excluded) {\n    current_stamp++;\n    int cnt = 0;\n    int stack_ptr = 0;\n    dfs_stack[stack_ptr++] = start;\n    temp_vis[start] = current_stamp;\n    temp_depth[start] = 0;\n    \n    while (stack_ptr > 0) {\n        int node = dfs_stack[--stack_ptr];\n        cnt++;\n        if (temp_depth[node] >= DEPTH_LIMIT) continue;\n        int next_depth = temp_depth[node] + 1;\n        for (int i = 0; i < deg[node]; ++i) {\n            int nxt = adj[node][i];\n            if (nxt != excluded && !vis[nxt] && temp_vis[nxt] != current_stamp) {\n                temp_vis[nxt] = current_stamp;\n                temp_depth[nxt] = next_depth;\n                dfs_stack[stack_ptr++] = nxt;\n            }\n        }\n    }\n    return cnt;\n}\n\nint get_2hop_score(int start, int excluded) {\n    int score = 0;\n    for (int i = 0; i < deg[start]; ++i) {\n        int x = adj[start][i];\n        if (x == excluded || vis[x]) continue;\n        for (int j = 0; j < deg[x]; ++j) {\n            int y = adj[x][j];\n            if (y == start || y == excluded || vis[y]) continue;\n            score++;\n        }\n    }\n    return score;\n}\n\nstruct Candidate {\n    int w;\n    int ni, nj;\n    int p;\n    int c_w;\n    int comp_size;\n    int hop2;\n};\n\nchar get_dir(int i, int j, int ni, int nj) {\n    if (ni == i - 1) return 'U';\n    if (ni == i + 1) return 'D';\n    if (nj == j - 1) return 'L';\n    if (nj == j + 1) return 'R';\n    return '?';\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int si, sj;\n    if (!(cin >> si >> sj)) return 0;\n\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            cin >> cell_to_tile[i][j];\n        }\n    }\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            cin >> p_val[i][j];\n        }\n    }\n\n    int dirs[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\n    \n    // Build adjacency list for tiles\n    memset(deg, 0, sizeof(deg));\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            int T1 = cell_to_tile[i][j];\n            for (auto& d : dirs) {\n                int ni = i + d[0], nj = j + d[1];\n                if (ni >= 0 && ni < 50 && nj >= 0 && nj < 50) {\n                    int T2 = cell_to_tile[ni][nj];\n                    if (T1 != T2) {\n                        bool found = false;\n                        for (int k = 0; k < deg[T1]; ++k) {\n                            if (adj[T1][k] == T2) { found = true; break; }\n                        }\n                        if (!found) adj[T1][deg[T1]++] = T2;\n                        \n                        found = false;\n                        for (int k = 0; k < deg[T2]; ++k) {\n                            if (adj[T2][k] == T1) { found = true; break; }\n                        }\n                        if (!found) adj[T2][deg[T2]++] = T1;\n                    }\n                }\n            }\n        }\n    }\n\n    auto cmp = [](const Candidate& a, const Candidate& b) {\n        bool a_safe = (a.c_w >= 2);\n        bool b_safe = (b.c_w >= 2);\n        if (a_safe != b_safe) return a_safe > b_safe;\n        \n        bool a_corr = (a.c_w == 1);\n        bool b_corr = (b.c_w == 1);\n        if (a_corr != b_corr) return a_corr > b_corr;\n        \n        if (a.comp_size != b.comp_size) return a.comp_size > b.comp_size;\n        if (a.hop2 != b.hop2) return a.hop2 > b.hop2;\n        if (a.p != b.p) return a.p > b.p;\n        \n        return false; // Keep original random order on exact ties\n    };\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    string best_path = \"\";\n    int best_score = -1;\n\n    for (int run = 0; run < 2; ++run) {\n        shuffle(begin(dirs), end(dirs), rng);\n        memset(vis, false, sizeof(vis));\n        \n        int u = cell_to_tile[si][sj];\n        vis[u] = true;\n        int i = si, j = sj;\n        int v = -1;\n        int curr_score = p_val[si][sj];\n        string curr_path = \"\";\n        \n        while (true) {\n            vector<Candidate> candidates;\n            for (auto& d : dirs) {\n                int ni = i + d[0], nj = j + d[1];\n                if (ni < 0 || ni >= 50 || nj < 0 || nj >= 50) continue;\n                int w = cell_to_tile[ni][nj];\n                if (w == u || w == v || vis[w]) continue;\n                \n                int c_w = 0;\n                for (int k = 0; k < deg[w]; ++k) {\n                    int nxt = adj[w][k];\n                    if (nxt != u && !vis[nxt]) c_w++;\n                }\n                \n                candidates.push_back({w, ni, nj, p_val[ni][nj], c_w, 0, 0});\n            }\n            \n            if (candidates.empty()) break;\n            \n            if (candidates.size() > 1) {\n                for (auto& cand : candidates) {\n                    cand.comp_size = limited_dfs(cand.w, u);\n                    cand.hop2 = get_2hop_score(cand.w, u);\n                }\n            }\n            \n            sort(candidates.begin(), candidates.end(), cmp);\n            \n            auto& best = candidates[0];\n            vis[best.w] = true;\n            curr_path += get_dir(i, j, best.ni, best.nj);\n            curr_score += best.p;\n            \n            v = u;\n            u = best.w;\n            i = best.ni;\n            j = best.nj;\n        }\n        \n        if (curr_score > best_score) {\n            best_score = curr_score;\n            best_path = curr_path;\n        }\n    }\n    \n    cout << best_path << \"\\n\";\n\n    return 0;\n}","ahc003":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <cmath>\n#include <tuple>\n#include <algorithm>\n\nusing namespace std;\n\nconst int N = 30;\ndouble W_h[N][N - 1]; // Horizontal edges: (i, j) to (i, j+1)\ndouble W_v[N - 1][N]; // Vertical edges:   (i, j) to (i+1, j)\n\nvector<vector<double>> dist(N, vector<double>(N));\nvector<vector<pair<int, int>>> prev_node(N, vector<pair<int, int>>(N));\nvector<tuple<int, int, int>> edges;\n\nstring dijkstra(int si, int sj, int ti, int tj) {\n    for (int i = 0; i < N; ++i) {\n        fill(dist[i].begin(), dist[i].end(), 1e18);\n        fill(prev_node[i].begin(), prev_node[i].end(), make_pair(-1, -1));\n    }\n    \n    // Min-heap priority queue: {distance, {row, col}}\n    priority_queue<pair<double, pair<int, int>>, vector<pair<double, pair<int, int>>>, greater<>> pq;\n    dist[si][sj] = 0;\n    pq.push({0.0, {si, sj}});\n\n    while (!pq.empty()) {\n        auto [d, u] = pq.top();\n        pq.pop();\n        int i = u.first, j = u.second;\n        \n        if (d > dist[i][j] + 1e-9) continue;\n        if (i == ti && j == tj) break;\n\n        // Up\n        if (i > 0) {\n            double w = W_v[i - 1][j];\n            if (dist[i][j] + w < dist[i - 1][j] - 1e-9) {\n                dist[i - 1][j] = dist[i][j] + w;\n                prev_node[i - 1][j] = {i, j};\n                pq.push({dist[i - 1][j], {i - 1, j}});\n            }\n        }\n        // Down\n        if (i < N - 1) {\n            double w = W_v[i][j];\n            if (dist[i][j] + w < dist[i + 1][j] - 1e-9) {\n                dist[i + 1][j] = dist[i][j] + w;\n                prev_node[i + 1][j] = {i, j};\n                pq.push({dist[i + 1][j], {i + 1, j}});\n            }\n        }\n        // Left\n        if (j > 0) {\n            double w = W_h[i][j - 1];\n            if (dist[i][j] + w < dist[i][j - 1] - 1e-9) {\n                dist[i][j - 1] = dist[i][j] + w;\n                prev_node[i][j - 1] = {i, j};\n                pq.push({dist[i][j - 1], {i, j - 1}});\n            }\n        }\n        // Right\n        if (j < N - 1) {\n            double w = W_h[i][j];\n            if (dist[i][j] + w < dist[i][j + 1] - 1e-9) {\n                dist[i][j + 1] = dist[i][j] + w;\n                prev_node[i][j + 1] = {i, j};\n                pq.push({dist[i][j + 1], {i, j + 1}});\n            }\n        }\n    }\n\n    string path = \"\";\n    int ci = ti, cj = tj;\n    // Trace back from target to start\n    while (ci != si || cj != sj) {\n        auto p = prev_node[ci][cj];\n        int pi = p.first, pj = p.second;\n        if (pi == ci - 1) path += 'D';\n        else if (pi == ci + 1) path += 'U';\n        else if (pj == cj - 1) path += 'R';\n        else if (pj == cj + 1) path += 'L';\n        ci = pi;\n        cj = pj;\n    }\n    \n    reverse(path.begin(), path.end());\n    return path;\n}\n\nint main() {\n    // Fast I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Initialize edge weights to a safe neutral estimate (midpoint of 1000 to 9000)\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N - 1; ++j) W_h[i][j] = 5000.0;\n    }\n    for (int i = 0; i < N - 1; ++i) {\n        for (int j = 0; j < N; ++j) W_v[i][j] = 5000.0;\n    }\n\n    double alpha = 0.2; // Optimal steady-state learning rate offset\n\n    for (int k = 0; k < 1000; ++k) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n\n        string path = dijkstra(si, sj, ti, tj);\n        \n        // Output path and flush immediately\n        cout << path << \"\\n\" << flush;\n\n        long long result;\n        cin >> result;\n\n        double L = 0;\n        int m = path.length();\n        edges.clear();\n        \n        int ci = si, cj = sj;\n        for (char c : path) {\n            if (c == 'U') {\n                edges.push_back({1, ci - 1, cj});\n                L += W_v[ci - 1][cj];\n                ci--;\n            } else if (c == 'D') {\n                edges.push_back({1, ci, cj});\n                L += W_v[ci][cj];\n                ci++;\n            } else if (c == 'L') {\n                edges.push_back({0, ci, cj - 1});\n                L += W_h[ci][cj - 1];\n                cj--;\n            } else if (c == 'R') {\n                edges.push_back({0, ci, cj});\n                L += W_h[ci][cj];\n                cj++;\n            }\n        }\n\n        // SGD weight update\n        if (m > 0) {\n            double delta = (result - L) / m;\n            for (auto& [type, i, j] : edges) {\n                if (type == 0) {\n                    W_h[i][j] = max(100.0, min(9000.0, W_h[i][j] + alpha * delta));\n                } else {\n                    W_v[i][j] = max(100.0, min(9000.0, W_v[i][j] + alpha * delta));\n                }\n            }\n        }\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    cin >> N >> M;\n    vector<string> s(M);\n    for (int i = 0; i < M; i++) cin >> s[i];\n    \n    struct Placement { int type, row, col, len, str_idx; };\n    vector<Placement> all_placements;\n    for (int m = 0; m < M; m++) {\n        int k = s[m].size();\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++)\n            all_placements.push_back({0, i, j, k, m});\n        for (int j = 0; j < N; j++) for (int i = 0; i < N; i++)\n            all_placements.push_back({1, i, j, k, m});\n    }\n    int P = all_placements.size();\n    \n    vector<vector<pair<int,int>>> placement_cells(P), cell_placements(N*N);\n    for (int p = 0; p < P; p++) {\n        auto& pl = all_placements[p];\n        for (int q = 0; q < pl.len; q++) {\n            int r = pl.type==0 ? pl.row : (pl.row+q)%N;\n            int c = pl.type==0 ? (pl.col+q)%N : pl.col;\n            placement_cells[p].push_back({r,c});\n            cell_placements[r*N+c].push_back({p,q});\n        }\n    }\n    \n    vector<array<int,8>> votes(N, array<int,8>{});\n    for (int p = 0; p < P; p++) {\n        auto& pl = all_placements[p];\n        for (int q = 0; q < pl.len; q++) {\n            auto [r,c] = placement_cells[p][q];\n            votes[r][c][s[pl.str_idx][q]-'A']++;\n        }\n    }\n    \n    vector<string> grid(N, string(N,'A'));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        int mx = -1; char best = 'A';\n        for (int c = 0; c < 8; c++) if (votes[i][j][c] > mx) { mx = votes[i][j][c]; best = 'A'+c; }\n        grid[i][j] = best;\n    }\n    \n    vector<int8_t> placement_match(P);\n    vector<int> string_match_count(M, 0);\n    for (int p = 0; p < P; p++) {\n        auto& pl = all_placements[p]; bool ok = true;\n        for (int q = 0; q < pl.len && ok; q++) {\n            auto [r,c] = placement_cells[p][q];\n            if (grid[r][c] != s[pl.str_idx][q]) ok = false;\n        }\n        placement_match[p] = ok;\n        if (ok) string_match_count[pl.str_idx]++;\n    }\n    \n    vector<tuple<int,int,int8_t>> changesToApply;\n    for (int iter = 0; iter < 3; iter++) {\n        bool improved = false;\n        for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) {\n            int ci = r*N+c; char oldChar = grid[r][c];\n            for (int ch = 0; ch < 8; ch++) {\n                char nc = 'A'+ch; if (nc == oldChar) continue;\n                changesToApply.clear(); map<int,int> countChange;\n                for (auto [p,q] : cell_placements[ci]) {\n                    auto& pl = all_placements[p]; int m = pl.str_idx; char exp = s[m][q];\n                    bool was = (oldChar==exp), is = (nc==exp);\n                    if (was == is) continue;\n                    if (was && !is) { if (placement_match[p]) { changesToApply.emplace_back(p,q,0); countChange[m]--; } }\n                    else { bool ok = true;\n                        for (int i = 0; i < pl.len && ok; i++) { if (i==q) continue; auto [rr,cc] = placement_cells[p][i]; if (grid[rr][cc]!=s[m][i]) ok=false; }\n                        if (ok && !placement_match[p]) { changesToApply.emplace_back(p,q,1); countChange[m]++; }\n                    }\n                }\n                if (countChange.empty()) continue;\n                int delta = 0;\n                for (auto& [m,chg] : countChange) {\n                    bool was = string_match_count[m]>0, is = string_match_count[m]+chg>0;\n                    if (!was && is) delta++; else if (was && !is) delta--;\n                }\n                if (delta > 0) {\n                    grid[r][c] = nc;\n                    for (auto [p,q,sm] : changesToApply) { int m = all_placements[p].str_idx; placement_match[p]=sm; string_match_count[m]+=(sm?1:-1); }\n                    oldChar = nc; improved = true;\n                }\n            }\n        }\n        if (!improved) break;\n    }\n    for (int i = 0; i < N; i++) cout << grid[i] << endl;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, si, sj;\nvector<string> grid;\nint cost[70][70];\nvector<pair<int,int>> roads;\nint seg_id[70][70][2];\nint num_segs;\n\nvoid find_segments() {\n    memset(seg_id, -1, sizeof(seg_id));\n    num_segs = 0;\n    for (int i = 0; i < N; i++) {\n        int j = 0;\n        while (j < N) {\n            if (grid[i][j] == '#') { j++; continue; }\n            int start = j;\n            while (j < N && grid[i][j] != '#') j++;\n            for (int k = start; k < j; k++) seg_id[i][k][0] = num_segs++;\n        }\n    }\n    for (int j = 0; j < N; j++) {\n        int i = 0;\n        while (i < N) {\n            if (grid[i][j] == '#') { i++; continue; }\n            int start = i;\n            while (i < N && grid[i][j] != '#') i++;\n            for (int k = start; k < i; k++) seg_id[k][j][1] = num_segs++;\n        }\n    }\n}\n\nvector<int> dist_arr, prev_arr;\nvoid dijkstra(int sx, int sy) {\n    int V = N * N;\n    dist_arr.assign(V, INT_MAX);\n    prev_arr.assign(V, -1);\n    dist_arr[sx * N + sy] = 0;\n    priority_queue<pair<int,int>, vector<pair<int,int>>, greater<>> pq;\n    pq.push({0, sx * N + sy});\n    const int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, -1, 1};\n    while (!pq.empty()) {\n        auto [d, u] = pq.top(); pq.pop();\n        if (d > dist_arr[u]) continue;\n        int x = u / N, y = u % N;\n        for (int k = 0; k < 4; k++) {\n            int nx = x + dx[k], ny = y + dy[k];\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N || grid[nx][ny] == '#') continue;\n            int v = nx * N + ny, nd = d + cost[nx][ny];\n            if (nd < dist_arr[v]) { dist_arr[v] = nd; prev_arr[v] = u; pq.push({nd, v}); }\n        }\n    }\n}\n\nstring get_path(int sx, int sy, int ex, int ey) {\n    if (sx == ex && sy == ey) return \"\";\n    vector<int> trace;\n    for (int u = ex * N + ey; u != sx * N + sy && u != -1; u = prev_arr[u]) trace.push_back(u);\n    reverse(trace.begin(), trace.end());\n    string path;\n    int cur = sx * N + sy;\n    for (int next : trace) {\n        int cx = cur/N, cy = cur%N, nx = next/N, ny = next%N;\n        path += (nx==cx-1) ? 'U' : (nx==cx+1) ? 'D' : (ny==cy-1) ? 'L' : 'R';\n        cur = next;\n    }\n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> si >> sj;\n    grid.resize(N);\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] != '#') { cost[i][j] = grid[i][j] - '0'; roads.push_back({i, j}); }\n    }\n    find_segments();\n    vector<bool> covered(num_segs, false);\n    covered[seg_id[si][sj][0]] = covered[seg_id[si][sj][1]] = true;\n    vector<pair<int,int>> selected;\n    while (true) {\n        int best_count = 0, best_dist = INT_MAX;\n        pair<int,int> best_cell = {-1, -1};\n        for (auto& [i, j] : roads) {\n            int count = (seg_id[i][j][0]!=-1 && !covered[seg_id[i][j][0]]) + (seg_id[i][j][1]!=-1 && !covered[seg_id[i][j][1]]);\n            if (count > best_count) { best_count = count; best_dist = INT_MAX; best_cell = {i, j}; }\n            if (count == best_count && count > 0) {\n                int min_d = abs(i-si) + abs(j-sj);\n                for (auto& [r, c] : selected) min_d = min(min_d, abs(i-r) + abs(j-c));\n                if (min_d < best_dist) { best_dist = min_d; best_cell = {i, j}; }\n            }\n        }\n        if (best_count == 0) break;\n        selected.push_back(best_cell);\n        covered[seg_id[best_cell.first][best_cell.second][0]] = covered[seg_id[best_cell.first][best_cell.second][1]] = true;\n    }\n    string result;\n    int cx = si, cy = sj;\n    vector<bool> visited(selected.size(), false);\n    for (size_t iter = 0; iter < selected.size(); iter++) {\n        dijkstra(cx, cy);\n        int best = -1, best_dist = INT_MAX;\n        for (size_t i = 0; i < selected.size(); i++) {\n            if (visited[i]) continue;\n            int d = dist_arr[selected[i].first * N + selected[i].second];\n            if (d < best_dist) { best_dist = d; best = i; }\n        }\n        if (best == -1) break;\n        visited[best] = true;\n        result += get_path(cx, cy, selected[best].first, selected[best].second);\n        cx = selected[best].first; cy = selected[best].second;\n    }\n    if (cx != si || cy != sj) { dijkstra(cx, cy); result += get_path(cx, cy, si, sj); }\n    cout << result << endl;\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K, R;\n    cin >> N >> M >> K >> R;\n    \n    vector<vector<int>> d(N, vector<int>(K));\n    for (int i = 0; i < N; i++)\n        for (int k = 0; k < K; k++) cin >> d[i][k];\n    \n    vector<vector<int>> deps(N), rdeps(N);\n    for (int i = 0; i < R; i++) {\n        int u, v; cin >> u >> v; u--; v--;\n        deps[v].push_back(u); rdeps[u].push_back(v);\n    }\n    \n    vector<int> topo;\n    { vector<int> indeg(N,0);\n      for(int v=0;v<N;v++) for(int u:deps[v]) indeg[v]++;\n      queue<int> q;\n      for(int i=0;i<N;i++) if(indeg[i]==0) q.push(i);\n      while(!q.empty()) { int u=q.front(); q.pop(); topo.push_back(u);\n        for(int v:rdeps[u]) if(--indeg[v]==0) q.push(v); } }\n    \n    vector<int> crit(N,1);\n    for(int u:topo) for(int v:rdeps[u]) crit[u]=max(crit[u],1+crit[v]);\n    \n    vector<vector<int>> proven(M,vector<int>(K,0)), est(M,vector<int>(K,0));\n    vector<int> tstatus(N,-1), mtask(M,-1), tstart(N,-1), tcount(M,0);\n    \n    auto can_start=[&](int t){ if(tstatus[t]!=-1) return false;\n        for(int dep:deps[t]) if(tstatus[dep]!=1) return false; return true; };\n    auto est_w=[&](int t,int m){ int w=0;\n        for(int k=0;k<K;k++) w+=max(0,d[t][k]-est[m][k]); return w; };\n    auto can_1day=[&](int t,int m){ for(int k=0;k<K;k++)\n        if(d[t][k]>proven[m][k]) return false; return true; };\n    \n    for(int day=1;day<=2000;day++) {\n        vector<int> avail;\n        for(int i=0;i<N;i++) if(can_start(i)) avail.push_back(i);\n        sort(avail.begin(),avail.end(),[&](int a,int b){ return crit[a]>crit[b]; });\n        \n        vector<int> freem;\n        for(int j=0;j<M;j++) if(mtask[j]==-1) freem.push_back(j);\n        \n        vector<pair<int,int>> assign;\n        vector<bool> tused(N,false), mused(M,false);\n        \n        for(int t:avail) { if(tused[t]) continue;\n            for(int m:freem) { if(mused[m]) continue;\n                if(can_1day(t,m)) { assign.push_back({m,t}); tused[t]=mused[m]=true;\n                    mtask[m]=t; tstatus[t]=0; tstart[t]=day; tcount[m]++; break; } } }\n        \n        for(int t:avail) { if(tused[t]) continue;\n            int best=-1; long long best_score=LLONG_MAX;\n            for(int m:freem) { if(mused[m]) continue;\n                long long score=(long long)est_w(t,m)*10000+tcount[m];\n                if(score<best_score) { best_score=score; best=m; } }\n            if(best!=-1) { assign.push_back({best,t}); tused[t]=mused[best]=true;\n                mtask[best]=t; tstatus[t]=0; tstart[t]=day; tcount[best]++; } }\n        \n        cout << assign.size();\n        for(auto [m,t]:assign) cout << \" \" << m+1 << \" \" << t+1;\n        cout << \"\\n\"; cout.flush();\n        \n        int n; cin >> n; if(n==-1) break;\n        for(int i=0;i<n;i++) { int m; cin >> m; m--;\n            int t=mtask[m], actual=day-tstart[t]+1;\n            tstatus[t]=1; mtask[m]=-1;\n            if(actual==1) { for(int k=0;k<K;k++)\n                proven[m][k]=max(proven[m][k],d[t][k]), est[m][k]=max(est[m][k],d[t][k]); }\n            else { int pred_w=est_w(t,m), target_w=actual;\n                vector<int> gap(K); int total_gap=0;\n                for(int k=0;k<K;k++) { gap[k]=max(0,d[t][k]-est[m][k]); total_gap+=gap[k]; }\n                if(total_gap==0) { for(int k=0;k<K;k++) if(d[t][k]>0)\n                    est[m][k]=max(proven[m][k],est[m][k]-(target_w+K-1)/K); }\n                else if(pred_w>target_w) { int excess=pred_w-target_w;\n                    vector<pair<int,int>> sg;\n                    for(int k=0;k<K;k++) if(gap[k]>0) sg.push_back({gap[k],k});\n                    sort(sg.rbegin(),sg.rend());\n                    for(auto [g,k]:sg) { int inc=min(g,excess); est[m][k]+=inc; excess-=inc;\n                        if(excess==0) break; } } } } }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint manhattan(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    vector<array<int, 4>> orders(1000);\n    for (int i = 0; i < 1000; i++)\n        cin >> orders[i][0] >> orders[i][1] >> orders[i][2] >> orders[i][3];\n    \n    vector<pair<double, int>> scored(1000);\n    for (int i = 0; i < 1000; i++) {\n        auto [a, b, c, d] = orders[i];\n        scored[i] = {manhattan(400, 400, (a+c)/2, (b+d)/2) * 2.0 + manhattan(a, b, c, d) * 0.5, i};\n    }\n    sort(scored.begin(), scored.end());\n    \n    vector<int> selected(50);\n    for (int i = 0; i < 50; i++) selected[i] = scored[i].second;\n    \n    auto get_xy = [&](int idx, bool is_del) {\n        int oid = selected[idx];\n        return is_del ? make_pair(orders[oid][2], orders[oid][3]) : make_pair(orders[oid][0], orders[oid][1]);\n    };\n    \n    auto build_route = [&](vector<int>& order_indices) {\n        vector<pair<int, bool>> route;\n        for (int t = 0; t < 50; t++) {\n            int idx = order_indices[t], n = route.size();\n            auto [a, b] = get_xy(idx, false), [c, d] = get_xy(idx, true);\n            int best_cost = INT_MAX, best_pick = -1, best_del = -1;\n            \n            for (int p = 0; p <= n; p++) for (int q = p; q <= n; q++) {\n                int cost = 0; int px = 400, py = 400;\n                for (int i = 0; i < p; i++) { auto [nx, ny] = get_xy(route[i].first, route[i].second); cost += manhattan(px, py, nx, ny); px = nx; py = ny; }\n                cost += manhattan(px, py, a, b); px = a; py = b;\n                for (int i = p; i < q; i++) { auto [nx, ny] = get_xy(route[i].first, route[i].second); cost += manhattan(px, py, nx, ny); px = nx; py = ny; }\n                cost += manhattan(px, py, c, d); px = c; py = d;\n                for (int i = q; i < n; i++) { auto [nx, ny] = get_xy(route[i].first, route[i].second); cost += manhattan(px, py, nx, ny); px = nx; py = ny; }\n                cost += manhattan(px, py, 400, 400);\n                if (cost < best_cost) { best_cost = cost; best_pick = p; best_del = q; }\n            }\n            route.insert(route.begin() + best_del, {idx, true});\n            route.insert(route.begin() + best_pick, {idx, false});\n        }\n        return route;\n    };\n    \n    auto find_pos = [](auto& r) {\n        vector<int> pu(50), de(50);\n        for (int i = 0; i < (int)r.size(); i++) r[i].second ? de[r[i].first] = i : pu[r[i].first] = i;\n        return make_pair(pu, de);\n    };\n    \n    vector<int> ord(50); iota(ord.begin(), ord.end(), 0);\n    vector<pair<int, bool>> best_route; int best_cost = INT_MAX;\n    \n    for (int trial = 0; trial < 8; trial++) {\n        if (trial > 0) shuffle(ord.begin(), ord.end(), rng);\n        auto route = build_route(ord);\n        int cost = 0; int px = 400, py = 400;\n        for (auto& [i, d] : route) { auto [nx, ny] = get_xy(i, d); cost += manhattan(px, py, nx, ny); px = nx; py = ny; }\n        cost += manhattan(px, py, 400, 400);\n        if (cost < best_cost) { best_cost = cost; best_route = route; }\n    }\n    \n    auto [pu_pos, de_pos] = find_pos(best_route);\n    for (int iter = 0; iter < 500; iter++) {\n        bool imp = false;\n        for (int i = 0; i < (int)best_route.size() && !imp; i++) {\n            int idx = best_route[i].first; bool is_d = best_route[i].second;\n            auto [xi, yi] = get_xy(idx, is_d);\n            for (int j = 0; j <= (int)best_route.size() && !imp; j++) {\n                if (j == i || j == i + 1) continue;\n                int nj = j < i ? j : j - 1;\n                int np = pu_pos[idx], nd = de_pos[idx];\n                is_d ? nd = nj : np = nj;\n                if (np >= nd) continue;\n                int n = best_route.size();\n                auto gp = [&](int p) -> pair<int,int> { return (p < 0 || p >= n) ? make_pair(400, 400) : get_xy(best_route[p].first, best_route[p].second); };\n                int delta = 0;\n                auto [xp, yp] = gp(i-1), [xn, yn] = gp(i+1);\n                delta -= manhattan(xp, yp, xi, yi) + manhattan(xi, yi, xn, yn) - manhattan(xp, yp, xn, yn);\n                auto ga = [&](int p) -> pair<int,int> { return (p < 0 || p >= n-1) ? make_pair(400, 400) : get_xy(best_route[p < i ? p : p+1].first, best_route[p < i ? p : p+1].second); };\n                auto [jp, jpy] = ga(nj-1), [jn, jny] = ga(nj);\n                delta -= manhattan(jp, jpy, jn, jny) - manhattan(jp, jpy, xi, yi) - manhattan(xi, yi, jn, jny);\n                if (delta < 0) {\n                    auto sv = best_route[i]; best_route.erase(best_route.begin() + i);\n                    best_route.insert(best_route.begin() + nj, sv); best_cost += delta;\n                    tie(pu_pos, de_pos) = find_pos(best_route); imp = true;\n                }\n            }\n        }\n        if (!imp) break;\n    }\n    \n    cout << 50; for (int i = 0; i < 50; i++) cout << \" \" << selected[i] + 1; cout << \"\\n\";\n    cout << best_route.size() + 2 << \" 400 400\";\n    for (auto& [i, d] : best_route) { auto [x, y] = get_xy(i, d); cout << \" \" << x << \" \" << y; }\n    cout << \" 400 400\\n\";\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <numeric>\n\nusing namespace std;\n\nstruct DSU {\n    vector<int> parent, rank_;\n    DSU(int n) : parent(n), rank_(n, 0) {\n        iota(parent.begin(), parent.end(), 0);\n    }\n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n    bool merge(int x, int y) {\n        x = find(x); y = find(y);\n        if (x == y) return false;\n        if (rank_[x] < rank_[y]) swap(x, y);\n        parent[y] = x;\n        if (rank_[x] == rank_[y]) rank_[x]++;\n        return true;\n    }\n};\n\nint main() {\n    // Fast I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N = 400, M = 1995;\n    vector<double> x(N), y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> x[i] >> y[i];\n    }\n\n    vector<int> u(M), v(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> u[i] >> v[i];\n    }\n\n    DSU dsu(N);\n    // Track rejected edges between component roots\n    // Max possible rejected edges between any two components is bounded\n    vector<vector<int8_t>> rejected(N, vector<int8_t>(N, 0));\n    \n    // Optimal thresholds derived from the optimal stopping rule for U(d, 3d)\n    // V_5 = 1.44984375\n    // V_4 = 1.5165625\n    // V_3 = 1.609375\n    // V_2 = 1.75\n    // V_1 = 2.0 (Not strictly used as we accept unconditionally at k=4)\n    double thresholds[4] = {1.44984375, 1.5165625, 1.609375, 1.75};\n\n    int accepted = 0;\n    for (int i = 0; i < M; ++i) {\n        int l;\n        cin >> l;\n        \n        int A = dsu.find(u[i]);\n        int B = dsu.find(v[i]);\n        \n        // If already connected, reject\n        if (A == B) {\n            cout << \"0\\n\" << std::flush;\n            continue;\n        }\n\n        // Global safety net: If we are running out of edges, accept any connecting edge\n        int remaining = M - i - 1;\n        int needed = (N - 1) - accepted;\n\n        if (remaining <= needed + 5) {\n            cout << \"1\\n\" << std::flush;\n            dsu.merge(A, B);\n            accepted++;\n            continue;\n        }\n\n        // Calculate base distance d_i\n        double dx = x[u[i]] - x[v[i]];\n        double dy = y[u[i]] - y[v[i]];\n        int d = std::round(std::sqrt(dx * dx + dy * dy));\n        \n        // Normalize roots to avoid asymmetric array accesses\n        if (A > B) swap(A, B);\n        \n        int k = rejected[A][B];\n        \n        // If we've seen and rejected 4 edges, this is guaranteed to be the 5th and final edge\n        if (k >= 4) {\n            cout << \"1\\n\" << std::flush;\n            dsu.merge(A, B);\n            accepted++;\n        } else {\n            double thresh = thresholds[k] * d;\n            if (l <= thresh) {\n                cout << \"1\\n\" << std::flush;\n                dsu.merge(A, B);\n                accepted++;\n            } else {\n                cout << \"0\\n\" << std::flush;\n                rejected[A][B]++;\n            }\n        }\n    }\n\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 30, W = 30;\nint N, M;\nint px[25], py[25], pt[25];\nint hx[15], hy[15];\nbool wall[H][W];\n\nint dx[] = {-1, 1, 0, 0};\nint dy[] = {0, 0, -1, 1};\nchar dir_char[] = \"UDLR\";\nchar wall_char[] = \"udlr\";\n\nbool in_bounds(int x, int y) { return 0 <= x && x < H && 0 <= y && y < W; }\n\nbool has_pet_at(int x, int y) {\n    for (int i = 0; i < N; i++) if (px[i] == x && py[i] == y) return true;\n    return false;\n}\n\nbool has_human_at(int x, int y) {\n    for (int i = 0; i < M; i++) if (hx[i] == x && hy[i] == y) return true;\n    return false;\n}\n\nbool pet_adjacent(int x, int y) {\n    for (int d = 0; d < 4; d++) if (has_pet_at(x + dx[d], y + dy[d])) return true;\n    return false;\n}\n\nbool can_place_wall(int x, int y) {\n    if (!in_bounds(x, y) || wall[x][y]) return false;\n    if (has_pet_at(x, y) || has_human_at(x, y)) return false;\n    if (pet_adjacent(x, y)) return false;\n    return true;\n}\n\nint wall_value(int wx, int wy, int hi) {\n    int val = 0;\n    for (int p = 0; p < N; p++) {\n        int weight = (pt[p] == 4) ? 4 : (pt[p] == 3) ? 2 : (pt[p] == 5) ? 2 : 1;\n        int dpw = abs(px[p] - wx) + abs(py[p] - wy);\n        int dwh = abs(wx - hx[hi]) + abs(wy - hy[hi]);\n        int dph = abs(px[p] - hx[hi]) + abs(py[p] - hy[hi]);\n        if (dpw + dwh == dph && dpw > 0 && dwh > 0) val += 100 * weight;\n        if (dpw < 6) val += (6 - dpw) * 10 * weight;\n    }\n    return val;\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++) { cin >> px[i] >> py[i] >> pt[i]; px[i]--; py[i]--; }\n    cin >> M;\n    for (int i = 0; i < M; i++) { cin >> hx[i] >> hy[i]; hx[i]--; hy[i]--; }\n    \n    memset(wall, false, sizeof(wall));\n    \n    for (int turn = 0; turn < 300; turn++) {\n        string actions(M, '.');\n        for (int i = 0; i < M; i++) {\n            int best_d = -1, best_val = 20;\n            for (int d = 0; d < 4; d++) {\n                int wx = hx[i] + dx[d], wy = hy[i] + dy[d];\n                if (can_place_wall(wx, wy)) {\n                    int val = wall_value(wx, wy, i);\n                    if (val > best_val) { best_val = val; best_d = d; }\n                }\n            }\n            if (best_d != -1) {\n                actions[i] = wall_char[best_d];\n            } else {\n                double gx = 0, gy = 0;\n                for (int p = 0; p < N; p++) {\n                    double dist = max(1.0, (double)(abs(hx[i]-px[p]) + abs(hy[i]-py[p])));\n                    gx += (hx[i] - px[p]) / (dist * dist);\n                    gy += (hy[i] - py[p]) / (dist * dist);\n                }\n                int bm = -1; double bd = 0.01;\n                for (int d = 0; d < 4; d++) {\n                    int nx = hx[i]+dx[d], ny = hy[i]+dy[d];\n                    if (in_bounds(nx,ny) && !wall[nx][ny]) {\n                        double dot = dx[d]*gx + dy[d]*gy;\n                        if (dot > bd) { bd = dot; bm = d; }\n                    }\n                }\n                if (bm != -1) actions[i] = dir_char[bm];\n            }\n        }\n        cout << actions << endl;\n        \n        for (int i = 0; i < N; i++) {\n            string mv; cin >> mv;\n            for (char c : mv) for (int d = 0; d < 4; d++) if (c == dir_char[d]) {\n                int nx = px[i]+dx[d], ny = py[i]+dy[d];\n                if (in_bounds(nx,ny) && !wall[nx][ny]) { px[i]=nx; py[i]=ny; }\n                break;\n            }\n        }\n        \n        for (int i = 0; i < M; i++) {\n            if (actions[i] != '.' && islower(actions[i])) {\n                for (int d = 0; d < 4; d++) if (actions[i] == wall_char[d]) {\n                    int nx=hx[i]+dx[d], ny=hy[i]+dy[d];\n                    if (in_bounds(nx,ny)) wall[nx][ny] = true;\n                    break;\n                }\n            }\n            if (actions[i] != '.' && isupper(actions[i])) {\n                for (int d = 0; d < 4; d++) if (actions[i] == dir_char[d]) {\n                    int nx=hx[i]+dx[d], ny=hy[i]+dy[d];\n                    if (in_bounds(nx,ny) && !wall[nx][ny]) { hx[i]=nx; hy[i]=ny; }\n                    break;\n                }\n            }\n        }\n    }\n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cstring>\n#include <cmath>\n\nusing namespace std;\n\nint si, sj, ti, tj;\ndouble p;\nchar h[20][19];\nchar v[19][20];\n\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\nchar dirs[] = {'U', 'D', 'L', 'R'};\n\n// MDP value function: S[r][i][j] is the max expected score from (i, j) with r steps remaining\ndouble S[201][20][20];\n\nbool can_move(int i, int j, int dir) {\n    if (dir == 0) return i > 0 && v[i-1][j] == '0'; // U\n    if (dir == 1) return i < 19 && v[i][j] == '0';   // D\n    if (dir == 2) return j > 0 && h[i][j-1] == '0'; // L\n    return j < 19 && h[i][j] == '0';                 // R\n}\n\nint main() {\n    // Fast I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    if (!(cin >> si >> sj >> ti >> tj >> p)) return 0;\n    \n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 19; ++j) {\n            cin >> h[i][j];\n        }\n    }\n    for (int i = 0; i < 19; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            cin >> v[i][j];\n        }\n    }\n    \n    int L = 200;\n    \n    // Precompute MDP Value Function\n    for (int r = 1; r <= L; ++r) {\n        double reach_score = 400.0 - L + r; // Score if reached at step t = L - r + 1\n        for (int i = 0; i < 20; ++i) {\n            for (int j = 0; j < 20; ++j) {\n                if (i == ti && j == tj) {\n                    S[r][i][j] = 0.0; // Already at target, process terminated\n                    continue;\n                }\n                double best_val = -1e18;\n                for (int dir = 0; dir < 4; ++dir) {\n                    bool wall = !can_move(i, j, dir);\n                    double move_prob = (1.0 - p) * (1.0 - wall);\n                    double stay_prob = 1.0 - move_prob;\n                    \n                    int ni = i + dr[dir], nj = j + dc[dir];\n                    double val = move_prob * reach_score;\n                    if (!wall && (ni != ti || nj != tj)) {\n                        val += move_prob * S[r-1][ni][nj];\n                    }\n                    val += stay_prob * S[r-1][i][j];\n                    \n                    if (val > best_val) {\n                        best_val = val;\n                    }\n                }\n                S[r][i][j] = best_val;\n            }\n        }\n    }\n    \n    // Greedy sequence construction tracking the exact probability distribution\n    double dp[20][20];\n    memset(dp, 0, sizeof(dp));\n    dp[si][sj] = 1.0;\n    string ans = \"\";\n    \n    for (int t = 1; t <= L; ++t) {\n        int R = L - t; // Remaining steps after this one\n        double best_E = -1e18;\n        int best_dir = 0;\n        double best_dp_next[20][20];\n        \n        for (int dir = 0; dir < 4; ++dir) {\n            double score = 0.0;\n            double dp_next[20][20];\n            memset(dp_next, 0, sizeof(dp_next));\n            \n            for (int i = 0; i < 20; ++i) {\n                for (int j = 0; j < 20; ++j) {\n                    if (dp[i][j] < 1e-15) continue;\n                    bool wall = !can_move(i, j, dir);\n                    double move_prob = (1.0 - p) * (1.0 - wall);\n                    double stay_prob = 1.0 - move_prob;\n                    \n                    int ni = i + dr[dir], nj = j + dc[dir];\n                    if (!wall && ni == ti && nj == tj) {\n                        score += dp[i][j] * move_prob * (401.0 - t);\n                    } else if (!wall) {\n                        dp_next[ni][nj] += dp[i][j] * move_prob;\n                    }\n                    dp_next[i][j] += dp[i][j] * stay_prob;\n                }\n            }\n            \n            // Evaluate future potential using the precomputed MDP upper bound\n            double future_val = 0.0;\n            for (int i = 0; i < 20; ++i) {\n                for (int j = 0; j < 20; ++j) {\n                    if (i == ti && j == tj) continue;\n                    future_val += dp_next[i][j] * S[R][i][j];\n                }\n            }\n            \n            double E = score + future_val;\n            if (E > best_E) {\n                best_E = E;\n                best_dir = dir;\n                memcpy(best_dp_next, dp_next, sizeof(dp_next));\n            }\n        }\n        \n        ans += dirs[best_dir];\n        memcpy(dp, best_dp_next, sizeof(dp));\n    }\n    \n    cout << ans << \"\\n\";\n    \n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <string>\n#include <set>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <ctime>\n\nusing namespace std;\n\nint to_table[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1},\n};\n\nint di[4] = {0, -1, 0, 1};\nint dj[4] = {-1, 0, 1, 0};\n\nint valid_out[8][4];\n\nint get_to_fast(int t, int r, int in_d) {\n    int orig_out = to_table[t][(in_d + r) % 4];\n    if (orig_out == -1) return -1;\n    return (orig_out - r + 4) % 4;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Precompute valid_out masks\n    for (int t = 0; t < 8; ++t) {\n        for (int r = 0; r < 4; ++r) {\n            int mask = 0;\n            for (int d = 0; d < 4; ++d) {\n                int orig_out = to_table[t][(d + r) % 4];\n                if (orig_out != -1) {\n                    int out_d = (orig_out - r + 4) % 4;\n                    mask |= (1 << out_d);\n                }\n            }\n            valid_out[t][r] = mask;\n        }\n    }\n\n    vector<int> tiles(900);\n    for (int i = 0; i < 30; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < 30; ++j) {\n            tiles[i * 30 + j] = row[j] - '0';\n        }\n    }\n\n    vector<int> rot(900, 0);\n    \n    // Greedy Initialization\n    for (int i = 0; i < 30; ++i) {\n        for (int j = 0; j < 30; ++j) {\n            int idx = i * 30 + j;\n            int t = tiles[idx];\n            int best_r = 0, best_matches = -1;\n            for (int r = 0; r < 4; ++r) {\n                rot[idx] = r;\n                int matches = 0;\n                if (i > 0) {\n                    int top_idx = (i - 1) * 30 + j;\n                    if ((valid_out[tiles[top_idx]][rot[top_idx]] >> 3) & 1) { // Top has down\n                        if ((valid_out[t][r] >> 1) & 1) matches++; // Current has up\n                    }\n                }\n                if (j > 0) {\n                    int left_idx = i * 30 + (j - 1);\n                    if ((valid_out[tiles[left_idx]][rot[left_idx]] >> 2) & 1) { // Left has right\n                        if ((valid_out[t][r] >> 0) & 1) matches++; // Current has left\n                    }\n                }\n                if (matches > best_matches) {\n                    best_matches = matches;\n                    best_r = r;\n                }\n            }\n            rot[idx] = best_r;\n        }\n    }\n\n    multiset<int> cycles;\n    int pos_x = 0, pos_y = 0;\n\n    auto connects_to = [&](int cx, int cy, int out_d) -> bool {\n        if (cx < 0 || cx >= 30 || cy < 0 || cy >= 30) return false;\n        int nx = cx + di[out_d];\n        int ny = cy + dj[out_d];\n        if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30) return false;\n        return (valid_out[tiles[cx * 30 + cy]][rot[cx * 30 + cy]] >> out_d) & 1;\n    };\n\n    auto trace = [&](int start_x, int start_y, int start_d) -> tuple<int, bool, int> {\n        int cx = start_x, cy = start_y;\n        int curr_in_d = (start_d + 2) % 4;\n        int len = 0;\n        while (true) {\n            int idx = cx * 30 + cy;\n            int out_d = get_to_fast(tiles[idx], rot[idx], curr_in_d);\n            if (out_d == -1) return {len, false, -1};\n            \n            int nx = cx + di[out_d];\n            int ny = cy + dj[out_d];\n            if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30) return {len, false, -1};\n            \n            len++;\n            if (nx == pos_x && ny == pos_y) {\n                return {len, true, out_d};\n            }\n            \n            cx = nx; cy = ny;\n            curr_in_d = (out_d + 2) % 4;\n        }\n    };\n\n    // Initial Evaluation\n    for (int i = 0; i < 30; ++i) {\n        for (int j = 0; j < 30; ++j) {\n            int idx = i * 30 + j;\n            int curr_out_mask = valid_out[tiles[idx]][rot[idx]];\n            for (int d = 0; d < 4; ++d) {\n                if (!(curr_out_mask & (1 << d))) continue;\n                int nx = i + di[d], ny = j + dj[d];\n                if (!connects_to(nx, ny, (d + 2) % 4)) continue;\n                \n                pos_x = i; pos_y = j;\n                auto [len, is_cycle, ret_d] = trace(nx, ny, d);\n                if (is_cycle && ret_d >= d) {\n                    cycles.insert(len + 1);\n                }\n            }\n        }\n    }\n\n    long long current_score = 0;\n    if (cycles.size() >= 2) {\n        auto it = cycles.rbegin();\n        current_score = (long long)*it * (long long)*std::next(it);\n    }\n\n    // SA Setup\n    random_device rd;\n    mt19937 rng(rd());\n    uniform_int_distribution<int> rand_tile(0, 899);\n    uniform_int_distribution<int> rand_rot(0, 3);\n    uniform_real_distribution<double> rand_prob(0.0, 1.0);\n\n    auto start_time = clock();\n    double temp = 100000.0;\n    double cool = 0.999995;\n\n    while (clock() - start_time < 1.8 * CLOCKS_PER_SEC) {\n        int idx = rand_tile(rng);\n        int old_r = rot[idx];\n        int new_r = rand_rot(rng);\n        if (old_r == new_r) continue;\n\n        pos_x = idx / 30; pos_y = idx % 30;\n        int t = tiles[idx];\n\n        // Extract old cycles\n        vector<int> old_cycles;\n        int curr_out_mask = valid_out[t][rot[idx]];\n        for (int d = 0; d < 4; ++d) {\n            if (!(curr_out_mask & (1 << d))) continue;\n            int nx = pos_x + di[d], ny = pos_y + dj[d];\n            if (!connects_to(nx, ny, (d + 2) % 4)) continue;\n            \n            auto [len, is_cycle, ret_d] = trace(nx, ny, d);\n            if (is_cycle && ret_d >= d) {\n                old_cycles.push_back(len + 1);\n            }\n        }\n\n        for (int c : old_cycles) {\n            auto it = cycles.find(c);\n            if (it != cycles.end()) cycles.erase(it);\n        }\n\n        // Apply new rotation\n        rot[idx] = new_r;\n\n        // Extract new cycles\n        vector<int> new_cycles;\n        curr_out_mask = valid_out[t][rot[idx]];\n        for (int d = 0; d < 4; ++d) {\n            if (!(curr_out_mask & (1 << d))) continue;\n            int nx = pos_x + di[d], ny = pos_y + dj[d];\n            if (!connects_to(nx, ny, (d + 2) % 4)) continue;\n            \n            auto [len, is_cycle, ret_d] = trace(nx, ny, d);\n            if (is_cycle && ret_d >= d) {\n                new_cycles.push_back(len + 1);\n            }\n        }\n\n        for (int c : new_cycles) {\n            cycles.insert(c);\n        }\n\n        long long new_score = 0;\n        if (cycles.size() >= 2) {\n            auto it = cycles.rbegin();\n            new_score = (long long)*it * (long long)*std::next(it);\n        }\n\n        // Accept / Reject\n        if (new_score > current_score || exp((new_score - current_score) / temp) > rand_prob(rng)) {\n            current_score = new_score;\n        } else {\n            rot[idx] = old_r;\n            for (int c : new_cycles) {\n                auto it = cycles.find(c);\n                if (it != cycles.end()) cycles.erase(it);\n            }\n            for (int c : old_cycles) {\n                cycles.insert(c);\n            }\n        }\n        temp *= cool;\n    }\n\n    // Output\n    string ans = \"\";\n    for (int i = 0; i < 900; ++i) {\n        ans += (char)('0' + rot[i]);\n    }\n    cout << ans << \"\\n\";\n\n    return 0;\n}","ahc011":"#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, T;\n    cin >> N >> T;\n    \n    vector<string> board(N);\n    for (int i = 0; i < N; i++) cin >> board[i];\n    \n    int ei, ej;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            if (board[i][j] == '0') { ei = i; ej = j; }\n    \n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    const char dc[] = {'U', 'D', 'L', 'R'};\n    const int line_mask[] = {2, 8, 1, 4};\n    const int opp_mask[] = {8, 2, 4, 1};\n    \n    auto get_tile = [&](int i, int j) -> int {\n        char c = board[i][j];\n        return (c == '0') ? -1 : ((c >= 'a') ? (c - 'a' + 10) : (c - '0'));\n    };\n    \n    string moves;\n    mt19937 rng(42);\n    \n    for (int step = 0; step < T; step++) {\n        int valid[4], vc = 0;\n        for (int d = 0; d < 4; d++) {\n            int ni = ei + di[d], nj = ej + dj[d];\n            if (ni >= 0 && ni < N && nj >= 0 && nj < N) valid[vc++] = d;\n        }\n        \n        int best = valid[0], best_delta = -100;\n        vector<int> ties;\n        \n        for (int v = 0; v < vc; v++) {\n            int d = valid[v];\n            int ni = ei + di[d], nj = ej + dj[d];\n            int t = get_tile(ni, nj);\n            if (t < 0) continue;\n            \n            int delta = 0;\n            for (int dd = 0; dd < 4; dd++) {\n                int nni = ei + di[dd], nnj = ej + dj[dd];\n                if (nni >= 0 && nni < N && nnj >= 0 && nnj < N) {\n                    int nt = get_tile(nni, nnj);\n                    if (nt >= 0 && (t & line_mask[dd]) && (nt & opp_mask[dd])) delta++;\n                }\n            }\n            for (int dd = 0; dd < 4; dd++) {\n                int nni = ni + di[dd], nnj = nj + dj[dd];\n                if (nni >= 0 && nni < N && nnj >= 0 && nnj < N) {\n                    int nt = get_tile(nni, nnj);\n                    if (nt >= 0 && (t & line_mask[dd]) && (nt & opp_mask[dd])) delta--;\n                }\n            }\n            \n            if (delta > best_delta) {\n                best_delta = delta;\n                best = d;\n                ties = {d};\n            } else if (delta == best_delta) {\n                ties.push_back(d);\n            }\n        }\n        \n        best = ties[rng() % ties.size()];\n        int ni = ei + di[best], nj = ej + dj[best];\n        swap(board[ei][ej], board[ni][nj]);\n        ei = ni; ej = nj;\n        moves += dc[best];\n    }\n    \n    cout << moves << endl;\n    return 0;\n}","ahc012":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <numeric>\n#include <random>\n\nusing namespace std;\n\nlong long ext_gcd(long long a, long long b, long long &x, long long &y) {\n    if (b == 0) {\n        x = 1; y = 0; return a;\n    }\n    long long x1, y1;\n    long long g = ext_gcd(b, a % b, x1, y1);\n    x = y1;\n    y = x1 - (a / b) * y1;\n    return g;\n}\n\nstruct Line {\n    int A, B;\n    double C;\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N;\n    if (!(cin >> N)) return 0;\n    int K_input;\n    cin >> K_input;\n    const int K = 100;\n    \n    int a[11] = {0};\n    for (int d = 1; d <= 10; d++) cin >> a[d];\n    \n    vector<pair<int, int>> points(N);\n    for (int i = 0; i < N; i++) {\n        cin >> points[i].first >> points[i].second;\n    }\n    \n    vector<pair<int, int>> dir_pool;\n    for (int a = -100; a <= 100; a++) {\n        for (int b = -100; b <= 100; b++) {\n            if (a == 0 && b == 0) continue;\n            if (__gcd(abs(a), abs(b)) == 1) {\n                dir_pool.push_back({a, b});\n            }\n        }\n    }\n    \n    mt19937 mt(42);\n    uniform_int_distribution<int> rand_dir(0, dir_pool.size() - 1);\n    uniform_int_distribution<int> rand_C(-10000, 10000);\n    normal_distribution<double> rand_norm(0.0, 1.0);\n    uniform_real_distribution<double> rand_prob(0.0, 1.0);\n    uniform_int_distribution<int> rand_idx(0, K - 1);\n    \n    vector<Line> lines(K);\n    for (int j = 0; j < K; j++) {\n        lines[j].A = dir_pool[rand_dir(mt)].first;\n        lines[j].B = dir_pool[rand_dir(mt)].second;\n        lines[j].C = rand_C(mt) + 0.5;\n    }\n    \n    auto evaluate = [&]() {\n        vector<pair<uint64_t, uint64_t>> sigs(N);\n        for (int i = 0; i < N; i++) {\n            uint64_t s1 = 0, s2 = 0;\n            int px = points[i].first, py = points[i].second;\n            for (int j = 0; j < K; j++) {\n                if (px * lines[j].A + py * lines[j].B + lines[j].C > 0) {\n                    if (j < 64) s1 |= (1ULL << j);\n                    else s2 |= (1ULL << (j - 64));\n                }\n            }\n            sigs[i] = {s1, s2};\n        }\n        \n        sort(sigs.begin(), sigs.end());\n        \n        int b[11] = {0};\n        int cnt = 1;\n        for (int i = 1; i < N; i++) {\n            if (sigs[i] == sigs[i-1]) cnt++;\n            else {\n                if (cnt <= 10) b[cnt]++;\n                cnt = 1;\n            }\n        }\n        if (cnt <= 10) b[cnt]++;\n        \n        int score = 0;\n        for (int d = 1; d <= 10; d++) score += min(a[d], b[d]);\n        return score;\n    };\n    \n    int best_score = evaluate();\n    vector<Line> best_lines = lines;\n    \n    double temp = 10.0;\n    for (int iter = 0; iter < 8000; iter++) {\n        temp *= 0.9995;\n        \n        int j = rand_idx(mt);\n        Line old_line = lines[j];\n        \n        if (rand_prob(mt) < 0.1) {\n            lines[j].A = dir_pool[rand_dir(mt)].first;\n            lines[j].B = dir_pool[rand_dir(mt)].second;\n            lines[j].C = rand_C(mt) + 0.5;\n        } else {\n            lines[j].C += rand_norm(mt) * (20.0 + temp);\n            if (lines[j].C > 15000.0) lines[j].C = 15000.0;\n            if (lines[j].C < -15000.0) lines[j].C = -15000.0;\n        }\n        \n        int new_score = evaluate();\n        int diff = new_score - best_score;\n        \n        if (diff > 0 || rand_prob(mt) < exp(diff / temp)) {\n            if (new_score > best_score) {\n                best_score = new_score;\n                best_lines = lines;\n            }\n        } else {\n            lines[j] = old_line;\n        }\n    }\n    \n    lines = best_lines;\n    \n    cout << K << \"\\n\";\n    for (int j = 0; j < K; j++) {\n        int A = lines[j].A;\n        int B = lines[j].B;\n        double C = lines[j].C;\n        \n        int C_int = round(C);\n        \n        bool bad = true;\n        while (bad) {\n            bad = false;\n            for (int i = 0; i < N; i++) {\n                if (A * points[i].first + B * points[i].second + C_int == 0) {\n                    C_int++;\n                    bad = true;\n                    break;\n                }\n            }\n        }\n        \n        long long x0, y0;\n        ext_gcd(A, B, x0, y0);\n        \n        long long px1 = -C_int * x0;\n        long long py1 = -C_int * y0;\n        long long px2 = px1 + B;\n        long long py2 = py1 - A;\n        \n        cout << px1 << \" \" << py1 << \" \" << px2 << \" \" << py2 << \"\\n\";\n    }\n\n    return 0;\n}","ahc014":"","ahc015":"#include <iostream>\n#include <cstring>\n\nusing namespace std;\n\nconst int N = 10;\nint grid[N][N];\n\nvoid tilt(char dir) {\n    if (dir == 'F') {\n        for (int c = 0; c < N; c++) {\n            int w = 0;\n            for (int r = 0; r < N; r++) if (grid[r][c]) { int f = grid[r][c]; grid[r][c] = 0; grid[w++][c] = f; }\n        }\n    } else if (dir == 'B') {\n        for (int c = 0; c < N; c++) {\n            int w = N - 1;\n            for (int r = N - 1; r >= 0; r--) if (grid[r][c]) { int f = grid[r][c]; grid[r][c] = 0; grid[w--][c] = f; }\n        }\n    } else if (dir == 'L') {\n        for (int r = 0; r < N; r++) {\n            int w = 0;\n            for (int c = 0; c < N; c++) if (grid[r][c]) { int f = grid[r][c]; grid[r][c] = 0; grid[r][w++] = f; }\n        }\n    } else {\n        for (int r = 0; r < N; r++) {\n            int w = N - 1;\n            for (int c = N - 1; c >= 0; c--) if (grid[r][c]) { int f = grid[r][c]; grid[r][c] = 0; grid[r][w--] = f; }\n        }\n    }\n}\n\nint computeSumSq() {\n    static int vis[N][N], stk[100];\n    memset(vis, 0, sizeof(vis));\n    int sumSq = 0;\n    const int dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1};\n    for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) if (grid[r][c] && !vis[r][c]) {\n        int sz = 0, f = grid[r][c], top = 0;\n        stk[top++] = r * N + c; vis[r][c] = 1;\n        while (top > 0) {\n            int p = stk[--top], cr = p / N, cc = p % N; sz++;\n            for (int d = 0; d < 4; d++) {\n                int nr = cr + dr[d], nc = cc + dc[d];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N && !vis[nr][nc] && grid[nr][nc] == f) {\n                    vis[nr][nc] = 1; stk[top++] = nr * N + nc;\n                }\n            }\n        }\n        sumSq += sz * sz;\n    }\n    return sumSq;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int flavors[100];\n    for (int i = 0; i < 100; i++) cin >> flavors[i];\n    memset(grid, 0, sizeof(grid));\n    for (int t = 0; t < 100; t++) {\n        int p; cin >> p;\n        int cnt = 0, r = -1, c = -1;\n        for (int i = 0; i < N && r < 0; i++) for (int j = 0; j < N && r < 0; j++) if (!grid[i][j] && ++cnt == p) { r = i; c = j; }\n        grid[r][c] = flavors[t];\n        if (t < 99) {\n            char bestDir = 'F'; int bestScore = -1;\n            for (char dir : {'F', 'B', 'L', 'R'}) {\n                int saved[N][N]; memcpy(saved, grid, sizeof(grid));\n                tilt(dir); int score = computeSumSq(); memcpy(grid, saved, sizeof(grid));\n                if (score > bestScore) { bestScore = score; bestDir = dir; }\n            }\n            tilt(bestDir); cout << bestDir << endl;\n        }\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int M;\n    double eps;\n    cin >> M >> eps;\n    \n    int N;\n    if (eps <= 0.01) N = 8;\n    else if (eps <= 0.03) N = 10;\n    else if (eps <= 0.06) N = 12;\n    else if (eps <= 0.10) N = 16;\n    else if (eps <= 0.15) N = 22;\n    else if (eps <= 0.20) N = 28;\n    else if (eps <= 0.30) N = 40;\n    else if (eps <= 0.40) N = 60;\n    else N = 80;\n    \n    N = max(N, 4);\n    N = min(N, 100);\n    \n    int total_pairs = N * (N - 1) / 2;\n    \n    mt19937 rng(42);\n    \n    vector<string> graphs(M);\n    vector<vector<int>> sorted_deg(M, vector<int>(N));\n    \n    for (int i = 0; i < M; i++) {\n        int num_edges = (int)((i + 0.5) * total_pairs / M);\n        string g(total_pairs, '0');\n        vector<int> indices(total_pairs);\n        iota(indices.begin(), indices.end(), 0);\n        shuffle(indices.begin(), indices.end(), rng);\n        for (int j = 0; j < num_edges; j++) g[indices[j]] = '1';\n        graphs[i] = g;\n        \n        int idx = 0;\n        for (int v = 0; v < N; v++) {\n            for (int u = v + 1; u < N; u++) {\n                if (g[idx++] == '1') {\n                    sorted_deg[i][v]++;\n                    sorted_deg[i][u]++;\n                }\n            }\n        }\n        sort(sorted_deg[i].begin(), sorted_deg[i].end());\n    }\n    \n    cout << N << \"\\n\";\n    for (auto& g : graphs) cout << g << \"\\n\";\n    cout << flush;\n    \n    for (int q = 0; q < 100; q++) {\n        string H;\n        cin >> H;\n        \n        vector<int> h_deg(N);\n        int idx = 0;\n        for (int v = 0; v < N; v++) {\n            for (int u = v + 1; u < N; u++) {\n                if (H[idx++] == '1') {\n                    h_deg[v]++;\n                    h_deg[u]++;\n                }\n            }\n        }\n        sort(h_deg.begin(), h_deg.end());\n        \n        int best = 0;\n        double best_dist = 1e18;\n        for (int i = 0; i < M; i++) {\n            double dist = 0;\n            for (int j = 0; j < N; j++) {\n                double diff = h_deg[j] - sorted_deg[i][j];\n                dist += diff * diff;\n            }\n            if (dist < best_dist) {\n                best_dist = dist;\n                best = i;\n            }\n        }\n        cout << best << \"\\n\" << 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    cin >> N >> M >> D >> K;\n    \n    vector<tuple<int, int, int>> edges(M);\n    vector<vector<pair<int, int>>> adj(N);\n    \n    for (int i = 0; i < M; i++) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        u--; v--;\n        edges[i] = {u, v, w};\n        adj[u].push_back({v, i});\n        adj[v].push_back({u, i});\n    }\n    \n    for (int i = 0; i < N; i++) { int x, y; cin >> x >> y; }\n    \n    vector<long long> edge_importance(M, 0);\n    mt19937 rng(42);\n    int S = min(100, N);\n    vector<int> sources(S);\n    iota(sources.begin(), sources.end(), 0);\n    shuffle(sources.begin(), sources.end(), rng);\n    \n    for (int s : sources) {\n        vector<long long> dist(N, 1e18);\n        vector<int> parent_edge(N, -1);\n        dist[s] = 0;\n        priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> pq;\n        pq.push({0, s});\n        \n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u]) continue;\n            for (auto [v, ei] : adj[u]) {\n                if (dist[u] + get<2>(edges[ei]) < dist[v]) {\n                    dist[v] = dist[u] + get<2>(edges[ei]);\n                    parent_edge[v] = ei;\n                    pq.push({dist[v], v});\n                }\n            }\n        }\n        \n        vector<vector<int>> children(N);\n        for (int v = 0; v < N; v++) {\n            if (parent_edge[v] != -1) {\n                auto [pu, pv, pw] = edges[parent_edge[v]];\n                children[(pu == v) ? pv : pu].push_back(v);\n            }\n        }\n        \n        vector<int> subtree_size(N, 1);\n        function<void(int)> dfs = [&](int u) {\n            for (int v : children[u]) {\n                dfs(v);\n                subtree_size[u] += subtree_size[v];\n            }\n            if (parent_edge[u] != -1) edge_importance[parent_edge[u]] += subtree_size[u];\n        };\n        dfs(s);\n    }\n    \n    vector<int> edge_order(M);\n    iota(edge_order.begin(), edge_order.end(), 0);\n    sort(edge_order.begin(), edge_order.end(), [&](int a, int b) {\n        return edge_importance[a] > edge_importance[b];\n    });\n    \n    vector<int> day_assignment(M), day_count(D, 0), vertex_day_count(N * D, 0);\n    \n    for (int e : edge_order) {\n        auto [u, v, w] = edges[e];\n        int best_day = -1, best_conflict = INT_MAX;\n        for (int d = 0; d < D; d++) {\n            if (day_count[d] >= K) continue;\n            int conflict = vertex_day_count[u * D + d] + vertex_day_count[v * D + d];\n            if (conflict < best_conflict) { best_conflict = conflict; best_day = d; }\n        }\n        if (best_day == -1) {\n            for (int d = 0; d < D; d++) {\n                int conflict = vertex_day_count[u * D + d] + vertex_day_count[v * D + d];\n                if (conflict < best_conflict) { best_conflict = conflict; best_day = d; }\n            }\n        }\n        day_assignment[e] = best_day;\n        day_count[best_day]++;\n        vertex_day_count[u * D + best_day]++;\n        vertex_day_count[v * D + best_day]++;\n    }\n    \n    vector<vector<int>> day_edges(D);\n    for (int e = 0; e < M; e++) day_edges[day_assignment[e]].push_back(e);\n    \n    double temperature = 10.0;\n    for (int iter = 0; iter < 300000; iter++) {\n        temperature *= 0.99995;\n        int d1 = rng() % D, d2 = rng() % D;\n        if (d1 == d2 || day_edges[d1].empty() || day_edges[d2].empty()) continue;\n        \n        int idx1 = rng() % day_edges[d1].size(), idx2 = rng() % day_edges[d2].size();\n        int e1 = day_edges[d1][idx1], e2 = day_edges[d2][idx2];\n        auto [u1, v1, w1] = edges[e1];\n        auto [u2, v2, w2] = edges[e2];\n        \n        long long c1 = vertex_day_count[u1 * D + d1] + vertex_day_count[v1 * D + d1] - 2;\n        long long c2 = vertex_day_count[u2 * D + d2] + vertex_day_count[v2 * D + d2] - 2;\n        long long n1 = vertex_day_count[u1 * D + d2] + vertex_day_count[v1 * D + d2] - (u2==u1||v2==u1) - (u2==v1||v2==v1);\n        long long n2 = vertex_day_count[u2 * D + d1] + vertex_day_count[v2 * D + d1] - (u1==u2||v1==u2) - (u1==v2||v1==v2);\n        long long delta = (n1 + n2) - (c1 + c2);\n        \n        if (delta < 0 || (temperature > 0.01 && (double)(rng() % 10000) / 10000.0 < exp(-(double)delta / temperature))) {\n            day_assignment[e1] = d2; day_assignment[e2] = d1;\n            vertex_day_count[u1 * D + d1]--; vertex_day_count[v1 * D + d1]--;\n            vertex_day_count[u1 * D + d2]++; vertex_day_count[v1 * D + d2]++;\n            vertex_day_count[u2 * D + d2]--; vertex_day_count[v2 * D + d2]--;\n            vertex_day_count[u2 * D + d1]++; vertex_day_count[v2 * D + d1]++;\n            day_edges[d1][idx1] = e2; day_edges[d2][idx2] = e1;\n        }\n    }\n    \n    for (int i = 0; i < M; i++) cout << day_assignment[i] + 1 << \" \\n\"[i == M - 1];\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D, b[2][15][15][15], n, rots[24][3][3], numRots=0;\nset<tuple<int,int,int>> V[2];\n\nvoid generateRotations() {\n    set<vector<int>> seen; queue<vector<int>> q;\n    vector<int> id={1,0,0,0,1,0,0,0,1}, rx={1,0,0,0,0,-1,0,1,0}, ry={0,0,1,0,1,0,-1,0,0}, rz={0,-1,0,1,0,0,0,0,1};\n    q.push(id); seen.insert(id);\n    auto mul=[](vector<int> a,vector<int> b){vector<int> c(9);for(int i=0;i<3;i++)for(int j=0;j<3;j++){c[i*3+j]=0;for(int k=0;k<3;k++)c[i*3+j]+=a[i*3+k]*b[k*3+j];}return c;};\n    while(!q.empty()){auto cur=q.front();q.pop();for(int i=0;i<9;i++)rots[numRots][i/3][i%3]=cur[i];numRots++;for(auto&base:{rx,ry,rz}){auto nx=mul(cur,base);if(!seen.count(nx)){seen.insert(nx);q.push(nx);}}}\n}\n\nstring canonical(const vector<tuple<int,int,int>>& cubes) {\n    string best;\n    for(int r=0;r<24;r++){vector<tuple<int,int,int>> rot;int mx=INT_MAX,my=INT_MAX,mz=INT_MAX;\n        for(auto&[x,y,z]:cubes){int nx=rots[r][0][0]*x+rots[r][0][1]*y+rots[r][0][2]*z,ny=rots[r][1][0]*x+rots[r][1][1]*y+rots[r][1][2]*z,nz=rots[r][2][0]*x+rots[r][2][1]*y+rots[r][2][2]*z;mx=min(mx,nx);my=min(my,ny);mz=min(mz,nz);rot.push_back({nx,ny,nz});}\n        sort(rot.begin(),rot.end());string s;for(auto&[x,y,z]:rot){s+=char(x-mx+'a');s+=char(y-my+'a');s+=char(z-mz+'a');}if(best.empty()||s<best)best=s;}return best;\n}\n\nvoid findComponents(int idx, vector<vector<tuple<int,int,int>>>& comps) {\n    set<tuple<int,int,int>> rem=V[idx]; int dx[]={1,-1,0,0,0,0},dy[]={0,0,1,-1,0,0},dz[]={0,0,0,0,1,-1};\n    while(!rem.empty()){auto [sx,sy,sz]=*rem.begin();rem.erase(rem.begin());vector<tuple<int,int,int>> comp;comp.push_back({sx,sy,sz});queue<tuple<int,int,int>> q;q.push({sx,sy,sz});\n        while(!q.empty()){auto[x,y,z]=q.front();q.pop();for(int d=0;d<6;d++){int nx=x+dx[d],ny=y+dy[d],nz=z+dz[d];auto np=make_tuple(nx,ny,nz);if(rem.count(np)){rem.erase(np);comp.push_back(np);q.push(np);}}}comps.push_back(comp);}\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    generateRotations(); cin>>D; int f[2][15][15],r[2][15][15];\n    for(int i=0;i<2;i++){for(int z=0;z<D;z++){string s;cin>>s;for(int x=0;x<D;x++)f[i][z][x]=s[x]-'0';}for(int z=0;z<D;z++){string s;cin>>s;for(int y=0;y<D;y++)r[i][z][y]=s[y]-'0';}}\n    for(int i=0;i<2;i++)for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++)if(f[i][z][x]&&r[i][z][y])V[i].insert({x,y,z});\n    vector<vector<tuple<int,int,int>>> comps[2]; findComponents(0,comps[0]); findComponents(1,comps[1]);\n    vector<string> canon[2];\n    for(int i=0;i<2;i++)for(auto&comp:comps[i]){vector<tuple<int,int,int>> norm=comp;int mx=INT_MAX,my=INT_MAX,mz=INT_MAX;for(auto&[x,y,z]:norm){mx=min(mx,x);my=min(my,y);mz=min(mz,z);}for(auto&[x,y,z]:norm){x-=mx;y-=my;z-=mz;}canon[i].push_back(canonical(norm));}\n    map<string,vector<int>> c2c[2]; for(int i=0;i<2;i++)for(int j=0;j<(int)comps[i].size();j++)c2c[i][canon[i][j]].push_back(j);\n    for(int i=0;i<2;i++)for(auto&[c,idx]:c2c[i])sort(idx.begin(),idx.end(),[&](int a,int b){return comps[i][a].size()>comps[i][b].size();});\n    memset(b,0,sizeof(b)); n=0; vector<bool> used[2]; used[0].resize(comps[0].size()); used[1].resize(comps[1].size());\n    for(auto&[c,idx0]:c2c[0])if(c2c[1].count(c)){auto&idx1=c2c[1][c];int mc=min(idx0.size(),idx1.size());for(int m=0;m<mc;m++){n++;int i0=idx0[m],i1=idx1[m];used[0][i0]=used[1][i1]=true;for(auto&[x,y,z]:comps[0][i0])b[0][x][y][z]=n;for(auto&[x,y,z]:comps[1][i1])b[1][x][y][z]=n;}}\n    for(int i=0;i<2;i++)for(int j=0;j<(int)comps[i].size();j++)if(!used[i][j]){n++;for(auto&[x,y,z]:comps[i][j])b[i][x][y][z]=n;}\n    cout<<n<<'\\n'; for(int i=0;i<2;i++){string out;for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){if(!out.empty())out+=' ';out+=to_string(b[i][x][y][z]);}cout<<out<<'\\n';}\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\ntypedef long long ll;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K;\n    cin >> N >> M >> K;\n    \n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    \n    vector<tuple<int, int, ll>> edges(M);\n    vector<vector<pair<int, ll>>> adj(N);\n    for (int j = 0; j < M; j++) {\n        int u, v; ll w;\n        cin >> u >> v >> w;\n        u--; v--;\n        edges[j] = {u, v, w};\n        adj[u].push_back({v, w});\n        adj[v].push_back({u, w});\n    }\n    \n    vector<int> a(K), b(K);\n    for (int k = 0; k < K; k++) cin >> a[k] >> b[k];\n    \n    vector<vector<int>> dist(K, vector<int>(N));\n    for (int k = 0; k < K; k++) {\n        for (int i = 0; i < N; i++) {\n            ll dx = (ll)(x[i] - a[k]) * (x[i] - a[k]);\n            ll dy = (ll)(y[i] - b[k]) * (y[i] - b[k]);\n            dist[k][i] = (int)round(sqrt((double)dx + dy));\n        }\n    }\n    \n    vector<int> closest(K), min_dist(K);\n    for (int k = 0; k < K; k++) {\n        int md = 5001, mv = 0;\n        for (int i = 0; i < N; i++)\n            if (dist[k][i] <= 5000 && dist[k][i] < md) { md = dist[k][i]; mv = i; }\n        closest[k] = mv; min_dist[k] = md;\n    }\n    \n    vector<bool> needed(N, false);\n    for (int k = 0; k < K; k++) needed[closest[k]] = true;\n    needed[0] = true;\n    \n    vector<int> par(N), rnk(N, 0);\n    iota(par.begin(), par.end(), 0);\n    function<int(int)> find = [&](int x) { return par[x] == x ? x : par[x] = find(par[x]); };\n    auto unite = [&](int x, int y) -> bool {\n        x = find(x); y = find(y);\n        if (x == y) return false;\n        if (rnk[x] < rnk[y]) swap(x, y);\n        par[y] = x;\n        if (rnk[x] == rnk[y]) rnk[x]++;\n        return true;\n    };\n    \n    vector<int> order(M); iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int i, int j) { return get<2>(edges[i]) < get<2>(edges[j]); });\n    \n    vector<bool> edge_used(M, false);\n    vector<vector<int>> tree_adj(N);\n    for (int idx : order) {\n        auto [u, v, w] = edges[idx];\n        if (unite(u, v)) {\n            edge_used[idx] = true;\n            tree_adj[u].push_back(v);\n            tree_adj[v].push_back(u);\n        }\n    }\n    \n    vector<bool> keep(N, false);\n    function<void(int, int)> dfs = [&](int u, int p) {\n        if (needed[u]) keep[u] = true;\n        for (int v : tree_adj[u]) {\n            if (v == p) continue;\n            dfs(v, u);\n            if (keep[v]) keep[u] = true;\n        }\n    };\n    dfs(0, -1);\n    \n    for (int idx = 0; idx < M; idx++) {\n        if (edge_used[idx]) {\n            auto [u, v, w] = edges[idx];\n            if (!keep[u] || !keep[v]) edge_used[idx] = false;\n        }\n    }\n    \n    vector<int> P(N, 0);\n    for (int k = 0; k < K; k++) {\n        int md = INT_MAX, mv = -1;\n        for (int i = 0; i < N; i++)\n            if (keep[i] && dist[k][i] < md) { md = dist[k][i]; mv = i; }\n        if (mv != -1 && md <= 5000) P[mv] = max(P[mv], md);\n    }\n    \n    for (int i = 0; i < N; i++) cout << P[i] << \" \\n\"[i == N - 1];\n    for (int j = 0; j < M; j++) cout << edge_used[j] << \" \\n\"[j == M - 1];\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N = 30;\nint grid[30][30];\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \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    vector<tuple<int,int,int,int>> ops;\n    \n    for (int pass = 0; pass < 50 && ops.size() < 10000; pass++) {\n        bool changed = false;\n        for (int x = N - 2; x >= 0; x--) {\n            for (int y = 0; y <= x; y++) {\n                if (ops.size() >= 10000) break;\n                int v = grid[x][y];\n                int c1 = grid[x+1][y];\n                int c2 = grid[x+1][y+1];\n                int min_c = min(c1, c2);\n                \n                if (v > min_c) {\n                    if (c1 <= c2) {\n                        swap(grid[x][y], grid[x+1][y]);\n                        ops.push_back({x, y, x+1, y});\n                    } else {\n                        swap(grid[x][y], grid[x+1][y+1]);\n                        ops.push_back({x, y, x+1, y+1});\n                    }\n                    changed = true;\n                }\n            }\n        }\n        if (!changed) break;\n    }\n    \n    cout << ops.size() << \"\\n\";\n    for (auto& [x1, y1, x2, y2] : ops) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << \"\\n\";\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D, N, grid[9][9], container_num[9][9], init_dist[9][9];\nint di[] = {0, 0, 1, -1}, dj[] = {1, -1, 0, 0};\nint entrance_i = 0, entrance_j;\nvector<pair<int,int>> all_cells_sorted;\n\nvoid compute_init_dist() {\n    queue<pair<int,int>> q;\n    memset(init_dist, -1, sizeof(init_dist));\n    init_dist[entrance_i][entrance_j] = 0;\n    q.push({entrance_i, entrance_j});\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int ni = i + di[d], nj = j + dj[d];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && init_dist[ni][nj] == -1 && grid[ni][nj] != 1) {\n                init_dist[ni][nj] = init_dist[i][j] + 1;\n                q.push({ni, nj});\n            }\n        }\n    }\n    for (int i = 0; i < D; i++)\n        for (int j = 0; j < D; j++)\n            if ((i != entrance_i || j != entrance_j) && grid[i][j] != 1)\n                all_cells_sorted.push_back({i, j});\n    sort(all_cells_sorted.begin(), all_cells_sorted.end(), [](auto& a, auto& b) {\n        return tie(init_dist[a.first][a.second], a.first, a.second) < tie(init_dist[b.first][b.second], b.first, b.second);\n    });\n}\n\nvector<pair<int,int>> get_reachable_empty() {\n    vector<pair<int,int>> cells;\n    queue<pair<int,int>> q;\n    int visited[9][9] = {};\n    visited[entrance_i][entrance_j] = 1;\n    q.push({entrance_i, entrance_j});\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        if ((i != entrance_i || j != entrance_j) && grid[i][j] == 0) cells.push_back({i, j});\n        for (int d = 0; d < 4; d++) {\n            int ni = i + di[d], nj = j + dj[d];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && !visited[ni][nj] && grid[ni][nj] == 0) {\n                visited[ni][nj] = 1;\n                q.push({ni, nj});\n            }\n        }\n    }\n    return cells;\n}\n\nvector<pair<int,int>> get_reachable_containers() {\n    vector<pair<int,int>> cells;\n    queue<pair<int,int>> q;\n    int visited[9][9] = {};\n    visited[entrance_i][entrance_j] = 1;\n    q.push({entrance_i, entrance_j});\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int ni = i + di[d], nj = j + dj[d];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && !visited[ni][nj]) {\n                visited[ni][nj] = 1;\n                if (grid[ni][nj] == 2) cells.push_back({ni, nj});\n                else if (grid[ni][nj] == 0) q.push({ni, nj});\n            }\n        }\n    }\n    return cells;\n}\n\npair<int,int> find_placement(int t, int total) {\n    auto cells = get_reachable_empty();\n    if (cells.empty()) return {-1, -1};\n    int ideal_dist = init_dist[all_cells_sorted[t].first][all_cells_sorted[t].second];\n    sort(cells.begin(), cells.end(), [ideal_dist](auto& a, auto& b) {\n        int da = abs(init_dist[a.first][a.second] - ideal_dist);\n        int db = abs(init_dist[b.first][b.second] - ideal_dist);\n        if (da != db) return da < db;\n        int ea = 0, eb = 0;\n        for (int d = 0; d < 4; d++) {\n            int ni = a.first + di[d], nj = a.second + dj[d];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && grid[ni][nj] == 0 && !(ni == entrance_i && nj == entrance_j)) ea++;\n            ni = b.first + di[d]; nj = b.second + dj[d];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && grid[ni][nj] == 0 && !(ni == entrance_i && nj == entrance_j)) eb++;\n        }\n        return tie(ea, a.first, a.second) < tie(eb, b.first, b.second);\n    });\n    return cells[0];\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> D >> N;\n    entrance_j = (D - 1) / 2;\n    memset(grid, 0, sizeof(grid));\n    memset(container_num, -1, sizeof(container_num));\n    for (int i = 0; i < N; i++) { int ri, rj; cin >> ri >> rj; grid[ri][rj] = 1; }\n    int total = D * D - 1 - N;\n    compute_init_dist();\n    for (int d = 0; d < total; d++) {\n        int t; cin >> t;\n        auto [pi, pj] = find_placement(t, total);\n        grid[pi][pj] = 2;\n        container_num[pi][pj] = t;\n        cout << pi << \" \" << pj << \"\\n\" << flush;\n    }\n    for (int d = 0; d < total; d++) {\n        auto containers = get_reachable_containers();\n        int best_num = INT_MAX;\n        pair<int,int> best_pos = {-1, -1};\n        for (auto& [i, j] : containers)\n            if (container_num[i][j] < best_num) { best_num = container_num[i][j]; best_pos = {i, j}; }\n        grid[best_pos.first][best_pos.second] = 0;\n        cout << best_pos.first << \" \" << best_pos.second << \"\\n\" << flush;\n    }\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\nusing namespace std::chrono;\n\nint n, m;\nint grid[50][50];\nset<int> adj_set[101];\nvector<pair<int,int>> color_pos[101];\nint adj_cnt[101][101];\nint boundary_cnt[101];\n\nint dr[] = {0, 0, 1, -1};\nint dc[] = {1, -1, 0, 0};\n\nint vis_gen[50][50];\nint cur_gen = 0;\n\nbool is_connected(int color, int er, int ec) {\n    cur_gen++;\n    int cnt = 0, sr = -1, sc = -1;\n    for (auto& [i, j] : color_pos[color]) {\n        if (grid[i][j] != color || (i == er && j == ec)) continue;\n        if (sr == -1) { sr = i; sc = j; }\n        cnt++;\n    }\n    if (cnt <= 1) return true;\n    queue<pair<int,int>> q;\n    q.push({sr, sc}); vis_gen[sr][sc] = cur_gen; int vc = 1;\n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nr = r + dr[d], nc = c + dc[d];\n            if (nr < 0 || nr >= n || nc < 0 || nc >= n) continue;\n            if (vis_gen[nr][nc] == cur_gen || (nr == er && nc == ec)) continue;\n            if (grid[nr][nc] == color) { vis_gen[nr][nc] = cur_gen; vc++; q.push({nr, nc}); }\n        }\n    }\n    return vc == cnt;\n}\n\nbool can_remove(int r, int c) {\n    int color = grid[r][c];\n    if (color == 0) return false;\n    int same = 0, boundary_here = 0, regular0_here = 0;\n    for (int d = 0; d < 4; d++) {\n        int nr = r + dr[d], nc = c + dc[d];\n        if (nr < 0 || nr >= n || nc < 0 || nc >= n) { boundary_here++; }\n        else {\n            int nb = grid[nr][nc];\n            if (nb == color) same++;\n            else if (nb == 0) regular0_here++;\n            else { if (!adj_set[0].count(nb)) return false; if (adj_cnt[color][nb] <= 1) return false; }\n        }\n    }\n    if (adj_set[color].count(0)) {\n        int remaining = (boundary_cnt[color] - boundary_here) + (adj_cnt[color][0] - regular0_here);\n        if (remaining <= 0) return false;\n    }\n    if (same <= 1) {\n        int cnt = 0;\n        for (auto& [i, j] : color_pos[color]) if (grid[i][j] == color) cnt++;\n        if (cnt <= 1) return false;\n    } else { if (!is_connected(color, r, c)) return false; }\n    return true;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(NULL);\n    auto start_time = high_resolution_clock::now();\n    cin >> n >> m;\n    for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { cin >> grid[i][j]; color_pos[grid[i][j]].push_back({i, j}); }\n    for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) {\n        int color = grid[i][j];\n        for (int d = 0; d < 4; d++) {\n            int nr = i + dr[d], nc = j + dc[d];\n            if (nr < 0 || nr >= n || nc < 0 || nc >= n) { boundary_cnt[color]++; adj_set[color].insert(0); adj_set[0].insert(color); }\n            else if (grid[nr][nc] != color) { int nb = grid[nr][nc]; adj_cnt[color][nb]++; adj_set[color].insert(nb); adj_set[nb].insert(color); }\n        }\n    }\n    bool changed = true;\n    while (changed) {\n        if (duration_cast<milliseconds>(high_resolution_clock::now() - start_time).count() > 1800) break;\n        changed = false;\n        for (int color = 1; color <= m; color++) {\n            vector<tuple<int,int,int>> tiles;\n            for (auto& [i, j] : color_pos[color]) {\n                if (grid[i][j] != color) continue;\n                int same = 0;\n                for (int d = 0; d < 4; d++) { int nr = i + dr[d], nc = j + dc[d]; if (nr >= 0 && nr < n && nc >= 0 && nc < n && grid[nr][nc] == color) same++; }\n                tiles.push_back({same, i, j});\n            }\n            sort(tiles.begin(), tiles.end());\n            for (auto& [_, r, c] : tiles) {\n                if (grid[r][c] != color) continue;\n                if (can_remove(r, c)) {\n                    for (int d = 0; d < 4; d++) {\n                        int nr = r + dr[d], nc = c + dc[d];\n                        if (nr < 0 || nr >= n || nc < 0 || nc >= n) boundary_cnt[color]--;\n                        else { int nb = grid[nr][nc]; if (nb != color) adj_cnt[color][nb]--; }\n                    }\n                    grid[r][c] = 0; changed = true;\n                }\n            }\n        }\n    }\n    for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { cout << grid[i][j]; if (j < n-1) cout << \" \"; } cout << \"\\n\"; }\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <numeric>\n\nusing namespace std;\n\nint N, D, Q;\n\nchar query(int x, int y) {\n    cout << \"1 1 \" << x << \" \" << y << \"\\n\" << flush;\n    char res;\n    cin >> res;\n    return res;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    if (!(cin >> N >> D >> Q)) return 0;\n    \n    vector<vector<int>> adj(N);\n    vector<int> sorted_items;\n    vector<int> unsorted_items;\n    for (int i = 0; i < N; ++i) {\n        unsorted_items.push_back(i);\n    }\n    \n    int q_left = Q;\n    while (q_left > 0 && !unsorted_items.empty()) {\n        int x = unsorted_items.back();\n        unsorted_items.pop_back();\n        \n        if (!sorted_items.empty()) {\n            int lo = 0, hi = sorted_items.size();\n            while (lo < hi && q_left > 0) {\n                int mid = (lo + hi) / 2;\n                int y = sorted_items[mid];\n                q_left--;\n                char res = query(x, y);\n                if (res == '>') {\n                    adj[x].push_back(y);\n                    hi = mid;\n                } else if (res == '<') {\n                    adj[y].push_back(x);\n                    lo = mid + 1;\n                } else { // '='\n                    break;\n                }\n            }\n            sorted_items.insert(sorted_items.begin() + lo, x);\n        } else {\n            if (!unsorted_items.empty()) {\n                int y = unsorted_items.back();\n                unsorted_items.pop_back();\n                q_left--;\n                char res = query(x, y);\n                if (res == '>') {\n                    adj[x].push_back(y);\n                    sorted_items.push_back(x);\n                    sorted_items.push_back(y);\n                } else if (res == '<') {\n                    adj[y].push_back(x);\n                    sorted_items.push_back(y);\n                    sorted_items.push_back(x);\n                } else {\n                    sorted_items.push_back(x);\n                    sorted_items.push_back(y);\n                }\n            } else {\n                sorted_items.push_back(x);\n            }\n        }\n    }\n    \n    // Append remaining unqueried items\n    for (int x : unsorted_items) {\n        sorted_items.push_back(x);\n    }\n    \n    // Compute longest path from sources in the DAG using Kahn's algorithm\n    vector<int> in_degree(N, 0);\n    for (int i = 0; i < N; ++i) {\n        for (int j : adj[i]) {\n            in_degree[j]++;\n        }\n    }\n    \n    queue<int> q;\n    for (int i = 0; i < N; ++i) {\n        if (in_degree[i] == 0) q.push(i);\n    }\n    \n    vector<int> dp(N, 0);\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : adj[u]) {\n            if (dp[v] < dp[u] + 1) {\n                dp[v] = dp[u] + 1;\n            }\n            in_degree[v]--;\n            if (in_degree[v] == 0) {\n                q.push(v);\n            }\n        }\n    }\n    \n    // Sort all items by their longest path value (ascending)\n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n    sort(items.begin(), items.end(), [&](int a, int b) {\n        if (dp[a] != dp[b]) return dp[a] < dp[b];\n        return a < b; // Tie-breaker\n    });\n    \n    // Map ranks to expected weights of exponential distribution order statistics\n    double W_max = 100000.0 * N / D;\n    vector<double> expected_w(N);\n    double sum = 0;\n    for (int i = 0; i < N; ++i) {\n        sum += 100000.0 / (N - i);\n        expected_w[i] = min(sum, W_max);\n    }\n    \n    // Greedy partitioning based on expected weights\n    vector<double> set_sums(D, 0);\n    vector<int> partition(N);\n    double total_sum = accumulate(expected_w.begin(), expected_w.end(), 0.0);\n    double target_sum = total_sum / D;\n    \n    // Process from largest expected weight to smallest\n    for (int i = N - 1; i >= 0; --i) {\n        int item = items[i];\n        double w = expected_w[i];\n        \n        int best_set = -1;\n        double max_deficit = 0;\n        for (int j = 0; j < D; ++j) {\n            double deficit = target_sum - set_sums[j];\n            if (deficit > max_deficit) {\n                max_deficit = deficit;\n                best_set = j;\n            }\n        }\n        \n        // Fallback if all sets exceed the target sum\n        if (best_set == -1) {\n            best_set = 0;\n            for (int j = 1; j < D; ++j) {\n                if (set_sums[j] < set_sums[best_set]) {\n                    best_set = j;\n                }\n            }\n        }\n        \n        set_sums[best_set] += w;\n        partition[item] = best_set;\n    }\n    \n    // Output the final division mapping\n    for (int i = 0; i < N; ++i) {\n        cout << partition[i] << (i == N - 1 ? \"\" : \" \");\n    }\n    cout << \"\\n\" << flush;\n    \n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> stacks(m);\n    vector<int> pos(n + 1), idx(n + 1);\n    \n    for (int i = 0; i < m; i++) {\n        stacks[i].resize(n / m);\n        for (int j = 0; j < n / m; j++) {\n            cin >> stacks[i][j];\n            pos[stacks[i][j]] = i;\n            idx[stacks[i][j]] = j;\n        }\n    }\n    \n    vector<pair<int, int>> operations;\n    int nextBox = 1;\n    \n    while (nextBox <= n) {\n        int si = pos[nextBox], pi = idx[nextBox];\n        \n        if (pi == (int)stacks[si].size() - 1) {\n            operations.push_back({nextBox, 0});\n            stacks[si].pop_back();\n            nextBox++;\n        } else {\n            int boxToMove = stacks[si][pi + 1];\n            \n            bool increasing = true;\n            for (int j = pi + 1; j < (int)stacks[si].size() - 1; j++) {\n                if (stacks[si][j] > stacks[si][j + 1]) { increasing = false; break; }\n            }\n            \n            int bestDest = -1, bestScore = -1e9;\n            for (int i = 0; i < m; i++) {\n                if (i == si) continue;\n                int score;\n                if (stacks[i].empty()) score = 500;\n                else if (stacks[i].back() < boxToMove) score = increasing ? 1000 + stacks[i].back() : 200;\n                else score = -1000;\n                if (score > bestScore) { bestScore = score; bestDest = i; }\n            }\n            \n            operations.push_back({boxToMove, bestDest + 1});\n            \n            int oldSize = stacks[si].size();\n            for (int j = pi + 1; j < oldSize; j++) {\n                int v = stacks[si][j];\n                stacks[bestDest].push_back(v);\n                pos[v] = bestDest;\n                idx[v] = stacks[bestDest].size() - 1;\n            }\n            stacks[si].resize(pi + 1);\n        }\n    }\n    \n    for (auto& op : operations) cout << op.first << \" \" << op.second << \"\\n\";\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\nint di[] = {0, 1, 0, -1};\nint dj[] = {1, 0, -1, 0};\nchar dc[] = \"RDLU\";\nvector<vector<pair<int,int>>> parent;\nvector<vector<int>> pd;\n\nbool can_move(int i, int j, int dir) {\n    int ni = i + di[dir], nj = j + dj[dir];\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    if (dir == 0) return v[i][j] == '0';\n    if (dir == 1) return h[i][j] == '0';\n    if (dir == 2) return v[i][nj] == '0';\n    return h[ni][j] == '0';\n}\n\nstring find_path(int si, int sj, int ti, int tj) {\n    if (si == ti && sj == tj) return \"\";\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) { parent[i][j] = {-1, -1}; pd[i][j] = -1; }\n    queue<pair<int,int>> q;\n    q.push({si, sj}); parent[si][sj] = {si, sj};\n    while (!q.empty()) {\n        auto [ci, cj] = q.front(); q.pop();\n        if (ci == ti && cj == tj) break;\n        for (int dir = 0; dir < 4; dir++) {\n            if (can_move(ci, cj, dir)) {\n                int ni = ci + di[dir], nj = cj + dj[dir];\n                if (parent[ni][nj].first == -1) {\n                    parent[ni][nj] = {ci, cj}; pd[ni][nj] = dir; q.push({ni, nj});\n                }\n            }\n        }\n    }\n    string path; int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        path += dc[(pd[ci][cj] + 2) % 4];\n        auto [pi, pj] = parent[ci][cj]; ci = pi; cj = pj;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N;\n    h.resize(N-1); v.resize(N);\n    for (int i = 0; i < N-1; i++) cin >> h[i];\n    for (int i = 0; i < N; i++) cin >> v[i];\n    d.resize(N, vector<int>(N));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cin >> d[i][j];\n    \n    parent.assign(N, vector<pair<int,int>>(N, {-1, -1}));\n    pd.assign(N, vector<int>(N, -1));\n    \n    vector<pair<int, pair<int,int>>> cells;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cells.push_back({d[i][j], {i, j}});\n    sort(cells.rbegin(), cells.rend());\n    \n    string route; int cur_i = 0, cur_j = 0;\n    const int MAX_LEN = 100000, RESERVE = N * N * 2;\n    \n    for (auto& [val, pos] : cells) {\n        auto [ti, tj] = pos;\n        route += find_path(cur_i, cur_j, ti, tj);\n        cur_i = ti; cur_j = tj;\n    }\n    \n    int top_k = max(1, (int)cells.size() / 5);\n    while (route.size() < MAX_LEN - RESERVE) {\n        for (int idx = 0; idx < top_k && route.size() < MAX_LEN - RESERVE; idx++) {\n            auto [ti, tj] = cells[idx].second;\n            string path = find_path(cur_i, cur_j, ti, tj);\n            if (route.size() + path.size() > MAX_LEN - RESERVE) break;\n            route += path; cur_i = ti; cur_j = tj;\n        }\n    }\n    route += find_path(cur_i, cur_j, 0, 0);\n    cout << route << endl;\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 16;\nconst int MAX_NODES = 1005;\nconst int INF = 1e9;\n\nint n, m;\nint si, sj;\nchar grid[MAXN][MAXN];\nstring words[205];\n\nint dist_to_char[26][MAXN][MAXN];\nint closest_x[26][MAXN][MAXN];\nint closest_y[26][MAXN][MAXN];\n\nint trie[MAX_NODES][26];\nint fail_link[MAX_NODES];\nvector<int> out[MAX_NODES];\nint node_cnt = 0;\n\nvoid insert(const string& s, int id) {\n    int cur = 0;\n    for (char c : s) {\n        int ch = c - 'A';\n        if (!trie[cur][ch]) trie[cur][ch] = ++node_cnt;\n        cur = trie[cur][ch];\n    }\n    out[cur].push_back(id);\n}\n\nvoid build_aho() {\n    queue<int> q;\n    for (int c = 0; c < 26; c++) {\n        if (trie[0][c]) q.push(trie[0][c]);\n    }\n    while (!q.empty()) {\n        int v = q.front(); q.pop();\n        for (int c = 0; c < 26; c++) {\n            if (trie[v][c]) {\n                fail_link[trie[v][c]] = trie[fail_link[v]][c];\n                for (int id : out[fail_link[trie[v][c]]]) {\n                    out[trie[v][c]].push_back(id);\n                }\n                q.push(trie[v][c]);\n            } else {\n                trie[v][c] = trie[fail_link[v]][c];\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> n >> m >> si >> sj;\n    \n    for (int i = 0; i < n; i++) {\n        string row; cin >> row;\n        for (int j = 0; j < n; j++) grid[i][j] = row[j];\n    }\n    \n    for (int i = 0; i < m; i++) {\n        cin >> words[i];\n        insert(words[i], i);\n    }\n    build_aho();\n    \n    for (int c = 0; c < 26; c++) {\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                dist_to_char[c][i][j] = INF;\n                for (int x = 0; x < n; x++) {\n                    for (int y = 0; y < n; y++) {\n                        if (grid[x][y] == c + 'A') {\n                            int d = abs(i - x) + abs(j - y);\n                            if (d < dist_to_char[c][i][j]) {\n                                dist_to_char[c][i][j] = d;\n                                closest_x[c][i][j] = x;\n                                closest_y[c][i][j] = y;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    int ci = si, cj = sj;\n    int state = 0;\n    vector<bool> covered(m, false);\n    int covered_cnt = 0;\n    vector<pair<int,int>> ops;\n    \n    while (covered_cnt < m && (int)ops.size() < 5000) {\n        int best_c = -1;\n        double best_score = -1e18;\n        bool has_immediate = false;\n        \n        for (int c = 0; c < 26; c++) {\n            if (dist_to_char[c][ci][cj] >= INF) continue;\n            int cost = dist_to_char[c][ci][cj] + 1;\n            int new_state = trie[state][c];\n            int new_words = 0;\n            for (int id : out[new_state]) if (!covered[id]) new_words++;\n            \n            double score;\n            if (new_words > 0) {\n                score = 1e6 + new_words * 100.0 - cost * 0.1;\n                has_immediate = true;\n            } else {\n                score = -cost;\n            }\n            if (score > best_score) { best_score = score; best_c = c; }\n        }\n        \n        if (best_c == -1) break;\n        \n        if (!has_immediate) {\n            int best_w = -1, best_cost = INF;\n            for (int w = 0; w < m; w++) {\n                if (covered[w]) continue;\n                int cost = 0, ti = ci, tj = cj;\n                for (char ch : words[w]) {\n                    int c = ch - 'A';\n                    if (dist_to_char[c][ti][tj] >= INF) { cost = INF; break; }\n                    cost += dist_to_char[c][ti][tj] + 1;\n                    ti = closest_x[c][ti][tj]; tj = closest_y[c][ti][tj];\n                }\n                if (cost < best_cost) { best_cost = cost; best_w = w; }\n            }\n            if (best_w != -1) best_c = words[best_w][0] - 'A';\n        }\n        \n        int ni = closest_x[best_c][ci][cj], nj = closest_y[best_c][ci][cj];\n        ops.push_back({ni, nj});\n        ci = ni; cj = nj;\n        state = trie[state][best_c];\n        for (int id : out[state]) if (!covered[id]) { covered[id] = true; covered_cnt++; }\n    }\n    \n    for (auto& [i, j] : ops) cout << i << \" \" << j << \"\\n\";\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M; double eps;\n    cin >> N >> M >> eps;\n    \n    vector<vector<pair<int,int>>> fields(M), norm_fields(M);\n    vector<int> field_w(M), field_h(M);\n    for (int k = 0; k < M; k++) {\n        int d; cin >> d;\n        fields[k].resize(d);\n        int mi = N, mj = N;\n        for (int i = 0; i < d; i++) {\n            cin >> fields[k][i].first >> fields[k][i].second;\n            mi = min(mi, fields[k][i].first);\n            mj = min(mj, fields[k][i].second);\n        }\n        for (int i = 0; i < d; i++) {\n            norm_fields[k].push_back({fields[k][i].first - mi, fields[k][i].second - mj});\n            field_w[k] = max(field_w[k], fields[k][i].first - mi);\n            field_h[k] = max(field_h[k], fields[k][i].second - mj);\n        }\n    }\n    \n    vector<vector<int>> known(N, vector<int>(N, -1));\n    vector<pair<int,int>> has_oil;\n    \n    auto drill = [&](int i, int j) -> int {\n        if (known[i][j] != -1) return known[i][j];\n        cout << \"q 1 \" << i << \" \" << j << \"\\n\" << flush;\n        int r; cin >> r;\n        known[i][j] = r;\n        if (r > 0) has_oil.push_back({i, j});\n        return r;\n    };\n    \n    auto divine = [&](vector<pair<int,int>> &sq) -> int {\n        if (sq.size() < 2) return -1;\n        cout << \"q \" << sq.size();\n        for (auto [i, j] : sq) cout << \" \" << i << \" \" << j;\n        cout << \"\\n\" << flush;\n        int r; cin >> r;\n        return r;\n    };\n    \n    bool use_divine = (eps <= 0.015);\n    int bs = use_divine ? 5 : N;\n    int nbi = (N + bs - 1) / bs, nbj = (N + bs - 1) / bs;\n    vector<vector<bool>> skip(nbi, vector<bool>(nbj, false));\n    \n    if (use_divine) {\n        for (int bi = 0; bi < nbi; bi++) for (int bj = 0; bj < nbj; bj++) {\n            vector<pair<int,int>> blk;\n            for (int i = bi*bs; i < min(N,(bi+1)*bs); i++)\n                for (int j = bj*bs; j < min(N,(bj+1)*bs); j++)\n                    blk.push_back({i, j});\n            if (blk.size() < 2) continue;\n            if (divine(blk) == 0) skip[bi][bj] = true;\n        }\n    }\n    \n    for (int bi = 0; bi < nbi; bi++) for (int bj = 0; bj < nbj; bj++) {\n        if (skip[bi][bj]) continue;\n        for (int i = bi*bs; i < min(N,(bi+1)*bs); i++)\n            for (int j = bj*bs; j < min(N,(bj+1)*bs); j++)\n                drill(i, j);\n    }\n    \n    if (use_divine && !has_oil.empty()) {\n        set<pair<int,int>> todo;\n        for (auto [oi, oj] : has_oil) for (int k = 0; k < M; k++)\n            for (auto [si, sj] : norm_fields[k]) {\n                int di = oi - si, dj = oj - sj;\n                if (di < 0 || dj < 0 || di + field_w[k] >= N || dj + field_h[k] >= N) continue;\n                bool ok = true;\n                for (auto [fi, fj] : norm_fields[k])\n                    if (known[di+fi][dj+fj] == 0) { ok = false; break; }\n                if (!ok) continue;\n                for (auto [fi, fj] : norm_fields[k])\n                    if (known[di+fi][dj+fj] == -1) todo.insert({di+fi, dj+fj});\n            }\n        for (auto [i, j] : todo) drill(i, j);\n    }\n    \n    cout << \"a \" << has_oil.size();\n    for (auto [i, j] : has_oil) cout << \" \" << i << \" \" << j;\n    cout << \"\\n\" << flush;\n    int resp; cin >> resp;\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W, D, N;\n    cin >> W >> D >> N;\n    \n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) cin >> a[d][k];\n    }\n    \n    if (N == 1) {\n        for (int d = 0; d < D; d++) cout << \"0 0 \" << W << \" \" << W << \"\\n\";\n        return 0;\n    }\n    \n    auto get_sorted_req = [&](int d) {\n        vector<int> req(N);\n        for (int k = 0; k < N; k++) req[k] = (a[d][k] + W - 1) / W;\n        sort(req.begin(), req.end());\n        return req;\n    };\n    \n    auto compute_parts = [&](const vector<int>& req) {\n        vector<int> parts(N-1);\n        long long cum = 0;\n        for (int k = 0; k < N-1; k++) {\n            cum += req[k];\n            parts[k] = (int)min(cum, (long long)(W - (N - 1 - k)));\n        }\n        for (int k = 1; k < N-1; k++)\n            if (parts[k] <= parts[k-1]) parts[k] = parts[k-1] + 1;\n        return parts;\n    };\n    \n    auto compute_deficit = [&](const vector<int>& parts, const vector<int>& req) {\n        vector<int> h(N);\n        h[0] = parts[0];\n        for (int k = 1; k < N-1; k++) h[k] = parts[k] - parts[k-1];\n        h[N-1] = W - parts[N-2];\n        long long def = 0;\n        for (int k = 0; k < N; k++) def += max(0, req[k] - h[k]);\n        return def;\n    };\n    \n    auto change_cost = [&](const vector<int>& p1, const vector<int>& p2) {\n        set<int> s1(p1.begin(), p1.end()), s2(p2.begin(), p2.end());\n        vector<int> diff;\n        set_symmetric_difference(s1.begin(), s1.end(), s2.begin(), s2.end(), back_inserter(diff));\n        return (long long)diff.size() * W;\n    };\n    \n    auto output = [&](const vector<int>& parts) {\n        for (int k = 0; k < N; k++) {\n            int s = k == 0 ? 0 : parts[k-1];\n            int e = k < N-1 ? parts[k] : W;\n            cout << s << \" 0 \" << e << \" \" << W << \"\\n\";\n        }\n    };\n    \n    vector<int> parts = compute_parts(get_sorted_req(0));\n    output(parts);\n    \n    for (int d = 1; d < D; d++) {\n        auto req = get_sorted_req(d);\n        long long cost_keep = compute_deficit(parts, req) * 100;\n        auto new_parts = compute_parts(req);\n        long long cost_change = change_cost(parts, new_parts) + compute_deficit(new_parts, req) * 100;\n        if (cost_change < cost_keep) parts = new_parts;\n        output(parts);\n    }\n    \n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <algorithm>\n\nusing namespace std;\n\nconst int P = 998244353;\nint N, M, K;\nvector<vector<int>> T_mod;\nvector<vector<vector<int>>> S;\nvector<long long> sum_S;\n\nlong long best_gain_at_pos[7][7];\nint best_m_at_pos[7][7];\n\nvoid update_pos(int p, int q) {\n    long long best_g = -1;\n    int best_m = 0;\n    int t00 = T_mod[p][q], t01 = T_mod[p][q+1], t02 = T_mod[p][q+2];\n    int t10 = T_mod[p+1][q], t11 = T_mod[p+1][q+1], t12 = T_mod[p+1][q+2];\n    int t20 = T_mod[p+2][q], t21 = T_mod[p+2][q+1], t22 = T_mod[p+2][q+2];\n    \n    for (int m = 0; m < M; ++m) {\n        int overflow = 0;\n        if (S[m][0][0] && t00 + S[m][0][0] >= P) overflow++;\n        if (S[m][0][1] && t01 + S[m][0][1] >= P) overflow++;\n        if (S[m][0][2] && t02 + S[m][0][2] >= P) overflow++;\n        if (S[m][1][0] && t10 + S[m][1][0] >= P) overflow++;\n        if (S[m][1][1] && t11 + S[m][1][1] >= P) overflow++;\n        if (S[m][1][2] && t12 + S[m][1][2] >= P) overflow++;\n        if (S[m][2][0] && t20 + S[m][2][0] >= P) overflow++;\n        if (S[m][2][1] && t21 + S[m][2][1] >= P) overflow++;\n        if (S[m][2][2] && t22 + S[m][2][2] >= P) overflow++;\n        \n        long long gain = sum_S[m] - (long long)P * overflow;\n        if (gain > best_g) {\n            best_g = gain;\n            best_m = m;\n        }\n    }\n    best_gain_at_pos[p][q] = best_g;\n    best_m_at_pos[p][q] = best_m;\n}\n\nvoid update_affected(int p_old, int q_old) {\n    for (int p = max(0, p_old - 2); p <= min(6, p_old + 2); ++p) {\n        for (int q = max(0, q_old - 2); q <= min(6, q_old + 2); ++q) {\n            update_pos(p, q);\n        }\n    }\n}\n\nvoid update_all() {\n    for (int p = 0; p <= 6; ++p)\n        for (int q = 0; q <= 6; ++q)\n            update_pos(p, q);\n}\n\nvoid apply_stamp(int m, int p, int q) {\n    if (S[m][0][0]) { int s = T_mod[p][q] + S[m][0][0]; T_mod[p][q] = s >= P ? s - P : s; }\n    if (S[m][0][1]) { int s = T_mod[p][q+1] + S[m][0][1]; T_mod[p][q+1] = s >= P ? s - P : s; }\n    if (S[m][0][2]) { int s = T_mod[p][q+2] + S[m][0][2]; T_mod[p][q+2] = s >= P ? s - P : s; }\n    if (S[m][1][0]) { int s = T_mod[p+1][q] + S[m][1][0]; T_mod[p+1][q] = s >= P ? s - P : s; }\n    if (S[m][1][1]) { int s = T_mod[p+1][q+1] + S[m][1][1]; T_mod[p+1][q+1] = s >= P ? s - P : s; }\n    if (S[m][1][2]) { int s = T_mod[p+1][q+2] + S[m][1][2]; T_mod[p+1][q+2] = s >= P ? s - P : s; }\n    if (S[m][2][0]) { int s = T_mod[p+2][q] + S[m][2][0]; T_mod[p+2][q] = s >= P ? s - P : s; }\n    if (S[m][2][1]) { int s = T_mod[p+2][q+1] + S[m][2][1]; T_mod[p+2][q+1] = s >= P ? s - P : s; }\n    if (S[m][2][2]) { int s = T_mod[p+2][q+2] + S[m][2][2]; T_mod[p+2][q+2] = s >= P ? s - P : s; }\n}\n\nvoid remove_stamp(int m, int p, int q) {\n    if (S[m][0][0]) { int t = T_mod[p][q]; T_mod[p][q] = t >= S[m][0][0] ? t - S[m][0][0] : t + P - S[m][0][0]; }\n    if (S[m][0][1]) { int t = T_mod[p][q+1]; T_mod[p][q+1] = t >= S[m][0][1] ? t - S[m][0][1] : t + P - S[m][0][1]; }\n    if (S[m][0][2]) { int t = T_mod[p][q+2]; T_mod[p][q+2] = t >= S[m][0][2] ? t - S[m][0][2] : t + P - S[m][0][2]; }\n    if (S[m][1][0]) { int t = T_mod[p+1][q]; T_mod[p+1][q] = t >= S[m][1][0] ? t - S[m][1][0] : t + P - S[m][1][0]; }\n    if (S[m][1][1]) { int t = T_mod[p+1][q+1]; T_mod[p+1][q+1] = t >= S[m][1][1] ? t - S[m][1][1] : t + P - S[m][1][1]; }\n    if (S[m][1][2]) { int t = T_mod[p+1][q+2]; T_mod[p+1][q+2] = t >= S[m][1][2] ? t - S[m][1][2] : t + P - S[m][1][2]; }\n    if (S[m][2][0]) { int t = T_mod[p+2][q]; T_mod[p+2][q] = t >= S[m][2][0] ? t - S[m][2][0] : t + P - S[m][2][0]; }\n    if (S[m][2][1]) { int t = T_mod[p+2][q+1]; T_mod[p+2][q+1] = t >= S[m][2][1] ? t - S[m][2][1] : t + P - S[m][2][1]; }\n    if (S[m][2][2]) { int t = T_mod[p+2][q+2]; T_mod[p+2][q+2] = t >= S[m][2][2] ? t - S[m][2][2] : t + P - S[m][2][2]; }\n}\n\nlong long compute_gain(int m, int p, int q) {\n    int overflow = 0;\n    if (S[m][0][0] && T_mod[p][q] + S[m][0][0] >= P) overflow++;\n    if (S[m][0][1] && T_mod[p][q+1] + S[m][0][1] >= P) overflow++;\n    if (S[m][0][2] && T_mod[p][q+2] + S[m][0][2] >= P) overflow++;\n    if (S[m][1][0] && T_mod[p+1][q] + S[m][1][0] >= P) overflow++;\n    if (S[m][1][1] && T_mod[p+1][q+1] + S[m][1][1] >= P) overflow++;\n    if (S[m][1][2] && T_mod[p+1][q+2] + S[m][1][2] >= P) overflow++;\n    if (S[m][2][0] && T_mod[p+2][q] + S[m][2][0] >= P) overflow++;\n    if (S[m][2][1] && T_mod[p+2][q+1] + S[m][2][1] >= P) overflow++;\n    if (S[m][2][2] && T_mod[p+2][q+2] + S[m][2][2] >= P) overflow++;\n    return sum_S[m] - (long long)P * overflow;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> N >> M >> K)) return 0;\n\n    T_mod.assign(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> T_mod[i][j];\n\n    S.assign(M, vector<vector<int>>(3, vector<int>(3)));\n    sum_S.assign(M, 0);\n    for (int m = 0; m < M; ++m) {\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                cin >> S[m][i][j];\n                sum_S[m] += S[m][i][j];\n            }\n        }\n    }\n\n    vector<tuple<int, int, int>> ops;\n    \n    // Greedy Phase\n    update_all();\n    for (int step = 0; step < K; ++step) {\n        long long best_gain = 0;\n        int best_p = -1, best_q = -1;\n        for (int p = 0; p <= 6; ++p) {\n            for (int q = 0; q <= 6; ++q) {\n                if (best_gain_at_pos[p][q] > best_gain) {\n                    best_gain = best_gain_at_pos[p][q];\n                    best_p = p; best_q = q;\n                }\n            }\n        }\n        if (best_gain <= 0) break;\n        \n        int best_m = best_m_at_pos[best_p][best_q];\n        ops.emplace_back(best_m, best_p, best_q);\n        apply_stamp(best_m, best_p, best_q);\n        update_affected(best_p, best_q);\n    }\n\n    // Local Search Phase\n    bool improved = true;\n    int max_ls_iters = 50;\n    while (improved && max_ls_iters-- > 0) {\n        improved = false;\n        update_all(); \n        \n        long long best_improvement = 0;\n        int best_idx = -1;\n        int ls_best_m = -1, ls_best_p = -1, ls_best_q = -1;\n        bool ls_is_removal = false;\n\n        for (int idx = 0; idx < ops.size(); ++idx) {\n            auto& [m_old, p_old, q_old] = ops[idx];\n            \n            remove_stamp(m_old, p_old, q_old);\n            update_affected(p_old, q_old);\n            \n            long long max_gain_new = 0;\n            int b_m = -1, b_p = -1, b_q = -1;\n            for (int p = 0; p <= 6; ++p) {\n                for (int q = 0; q <= 6; ++q) {\n                    if (best_gain_at_pos[p][q] > max_gain_new) {\n                        max_gain_new = best_gain_at_pos[p][q];\n                        b_m = best_m_at_pos[p][q];\n                        b_p = p; b_q = q;\n                    }\n                }\n            }\n            \n            long long gain_A = compute_gain(m_old, p_old, q_old);\n            long long max_gain_eff = std::max(0LL, max_gain_new);\n            long long improvement = max_gain_eff - gain_A;\n            \n            apply_stamp(m_old, p_old, q_old);\n            \n            if (improvement > best_improvement) {\n                best_improvement = improvement;\n                best_idx = idx;\n                ls_is_removal = (max_gain_new <= 0);\n                ls_best_m = b_m; ls_best_p = b_p; ls_best_q = b_q;\n                if (best_improvement > 0) improved = true;\n            }\n        }\n        \n        // Try adding\n        if (ops.size() < K) {\n            long long max_gain_new = 0;\n            int b_m = -1, b_p = -1, b_q = -1;\n            for (int p = 0; p <= 6; ++p) {\n                for (int q = 0; q <= 6; ++q) {\n                    if (best_gain_at_pos[p][q] > max_gain_new) {\n                        max_gain_new = best_gain_at_pos[p][q];\n                        b_m = best_m_at_pos[p][q];\n                        b_p = p; b_q = q;\n                    }\n                }\n            }\n            if (max_gain_new > best_improvement) {\n                best_improvement = max_gain_new;\n                best_idx = -1; \n                ls_is_removal = false;\n                ls_best_m = b_m; ls_best_p = b_p; ls_best_q = b_q;\n                improved = true;\n            }\n        }\n        \n        if (best_improvement > 0) {\n            if (best_idx != -1) {\n                auto& [m_old, p_old, q_old] = ops[best_idx];\n                remove_stamp(m_old, p_old, q_old);\n                update_affected(p_old, q_old);\n                \n                if (!ls_is_removal) {\n                    ops[best_idx] = {ls_best_m, ls_best_p, ls_best_q};\n                    apply_stamp(ls_best_m, ls_best_p, ls_best_q);\n                    update_affected(ls_best_p, ls_best_q);\n                } else {\n                    ops.erase(ops.begin() + best_idx);\n                }\n            } else {\n                ops.emplace_back(ls_best_m, ls_best_p, ls_best_q);\n                apply_stamp(ls_best_m, ls_best_p, ls_best_q);\n                update_affected(ls_best_p, ls_best_q);\n            }\n        }\n    }\n\n    cout << ops.size() << \"\\n\";\n    for (auto& [m, p, q] : ops) {\n        cout << m << \" \" << p << \" \" << q << \"\\n\";\n    }\n\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 5;\nint A[N][N], cont_row[25], cont_order[25];\nint grid[N][N], crx, cry, cr_held, recv_idx[N], next_dispatch[N];\nbool cr_carry, dispatched[25];\nstring cmds[N];\n\npair<int,int> find_cont(int id) {\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++)\n        if (grid[i][j] == id) return {i, j};\n    return {-1, -1};\n}\n\nint find_empty(int r, int mode) {\n    for (int j = 1; j < N-1; j++) if (grid[r][j] == -1) return j;\n    if (mode >= 1 && recv_idx[r] >= N && grid[r][0] == -1) return 0;\n    if (mode >= 2 && grid[r][N-1] == -1) return N-1;\n    return -1;\n}\n\nvoid move_to(int tx, int ty, char& a) {\n    if (crx < tx) a = 'D'; else if (crx > tx) a = 'U';\n    else if (cry < ty) a = 'R'; else if (cry > ty) a = 'L'; else a = '.';\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        cin >> A[i][j]; cont_row[A[i][j]] = A[i][j] / N; cont_order[A[i][j]] = A[i][j] % N;\n    }\n    memset(grid, -1, sizeof(grid)); crx = cry = 0; cr_carry = false; cr_held = -1;\n    memset(recv_idx, 0, sizeof(recv_idx)); memset(dispatched, false, sizeof(dispatched));\n    memset(next_dispatch, 0, sizeof(next_dispatch));\n    int target = -1;\n    for (int turn = 0; turn < 10000; turn++) {\n        for (int i = 0; i < N; i++) if (recv_idx[i] < N && grid[i][0] == -1 && !(crx == i && cry == 0 && cr_carry))\n            grid[i][0] = A[i][recv_idx[i]++];\n        char act[N]; fill(act, act + N, '.');\n        if (turn == 0) { for (int i = 1; i < N; i++) act[i] = 'R'; act[0] = 'D'; }\n        else if (turn == 1) { for (int i = 1; i < N; i++) act[i] = 'B'; }\n        else {\n            bool all_recv = true; for (int i = 0; i < N; i++) if (recv_idx[i] < N) all_recv = false;\n            if (!cr_carry) {\n                if (!all_recv) {\n                    int bx = -1, by = -1, bd = 1000;\n                    for (int i = 0; i < N; i++) if (grid[i][0] != -1) { int d = abs(i-crx)+abs(cry); if (d < bd) { bd = d; bx = i; by = 0; } }\n                    if (bx < 0) for (int i = 0; i < N; i++) for (int j = 1; j < N-1; j++) if (grid[i][j] != -1) { int d = abs(i-crx)+abs(j-cry); if (d < bd) { bd = d; bx = i; by = j; } }\n                    if (bx >= 0) { if (crx == bx && cry == by) { act[0] = 'P'; target = grid[bx][by]; } else move_to(bx, by, act[0]); }\n                } else {\n                    int best_cid = -1, best_d = 1000;\n                    for (int r = 0; r < N; r++) while (next_dispatch[r] < N) {\n                        int cid = r * N + next_dispatch[r]; auto [cx, cy] = find_cont(cid);\n                        if (cx >= 0) { int d = abs(cx-crx)+abs(cy-cry); if (d < best_d) { best_d = d; best_cid = cid; } break; } else next_dispatch[r]++;\n                    }\n                    if (best_cid >= 0) { auto [cx, cy] = find_cont(best_cid); if (crx == cx && cry == cy) { act[0] = 'P'; target = best_cid; } else move_to(cx, cy, act[0]); }\n                }\n            } else {\n                int tr = cont_row[target];\n                if (!all_recv) { int ty = find_empty(tr, 0); if (ty < 0) ty = find_empty(tr, 1); if (ty < 0) ty = find_empty(tr, 2); if (ty >= 0) { if (crx == tr && cry == ty) act[0] = 'Q'; else move_to(tr, ty, act[0]); } }\n                else { if (crx == tr && cry == N-1) act[0] = 'Q'; else move_to(tr, N-1, act[0]); }\n            }\n        }\n        for (int i = 0; i < N; i++) cmds[i] += act[i];\n        if (act[0] == 'P') { cr_held = grid[crx][cry]; grid[crx][cry] = -1; cr_carry = true; }\n        else if (act[0] == 'Q') { grid[crx][cry] = cr_held; cr_held = -1; cr_carry = false; }\n        else if (act[0] == 'U') crx--; else if (act[0] == 'D') crx++; else if (act[0] == 'L') cry--; else if (act[0] == 'R') cry++;\n        for (int i = 0; i < N; i++) if (grid[i][N-1] != -1) { int c = grid[i][N-1]; dispatched[c] = true; grid[i][N-1] = -1; if (i == cont_row[c] && cont_order[c] == next_dispatch[i]) next_dispatch[i]++; }\n        bool done = true; for (int i = 0; i < 25; i++) if (!dispatched[i]) { done = false; break; } if (done) break;\n    }\n    for (int i = 0; i < N; i++) cout << cmds[i] << endl;\n    return 0;\n}","ahc034":"#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;\n    cin >> N;\n    vector<vector<int>> h(N, vector<int>(N));\n    set<pair<int, int>> unvisited;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            cin >> h[i][j];\n            if (h[i][j] != 0) unvisited.insert({i, j});\n        }\n    \n    vector<string> ops;\n    int load = 0;\n    int ci = 0, cj = 0;\n    \n    auto move_to = [&](int ti, int tj) {\n        while (ci < ti) { ops.push_back(\"D\"); ci++; }\n        while (ci > ti) { ops.push_back(\"U\"); ci--; }\n        while (cj < tj) { ops.push_back(\"R\"); cj++; }\n        while (cj > tj) { ops.push_back(\"L\"); cj--; }\n    };\n    \n    while (!unvisited.empty()) {\n        int best_i = -1, best_j = -1;\n        double best_score = 1e18;\n        \n        int radius = 12;\n        for (int ni = max(0, ci - radius); ni <= min(N-1, ci + radius); ni++) {\n            for (int nj = max(0, cj - radius); nj <= min(N-1, cj + radius); nj++) {\n                if (unvisited.find({ni, nj}) == unvisited.end()) continue;\n                \n                int dist = abs(ci - ni) + abs(cj - nj);\n                double s = dist * 100.0 + load * dist;\n                if (load > 50 && h[ni][nj] < 0) {\n                    s -= min((long long)load, (long long)-h[ni][nj]) * 8.0;\n                }\n                if (load < -50 && h[ni][nj] > 0) {\n                    s -= min((long long)-load, (long long)h[ni][nj]) * 8.0;\n                }\n                if (s < best_score) {\n                    best_score = s;\n                    best_i = ni;\n                    best_j = nj;\n                }\n            }\n        }\n        \n        if (best_i == -1) {\n            for (auto [ni, nj] : unvisited) {\n                int dist = abs(ci - ni) + abs(cj - nj);\n                double s = dist * 100.0 + load * dist;\n                if (s < best_score) {\n                    best_score = s;\n                    best_i = ni;\n                    best_j = nj;\n                }\n            }\n        }\n        \n        move_to(best_i, best_j);\n        \n        if (h[best_i][best_j] > 0) {\n            ops.push_back(\"+\" + to_string(h[best_i][best_j]));\n            load += h[best_i][best_j];\n        } else {\n            ops.push_back(\"-\" + to_string(-h[best_i][best_j]));\n            load -= h[best_i][best_j];\n        }\n        \n        unvisited.erase({best_i, best_j});\n    }\n    \n    cout << ops.size() << \"\\n\";\n    for (const auto& op : ops) cout << op << \"\\n\";\n    \n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <random>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, T;\n    cin >> N >> M >> T;\n\n    const int seed_count = 2 * N * (N - 1);\n    const int grid_size = N * N;\n    vector<vector<int>> X(seed_count, vector<int>(M, 0));\n    vector<int> V(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    const int dr[] = {-1, 1, 0, 0};\n    const int dc[] = {0, 0, -1, 1};\n    vector<vector<int>> nbrs(grid_size);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int pos = i * N + j;\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dr[d], nj = j + dc[d];\n                if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                    nbrs[pos].push_back(ni * N + nj);\n                }\n            }\n        }\n    }\n\n    mt19937 rng(42);\n\n    for (int t = 0; t < T; t++) {\n        vector<int> sortedSeeds(seed_count);\n        iota(sortedSeeds.begin(), sortedSeeds.end(), 0);\n        sort(sortedSeeds.begin(), sortedSeeds.end(), [&](int a, int b) {\n            return V[a] > V[b];\n        });\n        \n        vector<int> perm(grid_size);\n        for (int i = 0; i < grid_size; i++) perm[i] = sortedSeeds[i];\n        \n        vector<vector<int>> es(grid_size, vector<int>(grid_size, 0));\n        for (int i = 0; i < grid_size; i++) {\n            for (int j = i + 1; j < grid_size; j++) {\n                int s = 0;\n                for (int l = 0; l < M; l++) s += max(X[perm[i]][l], X[perm[j]][l]);\n                es[i][j] = es[j][i] = s;\n            }\n        }\n        \n        double temp = 500.0;\n        double cooling = 0.99985;\n        uniform_real_distribution<double> dist(0.0, 1.0);\n        \n        for (int iter = 0; iter < 200000; iter++) {\n            int p1 = rng() % grid_size;\n            int p2 = rng() % grid_size;\n            if (p1 == p2) continue;\n            \n            int delta = 0;\n            for (int nb : nbrs[p1]) {\n                if (nb != p2) delta += es[p2][nb] - es[p1][nb];\n            }\n            for (int nb : nbrs[p2]) {\n                if (nb != p1) delta += es[p1][nb] - es[p2][nb];\n            }\n            \n            double acceptProb = delta >= 0 ? 1.0 : exp(delta / temp);\n            if (dist(rng) < acceptProb) {\n                swap(perm[p1], perm[p2]);\n                swap(es[p1], es[p2]);\n                for (int k = 0; k < grid_size; k++) {\n                    swap(es[k][p1], es[k][p2]);\n                }\n            }\n            \n            temp *= cooling;\n        }\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << perm[i * N + j];\n                if (j < N - 1) cout << \" \";\n                else cout << \"\\n\";\n            }\n        }\n        cout.flush();\n\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    }\n\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint dx[] = {0, 1, 0, -1};\nint dy[] = {1, 0, -1, 0};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, V;\n    cin >> N >> M >> V;\n    \n    vector<string> s(N), t(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    cout << V << \"\\n\";\n    for (int i = 1; i < V; i++) cout << 0 << \" \" << 1 << \"\\n\";\n    \n    int rx = 0, ry = 0;\n    cout << rx << \" \" << ry << \"\\n\";\n    \n    vector<int> dir(V, 0);\n    for (int i = 1; i < V; i++) dir[i] = (i - 1) % 4;\n    \n    vector<bool> holding(V, false);\n    \n    set<pair<int,int>> sources, dests;\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') sources.insert({i, j});\n            if (s[i][j] == '0' && t[i][j] == '1') dests.insert({i, j});\n        }\n    \n    auto inGrid = [&](int x, int y) { return 0 <= x && x < N && 0 <= y && y < N; };\n    \n    string S1(V * 2, '.');\n    for (int i = 1; i < V; i++) {\n        if (dir[i] == 1) S1[i] = 'R';\n        else if (dir[i] == 3) S1[i] = 'L';\n    }\n    if (S1.find_first_not_of('.') != string::npos) cout << S1 << \"\\n\";\n    \n    string S2(V * 2, '.');\n    for (int i = 1; i < V; i++) if (dir[i] == 2) S2[i] = 'R';\n    if (S2.find_first_not_of('.') != string::npos) cout << S2 << \"\\n\";\n    \n    auto fpos = [&](int i) { return make_pair(rx + dx[dir[i]], ry + dy[dir[i]]); };\n    \n    for (int turn = 0; turn < 100000 && (!sources.empty() || !dests.empty()); turn++) {\n        string S(V * 2, '.');\n        int minDist = INT_MAX;\n        pair<int,int> target = {-1, -1};\n        \n        for (auto [x, y] : sources)\n            for (int d = 0; d < 4; d++) {\n                int nx = x - dx[d], ny = y - dy[d];\n                if (inGrid(nx, ny)) {\n                    int dist = abs(nx - rx) + abs(ny - ry);\n                    if (dist < minDist) { minDist = dist; target = {nx, ny}; }\n                }\n            }\n        \n        for (auto [x, y] : dests)\n            for (int d = 0; d < 4; d++) {\n                int nx = x - dx[d], ny = y - dy[d];\n                if (inGrid(nx, ny)) {\n                    int dist = abs(nx - rx) + abs(ny - ry);\n                    if (dist < minDist) { minDist = dist; target = {nx, ny}; }\n                }\n            }\n        \n        if (target.first == -1) break;\n        \n        int tx = target.first, ty = target.second;\n        if (rx < tx) { S[0] = 'D'; rx++; }\n        else if (rx > tx) { S[0] = 'U'; rx--; }\n        else if (ry < ty) { S[0] = 'R'; ry++; }\n        else if (ry > ty) { S[0] = 'L'; ry--; }\n        \n        for (int i = 1; i < V; i++) {\n            auto [fx, fy] = fpos(i);\n            if (!inGrid(fx, fy)) continue;\n            if (holding[i] && dests.count({fx, fy})) {\n                S[V + i] = 'P'; s[fx][fy] = '1'; holding[i] = false; dests.erase({fx, fy});\n            } else if (!holding[i] && sources.count({fx, fy})) {\n                S[V + i] = 'P'; s[fx][fy] = '0'; holding[i] = true; sources.erase({fx, fy});\n            }\n        }\n        cout << S << \"\\n\";\n    }\n    return 0;\n}","ahc039":"#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;\n    cin >> N;\n    \n    vector<int> mx(N), my(N), sx(N), sy(N);\n    for (int i = 0; i < N; i++) cin >> mx[i] >> my[i];\n    for (int i = 0; i < N; i++) cin >> sx[i] >> sy[i];\n    \n    const int GRID = 100, CELL = 1001;\n    auto cell = [](int x) { return min(x / CELL, GRID - 1); };\n    \n    vector<vector<int>> grid(GRID, vector<int>(GRID, 0));\n    for (int i = 0; i < N; i++) grid[cell(mx[i])][cell(my[i])]++;\n    for (int i = 0; i < N; i++) grid[cell(sx[i])][cell(sy[i])]--;\n    \n    int best = 0, bx1 = 0, bx2 = 0, by1 = 0, by2 = 0;\n    for (int x1 = 0; x1 < GRID; x1++) {\n        vector<int> col(GRID, 0);\n        for (int x2 = x1; x2 < GRID; x2++) {\n            for (int y = 0; y < GRID; y++) col[y] += grid[x2][y];\n            int cur = 0, start = 0;\n            for (int y = 0; y < GRID; y++) {\n                if (cur <= 0) { cur = col[y]; start = y; }\n                else cur += col[y];\n                if (cur > best) { best = cur; bx1 = x1; bx2 = x2; by1 = start; by2 = y; }\n            }\n        }\n    }\n    \n    if (best <= 0) { cout << \"4\\n0 0\\n1000 0\\n1000 1000\\n0 1000\\n\"; return 0; }\n    \n    int cx1 = bx1 * CELL, cy1 = by1 * CELL;\n    int cx2 = min((bx2 + 1) * CELL, 100000), cy2 = min((by2 + 1) * CELL, 100000);\n    \n    set<int> x_set, y_set;\n    for (int i = 0; i < 2*N; i++) {\n        int x = (i < N) ? mx[i] : sx[i], y = (i < N) ? my[i] : sy[i];\n        if (x >= cx1 && x <= cx2) { x_set.insert(max(0,x-1)); x_set.insert(x); x_set.insert(min(100000,x+1)); }\n        if (y >= cy1 && y <= cy2) { y_set.insert(max(0,y-1)); y_set.insert(y); y_set.insert(min(100000,y+1)); }\n    }\n    x_set.insert(cx1); x_set.insert(cx2); y_set.insert(cy1); y_set.insert(cy2);\n    \n    vector<int> all_x(x_set.begin(), x_set.end()), all_y(y_set.begin(), y_set.end());\n    int nx = all_x.size(), ny = all_y.size();\n    \n    const int MAX_SZ = 250;\n    if (nx > MAX_SZ) { vector<int> t; for (int i = 0; i < nx; i += (nx+MAX_SZ-1)/MAX_SZ) t.push_back(all_x[i]); t.push_back(all_x.back()); all_x = t; nx = all_x.size(); }\n    if (ny > MAX_SZ) { vector<int> t; for (int i = 0; i < ny; i += (ny+MAX_SZ-1)/MAX_SZ) t.push_back(all_y[i]); t.push_back(all_y.back()); all_y = t; ny = all_y.size(); }\n    \n    vector<vector<int>> fg(nx, vector<int>(ny, 0));\n    for (int i = 0; i < N; i++) { int xi = lower_bound(all_x.begin(),all_x.end(),mx[i])-all_x.begin(), yi = lower_bound(all_y.begin(),all_y.end(),my[i])-all_y.begin(); if (xi<nx && yi<ny && all_x[xi]==mx[i] && all_y[yi]==my[i]) fg[xi][yi]++; }\n    for (int i = 0; i < N; i++) { int xi = lower_bound(all_x.begin(),all_x.end(),sx[i])-all_x.begin(), yi = lower_bound(all_y.begin(),all_y.end(),sy[i])-all_y.begin(); if (xi<nx && yi<ny && all_x[xi]==sx[i] && all_y[yi]==sy[i]) fg[xi][yi]--; }\n    \n    int fb = 0, fx1 = 0, fx2 = 0, fy1 = 0, fy2 = 0;\n    for (int x1 = 0; x1 < nx; x1++) {\n        vector<int> col(ny, 0);\n        for (int x2 = x1; x2 < nx; x2++) {\n            for (int y = 0; y < ny; y++) col[y] += fg[x2][y];\n            int cur = 0, start = 0;\n            for (int y = 0; y < ny; y++) { if (cur <= 0) { cur = col[y]; start = y; } else cur += col[y]; if (cur > fb) { fb = cur; fx1 = x1; fx2 = x2; fy1 = start; fy2 = y; } }\n        }\n    }\n    \n    int ax1 = max(0, all_x[fx1]), ay1 = max(0, all_y[fy1]);\n    int ax2 = min(100000, all_x[fx2]), ay2 = min(100000, all_y[fy2]);\n    if (ax2 <= ax1) ax2 = ax1 + 1; if (ay2 <= ay1) ay2 = ay1 + 1;\n    \n    cout << 4 << \"\\n\" << ax1 << \" \" << ay1 << \"\\n\" << ax2 << \" \" << ay1 << \"\\n\" << ax2 << \" \" << ay2 << \"\\n\" << ax1 << \" \" << ay2 << \"\\n\";\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, T;\n    double sigma;\n    cin >> N >> T >> sigma;\n    \n    vector<double> w(N), h(N);\n    for (int i = 0; i < N; i++) {\n        int wo, ho;\n        cin >> wo >> ho;\n        w[i] = wo;\n        h[i] = ho;\n    }\n    \n    for (int t = 0; t < T; t++) {\n        vector<tuple<double,double,double,double,int>> placed;\n        \n        auto find_y = [&](double x, double ww) -> double {\n            double y = 0;\n            for (auto& [px,py,pw,ph,idx] : placed)\n                if (px < x+ww && x < px+pw) y = max(y, py+ph);\n            return y;\n        };\n        \n        auto find_x = [&](double y, double hh) -> double {\n            double x = 0;\n            for (auto& [px,py,pw,ph,idx] : placed)\n                if (py < y+hh && y < py+ph) x = max(x, px+pw);\n            return x;\n        };\n        \n        auto get_ref_x = [&](int idx) -> double {\n            for (auto& [px,py,pw,ph,i] : placed) if (i==idx) return px+pw;\n            return 0.0;\n        };\n        \n        auto get_ref_y = [&](int idx) -> double {\n            for (auto& [px,py,pw,ph,i] : placed) if (i==idx) return py+ph;\n            return 0.0;\n        };\n        \n        vector<tuple<int,int,char,int>> placement;\n        \n        for (int i = 0; i < N; i++) {\n            double best_score = 1e18;\n            int best_rot = 0; char best_d = 'U'; int best_b = -1;\n            \n            for (int rot = 0; rot < 2; rot++) {\n                double rw = rot ? h[i] : w[i], rh = rot ? w[i] : h[i];\n                \n                auto try_place = [&](double x, double y, char d, int b) {\n                    double W = x+rw, H = y+rh;\n                    for (auto& [px,py,pw,ph,idx] : placed) { W = max(W,px+pw); H = max(H,py+ph); }\n                    if (W+H < best_score) { best_score = W+H; best_rot = rot; best_d = d; best_b = b; }\n                };\n                \n                try_place(0, find_y(0,rw), 'U', -1);\n                for (auto& [px,py,pw,ph,idx] : placed)\n                    try_place(px+pw, find_y(px+pw,rw), 'U', idx);\n                try_place(find_x(0,rh), 0, 'L', -1);\n                for (auto& [px,py,pw,ph,idx] : placed)\n                    try_place(find_x(py+ph,rh), py+ph, 'L', idx);\n            }\n            \n            double cur_wh = 0;\n            for (auto& [px,py,pw,ph,idx] : placed) cur_wh = max({cur_wh, px+pw, py+ph});\n            if (cur_wh + w[i] + h[i] < best_score) continue;\n            \n            double rw = best_rot ? h[i] : w[i], rh = best_rot ? w[i] : h[i];\n            double x, y;\n            if (best_d == 'U') { x = best_b==-1 ? 0 : get_ref_x(best_b); y = find_y(x,rw); }\n            else { y = best_b==-1 ? 0 : get_ref_y(best_b); x = find_x(y,rh); }\n            placed.emplace_back(x, y, rw, rh, i);\n            placement.emplace_back(i, best_rot, best_d, best_b);\n        }\n        \n        cout << placement.size() << \"\\n\";\n        for (auto& [p,r,d,b] : placement) cout << p << \" \" << r << \" \" << d << \" \" << b << \"\\n\";\n        cout.flush();\n        \n        int W_meas, H_meas;\n        cin >> W_meas >> H_meas;\n        \n        double W_exp = 0, H_exp = 0;\n        for (auto& [px,py,pw,ph,idx] : placed) { W_exp = max(W_exp,px+pw); H_exp = max(H_exp,py+ph); }\n        \n        if (W_exp > 0 && H_exp > 0) {\n            double alpha = 0.05;\n            double wr = W_meas/W_exp, hr = H_meas/H_exp;\n            for (int i = 0; i < N; i++) { w[i] *= (1-alpha) + wr*alpha; h[i] *= (1-alpha) + hr*alpha; }\n        }\n    }\n    \n    return 0;\n}","ahc041":"#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, H;\n    cin >> N >> M >> H;\n    \n    vector<int> A(N);\n    for (int i = 0; i < N; i++) cin >> A[i];\n    \n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    \n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    \n    vector<bitset<1000>> cover(N);\n    for (int s = 0; s < N; s++) {\n        vector<int> dist(N, H + 1);\n        dist[s] = 0;\n        queue<int> q;\n        q.push(s);\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            cover[s].set(u);\n            if (dist[u] < H) {\n                for (int v : adj[u]) {\n                    if (dist[v] == H + 1) {\n                        dist[v] = dist[u] + 1;\n                        q.push(v);\n                    }\n                }\n            }\n        }\n    }\n    \n    bitset<1000> uncovered;\n    for (int i = 0; i < N; i++) uncovered.set(i);\n    \n    vector<bool> is_root(N, false);\n    \n    while (uncovered.any()) {\n        int best_v = -1;\n        double best_ratio = -1;\n        \n        for (int v = 0; v < N; v++) {\n            int count = (cover[v] & uncovered).count();\n            if (count == 0) continue;\n            \n            double ratio = (double)count / A[v];\n            if (ratio > best_ratio) {\n                best_ratio = ratio;\n                best_v = v;\n            }\n        }\n        \n        if (best_v == -1) break;\n        \n        is_root[best_v] = true;\n        uncovered &= ~cover[best_v];\n    }\n    \n    vector<int> roots;\n    for (int v = 0; v < N; v++) {\n        if (is_root[v]) roots.push_back(v);\n    }\n    \n    sort(roots.begin(), roots.end(), [&](int a, int b) { return A[a] > A[b]; });\n    \n    for (int r : roots) {\n        bitset<1000> other_cover;\n        for (int v = 0; v < N; v++) {\n            if (is_root[v] && v != r) {\n                other_cover |= cover[v];\n            }\n        }\n        \n        if ((cover[r] & ~other_cover).none()) {\n            is_root[r] = false;\n        }\n    }\n    \n    vector<int> parent(N, -1);\n    vector<int> height(N, -1);\n    queue<int> q;\n    \n    for (int v = 0; v < N; v++) {\n        if (is_root[v]) {\n            height[v] = 0;\n            q.push(v);\n        }\n    }\n    \n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : adj[u]) {\n            if (height[v] == -1 && height[u] < H) {\n                height[v] = height[u] + 1;\n                parent[v] = u;\n                q.push(v);\n            }\n        }\n    }\n    \n    for (int v = 0; v < N; v++) {\n        if (height[v] == -1) {\n            height[v] = 0;\n            q.push(v);\n            while (!q.empty()) {\n                int u = q.front(); q.pop();\n                for (int w : adj[u]) {\n                    if (height[w] == -1 && height[u] < H) {\n                        height[w] = height[u] + 1;\n                        parent[w] = u;\n                        q.push(w);\n                    }\n                }\n            }\n        }\n    }\n    \n    for (int v = 0; v < N; v++) {\n        cout << parent[v];\n        if (v < N - 1) cout << \" \";\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N; cin >> N;\n    vector<string> board(N);\n    for (int i = 0; i < N; i++) cin >> board[i];\n    \n    vector<int> fmin_r(N,N), fmax_r(N,-1), fmin_c(N,N), fmax_c(N,-1);\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (board[i][j]=='o') {\n        fmin_r[i]=min(fmin_r[i],j); fmax_r[i]=max(fmax_r[i],j);\n        fmin_c[j]=min(fmin_c[j],i); fmax_c[j]=max(fmax_c[j],i);\n    }\n    \n    struct Oni { int i,j; set<int> s; };\n    vector<Oni> O;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (board[i][j]=='x') {\n        Oni o{o.i=i,o.j=j};\n        if (fmin_c[j]>i||fmin_c[j]==N) o.s.insert(0);\n        if (fmax_c[j]<i||fmax_c[j]==-1) o.s.insert(1);\n        if (fmin_r[i]>j||fmin_r[i]==N) o.s.insert(2);\n        if (fmax_r[i]<j||fmax_r[i]==-1) o.s.insert(3);\n        O.push_back(o);\n    }\n    \n    map<int,vector<int>> byR, byC;\n    for (int k=0; k<O.size(); k++) { byR[O[k].i].push_back(k); byC[O[k].j].push_back(k); }\n    \n    vector<int> dir(O.size(),-1);\n    map<pair<int,int>,int> md;\n    auto asgn = [&](int k, int d) {\n        dir[k]=d;\n        int idx=(d<=1)?O[k].j:O[k].i;\n        int dist=(d==0)?O[k].i+1:(d==1)?N-O[k].i:(d==2)?O[k].j+1:N-O[k].j;\n        md[{idx,d}]=max(md[{idx,d}],dist);\n    };\n    \n    for (auto&[r,ks]:byR) {\n        vector<int> ol,or2,b;\n        for (int k:ks) { bool cl=O[k].s.count(2),cr=O[k].s.count(3); if(cl&&cr)b.push_back(k); else if(cl)ol.push_back(k); else if(cr)or2.push_back(k); }\n        for(int k:ol)asgn(k,2); for(int k:or2)asgn(k,3);\n        if(!b.empty()) { int ml=0,mr=0; for(int k:ol)ml=max(ml,O[k].j+1); for(int k:or2)mr=max(mr,N-O[k].j); for(int k:b){ml=max(ml,O[k].j+1);mr=max(mr,N-O[k].j);} int cl=2*ml+(or2.empty()?0:2*mr),cr2=(ol.empty()?0:2*ml)+2*mr; for(int k:b)asgn(k,cl<=cr2?2:3); }\n    }\n    for (auto&[c,ks]:byC) {\n        vector<int> un; for(int k:ks)if(dir[k]==-1)un.push_back(k); if(un.empty())continue;\n        vector<int> ou,od,b;\n        for(int k:un){bool cu=O[k].s.count(0),cd=O[k].s.count(1);if(cu&&cd)b.push_back(k);else if(cu)ou.push_back(k);else if(cd)od.push_back(k);}\n        for(int k:ou)asgn(k,0); for(int k:od)asgn(k,1);\n        if(!b.empty()){int mu=0,md2=0;for(int k:ou)mu=max(mu,O[k].i+1);for(int k:od)md2=max(md2,N-O[k].i);for(int k:b){mu=max(mu,O[k].i+1);md2=max(md2,N-O[k].i);}int cu=2*mu+(od.empty()?0:2*md2),cd=(ou.empty()?0:2*mu)+2*md2;for(int k:b)asgn(k,cu<=cd?0:1);}\n    }\n    for(int k=0;k<O.size();k++){if(dir[k]!=-1)continue;int best=-1,bd=N+1;for(int d:O[k].s){int dist=(d==0)?O[k].i+1:(d==1)?N-O[k].i:(d==2)?O[k].j+1:N-O[k].j;if(dist<bd){bd=dist;best=d;}}asgn(k,best);}\n    \n    for(auto&[key,dist]:md){auto[idx,d]=key;char c=\"UDLR\"[d],cr=\"DULR\"[d];for(int t=0;t<dist;t++)cout<<c<<\" \"<<idx<<\"\\n\";for(int t=0;t<dist;t++)cout<<cr<<\" \"<<idx<<\"\\n\";}\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, L;\n    cin >> N >> L;\n    \n    vector<int> T(N);\n    for (int i = 0; i < N; i++) {\n        cin >> T[i];\n    }\n    \n    vector<int> a(N, -1), b(N, -1);\n    vector<int> cnt(N, 0);\n    cnt[0] = 1;\n    \n    vector<int> remain = T;\n    remain[0]--;\n    \n    auto choose_next = [&](int current) -> int {\n        // First, try to find an unvisited employee with positive remain\n        for (int i = 0; i < N; i++) {\n            if (i != current && cnt[i] == 0 && remain[i] > 0) {\n                return i;\n            }\n        }\n        // Then, find the employee with highest remain (excluding current)\n        int best = -1;\n        int best_remain = -1;\n        for (int i = 0; i < N; i++) {\n            if (i == current) continue;\n            if (remain[i] > best_remain) {\n                best_remain = remain[i];\n                best = i;\n            }\n        }\n        if (best == -1) {\n            best = current;\n        }\n        return best;\n    };\n    \n    int current = 0;\n    for (int week = 2; week <= L; week++) {\n        int k = cnt[current];\n        \n        int next;\n        if (k % 2 == 1) {\n            if (a[current] == -1) {\n                a[current] = choose_next(current);\n            }\n            next = a[current];\n        } else {\n            if (b[current] == -1) {\n                b[current] = choose_next(current);\n            }\n            next = b[current];\n        }\n        \n        cnt[next]++;\n        remain[next]--;\n        current = next;\n    }\n    \n    for (int i = 0; i < N; i++) {\n        if (a[i] == -1) a[i] = 0;\n        if (b[i] == -1) b[i] = 0;\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, Q, L, W;\nvector<int> G, cx, cy;\n\nvector<pair<int,int>> doQuery(vector<int>& cities) {\n    cout << \"? \" << cities.size();\n    for (int c : cities) cout << \" \" << c;\n    cout << \"\\n\";\n    cout.flush();\n    vector<pair<int,int>> edges(cities.size() - 1);\n    for (int i = 0; i < (int)cities.size() - 1; i++)\n        cin >> edges[i].first >> edges[i].second;\n    return edges;\n}\n\nvoid findMST(vector<int>& cities, vector<pair<int,int>>& edges, int& queriesLeft) {\n    int n = cities.size();\n    if (n <= 1) return;\n    if (n == 2) {\n        edges.push_back({min(cities[0], cities[1]), max(cities[0], cities[1])});\n        return;\n    }\n    if (n <= L && queriesLeft > 0) {\n        auto result = doQuery(cities);\n        edges.insert(edges.end(), result.begin(), result.end());\n        queriesLeft--;\n        return;\n    }\n    if (queriesLeft <= 0) {\n        for (int i = 0; i < n - 1; i++)\n            edges.push_back({min(cities[i], cities[i+1]), max(cities[i], cities[i+1])});\n        return;\n    }\n    vector<vector<int>> chunks;\n    for (int i = 0; i < n; i += L) {\n        vector<int> chunk;\n        for (int j = i; j < min(i + L, n); j++)\n            chunk.push_back(cities[j]);\n        chunks.push_back(chunk);\n    }\n    vector<int> reps;\n    for (auto& chunk : chunks) {\n        int sz = chunk.size();\n        if (sz >= 2 && queriesLeft > 0) {\n            auto result = doQuery(chunk);\n            edges.insert(edges.end(), result.begin(), result.end());\n            queriesLeft--;\n        } else if (sz >= 2) {\n            for (int j = 0; j < sz - 1; j++)\n                edges.push_back({min(chunk[j], chunk[j+1]), max(chunk[j], chunk[j+1])});\n        }\n        reps.push_back(chunk[sz / 2]);\n    }\n    findMST(reps, edges, queriesLeft);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    cx.resize(N); cy.resize(N);\n    for (int i = 0; i < N; i++) {\n        int lx, rx, ly, ry;\n        cin >> lx >> rx >> ly >> ry;\n        cx[i] = (lx + rx) / 2;\n        cy[i] = (ly + ry) / 2;\n    }\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [](int a, int b) {\n        if (cx[a] != cx[b]) return cx[a] < cx[b];\n        return cy[a] < cy[b];\n    });\n    vector<vector<int>> groups(M);\n    int idx = 0;\n    for (int i = 0; i < M; i++)\n        for (int j = 0; j < G[i]; j++)\n            groups[i].push_back(order[idx++]);\n    int queriesLeft = Q;\n    vector<vector<pair<int,int>>> allEdges(M);\n    for (int i = 0; i < M; i++)\n        findMST(groups[i], allEdges[i], queriesLeft);\n    cout << \"!\\n\";\n    for (int i = 0; i < M; i++) {\n        for (int j = 0; j < (int)groups[i].size(); j++) {\n            if (j > 0) cout << \" \";\n            cout << groups[i][j];\n        }\n        cout << \"\\n\";\n        for (auto& e : allEdges[i])\n            cout << e.first << \" \" << e.second << \"\\n\";\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nvector<pair<int,int>> targets;\nint grid[20][20];\nint ci, cj;\nvector<string> actions;\n\nint dx[] = {-1, 1, 0, 0};\nint dy[] = {0, 0, -1, 1};\nchar dirChar[] = {'U', 'D', 'L', 'R'};\n\nbool inBounds(int i, int j) { return 0 <= i && i < N && 0 <= j && j < N; }\n\nvoid addMove(int d) {\n    actions.push_back(string(\"M \") + dirChar[d]);\n    ci += dx[d]; cj += dy[d];\n}\n\nvoid addSlide(int d) {\n    actions.push_back(string(\"S \") + dirChar[d]);\n    while (inBounds(ci + dx[d], cj + dy[d]) && !grid[ci + dx[d]][cj + dy[d]]) {\n        ci += dx[d]; cj += dy[d];\n    }\n}\n\nvoid addAlter(int d) {\n    actions.push_back(string(\"A \") + dirChar[d]);\n    grid[ci + dx[d]][cj + dy[d]] ^= 1;\n}\n\npair<int,int> getSlideDest(int d) {\n    int ni = ci, nj = cj;\n    while (inBounds(ni + dx[d], nj + dy[d]) && !grid[ni + dx[d]][nj + dy[d]]) {\n        ni += dx[d]; nj += dy[d];\n    }\n    return {ni, nj};\n}\n\nbool trySlideAligned(int ti, int tj) {\n    if (ci == ti && cj == tj) return true;\n    int d = -1;\n    if (ci == ti && cj != tj) d = (tj > cj) ? 3 : 2;\n    else if (cj == tj && ci != ti) d = (ti > ci) ? 1 : 0;\n    if (d == -1) return false;\n    \n    if (getSlideDest(d) == make_pair(ti, tj)) { addSlide(d); return true; }\n    \n    int nextI = ti + dx[d], nextJ = tj + dy[d];\n    if (!inBounds(nextI, nextJ) || grid[nextI][nextJ]) return false;\n    \n    int ni = ci + dx[d], nj = cj + dy[d];\n    while (ni != ti || nj != tj) {\n        if (!inBounds(ni, nj) || grid[ni][nj]) return false;\n        ni += dx[d]; nj += dy[d];\n    }\n    addAlter(d); addSlide(d); addAlter(d);\n    return ci == ti && cj == tj;\n}\n\nvoid goTo(int ti, int tj) {\n    while (ci != ti || cj != tj) {\n        int manhattan = abs(ci - ti) + abs(cj - tj);\n        int bestSlideD = -1, bestBenefit = 0;\n        for (int d = 0; d < 4; d++) {\n            auto [ni, nj] = getSlideDest(d);\n            int newDist = abs(ni - ti) + abs(nj - tj);\n            int benefit = manhattan - newDist;\n            if (benefit > bestBenefit && newDist < manhattan) { bestSlideD = d; bestBenefit = benefit; }\n        }\n        if (bestSlideD >= 0) {\n            auto [ni, nj] = getSlideDest(bestSlideD);\n            bool aligned = (ni == ti || nj == tj);\n            if ((aligned && bestBenefit > 0) || bestBenefit > 3) { addSlide(bestSlideD); continue; }\n        }\n        int vertDist = abs(ti - ci), horizDist = abs(tj - cj);\n        if (vertDist >= horizDist && vertDist > 3) { if (trySlideAligned(ti, cj)) continue; }\n        if (horizDist > 3) { if (trySlideAligned(ci, tj)) continue; }\n        int d = (ci < ti) ? 1 : (ci > ti) ? 0 : (cj < tj) ? 3 : 2;\n        addMove(d);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N >> M >> ci >> cj;\n    targets.resize(M);\n    for (int i = 0; i < M; i++) cin >> targets[i].first >> targets[i].second;\n    memset(grid, 0, sizeof(grid));\n    for (int i = 1; i < M; i++) goTo(targets[i].first, targets[i].second);\n    for (const auto& a : actions) cout << a << \"\\n\";\n    return 0;\n}"},"2":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Company { int x, y, r, id; };\nstruct Rect { int a, b, c, d; };\n\nvoid solve(Rect region, vector<int> ids, vector<Company>& C, vector<Rect>& res) {\n    if (ids.empty()) return;\n    if (ids.size() == 1) { res[ids[0]] = region; return; }\n    \n    int w = region.c - region.a, h = region.d - region.b;\n    long long totalA = 0;\n    for (int id : ids) totalA += C[id].r;\n    \n    auto trySplits = [&](bool vert) -> tuple<long long,int,vector<int>,vector<int>> {\n        sort(ids.begin(), ids.end(), [&](int a, int b) {\n            return vert ? C[a].x < C[b].x : C[a].y < C[b].y;\n        });\n        long long bestD = LLONG_MAX; int bestS = -1, bestI = -1;\n        long long acc = 0;\n        for (int i = 0; i < (int)ids.size()-1; i++) {\n            acc += C[ids[i]].r;\n            int c1 = vert ? C[ids[i]].x : C[ids[i]].y;\n            int c2 = vert ? C[ids[i+1]].x : C[ids[i+1]].y;\n            if (c1 == c2) continue;\n            int lo, hi;\n            if (vert) { lo = max(region.a+1, c1+1); hi = min(region.c-1, c2); }\n            else { lo = max(region.b+1, c1+1); hi = min(region.d-1, c2); }\n            if (lo > hi) continue;\n            long long lA = acc, rA = totalA - acc;\n            auto calc = [&](int s) {\n                long long lC = vert ? (long long)(s-region.a)*h : (long long)w*(s-region.b);\n                long long rC = vert ? (long long)(region.c-s)*h : (long long)w*(region.d-s);\n                return max(0LL,lA-lC)*10 + lC-lA + max(0LL,rA-rC)*10 + rC-rA;\n            };\n            vector<int> cands = {lo, hi};\n            long long opt = vert ? region.a+(lA+h-1)/h : region.b+(lA+w-1)/w;\n            cands.push_back(max(lo, min(hi, (int)clamp(opt,0LL,10000LL))));\n            opt = vert ? region.c-(rA+h-1)/h : region.d-(rA+w-1)/w;\n            cands.push_back(max(lo, min(hi, (int)clamp(opt,0LL,10000LL))));\n            for (int s : cands) { long long d = calc(s); if (d < bestD) { bestD=d; bestS=s; bestI=i; } }\n        }\n        if (bestI == -1) return {LLONG_MAX,-1,{},{}};\n        return {bestD, bestS, vector<int>(ids.begin(),ids.begin()+bestI+1), vector<int>(ids.begin()+bestI+1,ids.end())};\n    };\n    \n    auto [vd,vs,vl,vr] = trySplits(true);\n    auto [hd,hs,hl,hr] = trySplits(false);\n    \n    if (vs == -1 && hs == -1) {\n        for (int id : ids) res[id] = {C[id].x, C[id].y, C[id].x+1, C[id].y+1};\n        return;\n    }\n    bool useV = (hs == -1) || (vs != -1 && vd <= hd);\n    if (useV) {\n        solve({region.a,region.b,vs,region.d}, vl, C, res);\n        solve({vs,region.b,region.c,region.d}, vr, C, res);\n    } else {\n        solve({region.a,region.b,region.c,hs}, hl, C, res);\n        solve({region.a,hs,region.c,region.d}, hr, C, res);\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(nullptr);\n    int n; cin >> n;\n    vector<Company> C(n);\n    for (int i = 0; i < n; i++) { cin >> C[i].x >> C[i].y >> C[i].r; C[i].id = i; }\n    vector<Rect> res(n);\n    vector<int> ids(n); iota(ids.begin(), ids.end(), 0);\n    solve({0,0,10000,10000}, ids, C, res);\n    for (int i = 0; i < n; i++) cout << res[i].a << \" \" << res[i].b << \" \" << res[i].c << \" \" << res[i].d << \"\\n\";\n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <chrono>\n#include <cstring>\n#include <random>\n\nusing namespace std;\n\nconst int DEPTH_LIMIT = 150;\nconst int MAX_TILES = 2500;\nconst int MAX_DEG = 8;\n\nint adj[MAX_TILES][MAX_DEG];\nint deg[MAX_TILES];\nbool vis[MAX_TILES];\n\nint temp_vis[MAX_TILES];\nint temp_depth[MAX_TILES];\nint dfs_stack[MAX_TILES];\nint current_stamp = 0;\n\nint cell_to_tile[50][50];\nint p_val[50][50];\n\nint limited_dfs(int start, int excluded) {\n    current_stamp++;\n    int cnt = 0;\n    int stack_ptr = 0;\n    dfs_stack[stack_ptr++] = start;\n    temp_vis[start] = current_stamp;\n    temp_depth[start] = 0;\n    \n    while (stack_ptr > 0) {\n        int node = dfs_stack[--stack_ptr];\n        cnt++;\n        if (temp_depth[node] >= DEPTH_LIMIT) continue;\n        int next_depth = temp_depth[node] + 1;\n        for (int i = 0; i < deg[node]; ++i) {\n            int nxt = adj[node][i];\n            if (nxt != excluded && !vis[nxt] && temp_vis[nxt] != current_stamp) {\n                temp_vis[nxt] = current_stamp;\n                temp_depth[nxt] = next_depth;\n                dfs_stack[stack_ptr++] = nxt;\n            }\n        }\n    }\n    return cnt;\n}\n\nint get_2hop_score(int start, int excluded) {\n    int score = 0;\n    for (int i = 0; i < deg[start]; ++i) {\n        int x = adj[start][i];\n        if (x == excluded || vis[x]) continue;\n        for (int j = 0; j < deg[x]; ++j) {\n            int y = adj[x][j];\n            if (y == start || y == excluded || vis[y]) continue;\n            score++;\n        }\n    }\n    return score;\n}\n\nstruct Candidate {\n    int w;\n    int ni, nj;\n    int p;\n    int c_w;\n    int comp_size;\n    int hop2;\n};\n\nchar get_dir(int i, int j, int ni, int nj) {\n    if (ni == i - 1) return 'U';\n    if (ni == i + 1) return 'D';\n    if (nj == j - 1) return 'L';\n    if (nj == j + 1) return 'R';\n    return '?';\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int si, sj;\n    if (!(cin >> si >> sj)) return 0;\n\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            cin >> cell_to_tile[i][j];\n        }\n    }\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            cin >> p_val[i][j];\n        }\n    }\n\n    int dirs[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\n    \n    // Build adjacency list for tiles\n    memset(deg, 0, sizeof(deg));\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            int T1 = cell_to_tile[i][j];\n            for (auto& d : dirs) {\n                int ni = i + d[0], nj = j + d[1];\n                if (ni >= 0 && ni < 50 && nj >= 0 && nj < 50) {\n                    int T2 = cell_to_tile[ni][nj];\n                    if (T1 != T2) {\n                        bool found = false;\n                        for (int k = 0; k < deg[T1]; ++k) {\n                            if (adj[T1][k] == T2) { found = true; break; }\n                        }\n                        if (!found) adj[T1][deg[T1]++] = T2;\n                        \n                        found = false;\n                        for (int k = 0; k < deg[T2]; ++k) {\n                            if (adj[T2][k] == T1) { found = true; break; }\n                        }\n                        if (!found) adj[T2][deg[T2]++] = T1;\n                    }\n                }\n            }\n        }\n    }\n\n    auto cmp = [](const Candidate& a, const Candidate& b) {\n        bool a_safe = (a.c_w >= 2);\n        bool b_safe = (b.c_w >= 2);\n        if (a_safe != b_safe) return a_safe > b_safe;\n        \n        bool a_corr = (a.c_w == 1);\n        bool b_corr = (b.c_w == 1);\n        if (a_corr != b_corr) return a_corr > b_corr;\n        \n        if (a.comp_size != b.comp_size) return a.comp_size > b.comp_size;\n        if (a.hop2 != b.hop2) return a.hop2 > b.hop2;\n        if (a.p != b.p) return a.p > b.p;\n        \n        return false; // Keep original random order on exact ties\n    };\n\n    std::mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    string best_path = \"\";\n    int best_score = -1;\n\n    for (int run = 0; run < 2; ++run) {\n        std::shuffle(begin(dirs), end(dirs), rng);\n        memset(vis, false, sizeof(vis));\n        \n        int u = cell_to_tile[si][sj];\n        vis[u] = true;\n        int i = si, j = sj;\n        int v = -1;\n        int curr_score = p_val[si][sj];\n        string curr_path = \"\";\n        \n        while (true) {\n            vector<Candidate> candidates;\n            for (auto& d : dirs) {\n                int ni = i + d[0], nj = j + d[1];\n                if (ni < 0 || ni >= 50 || nj < 0 || nj >= 50) continue;\n                int w = cell_to_tile[ni][nj];\n                if (w == u || w == v || vis[w]) continue;\n                \n                int c_w = 0;\n                for (int k = 0; k < deg[w]; ++k) {\n                    int nxt = adj[w][k];\n                    if (nxt != u && !vis[nxt]) c_w++;\n                }\n                \n                candidates.push_back({w, ni, nj, p_val[ni][nj], c_w, 0, 0});\n            }\n            \n            if (candidates.empty()) break;\n            \n            if (candidates.size() > 1) {\n                for (auto& cand : candidates) {\n                    cand.comp_size = limited_dfs(cand.w, u);\n                    cand.hop2 = get_2hop_score(cand.w, u);\n                }\n            }\n            \n            sort(candidates.begin(), candidates.end(), cmp);\n            \n            auto& best = candidates[0];\n            vis[best.w] = true;\n            curr_path += get_dir(i, j, best.ni, best.nj);\n            curr_score += best.p;\n            \n            v = u;\n            u = best.w;\n            i = best.ni;\n            j = best.nj;\n        }\n        \n        if (curr_score > best_score) {\n            best_score = curr_score;\n            best_path = curr_path;\n        }\n    }\n    \n    cout << best_path << \"\\n\";\n\n    return 0;\n}","ahc003":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <cmath>\n#include <tuple>\n#include <algorithm>\n\nusing namespace std;\n\nconst int N = 30;\ndouble W_h[N][N - 1]; // Horizontal edges: (i, j) to (i, j+1)\ndouble W_v[N - 1][N]; // Vertical edges:   (i, j) to (i+1, j)\n\nvector<vector<double>> dist(N, vector<double>(N));\nvector<vector<pair<int, int>>> prev_node(N, vector<pair<int, int>>(N));\nvector<tuple<int, int, int>> edges;\n\nstring dijkstra(int si, int sj, int ti, int tj) {\n    for (int i = 0; i < N; ++i) {\n        fill(dist[i].begin(), dist[i].end(), 1e18);\n        fill(prev_node[i].begin(), prev_node[i].end(), make_pair(-1, -1));\n    }\n    \n    // Min-heap priority queue: {distance, {row, col}}\n    priority_queue<pair<double, pair<int, int>>, vector<pair<double, pair<int, int>>>, greater<>> pq;\n    dist[si][sj] = 0;\n    pq.push({0.0, {si, sj}});\n\n    while (!pq.empty()) {\n        auto [d, u] = pq.top();\n        pq.pop();\n        int i = u.first, j = u.second;\n        \n        if (d > dist[i][j] + 1e-9) continue;\n        if (i == ti && j == tj) break;\n\n        // Up\n        if (i > 0) {\n            double w = W_v[i - 1][j];\n            if (dist[i][j] + w < dist[i - 1][j] - 1e-9) {\n                dist[i - 1][j] = dist[i][j] + w;\n                prev_node[i - 1][j] = {i, j};\n                pq.push({dist[i - 1][j], {i - 1, j}});\n            }\n        }\n        // Down\n        if (i < N - 1) {\n            double w = W_v[i][j];\n            if (dist[i][j] + w < dist[i + 1][j] - 1e-9) {\n                dist[i + 1][j] = dist[i][j] + w;\n                prev_node[i + 1][j] = {i, j};\n                pq.push({dist[i + 1][j], {i + 1, j}});\n            }\n        }\n        // Left\n        if (j > 0) {\n            double w = W_h[i][j - 1];\n            if (dist[i][j] + w < dist[i][j - 1] - 1e-9) {\n                dist[i][j - 1] = dist[i][j] + w;\n                prev_node[i][j - 1] = {i, j};\n                pq.push({dist[i][j - 1], {i, j - 1}});\n            }\n        }\n        // Right\n        if (j < N - 1) {\n            double w = W_h[i][j];\n            if (dist[i][j] + w < dist[i][j + 1] - 1e-9) {\n                dist[i][j + 1] = dist[i][j] + w;\n                prev_node[i][j + 1] = {i, j};\n                pq.push({dist[i][j + 1], {i, j + 1}});\n            }\n        }\n    }\n\n    string path = \"\";\n    int ci = ti, cj = tj;\n    // Trace back from target to start\n    while (ci != si || cj != sj) {\n        auto p = prev_node[ci][cj];\n        int pi = p.first, pj = p.second;\n        if (pi == ci - 1) path += 'D';\n        else if (pi == ci + 1) path += 'U';\n        else if (pj == cj - 1) path += 'R';\n        else if (pj == cj + 1) path += 'L';\n        ci = pi;\n        cj = pj;\n    }\n    \n    reverse(path.begin(), path.end());\n    return path;\n}\n\nint main() {\n    // Fast I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Initialize edge weights to a safe neutral estimate (midpoint of 1000 to 9000)\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N - 1; ++j) W_h[i][j] = 5000.0;\n    }\n    for (int i = 0; i < N - 1; ++i) {\n        for (int j = 0; j < N; ++j) W_v[i][j] = 5000.0;\n    }\n\n    double alpha = 0.2; // Optimal steady-state learning rate offset\n\n    for (int k = 0; k < 1000; ++k) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n\n        string path = dijkstra(si, sj, ti, tj);\n        \n        // Output path and flush immediately\n        cout << path << \"\\n\" << flush;\n\n        long long result;\n        cin >> result;\n\n        double L = 0;\n        int m = path.length();\n        edges.clear();\n        \n        int ci = si, cj = sj;\n        for (char c : path) {\n            if (c == 'U') {\n                edges.push_back({1, ci - 1, cj});\n                L += W_v[ci - 1][cj];\n                ci--;\n            } else if (c == 'D') {\n                edges.push_back({1, ci, cj});\n                L += W_v[ci][cj];\n                ci++;\n            } else if (c == 'L') {\n                edges.push_back({0, ci, cj - 1});\n                L += W_h[ci][cj - 1];\n                cj--;\n            } else if (c == 'R') {\n                edges.push_back({0, ci, cj});\n                L += W_h[ci][cj];\n                cj++;\n            }\n        }\n\n        // SGD weight update\n        if (m > 0) {\n            double delta = (result - L) / m;\n            for (auto& [type, i, j] : edges) {\n                if (type == 0) {\n                    W_h[i][j] = max(100.0, min(9000.0, W_h[i][j] + alpha * delta));\n                } else {\n                    W_v[i][j] = max(100.0, min(9000.0, W_v[i][j] + alpha * delta));\n                }\n            }\n        }\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    cin >> N >> M;\n    vector<string> s(M);\n    for (int i = 0; i < M; i++) cin >> s[i];\n    \n    struct Placement { int type, row, col, len, str_idx; };\n    vector<Placement> all_placements;\n    for (int m = 0; m < M; m++) {\n        int k = s[m].size();\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++)\n            all_placements.push_back({0, i, j, k, m});\n        for (int j = 0; j < N; j++) for (int i = 0; i < N; i++)\n            all_placements.push_back({1, i, j, k, m});\n    }\n    int P = all_placements.size();\n    \n    vector<vector<pair<int,int>>> placement_cells(P), cell_placements(N*N);\n    for (int p = 0; p < P; p++) {\n        auto& pl = all_placements[p];\n        for (int q = 0; q < pl.len; q++) {\n            int r = pl.type==0 ? pl.row : (pl.row+q)%N;\n            int c = pl.type==0 ? (pl.col+q)%N : pl.col;\n            placement_cells[p].push_back({r,c});\n            cell_placements[r*N+c].push_back({p,q});\n        }\n    }\n    \n    vector<vector<array<int,8>>> votes(N, vector<array<int,8>>(N));\n    for (int p = 0; p < P; p++) {\n        auto& pl = all_placements[p];\n        for (int q = 0; q < pl.len; q++) {\n            auto [r,c] = placement_cells[p][q];\n            votes[r][c][s[pl.str_idx][q]-'A']++;\n        }\n    }\n    \n    vector<string> grid(N, string(N,'A'));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        int mx = -1; char best = 'A';\n        for (int ch = 0; ch < 8; ch++) if (votes[i][j][ch] > mx) { mx = votes[i][j][ch]; best = 'A'+ch; }\n        grid[i][j] = best;\n    }\n    \n    vector<int8_t> placement_match(P);\n    vector<int> string_match_count(M, 0);\n    for (int p = 0; p < P; p++) {\n        auto& pl = all_placements[p]; bool ok = true;\n        for (int q = 0; q < pl.len && ok; q++) {\n            auto [r,c] = placement_cells[p][q];\n            if (grid[r][c] != s[pl.str_idx][q]) ok = false;\n        }\n        placement_match[p] = ok;\n        if (ok) string_match_count[pl.str_idx]++;\n    }\n    \n    vector<tuple<int,int,int8_t>> changesToApply;\n    for (int iter = 0; iter < 5; iter++) {\n        bool improved = false;\n        for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) {\n            int ci = r*N+c; char oldChar = grid[r][c];\n            for (int ch = 0; ch < 8; ch++) {\n                char nc = 'A'+ch; if (nc == oldChar) continue;\n                changesToApply.clear(); map<int,int> countChange;\n                for (auto [p,q] : cell_placements[ci]) {\n                    auto& pl = all_placements[p]; int m = pl.str_idx; char exp = s[m][q];\n                    bool was = (oldChar==exp), is = (nc==exp);\n                    if (was == is) continue;\n                    if (was && !is) { if (placement_match[p]) { changesToApply.emplace_back(p,q,0); countChange[m]--; } }\n                    else { bool ok = true;\n                        for (int i = 0; i < pl.len && ok; i++) { if (i==q) continue; auto [rr,cc] = placement_cells[p][i]; if (grid[rr][cc]!=s[m][i]) ok=false; }\n                        if (ok && !placement_match[p]) { changesToApply.emplace_back(p,q,1); countChange[m]++; }\n                    }\n                }\n                if (countChange.empty()) continue;\n                int delta = 0;\n                for (auto& [m,chg] : countChange) {\n                    bool was = string_match_count[m]>0, is = string_match_count[m]+chg>0;\n                    if (!was && is) delta++; else if (was && !is) delta--;\n                }\n                if (delta > 0) {\n                    grid[r][c] = nc;\n                    for (auto [p,q,sm] : changesToApply) { int m = all_placements[p].str_idx; placement_match[p]=sm; string_match_count[m]+=(sm?1:-1); }\n                    oldChar = nc; improved = true;\n                }\n            }\n        }\n        if (!improved) break;\n    }\n    for (int i = 0; i < N; i++) cout << grid[i] << endl;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, si, sj;\nvector<string> grid;\nint cost[70][70];\nvector<pair<int,int>> roads;\nint seg_id[70][70][2];\nint num_segs;\n\nvoid find_segments() {\n    memset(seg_id, -1, sizeof(seg_id));\n    num_segs = 0;\n    for (int i = 0; i < N; i++) {\n        int j = 0;\n        while (j < N) {\n            if (grid[i][j] == '#') { j++; continue; }\n            int start = j;\n            while (j < N && grid[i][j] != '#') j++;\n            for (int k = start; k < j; k++) seg_id[i][k][0] = num_segs++;\n        }\n    }\n    for (int j = 0; j < N; j++) {\n        int i = 0;\n        while (i < N) {\n            if (grid[i][j] == '#') { i++; continue; }\n            int start = i;\n            while (i < N && grid[i][j] != '#') i++;\n            for (int k = start; k < i; k++) seg_id[k][j][1] = num_segs++;\n        }\n    }\n}\n\nvector<int> dist_arr, prev_arr;\nvoid dijkstra(int sx, int sy) {\n    int V = N * N;\n    dist_arr.assign(V, INT_MAX);\n    prev_arr.assign(V, -1);\n    dist_arr[sx * N + sy] = 0;\n    priority_queue<pair<int,int>, vector<pair<int,int>>, greater<>> pq;\n    pq.push({0, sx * N + sy});\n    const int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, -1, 1};\n    while (!pq.empty()) {\n        auto [d, u] = pq.top(); pq.pop();\n        if (d > dist_arr[u]) continue;\n        int x = u / N, y = u % N;\n        for (int k = 0; k < 4; k++) {\n            int nx = x + dx[k], ny = y + dy[k];\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N || grid[nx][ny] == '#') continue;\n            int v = nx * N + ny, nd = d + cost[nx][ny];\n            if (nd < dist_arr[v]) { dist_arr[v] = nd; prev_arr[v] = u; pq.push({nd, v}); }\n        }\n    }\n}\n\nstring get_path(int sx, int sy, int ex, int ey) {\n    if (sx == ex && sy == ey) return \"\";\n    vector<int> trace;\n    for (int u = ex * N + ey; u != sx * N + sy && u != -1; u = prev_arr[u]) trace.push_back(u);\n    reverse(trace.begin(), trace.end());\n    string path;\n    int cur = sx * N + sy;\n    for (int next : trace) {\n        int cx = cur/N, cy = cur%N, nx = next/N, ny = next%N;\n        path += (nx==cx-1) ? 'U' : (nx==cx+1) ? 'D' : (ny==cy-1) ? 'L' : 'R';\n        cur = next;\n    }\n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> si >> sj;\n    grid.resize(N);\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] != '#') { cost[i][j] = grid[i][j] - '0'; roads.push_back({i, j}); }\n    }\n    find_segments();\n    vector<bool> covered(num_segs, false);\n    covered[seg_id[si][sj][0]] = covered[seg_id[si][sj][1]] = true;\n    vector<pair<int,int>> selected;\n    while (true) {\n        int best_count = 0, best_dist = INT_MAX;\n        pair<int,int> best_cell = {-1, -1};\n        for (auto& [i, j] : roads) {\n            int count = (seg_id[i][j][0]!=-1 && !covered[seg_id[i][j][0]]) + (seg_id[i][j][1]!=-1 && !covered[seg_id[i][j][1]]);\n            if (count > best_count) { best_count = count; best_dist = INT_MAX; best_cell = {i, j}; }\n            if (count == best_count && count > 0) {\n                int min_d = abs(i-si) + abs(j-sj);\n                for (auto& [r, c] : selected) min_d = min(min_d, abs(i-r) + abs(j-c));\n                if (min_d < best_dist) { best_dist = min_d; best_cell = {i, j}; }\n            }\n        }\n        if (best_count == 0) break;\n        selected.push_back(best_cell);\n        covered[seg_id[best_cell.first][best_cell.second][0]] = covered[seg_id[best_cell.first][best_cell.second][1]] = true;\n    }\n    string result;\n    int cx = si, cy = sj;\n    vector<bool> visited(selected.size(), false);\n    for (size_t iter = 0; iter < selected.size(); iter++) {\n        dijkstra(cx, cy);\n        int best = -1, best_dist = INT_MAX;\n        for (size_t i = 0; i < selected.size(); i++) {\n            if (visited[i]) continue;\n            int d = dist_arr[selected[i].first * N + selected[i].second];\n            if (d < best_dist) { best_dist = d; best = i; }\n        }\n        if (best == -1) break;\n        visited[best] = true;\n        result += get_path(cx, cy, selected[best].first, selected[best].second);\n        cx = selected[best].first; cy = selected[best].second;\n    }\n    if (cx != si || cy != sj) { dijkstra(cx, cy); result += get_path(cx, cy, si, sj); }\n    cout << result << endl;\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K, R;\n    cin >> N >> M >> K >> R;\n    \n    vector<vector<int>> d(N, vector<int>(K));\n    for (int i = 0; i < N; i++)\n        for (int k = 0; k < K; k++) cin >> d[i][k];\n    \n    vector<vector<int>> deps(N), rdeps(N);\n    for (int i = 0; i < R; i++) {\n        int u, v; cin >> u >> v; u--; v--;\n        deps[v].push_back(u); rdeps[u].push_back(v);\n    }\n    \n    vector<int> topo;\n    { vector<int> indeg(N,0);\n      for(int v=0;v<N;v++) for(int u:deps[v]) indeg[v]++;\n      queue<int> q;\n      for(int i=0;i<N;i++) if(indeg[i]==0) q.push(i);\n      while(!q.empty()) { int u=q.front(); q.pop(); topo.push_back(u);\n        for(int v:rdeps[u]) if(--indeg[v]==0) q.push(v); } }\n    \n    vector<int> crit(N,1);\n    for(int u:topo) for(int v:rdeps[u]) crit[u]=max(crit[u],1+crit[v]);\n    \n    vector<vector<int>> proven(M,vector<int>(K,0)), est(M,vector<int>(K,0));\n    vector<int> tstatus(N,-1), mtask(M,-1), tstart(N,-1), tcount(M,0);\n    \n    auto can_start=[&](int t){ if(tstatus[t]!=-1) return false;\n        for(int dep:deps[t]) if(tstatus[dep]!=1) return false; return true; };\n    auto est_w=[&](int t,int m){ int w=0;\n        for(int k=0;k<K;k++) w+=max(0,d[t][k]-est[m][k]); return w; };\n    auto can_1day=[&](int t,int m){ for(int k=0;k<K;k++)\n        if(d[t][k]>proven[m][k]) return false; return true; };\n    \n    for(int day=1;day<=2000;day++) {\n        vector<int> avail;\n        for(int i=0;i<N;i++) if(can_start(i)) avail.push_back(i);\n        sort(avail.begin(),avail.end(),[&](int a,int b){ return crit[a]>crit[b]; });\n        \n        vector<int> freem;\n        for(int j=0;j<M;j++) if(mtask[j]==-1) freem.push_back(j);\n        \n        vector<pair<int,int>> assign;\n        vector<bool> tused(N,false), mused(M,false);\n        \n        for(int t:avail) { if(tused[t]) continue;\n            for(int m:freem) { if(mused[m]) continue;\n                if(can_1day(t,m)) { assign.push_back({m,t}); tused[t]=mused[m]=true;\n                    mtask[m]=t; tstatus[t]=0; tstart[t]=day; tcount[m]++; break; } } }\n        \n        for(int t:avail) { if(tused[t]) continue;\n            int best=-1; long long best_score=LLONG_MAX;\n            for(int m:freem) { if(mused[m]) continue;\n                long long score=(long long)est_w(t,m)*10000+tcount[m];\n                if(score<best_score) { best_score=score; best=m; } }\n            if(best!=-1) { assign.push_back({best,t}); tused[t]=mused[best]=true;\n                mtask[best]=t; tstatus[t]=0; tstart[t]=day; tcount[best]++; } }\n        \n        cout << assign.size();\n        for(auto [m,t]:assign) cout << \" \" << m+1 << \" \" << t+1;\n        cout << \"\\n\"; cout.flush();\n        \n        int n; cin >> n; if(n==-1) break;\n        for(int i=0;i<n;i++) { int m; cin >> m; m--;\n            int t=mtask[m], actual=day-tstart[t]+1;\n            tstatus[t]=1; mtask[m]=-1;\n            if(actual==1) { for(int k=0;k<K;k++)\n                proven[m][k]=max(proven[m][k],d[t][k]), est[m][k]=max(est[m][k],d[t][k]); }\n            else { int pred_w=est_w(t,m), target_w=actual;\n                vector<int> gap(K); int total_gap=0;\n                for(int k=0;k<K;k++) { gap[k]=max(0,d[t][k]-est[m][k]); total_gap+=gap[k]; }\n                if(total_gap==0) { for(int k=0;k<K;k++) if(d[t][k]>0)\n                    est[m][k]=max(proven[m][k],est[m][k]-(target_w+K-1)/K); }\n                else if(pred_w>target_w) { int excess=pred_w-target_w;\n                    vector<pair<int,int>> sg;\n                    for(int k=0;k<K;k++) if(gap[k]>0) sg.push_back({gap[k],k});\n                    sort(sg.rbegin(),sg.rend());\n                    for(auto [g,k]:sg) { int inc=min(g,excess); est[m][k]+=inc; excess-=inc;\n                        if(excess==0) break; } } } } }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint manhattan(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    vector<array<int, 4>> orders(1000);\n    for (int i = 0; i < 1000; i++)\n        cin >> orders[i][0] >> orders[i][1] >> orders[i][2] >> orders[i][3];\n    \n    vector<pair<double, int>> scored(1000);\n    for (int i = 0; i < 1000; i++) {\n        int a = orders[i][0], b = orders[i][1], c = orders[i][2], d = orders[i][3];\n        scored[i] = {manhattan(400, 400, (a+c)/2, (b+d)/2) * 2.0 + manhattan(a, b, c, d) * 0.5, i};\n    }\n    sort(scored.begin(), scored.end());\n    \n    vector<int> selected(50);\n    for (int i = 0; i < 50; i++) selected[i] = scored[i].second;\n    \n    auto get_xy = [&](int idx, bool is_del) -> pair<int,int> {\n        int oid = selected[idx];\n        if (is_del) return {orders[oid][2], orders[oid][3]};\n        return {orders[oid][0], orders[oid][1]};\n    };\n    \n    auto build_route = [&](vector<int>& order_indices) {\n        vector<pair<int, bool>> route;\n        for (int t = 0; t < 50; t++) {\n            int idx = order_indices[t], n = route.size();\n            auto [a, b] = get_xy(idx, false);\n            auto [c, d] = get_xy(idx, true);\n            int best_cost = INT_MAX, best_pick = -1, best_del = -1;\n            \n            for (int p = 0; p <= n; p++) for (int q = p; q <= n; q++) {\n                int cost = 0; int px = 400, py = 400;\n                for (int i = 0; i < p; i++) { auto [nx, ny] = get_xy(route[i].first, route[i].second); cost += manhattan(px, py, nx, ny); px = nx; py = ny; }\n                cost += manhattan(px, py, a, b); px = a; py = b;\n                for (int i = p; i < q; i++) { auto [nx, ny] = get_xy(route[i].first, route[i].second); cost += manhattan(px, py, nx, ny); px = nx; py = ny; }\n                cost += manhattan(px, py, c, d); px = c; py = d;\n                for (int i = q; i < n; i++) { auto [nx, ny] = get_xy(route[i].first, route[i].second); cost += manhattan(px, py, nx, ny); px = nx; py = ny; }\n                cost += manhattan(px, py, 400, 400);\n                if (cost < best_cost) { best_cost = cost; best_pick = p; best_del = q; }\n            }\n            route.insert(route.begin() + best_del, {idx, true});\n            route.insert(route.begin() + best_pick, {idx, false});\n        }\n        return route;\n    };\n    \n    auto find_pos = [](vector<pair<int, bool>>& r) {\n        vector<int> pu(50), de(50);\n        for (int i = 0; i < (int)r.size(); i++) r[i].second ? de[r[i].first] = i : pu[r[i].first] = i;\n        return make_pair(pu, de);\n    };\n    \n    vector<int> ord(50); iota(ord.begin(), ord.end(), 0);\n    vector<pair<int, bool>> best_route; int best_cost = INT_MAX;\n    \n    for (int trial = 0; trial < 8; trial++) {\n        if (trial > 0) shuffle(ord.begin(), ord.end(), rng);\n        auto route = build_route(ord);\n        int cost = 0; int px = 400, py = 400;\n        for (auto& [i, d] : route) { auto [nx, ny] = get_xy(i, d); cost += manhattan(px, py, nx, ny); px = nx; py = ny; }\n        cost += manhattan(px, py, 400, 400);\n        if (cost < best_cost) { best_cost = cost; best_route = route; }\n    }\n    \n    auto [pu_pos, de_pos] = find_pos(best_route);\n    for (int iter = 0; iter < 500; iter++) {\n        bool imp = false;\n        for (int i = 0; i < (int)best_route.size() && !imp; i++) {\n            int idx = best_route[i].first; bool is_d = best_route[i].second;\n            int n = best_route.size();\n            auto [ex, ey] = get_xy(idx, is_d);\n            int pvx = 400, pvy = 400, nx = 400, ny = 400;\n            if (i > 0) { auto [px2, py2] = get_xy(best_route[i-1].first, best_route[i-1].second); pvx = px2; pvy = py2; }\n            if (i < n-1) { auto [nx2, ny2] = get_xy(best_route[i+1].first, best_route[i+1].second); nx = nx2; ny = ny2; }\n            int base = -manhattan(pvx, pvy, ex, ey) - manhattan(ex, ey, nx, ny) + manhattan(pvx, pvy, nx, ny);\n            auto gc = [&](int pos) -> pair<int,int> {\n                if (pos < 0 || pos >= n-1) return {400, 400};\n                int op = (pos < i) ? pos : pos + 1;\n                return get_xy(best_route[op].first, best_route[op].second);\n            };\n            for (int j = 0; j <= n-1 && !imp; j++) {\n                if (j == i) continue;\n                if (is_d) { if (j <= pu_pos[idx]) continue; }\n                else { int mj = de_pos[idx] - (de_pos[idx] > i ? 1 : 0); if (j > mj) continue; }\n                auto [ipx, ipy] = gc(j-1); auto [inx, iny] = gc(j);\n                int delta = base - manhattan(ipx, ipy, inx, iny) + manhattan(ipx, ipy, ex, ey) + manhattan(ex, ey, inx, iny);\n                if (delta < 0) {\n                    auto elem = best_route[i]; best_route.erase(best_route.begin() + i);\n                    best_route.insert(best_route.begin() + j, elem); best_cost += delta;\n                    auto [p, d] = find_pos(best_route); pu_pos = p; de_pos = d; imp = true;\n                }\n            }\n        }\n        if (!imp) break;\n    }\n    \n    cout << 50; for (int i = 0; i < 50; i++) cout << \" \" << selected[i] + 1; cout << \"\\n\";\n    cout << best_route.size() + 2 << \" 400 400\";\n    for (auto& [i, d] : best_route) { auto [x, y] = get_xy(i, d); cout << \" \" << x << \" \" << y; }\n    cout << \" 400 400\\n\";\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <numeric>\n\nusing namespace std;\n\nstruct DSU {\n    vector<int> parent, rank_;\n    DSU(int n) : parent(n), rank_(n, 0) {\n        iota(parent.begin(), parent.end(), 0);\n    }\n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n    bool merge(int x, int y) {\n        x = find(x); y = find(y);\n        if (x == y) return false;\n        if (rank_[x] < rank_[y]) swap(x, y);\n        parent[y] = x;\n        if (rank_[x] == rank_[y]) rank_[x]++;\n        return true;\n    }\n};\n\nint main() {\n    // Fast I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N = 400, M = 1995;\n    vector<double> x(N), y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> x[i] >> y[i];\n    }\n\n    vector<int> u(M), v(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> u[i] >> v[i];\n    }\n\n    DSU dsu(N);\n    // Track rejected edges between component roots\n    // Max possible rejected edges between any two components is bounded\n    vector<vector<int8_t>> rejected(N, vector<int8_t>(N, 0));\n    \n    // Optimal thresholds derived from the optimal stopping rule for U(d, 3d)\n    // V_5 = 1.44984375\n    // V_4 = 1.5165625\n    // V_3 = 1.609375\n    // V_2 = 1.75\n    // V_1 = 2.0 (Not strictly used as we accept unconditionally at k=4)\n    double thresholds[4] = {1.44984375, 1.5165625, 1.609375, 1.75};\n\n    int accepted = 0;\n    for (int i = 0; i < M; ++i) {\n        int l;\n        cin >> l;\n        \n        int A = dsu.find(u[i]);\n        int B = dsu.find(v[i]);\n        \n        // If already connected, reject\n        if (A == B) {\n            cout << \"0\\n\" << std::flush;\n            continue;\n        }\n\n        // Global safety net: If we are running out of edges, accept any connecting edge\n        int remaining = M - i - 1;\n        int needed = (N - 1) - accepted;\n\n        if (remaining <= needed + 5) {\n            cout << \"1\\n\" << std::flush;\n            dsu.merge(A, B);\n            accepted++;\n            continue;\n        }\n\n        // Calculate base distance d_i\n        double dx = x[u[i]] - x[v[i]];\n        double dy = y[u[i]] - y[v[i]];\n        int d = std::round(std::sqrt(dx * dx + dy * dy));\n        \n        // Normalize roots to avoid asymmetric array accesses\n        if (A > B) swap(A, B);\n        \n        int k = rejected[A][B];\n        \n        // If we've seen and rejected 4 edges, this is guaranteed to be the 5th and final edge\n        if (k >= 4) {\n            cout << \"1\\n\" << std::flush;\n            dsu.merge(A, B);\n            accepted++;\n        } else {\n            double thresh = thresholds[k] * d;\n            if (l <= thresh) {\n                cout << \"1\\n\" << std::flush;\n                dsu.merge(A, B);\n                accepted++;\n            } else {\n                cout << \"0\\n\" << std::flush;\n                rejected[A][B]++;\n            }\n        }\n    }\n\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 30, W = 30;\nint N, M;\nint px[25], py[25], pt[25];\nint hx[15], hy[15];\nbool wall[H][W];\n\nint dx[] = {-1, 1, 0, 0};\nint dy[] = {0, 0, -1, 1};\nchar dir_char[] = \"UDLR\";\nchar wall_char[] = \"udlr\";\n\nbool in_bounds(int x, int y) { return 0 <= x && x < H && 0 <= y && y < W; }\n\nbool has_pet_at(int x, int y) {\n    for (int i = 0; i < N; i++) if (px[i] == x && py[i] == y) return true;\n    return false;\n}\n\nbool has_human_at(int x, int y) {\n    for (int i = 0; i < M; i++) if (hx[i] == x && hy[i] == y) return true;\n    return false;\n}\n\nbool pet_adjacent(int x, int y) {\n    for (int d = 0; d < 4; d++) if (has_pet_at(x + dx[d], y + dy[d])) return true;\n    return false;\n}\n\nbool can_place_wall(int x, int y) {\n    if (!in_bounds(x, y) || wall[x][y]) return false;\n    if (has_pet_at(x, y) || has_human_at(x, y)) return false;\n    if (pet_adjacent(x, y)) return false;\n    return true;\n}\n\nint wall_value(int wx, int wy, int hi) {\n    int val = 0;\n    for (int p = 0; p < N; p++) {\n        int weight = (pt[p] == 4) ? 4 : (pt[p] == 3) ? 2 : (pt[p] == 5) ? 2 : 1;\n        int dpw = abs(px[p] - wx) + abs(py[p] - wy);\n        int dwh = abs(wx - hx[hi]) + abs(wy - hy[hi]);\n        int dph = abs(px[p] - hx[hi]) + abs(py[p] - hy[hi]);\n        if (dpw + dwh == dph && dpw > 0 && dwh > 0) val += 100 * weight;\n        if (dpw < 6) val += (6 - dpw) * 10 * weight;\n    }\n    return val;\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++) { cin >> px[i] >> py[i] >> pt[i]; px[i]--; py[i]--; }\n    cin >> M;\n    for (int i = 0; i < M; i++) { cin >> hx[i] >> hy[i]; hx[i]--; hy[i]--; }\n    \n    memset(wall, false, sizeof(wall));\n    \n    for (int turn = 0; turn < 300; turn++) {\n        string actions(M, '.');\n        for (int i = 0; i < M; i++) {\n            int best_d = -1, best_val = 20;\n            for (int d = 0; d < 4; d++) {\n                int wx = hx[i] + dx[d], wy = hy[i] + dy[d];\n                if (can_place_wall(wx, wy)) {\n                    int val = wall_value(wx, wy, i);\n                    if (val > best_val) { best_val = val; best_d = d; }\n                }\n            }\n            if (best_d != -1) {\n                actions[i] = wall_char[best_d];\n            } else {\n                double gx = 0, gy = 0;\n                for (int p = 0; p < N; p++) {\n                    double dist = max(1.0, (double)(abs(hx[i]-px[p]) + abs(hy[i]-py[p])));\n                    gx += (hx[i] - px[p]) / (dist * dist);\n                    gy += (hy[i] - py[p]) / (dist * dist);\n                }\n                int bm = -1; double bd = 0.01;\n                for (int d = 0; d < 4; d++) {\n                    int nx = hx[i]+dx[d], ny = hy[i]+dy[d];\n                    if (in_bounds(nx,ny) && !wall[nx][ny]) {\n                        double dot = dx[d]*gx + dy[d]*gy;\n                        if (dot > bd) { bd = dot; bm = d; }\n                    }\n                }\n                if (bm != -1) actions[i] = dir_char[bm];\n            }\n        }\n        cout << actions << endl;\n        \n        for (int i = 0; i < N; i++) {\n            string mv; cin >> mv;\n            for (char c : mv) for (int d = 0; d < 4; d++) if (c == dir_char[d]) {\n                int nx = px[i]+dx[d], ny = py[i]+dy[d];\n                if (in_bounds(nx,ny) && !wall[nx][ny]) { px[i]=nx; py[i]=ny; }\n                break;\n            }\n        }\n        \n        for (int i = 0; i < M; i++) {\n            if (actions[i] != '.' && islower(actions[i])) {\n                for (int d = 0; d < 4; d++) if (actions[i] == wall_char[d]) {\n                    int nx=hx[i]+dx[d], ny=hy[i]+dy[d];\n                    if (in_bounds(nx,ny)) wall[nx][ny] = true;\n                    break;\n                }\n            }\n            if (actions[i] != '.' && isupper(actions[i])) {\n                for (int d = 0; d < 4; d++) if (actions[i] == dir_char[d]) {\n                    int nx=hx[i]+dx[d], ny=hy[i]+dy[d];\n                    if (in_bounds(nx,ny) && !wall[nx][ny]) { hx[i]=nx; hy[i]=ny; }\n                    break;\n                }\n            }\n        }\n    }\n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cstring>\n#include <algorithm>\n#include <queue>\n\nusing namespace std;\n\nint si, sj, ti, tj;\ndouble p;\nchar h[20][19];\nchar v[19][20];\n\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\nchar dirs[] = {'U', 'D', 'L', 'R'};\n\nint dist[20][20];\nbool can[20][20][4];\ndouble move_prob_table[20][20][4];\ndouble stay_prob_table[20][20][4];\ndouble remaining_sq[201][41];\ndouble reach_score_table[201];\n\nvoid compute_distances() {\n    memset(dist, -1, sizeof(dist));\n    dist[ti][tj] = 0;\n    queue<pair<int, int>> q;\n    q.push({ti, tj});\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int dir = 0; dir < 4; ++dir) {\n            if (can[i][j][dir]) {\n                int ni = i + dr[dir], nj = j + dc[dir];\n                if (dist[ni][nj] == -1) {\n                    dist[ni][nj] = dist[i][j] + 1;\n                    q.push({ni, nj});\n                }\n            }\n        }\n    }\n}\n\nstruct Node {\n    vector<char> seq;\n    double exact_score;\n    double dp[400]; // Flattened 20x20 grid for fast copy\n    double value;\n};\n\nint main() {\n    // Fast I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    if (!(cin >> si >> sj >> ti >> tj >> p)) return 0;\n    \n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 19; ++j) {\n            cin >> h[i][j];\n        }\n    }\n    for (int i = 0; i < 19; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            cin >> v[i][j];\n        }\n    }\n    \n    // Precompute transition dynamics\n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            for (int dir = 0; dir < 4; ++dir) {\n                if (dir == 0) can[i][j][dir] = i > 0 && v[i-1][j] == '0';\n                else if (dir == 1) can[i][j][dir] = i < 19 && v[i][j] == '0';\n                else if (dir == 2) can[i][j][dir] = j > 0 && h[i][j-1] == '0';\n                else can[i][j][dir] = j < 19 && h[i][j] == '0';\n                \n                bool wall = !can[i][j][dir];\n                move_prob_table[i][j][dir] = (1.0 - p) * (1.0 - wall);\n                stay_prob_table[i][j][dir] = 1.0 - move_prob_table[i][j][dir];\n            }\n        }\n    }\n    \n    compute_distances();\n    \n    // Precompute scores and heuristic components\n    for (int t = 1; t <= 200; ++t) {\n        reach_score_table[t] = 401.0 - t;\n        for (int d = 0; d <= 40; ++d) {\n            int rem = 400 - t - d;\n            remaining_sq[t][d] = rem > 0 ? (double)rem * rem : 0.0;\n        }\n    }\n    \n    int L = 200;\n    int W = 100; // Beam width\n    \n    vector<Node> beam;\n    beam.resize(1);\n    beam[0].seq.clear();\n    beam[0].exact_score = 0.0;\n    memset(beam[0].dp, 0, sizeof(beam[0].dp));\n    beam[0].dp[si * 20 + sj] = 1.0;\n    beam[0].value = 0.0;\n    \n    vector<Node> next_beam_candidates;\n    next_beam_candidates.reserve(W * 4);\n    \n    for (int t = 1; t <= L; ++t) {\n        next_beam_candidates.clear();\n        \n        for (auto& node : beam) {\n            for (int dir = 0; dir < 4; ++dir) {\n                Node new_node;\n                new_node.seq = node.seq;\n                new_node.seq.push_back(dirs[dir]);\n                new_node.exact_score = node.exact_score;\n                memset(new_node.dp, 0, sizeof(new_node.dp));\n                \n                double reach_prob = 0.0;\n                double heuristic = 0.0;\n                \n                // Fast inner loop over distribution\n                for (int i = 0; i < 20; ++i) {\n                    for (int j = 0; j < 20; ++j) {\n                        double prob = node.dp[i * 20 + j];\n                        if (prob < 1e-15) continue;\n                        \n                        double move_prob = move_prob_table[i][j][dir];\n                        double stay_prob = stay_prob_table[i][j][dir];\n                        \n                        if (move_prob > 1e-15) {\n                            int ni = i + dr[dir], nj = j + dc[dir];\n                            if (ni == ti && nj == tj) {\n                                reach_prob += prob * move_prob;\n                            } else {\n                                new_node.dp[ni * 20 + nj] += prob * move_prob;\n                            }\n                        }\n                        \n                        if (stay_prob > 1e-15) {\n                            new_node.dp[i * 20 + j] += prob * stay_prob;\n                        }\n                    }\n                }\n                \n                // Exact lower bound score for reaching target\n                new_node.exact_score += reach_prob * reach_score_table[t];\n                \n                // Squared distance heuristic to aggressively pull mass towards target\n                for (int i = 0; i < 20; ++i) {\n                    for (int j = 0; j < 20; ++j) {\n                        if (i == ti && j == tj) continue;\n                        double prob = new_node.dp[i * 20 + j];\n                        if (prob < 1e-15) continue;\n                        heuristic += prob * remaining_sq[t][dist[i][j]];\n                    }\n                }\n                \n                // Balanced scaling between exact achievement and future potential\n                new_node.value = new_node.exact_score * 400.0 + heuristic;\n                next_beam_candidates.push_back(new_node);\n            }\n        }\n        \n        // Keep top W candidates\n        sort(next_beam_candidates.begin(), next_beam_candidates.end(), [](const Node& a, const Node& b) {\n            return a.value > b.value;\n        });\n        \n        int new_W = min(W, (int)next_beam_candidates.size());\n        beam.assign(next_beam_candidates.begin(), next_beam_candidates.begin() + new_W);\n    }\n    \n    cout << string(beam[0].seq.begin(), beam[0].seq.end()) << \"\\n\";\n    \n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <string>\n#include <set>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <ctime>\n\nusing namespace std;\n\nint to_table[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1},\n};\n\nint di[4] = {0, -1, 0, 1};\nint dj[4] = {-1, 0, 1, 0};\n\nint valid_out[8][4];\n\nstruct TraceResult {\n    int len;\n    bool is_cycle;\n    int ret_d;\n};\n\ninline int get_to_fast(int t, int r, int in_d) {\n    int orig_out = to_table[t][(in_d + r) % 4];\n    if (orig_out == -1) return -1;\n    return (orig_out - r + 4) % 4;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Precompute valid_out masks\n    for (int t = 0; t < 8; ++t) {\n        for (int r = 0; r < 4; ++r) {\n            int mask = 0;\n            for (int d = 0; d < 4; ++d) {\n                int orig_out = to_table[t][(d + r) % 4];\n                if (orig_out != -1) {\n                    int out_d = (orig_out - r + 4) % 4;\n                    mask |= (1 << out_d);\n                }\n            }\n            valid_out[t][r] = mask;\n        }\n    }\n\n    vector<int> tiles(900);\n    for (int i = 0; i < 30; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < 30; ++j) {\n            tiles[i * 30 + j] = row[j] - '0';\n        }\n    }\n\n    vector<int> rot(900, 0);\n    \n    // Greedy Initialization\n    for (int i = 0; i < 30; ++i) {\n        for (int j = 0; j < 30; ++j) {\n            int idx = i * 30 + j;\n            int t = tiles[idx];\n            int best_r = 0, best_matches = -1;\n            for (int r = 0; r < 4; ++r) {\n                rot[idx] = r;\n                int matches = 0;\n                if (i > 0) {\n                    int top_idx = (i - 1) * 30 + j;\n                    if ((valid_out[tiles[top_idx]][rot[top_idx]] >> 3) & 1) { \n                        if ((valid_out[t][r] >> 1) & 1) matches++; \n                    }\n                }\n                if (j > 0) {\n                    int left_idx = i * 30 + (j - 1);\n                    if ((valid_out[tiles[left_idx]][rot[left_idx]] >> 2) & 1) { \n                        if ((valid_out[t][r] >> 0) & 1) matches++; \n                    }\n                }\n                if (matches > best_matches) {\n                    best_matches = matches;\n                    best_r = r;\n                }\n            }\n            rot[idx] = best_r;\n        }\n    }\n\n    multiset<int> cycles;\n    int pos_x = 0, pos_y = 0;\n\n    auto trace = [&](int start_x, int start_y, int start_d) -> TraceResult {\n        int cx = start_x, cy = start_y;\n        int curr_in_d = (start_d + 2) % 4;\n        int len = 0;\n        while (true) {\n            int idx = cx * 30 + cy;\n            int out_d = get_to_fast(tiles[idx], rot[idx], curr_in_d);\n            if (out_d == -1) return {len, false, -1};\n            \n            int nx = cx + di[out_d];\n            int ny = cy + dj[out_d];\n            if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30) return {len, false, -1};\n            \n            len++;\n            if (nx == pos_x && ny == pos_y) {\n                return {len, true, out_d};\n            }\n            \n            cx = nx; cy = ny;\n            curr_in_d = (out_d + 2) % 4;\n        }\n    };\n\n    // Initial Evaluation\n    for (int i = 0; i < 30; ++i) {\n        for (int j = 0; j < 30; ++j) {\n            int idx = i * 30 + j;\n            int curr_out_mask = valid_out[tiles[idx]][rot[idx]];\n            for (int d = 0; d < 4; ++d) {\n                if (!(curr_out_mask & (1 << d))) continue;\n                int nx = i + di[d], ny = j + dj[d];\n                if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30) continue;\n                int neighbor_idx = nx * 30 + ny;\n                if (!((valid_out[tiles[neighbor_idx]][rot[neighbor_idx]] >> ((d + 2) % 4)) & 1)) continue;\n                \n                pos_x = i; pos_y = j;\n                TraceResult res = trace(nx, ny, d);\n                if (res.is_cycle && res.ret_d >= d) {\n                    cycles.insert(res.len + 1);\n                }\n            }\n        }\n    }\n\n    long long current_score = 0;\n    if (cycles.size() >= 2) {\n        auto it = cycles.rbegin();\n        current_score = (long long)*it * (long long)*std::next(it);\n    }\n\n    // SA Setup\n    random_device rd;\n    mt19937 rng(rd());\n    uniform_int_distribution<int> rand_tile(0, 899);\n    uniform_int_distribution<int> rand_rot(0, 3);\n    uniform_real_distribution<double> rand_prob(0.0, 1.0);\n\n    auto start_time = clock();\n    double temp = 100000.0;\n    double cool = 0.999995;\n\n    while (clock() - start_time < 1.8 * CLOCKS_PER_SEC) {\n        int idx = rand_tile(rng);\n        int old_r = rot[idx];\n        int new_r = rand_rot(rng);\n        if (old_r == new_r) continue;\n\n        pos_x = idx / 30; pos_y = idx % 30;\n        int t = tiles[idx];\n\n        // Extract old cycles\n        vector<int> old_cycles;\n        int curr_out_mask = valid_out[t][old_r];\n        for (int d = 0; d < 4; ++d) {\n            if (!(curr_out_mask & (1 << d))) continue;\n            int nx = pos_x + di[d], ny = pos_y + dj[d];\n            if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30) continue;\n            int neighbor_idx = nx * 30 + ny;\n            if (!((valid_out[tiles[neighbor_idx]][rot[neighbor_idx]] >> ((d + 2) % 4)) & 1)) continue;\n            \n            TraceResult res = trace(nx, ny, d);\n            if (res.is_cycle && res.ret_d >= d) {\n                old_cycles.push_back(res.len + 1);\n            }\n        }\n\n        for (int c : old_cycles) {\n            auto it = cycles.find(c);\n            if (it != cycles.end()) cycles.erase(it);\n        }\n\n        // Apply new rotation\n        rot[idx] = new_r;\n\n        // Extract new cycles\n        vector<int> new_cycles;\n        curr_out_mask = valid_out[t][new_r];\n        for (int d = 0; d < 4; ++d) {\n            if (!(curr_out_mask & (1 << d))) continue;\n            int nx = pos_x + di[d], ny = pos_y + dj[d];\n            if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30) continue;\n            int neighbor_idx = nx * 30 + ny;\n            if (!((valid_out[tiles[neighbor_idx]][rot[neighbor_idx]] >> ((d + 2) % 4)) & 1)) continue;\n            \n            TraceResult res = trace(nx, ny, d);\n            if (res.is_cycle && res.ret_d >= d) {\n                new_cycles.push_back(res.len + 1);\n            }\n        }\n\n        for (int c : new_cycles) {\n            cycles.insert(c);\n        }\n\n        long long new_score = 0;\n        if (cycles.size() >= 2) {\n            auto it = cycles.rbegin();\n            new_score = (long long)*it * (long long)*std::next(it);\n        }\n\n        // Accept / Reject\n        if (new_score > current_score || exp((new_score - current_score) / temp) > rand_prob(rng)) {\n            current_score = new_score;\n        } else {\n            rot[idx] = old_r;\n            for (int c : new_cycles) {\n                auto it = cycles.find(c);\n                if (it != cycles.end()) cycles.erase(it);\n            }\n            for (int c : old_cycles) {\n                cycles.insert(c);\n            }\n        }\n        temp *= cool;\n    }\n\n    // Output\n    string ans = \"\";\n    for (int i = 0; i < 900; ++i) {\n        ans += (char)('0' + rot[i]);\n    }\n    cout << ans << \"\\n\";\n\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nvector<string> board;\nint ei, ej;\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst char dc[] = {'U', 'D', 'L', 'R'};\nconst int line_mask[] = {2, 8, 1, 4};\nconst int opp_mask[] = {8, 2, 4, 1};\n\nint get_tile(int i, int j) {\n    char c = board[i][j];\n    return (c == '0') ? -1 : ((c >= 'a') ? (c - 'a' + 10) : (c - '0'));\n}\n\nint largest_tree_size() {\n    static bool visited[100];\n    static int comp[100];\n    memset(visited, false, sizeof(visited));\n    int best = 0;\n    for (int si = 0; si < N; si++) {\n        for (int sj = 0; sj < N; sj++) {\n            int idx = si * N + sj;\n            if (visited[idx] || get_tile(si, sj) < 0) continue;\n            queue<int> q;\n            q.push(idx);\n            visited[idx] = true;\n            int size = 0;\n            while (!q.empty()) {\n                int cur = q.front(); q.pop();\n                int ci = cur / N, cj = cur % N;\n                comp[size++] = cur;\n                int t = get_tile(ci, cj);\n                for (int d = 0; d < 4; d++) {\n                    int ni = ci + di[d], nj = cj + dj[d];\n                    if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                    int next = ni * N + nj;\n                    if (visited[next]) continue;\n                    int nt = get_tile(ni, nj);\n                    if (nt < 0) continue;\n                    if ((t & line_mask[d]) && (nt & opp_mask[d])) {\n                        visited[next] = true;\n                        q.push(next);\n                    }\n                }\n            }\n            if (size <= best) continue;\n            int edges = 0;\n            for (int k = 0; k < size; k++) {\n                int ci = comp[k] / N, cj = comp[k] % N;\n                int t = get_tile(ci, cj);\n                if (cj + 1 < N && (t & 4)) {\n                    int nt = get_tile(ci, cj + 1);\n                    if (nt >= 0 && (nt & 1)) edges++;\n                }\n                if (ci + 1 < N && (t & 8)) {\n                    int nt = get_tile(ci + 1, cj);\n                    if (nt >= 0 && (nt & 2)) edges++;\n                }\n            }\n            if (edges == size - 1) best = size;\n        }\n    }\n    return best;\n}\n\nint edge_delta(int d) {\n    int ni = ei + di[d], nj = ej + dj[d];\n    int t = get_tile(ni, nj);\n    int delta = 0;\n    for (int dd = 0; dd < 4; dd++) {\n        int nni = ei + di[dd], nnj = ej + dj[dd];\n        if (nni >= 0 && nni < N && nnj >= 0 && nnj < N) {\n            int nt = get_tile(nni, nnj);\n            if (nt >= 0 && (t & line_mask[dd]) && (nt & opp_mask[dd])) delta++;\n        }\n    }\n    for (int dd = 0; dd < 4; dd++) {\n        int nni = ni + di[dd], nnj = nj + dj[dd];\n        if (nni >= 0 && nni < N && nnj >= 0 && nnj < N) {\n            int nt = get_tile(nni, nnj);\n            if (nt >= 0 && (t & line_mask[dd]) && (nt & opp_mask[dd])) delta--;\n        }\n    }\n    return delta;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> T;\n    board.resize(N);\n    for (int i = 0; i < N; i++) cin >> board[i];\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            if (board[i][j] == '0') { ei = i; ej = j; }\n    \n    string moves;\n    mt19937 rng(42);\n    \n    for (int step = 0; step < T; step++) {\n        int valid[4], vc = 0;\n        for (int d = 0; d < 4; d++) {\n            int ni = ei + di[d], nj = ej + dj[d];\n            if (ni >= 0 && ni < N && nj >= 0 && nj < N) valid[vc++] = d;\n        }\n        \n        int best = valid[0], best_tree = -1, best_delta = -1e9;\n        vector<int> ties;\n        \n        for (int v = 0; v < vc; v++) {\n            int d = valid[v];\n            int ni = ei + di[d], nj = ej + dj[d];\n            if (get_tile(ni, nj) < 0) continue;\n            \n            swap(board[ei][ej], board[ni][nj]);\n            int tree = largest_tree_size();\n            swap(board[ei][ej], board[ni][nj]);\n            int delta = edge_delta(d);\n            \n            if (tree > best_tree || (tree == best_tree && delta > best_delta)) {\n                best_tree = tree;\n                best_delta = delta;\n                best = d;\n                ties = {d};\n            } else if (tree == best_tree && delta == best_delta) {\n                ties.push_back(d);\n            }\n        }\n        \n        best = ties[rng() % ties.size()];\n        int ni = ei + di[best], nj = ej + dj[best];\n        swap(board[ei][ej], board[ni][nj]);\n        ei = ni; ej = nj;\n        moves += dc[best];\n    }\n    cout << moves << endl;\n    return 0;\n}","ahc012":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <numeric>\n#include <unordered_map>\n\nusing namespace std;\n\nstruct PairHash {\n    size_t operator()(const pair<uint64_t, uint64_t>& p) const {\n        return p.first ^ (p.second * 2654435761ULL);\n    }\n};\n\nlong long ext_gcd(long long a, long long b, long long &x, long long &y) {\n    if (b == 0) {\n        x = 1; y = 0; return a;\n    }\n    long long x1, y1;\n    long long g = ext_gcd(b, a % b, x1, y1);\n    x = y1;\n    y = x1 - (a / b) * y1;\n    return g;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N;\n    if (!(cin >> N)) return 0;\n    int K_input;\n    cin >> K_input;\n    const int K = 100;\n    \n    int a[11] = {0};\n    for (int d = 1; d <= 10; d++) cin >> a[d];\n    \n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n    \n    auto rand_int = [](int L, int R) {\n        return L + rand() % (R - L + 1);\n    };\n    \n    vector<int> A(K), B(K);\n    for (int j = 0; j < K; j++) {\n        while (true) {\n            int a = rand_int(-100, 100);\n            int b = rand_int(-100, 100);\n            if (a == 0 && b == 0) continue;\n            if (__gcd(abs(a), abs(b)) == 1) {\n                A[j] = a;\n                B[j] = b;\n                break;\n            }\n        }\n    }\n    \n    vector<vector<pair<int, int>>> sorted_vals(K);\n    for (int j = 0; j < K; j++) {\n        sorted_vals[j].resize(N);\n        for (int i = 0; i < N; i++) {\n            sorted_vals[j][i] = {A[j] * x[i] + B[j] * y[i], i};\n        }\n        sort(sorted_vals[j].begin(), sorted_vals[j].end());\n    }\n    \n    vector<int> C_int(K);\n    for (int j = 0; j < K; j++) {\n        C_int[j] = rand_int(-10000, 10000);\n        bool bad = true;\n        while (bad) {\n            bad = false;\n            for (int i = 0; i < N; i++) {\n                if (A[j] * x[i] + B[j] * y[i] + C_int[j] == 0) {\n                    C_int[j] += rand_int(1, 10);\n                    bad = true;\n                    break;\n                }\n            }\n            if (C_int[j] > 15000) C_int[j] = rand_int(-15000, -10000);\n        }\n    }\n    \n    vector<uint64_t> sig1(N), sig2(N);\n    unordered_map<pair<uint64_t, uint64_t>, int, PairHash> cnt;\n    cnt.reserve(6000);\n    \n    for (int i = 0; i < N; i++) {\n        sig1[i] = 0;\n        sig2[i] = 0;\n        for (int j = 0; j < K; j++) {\n            if (A[j] * x[i] + B[j] * y[i] + C_int[j] > 0) {\n                if (j < 64) sig1[i] |= (1ULL << j);\n                else sig2[i] |= (1ULL << (j - 64));\n            }\n        }\n        cnt[{sig1[i], sig2[i]}]++;\n    }\n    \n    int b[11] = {0};\n    for (auto& p : cnt) {\n        if (p.second <= 10) b[p.second]++;\n    }\n    int current_score = 0;\n    for (int d = 1; d <= 10; d++) current_score += min(a[d], b[d]);\n    \n    int best_score = current_score;\n    vector<int> best_C = C_int;\n    \n    double temp = 10.0;\n    vector<int> flipped;\n    flipped.reserve(100);\n    \n    for (int iter = 0; iter < 10000000; iter++) {\n        temp *= 0.9999995;\n        int step = 400;\n        if (iter > 5000000) step = 150;\n        if (iter > 8000000) step = 40;\n        \n        int j = rand_int(0, K - 1);\n        int delta = rand_int(-step, step);\n        int C_new = C_int[j] + delta;\n        if (C_new > 15000) C_new = 15000;\n        if (C_new < -15000) C_new = -15000;\n        \n        auto& sv = sorted_vals[j];\n        auto it_check = lower_bound(sv.begin(), sv.end(), make_pair(-C_new, -1));\n        if (it_check != sv.end() && it_check->first == -C_new) {\n            continue; // Reject move to avoid slicing a strawberry\n        }\n        \n        if (C_new == C_int[j]) continue;\n        \n        int min_C = min(C_new, C_int[j]);\n        int max_C = max(C_new, C_int[j]);\n        int L_val = -max_C + 1;\n        int R_val = -min_C;\n        \n        auto it_lo = lower_bound(sv.begin(), sv.end(), make_pair(L_val, -1));\n        auto it_hi = upper_bound(sv.begin(), sv.end(), make_pair(R_val, N));\n        \n        flipped.clear();\n        for (auto it = it_lo; it != it_hi; ++it) {\n            flipped.push_back(it->second);\n        }\n        \n        for (int i : flipped) {\n            auto old_sig = make_pair(sig1[i], sig2[i]);\n            int S_old = cnt[old_sig];\n            if (S_old <= 10) b[S_old]--;\n            cnt[old_sig]--;\n            if (cnt[old_sig] > 0 && S_old - 1 <= 10) b[S_old - 1]++;\n            \n            if (j < 64) sig1[i] ^= (1ULL << j);\n            else sig2[i] ^= (1ULL << (j - 64));\n            \n            auto new_sig = make_pair(sig1[i], sig2[i]);\n            int S_new = cnt[new_sig];\n            if (S_new > 0 && S_new <= 10) b[S_new]--;\n            cnt[new_sig]++;\n            if (S_new + 1 <= 10) b[S_new + 1]++;\n        }\n        \n        int new_score = 0;\n        for (int d = 1; d <= 10; d++) new_score += min(a[d], b[d]);\n        \n        int diff = new_score - current_score;\n        if (diff > 0 || (double)rand() / RAND_MAX < exp(diff / temp)) {\n            current_score = new_score;\n            C_int[j] = C_new;\n            if (new_score > best_score) {\n                best_score = new_score;\n                best_C = C_int;\n            }\n        } else {\n            for (int i : flipped) {\n                auto old_sig = make_pair(sig1[i], sig2[i]);\n                int S_old = cnt[old_sig];\n                if (S_old > 0 && S_old <= 10) b[S_old]--;\n                cnt[old_sig]--;\n                if (cnt[old_sig] > 0 && S_old - 1 <= 10) b[S_old - 1]++;\n                \n                if (j < 64) sig1[i] ^= (1ULL << j);\n                else sig2[i] ^= (1ULL << (j - 64));\n                \n                auto new_sig = make_pair(sig1[i], sig2[i]);\n                int S_new = cnt[new_sig];\n                if (S_new <= 10) b[S_new]--;\n                cnt[new_sig]++;\n                if (S_new + 1 <= 10) b[S_new + 1]++;\n            }\n        }\n    }\n    \n    C_int = best_C;\n    \n    cout << K << \"\\n\";\n    for (int j = 0; j < K; j++) {\n        long long x0, y0;\n        ext_gcd(A[j], B[j], x0, y0);\n        \n        long long px1 = -C_int[j] * x0;\n        long long py1 = -C_int[j] * y0;\n        long long px2 = px1 + B[j];\n        long long py2 = py1 - A[j];\n        \n        cout << px1 << \" \" << py1 << \" \" << px2 << \" \" << py2 << \"\\n\";\n    }\n\n    return 0;\n}","ahc014":"","ahc015":"#include <iostream>\n#include <cstring>\n\nusing namespace std;\n\nconst int N = 10;\nint grid[N][N];\n\nvoid tilt(char dir) {\n    if (dir == 'F') {\n        for (int c = 0; c < N; c++) {\n            int w = 0;\n            for (int r = 0; r < N; r++) if (grid[r][c]) { int f = grid[r][c]; grid[r][c] = 0; grid[w++][c] = f; }\n        }\n    } else if (dir == 'B') {\n        for (int c = 0; c < N; c++) {\n            int w = N - 1;\n            for (int r = N - 1; r >= 0; r--) if (grid[r][c]) { int f = grid[r][c]; grid[r][c] = 0; grid[w--][c] = f; }\n        }\n    } else if (dir == 'L') {\n        for (int r = 0; r < N; r++) {\n            int w = 0;\n            for (int c = 0; c < N; c++) if (grid[r][c]) { int f = grid[r][c]; grid[r][c] = 0; grid[r][w++] = f; }\n        }\n    } else {\n        for (int r = 0; r < N; r++) {\n            int w = N - 1;\n            for (int c = N - 1; c >= 0; c--) if (grid[r][c]) { int f = grid[r][c]; grid[r][c] = 0; grid[r][w--] = f; }\n        }\n    }\n}\n\nint computeSumSq() {\n    static int vis[N][N], stk[100];\n    memset(vis, 0, sizeof(vis));\n    int sumSq = 0;\n    const int dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1};\n    for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) if (grid[r][c] && !vis[r][c]) {\n        int sz = 0, f = grid[r][c], top = 0;\n        stk[top++] = r * N + c; vis[r][c] = 1;\n        while (top > 0) {\n            int p = stk[--top], cr = p / N, cc = p % N; sz++;\n            for (int d = 0; d < 4; d++) {\n                int nr = cr + dr[d], nc = cc + dc[d];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N && !vis[nr][nc] && grid[nr][nc] == f) {\n                    vis[nr][nc] = 1; stk[top++] = nr * N + nc;\n                }\n            }\n        }\n        sumSq += sz * sz;\n    }\n    return sumSq;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int flavors[100];\n    for (int i = 0; i < 100; i++) cin >> flavors[i];\n    memset(grid, 0, sizeof(grid));\n    for (int t = 0; t < 100; t++) {\n        int p; cin >> p;\n        int cnt = 0, r = -1, c = -1;\n        for (int i = 0; i < N && r < 0; i++) for (int j = 0; j < N && r < 0; j++) if (!grid[i][j] && ++cnt == p) { r = i; c = j; }\n        grid[r][c] = flavors[t];\n        if (t < 99) {\n            char bestDir = 'F'; int bestScore = -1;\n            for (char dir : {'F', 'B', 'L', 'R'}) {\n                int saved[N][N]; memcpy(saved, grid, sizeof(grid));\n                tilt(dir); int score = computeSumSq(); memcpy(grid, saved, sizeof(grid));\n                if (score > bestScore) { bestScore = score; bestDir = dir; }\n            }\n            tilt(bestDir); cout << bestDir << endl;\n        }\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int M;\n    double eps;\n    cin >> M >> eps;\n    \n    int N;\n    if (eps <= 0.01) N = 8;\n    else if (eps <= 0.03) N = 10;\n    else if (eps <= 0.06) N = 12;\n    else if (eps <= 0.10) N = 16;\n    else if (eps <= 0.15) N = 22;\n    else if (eps <= 0.20) N = 28;\n    else if (eps <= 0.30) N = 40;\n    else if (eps <= 0.40) N = 60;\n    else N = 80;\n    \n    N = max(N, 4);\n    N = min(N, 100);\n    \n    int total_pairs = N * (N - 1) / 2;\n    \n    mt19937 rng(42);\n    \n    vector<string> graphs(M);\n    vector<vector<int>> sorted_deg(M, vector<int>(N));\n    \n    for (int i = 0; i < M; i++) {\n        int num_edges = (int)((i + 0.5) * total_pairs / M);\n        string g(total_pairs, '0');\n        vector<int> indices(total_pairs);\n        iota(indices.begin(), indices.end(), 0);\n        shuffle(indices.begin(), indices.end(), rng);\n        for (int j = 0; j < num_edges; j++) g[indices[j]] = '1';\n        graphs[i] = g;\n        \n        int idx = 0;\n        for (int v = 0; v < N; v++) {\n            for (int u = v + 1; u < N; u++) {\n                if (g[idx++] == '1') {\n                    sorted_deg[i][v]++;\n                    sorted_deg[i][u]++;\n                }\n            }\n        }\n        sort(sorted_deg[i].begin(), sorted_deg[i].end());\n    }\n    \n    cout << N << \"\\n\";\n    for (auto& g : graphs) cout << g << \"\\n\";\n    cout << flush;\n    \n    for (int q = 0; q < 100; q++) {\n        string H;\n        cin >> H;\n        \n        vector<int> h_deg(N);\n        int idx = 0;\n        for (int v = 0; v < N; v++) {\n            for (int u = v + 1; u < N; u++) {\n                if (H[idx++] == '1') {\n                    h_deg[v]++;\n                    h_deg[u]++;\n                }\n            }\n        }\n        sort(h_deg.begin(), h_deg.end());\n        \n        int best = 0;\n        double best_dist = 1e18;\n        for (int i = 0; i < M; i++) {\n            double dist = 0;\n            for (int j = 0; j < N; j++) {\n                double diff = h_deg[j] - sorted_deg[i][j];\n                dist += diff * diff;\n            }\n            if (dist < best_dist) {\n                best_dist = dist;\n                best = i;\n            }\n        }\n        cout << best << \"\\n\" << 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    cin >> N >> M >> D >> K;\n    \n    vector<tuple<int, int, int>> edges(M);\n    vector<vector<pair<int, int>>> adj(N);\n    \n    unsigned long long seed = N * 1000000007ULL + M * 1000003ULL + D * 1009ULL + K;\n    \n    for (int i = 0; i < M; i++) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        u--; v--;\n        edges[i] = {u, v, w};\n        adj[u].push_back({v, i});\n        adj[v].push_back({u, i});\n        seed ^= (unsigned long long)(u + 1) * 1000000007ULL + (v + 1) * 1000003ULL + w;\n    }\n    \n    for (int i = 0; i < N; i++) { int x, y; cin >> x >> y; seed ^= (unsigned long long)x * 10007ULL + y; }\n    \n    vector<long long> betweenness(M, 0);\n    mt19937 rng(seed);\n    int S = min(200, N);\n    vector<int> sources(S);\n    iota(sources.begin(), sources.end(), 0);\n    shuffle(sources.begin(), sources.end(), rng);\n    \n    for (int s : sources) {\n        vector<long long> dist(N, 1e18);\n        vector<int> parent_edge(N, -1);\n        dist[s] = 0;\n        priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> pq;\n        pq.push({0, s});\n        \n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u]) continue;\n            for (auto [v, ei] : adj[u]) {\n                if (dist[u] + get<2>(edges[ei]) < dist[v]) {\n                    dist[v] = dist[u] + get<2>(edges[ei]);\n                    parent_edge[v] = ei;\n                    pq.push({dist[v], v});\n                }\n            }\n        }\n        \n        vector<vector<int>> children(N);\n        for (int v = 0; v < N; v++) {\n            if (parent_edge[v] != -1) {\n                auto [pu, pv, pw] = edges[parent_edge[v]];\n                children[(pu == v) ? pv : pu].push_back(v);\n            }\n        }\n        \n        vector<int> subtree_size(N, 1);\n        function<void(int)> dfs = [&](int u) {\n            for (int v : children[u]) {\n                dfs(v);\n                subtree_size[u] += subtree_size[v];\n            }\n            if (parent_edge[u] != -1) betweenness[parent_edge[u]] += subtree_size[u];\n        };\n        dfs(s);\n    }\n    \n    vector<int> edge_order(M);\n    iota(edge_order.begin(), edge_order.end(), 0);\n    sort(edge_order.begin(), edge_order.end(), [&](int a, int b) {\n        return betweenness[a] > betweenness[b];\n    });\n    \n    vector<int> day_assignment(M, -1), day_count(D, 0);\n    vector<vector<int>> day_edges_list(D);\n    vector<long long> vertex_day_importance(N * D, 0);\n    \n    for (int e : edge_order) {\n        auto [u, v, w] = edges[e];\n        long long imp = betweenness[e];\n        \n        int best_day = -1;\n        long long best_conflict = LLONG_MAX;\n        for (int d = 0; d < D; d++) {\n            if (day_count[d] >= K) continue;\n            long long conflict = vertex_day_importance[u * D + d] + vertex_day_importance[v * D + d];\n            if (conflict < best_conflict) { best_conflict = conflict; best_day = d; }\n        }\n        if (best_day == -1) {\n            for (int d = 0; d < D; d++) {\n                long long conflict = vertex_day_importance[u * D + d] + vertex_day_importance[v * D + d];\n                if (conflict < best_conflict) { best_conflict = conflict; best_day = d; }\n            }\n        }\n        day_assignment[e] = best_day;\n        day_count[best_day]++;\n        day_edges_list[best_day].push_back(e);\n        vertex_day_importance[u * D + best_day] += imp;\n        vertex_day_importance[v * D + best_day] += imp;\n    }\n    \n    double temperature = 500.0;\n    for (int iter = 0; iter < 2000000; iter++) {\n        temperature *= 0.999997;\n        int d1 = rng() % D, d2 = rng() % D;\n        if (d1 == d2 || day_edges_list[d1].empty() || day_edges_list[d2].empty()) continue;\n        \n        int idx1 = rng() % day_edges_list[d1].size(), idx2 = rng() % day_edges_list[d2].size();\n        int e1 = day_edges_list[d1][idx1], e2 = day_edges_list[d2][idx2];\n        auto [u1, v1, w1] = edges[e1];\n        auto [u2, v2, w2] = edges[e2];\n        long long imp1 = betweenness[e1], imp2 = betweenness[e2];\n        \n        long long c1 = vertex_day_importance[u1 * D + d1] + vertex_day_importance[v1 * D + d1] - 2 * imp1;\n        long long c2 = vertex_day_importance[u2 * D + d2] + vertex_day_importance[v2 * D + d2] - 2 * imp2;\n        \n        long long e2_at_u1 = (u2 == u1 || v2 == u1) ? imp2 : 0;\n        long long e2_at_v1 = (u2 == v1 || v2 == v1) ? imp2 : 0;\n        long long e1_at_u2 = (u1 == u2 || v1 == u2) ? imp1 : 0;\n        long long e1_at_v2 = (u1 == v2 || v1 == v2) ? imp1 : 0;\n        \n        long long n1 = vertex_day_importance[u1 * D + d2] + vertex_day_importance[v1 * D + d2] - e2_at_u1 - e2_at_v1;\n        long long n2 = vertex_day_importance[u2 * D + d1] + vertex_day_importance[v2 * D + d1] - e1_at_u2 - e1_at_v2;\n        \n        long long delta = (n1 + n2) - (c1 + c2);\n        \n        if (delta < 0 || (temperature > 0.001 && (double)(rng() % 100000) / 100000.0 < exp(-(double)delta / max(temperature, 1.0)))) {\n            day_assignment[e1] = d2; day_assignment[e2] = d1;\n            vertex_day_importance[u1 * D + d1] -= imp1; vertex_day_importance[v1 * D + d1] -= imp1;\n            vertex_day_importance[u1 * D + d2] += imp1; vertex_day_importance[v1 * D + d2] += imp1;\n            vertex_day_importance[u2 * D + d2] -= imp2; vertex_day_importance[v2 * D + d2] -= imp2;\n            vertex_day_importance[u2 * D + d1] += imp2; vertex_day_importance[v2 * D + d1] += imp2;\n            day_edges_list[d1][idx1] = e2; day_edges_list[d2][idx2] = e1;\n        }\n    }\n    \n    for (int i = 0; i < M; i++) cout << day_assignment[i] + 1 << \" \\n\"[i == M - 1];\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\nusing namespace chrono;\n\nint D, b[2][15][15][15], n, rots[24][3][3], numRots=0;\nset<tuple<int,int,int>> V[2];\nhigh_resolution_clock::time_point start_time;\n\nvoid generateRotations() {\n    set<vector<int>> seen; queue<vector<int>> q;\n    vector<int> id={1,0,0,0,1,0,0,0,1},rx={1,0,0,0,0,-1,0,1,0},ry={0,0,1,0,1,0,-1,0,0},rz={0,-1,0,1,0,0,0,0,1};\n    q.push(id); seen.insert(id);\n    auto mul=[](vector<int> a,vector<int> b){vector<int> c(9);for(int i=0;i<3;i++)for(int j=0;j<3;j++){c[i*3+j]=0;for(int k=0;k<3;k++)c[i*3+j]+=a[i*3+k]*b[k*3+j];}return c;};\n    while(!q.empty()){auto cur=q.front();q.pop();for(int i=0;i<9;i++)rots[numRots][i/3][i%3]=cur[i];numRots++;for(auto&base:{rx,ry,rz}){auto nx=mul(cur,base);if(!seen.count(nx)){seen.insert(nx);q.push(nx);}}}\n}\n\nvoid findComponents(set<tuple<int,int,int>>& V, vector<vector<tuple<int,int,int>>>& comps) {\n    set<tuple<int,int,int>> rem=V; int dx[]={1,-1,0,0,0,0},dy[]={0,0,1,-1,0,0},dz[]={0,0,0,0,1,-1};\n    while(!rem.empty()){auto[sx,sy,sz]=*rem.begin();rem.erase(rem.begin());vector<tuple<int,int,int>> comp;comp.push_back({sx,sy,sz});queue<tuple<int,int,int>> q;q.push({sx,sy,sz});\n    while(!q.empty()){auto[x,y,z]=q.front();q.pop();for(int d=0;d<6;d++){int nx=x+dx[d],ny=y+dy[d],nz=z+dz[d];auto np=make_tuple(nx,ny,nz);if(rem.count(np)){rem.erase(np);comp.push_back(np);q.push(np);}}}comps.push_back(comp);}\n}\n\ntuple<int,int,tuple<int,int,int>> findBestAlignment(set<tuple<int,int,int>>& V0, set<tuple<int,int,int>>& V1) {\n    int best_count=0; tuple<int,int,int> best_trans; int best_rot=-1;\n    for(int rot=0;rot<24;rot++){vector<tuple<int,int,int>> br1;for(auto&[x,y,z]:V1){int bx=rots[rot][0][0]*x+rots[rot][1][0]*y+rots[rot][2][0]*z,by=rots[rot][0][1]*x+rots[rot][1][1]*y+rots[rot][2][1]*z,bz=rots[rot][0][2]*x+rots[rot][1][2]*y+rots[rot][2][2]*z;br1.push_back({bx,by,bz});}\n    map<tuple<int,int,int>,int> tc;for(auto&[x0,y0,z0]:V0)for(auto&[bx,by,bz]:br1)tc[{bx-x0,by-y0,bz-z0}]++;\n    for(auto&[trans,count]:tc)if(count>best_count){best_count=count;auto[tx,ty,tz]=trans;best_trans={rots[rot][0][0]*tx+rots[rot][0][1]*ty+rots[rot][0][2]*tz,rots[rot][1][0]*tx+rots[rot][1][1]*ty+rots[rot][1][2]*tz,rots[rot][2][0]*tx+rots[rot][2][1]*ty+rots[rot][2][2]*tz};best_rot=rot;}}\n    return {best_count,best_rot,best_trans};\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr); start_time=high_resolution_clock::now();\n    generateRotations(); cin>>D; int f[2][15][15],r[2][15][15];\n    for(int i=0;i<2;i++){for(int z=0;z<D;z++){string s;cin>>s;for(int x=0;x<D;x++)f[i][z][x]=s[x]-'0';}for(int z=0;z<D;z++){string s;cin>>s;for(int y=0;y<D;y++)r[i][z][y]=s[y]-'0';}}\n    for(int i=0;i<2;i++)for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++)if(f[i][z][x]&&r[i][z][y])V[i].insert({x,y,z});\n    memset(b,0,sizeof(b)); n=0; set<tuple<int,int,int>> rem[2]={V[0],V[1]};\n    while(!rem[0].empty()&&!rem[1].empty()){if(duration_cast<milliseconds>(high_resolution_clock::now()-start_time).count()>5000)break;\n    auto[count,rot,trans]=findBestAlignment(rem[0],rem[1]); if(count==0)break;\n    set<tuple<int,int,int>> m0;for(auto&[x,y,z]:rem[0]){int rx=rots[rot][0][0]*x+rots[rot][0][1]*y+rots[rot][0][2]*z+get<0>(trans),ry=rots[rot][1][0]*x+rots[rot][1][1]*y+rots[rot][1][2]*z+get<1>(trans),rz=rots[rot][2][0]*x+rots[rot][2][1]*y+rots[rot][2][2]*z+get<2>(trans);if(rem[1].count({rx,ry,rz}))m0.insert({x,y,z});}\n    vector<vector<tuple<int,int,int>>> comps;findComponents(m0,comps);\n    for(auto&comp:comps){n++;for(auto&[x,y,z]:comp){b[0][x][y][z]=n;int rx=rots[rot][0][0]*x+rots[rot][0][1]*y+rots[rot][0][2]*z+get<0>(trans),ry=rots[rot][1][0]*x+rots[rot][1][1]*y+rots[rot][1][2]*z+get<1>(trans),rz=rots[rot][2][0]*x+rots[rot][2][1]*y+rots[rot][2][2]*z+get<2>(trans);b[1][rx][ry][rz]=n;rem[0].erase({x,y,z});rem[1].erase({rx,ry,rz});}}}\n    for(int i=0;i<2;i++)for(auto&[x,y,z]:rem[i]){n++;b[i][x][y][z]=n;}\n    cout<<n<<'\\n';for(int i=0;i<2;i++){string out;for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){if(!out.empty())out+=' ';out+=to_string(b[i][x][y][z]);}cout<<out<<'\\n';}\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\ntypedef long long ll;\n\nstruct EdgeInfo { int to, idx; ll w; };\n\nint min_power(ll d2) {\n    if (d2 <= 0) return 0;\n    int r = (int)sqrt((double)d2);\n    while ((ll)r * r < d2) r++;\n    return r;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K;\n    cin >> N >> M >> K;\n    \n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    \n    vector<tuple<int, int, ll>> edges(M);\n    vector<vector<EdgeInfo>> adj(N);\n    for (int j = 0; j < M; j++) {\n        int u, v; ll w;\n        cin >> u >> v >> w;\n        u--; v--;\n        edges[j] = {u, v, w};\n        adj[u].push_back({v, j, w});\n        adj[v].push_back({u, j, w});\n    }\n    \n    vector<int> a(K), b(K);\n    for (int k = 0; k < K; k++) cin >> a[k] >> b[k];\n    \n    vector<vector<ll>> dist2(K, vector<ll>(N));\n    for (int k = 0; k < K; k++)\n        for (int i = 0; i < N; i++) {\n            ll dx = (ll)(x[i] - a[k]), dy = (ll)(y[i] - b[k]);\n            dist2[k][i] = dx * dx + dy * dy;\n        }\n    \n    vector<int> closest(K);\n    for (int k = 0; k < K; k++) {\n        ll min_d2 = LLONG_MAX; int mv = 0;\n        for (int i = 0; i < N; i++)\n            if (dist2[k][i] <= (ll)5000 * 5000 && dist2[k][i] < min_d2)\n                { min_d2 = dist2[k][i]; mv = i; }\n        closest[k] = mv;\n    }\n    \n    vector<bool> needed(N, false);\n    for (int k = 0; k < K; k++) needed[closest[k]] = true;\n    needed[0] = true;\n    \n    vector<ll> shortest_dist(N, LLONG_MAX);\n    vector<int> prev_edge(N, -1);\n    shortest_dist[0] = 0;\n    priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<>> pq;\n    pq.push({0, 0});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top(); pq.pop();\n        if (d > shortest_dist[u]) continue;\n        for (auto& e : adj[u])\n            if (shortest_dist[u] + e.w < shortest_dist[e.to]) {\n                shortest_dist[e.to] = shortest_dist[u] + e.w;\n                prev_edge[e.to] = e.idx;\n                pq.push({shortest_dist[e.to], e.to});\n            }\n    }\n    \n    vector<bool> edge_used(M, false);\n    for (int i = 0; i < N; i++)\n        if (needed[i] && i != 0) {\n            int v = i;\n            while (v != 0 && prev_edge[v] != -1) {\n                edge_used[prev_edge[v]] = true;\n                int ei = prev_edge[v];\n                v = (get<0>(edges[ei]) == v) ? get<1>(edges[ei]) : get<0>(edges[ei]);\n            }\n        }\n    \n    vector<bool> keep(N, false);\n    keep[0] = true;\n    bool changed = true;\n    while (changed) {\n        changed = false;\n        for (int idx = 0; idx < M; idx++)\n            if (edge_used[idx]) {\n                int u = get<0>(edges[idx]), v = get<1>(edges[idx]);\n                if (keep[u] && !keep[v]) { keep[v] = true; changed = true; }\n                if (keep[v] && !keep[u]) { keep[u] = true; changed = true; }\n            }\n    }\n    \n    vector<int> P(N, 0);\n    for (int k = 0; k < K; k++) {\n        ll min_d2 = LLONG_MAX; int mv = -1;\n        for (int i = 0; i < N; i++)\n            if (keep[i] && dist2[k][i] <= (ll)5000 * 5000 && dist2[k][i] < min_d2)\n                { min_d2 = dist2[k][i]; mv = i; }\n        if (mv != -1) P[mv] = max(P[mv], min_power(min_d2) + 1);\n    }\n    \n    for (int i = 0; i < N; i++) cout << P[i] << \" \\n\"[i == N - 1];\n    for (int j = 0; j < M; j++) cout << edge_used[j] << \" \\n\"[j == M - 1];\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N = 30;\nint grid[30][30];\n\nvoid sift_down(int x, int y, vector<tuple<int,int,int,int>>& ops) {\n    while (x < N - 1 && ops.size() < 10000) {\n        int v = grid[x][y];\n        int c1 = grid[x+1][y];\n        int c2 = grid[x+1][y+1];\n        \n        if (v < c1 && v < c2) break;\n        \n        if (c1 <= c2) {\n            swap(grid[x][y], grid[x+1][y]);\n            ops.push_back({x, y, x+1, y});\n            x++;\n        } else {\n            swap(grid[x][y], grid[x+1][y+1]);\n            ops.push_back({x, y, x+1, y+1});\n            x++;\n            y++;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \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    vector<tuple<int,int,int,int>> ops;\n    \n    for (int pass = 0; pass < 50 && ops.size() < 10000; pass++) {\n        bool changed = false;\n        for (int x = N - 2; x >= 0 && ops.size() < 10000; x--) {\n            for (int y = 0; y <= x && ops.size() < 10000; y++) {\n                int v = grid[x][y];\n                if (v < grid[x+1][y] && v < grid[x+1][y+1]) continue;\n                sift_down(x, y, ops);\n                changed = true;\n            }\n        }\n        if (!changed) break;\n    }\n    \n    cout << ops.size() << \"\\n\";\n    for (auto& [x1, y1, x2, y2] : ops) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << \"\\n\";\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D, N, grid[9][9], container_num[9][9], init_dist[9][9];\nint di[] = {0, 0, 1, -1}, dj[] = {1, -1, 0, 0};\nint entrance_i = 0, entrance_j;\nvector<pair<int,int>> all_cells_sorted;\n\nvoid compute_init_dist() {\n    queue<pair<int,int>> q;\n    memset(init_dist, -1, sizeof(init_dist));\n    init_dist[entrance_i][entrance_j] = 0;\n    q.push({entrance_i, entrance_j});\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int ni = i + di[d], nj = j + dj[d];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && init_dist[ni][nj] == -1 && grid[ni][nj] != 1) {\n                init_dist[ni][nj] = init_dist[i][j] + 1;\n                q.push({ni, nj});\n            }\n        }\n    }\n    for (int i = 0; i < D; i++)\n        for (int j = 0; j < D; j++)\n            if ((i != entrance_i || j != entrance_j) && grid[i][j] != 1)\n                all_cells_sorted.push_back({i, j});\n    sort(all_cells_sorted.begin(), all_cells_sorted.end(), [](auto& a, auto& b) {\n        return tie(init_dist[a.first][a.second], a.first, a.second) < tie(init_dist[b.first][b.second], b.first, b.second);\n    });\n}\n\nvector<pair<int,int>> get_reachable_empty() {\n    vector<pair<int,int>> cells;\n    queue<pair<int,int>> q;\n    int visited[9][9] = {};\n    visited[entrance_i][entrance_j] = 1;\n    q.push({entrance_i, entrance_j});\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        if ((i != entrance_i || j != entrance_j) && grid[i][j] == 0) cells.push_back({i, j});\n        for (int d = 0; d < 4; d++) {\n            int ni = i + di[d], nj = j + dj[d];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && !visited[ni][nj] && grid[ni][nj] == 0) {\n                visited[ni][nj] = 1;\n                q.push({ni, nj});\n            }\n        }\n    }\n    return cells;\n}\n\nvector<pair<int,int>> get_reachable_containers() {\n    vector<pair<int,int>> cells;\n    queue<pair<int,int>> q;\n    int visited[9][9] = {};\n    visited[entrance_i][entrance_j] = 1;\n    q.push({entrance_i, entrance_j});\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int ni = i + di[d], nj = j + dj[d];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && !visited[ni][nj]) {\n                visited[ni][nj] = 1;\n                if (grid[ni][nj] == 2) cells.push_back({ni, nj});\n                else if (grid[ni][nj] == 0) q.push({ni, nj});\n            }\n        }\n    }\n    return cells;\n}\n\npair<int,int> find_placement(int t, int total) {\n    auto cells = get_reachable_empty();\n    if (cells.empty()) return {-1, -1};\n    int ideal_dist = init_dist[all_cells_sorted[t].first][all_cells_sorted[t].second];\n    sort(cells.begin(), cells.end(), [ideal_dist](auto& a, auto& b) {\n        int da = abs(init_dist[a.first][a.second] - ideal_dist);\n        int db = abs(init_dist[b.first][b.second] - ideal_dist);\n        if (da != db) return da < db;\n        int ea = 0, eb = 0;\n        for (int d = 0; d < 4; d++) {\n            int ni = a.first + di[d], nj = a.second + dj[d];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && grid[ni][nj] == 0 && !(ni == entrance_i && nj == entrance_j)) ea++;\n            ni = b.first + di[d]; nj = b.second + dj[d];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && grid[ni][nj] == 0 && !(ni == entrance_i && nj == entrance_j)) eb++;\n        }\n        return tie(ea, a.first, a.second) < tie(eb, b.first, b.second);\n    });\n    return cells[0];\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> D >> N;\n    entrance_j = (D - 1) / 2;\n    memset(grid, 0, sizeof(grid));\n    memset(container_num, -1, sizeof(container_num));\n    for (int i = 0; i < N; i++) { int ri, rj; cin >> ri >> rj; grid[ri][rj] = 1; }\n    int total = D * D - 1 - N;\n    compute_init_dist();\n    for (int d = 0; d < total; d++) {\n        int t; cin >> t;\n        auto [pi, pj] = find_placement(t, total);\n        grid[pi][pj] = 2;\n        container_num[pi][pj] = t;\n        cout << pi << \" \" << pj << \"\\n\" << flush;\n    }\n    for (int d = 0; d < total; d++) {\n        auto containers = get_reachable_containers();\n        int best_num = INT_MAX;\n        pair<int,int> best_pos = {-1, -1};\n        for (auto& [i, j] : containers)\n            if (container_num[i][j] < best_num) { best_num = container_num[i][j]; best_pos = {i, j}; }\n        grid[best_pos.first][best_pos.second] = 0;\n        cout << best_pos.first << \" \" << best_pos.second << \"\\n\" << flush;\n    }\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\nusing namespace std::chrono;\n\nint n, m;\nint grid[50][50];\nset<int> adj_set[101];\nvector<pair<int,int>> color_pos[101];\nint adj_cnt[101][101];\nint boundary_cnt[101];\n\nint dr[] = {0, 0, 1, -1};\nint dc[] = {1, -1, 0, 0};\n\nint vis_gen[50][50];\nint cur_gen = 0;\n\nbool is_connected(int color, int er, int ec) {\n    cur_gen++;\n    int cnt = 0, sr = -1, sc = -1;\n    for (auto& [i, j] : color_pos[color]) {\n        if (grid[i][j] != color || (i == er && j == ec)) continue;\n        if (sr == -1) { sr = i; sc = j; }\n        cnt++;\n    }\n    if (cnt <= 1) return true;\n    queue<pair<int,int>> q;\n    q.push({sr, sc}); vis_gen[sr][sc] = cur_gen; int vc = 1;\n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nr = r + dr[d], nc = c + dc[d];\n            if (nr < 0 || nr >= n || nc < 0 || nc >= n) continue;\n            if (vis_gen[nr][nc] == cur_gen || (nr == er && nc == ec)) continue;\n            if (grid[nr][nc] == color) { vis_gen[nr][nc] = cur_gen; vc++; q.push({nr, nc}); }\n        }\n    }\n    return vc == cnt;\n}\n\nbool can_remove(int r, int c) {\n    int color = grid[r][c];\n    if (color == 0) return false;\n    int same = 0, boundary_here = 0, regular0_here = 0;\n    for (int d = 0; d < 4; d++) {\n        int nr = r + dr[d], nc = c + dc[d];\n        if (nr < 0 || nr >= n || nc < 0 || nc >= n) { boundary_here++; }\n        else {\n            int nb = grid[nr][nc];\n            if (nb == color) same++;\n            else if (nb == 0) regular0_here++;\n            else { if (!adj_set[0].count(nb)) return false; if (adj_cnt[color][nb] <= 1) return false; }\n        }\n    }\n    if (adj_set[color].count(0)) {\n        int remaining = (boundary_cnt[color] - boundary_here) + (adj_cnt[color][0] - regular0_here);\n        if (remaining <= 0) return false;\n    }\n    if (same <= 1) {\n        int cnt = 0;\n        for (auto& [i, j] : color_pos[color]) if (grid[i][j] == color) cnt++;\n        if (cnt <= 1) return false;\n    } else { if (!is_connected(color, r, c)) return false; }\n    return true;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(NULL);\n    auto start_time = high_resolution_clock::now();\n    cin >> n >> m;\n    for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { cin >> grid[i][j]; color_pos[grid[i][j]].push_back({i, j}); }\n    for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) {\n        int color = grid[i][j];\n        for (int d = 0; d < 4; d++) {\n            int nr = i + dr[d], nc = j + dc[d];\n            if (nr < 0 || nr >= n || nc < 0 || nc >= n) { boundary_cnt[color]++; adj_set[color].insert(0); adj_set[0].insert(color); }\n            else if (grid[nr][nc] != color) { int nb = grid[nr][nc]; adj_cnt[color][nb]++; adj_set[color].insert(nb); adj_set[nb].insert(color); }\n        }\n    }\n    bool changed = true;\n    while (changed) {\n        if (duration_cast<milliseconds>(high_resolution_clock::now() - start_time).count() > 1800) break;\n        changed = false;\n        for (int color = 1; color <= m; color++) {\n            vector<tuple<int,int,int>> tiles;\n            for (auto& [i, j] : color_pos[color]) {\n                if (grid[i][j] != color) continue;\n                int same = 0;\n                for (int d = 0; d < 4; d++) { int nr = i + dr[d], nc = j + dc[d]; if (nr >= 0 && nr < n && nc >= 0 && nc < n && grid[nr][nc] == color) same++; }\n                tiles.push_back({same, i, j});\n            }\n            sort(tiles.begin(), tiles.end());\n            for (auto& [_, r, c] : tiles) {\n                if (grid[r][c] != color) continue;\n                if (can_remove(r, c)) {\n                    for (int d = 0; d < 4; d++) {\n                        int nr = r + dr[d], nc = c + dc[d];\n                        if (nr < 0 || nr >= n || nc < 0 || nc >= n) boundary_cnt[color]--;\n                        else { int nb = grid[nr][nc]; if (nb != color) adj_cnt[color][nb]--; }\n                    }\n                    grid[r][c] = 0; changed = true;\n                }\n            }\n        }\n    }\n    for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { cout << grid[i][j]; if (j < n-1) cout << \" \"; } cout << \"\\n\"; }\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <numeric>\n\nusing namespace std;\n\nint N, D, Q;\n\nchar query(int x, int y) {\n    cout << \"1 1 \" << x << \" \" << y << \"\\n\" << flush;\n    char res;\n    cin >> res;\n    return res;\n}\n\nchar dummy_query(int x, int y) {\n    cout << \"1 1 \" << x << \" \" << y << \"\\n\" << flush;\n    char res;\n    cin >> res;\n    return res;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    if (!(cin >> N >> D >> Q)) return 0;\n    \n    vector<vector<int>> adj(N);\n    vector<int> sorted_items;\n    vector<int> unsorted_items;\n    for (int i = 0; i < N; ++i) {\n        unsorted_items.push_back(i);\n    }\n    \n    int q_left = Q;\n    while (q_left > 0) {\n        if (!unsorted_items.empty()) {\n            int x = unsorted_items.back();\n            unsorted_items.pop_back();\n            \n            if (!sorted_items.empty()) {\n                int lo = 0, hi = sorted_items.size();\n                while (lo < hi && q_left > 0) {\n                    int mid = (lo + hi) / 2;\n                    int y = sorted_items[mid];\n                    q_left--;\n                    char res = query(x, y);\n                    if (res == '>') {\n                        // x is heavier than y, goes after y\n                        adj[y].push_back(x);\n                        lo = mid + 1;\n                    } else if (res == '<') {\n                        // x is lighter than y, goes before y\n                        adj[x].push_back(y);\n                        hi = mid;\n                    } else {\n                        break;\n                    }\n                }\n                sorted_items.insert(sorted_items.begin() + lo, x);\n            } else {\n                if (!unsorted_items.empty()) {\n                    int y = unsorted_items.back();\n                    unsorted_items.pop_back();\n                    q_left--;\n                    char res = query(x, y);\n                    if (res == '>') {\n                        adj[y].push_back(x);\n                        sorted_items.push_back(y);\n                        sorted_items.push_back(x);\n                    } else if (res == '<') {\n                        adj[x].push_back(y);\n                        sorted_items.push_back(x);\n                        sorted_items.push_back(y);\n                    } else {\n                        sorted_items.push_back(x);\n                        sorted_items.push_back(y);\n                    }\n                } else {\n                    sorted_items.push_back(x);\n                }\n            }\n        } else {\n            // We exhausted items to sort but must fulfill the exact Q query quota\n            dummy_query(0, 1);\n            q_left--;\n        }\n    }\n    \n    // Append remaining unqueried items\n    for (int x : unsorted_items) {\n        sorted_items.push_back(x);\n    }\n    \n    // Compute longest path from sources in the DAG using Kahn's algorithm\n    vector<int> in_degree(N, 0);\n    for (int i = 0; i < N; ++i) {\n        for (int j : adj[i]) {\n            in_degree[j]++;\n        }\n    }\n    \n    queue<int> q;\n    for (int i = 0; i < N; ++i) {\n        if (in_degree[i] == 0) q.push(i);\n    }\n    \n    vector<int> dp(N, 0);\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : adj[u]) {\n            if (dp[v] < dp[u] + 1) {\n                dp[v] = dp[u] + 1;\n            }\n            in_degree[v]--;\n            if (in_degree[v] == 0) {\n                q.push(v);\n            }\n        }\n    }\n    \n    // Sort all items by their longest path value (ascending)\n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n    sort(items.begin(), items.end(), [&](int a, int b) {\n        if (dp[a] != dp[b]) return dp[a] < dp[b];\n        return a < b;\n    });\n    \n    // Map ranks to expected weights of exponential distribution order statistics\n    double W_max = 100000.0 * N / D;\n    vector<double> expected_w(N);\n    double sum = 0;\n    for (int i = 0; i < N; ++i) {\n        sum += 100000.0 / (N - i);\n        expected_w[i] = min(sum, W_max);\n    }\n    \n    // Greedy partitioning based on expected weights\n    vector<double> set_sums(D, 0);\n    vector<int> partition(N);\n    double total_sum = accumulate(expected_w.begin(), expected_w.end(), 0.0);\n    double target_sum = total_sum / D;\n    \n    // Process from largest expected weight to smallest\n    for (int i = N - 1; i >= 0; --i) {\n        int item = items[i];\n        double w = expected_w[i];\n        \n        int best_set = -1;\n        double max_deficit = 0;\n        for (int j = 0; j < D; ++j) {\n            double deficit = target_sum - set_sums[j];\n            if (deficit > max_deficit) {\n                max_deficit = deficit;\n                best_set = j;\n            }\n        }\n        \n        // Fallback if all sets exceed the target sum\n        if (best_set == -1) {\n            best_set = 0;\n            for (int j = 1; j < D; ++j) {\n                if (set_sums[j] < set_sums[best_set]) {\n                    best_set = j;\n                }\n            }\n        }\n        \n        set_sums[best_set] += w;\n        partition[item] = best_set;\n    }\n    \n    // Output the final division mapping\n    for (int i = 0; i < N; ++i) {\n        cout << partition[i] << (i == N - 1 ? \"\" : \" \");\n    }\n    cout << \"\\n\" << flush;\n    \n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> stacks(m);\n    vector<int> pos(n + 1), idx(n + 1);\n    \n    for (int i = 0; i < m; i++) {\n        stacks[i].resize(n / m);\n        for (int j = 0; j < n / m; j++) {\n            cin >> stacks[i][j];\n            pos[stacks[i][j]] = i;\n            idx[stacks[i][j]] = j;\n        }\n    }\n    \n    vector<bool> isClean(m, true);\n    for (int i = 0; i < m; i++) {\n        for (int j = 0; j < (int)stacks[i].size() - 1; j++) {\n            if (stacks[i][j] < stacks[i][j + 1]) { isClean[i] = false; break; }\n        }\n    }\n    \n    vector<pair<int, int>> operations;\n    int nextBox = 1;\n    \n    while (nextBox <= n) {\n        int si = pos[nextBox], pi = idx[nextBox];\n        \n        if (pi == (int)stacks[si].size() - 1) {\n            operations.push_back({nextBox, 0});\n            stacks[si].pop_back();\n            nextBox++;\n        } else {\n            vector<int> seq(stacks[si].begin() + pi + 1, stacks[si].end());\n            \n            vector<int> splitAfter;\n            for (int i = 0; i < (int)seq.size() - 1; i++) {\n                if (seq[i] < seq[i + 1]) splitAfter.push_back(i);\n            }\n            \n            vector<vector<int>> pieces;\n            int start = 0;\n            for (int sp : splitAfter) {\n                pieces.push_back(vector<int>(seq.begin() + start, seq.begin() + sp + 1));\n                start = sp + 1;\n            }\n            pieces.push_back(vector<int>(seq.begin() + start, seq.end()));\n            reverse(pieces.begin(), pieces.end());\n            \n            for (auto& piece : pieces) {\n                int moveFrom = piece[0];\n                int origStack = pos[moveFrom];\n                \n                int bestDest = -1, bestScore = -1e9;\n                for (int i = 0; i < m; i++) {\n                    if (i == origStack) continue;\n                    int score;\n                    if (stacks[i].empty()) score = 100;\n                    else if (isClean[i] && stacks[i].back() >= moveFrom) score = 300 + stacks[i].back();\n                    else if (!isClean[i] && stacks[i].back() >= moveFrom) score = 150 + stacks[i].back();\n                    else score = -50;\n                    if (score > bestScore || (score == bestScore && bestDest != -1 && stacks[i].size() < stacks[bestDest].size())) {\n                        bestScore = score; bestDest = i;\n                    }\n                }\n                \n                bool wasEmpty = stacks[bestDest].empty();\n                bool wasCleanDest = isClean[bestDest];\n                int oldBack = wasEmpty ? -1 : stacks[bestDest].back();\n                bool compatible = wasEmpty || (oldBack >= moveFrom);\n                \n                operations.push_back({moveFrom, bestDest + 1});\n                \n                int origIdx = idx[moveFrom];\n                for (int j = origIdx; j < (int)stacks[origStack].size(); j++) {\n                    int v = stacks[origStack][j];\n                    stacks[bestDest].push_back(v);\n                    pos[v] = bestDest;\n                    idx[v] = stacks[bestDest].size() - 1;\n                }\n                stacks[origStack].resize(origIdx);\n                \n                isClean[bestDest] = wasEmpty ? true : (wasCleanDest && compatible);\n            }\n        }\n    }\n    \n    for (auto& op : operations) cout << op.first << \" \" << op.second << \"\\n\";\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\nint di[] = {0, 1, 0, -1};\nint dj[] = {1, 0, -1, 0};\nchar dc[] = \"RDLU\";\nvector<vector<pair<int,int>>> parent;\nvector<vector<int>> pd;\n\nbool can_move(int i, int j, int dir) {\n    int ni = i + di[dir], nj = j + dj[dir];\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    if (dir == 0) return v[i][j] == '0';\n    if (dir == 1) return h[i][j] == '0';\n    if (dir == 2) return v[i][nj] == '0';\n    return h[ni][j] == '0';\n}\n\nstring find_path(int si, int sj, int ti, int tj) {\n    if (si == ti && sj == tj) return \"\";\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) { parent[i][j] = {-1, -1}; pd[i][j] = -1; }\n    queue<pair<int,int>> q;\n    q.push({si, sj}); parent[si][sj] = {si, sj};\n    while (!q.empty()) {\n        auto [ci, cj] = q.front(); q.pop();\n        if (ci == ti && cj == tj) break;\n        for (int dir = 0; dir < 4; dir++) {\n            if (can_move(ci, cj, dir)) {\n                int ni = ci + di[dir], nj = cj + dj[dir];\n                if (parent[ni][nj].first == -1) {\n                    parent[ni][nj] = {ci, cj}; pd[ni][nj] = dir; q.push({ni, nj});\n                }\n            }\n        }\n    }\n    string path; int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        path += dc[(pd[ci][cj] + 2) % 4];\n        auto [pi, pj] = parent[ci][cj]; ci = pi; cj = pj;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N;\n    h.resize(N-1); v.resize(N);\n    for (int i = 0; i < N-1; i++) cin >> h[i];\n    for (int i = 0; i < N; i++) cin >> v[i];\n    d.resize(N, vector<int>(N));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cin >> d[i][j];\n    \n    parent.assign(N, vector<pair<int,int>>(N, {-1, -1}));\n    pd.assign(N, vector<int>(N, -1));\n    \n    vector<pair<int, pair<int,int>>> cells;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cells.push_back({d[i][j], {i, j}});\n    sort(cells.rbegin(), cells.rend());\n    \n    string route; int cur_i = 0, cur_j = 0;\n    const int MAX_LEN = 100000, RESERVE = N * N * 2;\n    \n    for (auto& [val, pos] : cells) {\n        auto [ti, tj] = pos;\n        route += find_path(cur_i, cur_j, ti, tj);\n        cur_i = ti; cur_j = tj;\n    }\n    \n    int top_k = max(1, (int)cells.size() / 5);\n    while (route.size() < MAX_LEN - RESERVE) {\n        for (int idx = 0; idx < top_k && route.size() < MAX_LEN - RESERVE; idx++) {\n            auto [ti, tj] = cells[idx].second;\n            string path = find_path(cur_i, cur_j, ti, tj);\n            if (route.size() + path.size() > MAX_LEN - RESERVE) break;\n            route += path; cur_i = ti; cur_j = tj;\n        }\n    }\n    route += find_path(cur_i, cur_j, 0, 0);\n    cout << route << endl;\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n, m, si, sj;\nchar grid[16][16];\nstring words[205];\nint cx[26][16][16], cy[26][16][16], cd[26][16][16];\n\nconst int MAXN = 1100;\nint trie[MAXN][26], fail_link[MAXN], node_cnt;\nvector<int> out[MAXN];\n\nvoid insert(const string& s, int id) {\n    int cur = 0;\n    for (char c : s) {\n        int ch = c - 'A';\n        if (!trie[cur][ch]) trie[cur][ch] = ++node_cnt;\n        cur = trie[cur][ch];\n    }\n    out[cur].push_back(id);\n}\n\nvoid build() {\n    queue<int> q;\n    for (int c = 0; c < 26; c++) {\n        if (trie[0][c]) { fail_link[trie[0][c]] = 0; q.push(trie[0][c]); }\n        else trie[0][c] = 0;\n    }\n    while (!q.empty()) {\n        int v = q.front(); q.pop();\n        for (int c = 0; c < 26; c++) {\n            if (trie[v][c]) {\n                fail_link[trie[v][c]] = trie[fail_link[v]][c];\n                for (int id : out[fail_link[trie[v][c]]]) out[trie[v][c]].push_back(id);\n                q.push(trie[v][c]);\n            } else trie[v][c] = trie[fail_link[v]][c];\n        }\n    }\n}\n\nbool was[MAXN][205]; int overlap[MAXN][205];\nvoid precompute() {\n    for (int st = 0; st <= node_cnt; st++) {\n        for (int id : out[st]) was[st][id] = true;\n        for (int w = 0; w < m; w++) {\n            int cur = st, need = 0; bool found = false;\n            for (int i = 0; i < 5; i++) {\n                cur = trie[cur][words[w][i]-'A']; need++;\n                if (was[cur][w]) { found = true; break; }\n            }\n            overlap[st][w] = found ? need : 6;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> n >> m >> si >> sj;\n    for (int i = 0; i < n; i++) { string r; cin >> r; for (int j = 0; j < n; j++) grid[i][j] = r[j]; }\n    for (int i = 0; i < m; i++) { cin >> words[i]; insert(words[i], i); }\n    build(); precompute();\n    const int INF = 1e9;\n    for (int c = 0; c < 26; c++) for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) {\n        cd[c][i][j] = INF;\n        for (int x = 0; x < n; x++) for (int y = 0; y < n; y++) if (grid[x][y] == 'A'+c) {\n            int d = abs(i-x)+abs(j-y); if (d < cd[c][i][j]) { cd[c][i][j]=d; cx[c][i][j]=x; cy[c][i][j]=y; }\n        }\n    }\n    int ci=si, cj=sj, st=0, done_cnt=0; vector<bool> done(m,false); vector<pair<int,int>> ops;\n    while (done_cnt < m && (int)ops.size() < 5000) {\n        int bw=-1, bc=INF;\n        for (int w = 0; w < m; w++) { if (done[w]) continue; int need=overlap[st][w]; if (need>5) continue;\n            int cost=0, ti=ci, tj=cj; for (int i = 0; i < need; i++) { int c=words[w][5-need+i]-'A';\n                if (cd[c][ti][tj]>=INF) { cost=INF; break; } cost+=cd[c][ti][tj]+1; ti=cx[c][ti][tj]; tj=cy[c][ti][tj]; }\n            if (cost<bc) { bc=cost; bw=w; } }\n        if (bw<0) { bc=INF; for (int w = 0; w < m; w++) { if (done[w]) continue; int cost=0, ti=ci, tj=cj;\n            for (int i = 0; i < 5; i++) { int c=words[w][i]-'A'; if (cd[c][ti][tj]>=INF) { cost=INF; break; }\n                cost+=cd[c][ti][tj]+1; ti=cx[c][ti][tj]; tj=cy[c][ti][tj]; } if (cost<bc) { bc=cost; bw=w; } }\n            if (bw<0) break; for (int i = 0; i < 5; i++) { int c=words[bw][i]-'A', ni=cx[c][ci][cj], nj=cy[c][ci][cj];\n                ops.push_back({ni,nj}); ci=ni; cj=nj; st=trie[st][c]; for (int id:out[st]) if (!done[id]) { done[id]=true; done_cnt++; } } }\n        else { int need=overlap[st][bw]; for (int i = 0; i < need; i++) { int c=words[bw][5-need+i]-'A', ni=cx[c][ci][cj], nj=cy[c][ci][cj];\n            ops.push_back({ni,nj}); ci=ni; cj=nj; st=trie[st][c]; for (int id:out[st]) if (!done[id]) { done[id]=true; done_cnt++; } } }\n    }\n    for (auto& [x,y] : ops) cout << x << \" \" << y << \"\\n\";\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M; double eps;\n    cin >> N >> M >> eps;\n    \n    vector<vector<pair<int,int>>> norm_fields(M);\n    vector<int> field_w(M), field_h(M);\n    for (int k = 0; k < M; k++) {\n        int d; cin >> d;\n        vector<pair<int,int>> raw(d);\n        int mi = N, mj = N;\n        for (int i = 0; i < d; i++) {\n            cin >> raw[i].first >> raw[i].second;\n            mi = min(mi, raw[i].first);\n            mj = min(mj, raw[i].second);\n        }\n        for (int i = 0; i < d; i++) {\n            norm_fields[k].push_back({raw[i].first - mi, raw[i].second - mj});\n            field_w[k] = max(field_w[k], raw[i].first - mi);\n            field_h[k] = max(field_h[k], raw[i].second - mj);\n        }\n    }\n    \n    vector<vector<int>> known(N, vector<int>(N, -1));\n    vector<pair<int,int>> has_oil;\n    \n    auto drill = [&](int i, int j) -> int {\n        if (known[i][j] != -1) return known[i][j];\n        cout << \"q 1 \" << i << \" \" << j << \"\\n\" << flush;\n        int r; cin >> r;\n        known[i][j] = r;\n        if (r > 0) has_oil.push_back({i, j});\n        return r;\n    };\n    \n    auto divine = [&](vector<pair<int,int>> &sq) -> int {\n        if (sq.size() < 2) return -1;\n        cout << \"q \" << sq.size();\n        for (auto [i, j] : sq) cout << \" \" << i << \" \" << j;\n        cout << \"\\n\" << flush;\n        int r; cin >> r;\n        return r;\n    };\n    \n    int bs = (N >= 15) ? 7 : 5;\n    int nbi = (N + bs - 1) / bs, nbj = (N + bs - 1) / bs;\n    vector<vector<bool>> skip(nbi, vector<bool>(nbj, false));\n    \n    for (int bi = 0; bi < nbi; bi++) for (int bj = 0; bj < nbj; bj++) {\n        vector<pair<int,int>> blk;\n        for (int i = bi*bs; i < min(N,(bi+1)*bs); i++)\n            for (int j = bj*bs; j < min(N,(bj+1)*bs); j++)\n                blk.push_back({i, j});\n        if (blk.size() < 2) continue;\n        if (divine(blk) == 0) skip[bi][bj] = true;\n    }\n    \n    for (int bi = 0; bi < nbi; bi++) for (int bj = 0; bj < nbj; bj++) {\n        if (skip[bi][bj]) continue;\n        for (int i = bi*bs; i < min(N,(bi+1)*bs); i++)\n            for (int j = bj*bs; j < min(N,(bj+1)*bs); j++)\n                drill(i, j);\n    }\n    \n    for (int iter = 0; iter < 3 && !has_oil.empty(); iter++) {\n        vector<vector<int>> cnt(N, vector<int>(N, 0));\n        for (int k = 0; k < M; k++) {\n            for (int di = 0; di <= N - 1 - field_w[k]; di++) {\n                for (int dj = 0; dj <= N - 1 - field_h[k]; dj++) {\n                    bool ok = true;\n                    for (auto [si, sj] : norm_fields[k])\n                        if (known[di+si][dj+sj] == 0) { ok = false; break; }\n                    if (!ok) continue;\n                    for (auto [si, sj] : norm_fields[k])\n                        if (known[di+si][dj+sj] == -1) cnt[di+si][dj+sj]++;\n                }\n            }\n        }\n        vector<pair<int,pair<int,int>>> todo;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++)\n            if (cnt[i][j] > 0) todo.push_back({-cnt[i][j], {i, j}});\n        sort(todo.begin(), todo.end());\n        for (auto [_, p] : todo) drill(p.first, p.second);\n    }\n    \n    cout << \"a \" << has_oil.size();\n    for (auto [i, j] : has_oil) cout << \" \" << i << \" \" << j;\n    cout << \"\\n\" << flush;\n    int resp; cin >> resp;\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W, D, N;\n    cin >> W >> D >> N;\n    \n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) cin >> a[d][k];\n    }\n    \n    if (N == 1) {\n        for (int d = 0; d < D; d++) cout << \"0 0 \" << W << \" \" << W << \"\\n\";\n        return 0;\n    }\n    \n    auto get_sorted_req = [&](int d) {\n        vector<int> req(N);\n        for (int k = 0; k < N; k++) req[k] = (a[d][k] + W - 1) / W;\n        sort(req.begin(), req.end());\n        return req;\n    };\n    \n    auto compute_parts = [&](const vector<int>& req) {\n        vector<int> parts(N-1);\n        long long cum = 0;\n        for (int k = 0; k < N-1; k++) {\n            cum += req[k];\n            parts[k] = (int)min(cum, (long long)(W - (N - 1 - k)));\n        }\n        for (int k = 1; k < N-1; k++)\n            if (parts[k] <= parts[k-1]) parts[k] = parts[k-1] + 1;\n        return parts;\n    };\n    \n    auto compute_deficit = [&](const vector<int>& parts, const vector<int>& req) {\n        vector<int> h(N);\n        h[0] = parts[0];\n        for (int k = 1; k < N-1; k++) h[k] = parts[k] - parts[k-1];\n        h[N-1] = W - parts[N-2];\n        long long def = 0;\n        for (int k = 0; k < N; k++) def += max(0, req[k] - h[k]);\n        return def;\n    };\n    \n    auto change_cost = [&](const vector<int>& p1, const vector<int>& p2) {\n        set<int> s1(p1.begin(), p1.end()), s2(p2.begin(), p2.end());\n        vector<int> diff;\n        set_symmetric_difference(s1.begin(), s1.end(), s2.begin(), s2.end(), back_inserter(diff));\n        return (long long)diff.size() * W;\n    };\n    \n    auto output = [&](const vector<int>& parts) {\n        for (int k = 0; k < N; k++) {\n            int s = k == 0 ? 0 : parts[k-1];\n            int e = k < N-1 ? parts[k] : W;\n            cout << s << \" 0 \" << e << \" \" << W << \"\\n\";\n        }\n    };\n    \n    vector<int> parts = compute_parts(get_sorted_req(0));\n    output(parts);\n    \n    for (int d = 1; d < D; d++) {\n        auto req = get_sorted_req(d);\n        long long cost_keep = compute_deficit(parts, req) * 100;\n        auto new_parts = compute_parts(req);\n        long long cost_change = change_cost(parts, new_parts) + compute_deficit(new_parts, req) * 100;\n        if (cost_change < cost_keep) parts = new_parts;\n        output(parts);\n    }\n    \n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <algorithm>\n\nusing namespace std;\n\nconst int P = 998244353;\nint N, M, K;\nvector<vector<int>> T_mod;\nvector<vector<vector<int>>> S;\nvector<long long> sum_S;\n\nlong long best_gain_at_pos[7][7];\nint best_m_at_pos[7][7];\n\nvoid update_pos(int p, int q) {\n    long long best_g = -1;\n    int best_m = 0;\n    int t00 = T_mod[p][q], t01 = T_mod[p][q+1], t02 = T_mod[p][q+2];\n    int t10 = T_mod[p+1][q], t11 = T_mod[p+1][q+1], t12 = T_mod[p+1][q+2];\n    int t20 = T_mod[p+2][q], t21 = T_mod[p+2][q+1], t22 = T_mod[p+2][q+2];\n    \n    for (int m = 0; m < M; ++m) {\n        int overflow = 0;\n        if (S[m][0][0] && t00 + S[m][0][0] >= P) overflow++;\n        if (S[m][0][1] && t01 + S[m][0][1] >= P) overflow++;\n        if (S[m][0][2] && t02 + S[m][0][2] >= P) overflow++;\n        if (S[m][1][0] && t10 + S[m][1][0] >= P) overflow++;\n        if (S[m][1][1] && t11 + S[m][1][1] >= P) overflow++;\n        if (S[m][1][2] && t12 + S[m][1][2] >= P) overflow++;\n        if (S[m][2][0] && t20 + S[m][2][0] >= P) overflow++;\n        if (S[m][2][1] && t21 + S[m][2][1] >= P) overflow++;\n        if (S[m][2][2] && t22 + S[m][2][2] >= P) overflow++;\n        \n        long long gain = sum_S[m] - (long long)P * overflow;\n        if (gain > best_g) {\n            best_g = gain;\n            best_m = m;\n        }\n    }\n    best_gain_at_pos[p][q] = best_g;\n    best_m_at_pos[p][q] = best_m;\n}\n\nvoid update_affected(int p_old, int q_old) {\n    for (int p = max(0, p_old - 2); p <= min(6, p_old + 2); ++p) {\n        for (int q = max(0, q_old - 2); q <= min(6, q_old + 2); ++q) {\n            update_pos(p, q);\n        }\n    }\n}\n\nvoid update_all() {\n    for (int p = 0; p <= 6; ++p)\n        for (int q = 0; q <= 6; ++q)\n            update_pos(p, q);\n}\n\nvoid apply_stamp(int m, int p, int q) {\n    if (S[m][0][0]) { int s = T_mod[p][q] + S[m][0][0]; T_mod[p][q] = s >= P ? s - P : s; }\n    if (S[m][0][1]) { int s = T_mod[p][q+1] + S[m][0][1]; T_mod[p][q+1] = s >= P ? s - P : s; }\n    if (S[m][0][2]) { int s = T_mod[p][q+2] + S[m][0][2]; T_mod[p][q+2] = s >= P ? s - P : s; }\n    if (S[m][1][0]) { int s = T_mod[p+1][q] + S[m][1][0]; T_mod[p+1][q] = s >= P ? s - P : s; }\n    if (S[m][1][1]) { int s = T_mod[p+1][q+1] + S[m][1][1]; T_mod[p+1][q+1] = s >= P ? s - P : s; }\n    if (S[m][1][2]) { int s = T_mod[p+1][q+2] + S[m][1][2]; T_mod[p+1][q+2] = s >= P ? s - P : s; }\n    if (S[m][2][0]) { int s = T_mod[p+2][q] + S[m][2][0]; T_mod[p+2][q] = s >= P ? s - P : s; }\n    if (S[m][2][1]) { int s = T_mod[p+2][q+1] + S[m][2][1]; T_mod[p+2][q+1] = s >= P ? s - P : s; }\n    if (S[m][2][2]) { int s = T_mod[p+2][q+2] + S[m][2][2]; T_mod[p+2][q+2] = s >= P ? s - P : s; }\n}\n\nvoid remove_stamp(int m, int p, int q) {\n    if (S[m][0][0]) { int t = T_mod[p][q]; T_mod[p][q] = t >= S[m][0][0] ? t - S[m][0][0] : t + P - S[m][0][0]; }\n    if (S[m][0][1]) { int t = T_mod[p][q+1]; T_mod[p][q+1] = t >= S[m][0][1] ? t - S[m][0][1] : t + P - S[m][0][1]; }\n    if (S[m][0][2]) { int t = T_mod[p][q+2]; T_mod[p][q+2] = t >= S[m][0][2] ? t - S[m][0][2] : t + P - S[m][0][2]; }\n    if (S[m][1][0]) { int t = T_mod[p+1][q]; T_mod[p+1][q] = t >= S[m][1][0] ? t - S[m][1][0] : t + P - S[m][1][0]; }\n    if (S[m][1][1]) { int t = T_mod[p+1][q+1]; T_mod[p+1][q+1] = t >= S[m][1][1] ? t - S[m][1][1] : t + P - S[m][1][1]; }\n    if (S[m][1][2]) { int t = T_mod[p+1][q+2]; T_mod[p+1][q+2] = t >= S[m][1][2] ? t - S[m][1][2] : t + P - S[m][1][2]; }\n    if (S[m][2][0]) { int t = T_mod[p+2][q]; T_mod[p+2][q] = t >= S[m][2][0] ? t - S[m][2][0] : t + P - S[m][2][0]; }\n    if (S[m][2][1]) { int t = T_mod[p+2][q+1]; T_mod[p+2][q+1] = t >= S[m][2][1] ? t - S[m][2][1] : t + P - S[m][2][1]; }\n    if (S[m][2][2]) { int t = T_mod[p+2][q+2]; T_mod[p+2][q+2] = t >= S[m][2][2] ? t - S[m][2][2] : t + P - S[m][2][2]; }\n}\n\nlong long compute_gain(int m, int p, int q) {\n    int overflow = 0;\n    if (S[m][0][0] && T_mod[p][q] + S[m][0][0] >= P) overflow++;\n    if (S[m][0][1] && T_mod[p][q+1] + S[m][0][1] >= P) overflow++;\n    if (S[m][0][2] && T_mod[p][q+2] + S[m][0][2] >= P) overflow++;\n    if (S[m][1][0] && T_mod[p+1][q] + S[m][1][0] >= P) overflow++;\n    if (S[m][1][1] && T_mod[p+1][q+1] + S[m][1][1] >= P) overflow++;\n    if (S[m][1][2] && T_mod[p+1][q+2] + S[m][1][2] >= P) overflow++;\n    if (S[m][2][0] && T_mod[p+2][q] + S[m][2][0] >= P) overflow++;\n    if (S[m][2][1] && T_mod[p+2][q+1] + S[m][2][1] >= P) overflow++;\n    if (S[m][2][2] && T_mod[p+2][q+2] + S[m][2][2] >= P) overflow++;\n    return sum_S[m] - (long long)P * overflow;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> N >> M >> K)) return 0;\n\n    T_mod.assign(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> T_mod[i][j];\n\n    S.assign(M, vector<vector<int>>(3, vector<int>(3)));\n    sum_S.assign(M, 0);\n    for (int m = 0; m < M; ++m) {\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                cin >> S[m][i][j];\n                sum_S[m] += S[m][i][j];\n            }\n        }\n    }\n\n    vector<tuple<int, int, int>> ops;\n    \n    // Greedy Phase\n    update_all();\n    for (int step = 0; step < K; ++step) {\n        long long best_gain = 0;\n        int best_p = -1, best_q = -1;\n        for (int p = 0; p <= 6; ++p) {\n            for (int q = 0; q <= 6; ++q) {\n                if (best_gain_at_pos[p][q] > best_gain) {\n                    best_gain = best_gain_at_pos[p][q];\n                    best_p = p; best_q = q;\n                }\n            }\n        }\n        if (best_gain <= 0) break;\n        \n        int best_m = best_m_at_pos[best_p][best_q];\n        ops.emplace_back(best_m, best_p, best_q);\n        apply_stamp(best_m, best_p, best_q);\n        update_affected(best_p, best_q);\n    }\n\n    // Local Search Phase\n    bool improved = true;\n    int max_ls_iters = 50;\n    while (improved && max_ls_iters-- > 0) {\n        improved = false;\n        update_all(); \n        \n        long long best_improvement = 0;\n        int best_idx = -1;\n        int ls_best_m = -1, ls_best_p = -1, ls_best_q = -1;\n        bool ls_is_removal = false;\n\n        for (int idx = 0; idx < ops.size(); ++idx) {\n            auto& [m_old, p_old, q_old] = ops[idx];\n            \n            remove_stamp(m_old, p_old, q_old);\n            update_affected(p_old, q_old);\n            \n            long long max_gain_new = 0;\n            int b_m = -1, b_p = -1, b_q = -1;\n            for (int p = 0; p <= 6; ++p) {\n                for (int q = 0; q <= 6; ++q) {\n                    if (best_gain_at_pos[p][q] > max_gain_new) {\n                        max_gain_new = best_gain_at_pos[p][q];\n                        b_m = best_m_at_pos[p][q];\n                        b_p = p; b_q = q;\n                    }\n                }\n            }\n            \n            long long gain_A = compute_gain(m_old, p_old, q_old);\n            long long max_gain_eff = std::max(0LL, max_gain_new);\n            long long improvement = max_gain_eff - gain_A;\n            \n            apply_stamp(m_old, p_old, q_old);\n            \n            if (improvement > best_improvement) {\n                best_improvement = improvement;\n                best_idx = idx;\n                ls_is_removal = (max_gain_new <= 0);\n                ls_best_m = b_m; ls_best_p = b_p; ls_best_q = b_q;\n                if (best_improvement > 0) improved = true;\n            }\n        }\n        \n        // Try adding\n        if (ops.size() < K) {\n            long long max_gain_new = 0;\n            int b_m = -1, b_p = -1, b_q = -1;\n            for (int p = 0; p <= 6; ++p) {\n                for (int q = 0; q <= 6; ++q) {\n                    if (best_gain_at_pos[p][q] > max_gain_new) {\n                        max_gain_new = best_gain_at_pos[p][q];\n                        b_m = best_m_at_pos[p][q];\n                        b_p = p; b_q = q;\n                    }\n                }\n            }\n            if (max_gain_new > best_improvement) {\n                best_improvement = max_gain_new;\n                best_idx = -1; \n                ls_is_removal = false;\n                ls_best_m = b_m; ls_best_p = b_p; ls_best_q = b_q;\n                improved = true;\n            }\n        }\n        \n        if (best_improvement > 0) {\n            if (best_idx != -1) {\n                auto& [m_old, p_old, q_old] = ops[best_idx];\n                remove_stamp(m_old, p_old, q_old);\n                update_affected(p_old, q_old);\n                \n                if (!ls_is_removal) {\n                    ops[best_idx] = {ls_best_m, ls_best_p, ls_best_q};\n                    apply_stamp(ls_best_m, ls_best_p, ls_best_q);\n                    update_affected(ls_best_p, ls_best_q);\n                } else {\n                    ops.erase(ops.begin() + best_idx);\n                }\n            } else {\n                ops.emplace_back(ls_best_m, ls_best_p, ls_best_q);\n                apply_stamp(ls_best_m, ls_best_p, ls_best_q);\n                update_affected(ls_best_p, ls_best_q);\n            }\n        }\n    }\n\n    cout << ops.size() << \"\\n\";\n    for (auto& [m, p, q] : ops) {\n        cout << m << \" \" << p << \" \" << q << \"\\n\";\n    }\n\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 5;\nint A[N][N], cont_row[25], cont_order[25];\nint grid[N][N], crx, cry, cr_held, recv_idx[N], next_dispatch[N];\nbool cr_carry, dispatched[25];\nstring cmds[N];\n\npair<int,int> find_cont(int id) {\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++)\n        if (grid[i][j] == id) return {i, j};\n    return {-1, -1};\n}\n\nint find_empty(int r, int mode) {\n    for (int j = 1; j < N-1; j++) if (grid[r][j] == -1) return j;\n    if (mode >= 1 && recv_idx[r] >= N && grid[r][0] == -1) return 0;\n    if (mode >= 2 && grid[r][N-1] == -1) return N-1;\n    return -1;\n}\n\nvoid move_to(int tx, int ty, char& a) {\n    if (crx < tx) a = 'D'; else if (crx > tx) a = 'U';\n    else if (cry < ty) a = 'R'; else if (cry > ty) a = 'L'; else a = '.';\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        cin >> A[i][j]; cont_row[A[i][j]] = A[i][j] / N; cont_order[A[i][j]] = A[i][j] % N;\n    }\n    memset(grid, -1, sizeof(grid)); crx = cry = 0; cr_carry = false; cr_held = -1;\n    memset(recv_idx, 0, sizeof(recv_idx)); memset(dispatched, false, sizeof(dispatched));\n    memset(next_dispatch, 0, sizeof(next_dispatch));\n    int target = -1;\n    for (int turn = 0; turn < 10000; turn++) {\n        for (int i = 0; i < N; i++) if (recv_idx[i] < N && grid[i][0] == -1 && !(crx == i && cry == 0 && cr_carry))\n            grid[i][0] = A[i][recv_idx[i]++];\n        char act[N]; fill(act, act + N, '.');\n        if (turn == 0) { for (int i = 1; i < N; i++) act[i] = 'R'; act[0] = 'D'; }\n        else if (turn == 1) { for (int i = 1; i < N; i++) act[i] = 'B'; }\n        else {\n            bool all_recv = true; for (int i = 0; i < N; i++) if (recv_idx[i] < N) all_recv = false;\n            if (!cr_carry) {\n                if (!all_recv) {\n                    int bx = -1, by = -1, bd = 1000;\n                    for (int i = 0; i < N; i++) if (grid[i][0] != -1) { int d = abs(i-crx)+abs(cry); if (d < bd) { bd = d; bx = i; by = 0; } }\n                    if (bx < 0) for (int i = 0; i < N; i++) for (int j = 1; j < N-1; j++) if (grid[i][j] != -1) { int d = abs(i-crx)+abs(j-cry); if (d < bd) { bd = d; bx = i; by = j; } }\n                    if (bx >= 0) { if (crx == bx && cry == by) { act[0] = 'P'; target = grid[bx][by]; } else move_to(bx, by, act[0]); }\n                } else {\n                    int best_cid = -1, best_d = 1000;\n                    for (int r = 0; r < N; r++) while (next_dispatch[r] < N) {\n                        int cid = r * N + next_dispatch[r]; auto [cx, cy] = find_cont(cid);\n                        if (cx >= 0) { int d = abs(cx-crx)+abs(cy-cry); if (d < best_d) { best_d = d; best_cid = cid; } break; } else next_dispatch[r]++;\n                    }\n                    if (best_cid >= 0) { auto [cx, cy] = find_cont(best_cid); if (crx == cx && cry == cy) { act[0] = 'P'; target = best_cid; } else move_to(cx, cy, act[0]); }\n                }\n            } else {\n                int tr = cont_row[target];\n                if (!all_recv) { int ty = find_empty(tr, 0); if (ty < 0) ty = find_empty(tr, 1); if (ty < 0) ty = find_empty(tr, 2); if (ty >= 0) { if (crx == tr && cry == ty) act[0] = 'Q'; else move_to(tr, ty, act[0]); } }\n                else { if (crx == tr && cry == N-1) act[0] = 'Q'; else move_to(tr, N-1, act[0]); }\n            }\n        }\n        for (int i = 0; i < N; i++) cmds[i] += act[i];\n        if (act[0] == 'P') { cr_held = grid[crx][cry]; grid[crx][cry] = -1; cr_carry = true; }\n        else if (act[0] == 'Q') { grid[crx][cry] = cr_held; cr_held = -1; cr_carry = false; }\n        else if (act[0] == 'U') crx--; else if (act[0] == 'D') crx++; else if (act[0] == 'L') cry--; else if (act[0] == 'R') cry++;\n        for (int i = 0; i < N; i++) if (grid[i][N-1] != -1) { int c = grid[i][N-1]; dispatched[c] = true; grid[i][N-1] = -1; if (i == cont_row[c] && cont_order[c] == next_dispatch[i]) next_dispatch[i]++; }\n        bool done = true; for (int i = 0; i < 25; i++) if (!dispatched[i]) { done = false; break; } if (done) break;\n    }\n    for (int i = 0; i < N; i++) cout << cmds[i] << endl;\n    return 0;\n}","ahc034":"#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;\n    cin >> N;\n    vector<vector<int>> h(N, vector<int>(N));\n    set<pair<int, int>> unvisited;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            cin >> h[i][j];\n            if (h[i][j] != 0) unvisited.insert({i, j});\n        }\n    \n    vector<string> ops;\n    int load = 0;\n    int ci = 0, cj = 0;\n    \n    auto move_to = [&](int ti, int tj) {\n        while (ci < ti) { ops.push_back(\"D\"); ci++; }\n        while (ci > ti) { ops.push_back(\"U\"); ci--; }\n        while (cj < tj) { ops.push_back(\"R\"); cj++; }\n        while (cj > tj) { ops.push_back(\"L\"); cj--; }\n    };\n    \n    while (!unvisited.empty()) {\n        int best_i = -1, best_j = -1;\n        double best_score = 1e18;\n        \n        int radius = 12;\n        for (int ni = max(0, ci - radius); ni <= min(N-1, ci + radius); ni++) {\n            for (int nj = max(0, cj - radius); nj <= min(N-1, cj + radius); nj++) {\n                if (unvisited.find({ni, nj}) == unvisited.end()) continue;\n                \n                int dist = abs(ci - ni) + abs(cj - nj);\n                double s = dist * 100.0 + load * dist;\n                if (load > 50 && h[ni][nj] < 0) {\n                    s -= min((long long)load, (long long)-h[ni][nj]) * 8.0;\n                }\n                if (load < -50 && h[ni][nj] > 0) {\n                    s -= min((long long)-load, (long long)h[ni][nj]) * 8.0;\n                }\n                if (s < best_score) {\n                    best_score = s;\n                    best_i = ni;\n                    best_j = nj;\n                }\n            }\n        }\n        \n        if (best_i == -1) {\n            for (auto [ni, nj] : unvisited) {\n                int dist = abs(ci - ni) + abs(cj - nj);\n                double s = dist * 100.0 + load * dist;\n                if (s < best_score) {\n                    best_score = s;\n                    best_i = ni;\n                    best_j = nj;\n                }\n            }\n        }\n        \n        move_to(best_i, best_j);\n        \n        if (h[best_i][best_j] > 0) {\n            ops.push_back(\"+\" + to_string(h[best_i][best_j]));\n            load += h[best_i][best_j];\n        } else {\n            ops.push_back(\"-\" + to_string(-h[best_i][best_j]));\n            load -= h[best_i][best_j];\n        }\n        \n        unvisited.erase({best_i, best_j});\n    }\n    \n    cout << ops.size() << \"\\n\";\n    for (const auto& op : ops) cout << op << \"\\n\";\n    \n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, T;\n    cin >> N >> M >> T;\n\n    const int seed_count = 2 * N * (N - 1);\n    const int grid_size = N * N;\n    vector<vector<int>> X(seed_count, vector<int>(M, 0));\n    vector<int> V(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    const int dr[] = {-1, 1, 0, 0};\n    const int dc[] = {0, 0, -1, 1};\n    vector<vector<int>> nbrs(grid_size);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int pos = i * N + j;\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dr[d], nj = j + dc[d];\n                if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                    nbrs[pos].push_back(ni * N + nj);\n                }\n            }\n        }\n    }\n\n    mt19937 rng(12345);\n\n    for (int t = 0; t < T; t++) {\n        vector<vector<int>> allEP(seed_count, vector<int>(seed_count, 0));\n        for (int i = 0; i < seed_count; i++) {\n            for (int j = i + 1; j < seed_count; j++) {\n                int s = 0;\n                for (int l = 0; l < M; l++) s += max(X[i][l], X[j][l]);\n                allEP[i][j] = allEP[j][i] = s;\n            }\n        }\n        \n        vector<pair<int,int>> pairs;\n        for (int i = 0; i < seed_count; i++) {\n            for (int j = i + 1; j < seed_count; j++) {\n                pairs.push_back({allEP[i][j], i * seed_count + j});\n            }\n        }\n        sort(pairs.rbegin(), pairs.rend());\n        \n        vector<int> selected;\n        vector<bool> used(seed_count, false);\n        \n        int pairsAdded = 0;\n        for (auto& [pot, encoded] : pairs) {\n            if (pairsAdded >= 12) break;\n            int a = encoded / seed_count, b = encoded % seed_count;\n            if (!used[a] && !used[b]) {\n                selected.push_back(a);\n                selected.push_back(b);\n                used[a] = used[b] = true;\n                pairsAdded++;\n            }\n        }\n        \n        while ((int)selected.size() < grid_size) {\n            int bestSeed = -1, bestScore = -1;\n            for (int s = 0; s < seed_count; s++) {\n                if (used[s]) continue;\n                int maxPot = 0;\n                for (int sel : selected) {\n                    maxPot = max(maxPot, allEP[s][sel]);\n                }\n                int score = maxPot * 10000 + V[s];\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestSeed = s;\n                }\n            }\n            selected.push_back(bestSeed);\n            used[bestSeed] = true;\n        }\n        \n        vector<int> perm = selected;\n        \n        int bestLocalI = 0, bestLocalJ = 0, bestLocalPot = 0;\n        for (int i = 0; i < grid_size; i++) {\n            for (int j = i + 1; j < grid_size; j++) {\n                if (allEP[perm[i]][perm[j]] > bestLocalPot) {\n                    bestLocalPot = allEP[perm[i]][perm[j]];\n                    bestLocalI = i;\n                    bestLocalJ = j;\n                }\n            }\n        }\n        swap(perm[0], perm[bestLocalI]);\n        if (bestLocalJ == 0) bestLocalJ = bestLocalI;\n        swap(perm[1], perm[bestLocalJ]);\n        \n        vector<vector<int>> ep(grid_size, vector<int>(grid_size, 0));\n        for (int i = 0; i < grid_size; i++) {\n            for (int j = i + 1; j < grid_size; j++) {\n                ep[i][j] = ep[j][i] = allEP[perm[i]][perm[j]];\n            }\n        }\n        \n        long long totalScore = 0;\n        for (int i = 0; i < grid_size; i++) {\n            for (int j : nbrs[i]) {\n                if (j > i) totalScore += ep[i][j];\n            }\n        }\n        \n        double temp = 500.0;\n        double cooling = 0.9999;\n        uniform_real_distribution<double> dist(0.0, 1.0);\n        \n        for (int iter = 0; iter < 280000; iter++) {\n            int p1 = rng() % grid_size;\n            int p2 = rng() % grid_size;\n            if (p1 == p2) continue;\n            \n            int delta = 0;\n            for (int nb : nbrs[p1]) {\n                if (nb != p2) delta += ep[p2][nb] - ep[p1][nb];\n            }\n            for (int nb : nbrs[p2]) {\n                if (nb != p1) delta += ep[p1][nb] - ep[p2][nb];\n            }\n            \n            double acceptProb = delta >= 0 ? 1.0 : exp(delta / temp);\n            if (dist(rng) < acceptProb) {\n                totalScore += delta;\n                swap(perm[p1], perm[p2]);\n                swap(ep[p1], ep[p2]);\n                for (int k = 0; k < grid_size; k++) {\n                    swap(ep[k][p1], ep[k][p2]);\n                }\n            }\n            temp *= cooling;\n        }\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << perm[i * N + j];\n                if (j < N - 1) cout << \" \";\n                else cout << \"\\n\";\n            }\n        }\n        cout.flush();\n\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    }\n\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint dx[] = {0, 1, 0, -1};\nint dy[] = {1, 0, -1, 0};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, V;\n    cin >> N >> M >> V;\n    \n    vector<string> s(N), t(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    cout << V << \"\\n\";\n    for (int i = 1; i < V; i++) cout << 0 << \" \" << 1 << \"\\n\";\n    \n    int rx = 0, ry = 0;\n    cout << rx << \" \" << ry << \"\\n\";\n    \n    vector<int> dir(V, 0);\n    for (int i = 1; i < V; i++) dir[i] = (i - 1) % 4;\n    \n    vector<bool> holding(V, false);\n    \n    set<pair<int,int>> sources, dests;\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') sources.insert({i, j});\n            if (s[i][j] == '0' && t[i][j] == '1') dests.insert({i, j});\n        }\n    \n    auto inGrid = [&](int x, int y) { return 0 <= x && x < N && 0 <= y && y < N; };\n    \n    string S1(V * 2, '.');\n    for (int i = 1; i < V; i++) {\n        if (dir[i] == 1) S1[i] = 'R';\n        else if (dir[i] == 2) S1[i] = 'R';\n        else if (dir[i] == 3) S1[i] = 'L';\n    }\n    \n    string S2(V * 2, '.');\n    for (int i = 1; i < V; i++) if (dir[i] == 2) S2[i] = 'R';\n    \n    int initialTurns = 0;\n    if (S1.find_first_not_of('.') != string::npos) { cout << S1 << \"\\n\"; initialTurns++; }\n    if (S2.find_first_not_of('.') != string::npos) { cout << S2 << \"\\n\"; initialTurns++; }\n    \n    auto fpos = [&](int i) { return make_pair(rx + dx[dir[i]], ry + dy[dir[i]]); };\n    \n    int maxTurns = 100000 - initialTurns;\n    for (int turn = 0; turn < maxTurns && (!sources.empty() || !dests.empty()); turn++) {\n        string S(V * 2, '.');\n        \n        bool canAct = false;\n        for (int i = 1; i < V; i++) {\n            auto [fx, fy] = fpos(i);\n            if (!inGrid(fx, fy)) continue;\n            if ((holding[i] && dests.count({fx, fy})) || (!holding[i] && sources.count({fx, fy}))) {\n                canAct = true; break;\n            }\n        }\n        \n        if (!canAct) {\n            for (int i = 1; i < V && !canAct; i++) {\n                for (int rot : {1, 3}) {\n                    int newDir = (dir[i] + rot) % 4;\n                    int fx = rx + dx[newDir], fy = ry + dy[newDir];\n                    if (inGrid(fx, fy) && ((holding[i] && dests.count({fx, fy})) || (!holding[i] && sources.count({fx, fy})))) {\n                        S[i] = rot == 1 ? 'R' : 'L';\n                        dir[i] = newDir;\n                        canAct = true; break;\n                    }\n                }\n            }\n        }\n        \n        if (!canAct) {\n            int minDist = INT_MAX;\n            pair<int,int> target = {-1, -1};\n            \n            for (auto [x, y] : sources)\n                for (int d = 0; d < 4; d++) {\n                    int nx = x - dx[d], ny = y - dy[d];\n                    if (inGrid(nx, ny)) {\n                        int dist = abs(nx - rx) + abs(ny - ry);\n                        if (nx == rx && ny == ry) dist += 1000;\n                        if (dist < minDist) { minDist = dist; target = {nx, ny}; }\n                    }\n                }\n            \n            for (auto [x, y] : dests)\n                for (int d = 0; d < 4; d++) {\n                    int nx = x - dx[d], ny = y - dy[d];\n                    if (inGrid(nx, ny)) {\n                        int dist = abs(nx - rx) + abs(ny - ry);\n                        if (nx == rx && ny == ry) dist += 1000;\n                        if (dist < minDist) { minDist = dist; target = {nx, ny}; }\n                    }\n                }\n            \n            if (target.first == -1) break;\n            \n            int tx = target.first, ty = target.second;\n            if (rx < tx) { S[0] = 'D'; rx++; }\n            else if (rx > tx) { S[0] = 'U'; rx--; }\n            else if (ry < ty) { S[0] = 'R'; ry++; }\n            else if (ry > ty) { S[0] = 'L'; ry--; }\n        }\n        \n        for (int i = 1; i < V; i++) {\n            auto [fx, fy] = fpos(i);\n            if (!inGrid(fx, fy)) continue;\n            if (holding[i] && dests.count({fx, fy})) {\n                S[V + i] = 'P'; holding[i] = false; dests.erase({fx, fy});\n            } else if (!holding[i] && sources.count({fx, fy})) {\n                S[V + i] = 'P'; holding[i] = true; sources.erase({fx, fy});\n            }\n        }\n        cout << S << \"\\n\";\n    }\n    return 0;\n}","ahc039":"#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;\n    cin >> N;\n    \n    vector<int> mx(N), my(N), sx(N), sy(N);\n    for (int i = 0; i < N; i++) cin >> mx[i] >> my[i];\n    for (int i = 0; i < N; i++) cin >> sx[i] >> sy[i];\n    \n    const int GRID = 100, CELL = 1001;\n    auto cell = [](int x) { return min(x / CELL, GRID - 1); };\n    \n    vector<vector<int>> grid(GRID, vector<int>(GRID, 0));\n    for (int i = 0; i < N; i++) grid[cell(mx[i])][cell(my[i])]++;\n    for (int i = 0; i < N; i++) grid[cell(sx[i])][cell(sy[i])]--;\n    \n    int best = 0, bx1 = 0, bx2 = 0, by1 = 0, by2 = 0;\n    for (int x1 = 0; x1 < GRID; x1++) {\n        vector<int> col(GRID, 0);\n        for (int x2 = x1; x2 < GRID; x2++) {\n            for (int y = 0; y < GRID; y++) col[y] += grid[x2][y];\n            int cur = 0, start = 0;\n            for (int y = 0; y < GRID; y++) {\n                if (cur <= 0) { cur = col[y]; start = y; }\n                else cur += col[y];\n                if (cur > best) { best = cur; bx1 = x1; bx2 = x2; by1 = start; by2 = y; }\n            }\n        }\n    }\n    \n    if (best <= 0) { cout << \"4\\n0 0\\n1000 0\\n1000 1000\\n0 1000\\n\"; return 0; }\n    \n    int cx1 = bx1 * CELL, cy1 = by1 * CELL;\n    int cx2 = min((bx2 + 1) * CELL, 100000), cy2 = min((by2 + 1) * CELL, 100000);\n    \n    set<int> x_set, y_set;\n    for (int i = 0; i < 2*N; i++) {\n        int x = (i < N) ? mx[i] : sx[i], y = (i < N) ? my[i] : sy[i];\n        if (x >= cx1 && x <= cx2) { x_set.insert(max(0,x-1)); x_set.insert(x); x_set.insert(min(100000,x+1)); }\n        if (y >= cy1 && y <= cy2) { y_set.insert(max(0,y-1)); y_set.insert(y); y_set.insert(min(100000,y+1)); }\n    }\n    x_set.insert(cx1); x_set.insert(cx2); y_set.insert(cy1); y_set.insert(cy2);\n    \n    vector<int> all_x(x_set.begin(), x_set.end()), all_y(y_set.begin(), y_set.end());\n    int nx = all_x.size(), ny = all_y.size();\n    \n    const int MAX_SZ = 250;\n    if (nx > MAX_SZ) { vector<int> t; for (int i = 0; i < nx; i += (nx+MAX_SZ-1)/MAX_SZ) t.push_back(all_x[i]); t.push_back(all_x.back()); all_x = t; nx = all_x.size(); }\n    if (ny > MAX_SZ) { vector<int> t; for (int i = 0; i < ny; i += (ny+MAX_SZ-1)/MAX_SZ) t.push_back(all_y[i]); t.push_back(all_y.back()); all_y = t; ny = all_y.size(); }\n    \n    vector<vector<int>> fg(nx, vector<int>(ny, 0));\n    for (int i = 0; i < N; i++) { int xi = lower_bound(all_x.begin(),all_x.end(),mx[i])-all_x.begin(), yi = lower_bound(all_y.begin(),all_y.end(),my[i])-all_y.begin(); if (xi<nx && yi<ny && all_x[xi]==mx[i] && all_y[yi]==my[i]) fg[xi][yi]++; }\n    for (int i = 0; i < N; i++) { int xi = lower_bound(all_x.begin(),all_x.end(),sx[i])-all_x.begin(), yi = lower_bound(all_y.begin(),all_y.end(),sy[i])-all_y.begin(); if (xi<nx && yi<ny && all_x[xi]==sx[i] && all_y[yi]==sy[i]) fg[xi][yi]--; }\n    \n    int fb = 0, fx1 = 0, fx2 = 0, fy1 = 0, fy2 = 0;\n    for (int x1 = 0; x1 < nx; x1++) {\n        vector<int> col(ny, 0);\n        for (int x2 = x1; x2 < nx; x2++) {\n            for (int y = 0; y < ny; y++) col[y] += fg[x2][y];\n            int cur = 0, start = 0;\n            for (int y = 0; y < ny; y++) { if (cur <= 0) { cur = col[y]; start = y; } else cur += col[y]; if (cur > fb) { fb = cur; fx1 = x1; fx2 = x2; fy1 = start; fy2 = y; } }\n        }\n    }\n    \n    int ax1 = max(0, all_x[fx1]), ay1 = max(0, all_y[fy1]);\n    int ax2 = min(100000, all_x[fx2]), ay2 = min(100000, all_y[fy2]);\n    if (ax2 <= ax1) ax2 = ax1 + 1; if (ay2 <= ay1) ay2 = ay1 + 1;\n    \n    cout << 4 << \"\\n\" << ax1 << \" \" << ay1 << \"\\n\" << ax2 << \" \" << ay1 << \"\\n\" << ax2 << \" \" << ay2 << \"\\n\" << ax1 << \" \" << ay2 << \"\\n\";\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nmt19937 rng(42);\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, T;\n    double sigma;\n    cin >> N >> T >> sigma;\n    \n    vector<double> w(N), h(N);\n    for (int i = 0; i < N; i++) {\n        int wo, ho;\n        cin >> wo >> ho;\n        w[i] = wo;\n        h[i] = ho;\n    }\n    \n    double w_ratio = 1.0, h_ratio = 1.0;\n    \n    for (int t = 0; t < T; t++) {\n        vector<double> aw(N), ah(N);\n        for (int i = 0; i < N; i++) {\n            aw[i] = w[i] * w_ratio;\n            ah[i] = h[i] * h_ratio;\n        }\n        \n        vector<tuple<double,double,double,double,int>> placed;\n        \n        auto find_y = [&](double x, double ww) -> double {\n            double y = 0;\n            for (auto& [px,py,pw,ph,idx] : placed)\n                if (px < x+ww && x < px+pw) y = max(y, py+ph);\n            return y;\n        };\n        \n        auto find_x = [&](double y, double hh) -> double {\n            double x = 0;\n            for (auto& [px,py,pw,ph,idx] : placed)\n                if (py < y+hh && y < py+ph) x = max(x, px+pw);\n            return x;\n        };\n        \n        auto get_ref_x = [&](int idx) -> double {\n            for (auto& [px,py,pw,ph,i] : placed) if (i==idx) return px+pw;\n            return 0.0;\n        };\n        \n        auto get_ref_y = [&](int idx) -> double {\n            for (auto& [px,py,pw,ph,i] : placed) if (i==idx) return py+ph;\n            return 0.0;\n        };\n        \n        vector<tuple<int,int,char,int>> placement;\n        int strategy = t % 5;\n        double skip_mult = (strategy == 3) ? 0.92 : (strategy == 4) ? 1.08 : 1.0;\n        \n        for (int i = 0; i < N; i++) {\n            vector<tuple<double,int,char,int>> options;\n            \n            for (int rot = 0; rot < 2; rot++) {\n                double rw = rot ? ah[i] : aw[i], rh = rot ? aw[i] : ah[i];\n                \n                auto try_place = [&](double x, double y, char d, int b) {\n                    double W = x+rw, H = y+rh;\n                    for (auto& [px,py,pw,ph,idx] : placed) { W = max(W,px+pw); H = max(H,py+ph); }\n                    options.emplace_back(W+H, rot, d, b);\n                };\n                \n                try_place(0, find_y(0,rw), 'U', -1);\n                for (auto& [px,py,pw,ph,idx] : placed)\n                    try_place(px+pw, find_y(px+pw,rw), 'U', idx);\n                try_place(find_x(0,rh), 0, 'L', -1);\n                for (auto& [px,py,pw,ph,idx] : placed)\n                    try_place(find_x(py+ph,rh), py+ph, 'L', idx);\n            }\n            \n            sort(options.begin(), options.end());\n            options.erase(unique(options.begin(), options.end()), options.end());\n            \n            double cur_W = 0, cur_H = 0;\n            for (auto& [px,py,pw,ph,idx] : placed) { cur_W = max(cur_W, px+pw); cur_H = max(cur_H, py+ph); }\n            \n            double skip_penalty = (aw[i] + ah[i]) * skip_mult;\n            if (options.empty() || cur_W + cur_H + skip_penalty < get<0>(options[0])) continue;\n            \n            int choice = 0;\n            if (strategy == 1 && options.size() > 1) {\n                for (int j = 0; j < options.size(); j++)\n                    if (get<2>(options[j]) == 'U') { choice = j; break; }\n            } else if (strategy == 2 && options.size() > 1) {\n                for (int j = 0; j < options.size(); j++)\n                    if (get<2>(options[j]) == 'L') { choice = j; break; }\n            } else if (strategy == 4 && options.size() > 2) {\n                uniform_int_distribution<int> dist(0, min(2, (int)options.size()-1));\n                choice = dist(rng);\n            }\n            \n            auto& [score, rot, d, b] = options[choice];\n            double rw = rot ? ah[i] : aw[i], rh = rot ? aw[i] : ah[i];\n            double x, y;\n            if (d == 'U') { x = b==-1 ? 0 : get_ref_x(b); y = find_y(x,rw); }\n            else { y = b==-1 ? 0 : get_ref_y(b); x = find_x(y,rh); }\n            placed.emplace_back(x, y, rw, rh, i);\n            placement.emplace_back(i, rot, d, b);\n        }\n        \n        cout << placement.size() << \"\\n\";\n        for (auto& [p,r,d,b] : placement) cout << p << \" \" << r << \" \" << d << \" \" << b << \"\\n\";\n        cout.flush();\n        \n        int W_meas, H_meas;\n        cin >> W_meas >> H_meas;\n        \n        double W_exp = 0, H_exp = 0;\n        for (auto& [px,py,pw,ph,idx] : placed) { W_exp = max(W_exp,px+pw); H_exp = max(H_exp,py+ph); }\n        \n        if (W_exp > 0 && H_exp > 0 && !placed.empty()) {\n            double wr = W_meas / W_exp;\n            double hr = H_meas / H_exp;\n            double alpha = 0.25 / (1 + t * 0.05);\n            w_ratio = w_ratio * (1-alpha) + wr * alpha;\n            h_ratio = h_ratio * (1-alpha) + hr * alpha;\n        }\n    }\n    \n    return 0;\n}","ahc041":"#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, H;\n    cin >> N >> M >> H;\n    \n    vector<int> A(N);\n    for (int i = 0; i < N; i++) cin >> A[i];\n    \n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    \n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    \n    vector<vector<int>> dist_mat(N, vector<int>(N, H + 1));\n    for (int s = 0; s < N; s++) {\n        dist_mat[s][s] = 0;\n        queue<int> q;\n        q.push(s);\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int v : adj[u]) {\n                if (dist_mat[s][v] == H + 1) {\n                    dist_mat[s][v] = dist_mat[s][u] + 1;\n                    q.push(v);\n                }\n            }\n        }\n    }\n    \n    vector<bitset<1000>> cover(N);\n    for (int v = 0; v < N; v++) {\n        for (int u = 0; u < N; u++) {\n            if (dist_mat[v][u] <= H) cover[v].set(u);\n        }\n    }\n    \n    auto is_valid = [&](const vector<bool>& is_root) -> bool {\n        bitset<1000> covered;\n        for (int v = 0; v < N; v++) {\n            if (is_root[v]) covered |= cover[v];\n        }\n        return covered.count() == N;\n    };\n    \n    auto compute_score = [&](const vector<bool>& is_root) -> long long {\n        long long score = 0;\n        for (int v = 0; v < N; v++) {\n            int min_d = H + 1;\n            if (is_root[v]) {\n                min_d = 0;\n            } else {\n                for (int u = 0; u < N; u++) {\n                    if (is_root[u]) min_d = min(min_d, dist_mat[v][u]);\n                }\n            }\n            if (min_d <= H) score += (long long)(min_d + 1) * A[v];\n        }\n        return score;\n    };\n    \n    auto local_search = [&](vector<bool>& is_root) -> void {\n        bool changed = true;\n        while (changed) {\n            changed = false;\n            for (int v = 0; v < N; v++) {\n                if (!is_root[v]) continue;\n                is_root[v] = false;\n                if (is_valid(is_root)) changed = true;\n                else is_root[v] = true;\n            }\n        }\n        \n        changed = true;\n        while (changed) {\n            changed = false;\n            for (int v = 0; v < N; v++) {\n                if (!is_root[v]) continue;\n                for (int u : adj[v]) {\n                    if (is_root[u] || A[u] >= A[v]) continue;\n                    is_root[v] = false;\n                    is_root[u] = true;\n                    if (is_valid(is_root)) { changed = true; break; }\n                    is_root[v] = true;\n                    is_root[u] = false;\n                }\n                if (changed) break;\n            }\n        }\n    };\n    \n    vector<bool> best_roots(N, false);\n    long long best_score = -1;\n    \n    mt19937 rng(12345);\n    \n    for (int trial = 0; trial < 100; trial++) {\n        bitset<1000> uncovered;\n        for (int i = 0; i < N; i++) uncovered.set(i);\n        \n        vector<bool> is_root(N, false);\n        \n        while (uncovered.any()) {\n            int best_count = 0;\n            vector<int> candidates;\n            \n            for (int v = 0; v < N; v++) {\n                int count = (cover[v] & uncovered).count();\n                if (count > best_count) {\n                    best_count = count;\n                    candidates = {v};\n                } else if (count == best_count) {\n                    candidates.push_back(v);\n                }\n            }\n            \n            if (best_count == 0) break;\n            \n            uniform_int_distribution<int> dist(0, candidates.size() - 1);\n            int chosen = candidates[dist(rng)];\n            \n            is_root[chosen] = true;\n            uncovered &= ~cover[chosen];\n        }\n        \n        local_search(is_root);\n        \n        long long score = compute_score(is_root);\n        if (score > best_score) {\n            best_score = score;\n            best_roots = is_root;\n        }\n    }\n    \n    // Final score-based refinement\n    for (int iter = 0; iter < 5; iter++) {\n        long long current_score = compute_score(best_roots);\n        int best_v = -1, best_u = -1;\n        long long best_new_score = current_score;\n        bool is_swap = false;\n        \n        for (int v = 0; v < N; v++) {\n            if (!best_roots[v]) continue;\n            best_roots[v] = false;\n            if (is_valid(best_roots)) {\n                long long new_score = compute_score(best_roots);\n                if (new_score > best_new_score) {\n                    best_new_score = new_score;\n                    best_v = v;\n                    best_u = -1;\n                    is_swap = false;\n                }\n            }\n            best_roots[v] = true;\n        }\n        \n        for (int v = 0; v < N; v++) {\n            if (!best_roots[v]) continue;\n            for (int u : adj[v]) {\n                if (best_roots[u]) continue;\n                best_roots[v] = false;\n                best_roots[u] = true;\n                if (is_valid(best_roots)) {\n                    long long new_score = compute_score(best_roots);\n                    if (new_score > best_new_score) {\n                        best_new_score = new_score;\n                        best_v = v;\n                        best_u = u;\n                        is_swap = true;\n                    }\n                }\n                best_roots[v] = true;\n                best_roots[u] = false;\n            }\n        }\n        \n        if (best_v == -1) break;\n        best_roots[best_v] = false;\n        if (is_swap) best_roots[best_u] = true;\n    }\n    \n    vector<int> parent(N, -1);\n    vector<int> height(N, -1);\n    queue<int> q;\n    \n    for (int v = 0; v < N; v++) {\n        if (best_roots[v]) {\n            height[v] = 0;\n            q.push(v);\n        }\n    }\n    \n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : adj[u]) {\n            if (height[v] == -1 && height[u] < H) {\n                height[v] = height[u] + 1;\n                parent[v] = u;\n                q.push(v);\n            }\n        }\n    }\n    \n    for (int v = 0; v < N; v++) {\n        if (height[v] == -1) {\n            height[v] = 0;\n            q.push(v);\n            while (!q.empty()) {\n                int u = q.front(); q.pop();\n                for (int w : adj[u]) {\n                    if (height[w] == -1 && height[u] < H) {\n                        height[w] = height[u] + 1;\n                        parent[w] = u;\n                        q.push(w);\n                    }\n                }\n            }\n        }\n    }\n    \n    for (int v = 0; v < N; v++) {\n        cout << parent[v];\n        if (v < N - 1) cout << \" \";\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N; cin >> N;\n    vector<string> board(N);\n    for (int i = 0; i < N; i++) cin >> board[i];\n    \n    vector<int> fmin_r(N,N), fmax_r(N,-1), fmin_c(N,N), fmax_c(N,-1);\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (board[i][j]=='o') {\n        fmin_r[i]=min(fmin_r[i],j); fmax_r[i]=max(fmax_r[i],j);\n        fmin_c[j]=min(fmin_c[j],i); fmax_c[j]=max(fmax_c[j],i);\n    }\n    \n    struct Oni { int i,j; set<int> s; };\n    vector<Oni> O;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (board[i][j]=='x') {\n        Oni o{o.i=i,o.j=j};\n        if (fmin_c[j]>i||fmin_c[j]==N) o.s.insert(0);\n        if (fmax_c[j]<i||fmax_c[j]==-1) o.s.insert(1);\n        if (fmin_r[i]>j||fmin_r[i]==N) o.s.insert(2);\n        if (fmax_r[i]<j||fmax_r[i]==-1) o.s.insert(3);\n        O.push_back(o);\n    }\n    \n    map<int,vector<int>> byR, byC;\n    for (int k=0; k<O.size(); k++) { byR[O[k].i].push_back(k); byC[O[k].j].push_back(k); }\n    \n    vector<int> dir(O.size(),-1);\n    map<pair<int,int>,int> md;\n    auto asgn = [&](int k, int d) {\n        dir[k]=d;\n        int idx=(d<=1)?O[k].j:O[k].i;\n        int dist=(d==0)?O[k].i+1:(d==1)?N-O[k].i:(d==2)?O[k].j+1:N-O[k].j;\n        md[{idx,d}]=max(md[{idx,d}],dist);\n    };\n    \n    for (auto&[r,ks]:byR) {\n        vector<int> ol,or2,b;\n        for (int k:ks) { bool cl=O[k].s.count(2),cr=O[k].s.count(3); if(cl&&cr)b.push_back(k); else if(cl)ol.push_back(k); else if(cr)or2.push_back(k); }\n        for(int k:ol)asgn(k,2); for(int k:or2)asgn(k,3);\n        if(!b.empty()) { int ml=0,mr=0; for(int k:ol)ml=max(ml,O[k].j+1); for(int k:or2)mr=max(mr,N-O[k].j); for(int k:b){ml=max(ml,O[k].j+1);mr=max(mr,N-O[k].j);} int cl=2*ml+(or2.empty()?0:2*mr),cr2=(ol.empty()?0:2*ml)+2*mr; for(int k:b)asgn(k,cl<=cr2?2:3); }\n    }\n    for (auto&[c,ks]:byC) {\n        vector<int> un; for(int k:ks)if(dir[k]==-1)un.push_back(k); if(un.empty())continue;\n        vector<int> ou,od,b;\n        for(int k:un){bool cu=O[k].s.count(0),cd=O[k].s.count(1);if(cu&&cd)b.push_back(k);else if(cu)ou.push_back(k);else if(cd)od.push_back(k);}\n        for(int k:ou)asgn(k,0); for(int k:od)asgn(k,1);\n        if(!b.empty()){int mu=0,md2=0;for(int k:ou)mu=max(mu,O[k].i+1);for(int k:od)md2=max(md2,N-O[k].i);for(int k:b){mu=max(mu,O[k].i+1);md2=max(md2,N-O[k].i);}int cu=2*mu+(od.empty()?0:2*md2),cd=(ou.empty()?0:2*mu)+2*md2;for(int k:b)asgn(k,cu<=cd?0:1);}\n    }\n    for(int k=0;k<O.size();k++){if(dir[k]!=-1)continue;int best=-1,bd=N+1;for(int d:O[k].s){int dist=(d==0)?O[k].i+1:(d==1)?N-O[k].i:(d==2)?O[k].j+1:N-O[k].j;if(dist<bd){bd=dist;best=d;}}asgn(k,best);}\n    \n    for(auto&[key,dist]:md){auto[idx,d]=key;char c=\"UDLR\"[d],cr=\"DULR\"[d];for(int t=0;t<dist;t++)cout<<c<<\" \"<<idx<<\"\\n\";for(int t=0;t<dist;t++)cout<<cr<<\" \"<<idx<<\"\\n\";}\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, L;\n    cin >> N >> L;\n    \n    vector<int> T(N);\n    for (int i = 0; i < N; i++) {\n        cin >> T[i];\n    }\n    \n    vector<int> a(N, -1), b(N, -1);\n    vector<int> cnt(N, 0);\n    cnt[0] = 1;\n    \n    vector<int> remain = T;\n    remain[0]--;\n    \n    auto choose_next = [&](int current, int week) -> int {\n        double best_deficit = -1e18;\n        int best_remain = -1;\n        int best = -1;\n        \n        for (int i = 0; i < N; i++) {\n            if (i == current) continue;\n            if (remain[i] <= 0) continue;\n            \n            double expected = (double)T[i] * week / L;\n            double deficit = expected - cnt[i];\n            \n            if (deficit > best_deficit + 1e-9 || (abs(deficit - best_deficit) < 1e-9 && remain[i] > best_remain)) {\n                best_deficit = deficit;\n                best_remain = remain[i];\n                best = i;\n            }\n        }\n        \n        if (best == -1) {\n            best = current;\n        }\n        \n        return best;\n    };\n    \n    int current = 0;\n    for (int week = 2; week <= L; week++) {\n        int k = cnt[current];\n        \n        int next;\n        if (k % 2 == 1) {\n            if (a[current] == -1) {\n                a[current] = choose_next(current, week);\n            }\n            next = a[current];\n        } else {\n            if (b[current] == -1) {\n                b[current] = choose_next(current, week);\n            }\n            next = b[current];\n        }\n        \n        cnt[next]++;\n        remain[next]--;\n        current = next;\n    }\n    \n    for (int i = 0; i < N; i++) {\n        if (a[i] == -1) a[i] = 0;\n        if (b[i] == -1) b[i] = 0;\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    vector<int> parent, sz;\n    DSU(int n) : parent(n), sz(n, 1) { 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) return false;\n        if (sz[x] < sz[y]) swap(x, y);\n        parent[y] = x; sz[x] += sz[y]; return true;\n    }\n};\n\nint N, M, Q, L, W;\nvector<int> G, cx, cy;\ndouble estDist(int i, int j) { double dx=cx[i]-cx[j], dy=cy[i]-cy[j]; return sqrt(dx*dx+dy*dy); }\n\nvector<pair<int,int>> doQuery(vector<int>& cities) {\n    cout << \"? \" << cities.size();\n    for (int c : cities) cout << \" \" << c;\n    cout << \"\\n\" << flush;\n    vector<pair<int,int>> edges(cities.size() - 1);\n    for (int i = 0; i < (int)cities.size() - 1; i++) cin >> edges[i].first >> edges[i].second;\n    return edges;\n}\n\nvoid findMST(vector<int>& cities, vector<pair<int,int>>& edges, int& queriesLeft) {\n    int n = cities.size();\n    if (n <= 1) return;\n    if (n == 2) { edges.push_back({min(cities[0],cities[1]), max(cities[0],cities[1])}); return; }\n    sort(cities.begin(), cities.end(), [](int a, int b) { return cx[a]!=cx[b] ? cx[a]<cx[b] : cy[a]<cy[b]; });\n    if (n <= L && queriesLeft > 0) { auto r = doQuery(cities); edges.insert(edges.end(), r.begin(), r.end()); queriesLeft--; return; }\n    if (queriesLeft <= 0) { for (int i = 0; i < n-1; i++) edges.push_back({min(cities[i],cities[i+1]), max(cities[i],cities[i+1])}); return; }\n    \n    vector<vector<int>> chunks;\n    for (int i = 0; i < n; i += L) {\n        vector<int> chunk;\n        for (int j = i; j < min(i+L, n); j++) chunk.push_back(cities[j]);\n        chunks.push_back(chunk);\n    }\n    vector<int> reps;\n    for (auto& chunk : chunks) {\n        int sz = chunk.size();\n        if (sz >= 2 && queriesLeft > 0) {\n            auto result = doQuery(chunk);\n            edges.insert(edges.end(), result.begin(), result.end());\n            map<int,int> deg;\n            for (auto& [u,v] : result) { deg[u]++; deg[v]++; }\n            int bestRep = chunk[0], maxDeg = 0;\n            for (int c : chunk) if (deg[c] > maxDeg) { maxDeg = deg[c]; bestRep = c; }\n            reps.push_back(bestRep); queriesLeft--;\n        } else if (sz >= 2) {\n            for (int j = 0; j < sz-1; j++) edges.push_back({min(chunk[j],chunk[j+1]), max(chunk[j],chunk[j+1])});\n            double cX=0, cY=0; for (int c:chunk) { cX+=cx[c]; cY+=cy[c]; } cX/=sz; cY/=sz;\n            int bestRep=chunk[0]; double bd=1e18;\n            for (int c:chunk) { double d=(cx[c]-cX)*(cx[c]-cX)+(cy[c]-cY)*(cy[c]-cY); if(d<bd){bd=d;bestRep=c;} }\n            reps.push_back(bestRep);\n        } else reps.push_back(chunk[0]);\n    }\n    findMST(reps, edges, queriesLeft);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M); for (int i=0;i<M;i++) cin>>G[i];\n    cx.resize(N); cy.resize(N);\n    for (int i=0;i<N;i++) { int lx,rx,ly,ry; cin>>lx>>rx>>ly>>ry; cx[i]=(lx+rx)/2; cy[i]=(ly+ry)/2; }\n    \n    vector<tuple<double,int,int>> allEdges;\n    for (int i=0;i<N;i++) for (int j=i+1;j<N;j++) allEdges.push_back({estDist(i,j),i,j});\n    sort(allEdges.begin(), allEdges.end());\n    DSU dsu(N); vector<tuple<double,int,int>> mstEdges;\n    for (auto& [d,u,v] : allEdges) { if(dsu.unite(u,v)) mstEdges.push_back({d,u,v}); if((int)mstEdges.size()==N-1) break; }\n    \n    vector<vector<pair<double,int>>> adj(N);\n    for (auto& [d,u,v] : mstEdges) { adj[u].push_back({d,v}); adj[v].push_back({d,u}); }\n    \n    vector<int> dfsOrder; vector<bool> vis(N,false);\n    function<void(int)> dfs = [&](int u) {\n        vis[u]=true; dfsOrder.push_back(u);\n        vector<pair<double,int>> nb; for (auto& [d,v]:adj[u]) if(!vis[v]) nb.push_back({d,v});\n        sort(nb.begin(), nb.end());\n        for (auto& [d,v]:nb) if(!vis[v]) dfs(v);\n    };\n    dfs(0);\n    \n    vector<vector<int>> groups(M); int idx=0;\n    for (int i=0;i<M;i++) for (int j=0;j<G[i];j++) groups[i].push_back(dfsOrder[idx++]);\n    \n    vector<int> gOrder(M); iota(gOrder.begin(),gOrder.end(),0);\n    sort(gOrder.begin(),gOrder.end(),[](int a,int b){return G[a]>G[b];});\n    \n    int queriesLeft = Q; vector<vector<pair<int,int>>> allEdgesOut(M);\n    for (int gi : gOrder) findMST(groups[gi], allEdgesOut[gi], queriesLeft);\n    \n    cout << \"!\\n\";\n    for (int i=0;i<M;i++) {\n        for (int j=0;j<(int)groups[i].size();j++) { if(j>0) cout<<\" \"; cout<<groups[i][j]; }\n        cout<<\"\\n\";\n        for (auto& e : allEdgesOut[i]) cout<<e.first<<\" \"<<e.second<<\"\\n\";\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint grid[20][20];\nint ci, cj;\nvector<string> actions;\n\nint dx[] = {-1, 1, 0, 0};\nint dy[] = {0, 0, -1, 1};\nchar dirChar[] = {'U', 'D', 'L', 'R'};\n\nbool inBounds(int i, int j) { return 0 <= i && i < N && 0 <= j < N; }\n\nvoid addMove(int d) {\n    actions.push_back(string(\"M \") + dirChar[d]);\n    ci += dx[d]; cj += dy[d];\n}\n\nvoid addSlide(int d) {\n    actions.push_back(string(\"S \") + dirChar[d]);\n    while (inBounds(ci + dx[d], cj + dy[d]) && !grid[ci + dx[d]][cj + dy[d]]) {\n        ci += dx[d]; cj += dy[d];\n    }\n}\n\npair<int,int> getSlideDest(int d) {\n    int ni = ci, nj = cj;\n    while (inBounds(ni + dx[d], nj + dy[d]) && !grid[ni + dx[d]][nj + dy[d]]) {\n        ni += dx[d]; nj += dy[d];\n    }\n    return {ni, nj};\n}\n\nvoid goTo(int ti, int tj) {\n    while (ci != ti || cj != tj) {\n        int moveCost = abs(ci - ti) + abs(cj - tj);\n        bool onTopEdge = (ti == 0), onBottomEdge = (ti == N - 1);\n        bool onLeftEdge = (tj == 0), onRightEdge = (tj == N - 1);\n        \n        if ((onTopEdge || onBottomEdge) && cj == tj && ci != ti) {\n            int slideDir = onTopEdge ? 0 : 1;\n            auto [ni, nj] = getSlideDest(slideDir);\n            if (ni == ti) { addSlide(slideDir); continue; }\n        }\n        if ((onLeftEdge || onRightEdge) && ci == ti && cj != tj) {\n            int slideDir = onLeftEdge ? 2 : 3;\n            auto [ni, nj] = getSlideDest(slideDir);\n            if (nj == tj) { addSlide(slideDir); continue; }\n        }\n        \n        int bestCost = moveCost, bestDir = -1;\n        if ((onTopEdge || onBottomEdge) && cj != tj) {\n            int cost = abs(cj - tj) + 1;\n            if (cost < bestCost) { bestCost = cost; bestDir = (cj < tj) ? 3 : 2; }\n        }\n        if ((onLeftEdge || onRightEdge) && ci != ti) {\n            int cost = abs(ci - ti) + 1;\n            if (cost < bestCost) { bestCost = cost; bestDir = (ci < ti) ? 1 : 0; }\n        }\n        \n        if (bestDir >= 0) addMove(bestDir);\n        else addMove((ci < ti) ? 1 : (ci > ti) ? 0 : (cj < tj) ? 3 : 2);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N >> M >> ci >> cj;\n    vector<pair<int,int>> targets(M);\n    for (int i = 0; i < M; i++) cin >> targets[i].first >> targets[i].second;\n    memset(grid, 0, sizeof(grid));\n    for (int i = 1; i < M; i++) goTo(targets[i].first, targets[i].second);\n    for (const auto& a : actions) cout << a << \"\\n\";\n    return 0;\n}"},"4":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nmt19937 rng(42);\n\nstruct Company { int x, y, r; };\nstruct Rect { int a, b, c, d; };\n\ndouble calcScore(int count, long long capacity, long long required) {\n    if (count <= 0 || capacity <= 0) return -1e18;\n    double ratio = (double)capacity / required;\n    double r = (ratio <= 1) ? ratio : 1.0/ratio;\n    return count * (1.0 - (1.0 - r) * (1.0 - r));\n}\n\nvoid solve(Rect R, vector<int> ids, vector<Company>& C, vector<Rect>& res, bool randomize, int depth = 0) {\n    if (ids.empty()) return;\n    if (ids.size() == 1) { res[ids[0]] = R; return; }\n    \n    int w = R.c - R.a, h = R.d - R.b;\n    long long total = 0;\n    for (int i : ids) total += C[i].r;\n    \n    double bestScore = -1e18;\n    int bestSplit = -1, bestIdx = -1;\n    bool bestVert = true;\n    \n    vector<int> dirs = {0, 1};\n    if (randomize && rng() % 3 == 0) swap(dirs[0], dirs[1]);\n    \n    for (int vert : dirs) {\n        sort(ids.begin(), ids.end(), [&](int a, int b) {\n            return vert ? C[a].x < C[b].x : C[a].y < C[b].y;\n        });\n        long long acc = 0;\n        for (size_t i = 0; i < ids.size()-1; i++) {\n            acc += C[ids[i]].r;\n            int c1 = vert ? C[ids[i]].x : C[ids[i]].y;\n            int c2 = vert ? C[ids[i+1]].x : C[ids[i+1]].y;\n            if (c1 == c2) continue;\n            int lo, hi;\n            if (vert) { lo = max(R.a+1, c1+1); hi = min(R.c-1, c2); }\n            else { lo = max(R.b+1, c1+1); hi = min(R.d-1, c2); }\n            if (lo > hi) continue;\n            \n            long long leftA = acc, rightA = total - acc;\n            int lCnt = i + 1, rCnt = (int)ids.size() - i - 1;\n            double ratio = (double)leftA / rightA;\n            int opt = vert ? R.a + (int)((w * ratio) / (1 + ratio))\n                           : R.b + (int)((h * ratio) / (1 + ratio));\n            opt = max(lo, min(hi, opt));\n            \n            vector<int> cands = {lo, hi, opt};\n            for (int d = -12; d <= 12; d++) cands.push_back(max(lo, min(hi, opt + d)));\n            if (randomize && depth < 5) {\n                uniform_int_distribution<int> dist(lo, hi);\n                for (int j = 0; j < 3; j++) cands.push_back(dist(rng));\n            }\n            sort(cands.begin(), cands.end());\n            cands.erase(unique(cands.begin(), cands.end()), cands.end());\n            \n            for (int s : cands) {\n                long long leftC = vert ? (long long)(s-R.a)*h : (long long)w*(s-R.b);\n                long long rightC = vert ? (long long)(R.c-s)*h : (long long)w*(R.d-s);\n                double score = calcScore(lCnt, leftC, leftA) + calcScore(rCnt, rightC, rightA);\n                bool accept = score > bestScore;\n                if (!accept && randomize && bestScore > -1e17 && score > bestScore - 0.05 * lCnt && rng() % 25 == 0)\n                    accept = true;\n                if (accept) { bestScore = score; bestSplit = s; bestVert = vert; bestIdx = i; }\n            }\n        }\n    }\n    \n    if (bestSplit == -1) {\n        for (int i : ids) res[i] = {C[i].x, C[i].y, C[i].x+1, C[i].y+1};\n        return;\n    }\n    sort(ids.begin(), ids.end(), [&](int a, int b) {\n        return bestVert ? C[a].x < C[b].x : C[a].y < C[b].y;\n    });\n    vector<int> left(ids.begin(), ids.begin()+bestIdx+1);\n    vector<int> right(ids.begin()+bestIdx+1, ids.end());\n    if (bestVert) {\n        solve({R.a, R.b, bestSplit, R.d}, left, C, res, randomize, depth + 1);\n        solve({bestSplit, R.b, R.c, R.d}, right, C, res, randomize, depth + 1);\n    } else {\n        solve({R.a, R.b, R.c, bestSplit}, left, C, res, randomize, depth + 1);\n        solve({R.a, bestSplit, R.c, R.d}, right, C, res, randomize, depth + 1);\n    }\n}\n\ndouble totalSat(const vector<Rect>& res, const vector<Company>& C) {\n    double score = 0;\n    for (size_t i = 0; i < res.size(); i++) {\n        int s = (res[i].c - res[i].a) * (res[i].d - res[i].b);\n        double r = (double)min(C[i].r, s) / max(C[i].r, s);\n        score += 1.0 - (1.0 - r) * (1.0 - r);\n    }\n    return score;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(nullptr);\n    int n; cin >> n;\n    vector<Company> C(n);\n    for (int i = 0; i < n; i++) cin >> C[i].x >> C[i].y >> C[i].r;\n    \n    vector<Rect> bestRes(n);\n    double bestScore = -1;\n    for (int trial = 0; trial < 150; trial++) {\n        vector<Rect> res(n);\n        vector<int> ids(n); iota(ids.begin(), ids.end(), 0);\n        solve({0,0,10000,10000}, ids, C, res, trial > 0);\n        double score = totalSat(res, C);\n        if (score > bestScore) { bestScore = score; bestRes = res; }\n    }\n    for (int i = 0; i < n; i++)\n        cout << bestRes[i].a << \" \" << bestRes[i].b << \" \" << bestRes[i].c << \" \" << bestRes[i].d << \"\\n\";\n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <chrono>\n#include <cstring>\n#include <random>\n\nusing namespace std;\n\nconst int DEPTH_LIMIT = 150;\nconst int MAX_TILES = 2500;\nconst int MAX_DEG = 8;\n\nint adj[MAX_TILES][MAX_DEG];\nint deg[MAX_TILES];\nbool vis[MAX_TILES];\n\nint temp_vis[MAX_TILES];\nint temp_depth[MAX_TILES];\nint dfs_stack[MAX_TILES];\nint current_stamp = 0;\n\nint cell_to_tile[50][50];\nint p_val[50][50];\n\nint limited_dfs(int start, int excluded) {\n    current_stamp++;\n    int cnt = 0;\n    int stack_ptr = 0;\n    dfs_stack[stack_ptr++] = start;\n    temp_vis[start] = current_stamp;\n    temp_depth[start] = 0;\n    \n    while (stack_ptr > 0) {\n        int node = dfs_stack[--stack_ptr];\n        cnt++;\n        if (temp_depth[node] >= DEPTH_LIMIT) continue;\n        int next_depth = temp_depth[node] + 1;\n        for (int i = 0; i < deg[node]; ++i) {\n            int nxt = adj[node][i];\n            if (nxt != excluded && !vis[nxt] && temp_vis[nxt] != current_stamp) {\n                temp_vis[nxt] = current_stamp;\n                temp_depth[nxt] = next_depth;\n                dfs_stack[stack_ptr++] = nxt;\n            }\n        }\n    }\n    return cnt;\n}\n\nint get_2hop_score(int start, int excluded) {\n    int score = 0;\n    for (int i = 0; i < deg[start]; ++i) {\n        int x = adj[start][i];\n        if (x == excluded || vis[x]) continue;\n        for (int j = 0; j < deg[x]; ++j) {\n            int y = adj[x][j];\n            if (y == start || y == excluded || vis[y]) continue;\n            score++;\n        }\n    }\n    return score;\n}\n\nstruct Candidate {\n    int w;\n    int ni, nj;\n    int p;\n    int c_w;\n    int comp_size;\n    int hop2;\n};\n\nchar get_dir(int i, int j, int ni, int nj) {\n    if (ni == i - 1) return 'U';\n    if (ni == i + 1) return 'D';\n    if (nj == j - 1) return 'L';\n    if (nj == j + 1) return 'R';\n    return '?';\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int si, sj;\n    if (!(cin >> si >> sj)) return 0;\n\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            cin >> cell_to_tile[i][j];\n        }\n    }\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            cin >> p_val[i][j];\n        }\n    }\n\n    int dirs[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\n    \n    // Build adjacency list for tiles\n    memset(deg, 0, sizeof(deg));\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            int T1 = cell_to_tile[i][j];\n            for (auto& d : dirs) {\n                int ni = i + d[0], nj = j + d[1];\n                if (ni >= 0 && ni < 50 && nj >= 0 && nj < 50) {\n                    int T2 = cell_to_tile[ni][nj];\n                    if (T1 != T2) {\n                        bool found = false;\n                        for (int k = 0; k < deg[T1]; ++k) {\n                            if (adj[T1][k] == T2) { found = true; break; }\n                        }\n                        if (!found) adj[T1][deg[T1]++] = T2;\n                        \n                        found = false;\n                        for (int k = 0; k < deg[T2]; ++k) {\n                            if (adj[T2][k] == T1) { found = true; break; }\n                        }\n                        if (!found) adj[T2][deg[T2]++] = T1;\n                    }\n                }\n            }\n        }\n    }\n\n    auto cmp = [](const Candidate& a, const Candidate& b) {\n        bool a_safe = (a.c_w >= 2);\n        bool b_safe = (b.c_w >= 2);\n        if (a_safe != b_safe) return a_safe > b_safe;\n        \n        bool a_corr = (a.c_w == 1);\n        bool b_corr = (b.c_w == 1);\n        if (a_corr != b_corr) return a_corr > b_corr;\n        \n        if (a.comp_size != b.comp_size) return a.comp_size > b.comp_size;\n        if (a.hop2 != b.hop2) return a.hop2 > b.hop2;\n        if (a.p != b.p) return a.p > b.p;\n        \n        return false; // Keep original random order on exact ties\n    };\n\n    std::mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    string best_path = \"\";\n    int best_score = -1;\n\n    for (int run = 0; run < 2; ++run) {\n        std::shuffle(begin(dirs), end(dirs), rng);\n        memset(vis, false, sizeof(vis));\n        \n        int u = cell_to_tile[si][sj];\n        vis[u] = true;\n        int i = si, j = sj;\n        int v = -1;\n        int curr_score = p_val[si][sj];\n        string curr_path = \"\";\n        \n        while (true) {\n            vector<Candidate> candidates;\n            for (auto& d : dirs) {\n                int ni = i + d[0], nj = j + d[1];\n                if (ni < 0 || ni >= 50 || nj < 0 || nj >= 50) continue;\n                int w = cell_to_tile[ni][nj];\n                if (w == u || w == v || vis[w]) continue;\n                \n                int c_w = 0;\n                for (int k = 0; k < deg[w]; ++k) {\n                    int nxt = adj[w][k];\n                    if (nxt != u && !vis[nxt]) c_w++;\n                }\n                \n                candidates.push_back({w, ni, nj, p_val[ni][nj], c_w, 0, 0});\n            }\n            \n            if (candidates.empty()) break;\n            \n            if (candidates.size() > 1) {\n                for (auto& cand : candidates) {\n                    cand.comp_size = limited_dfs(cand.w, u);\n                    cand.hop2 = get_2hop_score(cand.w, u);\n                }\n            }\n            \n            sort(candidates.begin(), candidates.end(), cmp);\n            \n            auto& best = candidates[0];\n            vis[best.w] = true;\n            curr_path += get_dir(i, j, best.ni, best.nj);\n            curr_score += best.p;\n            \n            v = u;\n            u = best.w;\n            i = best.ni;\n            j = best.nj;\n        }\n        \n        if (curr_score > best_score) {\n            best_score = curr_score;\n            best_path = curr_path;\n        }\n    }\n    \n    cout << best_path << \"\\n\";\n\n    return 0;\n}","ahc003":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <cmath>\n#include <tuple>\n#include <algorithm>\n\nusing namespace std;\n\nconst int N = 30;\nbool visited_h[N][N-1] = {false};\nbool visited_v[N-1][N] = {false};\ndouble W_h[N][N-1], W_v[N-1][N];\n\ndouble row_sum_h[N] = {0}, row_cnt_h[N] = {0};\ndouble col_sum_v[N] = {0}, col_cnt_v[N] = {0};\n\nvector<vector<double>> dist(N, vector<double>(N));\nvector<vector<pair<int, int>>> prev_node(N, vector<pair<int, int>>(N));\n\ndouble get_w_h(int i, int j) {\n    if (visited_h[i][j]) return W_h[i][j];\n    \n    // If the row has NO visits, return the safe neutral baseline 5000\n    if (row_cnt_h[i] < 0.1) return 5000.0;\n    \n    double row_w = row_sum_h[i] / row_cnt_h[i];\n    // Smoothly blend with 5000 based on how many edge-visits the row has\n    double alpha_row = min(1.0, row_cnt_h[i] * 0.1);\n    return 5000.0 + alpha_row * (row_w - 5000.0);\n}\n\ndouble get_w_v(int i, int j) {\n    if (visited_v[i][j]) return W_v[i][j];\n    \n    if (col_cnt_v[j] < 0.1) return 5000.0;\n    \n    double col_w = col_sum_v[j] / col_cnt_v[j];\n    double alpha_col = min(1.0, col_cnt_v[j] * 0.1);\n    return 5000.0 + alpha_col * (col_w - 5000.0);\n}\n\nstring dijkstra(int si, int sj, int ti, int tj) {\n    for (int i = 0; i < N; ++i) {\n        fill(dist[i].begin(), dist[i].end(), 1e18);\n        fill(prev_node[i].begin(), prev_node[i].end(), make_pair(-1, -1));\n    }\n    \n    priority_queue<pair<double, pair<int, int>>, vector<pair<double, pair<int, int>>>, greater<>> pq;\n    dist[si][sj] = 0;\n    pq.push({0.0, {si, sj}});\n\n    while (!pq.empty()) {\n        auto [d, u] = pq.top();\n        pq.pop();\n        int i = u.first, j = u.second;\n        \n        if (d > dist[i][j] + 1e-9) continue;\n        if (i == ti && j == tj) break;\n\n        if (i > 0) {\n            double w = get_w_v(i - 1, j);\n            if (dist[i][j] + w < dist[i - 1][j] - 1e-9) {\n                dist[i - 1][j] = dist[i][j] + w;\n                prev_node[i - 1][j] = {i, j};\n                pq.push({dist[i - 1][j], {i - 1, j}});\n            }\n        }\n        if (i < N - 1) {\n            double w = get_w_v(i, j);\n            if (dist[i][j] + w < dist[i + 1][j] - 1e-9) {\n                dist[i + 1][j] = dist[i][j] + w;\n                prev_node[i + 1][j] = {i, j};\n                pq.push({dist[i + 1][j], {i + 1, j}});\n            }\n        }\n        if (j > 0) {\n            double w = get_w_h(i, j - 1);\n            if (dist[i][j] + w < dist[i][j - 1] - 1e-9) {\n                dist[i][j - 1] = dist[i][j] + w;\n                prev_node[i][j - 1] = {i, j};\n                pq.push({dist[i][j - 1], {i, j - 1}});\n            }\n        }\n        if (j < N - 1) {\n            double w = get_w_h(i, j);\n            if (dist[i][j] + w < dist[i][j + 1] - 1e-9) {\n                dist[i][j + 1] = dist[i][j] + w;\n                prev_node[i][j + 1] = {i, j};\n                pq.push({dist[i][j + 1], {i, j + 1}});\n            }\n        }\n    }\n\n    string path = \"\";\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        auto p = prev_node[ci][cj];\n        int pi = p.first, pj = p.second;\n        if (pi == ci - 1) path += 'D';\n        else if (pi == ci + 1) path += 'U';\n        else if (pj == cj - 1) path += 'R';\n        else if (pj == cj + 1) path += 'L';\n        ci = pi;\n        cj = pj;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N - 1; ++j) W_h[i][j] = 5000.0;\n    }\n    for (int i = 0; i < N - 1; ++i) {\n        for (int j = 0; j < N; ++j) W_v[i][j] = 5000.0;\n    }\n\n    for (int k = 0; k < 1000; ++k) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n\n        string path = dijkstra(si, sj, ti, tj);\n        cout << path << \"\\n\" << flush;\n\n        long long result;\n        cin >> result;\n\n        double L = 0;\n        int m = path.length();\n        vector<tuple<int, int, int>> edges;\n        \n        int ci = si, cj = sj;\n        for (char c : path) {\n            if (c == 'U') {\n                edges.push_back({1, ci - 1, cj});\n                L += get_w_v(ci - 1, cj);\n                ci--;\n            } else if (c == 'D') {\n                edges.push_back({1, ci, cj});\n                L += get_w_v(ci, cj);\n                ci++;\n            } else if (c == 'L') {\n                edges.push_back({0, ci, cj - 1});\n                L += get_w_h(ci, cj - 1);\n                cj--;\n            } else if (c == 'R') {\n                edges.push_back({0, ci, cj});\n                L += get_w_h(ci, cj);\n                cj++;\n            }\n        }\n\n        if (m > 0) {\n            double delta = (result - L) / m;\n            for (auto& [type, i, j] : edges) {\n                if (type == 0) {\n                    if (!visited_h[i][j]) {\n                        visited_h[i][j] = true;\n                        // Initialize to the best hierarchical prior guess\n                        W_h[i][j] = get_w_h(i, j);\n                    }\n                    // Asymmetric learning: fast upward (bottlenecks), slow downward\n                    if (delta > 0) W_h[i][j] += 1.0 * delta;\n                    else W_h[i][j] += 0.2 * delta;\n                    \n                    W_h[i][j] = max(100.0, min(9000.0, W_h[i][j]));\n                    \n                    // Update row average with the new weight\n                    row_sum_h[i] += W_h[i][j];\n                    row_cnt_h[i] += 1.0;\n                } else {\n                    if (!visited_v[i][j]) {\n                        visited_v[i][j] = true;\n                        W_v[i][j] = get_w_v(i, j);\n                    }\n                    if (delta > 0) W_v[i][j] += 1.0 * delta;\n                    else W_v[i][j] += 0.2 * delta;\n                    \n                    W_v[i][j] = max(100.0, min(9000.0, W_v[i][j]));\n                    \n                    // Update column average with the new weight\n                    col_sum_v[j] += W_v[i][j];\n                    col_cnt_v[j] += 1.0;\n                }\n            }\n        }\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    cin >> N >> M;\n    vector<string> s(M);\n    for (int i = 0; i < M; i++) cin >> s[i];\n    \n    struct Placement { int type, row, col, len, str_idx; };\n    vector<Placement> all_placements;\n    all_placements.reserve(M * 800);\n    for (int m = 0; m < M; m++) {\n        int k = s[m].size();\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++)\n            all_placements.push_back({0, i, j, k, m});\n        for (int j = 0; j < N; j++) for (int i = 0; i < N; i++)\n            all_placements.push_back({1, i, j, k, m});\n    }\n    int P = all_placements.size();\n    \n    vector<vector<pair<int,int>>> placement_cells(P), cell_placements(N*N);\n    for (int p = 0; p < P; p++) {\n        auto& pl = all_placements[p];\n        for (int q = 0; q < pl.len; q++) {\n            int r = pl.type==0 ? pl.row : (pl.row+q)%N;\n            int c = pl.type==0 ? (pl.col+q)%N : pl.col;\n            placement_cells[p].push_back({r,c});\n            cell_placements[r*N+c].push_back({p,q});\n        }\n    }\n    \n    vector<vector<array<int,8>>> votes(N, vector<array<int,8>>(N));\n    for (int p = 0; p < P; p++) {\n        auto& pl = all_placements[p];\n        for (int q = 0; q < pl.len; q++) {\n            auto [r,c] = placement_cells[p][q];\n            votes[r][c][s[pl.str_idx][q]-'A']++;\n        }\n    }\n    \n    vector<string> grid(N, string(N,'A'));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        int mx = -1; char best = 'A';\n        for (int ch = 0; ch < 8; ch++) if (votes[i][j][ch] > mx) { mx = votes[i][j][ch]; best = 'A'+ch; }\n        grid[i][j] = best;\n    }\n    \n    vector<int16_t> mismatch_count(P);\n    vector<int> string_match_count(M, 0);\n    for (int p = 0; p < P; p++) {\n        auto& pl = all_placements[p]; int cnt = 0;\n        for (int q = 0; q < pl.len; q++) {\n            auto [r,c] = placement_cells[p][q];\n            if (grid[r][c] != s[pl.str_idx][q]) cnt++;\n        }\n        mismatch_count[p] = cnt;\n        if (cnt == 0) string_match_count[pl.str_idx]++;\n    }\n    \n    vector<int> cell_order(N*N);\n    iota(cell_order.begin(), cell_order.end(), 0);\n    \n    vector<int> lose_strings; lose_strings.reserve(100);\n    vector<int> gain_by_char[8];\n    for (int ch = 0; ch < 8; ch++) gain_by_char[ch].reserve(100);\n    int temp_chg[800];\n    memset(temp_chg, 0, sizeof(temp_chg));\n    vector<int> affected; affected.reserve(200);\n    \n    for (int iter = 0; iter < 100; iter++) {\n        bool improved = false;\n        for (int ci : cell_order) {\n            int r = ci / N, c = ci % N;\n            char originalChar = grid[r][c];\n            \n            lose_strings.clear();\n            for (int ch = 0; ch < 8; ch++) gain_by_char[ch].clear();\n            \n            for (auto [p, q] : cell_placements[ci]) {\n                int m = all_placements[p].str_idx;\n                char exp = s[m][q];\n                bool wasMatch = (originalChar == exp);\n                \n                if (wasMatch && mismatch_count[p] == 0 && string_match_count[m] == 1)\n                    lose_strings.push_back(m);\n                if (!wasMatch && mismatch_count[p] == 1 && string_match_count[m] == 0)\n                    gain_by_char[exp - 'A'].push_back(m);\n            }\n            \n            int bestDelta = 0; char bestChar = originalChar;\n            \n            for (int ch = 0; ch < 8; ch++) {\n                if (ch + 'A' == originalChar) continue;\n                \n                affected.clear();\n                for (int m : gain_by_char[ch]) {\n                    if (temp_chg[m] == 0) affected.push_back(m);\n                    temp_chg[m] += 1;\n                }\n                for (int m : lose_strings) {\n                    if (temp_chg[m] == 0) affected.push_back(m);\n                    temp_chg[m] -= 1;\n                }\n                \n                int delta = 0;\n                for (int m : affected) {\n                    bool was = string_match_count[m] > 0;\n                    bool is = string_match_count[m] + temp_chg[m] > 0;\n                    if (!was && is) delta++;\n                    else if (was && !is) delta--;\n                    temp_chg[m] = 0;\n                }\n                \n                if (delta > bestDelta) { bestDelta = delta; bestChar = 'A' + ch; }\n            }\n            \n            if (bestDelta > 0) {\n                grid[r][c] = bestChar;\n                for (auto [p, q] : cell_placements[ci]) {\n                    int m = all_placements[p].str_idx;\n                    char exp = s[m][q];\n                    bool wasMatch = (originalChar == exp);\n                    bool isMatch = (bestChar == exp);\n                    if (wasMatch == isMatch) continue;\n                    \n                    if (wasMatch && !isMatch) {\n                        mismatch_count[p]++;\n                        if (mismatch_count[p] == 1) string_match_count[m]--;\n                    } else {\n                        mismatch_count[p]--;\n                        if (mismatch_count[p] == 0) string_match_count[m]++;\n                    }\n                }\n                improved = true;\n            }\n        }\n        if (!improved) break;\n    }\n    \n    for (int i = 0; i < N; i++) cout << grid[i] << \"\\n\";\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\nusing namespace chrono;\n\nint N, si, sj;\nvector<string> grid;\nint cost[70][70];\nvector<pair<int,int>> roads;\nint seg_id[70][70][2];\nint num_segs;\n\nvoid find_segments() {\n    memset(seg_id, -1, sizeof(seg_id));\n    num_segs = 0;\n    for (int i = 0; i < N; i++) {\n        int j = 0;\n        while (j < N) {\n            if (grid[i][j] == '#') { j++; continue; }\n            int start = j;\n            while (j < N && grid[i][j] != '#') j++;\n            for (int k = start; k < j; k++) seg_id[i][k][0] = num_segs++;\n        }\n    }\n    for (int j = 0; j < N; j++) {\n        int i = 0;\n        while (i < N) {\n            if (grid[i][j] == '#') { i++; continue; }\n            int start = i;\n            while (i < N && grid[i][j] != '#') i++;\n            for (int k = start; k < i; k++) seg_id[k][j][1] = num_segs++;\n        }\n    }\n}\n\nvector<int> dist_arr, prev_arr;\nvoid dijkstra(int sx, int sy) {\n    int V = N * N;\n    dist_arr.assign(V, INT_MAX);\n    prev_arr.assign(V, -1);\n    dist_arr[sx * N + sy] = 0;\n    priority_queue<pair<int,int>, vector<pair<int,int>>, greater<>> pq;\n    pq.push({0, sx * N + sy});\n    const int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, -1, 1};\n    while (!pq.empty()) {\n        auto [d, u] = pq.top(); pq.pop();\n        if (d > dist_arr[u]) continue;\n        int x = u / N, y = u % N;\n        for (int k = 0; k < 4; k++) {\n            int nx = x + dx[k], ny = y + dy[k];\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N || grid[nx][ny] == '#') continue;\n            int v = nx * N + ny, nd = d + cost[nx][ny];\n            if (nd < dist_arr[v]) { dist_arr[v] = nd; prev_arr[v] = u; pq.push({nd, v}); }\n        }\n    }\n}\n\nstring get_path(int sx, int sy, int ex, int ey) {\n    if (sx == ex && sy == ey) return \"\";\n    vector<int> trace;\n    for (int u = ex * N + ey; u != sx * N + sy && u != -1; u = prev_arr[u]) trace.push_back(u);\n    reverse(trace.begin(), trace.end());\n    string path;\n    int cur = sx * N + sy;\n    for (int next : trace) {\n        int cx = cur/N, cy = cur%N, nx = next/N, ny = next%N;\n        path += (nx==cx-1) ? 'U' : (nx==cx+1) ? 'D' : (ny==cy-1) ? 'L' : 'R';\n        cur = next;\n    }\n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    auto total_start = steady_clock::now();\n    \n    cin >> N >> si >> sj;\n    grid.resize(N);\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] != '#') { cost[i][j] = grid[i][j] - '0'; roads.push_back({i, j}); }\n    }\n    find_segments();\n    \n    vector<bool> covered(num_segs, false);\n    covered[seg_id[si][sj][0]] = covered[seg_id[si][sj][1]] = true;\n    vector<pair<int,int>> selected = {{si, sj}};\n    while (true) {\n        int best_count = 0, best_dist = INT_MAX;\n        pair<int,int> best_cell = {-1, -1};\n        for (auto& [i, j] : roads) {\n            int count = (seg_id[i][j][0]!=-1 && !covered[seg_id[i][j][0]]) + (seg_id[i][j][1]!=-1 && !covered[seg_id[i][j][1]]);\n            if (count > best_count) { best_count = count; best_dist = INT_MAX; best_cell = {i, j}; }\n            if (count == best_count && count > 0) {\n                int min_d = abs(i-si) + abs(j-sj);\n                for (auto& [r, c] : selected) min_d = min(min_d, abs(i-r) + abs(j-c));\n                if (min_d < best_dist) { best_dist = min_d; best_cell = {i, j}; }\n            }\n        }\n        if (best_count == 0) break;\n        selected.push_back(best_cell);\n        covered[seg_id[best_cell.first][best_cell.second][0]] = covered[seg_id[best_cell.first][best_cell.second][1]] = true;\n    }\n    \n    int orig_m = selected.size();\n    vector<int> seg_count(num_segs, 0);\n    for (int i = 0; i < orig_m; i++) {\n        int s0 = seg_id[selected[i].first][selected[i].second][0];\n        int s1 = seg_id[selected[i].first][selected[i].second][1];\n        if (s0 != -1) seg_count[s0]++;\n        if (s1 != -1) seg_count[s1]++;\n    }\n    vector<pair<int,int>> pruned;\n    for (int i = 0; i < orig_m; i++) {\n        int s0 = seg_id[selected[i].first][selected[i].second][0];\n        int s1 = seg_id[selected[i].first][selected[i].second][1];\n        bool can_remove = (i > 0);\n        if (s0 != -1 && seg_count[s0] <= 1) can_remove = false;\n        if (s1 != -1 && seg_count[s1] <= 1) can_remove = false;\n        if (!can_remove) pruned.push_back(selected[i]);\n        else { if (s0 != -1) seg_count[s0]--; if (s1 != -1) seg_count[s1]--; }\n    }\n    \n    int m = pruned.size();\n    if (m <= 1) { cout << \"\" << endl; return 0; }\n    \n    vector<vector<int>> dist(m, vector<int>(m));\n    for (int i = 0; i < m; i++) {\n        dijkstra(pruned[i].first, pruned[i].second);\n        for (int j = 0; j < m; j++) dist[i][j] = dist_arr[pruned[j].first * N + pruned[j].second];\n    }\n    \n    vector<int> tour(m);\n    iota(tour.begin(), tour.end(), 0);\n    { vector<bool> vis(m, false); vis[0] = true; int cur = 0;\n      for (int iter = 1; iter < m; iter++) {\n          int best = -1, best_d = INT_MAX;\n          for (int i = 0; i < m; i++) if (!vis[i] && dist[cur][i] < best_d) { best_d = dist[cur][i]; best = i; }\n          vis[best] = true; tour[iter] = best; cur = best;\n      }\n    }\n    \n    auto time_ok = [&]() { return duration_cast<duration<double>>(steady_clock::now() - total_start).count() < 2.5; };\n    \n    bool improved = true;\n    while (improved && time_ok()) {\n        improved = false;\n        for (int i = 0; i < m - 1 && !improved; i++)\n            for (int j = i + 2; j < m && !improved; j++) {\n                if (i == 0 && j == m - 1) continue;\n                int saving = dist[tour[i]][tour[i+1]] + dist[tour[j]][tour[(j+1)%m]] - dist[tour[i]][tour[j]] - dist[tour[i+1]][tour[(j+1)%m]];\n                if (saving > 0) { reverse(tour.begin() + i + 1, tour.begin() + j + 1); improved = true; }\n            }\n        if (improved) continue;\n        if (m > 2) for (int i = 0; i < m && !improved; i++) {\n            int node = tour[i], prev_i = (i - 1 + m) % m, next_i = (i + 1) % m;\n            int remove_saving = dist[tour[prev_i]][node] + dist[node][tour[next_i]] - dist[tour[prev_i]][tour[next_i]];\n            vector<int> base; for (int k = 0; k < m; k++) if (k != i) base.push_back(tour[k]);\n            int orig_pos = (prev_i < i) ? prev_i : prev_i - 1;\n            for (int pos = 0; pos < m - 1 && !improved; pos++) {\n                if (pos == orig_pos) continue;\n                int insert_cost = dist[base[pos]][node] + dist[node][base[(pos+1)%(m-1)]] - dist[base[pos]][base[(pos+1)%(m-1)]];\n                if (insert_cost < remove_saving) { base.insert(base.begin() + pos + 1, node); tour = base; improved = true; }\n            }\n        }\n    }\n    \n    string result; int cx = si, cy = sj;\n    for (int i = 1; i < m; i++) { dijkstra(cx, cy); result += get_path(cx, cy, pruned[tour[i]].first, pruned[tour[i]].second); cx = pruned[tour[i]].first; cy = pruned[tour[i]].second; }\n    if (cx != si || cy != sj) { dijkstra(cx, cy); result += get_path(cx, cy, si, sj); }\n    cout << result << endl;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K, R;\n    cin >> N >> M >> K >> R;\n    \n    vector<vector<int>> d(N, vector<int>(K));\n    for (int i = 0; i < N; i++)\n        for (int k = 0; k < K; k++) cin >> d[i][k];\n    \n    vector<vector<int>> deps(N), rdeps(N);\n    for (int i = 0; i < R; i++) {\n        int u, v; cin >> u >> v; u--; v--;\n        deps[v].push_back(u); rdeps[u].push_back(v);\n    }\n    \n    vector<int> topo;\n    { vector<int> indeg(N,0);\n      for(int v=0;v<N;v++) for(int u:deps[v]) indeg[v]++;\n      queue<int> q;\n      for(int i=0;i<N;i++) if(indeg[i]==0) q.push(i);\n      while(!q.empty()) { int u=q.front(); q.pop(); topo.push_back(u);\n        for(int v:rdeps[u]) if(--indeg[v]==0) q.push(v); } }\n    \n    vector<int> crit(N, 1);\n    for(int u:topo) for(int v:rdeps[u]) crit[u]=max(crit[u], 1+crit[v]);\n    \n    vector<vector<int>> proven(M, vector<int>(K, 0));\n    vector<vector<int>> est(M, vector<int>(K, 0));\n    vector<int> tstatus(N, -1), mtask(M, -1), tstart(N, -1), tcount(M, 0);\n    \n    auto can_start = [&](int t) {\n        if(tstatus[t] != -1) return false;\n        for(int dep: deps[t]) if(tstatus[dep] != 1) return false;\n        return true;\n    };\n    \n    auto est_w = [&](int t, int m) {\n        int w = 0;\n        for(int k = 0; k < K; k++) w += max(0, d[t][k] - est[m][k]);\n        return w;\n    };\n    \n    auto can_1day = [&](int t, int m) {\n        for(int k = 0; k < K; k++) if(d[t][k] > proven[m][k]) return false;\n        return true;\n    };\n    \n    for(int day = 1; day <= 2000; day++) {\n        vector<int> avail;\n        for(int i = 0; i < N; i++) if(can_start(i)) avail.push_back(i);\n        sort(avail.begin(), avail.end(), [&](int a, int b) { return crit[a] > crit[b]; });\n        \n        vector<int> freem;\n        for(int j = 0; j < M; j++) if(mtask[j] == -1) freem.push_back(j);\n        \n        vector<pair<int,int>> assign;\n        vector<bool> tused(N, false), mused(M, false);\n        \n        for(int t: avail) {\n            if(tused[t]) continue;\n            for(int m: freem) {\n                if(mused[m]) continue;\n                if(can_1day(t, m)) {\n                    assign.push_back({m, t});\n                    tused[t] = mused[m] = true;\n                    mtask[m] = t; tstatus[t] = 0; tstart[t] = day; tcount[m]++;\n                    break;\n                }\n            }\n        }\n        \n        for(int t: avail) {\n            if(tused[t]) continue;\n            int best = -1; long long best_score = LLONG_MAX;\n            for(int m: freem) {\n                if(mused[m]) continue;\n                int w = est_w(t, m);\n                long long score = (long long)w * 10000 + tcount[m];\n                if(score < best_score) { best_score = score; best = m; }\n            }\n            if(best != -1) {\n                assign.push_back({best, t});\n                tused[t] = mused[best] = true;\n                mtask[best] = t; tstatus[t] = 0; tstart[t] = day; tcount[best]++;\n            }\n        }\n        \n        cout << assign.size();\n        for(auto [m,t]: assign) cout << \" \" << m+1 << \" \" << t+1;\n        cout << \"\\n\"; cout.flush();\n        \n        int n; cin >> n;\n        if(n == -1) break;\n        \n        for(int i = 0; i < n; i++) {\n            int m; cin >> m; m--;\n            int t = mtask[m], actual = day - tstart[t] + 1;\n            tstatus[t] = 1; mtask[m] = -1;\n            \n            if(actual == 1) {\n                for(int k = 0; k < K; k++)\n                    proven[m][k] = est[m][k] = max(proven[m][k], max(est[m][k], d[t][k]));\n            } else {\n                int pred_w = est_w(t, m);\n                int w_lo = max(1, actual - 3);\n                int w_hi = actual + 3;\n                \n                if(pred_w < w_lo || pred_w > w_hi) {\n                    int target_w;\n                    if(pred_w < w_lo) target_w = (4 * pred_w + 6 * w_lo + 5) / 10;\n                    else target_w = (4 * pred_w + 6 * w_hi + 5) / 10;\n                    \n                    int diff = target_w - pred_w;\n                    \n                    vector<int> weight(K);\n                    int total_weight = 0;\n                    for(int k = 0; k < K; k++) {\n                        int gap = max(0, d[t][k] - est[m][k]);\n                        weight[k] = max(1, d[t][k] + gap);\n                        total_weight += weight[k];\n                    }\n                    \n                    for(int k = 0; k < K; k++) {\n                        int adj = (diff * weight[k] + total_weight/2) / total_weight;\n                        est[m][k] = max(proven[m][k], est[m][k] - adj);\n                    }\n                }\n            }\n        }\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint manhattan(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    vector<array<int, 4>> orders(1000);\n    for (int i = 0; i < 1000; i++)\n        cin >> orders[i][0] >> orders[i][1] >> orders[i][2] >> orders[i][3];\n    \n    vector<pair<double, int>> scored(1000);\n    for (int i = 0; i < 1000; i++) {\n        int a = orders[i][0], b = orders[i][1], c = orders[i][2], d = orders[i][3];\n        scored[i] = {manhattan(400, 400, (a+c)/2, (b+d)/2) * 2.0 + manhattan(a, b, c, d) * 0.5, i};\n    }\n    sort(scored.begin(), scored.end());\n    \n    vector<int> selected(50);\n    for (int i = 0; i < 50; i++) selected[i] = scored[i].second;\n    \n    auto get_xy = [&](int idx, bool is_del) -> pair<int,int> {\n        int oid = selected[idx];\n        if (is_del) return {orders[oid][2], orders[oid][3]};\n        return {orders[oid][0], orders[oid][1]};\n    };\n    \n    auto build_route = [&](vector<int>& order_indices) {\n        vector<pair<int, bool>> route;\n        for (int t = 0; t < 50; t++) {\n            int idx = order_indices[t], n = route.size();\n            auto [a, b] = get_xy(idx, false);\n            auto [c, d] = get_xy(idx, true);\n            int best_cost = INT_MAX, best_pick = -1, best_del = -1;\n            \n            for (int p = 0; p <= n; p++) for (int q = p; q <= n; q++) {\n                int cost = 0; int px = 400, py = 400;\n                for (int i = 0; i < p; i++) { auto [nx, ny] = get_xy(route[i].first, route[i].second); cost += manhattan(px, py, nx, ny); px = nx; py = ny; }\n                cost += manhattan(px, py, a, b); px = a; py = b;\n                for (int i = p; i < q; i++) { auto [nx, ny] = get_xy(route[i].first, route[i].second); cost += manhattan(px, py, nx, ny); px = nx; py = ny; }\n                cost += manhattan(px, py, c, d); px = c; py = d;\n                for (int i = q; i < n; i++) { auto [nx, ny] = get_xy(route[i].first, route[i].second); cost += manhattan(px, py, nx, ny); px = nx; py = ny; }\n                cost += manhattan(px, py, 400, 400);\n                if (cost < best_cost) { best_cost = cost; best_pick = p; best_del = q; }\n            }\n            route.insert(route.begin() + best_del, {idx, true});\n            route.insert(route.begin() + best_pick, {idx, false});\n        }\n        return route;\n    };\n    \n    auto find_pos = [](vector<pair<int, bool>>& r) {\n        vector<int> pu(50), de(50);\n        for (int i = 0; i < (int)r.size(); i++) r[i].second ? de[r[i].first] = i : pu[r[i].first] = i;\n        return make_pair(pu, de);\n    };\n    \n    vector<int> ord(50); iota(ord.begin(), ord.end(), 0);\n    vector<pair<int, bool>> best_route; int best_cost = INT_MAX;\n    \n    for (int trial = 0; trial < 8; trial++) {\n        if (trial > 0) shuffle(ord.begin(), ord.end(), rng);\n        auto route = build_route(ord);\n        int cost = 0; int px = 400, py = 400;\n        for (auto& [i, d] : route) { auto [nx, ny] = get_xy(i, d); cost += manhattan(px, py, nx, ny); px = nx; py = ny; }\n        cost += manhattan(px, py, 400, 400);\n        if (cost < best_cost) { best_cost = cost; best_route = route; }\n    }\n    \n    auto [pu_pos, de_pos] = find_pos(best_route);\n    for (int iter = 0; iter < 500; iter++) {\n        bool imp = false;\n        for (int i = 0; i < (int)best_route.size() && !imp; i++) {\n            int idx = best_route[i].first; bool is_d = best_route[i].second;\n            int n = best_route.size();\n            auto [ex, ey] = get_xy(idx, is_d);\n            int pvx = 400, pvy = 400, nx = 400, ny = 400;\n            if (i > 0) { auto [px2, py2] = get_xy(best_route[i-1].first, best_route[i-1].second); pvx = px2; pvy = py2; }\n            if (i < n-1) { auto [nx2, ny2] = get_xy(best_route[i+1].first, best_route[i+1].second); nx = nx2; ny = ny2; }\n            int base = -manhattan(pvx, pvy, ex, ey) - manhattan(ex, ey, nx, ny) + manhattan(pvx, pvy, nx, ny);\n            auto gc = [&](int pos) -> pair<int,int> {\n                if (pos < 0 || pos >= n-1) return {400, 400};\n                int op = (pos < i) ? pos : pos + 1;\n                return get_xy(best_route[op].first, best_route[op].second);\n            };\n            for (int j = 0; j <= n-1 && !imp; j++) {\n                if (j == i) continue;\n                if (is_d) { if (j <= pu_pos[idx]) continue; }\n                else { int mj = de_pos[idx] - (de_pos[idx] > i ? 1 : 0); if (j > mj) continue; }\n                auto [ipx, ipy] = gc(j-1); auto [inx, iny] = gc(j);\n                int delta = base - manhattan(ipx, ipy, inx, iny) + manhattan(ipx, ipy, ex, ey) + manhattan(ex, ey, inx, iny);\n                if (delta < 0) {\n                    auto elem = best_route[i]; best_route.erase(best_route.begin() + i);\n                    best_route.insert(best_route.begin() + j, elem); best_cost += delta;\n                    auto [p, d] = find_pos(best_route); pu_pos = p; de_pos = d; imp = true;\n                }\n            }\n        }\n        if (!imp) break;\n    }\n    \n    cout << 50; for (int i = 0; i < 50; i++) cout << \" \" << selected[i] + 1; cout << \"\\n\";\n    cout << best_route.size() + 2 << \" 400 400\";\n    for (auto& [i, d] : best_route) { auto [x, y] = get_xy(i, d); cout << \" \" << x << \" \" << y; }\n    cout << \" 400 400\\n\";\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <numeric>\n\nusing namespace std;\n\nstruct DSU {\n    vector<int> parent, rank_;\n    DSU(int n) : parent(n), rank_(n, 0) {\n        iota(parent.begin(), parent.end(), 0);\n    }\n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n    bool merge(int x, int y) {\n        x = find(x); y = find(y);\n        if (x == y) return false;\n        if (rank_[x] < rank_[y]) swap(x, y);\n        parent[y] = x;\n        if (rank_[x] == rank_[y]) rank_[x]++;\n        return true;\n    }\n};\n\nint main() {\n    // Fast I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N = 400, M = 1995;\n    vector<double> x(N), y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> x[i] >> y[i];\n    }\n\n    vector<int> u(M), v(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> u[i] >> v[i];\n    }\n\n    DSU dsu(N);\n    // Track rejected edges between component roots\n    // Max possible rejected edges between any two components is bounded\n    vector<vector<int8_t>> rejected(N, vector<int8_t>(N, 0));\n    \n    // Optimal thresholds derived from the optimal stopping rule for U(d, 3d)\n    // V_5 = 1.44984375\n    // V_4 = 1.5165625\n    // V_3 = 1.609375\n    // V_2 = 1.75\n    // V_1 = 2.0 (Not strictly used as we accept unconditionally at k=4)\n    double thresholds[4] = {1.44984375, 1.5165625, 1.609375, 1.75};\n\n    int accepted = 0;\n    for (int i = 0; i < M; ++i) {\n        int l;\n        cin >> l;\n        \n        int A = dsu.find(u[i]);\n        int B = dsu.find(v[i]);\n        \n        // If already connected, reject\n        if (A == B) {\n            cout << \"0\\n\" << std::flush;\n            continue;\n        }\n\n        // Global safety net: If we are running out of edges, accept any connecting edge\n        int remaining = M - i - 1;\n        int needed = (N - 1) - accepted;\n\n        if (remaining <= needed + 5) {\n            cout << \"1\\n\" << std::flush;\n            dsu.merge(A, B);\n            accepted++;\n            continue;\n        }\n\n        // Calculate base distance d_i\n        double dx = x[u[i]] - x[v[i]];\n        double dy = y[u[i]] - y[v[i]];\n        int d = std::round(std::sqrt(dx * dx + dy * dy));\n        \n        // Normalize roots to avoid asymmetric array accesses\n        if (A > B) swap(A, B);\n        \n        int k = rejected[A][B];\n        \n        // If we've seen and rejected 4 edges, this is guaranteed to be the 5th and final edge\n        if (k >= 4) {\n            cout << \"1\\n\" << std::flush;\n            dsu.merge(A, B);\n            accepted++;\n        } else {\n            double thresh = thresholds[k] * d;\n            if (l <= thresh) {\n                cout << \"1\\n\" << std::flush;\n                dsu.merge(A, B);\n                accepted++;\n            } else {\n                cout << \"0\\n\" << std::flush;\n                rejected[A][B]++;\n            }\n        }\n    }\n\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 30, W = 30;\nint N, M;\nint px[25], py[25], pt[25];\nint hx[15], hy[15];\nbool wall[H][W];\nint pet_dist[25][H][W];\n\nint dx[] = {-1, 1, 0, 0};\nint dy[] = {0, 0, -1, 1};\nchar dir_char[] = \"UDLR\";\nchar wall_char[] = \"udlr\";\n\nbool in_bounds(int x, int y) { return 0 <= x && x < H && 0 <= y < W; }\n\nbool has_pet_at(int x, int y) {\n    for (int i = 0; i < N; i++) if (px[i] == x && py[i] == y) return true;\n    return false;\n}\n\nbool has_human_at(int x, int y) {\n    for (int i = 0; i < M; i++) if (hx[i] == x && hy[i] == y) return true;\n    return false;\n}\n\nbool pet_adjacent(int x, int y) {\n    for (int d = 0; d < 4; d++) if (has_pet_at(x + dx[d], y + dy[d])) return true;\n    return false;\n}\n\nbool can_place_wall(int x, int y) {\n    if (!in_bounds(x, y) || wall[x][y]) return false;\n    if (has_pet_at(x, y) || has_human_at(x, y)) return false;\n    if (pet_adjacent(x, y)) return false;\n    return true;\n}\n\nvoid compute_pet_distances() {\n    for (int p = 0; p < N; p++) {\n        queue<pair<int,int>> q;\n        memset(pet_dist[p], -1, sizeof(pet_dist[p]));\n        q.push({px[p], py[p]});\n        pet_dist[p][px[p]][py[p]] = 0;\n        while (!q.empty()) {\n            auto [x, y] = q.front(); q.pop();\n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (in_bounds(nx, ny) && !wall[nx][ny] && pet_dist[p][nx][ny] == -1) {\n                    pet_dist[p][nx][ny] = pet_dist[p][x][y] + 1;\n                    q.push({nx, ny});\n                }\n            }\n        }\n    }\n}\n\nint wall_value(int wx, int wy, int hi) {\n    int val = 0;\n    \n    for (int p = 0; p < N; p++) {\n        int weight;\n        if (pt[p] == 4) weight = 12;      // Dog - highest priority\n        else if (pt[p] == 3) weight = 3;   // Rabbit\n        else if (pt[p] == 5) weight = 2;   // Cat\n        else weight = 1;                    // Cow, Pig\n        \n        int dpw = pet_dist[p][wx][wy];\n        if (dpw < 0 || dpw == 0) continue;\n        \n        int dph = pet_dist[p][hx[hi]][hy[hi]];\n        if (dph < 0) continue;\n        \n        // Emergency: dog very close\n        if (pt[p] == 4 && dph <= 6) {\n            weight *= 4;\n            if (dpw <= 3) val += 1000;\n        }\n        \n        if (dph > 15 && pt[p] != 4) continue;\n        if (dph > 25) continue;\n        \n        // On path check using Manhattan as lower bound\n        int dwh = abs(wx - hx[hi]) + abs(wy - hy[hi]);\n        if (dpw + dwh == dph) val += 100 * weight;\n        \n        // Proximity value\n        if (dpw < 8) val += (8 - dpw) * 6 * weight;\n    }\n    \n    return val;\n}\n\nstring pet_moves[25];\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++) { cin >> px[i] >> py[i] >> pt[i]; px[i]--; py[i]--; }\n    cin >> M;\n    for (int i = 0; i < M; i++) { cin >> hx[i] >> hy[i]; hx[i]--; hy[i]--; }\n    \n    memset(wall, false, sizeof(wall));\n    \n    for (int turn = 0; turn < 300; turn++) {\n        compute_pet_distances();\n        \n        // Find and rank wall candidates globally\n        vector<tuple<int, int, int>> wall_candidates;\n        for (int i = 0; i < M; i++) {\n            for (int d = 0; d < 4; d++) {\n                int wx = hx[i] + dx[d], wy = hy[i] + dy[d];\n                if (can_place_wall(wx, wy)) {\n                    int val = wall_value(wx, wy, i);\n                    if (val > 15) wall_candidates.push_back({val, i, d});\n                }\n            }\n        }\n        sort(wall_candidates.rbegin(), wall_candidates.rend());\n        \n        // Coordinate wall assignment\n        set<int> assigned;\n        set<pair<int,int>> wall_positions;\n        vector<pair<int,int>> planned_walls(M, {-1, -1});\n        \n        for (auto& [val, hi, d] : wall_candidates) {\n            if (assigned.count(hi)) continue;\n            int wx = hx[hi] + dx[d], wy = hy[hi] + dy[d];\n            if (wall_positions.count({wx, wy})) continue;\n            assigned.insert(hi);\n            wall_positions.insert({wx, wy});\n            planned_walls[hi] = {wx, wy};\n        }\n        \n        string actions(M, '.');\n        for (int i = 0; i < M; i++) {\n            if (planned_walls[i].first != -1) {\n                for (int d = 0; d < 4; d++) {\n                    if (planned_walls[i] == make_pair(hx[i]+dx[d], hy[i]+dy[d])) {\n                        actions[i] = wall_char[d];\n                        break;\n                    }\n                }\n                continue;\n            }\n            \n            // Move away from pets\n            double gx = 0, gy = 0;\n            for (int p = 0; p < N; p++) {\n                double dist = max(1.0, (double)(abs(hx[i]-px[p]) + abs(hy[i]-py[p])));\n                gx += (hx[i] - px[p]) / (dist * dist);\n                gy += (hy[i] - py[p]) / (dist * dist);\n            }\n            int bm = -1, bm_safe = -1; \n            double bd = 0.01, bd_safe = 0.01;\n            for (int d = 0; d < 4; d++) {\n                int nx = hx[i]+dx[d], ny = hy[i]+dy[d];\n                bool blocked = !in_bounds(nx,ny) || wall[nx][ny] || wall_positions.count({nx,ny});\n                if (!blocked) {\n                    double dot = dx[d]*gx + dy[d]*gy;\n                    if (dot > bd) { bd = dot; bm = d; }\n                    if (!pet_adjacent(nx, ny) && dot > bd_safe) { bd_safe = dot; bm_safe = d; }\n                }\n            }\n            if (bm_safe != -1) bm = bm_safe;\n            if (bm != -1) actions[i] = dir_char[bm];\n        }\n        \n        cout << actions << endl;\n        \n        for (int i = 0; i < N; i++) cin >> pet_moves[i];\n        \n        // Update walls first\n        for (int i = 0; i < M; i++) {\n            if (actions[i] != '.' && islower(actions[i])) {\n                for (int d = 0; d < 4; d++) if (actions[i] == wall_char[d]) {\n                    int nx=hx[i]+dx[d], ny=hy[i]+dy[d];\n                    if (in_bounds(nx,ny)) wall[nx][ny] = true;\n                }\n            }\n        }\n        \n        // Update human positions\n        for (int i = 0; i < M; i++) {\n            if (actions[i] != '.' && isupper(actions[i])) {\n                for (int d = 0; d < 4; d++) if (actions[i] == dir_char[d]) {\n                    int nx=hx[i]+dx[d], ny=hy[i]+dy[d];\n                    if (in_bounds(nx,ny) && !wall[nx][ny]) {\n                        hx[i]=nx; hy[i]=ny;\n                    }\n                    break;\n                }\n            }\n        }\n        \n        // Update pet positions\n        for (int i = 0; i < N; i++) {\n            for (char c : pet_moves[i]) for (int d = 0; d < 4; d++) if (c == dir_char[d]) {\n                px[i]+=dx[d]; py[i]+=dy[d];\n                break;\n            }\n        }\n    }\n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cstring>\n#include <algorithm>\n#include <queue>\n\nusing namespace std;\n\nint si, sj, ti, tj;\ndouble p;\nchar h[20][19];\nchar v[19][20];\n\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\nchar dirs[] = {'U', 'D', 'L', 'R'};\n\nint dist[20][20];\nbool can[20][20][4];\ndouble move_prob_table[20][20][4];\ndouble stay_prob_table[20][20][4];\ndouble remaining_sq[201][41];\ndouble reach_score_table[201];\n\nvoid compute_distances() {\n    memset(dist, -1, sizeof(dist));\n    dist[ti][tj] = 0;\n    queue<pair<int, int>> q;\n    q.push({ti, tj});\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int dir = 0; dir < 4; ++dir) {\n            if (can[i][j][dir]) {\n                int ni = i + dr[dir], nj = j + dc[dir];\n                if (dist[ni][nj] == -1) {\n                    dist[ni][nj] = dist[i][j] + 1;\n                    q.push({ni, nj});\n                }\n            }\n        }\n    }\n}\n\nstruct Node {\n    vector<char> seq;\n    double exact_score;\n    double dp[400]; // Flattened 20x20 grid for fast copy\n    double value;\n};\n\nint main() {\n    // Fast I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    if (!(cin >> si >> sj >> ti >> tj >> p)) return 0;\n    \n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 19; ++j) {\n            cin >> h[i][j];\n        }\n    }\n    for (int i = 0; i < 19; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            cin >> v[i][j];\n        }\n    }\n    \n    // Precompute transition dynamics\n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            for (int dir = 0; dir < 4; ++dir) {\n                if (dir == 0) can[i][j][dir] = i > 0 && v[i-1][j] == '0';\n                else if (dir == 1) can[i][j][dir] = i < 19 && v[i][j] == '0';\n                else if (dir == 2) can[i][j][dir] = j > 0 && h[i][j-1] == '0';\n                else can[i][j][dir] = j < 19 && h[i][j] == '0';\n                \n                bool wall = !can[i][j][dir];\n                move_prob_table[i][j][dir] = (1.0 - p) * (1.0 - wall);\n                stay_prob_table[i][j][dir] = 1.0 - move_prob_table[i][j][dir];\n            }\n        }\n    }\n    \n    compute_distances();\n    \n    // Precompute scores and heuristic components\n    for (int t = 1; t <= 200; ++t) {\n        reach_score_table[t] = 401.0 - t;\n        for (int d = 0; d <= 40; ++d) {\n            int rem = 400 - t - d;\n            remaining_sq[t][d] = rem > 0 ? (double)rem * rem : 0.0;\n        }\n    }\n    \n    int L = 200;\n    int W = 100; // Beam width\n    \n    vector<Node> beam;\n    beam.resize(1);\n    beam[0].seq.clear();\n    beam[0].exact_score = 0.0;\n    memset(beam[0].dp, 0, sizeof(beam[0].dp));\n    beam[0].dp[si * 20 + sj] = 1.0;\n    beam[0].value = 0.0;\n    \n    vector<Node> next_beam_candidates;\n    next_beam_candidates.reserve(W * 4);\n    \n    for (int t = 1; t <= L; ++t) {\n        next_beam_candidates.clear();\n        \n        for (auto& node : beam) {\n            for (int dir = 0; dir < 4; ++dir) {\n                Node new_node;\n                new_node.seq = node.seq;\n                new_node.seq.push_back(dirs[dir]);\n                new_node.exact_score = node.exact_score;\n                memset(new_node.dp, 0, sizeof(new_node.dp));\n                \n                double reach_prob = 0.0;\n                double heuristic = 0.0;\n                \n                // Fast inner loop over distribution\n                for (int i = 0; i < 20; ++i) {\n                    for (int j = 0; j < 20; ++j) {\n                        double prob = node.dp[i * 20 + j];\n                        if (prob < 1e-15) continue;\n                        \n                        double move_prob = move_prob_table[i][j][dir];\n                        double stay_prob = stay_prob_table[i][j][dir];\n                        \n                        if (move_prob > 1e-15) {\n                            int ni = i + dr[dir], nj = j + dc[dir];\n                            if (ni == ti && nj == tj) {\n                                reach_prob += prob * move_prob;\n                            } else {\n                                new_node.dp[ni * 20 + nj] += prob * move_prob;\n                            }\n                        }\n                        \n                        if (stay_prob > 1e-15) {\n                            new_node.dp[i * 20 + j] += prob * stay_prob;\n                        }\n                    }\n                }\n                \n                // Exact lower bound score for reaching target\n                new_node.exact_score += reach_prob * reach_score_table[t];\n                \n                // Squared distance heuristic to aggressively pull mass towards target\n                for (int i = 0; i < 20; ++i) {\n                    for (int j = 0; j < 20; ++j) {\n                        if (i == ti && j == tj) continue;\n                        double prob = new_node.dp[i * 20 + j];\n                        if (prob < 1e-15) continue;\n                        heuristic += prob * remaining_sq[t][dist[i][j]];\n                    }\n                }\n                \n                // Balanced scaling between exact achievement and future potential\n                new_node.value = new_node.exact_score * 400.0 + heuristic;\n                next_beam_candidates.push_back(new_node);\n            }\n        }\n        \n        // Keep top W candidates\n        sort(next_beam_candidates.begin(), next_beam_candidates.end(), [](const Node& a, const Node& b) {\n            return a.value > b.value;\n        });\n        \n        int new_W = min(W, (int)next_beam_candidates.size());\n        beam.assign(next_beam_candidates.begin(), next_beam_candidates.begin() + new_W);\n    }\n    \n    cout << string(beam[0].seq.begin(), beam[0].seq.end()) << \"\\n\";\n    \n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <string>\n#include <set>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <ctime>\n\nusing namespace std;\n\nint to_table[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1},\n};\n\nint di[4] = {0, -1, 0, 1};\nint dj[4] = {-1, 0, 1, 0};\n\nint valid_out[8][4];\n\nstruct TraceResult {\n    int len;\n    bool is_cycle;\n    int ret_d;\n};\n\ninline int get_to_fast(int t, int r, int in_d) {\n    int orig_out = to_table[t][(in_d + r) % 4];\n    if (orig_out == -1) return -1;\n    return (orig_out - r + 4) % 4;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    for (int t = 0; t < 8; ++t) {\n        for (int r = 0; r < 4; ++r) {\n            int mask = 0;\n            for (int d = 0; d < 4; ++d) {\n                int orig_out = to_table[t][(d + r) % 4];\n                if (orig_out != -1) {\n                    int out_d = (orig_out - r + 4) % 4;\n                    mask |= (1 << out_d);\n                }\n            }\n            valid_out[t][r] = mask;\n        }\n    }\n\n    vector<int> tiles(900);\n    for (int i = 0; i < 30; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < 30; ++j) {\n            tiles[i * 30 + j] = row[j] - '0';\n        }\n    }\n\n    vector<int> rot(900, 0);\n    \n    for (int i = 0; i < 30; ++i) {\n        for (int j = 0; j < 30; ++j) {\n            int idx = i * 30 + j;\n            int t = tiles[idx];\n            int best_r = 0, best_matches = -1;\n            for (int r = 0; r < 4; ++r) {\n                rot[idx] = r;\n                int matches = 0;\n                if (i > 0) {\n                    int top_idx = (i - 1) * 30 + j;\n                    if ((valid_out[tiles[top_idx]][rot[top_idx]] >> 3) & 1) { \n                        if ((valid_out[t][r] >> 1) & 1) matches++; \n                    }\n                }\n                if (j > 0) {\n                    int left_idx = i * 30 + (j - 1);\n                    if ((valid_out[tiles[left_idx]][rot[left_idx]] >> 2) & 1) { \n                        if ((valid_out[t][r] >> 0) & 1) matches++; \n                    }\n                }\n                if (matches > best_matches) {\n                    best_matches = matches;\n                    best_r = r;\n                }\n            }\n            rot[idx] = best_r;\n        }\n    }\n\n    multiset<int> cycles;\n    int pos_x = 0, pos_y = 0;\n\n    auto trace = [&](int start_x, int start_y, int start_d) -> TraceResult {\n        int cx = start_x, cy = start_y;\n        int curr_in_d = (start_d + 2) % 4;\n        int len = 0;\n        while (true) {\n            int idx = cx * 30 + cy;\n            int out_d = get_to_fast(tiles[idx], rot[idx], curr_in_d);\n            if (out_d == -1) return {len, false, -1};\n            \n            int nx = cx + di[out_d];\n            int ny = cy + dj[out_d];\n            if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30) return {len, false, -1};\n            \n            len++;\n            if (nx == pos_x && ny == pos_y) {\n                return {len, true, out_d};\n            }\n            \n            cx = nx; cy = ny;\n            curr_in_d = (out_d + 2) % 4;\n        }\n    };\n\n    auto extract_and_remove_cycles = [&](int idx, int r) {\n        vector<int> found_cycles;\n        found_cycles.reserve(4);\n        pos_x = idx / 30; pos_y = idx % 30;\n        int t = tiles[idx];\n        int curr_out_mask = valid_out[t][r];\n        for (int d = 0; d < 4; ++d) {\n            if (!(curr_out_mask & (1 << d))) continue;\n            int nx = pos_x + di[d], ny = pos_y + dj[d];\n            if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30) continue;\n            int neighbor_idx = nx * 30 + ny;\n            if (!((valid_out[tiles[neighbor_idx]][rot[neighbor_idx]] >> ((d + 2) % 4)) & 1)) continue;\n            \n            TraceResult res = trace(nx, ny, d);\n            if (res.is_cycle && res.ret_d >= d) {\n                found_cycles.push_back(res.len + 1);\n            }\n        }\n        for (int c : found_cycles) {\n            auto it = cycles.find(c);\n            if (it != cycles.end()) cycles.erase(it);\n        }\n        return found_cycles;\n    };\n\n    auto apply_and_insert_cycles = [&](int idx, int r) {\n        vector<int> found_cycles;\n        found_cycles.reserve(4);\n        pos_x = idx / 30; pos_y = idx % 30;\n        int t = tiles[idx];\n        int curr_out_mask = valid_out[t][r];\n        for (int d = 0; d < 4; ++d) {\n            if (!(curr_out_mask & (1 << d))) continue;\n            int nx = pos_x + di[d], ny = pos_y + dj[d];\n            if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30) continue;\n            int neighbor_idx = nx * 30 + ny;\n            if (!((valid_out[tiles[neighbor_idx]][rot[neighbor_idx]] >> ((d + 2) % 4)) & 1)) continue;\n            \n            TraceResult res = trace(nx, ny, d);\n            if (res.is_cycle && res.ret_d >= d) {\n                found_cycles.push_back(res.len + 1);\n            }\n        }\n        for (int c : found_cycles) {\n            cycles.insert(c);\n        }\n        return found_cycles;\n    };\n\n    for (int i = 0; i < 30; ++i) {\n        for (int j = 0; j < 30; ++j) {\n            int idx = i * 30 + j;\n            pos_x = i; pos_y = j;\n            int curr_out_mask = valid_out[tiles[idx]][rot[idx]];\n            for (int d = 0; d < 4; ++d) {\n                if (!(curr_out_mask & (1 << d))) continue;\n                int nx = i + di[d], ny = j + dj[d];\n                if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30) continue;\n                int neighbor_idx = nx * 30 + ny;\n                if (!((valid_out[tiles[neighbor_idx]][rot[neighbor_idx]] >> ((d + 2) % 4)) & 1)) continue;\n                \n                TraceResult res = trace(nx, ny, d);\n                if (res.is_cycle && res.ret_d >= d) {\n                    cycles.insert(res.len + 1);\n                }\n            }\n        }\n    }\n\n    long long sum_sq = 0;\n    for (int len : cycles) sum_sq += (long long)len * len;\n    long long current_sum_sq = sum_sq;\n\n    random_device rd;\n    mt19937 rng(rd());\n    uniform_int_distribution<int> rand_tile(0, 899);\n    uniform_int_distribution<int> rand_rot_diff(1, 3);\n    uniform_real_distribution<double> rand_prob(0.0, 1.0);\n\n    auto start_time = clock();\n    double temp = 80000.0;\n    double cool = 0.999997;\n\n    // Phase 1: SA with Sum of Squares to aggressively merge loops\n    while (clock() - start_time < 1.5 * CLOCKS_PER_SEC) {\n        int idx = rand_tile(rng);\n        int old_r = rot[idx];\n        int new_r = (old_r + rand_rot_diff(rng)) % 4;\n\n        vector<int> old_cycles = extract_and_remove_cycles(idx, old_r);\n        rot[idx] = new_r;\n        vector<int> new_cycles = apply_and_insert_cycles(idx, new_r);\n\n        long long new_sum_sq = sum_sq;\n        for (int c : old_cycles) new_sum_sq -= (long long)c * c;\n        for (int c : new_cycles) new_sum_sq += (long long)c * c;\n\n        if (new_sum_sq > current_sum_sq || exp((new_sum_sq - current_sum_sq) / temp) > rand_prob(rng)) {\n            current_sum_sq = new_sum_sq;\n            sum_sq = new_sum_sq;\n        } else {\n            rot[idx] = old_r;\n            for (int c : new_cycles) {\n                auto it = cycles.find(c);\n                if (it != cycles.end()) cycles.erase(it);\n            }\n            for (int c : old_cycles) {\n                cycles.insert(c);\n            }\n        }\n        temp *= cool;\n    }\n\n    // Phase 2: Strict Hill Climbing with True Score to balance top two loops\n    long long true_score = 0;\n    if (cycles.size() >= 2) {\n        auto it = cycles.rbegin();\n        true_score = (long long)*it * (long long)*std::next(it);\n    }\n\n    while (clock() - start_time < 1.95 * CLOCKS_PER_SEC) {\n        int idx = rand_tile(rng);\n        int old_r = rot[idx];\n        int new_r = (old_r + rand_rot_diff(rng)) % 4;\n\n        vector<int> old_cycles = extract_and_remove_cycles(idx, old_r);\n        rot[idx] = new_r;\n        vector<int> new_cycles = apply_and_insert_cycles(idx, new_r);\n\n        long long new_true_score = 0;\n        if (cycles.size() >= 2) {\n            auto it = cycles.rbegin();\n            new_true_score = (long long)*it * (long long)*std::next(it);\n        }\n\n        if (new_true_score > true_score) {\n            true_score = new_true_score;\n        } else {\n            rot[idx] = old_r;\n            for (int c : new_cycles) {\n                auto it = cycles.find(c);\n                if (it != cycles.end()) cycles.erase(it);\n            }\n            for (int c : old_cycles) {\n                cycles.insert(c);\n            }\n        }\n    }\n\n    string ans = \"\";\n    for (int i = 0; i < 900; ++i) {\n        ans += (char)('0' + rot[i]);\n    }\n    cout << ans << \"\\n\";\n\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nchar board[12][12];\nint ei, ej;\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst char dc[] = {'U', 'D', 'L', 'R'};\nconst int lm[] = {2, 8, 1, 4};\nconst int om[] = {8, 2, 4, 1};\n\ninline int gt(int i, int j) {\n    char c = board[i][j];\n    return (c == '0') ? -1 : ((c >= 'a') ? (c - 'a' + 10) : (c - '0'));\n}\n\nint vis[100], comp[100];\n\nint lts() {\n    int best = 0;\n    for (int i = 0; i < N * N; i++) vis[i] = 0;\n    for (int si = 0; si < N * N; si++) {\n        if (vis[si] || gt(si/N, si%N) < 0) continue;\n        int h = 0, t = 0;\n        comp[t++] = si; vis[si] = 1;\n        while (h < t) {\n            int c = comp[h++], ci = c/N, cj = c%N, ct = gt(ci, cj);\n            for (int d = 0; d < 4; d++) {\n                int ni = ci+di[d], nj = cj+dj[d];\n                if (ni<0||ni>=N||nj<0||nj>=N) continue;\n                int nx = ni*N+nj;\n                if (vis[nx]) continue;\n                int nt = gt(ni, nj);\n                if (nt>=0 && (ct&lm[d]) && (nt&om[d])) { vis[nx]=1; comp[t++]=nx; }\n            }\n        }\n        if (t <= best) continue;\n        int e = 0;\n        for (int k = 0; k < t; k++) {\n            int ci=comp[k]/N, cj=comp[k]%N, ct=gt(ci,cj);\n            if (cj+1<N && (ct&4)) { int nt=gt(ci,cj+1); if (nt>=0&&(nt&1)) e++; }\n            if (ci+1<N && (ct&8)) { int nt=gt(ci+1,cj); if (nt>=0&&(nt&2)) e++; }\n        }\n        if (e == t-1) best = t;\n        if (best == N*N-1) return best;\n    }\n    return best;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> T;\n    for (int i = 0; i < N; i++) cin >> board[i];\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++)\n        if (board[i][j] == '0') { ei = i; ej = j; }\n    \n    string moves;\n    mt19937 rng(42);\n    int cur_tree = lts();\n    int stuck = 0;\n    double rp = 0.4;\n    double cool = pow(0.01, 1.0/T);\n    \n    for (int step = 0; step < T; step++) {\n        int valid[4], vc = 0;\n        for (int d = 0; d < 4; d++) {\n            int ni = ei+di[d], nj = ej+dj[d];\n            if (ni>=0 && ni<N && nj>=0 && nj<N) valid[vc++] = d;\n        }\n        \n        int best = valid[0], best_tree = -1, best_delta = -100;\n        vector<int> ties;\n        \n        for (int v = 0; v < vc; v++) {\n            int d = valid[v], ni = ei+di[d], nj = ej+dj[d];\n            int t = gt(ni, nj);\n            if (t < 0) continue;\n            \n            int delta = 0;\n            for (int dd = 0; dd < 4; dd++) {\n                int nni=ei+di[dd], nnj=ej+dj[dd];\n                if (nni>=0&&nni<N&&nnj>=0&&nnj<N) {\n                    int nt=gt(nni,nnj);\n                    if (nt>=0&&(t&lm[dd])&&(nt&om[dd])) delta++;\n                }\n            }\n            for (int dd = 0; dd < 4; dd++) {\n                int nni=ni+di[dd], nnj=nj+dj[dd];\n                if (nni>=0&&nni<N&&nnj>=0&&nnj<N) {\n                    int nt=gt(nni,nnj);\n                    if (nt>=0&&(t&lm[dd])&&(nt&om[dd])) delta--;\n                }\n            }\n            \n            int tree = cur_tree;\n            if (delta > 0 || stuck > 20) {\n                swap(board[ei][ej], board[ni][nj]);\n                tree = lts();\n                swap(board[ei][ej], board[ni][nj]);\n            }\n            \n            if (tree > best_tree || (tree == best_tree && delta > best_delta)) {\n                best_tree = tree; best_delta = delta; best = d; ties = {d};\n            } else if (tree == best_tree && delta == best_delta) {\n                ties.push_back(d);\n            }\n        }\n        \n        if ((double)(rng()%1000)/1000.0 < rp) best = valid[rng()%vc];\n        else best = ties[rng()%ties.size()];\n        \n        int ni = ei+di[best], nj = ej+dj[best];\n        swap(board[ei][ej], board[ni][nj]);\n        ei = ni; ej = nj;\n        moves += dc[best];\n        \n        if (step % 20 == 0) {\n            int new_tree = lts();\n            if (new_tree >= cur_tree) { stuck = 0; cur_tree = new_tree; }\n            else stuck += 20;\n        } else if (best_tree > cur_tree) {\n            cur_tree = best_tree; stuck = 0;\n        } else {\n            stuck++;\n        }\n        \n        rp *= cool;\n    }\n    cout << moves << endl;\n}","ahc012":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <numeric>\n#include <unordered_map>\n#include <unordered_set>\n#include <random>\n\nusing namespace std;\n\nstruct PairHash {\n    size_t operator()(const pair<uint64_t, uint64_t>& p) const {\n        return p.first ^ (p.second * 2654435761ULL);\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N;\n    if (!(cin >> N)) return 0;\n    int K_input;\n    cin >> K_input;\n    \n    int a[11] = {0};\n    for (int d = 1; d <= 10; d++) cin >> a[d];\n    \n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n    \n    if (N == 0) {\n        cout << 0 << \"\\n\";\n        return 0;\n    }\n    \n    int total_V = min(50, N - 1);\n    int total_H = min(50, N - 1);\n    int actual_K = total_V + total_H;\n    \n    vector<int> A(actual_K), B(actual_K), C_int(actual_K, -20000);\n    vector<bool> is_vertical(actual_K);\n    \n    for (int j = 0; j < total_V; j++) {\n        A[j] = 1; B[j] = 0;\n        is_vertical[j] = true;\n    }\n    for (int j = total_V; j < actual_K; j++) {\n        A[j] = 0; B[j] = 1;\n        is_vertical[j] = false;\n    }\n    \n    unordered_set<int> neg_x, neg_y;\n    neg_x.reserve(N);\n    neg_y.reserve(N);\n    for (int i = 0; i < N; i++) {\n        neg_x.insert(-x[i]);\n        neg_y.insert(-y[i]);\n    }\n    \n    vector<int> sorted_idx_x(N), sorted_idx_y(N);\n    iota(sorted_idx_x.begin(), sorted_idx_x.end(), 0);\n    sort(sorted_idx_x.begin(), sorted_idx_x.end(), [&](int i, int j) { return x[i] < x[j]; });\n    iota(sorted_idx_y.begin(), sorted_idx_y.end(), 0);\n    sort(sorted_idx_y.begin(), sorted_idx_y.end(), [&](int i, int j) { return y[i] < y[j]; });\n    \n    // Initialize grid lines exactly at point percentiles\n    int j = 0;\n    for (int i = 1; i <= total_V; i++) {\n        int idx = i * N / (total_V + 1);\n        int x_left = x[sorted_idx_x[idx - 1]];\n        int x_right = x[sorted_idx_x[idx]];\n        \n        int C = -x_left - 1;\n        while(neg_x.count(C) && C > -x_right) C--;\n        if (neg_x.count(C)) {\n            C = -x_right + 1;\n            while(neg_x.count(C) && C < -x_left) C++;\n            if (neg_x.count(C)) C = -20000; // fallback dummy cut\n        }\n        C_int[j++] = C;\n    }\n    \n    for (int i = 1; i <= total_H; i++) {\n        int idx = i * N / (total_H + 1);\n        int y_left = y[sorted_idx_y[idx - 1]];\n        int y_right = y[sorted_idx_y[idx]];\n        \n        int C = -y_left - 1;\n        while(neg_y.count(C) && C > -y_right) C--;\n        if (neg_y.count(C)) {\n            C = -y_right + 1;\n            while(neg_y.count(C) && C < -y_left) C++;\n            if (neg_y.count(C)) C = -20000;\n        }\n        C_int[j++] = C;\n    }\n    \n    vector<pair<int, int>> sorted_x(N);\n    for (int i = 0; i < N; i++) sorted_x[i] = {x[i], i};\n    sort(sorted_x.begin(), sorted_x.end());\n    \n    vector<pair<int, int>> sorted_y(N);\n    for (int i = 0; i < N; i++) sorted_y[i] = {y[i], i};\n    sort(sorted_y.begin(), sorted_y.end());\n    \n    // Precompute sorted projections for O(log N) flipped point retrieval\n    vector<vector<pair<int, int>>> sorted_vals(actual_K);\n    for (int j = 0; j < total_V; j++) sorted_vals[j] = sorted_x;\n    for (int j = total_V; j < actual_K; j++) sorted_vals[j] = sorted_y;\n    \n    vector<uint64_t> sig1(N), sig2(N);\n    unordered_map<pair<uint64_t, uint64_t>, int, PairHash> cnt;\n    cnt.reserve(6000);\n    \n    for (int i = 0; i < N; i++) {\n        sig1[i] = 0; sig2[i] = 0;\n        for (int j = 0; j < actual_K; j++) {\n            if (A[j] * x[i] + B[j] * y[i] + C_int[j] > 0) {\n                if (j < 64) sig1[i] |= (1ULL << j);\n                else sig2[i] |= (1ULL << (j - 64));\n            }\n        }\n        cnt[{sig1[i], sig2[i]}]++;\n    }\n    \n    int b[11] = {0};\n    for (auto& p : cnt) {\n        if (p.second <= 10) b[p.second]++;\n    }\n    int current_score = 0;\n    for (int d = 1; d <= 10; d++) current_score += min(a[d], b[d]);\n    \n    int best_score = current_score;\n    vector<int> best_C = C_int;\n    \n    mt19937 mt(42);\n    uniform_int_distribution<int> rand_idx(0, actual_K - 1);\n    uniform_int_distribution<int> rand_delta(0, 1);\n    uniform_real_distribution<double> rand_prob(0.0, 1.0);\n    \n    double temp = 1.0;\n    vector<int> flipped;\n    flipped.reserve(10);\n    \n    // Ultra-fast Simulated Annealing\n    for (int iter = 0; iter < 15000000; iter++) {\n        temp *= 0.9999998;\n        \n        int j = rand_idx(mt);\n        int delta = rand_delta(mt) == 0 ? -1 : 1;\n        int C_new = C_int[j] + delta;\n        if (C_new < -10000 || C_new > 10000) continue;\n        \n        // O(1) validity check based on point gaps >= 11\n        if (is_vertical[j]) {\n            if (neg_x.count(C_new)) continue;\n        } else {\n            if (neg_y.count(C_new)) continue;\n        }\n        \n        auto& sv = sorted_vals[j];\n        int min_C = min(C_new, C_int[j]);\n        int max_C = max(C_new, C_int[j]);\n        int L_val = -max_C + 1;\n        int R_val = -min_C;\n        \n        auto it_lo = lower_bound(sv.begin(), sv.end(), make_pair(L_val, -1));\n        auto it_hi = upper_bound(sv.begin(), sv.end(), make_pair(R_val, N));\n        \n        flipped.clear();\n        for (auto it = it_lo; it != it_hi; ++it) {\n            flipped.push_back(it->second);\n        }\n        \n        for (int i : flipped) {\n            auto old_sig = make_pair(sig1[i], sig2[i]);\n            int S_old = cnt[old_sig];\n            if (S_old <= 10) b[S_old]--;\n            cnt[old_sig]--;\n            if (cnt[old_sig] > 0 && S_old - 1 <= 10) b[S_old - 1]++;\n            \n            if (j < 64) sig1[i] ^= (1ULL << j);\n            else sig2[i] ^= (1ULL << (j - 64));\n            \n            auto new_sig = make_pair(sig1[i], sig2[i]);\n            int S_new = cnt[new_sig];\n            if (S_new > 0 && S_new <= 10) b[S_new]--;\n            cnt[new_sig]++;\n            if (S_new + 1 <= 10) b[S_new + 1]++;\n        }\n        \n        int new_score = 0;\n        for (int d = 1; d <= 10; d++) new_score += min(a[d], b[d]);\n        \n        int diff = new_score - current_score;\n        if (diff > 0 || rand_prob(mt) < exp(diff / temp)) {\n            current_score = new_score;\n            C_int[j] = C_new;\n            if (new_score > best_score) {\n                best_score = new_score;\n                best_C = C_int;\n            }\n        } else {\n            for (int i : flipped) {\n                auto old_sig = make_pair(sig1[i], sig2[i]);\n                int S_old = cnt[old_sig];\n                if (S_old > 0 && S_old <= 10) b[S_old]--;\n                cnt[old_sig]--;\n                if (cnt[old_sig] > 0 && S_old - 1 <= 10) b[S_old - 1]++;\n                \n                if (j < 64) sig1[i] ^= (1ULL << j);\n                else sig2[i] ^= (1ULL << (j - 64));\n                \n                auto new_sig = make_pair(sig1[i], sig2[i]);\n                int S_new = cnt[new_sig];\n                if (S_new <= 10) b[S_new]--;\n                cnt[new_sig]++;\n                if (S_new + 1 <= 10) b[S_new + 1]++;\n            }\n        }\n    }\n    \n    C_int = best_C;\n    \n    cout << actual_K << \"\\n\";\n    for (int j = 0; j < actual_K; j++) {\n        long long x0 = is_vertical[j] ? 1 : 0;\n        long long y0 = is_vertical[j] ? 0 : 1;\n        \n        long long px1 = -C_int[j] * x0;\n        long long py1 = -C_int[j] * y0;\n        long long px2 = px1 + B[j];\n        long long py2 = py1 - A[j];\n        \n        cout << px1 << \" \" << py1 << \" \" << px2 << \" \" << py2 << \"\\n\";\n    }\n\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\nusing namespace chrono;\n\nint N, M, c;\nbool dot[64][64];\nvector<tuple<int,int,int,int,int,int,int,int>> ops;\nmap<int, vector<pair<int,int>>> segMap[4];\n\nint getLineType(int x1, int y1, int x2, int y2) {\n    if (x1 == x2) return 1;\n    if (y1 == y2) return 0;\n    if (x1 + y1 == x2 + y2) return 2;\n    return 3;\n}\n\nint getLineId(int type, int x, int y) {\n    if (type == 0) return y;\n    if (type == 1) return x;\n    if (type == 2) return x + y;\n    return x - y;\n}\n\nint getCoord(int type, int x, int y) {\n    return (type == 1) ? y : x;\n}\n\nbool chk(int x1, int y1, int x2, int y2) {\n    int type = getLineType(x1, y1, x2, y2);\n    int line = getLineId(type, x1, y1);\n    int lo = getCoord(type, x1, y1);\n    int hi = getCoord(type, x2, y2);\n    if (lo > hi) swap(lo, hi);\n    auto it = segMap[type].find(line);\n    if (it == segMap[type].end()) return true;\n    for (auto& seg : it->second) {\n        if (lo < seg.second && hi > seg.first) return false;\n    }\n    return true;\n}\n\nvoid add(int x1, int y1, int x2, int y2) {\n    int type = getLineType(x1, y1, x2, y2);\n    int line = getLineId(type, x1, y1);\n    int lo = getCoord(type, x1, y1);\n    int hi = getCoord(type, x2, y2);\n    if (lo > hi) swap(lo, hi);\n    segMap[type][line].push_back({lo, hi});\n}\n\nint wt(int x, int y) { int dx=x-c, dy=y-c; return dx*dx+dy*dy+1; }\nbool inBounds(int x, int y) { return x>=0 && x<N && y>=0 && y<N; }\n\nbool tryR(int tx, int ty, int x2, int y2, int x3, int y3, int x4, int y4) {\n    if (!inBounds(x2,y2) || !inBounds(x3,y3) || !inBounds(x4,y4)) return false;\n    if (!dot[x2][y2] || !dot[x3][y3] || !dot[x4][y4]) return false;\n    int xs[4]={tx,x2,x3,x4}, ys[4]={ty,y2,y3,y4};\n    for (int i=0;i<4;i++) {\n        int ni=(i+1)%4, ni2=(i+2)%4;\n        int dx1=xs[ni]-xs[i], dy1=ys[ni]-ys[i];\n        int dx2=xs[ni2]-xs[ni], dy2=ys[ni2]-ys[ni];\n        if (dx1*dx2+dy1*dy2 != 0) return false;\n    }\n    for (int i=0;i<4;i++) { int ni=(i+1)%4; if (!chk(xs[i],ys[i],xs[ni],ys[ni])) return false; }\n    for (int i=0;i<4;i++) { int ni=(i+1)%4; add(xs[i],ys[i],xs[ni],ys[ni]); }\n    dot[tx][ty]=true;\n    ops.emplace_back(tx,ty,x2,y2,x3,y3,x4,y4);\n    return true;\n}\n\nbool tryUnitSquare(int tx, int ty) {\n    for (int dx=-1;dx<=1;dx+=2) for (int dy=-1;dy<=1;dy+=2)\n        if (tryR(tx,ty,tx+dx,ty,tx+dx,ty+dy,tx,ty+dy)) return true;\n    return false;\n}\n\nbool tryUnitDiamond(int tx, int ty) {\n    int ddx[]={1,0,-1,0}, ddy[]={0,1,0,-1};\n    for (int d=0;d<4;d++) {\n        int cx=tx-ddx[d], cy=ty-ddy[d], ox[3], oy[3]; bool valid=true;\n        for (int i=0;i<3;i++) {\n            int dir=(d+1+i)%4; ox[i]=cx+ddx[dir]; oy[i]=cy+ddy[dir];\n            if (!inBounds(ox[i],oy[i]) || !dot[ox[i]][oy[i]]) { valid=false; break; }\n        }\n        if (valid && tryR(tx,ty,ox[0],oy[0],ox[1],oy[1],ox[2],oy[2])) return true;\n    }\n    return false;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    auto start=steady_clock::now();\n    cin>>N>>M; c=(N-1)/2;\n    for (int i=0;i<M;i++) { int x,y; cin>>x>>y; dot[x][y]=true; }\n    set<tuple<int,int,int>,greater<>> cand;\n    for (int x=0;x<N;x++) for (int y=0;y<N;y++) if (!dot[x][y]) cand.emplace(wt(x,y),x,y);\n    bool added=true;\n    while (added) {\n        added=false;\n        if (duration_cast<milliseconds>(steady_clock::now()-start).count()>4500) break;\n        for (auto it=cand.begin();it!=cand.end();) {\n            int x=get<1>(*it), y=get<2>(*it);\n            if (dot[x][y]) { it=cand.erase(it); continue; }\n            if (tryUnitSquare(x,y) || tryUnitDiamond(x,y)) { it=cand.erase(it); added=true; break; }\n            ++it;\n        }\n    }\n    cout<<ops.size()<<\"\\n\";\n    for (auto& op:ops) cout<<get<0>(op)<<\" \"<<get<1>(op)<<\" \"<<get<2>(op)<<\" \"<<get<3>(op)<<\" \"<<get<4>(op)<<\" \"<<get<5>(op)<<\" \"<<get<6>(op)<<\" \"<<get<7>(op)<<\"\\n\";\n    return 0;\n}","ahc015":"#include <iostream>\n#include <cstring>\n#include <vector>\n\nusing namespace std;\n\nconst int N = 10;\nint grid[N][N];\nconst int dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1};\nconst char dirs[] = {'F', 'B', 'L', 'R'};\n\nvoid tilt(char dir) {\n    if (dir == 'F') {\n        for (int c = 0; c < N; c++) { int w = 0; for (int r = 0; r < N; r++) if (grid[r][c]) { int f = grid[r][c]; grid[r][c] = 0; grid[w++][c] = f; } }\n    } else if (dir == 'B') {\n        for (int c = 0; c < N; c++) { int w = N - 1; for (int r = N - 1; r >= 0; r--) if (grid[r][c]) { int f = grid[r][c]; grid[r][c] = 0; grid[w--][c] = f; } }\n    } else if (dir == 'L') {\n        for (int r = 0; r < N; r++) { int w = 0; for (int c = 0; c < N; c++) if (grid[r][c]) { int f = grid[r][c]; grid[r][c] = 0; grid[r][w++] = f; } }\n    } else {\n        for (int r = 0; r < N; r++) { int w = N - 1; for (int c = N - 1; c >= 0; c--) if (grid[r][c]) { int f = grid[r][c]; grid[r][c] = 0; grid[r][w--] = f; } }\n    }\n}\n\nint computeSumSq() {\n    static int vis[N][N], stk[100];\n    memset(vis, 0, sizeof(vis));\n    int sumSq = 0;\n    for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) if (grid[r][c] && !vis[r][c]) {\n        int sz = 0, f = grid[r][c], top = 0;\n        stk[top++] = r * N + c; vis[r][c] = 1;\n        while (top > 0) {\n            int p = stk[--top], cr = p / N, cc = p % N; sz++;\n            for (int d = 0; d < 4; d++) {\n                int nr = cr + dr[d], nc = cc + dc[d];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N && !vis[nr][nc] && grid[nr][nc] == f) { vis[nr][nc] = 1; stk[top++] = nr * N + nc; }\n            }\n        }\n        sumSq += sz * sz;\n    }\n    return sumSq;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int flavors[100];\n    for (int i = 0; i < 100; i++) cin >> flavors[i];\n    memset(grid, 0, sizeof(grid));\n    \n    for (int t = 0; t < 100; t++) {\n        int p; cin >> p;\n        int cnt = 0, r = -1, c = -1;\n        for (int i = 0; i < N && r < 0; i++) for (int j = 0; j < N && r < 0; j++) if (!grid[i][j] && ++cnt == p) { r = i; c = j; }\n        grid[r][c] = flavors[t];\n        \n        if (t < 99) {\n            char bestDir = 'F'; int bestScore = -1;\n            int nextFlavor = flavors[t + 1];\n            \n            for (int di = 0; di < 4; di++) {\n                int saved[N][N]; memcpy(saved, grid, sizeof(grid));\n                tilt(dirs[di]);\n                int currentScore = computeSumSq();\n                \n                vector<pair<int,int>> priorityCells, otherCells;\n                for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (!grid[i][j]) {\n                    bool adjacent = false;\n                    for (int d = 0; d < 4; d++) {\n                        int ni = i + dr[d], nj = j + dc[d];\n                        if (ni >= 0 && ni < N && nj >= 0 && nj < N && grid[ni][nj] == nextFlavor) { adjacent = true; break; }\n                    }\n                    if (adjacent) priorityCells.push_back({i, j});\n                    else otherCells.push_back({i, j});\n                }\n                \n                int numEmpty = priorityCells.size() + otherCells.size();\n                int maxSamples = numEmpty <= 25 ? numEmpty : 20;\n                \n                vector<pair<int,int>> samples = priorityCells;\n                int remaining = maxSamples - samples.size();\n                if (remaining > 0 && !otherCells.empty()) {\n                    int step = max(1, (int)otherCells.size() / remaining);\n                    for (int i = 0; i < (int)otherCells.size() && samples.size() < maxSamples; i += step)\n                        samples.push_back(otherCells[i]);\n                }\n                \n                int sampleCount = samples.size();\n                int totalFutureBest = 0;\n                for (auto& [er, ec] : samples) {\n                    grid[er][ec] = nextFlavor;\n                    int bestFuture = 0;\n                    for (int d2 = 0; d2 < 4; d2++) {\n                        int saved2[N][N]; memcpy(saved2, grid, sizeof(grid));\n                        tilt(dirs[d2]);\n                        int score = computeSumSq();\n                        if (score > bestFuture) bestFuture = score;\n                        memcpy(grid, saved2, sizeof(grid));\n                    }\n                    totalFutureBest += bestFuture;\n                    grid[er][ec] = 0;\n                }\n                \n                int score = currentScore * sampleCount * 3 + totalFutureBest * 2;\n                memcpy(grid, saved, sizeof(grid));\n                if (score > bestScore) { bestScore = score; bestDir = dirs[di]; }\n            }\n            tilt(bestDir); cout << bestDir << endl;\n        }\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int M;\n    double eps;\n    cin >> M >> eps;\n    \n    int N;\n    if (eps <= 0.01) N = 8;\n    else if (eps <= 0.03) N = 10;\n    else if (eps <= 0.06) N = 12;\n    else if (eps <= 0.10) N = 16;\n    else if (eps <= 0.15) N = 22;\n    else if (eps <= 0.20) N = 28;\n    else if (eps <= 0.30) N = 40;\n    else if (eps <= 0.40) N = 60;\n    else N = 80;\n    \n    N = max(N, 4);\n    N = min(N, 100);\n    \n    int total_pairs = N * (N - 1) / 2;\n    \n    mt19937 rng(42);\n    \n    vector<string> graphs(M);\n    vector<vector<int>> sorted_deg(M, vector<int>(N));\n    \n    for (int i = 0; i < M; i++) {\n        int num_edges = (int)((i + 0.5) * total_pairs / M);\n        string g(total_pairs, '0');\n        vector<int> indices(total_pairs);\n        iota(indices.begin(), indices.end(), 0);\n        shuffle(indices.begin(), indices.end(), rng);\n        for (int j = 0; j < num_edges; j++) g[indices[j]] = '1';\n        graphs[i] = g;\n        \n        int idx = 0;\n        for (int v = 0; v < N; v++) {\n            for (int u = v + 1; u < N; u++) {\n                if (g[idx++] == '1') {\n                    sorted_deg[i][v]++;\n                    sorted_deg[i][u]++;\n                }\n            }\n        }\n        sort(sorted_deg[i].begin(), sorted_deg[i].end());\n    }\n    \n    cout << N << \"\\n\";\n    for (auto& g : graphs) cout << g << \"\\n\";\n    cout << flush;\n    \n    for (int q = 0; q < 100; q++) {\n        string H;\n        cin >> H;\n        \n        vector<int> h_deg(N);\n        int idx = 0;\n        for (int v = 0; v < N; v++) {\n            for (int u = v + 1; u < N; u++) {\n                if (H[idx++] == '1') {\n                    h_deg[v]++;\n                    h_deg[u]++;\n                }\n            }\n        }\n        sort(h_deg.begin(), h_deg.end());\n        \n        int best = 0;\n        double best_dist = 1e18;\n        for (int i = 0; i < M; i++) {\n            double dist = 0;\n            for (int j = 0; j < N; j++) {\n                double diff = h_deg[j] - sorted_deg[i][j];\n                dist += diff * diff;\n            }\n            if (dist < best_dist) {\n                best_dist = dist;\n                best = i;\n            }\n        }\n        cout << best << \"\\n\" << 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    cin >> N >> M >> D >> K;\n    \n    vector<tuple<int, int, int>> edges(M);\n    vector<vector<pair<int, int>>> adj(N);\n    \n    unsigned long long seed = N * 1000000007ULL + M * 1000003ULL + D * 1009ULL + K;\n    \n    for (int i = 0; i < M; i++) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        u--; v--;\n        edges[i] = {u, v, w};\n        adj[u].push_back({v, i});\n        adj[v].push_back({u, i});\n        seed ^= (unsigned long long)(u + 1) * 1000000007ULL + (v + 1) * 1000003ULL + w;\n    }\n    \n    for (int i = 0; i < N; i++) { int x, y; cin >> x >> y; seed ^= (unsigned long long)x * 10007ULL + y; }\n    \n    vector<long long> betweenness(M, 0);\n    mt19937 rng(seed);\n    int S = min(200, N);\n    vector<int> sources(S);\n    iota(sources.begin(), sources.end(), 0);\n    shuffle(sources.begin(), sources.end(), rng);\n    \n    for (int s : sources) {\n        vector<long long> dist(N, 1e18);\n        vector<int> parent_edge(N, -1);\n        dist[s] = 0;\n        priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> pq;\n        pq.push({0, s});\n        \n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u]) continue;\n            for (auto [v, ei] : adj[u]) {\n                if (dist[u] + get<2>(edges[ei]) < dist[v]) {\n                    dist[v] = dist[u] + get<2>(edges[ei]);\n                    parent_edge[v] = ei;\n                    pq.push({dist[v], v});\n                }\n            }\n        }\n        \n        vector<vector<int>> children(N);\n        for (int v = 0; v < N; v++) {\n            if (parent_edge[v] != -1) {\n                auto [pu, pv, pw] = edges[parent_edge[v]];\n                children[(pu == v) ? pv : pu].push_back(v);\n            }\n        }\n        \n        vector<int> subtree_size(N, 1);\n        function<void(int)> dfs = [&](int u) {\n            for (int v : children[u]) {\n                dfs(v);\n                subtree_size[u] += subtree_size[v];\n            }\n            if (parent_edge[u] != -1) betweenness[parent_edge[u]] += subtree_size[u];\n        };\n        dfs(s);\n    }\n    \n    vector<int> edge_order(M);\n    iota(edge_order.begin(), edge_order.end(), 0);\n    sort(edge_order.begin(), edge_order.end(), [&](int a, int b) {\n        return betweenness[a] > betweenness[b];\n    });\n    \n    vector<int> day_assignment(M, -1), day_count(D, 0);\n    vector<vector<int>> day_edges_list(D);\n    vector<long long> vertex_day_importance(N * D, 0);\n    \n    for (int e : edge_order) {\n        auto [u, v, w] = edges[e];\n        long long imp = betweenness[e];\n        \n        int best_day = -1;\n        long long best_conflict = LLONG_MAX;\n        for (int d = 0; d < D; d++) {\n            if (day_count[d] >= K) continue;\n            long long conflict = vertex_day_importance[u * D + d] + vertex_day_importance[v * D + d];\n            if (conflict < best_conflict) { best_conflict = conflict; best_day = d; }\n        }\n        if (best_day == -1) {\n            for (int d = 0; d < D; d++) {\n                long long conflict = vertex_day_importance[u * D + d] + vertex_day_importance[v * D + d];\n                if (conflict < best_conflict) { best_conflict = conflict; best_day = d; }\n            }\n        }\n        day_assignment[e] = best_day;\n        day_count[best_day]++;\n        day_edges_list[best_day].push_back(e);\n        vertex_day_importance[u * D + best_day] += imp;\n        vertex_day_importance[v * D + best_day] += imp;\n    }\n    \n    double temperature = 500.0;\n    for (int iter = 0; iter < 2000000; iter++) {\n        temperature *= 0.999997;\n        int d1 = rng() % D, d2 = rng() % D;\n        if (d1 == d2 || day_edges_list[d1].empty() || day_edges_list[d2].empty()) continue;\n        \n        int idx1 = rng() % day_edges_list[d1].size(), idx2 = rng() % day_edges_list[d2].size();\n        int e1 = day_edges_list[d1][idx1], e2 = day_edges_list[d2][idx2];\n        auto [u1, v1, w1] = edges[e1];\n        auto [u2, v2, w2] = edges[e2];\n        long long imp1 = betweenness[e1], imp2 = betweenness[e2];\n        \n        long long c1 = vertex_day_importance[u1 * D + d1] + vertex_day_importance[v1 * D + d1] - 2 * imp1;\n        long long c2 = vertex_day_importance[u2 * D + d2] + vertex_day_importance[v2 * D + d2] - 2 * imp2;\n        \n        long long e2_at_u1 = (u2 == u1 || v2 == u1) ? imp2 : 0;\n        long long e2_at_v1 = (u2 == v1 || v2 == v1) ? imp2 : 0;\n        long long e1_at_u2 = (u1 == u2 || v1 == u2) ? imp1 : 0;\n        long long e1_at_v2 = (u1 == v2 || v1 == v2) ? imp1 : 0;\n        \n        long long n1 = vertex_day_importance[u1 * D + d2] + vertex_day_importance[v1 * D + d2] - e2_at_u1 - e2_at_v1;\n        long long n2 = vertex_day_importance[u2 * D + d1] + vertex_day_importance[v2 * D + d1] - e1_at_u2 - e1_at_v2;\n        \n        long long delta = (n1 + n2) - (c1 + c2);\n        \n        if (delta < 0 || (temperature > 0.001 && (double)(rng() % 100000) / 100000.0 < exp(-(double)delta / max(temperature, 1.0)))) {\n            day_assignment[e1] = d2; day_assignment[e2] = d1;\n            vertex_day_importance[u1 * D + d1] -= imp1; vertex_day_importance[v1 * D + d1] -= imp1;\n            vertex_day_importance[u1 * D + d2] += imp1; vertex_day_importance[v1 * D + d2] += imp1;\n            vertex_day_importance[u2 * D + d2] -= imp2; vertex_day_importance[v2 * D + d2] -= imp2;\n            vertex_day_importance[u2 * D + d1] += imp2; vertex_day_importance[v2 * D + d1] += imp2;\n            day_edges_list[d1][idx1] = e2; day_edges_list[d2][idx2] = e1;\n        }\n    }\n    \n    for (int i = 0; i < M; i++) cout << day_assignment[i] + 1 << \" \\n\"[i == M - 1];\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\nusing namespace chrono;\n\nint D, b[2][15][15][15], n, rots[24][3][3], numRots=0;\nset<tuple<int,int,int>> V[2];\nhigh_resolution_clock::time_point start_time;\n\nvoid generateRotations() {\n    set<vector<int>> seen; queue<vector<int>> q;\n    vector<int> id={1,0,0,0,1,0,0,0,1},rx={1,0,0,0,0,-1,0,1,0},ry={0,0,1,0,1,0,-1,0,0},rz={0,-1,0,1,0,0,0,0,1};\n    q.push(id); seen.insert(id);\n    auto mul=[](vector<int> a,vector<int> b){vector<int> c(9);for(int i=0;i<3;i++)for(int j=0;j<3;j++){c[i*3+j]=0;for(int k=0;k<3;k++)c[i*3+j]+=a[i*3+k]*b[k*3+j];}return c;};\n    while(!q.empty()){auto cur=q.front();q.pop();for(int i=0;i<9;i++)rots[numRots][i/3][i%3]=cur[i];numRots++;for(auto&base:{rx,ry,rz}){auto nx=mul(cur,base);if(!seen.count(nx)){seen.insert(nx);q.push(nx);}}}\n}\n\nstring canonical(const vector<tuple<int,int,int>>& cubes) {\n    string best;\n    for(int r=0;r<24;r++){\n        vector<tuple<int,int,int>> rot;\n        int mx=INT_MAX,my=INT_MAX,mz=INT_MAX;\n        for(auto&[x,y,z]:cubes){\n            int nx=rots[r][0][0]*x+rots[r][0][1]*y+rots[r][0][2]*z;\n            int ny=rots[r][1][0]*x+rots[r][1][1]*y+rots[r][1][2]*z;\n            int nz=rots[r][2][0]*x+rots[r][2][1]*y+rots[r][2][2]*z;\n            mx=min(mx,nx);my=min(my,ny);mz=min(mz,nz);\n            rot.push_back({nx,ny,nz});\n        }\n        sort(rot.begin(),rot.end());\n        string s;\n        for(auto&[x,y,z]:rot){s+=char(x-mx+'a');s+=char(y-my+'a');s+=char(z-mz+'a');}\n        if(best.empty()||s<best)best=s;\n    }\n    return best;\n}\n\nvoid findComponents(set<tuple<int,int,int>>& V, vector<vector<tuple<int,int,int>>>& comps) {\n    set<tuple<int,int,int>> rem=V; int dx[]={1,-1,0,0,0,0},dy[]={0,0,1,-1,0,0},dz[]={0,0,0,0,1,-1};\n    while(!rem.empty()){auto[sx,sy,sz]=*rem.begin();rem.erase(rem.begin());vector<tuple<int,int,int>> comp;comp.push_back({sx,sy,sz});queue<tuple<int,int,int>> q;q.push({sx,sy,sz});\n    while(!q.empty()){auto[x,y,z]=q.front();q.pop();for(int d=0;d<6;d++){int nx=x+dx[d],ny=y+dy[d],nz=z+dz[d];auto np=make_tuple(nx,ny,nz);if(rem.count(np)){rem.erase(np);comp.push_back(np);q.push(np);}}}comps.push_back(comp);}\n}\n\ntuple<int,int,tuple<int,int,int>> findBestAlignment(set<tuple<int,int,int>>& V0, set<tuple<int,int,int>>& V1) {\n    int best_count=0; tuple<int,int,int> best_trans; int best_rot=-1;\n    for(int rot=0;rot<24;rot++){\n        vector<tuple<int,int,int>> br1;\n        for(auto&[x,y,z]:V1){int bx=rots[rot][0][0]*x+rots[rot][0][1]*y+rots[rot][0][2]*z,by=rots[rot][1][0]*x+rots[rot][1][1]*y+rots[rot][1][2]*z,bz=rots[rot][2][0]*x+rots[rot][2][1]*y+rots[rot][2][2]*z;br1.push_back({bx,by,bz});}\n        map<tuple<int,int,int>,int> tc;\n        for(auto&[x0,y0,z0]:V0)for(auto&[bx,by,bz]:br1)tc[{x0-bx,y0-by,z0-bz}]++;\n        for(auto&[trans,count]:tc)if(count>best_count){best_count=count;best_trans=trans;best_rot=rot;}\n    }\n    return {best_count,best_rot,best_trans};\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr); start_time=high_resolution_clock::now();\n    generateRotations(); cin>>D; int f[2][15][15],r[2][15][15];\n    for(int i=0;i<2;i++){for(int z=0;z<D;z++){string s;cin>>s;for(int x=0;x<D;x++)f[i][z][x]=s[x]-'0';}for(int z=0;z<D;z++){string s;cin>>s;for(int y=0;y<D;y++)r[i][z][y]=s[y]-'0';}}\n    for(int i=0;i<2;i++)for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++)if(f[i][z][x]&&r[i][z][y])V[i].insert({x,y,z});\n    memset(b,0,sizeof(b)); n=0; set<tuple<int,int,int>> rem[2]={V[0],V[1]};\n    auto check_time=[&](){return duration_cast<milliseconds>(high_resolution_clock::now()-start_time).count();};\n    while(!rem[0].empty()&&!rem[1].empty()){if(check_time()>3500)break;\n    auto[count,rot,trans]=findBestAlignment(rem[0],rem[1]);if(count<3)break;\n    set<tuple<int,int,int>> m0;for(auto&[x,y,z]:rem[0]){int rx=rots[rot][0][0]*(x-get<0>(trans))+rots[rot][1][0]*(y-get<1>(trans))+rots[rot][2][0]*(z-get<2>(trans)),ry=rots[rot][0][1]*(x-get<0>(trans))+rots[rot][1][1]*(y-get<1>(trans))+rots[rot][2][1]*(z-get<2>(trans)),rz=rots[rot][0][2]*(x-get<0>(trans))+rots[rot][1][2]*(y-get<1>(trans))+rots[rot][2][2]*(z-get<2>(trans));if(rem[1].count({rx,ry,rz}))m0.insert({x,y,z});}\n    vector<vector<tuple<int,int,int>>> comps;findComponents(m0,comps);\n    for(auto&comp:comps){n++;for(auto&[x,y,z]:comp){b[0][x][y][z]=n;int rx=rots[rot][0][0]*(x-get<0>(trans))+rots[rot][1][0]*(y-get<1>(trans))+rots[rot][2][0]*(z-get<2>(trans)),ry=rots[rot][0][1]*(x-get<0>(trans))+rots[rot][1][1]*(y-get<1>(trans))+rots[rot][2][1]*(z-get<2>(trans)),rz=rots[rot][0][2]*(x-get<0>(trans))+rots[rot][1][2]*(y-get<1>(trans))+rots[rot][2][2]*(z-get<2>(trans));b[1][rx][ry][rz]=n;rem[0].erase({x,y,z});rem[1].erase({rx,ry,rz});}}}\n    vector<vector<tuple<int,int,int>>> comps[2];findComponents(rem[0],comps[0]);findComponents(rem[1],comps[1]);\n    map<string,vector<pair<int,int>>> canon_map;vector<bool> comp_used[2];comp_used[0].resize(comps[0].size());comp_used[1].resize(comps[1].size());\n    for(int i=0;i<2;i++)for(int j=0;j<(int)comps[i].size();j++){auto&comp=comps[i][j];vector<tuple<int,int,int>> norm=comp;int mx=INT_MAX,my=INT_MAX,mz=INT_MAX;for(auto&[x,y,z]:norm){mx=min(mx,x);my=min(my,y);mz=min(mz,z);}for(auto&[x,y,z]:norm){x-=mx;y-=my;z-=mz;}canon_map[canonical(norm)].push_back({i,j});}\n    for(auto&[c,entries]:canon_map){vector<int> idx[2];for(auto&[obj,comp]:entries)idx[obj].push_back(comp);int pairs=min(idx[0].size(),idx[1].size());for(int p=0;p<pairs;p++){int i0=idx[0][p],i1=idx[1][p];comp_used[0][i0]=comp_used[1][i1]=true;n++;for(auto&[x,y,z]:comps[0][i0])b[0][x][y][z]=n;for(auto&[x,y,z]:comps[1][i1])b[1][x][y][z]=n;}}\n    for(int i=0;i<2;i++)for(int j=0;j<(int)comps[i].size();j++)if(!comp_used[i][j])for(auto&[x,y,z]:comps[i][j]){n++;b[i][x][y][z]=n;}\n    cout<<n<<'\\n';for(int i=0;i<2;i++){string out;for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){if(!out.empty())out+=' ';out+=to_string(b[i][x][y][z]);}cout<<out<<'\\n';}\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\ntypedef long long ll;\n\nstruct EdgeInfo { int to, idx; ll w; };\n\nint min_power(ll d2) {\n    if (d2 <= 0) return 0;\n    int r = (int)sqrt((double)d2);\n    while ((ll)r * r < d2) r++;\n    return r;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K;\n    cin >> N >> M >> K;\n    \n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    \n    vector<tuple<int, int, ll>> edges(M);\n    vector<vector<EdgeInfo>> adj(N);\n    for (int j = 0; j < M; j++) {\n        int u, v; ll w;\n        cin >> u >> v >> w;\n        u--; v--;\n        edges[j] = {u, v, w};\n        adj[u].push_back({v, j, w});\n        adj[v].push_back({u, j, w});\n    }\n    \n    vector<int> a(K), b(K);\n    for (int k = 0; k < K; k++) cin >> a[k] >> b[k];\n    \n    vector<vector<ll>> dist2(K, vector<ll>(N));\n    for (int k = 0; k < K; k++)\n        for (int i = 0; i < N; i++) {\n            ll dx = (ll)(x[i] - a[k]), dy = (ll)(y[i] - b[k]);\n            dist2[k][i] = dx * dx + dy * dy;\n        }\n    \n    vector<int> closest(K);\n    for (int k = 0; k < K; k++) {\n        ll min_d2 = LLONG_MAX; int mv = 0;\n        for (int i = 0; i < N; i++)\n            if (dist2[k][i] <= (ll)5000 * 5000 && dist2[k][i] < min_d2)\n                { min_d2 = dist2[k][i]; mv = i; }\n        closest[k] = mv;\n    }\n    \n    vector<bool> needed(N, false);\n    for (int k = 0; k < K; k++) needed[closest[k]] = true;\n    needed[0] = true;\n    \n    vector<ll> shortest_dist(N, LLONG_MAX);\n    vector<int> prev_edge(N, -1);\n    shortest_dist[0] = 0;\n    priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<>> pq;\n    pq.push({0, 0});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top(); pq.pop();\n        if (d > shortest_dist[u]) continue;\n        for (auto& e : adj[u])\n            if (shortest_dist[u] + e.w < shortest_dist[e.to]) {\n                shortest_dist[e.to] = shortest_dist[u] + e.w;\n                prev_edge[e.to] = e.idx;\n                pq.push({shortest_dist[e.to], e.to});\n            }\n    }\n    \n    vector<bool> edge_used(M, false);\n    for (int i = 0; i < N; i++)\n        if (needed[i] && i != 0) {\n            int v = i;\n            while (v != 0 && prev_edge[v] != -1) {\n                edge_used[prev_edge[v]] = true;\n                int ei = prev_edge[v];\n                v = (get<0>(edges[ei]) == v) ? get<1>(edges[ei]) : get<0>(edges[ei]);\n            }\n        }\n    \n    vector<bool> keep(N, false);\n    keep[0] = true;\n    bool changed = true;\n    while (changed) {\n        changed = false;\n        for (int idx = 0; idx < M; idx++)\n            if (edge_used[idx]) {\n                int u = get<0>(edges[idx]), v = get<1>(edges[idx]);\n                if (keep[u] && !keep[v]) { keep[v] = true; changed = true; }\n                if (keep[v] && !keep[u]) { keep[u] = true; changed = true; }\n            }\n    }\n    \n    vector<int> P(N, 0);\n    for (int k = 0; k < K; k++) {\n        ll min_d2 = LLONG_MAX; int mv = -1;\n        for (int i = 0; i < N; i++)\n            if (keep[i] && dist2[k][i] <= (ll)5000 * 5000 && dist2[k][i] < min_d2)\n                { min_d2 = dist2[k][i]; mv = i; }\n        if (mv != -1) P[mv] = max(P[mv], min_power(min_d2) + 1);\n    }\n    \n    for (int i = 0; i < N; i++) cout << P[i] << \" \\n\"[i == N - 1];\n    for (int j = 0; j < M; j++) cout << edge_used[j] << \" \\n\"[j == M - 1];\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N = 30;\nint grid[30][30];\n\nvoid sift_down(int x, int y, vector<tuple<int,int,int,int>>& ops) {\n    while (x < N - 1 && ops.size() < 10000) {\n        int v = grid[x][y];\n        int c1 = grid[x+1][y];\n        int c2 = grid[x+1][y+1];\n        \n        if (v < c1 && v < c2) break;\n        \n        if (c1 <= c2) {\n            swap(grid[x][y], grid[x+1][y]);\n            ops.push_back({x, y, x+1, y});\n            x++;\n        } else {\n            swap(grid[x][y], grid[x+1][y+1]);\n            ops.push_back({x, y, x+1, y+1});\n            x++;\n            y++;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \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    vector<tuple<int,int,int,int>> ops;\n    \n    for (int pass = 0; pass < 50 && ops.size() < 10000; pass++) {\n        bool changed = false;\n        for (int x = N - 2; x >= 0 && ops.size() < 10000; x--) {\n            for (int y = 0; y <= x && ops.size() < 10000; y++) {\n                int v = grid[x][y];\n                if (v < grid[x+1][y] && v < grid[x+1][y+1]) continue;\n                sift_down(x, y, ops);\n                changed = true;\n            }\n        }\n        if (!changed) break;\n    }\n    \n    cout << ops.size() << \"\\n\";\n    for (auto& [x1, y1, x2, y2] : ops) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << \"\\n\";\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D, N, grid[9][9], container_num[9][9], init_dist[9][9];\nint di[] = {0, 0, 1, -1}, dj[] = {1, -1, 0, 0};\nint entrance_i = 0, entrance_j;\nvector<pair<int,int>> all_cells_sorted;\n\nvoid compute_init_dist() {\n    queue<pair<int,int>> q;\n    memset(init_dist, -1, sizeof(init_dist));\n    init_dist[entrance_i][entrance_j] = 0;\n    q.push({entrance_i, entrance_j});\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int ni = i + di[d], nj = j + dj[d];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && init_dist[ni][nj] == -1 && grid[ni][nj] != 1) {\n                init_dist[ni][nj] = init_dist[i][j] + 1;\n                q.push({ni, nj});\n            }\n        }\n    }\n    for (int i = 0; i < D; i++)\n        for (int j = 0; j < D; j++)\n            if ((i != entrance_i || j != entrance_j) && grid[i][j] != 1)\n                all_cells_sorted.push_back({i, j});\n    sort(all_cells_sorted.begin(), all_cells_sorted.end(), [](auto& a, auto& b) {\n        return tie(init_dist[a.first][a.second], a.first, a.second) < tie(init_dist[b.first][b.second], b.first, b.second);\n    });\n}\n\nvector<pair<int,int>> get_reachable_empty() {\n    vector<pair<int,int>> cells;\n    queue<pair<int,int>> q;\n    int visited[9][9] = {};\n    visited[entrance_i][entrance_j] = 1;\n    q.push({entrance_i, entrance_j});\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        if ((i != entrance_i || j != entrance_j) && grid[i][j] == 0) cells.push_back({i, j});\n        for (int d = 0; d < 4; d++) {\n            int ni = i + di[d], nj = j + dj[d];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && !visited[ni][nj] && grid[ni][nj] == 0) {\n                visited[ni][nj] = 1;\n                q.push({ni, nj});\n            }\n        }\n    }\n    return cells;\n}\n\nvector<pair<int,int>> get_reachable_containers() {\n    vector<pair<int,int>> cells;\n    queue<pair<int,int>> q;\n    int visited[9][9] = {};\n    visited[entrance_i][entrance_j] = 1;\n    q.push({entrance_i, entrance_j});\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int ni = i + di[d], nj = j + dj[d];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && !visited[ni][nj]) {\n                visited[ni][nj] = 1;\n                if (grid[ni][nj] == 2) cells.push_back({ni, nj});\n                else if (grid[ni][nj] == 0) q.push({ni, nj});\n            }\n        }\n    }\n    return cells;\n}\n\npair<int,int> find_placement(int t, int total) {\n    auto cells = get_reachable_empty();\n    if (cells.empty()) return {-1, -1};\n    int ideal_dist = init_dist[all_cells_sorted[t].first][all_cells_sorted[t].second];\n    sort(cells.begin(), cells.end(), [ideal_dist](auto& a, auto& b) {\n        int da = abs(init_dist[a.first][a.second] - ideal_dist);\n        int db = abs(init_dist[b.first][b.second] - ideal_dist);\n        if (da != db) return da < db;\n        int ea = 0, eb = 0;\n        for (int d = 0; d < 4; d++) {\n            int ni = a.first + di[d], nj = a.second + dj[d];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && grid[ni][nj] == 0 && !(ni == entrance_i && nj == entrance_j)) ea++;\n            ni = b.first + di[d]; nj = b.second + dj[d];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && grid[ni][nj] == 0 && !(ni == entrance_i && nj == entrance_j)) eb++;\n        }\n        return tie(ea, a.first, a.second) < tie(eb, b.first, b.second);\n    });\n    return cells[0];\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> D >> N;\n    entrance_j = (D - 1) / 2;\n    memset(grid, 0, sizeof(grid));\n    memset(container_num, -1, sizeof(container_num));\n    for (int i = 0; i < N; i++) { int ri, rj; cin >> ri >> rj; grid[ri][rj] = 1; }\n    int total = D * D - 1 - N;\n    compute_init_dist();\n    for (int d = 0; d < total; d++) {\n        int t; cin >> t;\n        auto [pi, pj] = find_placement(t, total);\n        grid[pi][pj] = 2;\n        container_num[pi][pj] = t;\n        cout << pi << \" \" << pj << \"\\n\" << flush;\n    }\n    for (int d = 0; d < total; d++) {\n        auto containers = get_reachable_containers();\n        int best_num = INT_MAX;\n        pair<int,int> best_pos = {-1, -1};\n        for (auto& [i, j] : containers)\n            if (container_num[i][j] < best_num) { best_num = container_num[i][j]; best_pos = {i, j}; }\n        grid[best_pos.first][best_pos.second] = 0;\n        cout << best_pos.first << \" \" << best_pos.second << \"\\n\" << flush;\n    }\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\nusing namespace std::chrono;\n\nint n, m;\nint grid[50][50];\nint original_grid[50][50];\nset<int> adj_set[101];\nset<pair<int,int>> original_adj;\nvector<pair<int,int>> color_pos[101];\nint adj_cnt[101][101];\nint boundary_cnt[101];\nint color_cnt[101];\n\nint dr[] = {0, 0, 1, -1};\nint dc[] = {1, -1, 0, 0};\n\nint vis_gen[50][50];\nint cur_gen = 0;\n\nbool is_connected(int color, int er, int ec) {\n    int cnt = color_cnt[color] - 1;\n    if (cnt <= 1) return true;\n    cur_gen++;\n    int sr = -1, sc = -1;\n    for (auto& [i, j] : color_pos[color]) {\n        if (grid[i][j] != color || (i == er && j == ec)) continue;\n        sr = i; sc = j; break;\n    }\n    if (sr == -1) return true;\n    queue<pair<int,int>> q;\n    q.push({sr, sc}); vis_gen[sr][sc] = cur_gen; int vc = 1;\n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nr = r + dr[d], nc = c + dc[d];\n            if (nr < 0 || nr >= n || nc < 0 || nc >= n) continue;\n            if (vis_gen[nr][nc] == cur_gen || (nr == er && nc == ec)) continue;\n            if (grid[nr][nc] == color) { vis_gen[nr][nc] = cur_gen; vc++; q.push({nr, nc}); }\n        }\n    }\n    return vc == cnt;\n}\n\nbool would_zero_connect(int r, int c) {\n    if (r == 0 || r == n-1 || c == 0 || c == n-1) return true;\n    for (int d = 0; d < 4; d++) {\n        int nr = r + dr[d], nc = c + dc[d];\n        if (nr >= 0 && nr < n && nc >= 0 && nc < n && grid[nr][nc] == 0) return true;\n    }\n    return false;\n}\n\nbool can_remove(int r, int c, int min_edges) {\n    int color = grid[r][c];\n    if (color == 0) return false;\n    int same = 0, boundary_here = 0, regular0_here = 0;\n    for (int d = 0; d < 4; d++) {\n        int nr = r + dr[d], nc = c + dc[d];\n        if (nr < 0 || nr >= n || nc < 0 || nc >= n) boundary_here++;\n        else if (grid[nr][nc] == color) same++;\n        else if (grid[nr][nc] == 0) regular0_here++;\n    }\n    if (same == 0) return false;\n    if (!adj_set[0].count(color)) return false;\n    if (!would_zero_connect(r, c)) return false;\n    if (boundary_cnt[color] + adj_cnt[color][0] + same - boundary_here - regular0_here <= 0) return false;\n    if (!is_connected(color, r, c)) return false;\n    for (int d = 0; d < 4; d++) {\n        int nr = r + dr[d], nc = c + dc[d];\n        if (nr < 0 || nr >= n || nc < 0 || nc >= n) continue;\n        int nb = grid[nr][nc];\n        if (nb == color || nb == 0) continue;\n        if (!adj_set[0].count(nb)) return false;\n        if (adj_cnt[color][nb] <= min_edges) return false;\n    }\n    return true;\n}\n\nbool verify() {\n    set<pair<int,int>> output_adj;\n    for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) {\n        int color = grid[i][j];\n        for (int d = 0; d < 4; d++) {\n            int nr = i + dr[d], nc = j + dc[d];\n            int nb = (nr < 0 || nr >= n || nc < 0 || nc >= n) ? 0 : grid[nr][nc];\n            if (nb != color) {\n                int lo = min(color, nb), hi = max(color, nb);\n                output_adj.insert({lo, hi});\n            }\n        }\n    }\n    for (auto [c, nb] : original_adj) {\n        if (output_adj.find({c, nb}) == output_adj.end()) return false;\n    }\n    for (auto [c, nb] : output_adj) {\n        if (original_adj.find({c, nb}) == original_adj.end()) return false;\n    }\n    for (int color = 1; color <= m; color++) {\n        cur_gen++; int cnt = 0, sr = -1, sc = -1;\n        for (auto& [i, j] : color_pos[color]) {\n            if (grid[i][j] != color) continue;\n            if (sr == -1) { sr = i; sc = j; }\n            cnt++;\n        }\n        if (cnt == 0) return false;\n        if (cnt == 1) continue;\n        queue<pair<int,int>> q;\n        q.push({sr, sc}); vis_gen[sr][sc] = cur_gen; int vc = 1;\n        while (!q.empty()) {\n            auto [r, c] = q.front(); q.pop();\n            for (int d = 0; d < 4; d++) {\n                int nr = r + dr[d], nc = c + dc[d];\n                if (nr < 0 || nr >= n || nc < 0 || nc >= n) continue;\n                if (vis_gen[nr][nc] == cur_gen) continue;\n                if (grid[nr][nc] == color) { vis_gen[nr][nc] = cur_gen; vc++; q.push({nr, nc}); }\n            }\n        }\n        if (vc != cnt) return false;\n    }\n    cur_gen++;\n    queue<pair<int,int>> q;\n    for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) {\n        if (grid[i][j] == 0 && (i == 0 || i == n-1 || j == 0 || j == n-1)) {\n            q.push({i, j}); vis_gen[i][j] = cur_gen;\n        }\n    }\n    int zcnt = 0;\n    for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) if (grid[i][j] == 0) zcnt++;\n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop(); zcnt--;\n        for (int d = 0; d < 4; d++) {\n            int nr = r + dr[d], nc = c + dc[d];\n            if (nr < 0 || nr >= n || nc < 0 || nc >= n) continue;\n            if (vis_gen[nr][nc] == cur_gen || grid[nr][nc] != 0) continue;\n            vis_gen[nr][nc] = cur_gen; q.push({nr, nc});\n        }\n    }\n    return zcnt == 0;\n}\n\nvoid run_removal(int min_edges) {\n    for (int color = 1; color <= m; color++) {\n        vector<tuple<int,int,int>> tiles;\n        for (auto& [i, j] : color_pos[color]) {\n            if (grid[i][j] != color) continue;\n            int same = 0;\n            for (int d = 0; d < 4; d++) { int nr = i + dr[d], nc = j + dc[d]; if (nr >= 0 && nr < n && nc >= 0 && nc < n && grid[nr][nc] == color) same++; }\n            tiles.push_back({same, i, j});\n        }\n        sort(tiles.begin(), tiles.end());\n        for (auto& [_, r, c] : tiles) {\n            if (grid[r][c] != color) continue;\n            if (can_remove(r, c, min_edges)) {\n                for (int d = 0; d < 4; d++) {\n                    int nr = r + dr[d], nc = c + dc[d];\n                    if (nr < 0 || nr >= n || nc < 0 || nc >= n) boundary_cnt[color]--;\n                    else {\n                        int nb = grid[nr][nc];\n                        if (nb == color) adj_cnt[color][0]++;\n                        else if (nb == 0) adj_cnt[color][0]--;\n                        else { adj_cnt[color][nb]--; adj_cnt[nb][color]--; adj_cnt[nb][0]++; }\n                    }\n                }\n                grid[r][c] = 0; color_cnt[color]--;\n            }\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(NULL);\n    cin >> n >> m;\n    memset(adj_cnt, 0, sizeof(adj_cnt));\n    memset(boundary_cnt, 0, sizeof(boundary_cnt));\n    memset(color_cnt, 0, sizeof(color_cnt));\n    for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { \n        cin >> grid[i][j]; original_grid[i][j] = grid[i][j]; color_pos[grid[i][j]].push_back({i, j}); color_cnt[grid[i][j]]++;\n    }\n    for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) {\n        int color = grid[i][j];\n        for (int d = 0; d < 4; d++) {\n            int nr = i + dr[d], nc = j + dc[d];\n            int nb = (nr < 0 || nr >= n || nc < 0 || nc >= n) ? 0 : grid[nr][nc];\n            if (nb != color) {\n                int lo = min(color, nb), hi = max(color, nb);\n                original_adj.insert({lo, hi});\n                if (nb == 0) { boundary_cnt[color]++; adj_set[color].insert(0); adj_set[0].insert(color); }\n                else { adj_cnt[color][nb]++; adj_set[color].insert(nb); adj_set[nb].insert(color); }\n            }\n        }\n    }\n    for (int min_edges = 1; min_edges <= 3; min_edges++) {\n        memcpy(grid, original_grid, sizeof(grid));\n        memset(adj_cnt, 0, sizeof(adj_cnt));\n        memset(boundary_cnt, 0, sizeof(boundary_cnt));\n        memset(color_cnt, 0, sizeof(color_cnt));\n        for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) color_cnt[grid[i][j]]++;\n        for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) {\n            int color = grid[i][j];\n            for (int d = 0; d < 4; d++) {\n                int nr = i + dr[d], nc = j + dc[d];\n                if (nr < 0 || nr >= n || nc < 0 || nc >= n) boundary_cnt[color]++;\n                else if (grid[nr][nc] != color) adj_cnt[color][grid[nr][nc]]++;\n            }\n        }\n        run_removal(min_edges);\n        if (verify()) break;\n    }\n    if (!verify()) memcpy(grid, original_grid, sizeof(grid));\n    for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { cout << grid[i][j]; if (j < n-1) cout << \" \"; } cout << \"\\n\"; }\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <numeric>\n\nusing namespace std;\n\nint N, D, Q;\n\nchar query(int x, int y) {\n    cout << \"1 1 \" << x << \" \" << y << \"\\n\" << flush;\n    char res;\n    cin >> res;\n    return res;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    if (!(cin >> N >> D >> Q)) return 0;\n    \n    // Distribute queries equally among all items to guarantee none are left unqueried\n    int B = Q / N;\n    if (B == 0) B = 1; // Safety check for edge cases\n    \n    vector<vector<int>> adj(N);\n    vector<int> sorted_items;\n    vector<int> unsorted_items;\n    for (int i = 0; i < N; ++i) {\n        unsorted_items.push_back(i);\n    }\n    \n    int q_left = Q;\n    \n    while (!unsorted_items.empty()) {\n        int x = unsorted_items.back();\n        unsorted_items.pop_back();\n        \n        if (!sorted_items.empty()) {\n            int lo = 0, hi = sorted_items.size();\n            int steps = 0;\n            // Bounded binary insertion: strictly limit to B queries per item\n            while (steps < B && lo < hi) {\n                int mid = (lo + hi) / 2;\n                int y = sorted_items[mid];\n                q_left--;\n                steps++;\n                char res = query(x, y);\n                if (res == '>') {\n                    adj[y].push_back(x); // x is heavier than y\n                    lo = mid + 1;\n                } else if (res == '<') {\n                    adj[x].push_back(y); // x is lighter than y\n                    hi = mid;\n                } else {\n                    break;\n                }\n            }\n            sorted_items.insert(sorted_items.begin() + lo, x);\n        } else {\n            if (!unsorted_items.empty()) {\n                int y = unsorted_items.back();\n                unsorted_items.pop_back();\n                q_left--;\n                char res = query(x, y);\n                if (res == '>') {\n                    adj[y].push_back(x);\n                    sorted_items.push_back(y);\n                    sorted_items.push_back(x);\n                } else if (res == '<') {\n                    adj[x].push_back(y);\n                    sorted_items.push_back(x);\n                    sorted_items.push_back(y);\n                } else {\n                    sorted_items.push_back(x);\n                    sorted_items.push_back(y);\n                }\n            } else {\n                sorted_items.push_back(x);\n            }\n        }\n    }\n    \n    // Fulfill remaining query quota with dummy queries if B was generous\n    while (q_left > 0) {\n        query(0, 1);\n        q_left--;\n    }\n    \n    // Compute longest path from sources in the DAG using Kahn's algorithm\n    vector<int> in_degree(N, 0);\n    for (int i = 0; i < N; ++i) {\n        for (int j : adj[i]) {\n            in_degree[j]++;\n        }\n    }\n    \n    queue<int> q;\n    for (int i = 0; i < N; ++i) {\n        if (in_degree[i] == 0) q.push(i);\n    }\n    \n    vector<int> dp(N, 0);\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : adj[u]) {\n            if (dp[v] < dp[u] + 1) {\n                dp[v] = dp[u] + 1;\n            }\n            in_degree[v]--;\n            if (in_degree[v] == 0) {\n                q.push(v);\n            }\n        }\n    }\n    \n    // Sort all items by their longest path value (ascending)\n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n    sort(items.begin(), items.end(), [&](int a, int b) {\n        if (dp[a] != dp[b]) return dp[a] < dp[b];\n        return a < b; // Tie-breaker\n    });\n    \n    // Map ranks to expected weights of exponential distribution order statistics\n    double W_max = 100000.0 * N / D;\n    vector<double> expected_w(N);\n    double sum = 0;\n    for (int i = 0; i < N; ++i) {\n        sum += 100000.0 / (N - i);\n        expected_w[i] = min(sum, W_max);\n    }\n    \n    // Greedy partitioning based on expected weights\n    vector<double> set_sums(D, 0);\n    vector<int> partition(N);\n    double total_sum = accumulate(expected_w.begin(), expected_w.end(), 0.0);\n    double target_sum = total_sum / D;\n    \n    // Process from largest expected weight to smallest\n    for (int i = N - 1; i >= 0; --i) {\n        int item = items[i];\n        double w = expected_w[i];\n        \n        int best_set = -1;\n        double max_deficit = 0;\n        for (int j = 0; j < D; ++j) {\n            double deficit = target_sum - set_sums[j];\n            if (deficit > max_deficit) {\n                max_deficit = deficit;\n                best_set = j;\n            }\n        }\n        \n        // Fallback if all sets exceed the target sum\n        if (best_set == -1) {\n            best_set = 0;\n            for (int j = 1; j < D; ++j) {\n                if (set_sums[j] < set_sums[best_set]) {\n                    best_set = j;\n                }\n            }\n        }\n        \n        set_sums[best_set] += w;\n        partition[item] = best_set;\n    }\n    \n    // Output the final division mapping\n    for (int i = 0; i < N; ++i) {\n        cout << partition[i] << (i == N - 1 ? \"\" : \" \");\n    }\n    cout << \"\\n\" << flush;\n    \n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> stacks(m);\n    vector<int> pos(n + 1), idx(n + 1);\n    \n    for (int i = 0; i < m; i++) {\n        stacks[i].resize(n / m);\n        for (int j = 0; j < n / m; j++) {\n            cin >> stacks[i][j];\n            pos[stacks[i][j]] = i;\n            idx[stacks[i][j]] = j;\n        }\n    }\n    \n    vector<bool> isClean(m, true);\n    for (int i = 0; i < m; i++) {\n        for (int j = 0; j < (int)stacks[i].size() - 1; j++) {\n            if (stacks[i][j] < stacks[i][j + 1]) { isClean[i] = false; break; }\n        }\n    }\n    \n    auto updateClean = [&](int s) {\n        isClean[s] = true;\n        for (int j = 0; j < (int)stacks[s].size() - 1; j++) {\n            if (stacks[s][j] < stacks[s][j + 1]) { isClean[s] = false; break; }\n        }\n    };\n    \n    vector<pair<int, int>> operations;\n    int nextBox = 1;\n    \n    while (nextBox <= n) {\n        int si = pos[nextBox], pi = idx[nextBox];\n        \n        if (pi == (int)stacks[si].size() - 1) {\n            operations.push_back({nextBox, 0});\n            stacks[si].pop_back();\n            updateClean(si);\n            nextBox++;\n        } else {\n            vector<int> seq(stacks[si].begin() + pi + 1, stacks[si].end());\n            \n            vector<int> splitAfter;\n            for (int i = 0; i < (int)seq.size() - 1; i++) {\n                if (seq[i] < seq[i + 1]) splitAfter.push_back(i);\n            }\n            \n            vector<vector<int>> pieces;\n            int start = 0;\n            for (int sp : splitAfter) {\n                pieces.push_back(vector<int>(seq.begin() + start, seq.begin() + sp + 1));\n                start = sp + 1;\n            }\n            pieces.push_back(vector<int>(seq.begin() + start, seq.end()));\n            reverse(pieces.begin(), pieces.end());\n            \n            for (auto& piece : pieces) {\n                int moveFrom = piece[0];\n                int origStack = pos[moveFrom];\n                \n                int bestDest = -1, bestScore = -1e9;\n                for (int i = 0; i < m; i++) {\n                    if (i == origStack) continue;\n                    int score;\n                    if (stacks[i].empty()) {\n                        score = 350;\n                    } else if (isClean[i] && stacks[i].back() >= moveFrom) {\n                        score = 601 - stacks[i].back();\n                    } else if (stacks[i].back() >= moveFrom) {\n                        score = 201 - stacks[i].back();\n                    } else {\n                        score = -999 + stacks[i].back();\n                    }\n                    if (score > bestScore || (score == bestScore && bestDest != -1 && stacks[i].size() < stacks[bestDest].size())) {\n                        bestScore = score; bestDest = i;\n                    }\n                }\n                \n                bool wasEmpty = stacks[bestDest].empty();\n                bool wasCleanDest = isClean[bestDest];\n                int oldBack = wasEmpty ? -1 : stacks[bestDest].back();\n                bool compatible = wasEmpty || (oldBack >= moveFrom);\n                \n                operations.push_back({moveFrom, bestDest + 1});\n                \n                int origIdx = idx[moveFrom];\n                for (int j = origIdx; j < (int)stacks[origStack].size(); j++) {\n                    int v = stacks[origStack][j];\n                    stacks[bestDest].push_back(v);\n                    pos[v] = bestDest;\n                    idx[v] = stacks[bestDest].size() - 1;\n                }\n                stacks[origStack].resize(origIdx);\n                \n                isClean[bestDest] = wasEmpty ? true : (wasCleanDest && compatible);\n                updateClean(origStack);\n            }\n        }\n    }\n    \n    for (auto& op : operations) cout << op.first << \" \" << op.second << \"\\n\";\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> h, v;\nint di[] = {0, 1, 0, -1};\nint dj[] = {1, 0, -1, 0};\nchar dc[] = \"RDLU\";\n\nbool can_move(int i, int j, int dir) {\n    int ni = i + di[dir], nj = j + dj[dir];\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    if (dir == 0) return v[i][j] == '0';\n    if (dir == 1) return h[i][j] == '0';\n    if (dir == 2) return v[i][nj] == '0';\n    return h[ni][j] == '0';\n}\n\nvoid dfs(int i, int j, string& route, vector<vector<bool>>& visited) {\n    visited[i][j] = true;\n    for (int dir = 0; dir < 4; dir++) {\n        if (can_move(i, j, dir)) {\n            int ni = i + di[dir], nj = j + dj[dir];\n            if (!visited[ni][nj]) {\n                route += dc[dir];\n                dfs(ni, nj, route, visited);\n                route += dc[(dir + 2) % 4];\n            }\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N;\n    h.resize(N-1); v.resize(N);\n    for (int i = 0; i < N-1; i++) cin >> h[i];\n    for (int i = 0; i < N; i++) cin >> v[i];\n    vector<vector<int>> d(N, vector<int>(N));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cin >> d[i][j];\n    \n    string route;\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    dfs(0, 0, route, visited);\n    cout << route << endl;\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n, m, si, sj;\nchar grid[16][16];\nstring words[205];\nint cx[26][16][16], cy[26][16][16], cd[26][16][16];\n\nconst int MAXN = 1100;\nint trie[MAXN][26], fail_link[MAXN], node_cnt;\nvector<int> out[MAXN];\n\nvoid insert(const string& s, int id) {\n    int cur = 0;\n    for (char c : s) {\n        int ch = c - 'A';\n        if (!trie[cur][ch]) trie[cur][ch] = ++node_cnt;\n        cur = trie[cur][ch];\n    }\n    out[cur].push_back(id);\n}\n\nvoid build() {\n    queue<int> q;\n    for (int c = 0; c < 26; c++) {\n        if (trie[0][c]) { fail_link[trie[0][c]] = 0; q.push(trie[0][c]); }\n        else trie[0][c] = 0;\n    }\n    while (!q.empty()) {\n        int v = q.front(); q.pop();\n        for (int c = 0; c < 26; c++) {\n            if (trie[v][c]) {\n                fail_link[trie[v][c]] = trie[fail_link[v]][c];\n                for (int id : out[fail_link[trie[v][c]]]) out[trie[v][c]].push_back(id);\n                q.push(trie[v][c]);\n            } else trie[v][c] = trie[fail_link[v]][c];\n        }\n    }\n}\n\nbool was[MAXN][205]; int overlap[MAXN][205];\nvoid precompute() {\n    for (int st = 0; st <= node_cnt; st++) {\n        for (int id : out[st]) was[st][id] = true;\n        for (int w = 0; w < m; w++) {\n            int cur = st, need = 0; bool found = false;\n            for (int i = 0; i < 5; i++) {\n                cur = trie[cur][words[w][i]-'A']; need++;\n                if (was[cur][w]) { found = true; break; }\n            }\n            overlap[st][w] = found ? need : 6;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> n >> m >> si >> sj;\n    for (int i = 0; i < n; i++) { string r; cin >> r; for (int j = 0; j < n; j++) grid[i][j] = r[j]; }\n    for (int i = 0; i < m; i++) { cin >> words[i]; insert(words[i], i); }\n    build(); precompute();\n    const int INF = 1e9;\n    for (int c = 0; c < 26; c++) for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) {\n        cd[c][i][j] = INF;\n        for (int x = 0; x < n; x++) for (int y = 0; y < n; y++) if (grid[x][y] == 'A'+c) {\n            int d = abs(i-x)+abs(j-y); if (d < cd[c][i][j]) { cd[c][i][j]=d; cx[c][i][j]=x; cy[c][i][j]=y; }\n        }\n    }\n    int ci=si, cj=sj, st=0, done_cnt=0; vector<bool> done(m,false); vector<pair<int,int>> ops;\n    while (done_cnt < m && (int)ops.size() < 5000) {\n        int bw=-1, bc=INF;\n        for (int w = 0; w < m; w++) { if (done[w]) continue; int need=overlap[st][w]; if (need>5) continue;\n            int cost=0, ti=ci, tj=cj; for (int i = 0; i < need; i++) { int c=words[w][5-need+i]-'A';\n                if (cd[c][ti][tj]>=INF) { cost=INF; break; } cost+=cd[c][ti][tj]+1; ti=cx[c][ti][tj]; tj=cy[c][ti][tj]; }\n            if (cost<bc) { bc=cost; bw=w; } }\n        if (bw<0) { bc=INF; for (int w = 0; w < m; w++) { if (done[w]) continue; int cost=0, ti=ci, tj=cj;\n            for (int i = 0; i < 5; i++) { int c=words[w][i]-'A'; if (cd[c][ti][tj]>=INF) { cost=INF; break; }\n                cost+=cd[c][ti][tj]+1; ti=cx[c][ti][tj]; tj=cy[c][ti][tj]; } if (cost<bc) { bc=cost; bw=w; } }\n            if (bw<0) break; for (int i = 0; i < 5; i++) { int c=words[bw][i]-'A', ni=cx[c][ci][cj], nj=cy[c][ci][cj];\n                ops.push_back({ni,nj}); ci=ni; cj=nj; st=trie[st][c]; for (int id:out[st]) if (!done[id]) { done[id]=true; done_cnt++; } } }\n        else { int need=overlap[st][bw]; for (int i = 0; i < need; i++) { int c=words[bw][5-need+i]-'A', ni=cx[c][ci][cj], nj=cy[c][ci][cj];\n            ops.push_back({ni,nj}); ci=ni; cj=nj; st=trie[st][c]; for (int id:out[st]) if (!done[id]) { done[id]=true; done_cnt++; } } }\n    }\n    for (auto& [x,y] : ops) cout << x << \" \" << y << \"\\n\";\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M; double eps;\n    cin >> N >> M >> eps;\n    \n    vector<vector<pair<int,int>>> norm_fields(M);\n    vector<int> field_w(M), field_h(M);\n    for (int k = 0; k < M; k++) {\n        int d; cin >> d;\n        vector<pair<int,int>> raw(d);\n        int mi = N, mj = N;\n        for (int i = 0; i < d; i++) {\n            cin >> raw[i].first >> raw[i].second;\n            mi = min(mi, raw[i].first);\n            mj = min(mj, raw[i].second);\n        }\n        for (int i = 0; i < d; i++) {\n            norm_fields[k].push_back({raw[i].first - mi, raw[i].second - mj});\n            field_w[k] = max(field_w[k], raw[i].first - mi);\n            field_h[k] = max(field_h[k], raw[i].second - mj);\n        }\n    }\n    \n    vector<vector<int>> known(N, vector<int>(N, -1));\n    vector<pair<int,int>> has_oil;\n    \n    auto drill = [&](int i, int j) -> int {\n        if (known[i][j] != -1) return known[i][j];\n        cout << \"q 1 \" << i << \" \" << j << \"\\n\" << flush;\n        int r; cin >> r;\n        known[i][j] = r;\n        if (r > 0) has_oil.push_back({i, j});\n        return r;\n    };\n    \n    auto divine = [&](vector<pair<int,int>> &sq) -> int {\n        if (sq.size() < 2) return -1;\n        cout << \"q \" << sq.size();\n        for (auto [i, j] : sq) cout << \" \" << i << \" \" << j;\n        cout << \"\\n\" << flush;\n        int r; cin >> r;\n        return r;\n    };\n    \n    int bs = (N >= 15) ? 7 : 5;\n    int nbi = (N + bs - 1) / bs, nbj = (N + bs - 1) / bs;\n    vector<vector<bool>> skip(nbi, vector<bool>(nbj, false));\n    \n    for (int bi = 0; bi < nbi; bi++) for (int bj = 0; bj < nbj; bj++) {\n        vector<pair<int,int>> blk;\n        for (int i = bi*bs; i < min(N,(bi+1)*bs); i++)\n            for (int j = bj*bs; j < min(N,(bj+1)*bs); j++)\n                blk.push_back({i, j});\n        if (blk.size() < 2) continue;\n        if (divine(blk) == 0) skip[bi][bj] = true;\n    }\n    \n    for (int bi = 0; bi < nbi; bi++) for (int bj = 0; bj < nbj; bj++) {\n        if (skip[bi][bj]) continue;\n        for (int i = bi*bs; i < min(N,(bi+1)*bs); i++)\n            for (int j = bj*bs; j < min(N,(bj+1)*bs); j++)\n                drill(i, j);\n    }\n    \n    for (int iter = 0; iter < 3 && !has_oil.empty(); iter++) {\n        vector<vector<int>> cnt(N, vector<int>(N, 0));\n        for (int k = 0; k < M; k++) {\n            for (int di = 0; di <= N - 1 - field_w[k]; di++) {\n                for (int dj = 0; dj <= N - 1 - field_h[k]; dj++) {\n                    bool ok = true;\n                    for (auto [si, sj] : norm_fields[k])\n                        if (known[di+si][dj+sj] == 0) { ok = false; break; }\n                    if (!ok) continue;\n                    for (auto [si, sj] : norm_fields[k])\n                        if (known[di+si][dj+sj] == -1) cnt[di+si][dj+sj]++;\n                }\n            }\n        }\n        vector<pair<int,pair<int,int>>> todo;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++)\n            if (cnt[i][j] > 0) todo.push_back({-cnt[i][j], {i, j}});\n        sort(todo.begin(), todo.end());\n        for (auto [_, p] : todo) drill(p.first, p.second);\n    }\n    \n    cout << \"a \" << has_oil.size();\n    for (auto [i, j] : has_oil) cout << \" \" << i << \" \" << j;\n    cout << \"\\n\" << flush;\n    int resp; cin >> resp;\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W, D, N;\n    cin >> W >> D >> N;\n    \n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; d++)\n        for (int k = 0; k < N; k++) cin >> a[d][k];\n    \n    if (N == 1) {\n        for (int d = 0; d < D; d++) cout << \"0 0 \" << W << \" \" << W << \"\\n\";\n        return 0;\n    }\n    \n    auto compute_parts = [&](const vector<int>& areas) {\n        vector<int> req(N);\n        for (int k = 0; k < N; k++) req[k] = (areas[k] + W - 1) / W;\n        vector<int> heights = req;\n        long long total = accumulate(heights.begin(), heights.end(), 0LL);\n        long long excess = total - W;\n        if (excess > 0) {\n            for (int k = N-1; k >= 0 && excess > 0; k--) {\n                int min_h = (k == 0) ? 1 : heights[k-1];\n                long long reduce = min(excess, (long long)(heights[k] - min_h));\n                heights[k] -= reduce;\n                excess -= reduce;\n            }\n        }\n        vector<int> parts(N-1);\n        long long cum = 0;\n        for (int k = 0; k < N-1; k++) { cum += heights[k]; parts[k] = cum; }\n        return parts;\n    };\n    \n    auto get_heights = [&](const vector<int>& parts) {\n        vector<int> h(N);\n        h[0] = parts[0];\n        for (int k = 1; k < N-1; k++) h[k] = parts[k] - parts[k-1];\n        h[N-1] = W - parts[N-2];\n        return h;\n    };\n    \n    auto deficit_sorted = [&](const vector<int>& areas, vector<int> heights) {\n        sort(heights.begin(), heights.end());\n        long long def = 0;\n        for (int k = 0; k < N; k++)\n            def += max(0LL, (long long)areas[k] - (long long)heights[k] * W);\n        return def;\n    };\n    \n    auto output_new = [&](const vector<int>& parts) {\n        for (int k = 0; k < N; k++) {\n            int s = k == 0 ? 0 : parts[k-1];\n            int e = k < N-1 ? parts[k] : W;\n            cout << s << \" 0 \" << e << \" \" << W << \"\\n\";\n        }\n    };\n    \n    auto output_keep = [&](const vector<int>& parts) {\n        auto heights = get_heights(parts);\n        vector<pair<int,int>> hp(N);\n        for (int k = 0; k < N; k++) hp[k] = {heights[k], k};\n        sort(hp.begin(), hp.end());\n        for (int i = 0; i < N; i++) {\n            int s = hp[i].second;\n            int s0 = s == 0 ? 0 : parts[s-1];\n            int s1 = s < N-1 ? parts[s] : W;\n            cout << s0 << \" 0 \" << s1 << \" \" << W << \"\\n\";\n        }\n    };\n    \n    vector<int> parts = compute_parts(a[0]);\n    output_new(parts);\n    \n    for (int d = 1; d < D; d++) {\n        long long cost_keep = deficit_sorted(a[d], get_heights(parts)) * 100;\n        auto new_parts = compute_parts(a[d]);\n        long long new_def = deficit_sorted(a[d], get_heights(new_parts)) * 100;\n        \n        set<int> s1(parts.begin(), parts.end()), s2(new_parts.begin(), new_parts.end());\n        vector<int> diff;\n        set_symmetric_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),back_inserter(diff));\n        long long cost_change = (long long)diff.size() * W + new_def;\n        \n        if (cost_change < cost_keep) { parts = new_parts; output_new(parts); }\n        else output_keep(parts);\n    }\n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <algorithm>\n#include <chrono>\n\nusing namespace std;\n\nconst int P = 998244353;\nint N, M, K;\nvector<vector<int>> T_mod;\nvector<int> S_flat;\nvector<long long> sum_S;\n\nlong long best_gain_at_pos[7][7];\nint best_m_at_pos[7][7];\n\ninline void update_pos(int p, int q) {\n    long long best_g = -1; int best_m = 0;\n    int t[9];\n    for(int i=0; i<3; ++i) for(int j=0; j<3; ++j) t[i*3+j] = T_mod[p+i][q+j];\n    \n    for (int m = 0; m < M; ++m) {\n        int* s = &S_flat[m * 9];\n        int overflow = 0;\n        for(int k=0; k<9; ++k) {\n            if (s[k] && t[k] + s[k] >= P) overflow++;\n        }\n        long long gain = sum_S[m] - (long long)P * overflow;\n        if (gain > best_g) { best_g = gain; best_m = m; }\n    }\n    best_gain_at_pos[p][q] = best_g; best_m_at_pos[p][q] = best_m;\n}\n\ninline void update_affected(int p_old, int q_old) {\n    for (int p = max(0, p_old - 2); p <= min(6, p_old + 2); ++p)\n        for (int q = max(0, q_old - 2); q <= min(6, q_old + 2); ++q)\n            update_pos(p, q);\n}\n\ninline void update_all() { for (int p = 0; p <= 6; ++p) for (int q = 0; q <= 6; ++q) update_pos(p, q); }\n\ninline void apply_stamp(int m, int p, int q) {\n    int* s = &S_flat[m * 9];\n    for(int k=0; k<9; ++k) {\n        if (s[k]) {\n            int t = T_mod[p + k/3][q + k%3] + s[k];\n            if (t >= P) t -= P;\n            T_mod[p + k/3][q + k%3] = t;\n        }\n    }\n}\n\ninline void remove_stamp(int m, int p, int q) {\n    int* s = &S_flat[m * 9];\n    for(int k=0; k<9; ++k) {\n        if (s[k]) {\n            int t = T_mod[p + k/3][q + k%3] - s[k];\n            if (t < 0) t += P;\n            T_mod[p + k/3][q + k%3] = t;\n        }\n    }\n}\n\ninline long long compute_gain(int m, int p, int q) {\n    int* s = &S_flat[m * 9];\n    int overflow = 0;\n    for(int k=0; k<9; ++k) {\n        if (s[k] && T_mod[p + k/3][q + k%3] + s[k] >= P) overflow++;\n    }\n    return sum_S[m] - (long long)P * overflow;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    if (!(cin >> N >> M >> K)) return 0;\n\n    T_mod.assign(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> T_mod[i][j];\n\n    S_flat.assign(M * 9, 0);\n    sum_S.assign(M, 0);\n    for (int m = 0; m < M; ++m) {\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                int idx = m * 9 + i * 3 + j;\n                cin >> S_flat[idx];\n                sum_S[m] += S_flat[idx];\n            }\n        }\n    }\n\n    vector<tuple<int, int, int>> ops;\n    \n    // Greedy Phase\n    update_all();\n    for (int step = 0; step < K; ++step) {\n        long long best_gain = 0;\n        int best_p = -1, best_q = -1;\n        for (int p = 0; p <= 6; ++p) {\n            for (int q = 0; q <= 6; ++q) {\n                if (best_gain_at_pos[p][q] > best_gain) {\n                    best_gain = best_gain_at_pos[p][q];\n                    best_p = p; best_q = q;\n                }\n            }\n        }\n        if (best_gain <= 0) break;\n        \n        int best_m = best_m_at_pos[best_p][best_q];\n        ops.emplace_back(best_m, best_p, best_q);\n        apply_stamp(best_m, best_p, best_q);\n        update_affected(best_p, best_q);\n    }\n\n    // 2-opt Local Search Phase\n    auto start_time = std::chrono::high_resolution_clock::now();\n    bool improved = true;\n    while (improved) {\n        auto current_time = std::chrono::high_resolution_clock::now();\n        double elapsed = std::chrono::duration<double>(current_time - start_time).count();\n        if (elapsed > 1.5) break;\n        \n        improved = false;\n        update_all(); \n        \n        long long best_net_gain = 0;\n        int best_i = -1, best_j = -1;\n        int best_m1 = -1, best_p1 = -1, best_q1 = -1;\n        int best_m2 = -1, best_p2 = -1, best_q2 = -1;\n        bool add_two = false;\n\n        for (int i = 0; i <= ops.size(); ++i) {\n            int j_start = (i < ops.size()) ? i + 1 : i;\n            bool is_i_valid = (i < ops.size());\n            long long loss_i = 0;\n            \n            if (is_i_valid) {\n                const auto& [mi, pi, qi] = ops[i];\n                remove_stamp(mi, pi, qi);\n                update_affected(pi, qi);\n                loss_i = compute_gain(mi, pi, qi);\n            }\n            \n            for (int j = j_start; j <= ops.size(); ++j) {\n                bool is_j_valid = (j < ops.size());\n                long long loss_j = 0;\n                \n                if (is_j_valid) {\n                    const auto& [mj, pj, qj] = ops[j];\n                    remove_stamp(mj, pj, qj);\n                    update_affected(pj, qj);\n                    loss_j = compute_gain(mj, pj, qj);\n                }\n                \n                long long total_loss = loss_i + loss_j;\n                int current_sim_size = ops.size() - (is_i_valid ? 1 : 0) - (is_j_valid ? 1 : 0);\n\n                long long max_gain_1 = 0;\n                int bm1 = -1, bp1 = -1, bq1 = -1;\n                for (int p = 0; p <= 6; ++p) {\n                    for (int q = 0; q <= 6; ++q) {\n                        if (best_gain_at_pos[p][q] > max_gain_1) {\n                            max_gain_1 = best_gain_at_pos[p][q];\n                            bm1 = best_m_at_pos[p][q]; bp1 = p; bq1 = q;\n                        }\n                    }\n                }\n\n                if (current_sim_size + 1 <= K) {\n                    long long net_gain_1 = max_gain_1 - total_loss;\n                    if (net_gain_1 > best_net_gain) {\n                        best_net_gain = net_gain_1;\n                        best_i = i; best_j = j;\n                        best_m1 = bm1; best_p1 = bp1; best_q1 = bq1;\n                        best_m2 = -1; best_p2 = -1; best_q2 = -1;\n                        add_two = false;\n                    }\n                }\n\n                if (current_sim_size + 2 <= K) {\n                    if (bm1 != -1) {\n                        apply_stamp(bm1, bp1, bq1);\n                        update_affected(bp1, bq1);\n\n                        long long max_gain_2 = 0;\n                        int bm2 = -1, bp2 = -1, bq2 = -1;\n                        for (int p = 0; p <= 6; ++p) {\n                            for (int q = 0; q <= 6; ++q) {\n                                if (best_gain_at_pos[p][q] > max_gain_2) {\n                                    max_gain_2 = best_gain_at_pos[p][q];\n                                    bm2 = best_m_at_pos[p][q]; bp2 = p; bq2 = q;\n                                }\n                            }\n                        }\n                        long long net_gain_2 = max_gain_1 + max_gain_2 - total_loss;\n                        if (net_gain_2 > best_net_gain) {\n                            best_net_gain = net_gain_2;\n                            best_i = i; best_j = j;\n                            best_m1 = bm1; best_p1 = bp1; best_q1 = bq1;\n                            best_m2 = bm2; best_p2 = bp2; best_q2 = bq2;\n                            add_two = true;\n                        }\n                        remove_stamp(bm1, bp1, bq1);\n                        update_affected(bp1, bq1);\n                    }\n                }\n                \n                if (is_j_valid) {\n                    const auto& [mj, pj, qj] = ops[j];\n                    apply_stamp(mj, pj, qj);\n                    update_affected(pj, qj);\n                }\n            }\n            \n            if (is_i_valid) {\n                const auto& [mi, pi, qi] = ops[i];\n                apply_stamp(mi, pi, qi);\n                update_affected(pi, qi);\n            }\n        }\n        \n        if (best_net_gain > 0) {\n            improved = true;\n            if (best_i < ops.size()) {\n                const auto& [mi, pi, qi] = ops[best_i];\n                remove_stamp(mi, pi, qi); update_affected(pi, qi);\n            }\n            if (best_j < ops.size()) {\n                const auto& [mj, pj, qj] = ops[best_j];\n                remove_stamp(mj, pj, qj); update_affected(pj, qj);\n            }\n            \n            if (best_m1 != -1) {\n                apply_stamp(best_m1, best_p1, best_q1); update_affected(best_p1, best_q1);\n            }\n            if (add_two && best_m2 != -1) {\n                apply_stamp(best_m2, best_p2, best_q2); update_affected(best_p2, best_q2);\n            }\n\n            vector<tuple<int, int, int>> new_ops;\n            for(int k = 0; k < ops.size(); ++k) {\n                if (k != best_i && k != best_j) new_ops.push_back(ops[k]);\n            }\n            if (best_m1 != -1) new_ops.emplace_back(best_m1, best_p1, best_q1);\n            if (add_two && best_m2 != -1) new_ops.emplace_back(best_m2, best_p2, best_q2);\n            ops = new_ops;\n        }\n    }\n\n    cout << ops.size() << \"\\n\";\n    for (const auto& [m, p, q] : ops) {\n        cout << m << \" \" << p << \" \" << q << \"\\n\";\n    }\n\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 5;\nint A[N][N], cont_row[25], cont_order[25];\nint grid[N][N], crx, cry, cr_held, recv_idx[N], next_dispatch[N];\nbool cr_carry, dispatched[25];\nstring cmds[N];\n\npair<int,int> find_cont(int id) {\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++)\n        if (grid[i][j] == id) return {i, j};\n    return {-1, -1};\n}\n\nint find_empty(int r, int mode) {\n    for (int j = 1; j < N-1; j++) if (grid[r][j] == -1) return j;\n    if (mode >= 1 && recv_idx[r] >= N && grid[r][0] == -1) return 0;\n    if (mode >= 2 && grid[r][N-1] == -1) return N-1;\n    return -1;\n}\n\nvoid move_to(int tx, int ty, char& a) {\n    if (crx < tx) a = 'D'; else if (crx > tx) a = 'U';\n    else if (cry < ty) a = 'R'; else if (cry > ty) a = 'L'; else a = '.';\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        cin >> A[i][j]; cont_row[A[i][j]] = A[i][j] / N; cont_order[A[i][j]] = A[i][j] % N;\n    }\n    memset(grid, -1, sizeof(grid)); crx = cry = 0; cr_carry = false; cr_held = -1;\n    memset(recv_idx, 0, sizeof(recv_idx)); memset(dispatched, false, sizeof(dispatched));\n    memset(next_dispatch, 0, sizeof(next_dispatch));\n    int target = -1;\n    for (int turn = 0; turn < 10000; turn++) {\n        for (int i = 0; i < N; i++) if (recv_idx[i] < N && grid[i][0] == -1 && !(crx == i && cry == 0 && cr_carry))\n            grid[i][0] = A[i][recv_idx[i]++];\n        char act[N]; fill(act, act + N, '.');\n        if (turn == 0) { for (int i = 1; i < N; i++) act[i] = 'R'; act[0] = 'D'; }\n        else if (turn == 1) { for (int i = 1; i < N; i++) act[i] = 'B'; }\n        else {\n            bool all_recv = true; for (int i = 0; i < N; i++) if (recv_idx[i] < N) all_recv = false;\n            if (!cr_carry) {\n                if (!all_recv) {\n                    int bx = -1, by = -1, bd = 1000;\n                    for (int i = 0; i < N; i++) if (grid[i][0] != -1) { int d = abs(i-crx)+abs(cry); if (d < bd) { bd = d; bx = i; by = 0; } }\n                    if (bx < 0) for (int i = 0; i < N; i++) for (int j = 1; j < N-1; j++) if (grid[i][j] != -1) { int d = abs(i-crx)+abs(j-cry); if (d < bd) { bd = d; bx = i; by = j; } }\n                    if (bx >= 0) { if (crx == bx && cry == by) { act[0] = 'P'; target = grid[bx][by]; } else move_to(bx, by, act[0]); }\n                } else {\n                    int best_cid = -1, best_d = 1000;\n                    for (int r = 0; r < N; r++) while (next_dispatch[r] < N) {\n                        int cid = r * N + next_dispatch[r]; auto [cx, cy] = find_cont(cid);\n                        if (cx >= 0) { int d = abs(cx-crx)+abs(cy-cry); if (d < best_d) { best_d = d; best_cid = cid; } break; } else next_dispatch[r]++;\n                    }\n                    if (best_cid >= 0) { auto [cx, cy] = find_cont(best_cid); if (crx == cx && cry == cy) { act[0] = 'P'; target = best_cid; } else move_to(cx, cy, act[0]); }\n                }\n            } else {\n                int tr = cont_row[target];\n                if (!all_recv) { int ty = find_empty(tr, 0); if (ty < 0) ty = find_empty(tr, 1); if (ty < 0) ty = find_empty(tr, 2); if (ty >= 0) { if (crx == tr && cry == ty) act[0] = 'Q'; else move_to(tr, ty, act[0]); } }\n                else { if (crx == tr && cry == N-1) act[0] = 'Q'; else move_to(tr, N-1, act[0]); }\n            }\n        }\n        for (int i = 0; i < N; i++) cmds[i] += act[i];\n        if (act[0] == 'P') { cr_held = grid[crx][cry]; grid[crx][cry] = -1; cr_carry = true; }\n        else if (act[0] == 'Q') { grid[crx][cry] = cr_held; cr_held = -1; cr_carry = false; }\n        else if (act[0] == 'U') crx--; else if (act[0] == 'D') crx++; else if (act[0] == 'L') cry--; else if (act[0] == 'R') cry++;\n        for (int i = 0; i < N; i++) if (grid[i][N-1] != -1) { int c = grid[i][N-1]; dispatched[c] = true; grid[i][N-1] = -1; if (i == cont_row[c] && cont_order[c] == next_dispatch[i]) next_dispatch[i]++; }\n        bool done = true; for (int i = 0; i < 25; i++) if (!dispatched[i]) { done = false; break; } if (done) break;\n    }\n    for (int i = 0; i < N; i++) cout << cmds[i] << endl;\n    return 0;\n}","ahc034":"#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;\n    cin >> N;\n    vector<vector<int>> h(N, vector<int>(N));\n    set<pair<int, int>> unvisited;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            cin >> h[i][j];\n            if (h[i][j] != 0) unvisited.insert({i, j});\n        }\n    \n    vector<string> ops;\n    int load = 0;\n    int ci = 0, cj = 0;\n    \n    auto move_to = [&](int ti, int tj) {\n        while (ci < ti) { ops.push_back(\"D\"); ci++; }\n        while (ci > ti) { ops.push_back(\"U\"); ci--; }\n        while (cj < tj) { ops.push_back(\"R\"); cj++; }\n        while (cj > tj) { ops.push_back(\"L\"); cj--; }\n    };\n    \n    while (!unvisited.empty()) {\n        int best_i = -1, best_j = -1;\n        double best_score = 1e18;\n        \n        int radius = 12;\n        for (int ni = max(0, ci - radius); ni <= min(N-1, ci + radius); ni++) {\n            for (int nj = max(0, cj - radius); nj <= min(N-1, cj + radius); nj++) {\n                if (unvisited.find({ni, nj}) == unvisited.end()) continue;\n                // Skip negative cells if we don't have enough load to unload\n                if (h[ni][nj] < 0 && load < -h[ni][nj]) continue;\n                \n                int dist = abs(ci - ni) + abs(cj - nj);\n                double s = dist * 100.0 + load * dist;\n                // Bonus for unloading (reduces future carrying cost)\n                if (h[ni][nj] < 0) {\n                    s -= min((long long)load, (long long)-h[ni][nj]) * 5.0;\n                }\n                if (s < best_score) {\n                    best_score = s;\n                    best_i = ni;\n                    best_j = nj;\n                }\n            }\n        }\n        \n        if (best_i == -1) {\n            for (auto [ni, nj] : unvisited) {\n                if (h[ni][nj] < 0 && load < -h[ni][nj]) continue;\n                \n                int dist = abs(ci - ni) + abs(cj - nj);\n                double s = dist * 100.0 + load * dist;\n                if (h[ni][nj] < 0) {\n                    s -= min((long long)load, (long long)-h[ni][nj]) * 5.0;\n                }\n                if (s < best_score) {\n                    best_score = s;\n                    best_i = ni;\n                    best_j = nj;\n                }\n            }\n        }\n        \n        move_to(best_i, best_j);\n        \n        int amount = h[best_i][best_j];\n        if (amount > 0) {\n            ops.push_back(\"+\" + to_string(amount));\n        } else {\n            ops.push_back(\"-\" + to_string(-amount));\n        }\n        load += amount;  // Fixed: for negative h, this decreases load correctly\n        \n        unvisited.erase({best_i, best_j});\n    }\n    \n    for (const auto& op : ops) cout << op << \"\\n\";\n    \n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, T;\n    cin >> N >> M >> T;\n\n    const int seed_count = 2 * N * (N - 1);\n    const int grid_size = N * N;\n    vector<vector<int>> X(seed_count, vector<int>(M, 0));\n    vector<int> V(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    const int dr[] = {-1, 1, 0, 0};\n    const int dc[] = {0, 0, -1, 1};\n    vector<vector<int>> nbrs(grid_size);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int pos = i * N + j;\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dr[d], nj = j + dc[d];\n                if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                    nbrs[pos].push_back(ni * N + nj);\n                }\n            }\n        }\n    }\n\n    mt19937 rng(12345);\n\n    for (int t = 0; t < T; t++) {\n        vector<vector<int>> allEP(seed_count, vector<int>(seed_count, 0));\n        for (int i = 0; i < seed_count; i++) {\n            for (int j = i + 1; j < seed_count; j++) {\n                int s = 0;\n                for (int l = 0; l < M; l++) s += max(X[i][l], X[j][l]);\n                allEP[i][j] = allEP[j][i] = s;\n            }\n        }\n        \n        vector<pair<int,int>> pairs;\n        for (int i = 0; i < seed_count; i++) {\n            for (int j = i + 1; j < seed_count; j++) {\n                pairs.push_back({allEP[i][j], i * seed_count + j});\n            }\n        }\n        sort(pairs.rbegin(), pairs.rend());\n        \n        vector<int> selected;\n        vector<bool> used(seed_count, false);\n        \n        int pairsAdded = 0;\n        for (auto& [pot, encoded] : pairs) {\n            if (pairsAdded >= 12) break;\n            int a = encoded / seed_count, b = encoded % seed_count;\n            if (!used[a] && !used[b]) {\n                selected.push_back(a);\n                selected.push_back(b);\n                used[a] = used[b] = true;\n                pairsAdded++;\n            }\n        }\n        \n        while ((int)selected.size() < grid_size) {\n            int bestSeed = -1, bestScore = -1;\n            for (int s = 0; s < seed_count; s++) {\n                if (used[s]) continue;\n                int maxPot = 0;\n                for (int sel : selected) {\n                    maxPot = max(maxPot, allEP[s][sel]);\n                }\n                int score = maxPot * 10000 + V[s];\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestSeed = s;\n                }\n            }\n            selected.push_back(bestSeed);\n            used[bestSeed] = true;\n        }\n        \n        vector<int> perm = selected;\n        \n        int bestLocalI = 0, bestLocalJ = 0, bestLocalPot = 0;\n        for (int i = 0; i < grid_size; i++) {\n            for (int j = i + 1; j < grid_size; j++) {\n                if (allEP[perm[i]][perm[j]] > bestLocalPot) {\n                    bestLocalPot = allEP[perm[i]][perm[j]];\n                    bestLocalI = i;\n                    bestLocalJ = j;\n                }\n            }\n        }\n        swap(perm[0], perm[bestLocalI]);\n        if (bestLocalJ == 0) bestLocalJ = bestLocalI;\n        swap(perm[1], perm[bestLocalJ]);\n        \n        vector<vector<int>> ep(grid_size, vector<int>(grid_size, 0));\n        for (int i = 0; i < grid_size; i++) {\n            for (int j = i + 1; j < grid_size; j++) {\n                ep[i][j] = ep[j][i] = allEP[perm[i]][perm[j]];\n            }\n        }\n        \n        long long totalScore = 0;\n        for (int i = 0; i < grid_size; i++) {\n            for (int j : nbrs[i]) {\n                if (j > i) totalScore += ep[i][j];\n            }\n        }\n        \n        double temp = 500.0;\n        double cooling = 0.9999;\n        uniform_real_distribution<double> dist(0.0, 1.0);\n        \n        for (int iter = 0; iter < 280000; iter++) {\n            int p1 = rng() % grid_size;\n            int p2 = rng() % grid_size;\n            if (p1 == p2) continue;\n            \n            int delta = 0;\n            for (int nb : nbrs[p1]) {\n                if (nb != p2) delta += ep[p2][nb] - ep[p1][nb];\n            }\n            for (int nb : nbrs[p2]) {\n                if (nb != p1) delta += ep[p1][nb] - ep[p2][nb];\n            }\n            \n            double acceptProb = delta >= 0 ? 1.0 : exp(delta / temp);\n            if (dist(rng) < acceptProb) {\n                totalScore += delta;\n                swap(perm[p1], perm[p2]);\n                swap(ep[p1], ep[p2]);\n                for (int k = 0; k < grid_size; k++) {\n                    swap(ep[k][p1], ep[k][p2]);\n                }\n            }\n            temp *= cooling;\n        }\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << perm[i * N + j];\n                if (j < N - 1) cout << \" \";\n                else cout << \"\\n\";\n            }\n        }\n        cout.flush();\n\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    }\n\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint dx[] = {0, 1, 0, -1};\nint dy[] = {1, 0, -1, 0};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, V;\n    cin >> N >> M >> V;\n    \n    vector<string> s(N), t(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    int edgeLen = 1;\n    \n    cout << V << \"\\n\";\n    for (int i = 1; i < V; i++) cout << 0 << \" \" << edgeLen << \"\\n\";\n    \n    int sumX = 0, sumY = 0, taskCount = 0;\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') || (s[i][j] == '0' && t[i][j] == '1')) {\n                sumX += i; sumY += j; taskCount++;\n            }\n        }\n    int rx = taskCount > 0 ? sumX / taskCount : N / 2;\n    int ry = taskCount > 0 ? sumY / taskCount : N / 2;\n    rx = max(0, min(N - 1, rx));\n    ry = max(0, min(N - 1, ry));\n    cout << rx << \" \" << ry << \"\\n\";\n    \n    vector<int> dir(V, 0);\n    for (int i = 1; i < V; i++) dir[i] = (i - 1) % 4;\n    \n    vector<bool> holding(V, false);\n    \n    set<pair<int,int>> sources, dests;\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') sources.insert({i, j});\n            if (s[i][j] == '0' && t[i][j] == '1') dests.insert({i, j});\n        }\n    \n    auto inGrid = [&](int x, int y) { return x >= 0 && x < N && y >= 0 && y < N; };\n    \n    string S1(V * 2, '.');\n    string S2(V * 2, '.');\n    for (int i = 1; i < V; i++) {\n        int t = dir[i];\n        if (t == 1) S1[i] = 'R';\n        else if (t == 2) { S1[i] = 'R'; S2[i] = 'R'; }\n        else if (t == 3) S1[i] = 'L';\n    }\n    \n    int initialTurns = 0;\n    if (S1.find_first_not_of('.') != string::npos) { cout << S1 << \"\\n\"; initialTurns++; }\n    if (S2.find_first_not_of('.') != string::npos) { cout << S2 << \"\\n\"; initialTurns++; }\n    \n    auto fpos = [&](int i) { return make_pair(rx + dx[dir[i]] * edgeLen, ry + dy[dir[i]] * edgeLen); };\n    \n    int maxTurns = 100000 - initialTurns;\n    \n    for (int turn = 0; turn < maxTurns && (!sources.empty() || !dests.empty()); turn++) {\n        string S(V * 2, '.');\n        \n        bool anyHolding = false;\n        for (int i = 1; i < V; i++) if (holding[i]) { anyHolding = true; break; }\n        \n        for (int i = 1; i < V; i++) {\n            bool shouldRotate = false;\n            int bestRot = 0;\n            \n            if (holding[i]) {\n                for (int rot : {1, 3}) {\n                    int newDir = (dir[i] + rot) % 4;\n                    int fx = rx + dx[newDir] * edgeLen, fy = ry + dy[newDir] * edgeLen;\n                    if (inGrid(fx, fy) && dests.count({fx, fy})) {\n                        shouldRotate = true; bestRot = rot; break;\n                    }\n                }\n            } else if (!anyHolding || dests.empty()) {\n                for (int rot : {1, 3}) {\n                    int newDir = (dir[i] + rot) % 4;\n                    int fx = rx + dx[newDir] * edgeLen, fy = ry + dy[newDir] * edgeLen;\n                    if (inGrid(fx, fy) && sources.count({fx, fy})) {\n                        shouldRotate = true; bestRot = rot; break;\n                    }\n                }\n            }\n            \n            if (shouldRotate) {\n                S[i] = bestRot == 1 ? 'R' : 'L';\n                dir[i] = (dir[i] + bestRot) % 4;\n            }\n        }\n        \n        pair<int,int> target = {-1, -1};\n        int minDist = INT_MAX;\n        \n        auto findTarget = [&](const set<pair<int,int>>& cells) {\n            for (auto [x, y] : cells) {\n                for (int d = 0; d < 4; d++) {\n                    int nx = x - dx[d], ny = y - dy[d];\n                    if (inGrid(nx, ny)) {\n                        int dist = abs(nx - rx) + abs(ny - ry);\n                        if (dist < minDist) { minDist = dist; target = {nx, ny}; }\n                    }\n                }\n            }\n        };\n        \n        if (anyHolding && !dests.empty()) findTarget(dests);\n        if (target.first == -1 && !sources.empty()) findTarget(sources);\n        if (target.first == -1 && !dests.empty()) findTarget(dests);\n        \n        if (target.first != -1) {\n            int tx = target.first, ty = target.second;\n            if (rx < tx) { S[0] = 'D'; rx++; }\n            else if (rx > tx) { S[0] = 'U'; rx--; }\n            else if (ry < ty) { S[0] = 'R'; ry++; }\n            else if (ry > ty) { S[0] = 'L'; ry--; }\n        } else {\n            break;\n        }\n        \n        for (int i = 1; i < V; i++) {\n            auto [fx, fy] = fpos(i);\n            if (!inGrid(fx, fy)) continue;\n            if (holding[i] && dests.count({fx, fy})) {\n                S[V + i] = 'P'; holding[i] = false; dests.erase({fx, fy});\n            } else if (!holding[i] && sources.count({fx, fy})) {\n                S[V + i] = 'P'; holding[i] = true; sources.erase({fx, fy});\n            }\n        }\n        \n        cout << S << \"\\n\";\n    }\n    return 0;\n}","ahc039":"#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;\n    cin >> N;\n    \n    vector<int> mx(N), my(N), sx(N), sy(N);\n    for (int i = 0; i < N; i++) cin >> mx[i] >> my[i];\n    for (int i = 0; i < N; i++) cin >> sx[i] >> sy[i];\n    \n    auto count_rect = [&](int x1, int y1, int x2, int y2) -> int {\n        int net = 0;\n        for (int i = 0; i < N; i++) if (mx[i] >= x1 && mx[i] <= x2 && my[i] >= y1 && my[i] <= y2) net++;\n        for (int i = 0; i < N; i++) if (sx[i] >= x1 && sx[i] <= x2 && sy[i] >= y1 && sy[i] <= y2) net--;\n        return net;\n    };\n    \n    int best_score = 0, best_x1 = 0, best_y1 = 0, best_x2 = 1, best_y2 = 1;\n    \n    auto grid_search = [&](int GRID, int CELL) {\n        auto cell = [&](int x) { return min(x / CELL, GRID - 1); };\n        vector<vector<int>> grid(GRID, vector<int>(GRID, 0));\n        for (int i = 0; i < N; i++) grid[cell(mx[i])][cell(my[i])]++;\n        for (int i = 0; i < N; i++) grid[cell(sx[i])][cell(sy[i])]--;\n        \n        int best = 0, bx1 = 0, bx2 = 0, by1 = 0, by2 = 0;\n        for (int x1 = 0; x1 < GRID; x1++) {\n            vector<int> col(GRID, 0);\n            for (int x2 = x1; x2 < GRID; x2++) {\n                for (int y = 0; y < GRID; y++) col[y] += grid[x2][y];\n                int cur = 0, start = 0;\n                for (int y = 0; y < GRID; y++) {\n                    if (cur <= 0) { cur = col[y]; start = y; } else cur += col[y];\n                    if (cur > best) { best = cur; bx1 = x1; bx2 = x2; by1 = start; by2 = y; }\n                }\n            }\n        }\n        \n        if (best <= 0) return;\n        \n        int cx1 = bx1*CELL, cy1 = by1*CELL;\n        int cx2 = min((bx2+1)*CELL - 1, 100000), cy2 = min((by2+1)*CELL - 1, 100000);\n        \n        set<int> x_set, y_set;\n        x_set.insert(cx1); x_set.insert(cx2); y_set.insert(cy1); y_set.insert(cy2);\n        for (int i = 0; i < 2*N; i++) {\n            int x = (i<N)?mx[i]:sx[i], y = (i<N)?my[i]:sy[i];\n            if (x>=cx1 && x<=cx2) { x_set.insert(max(0,x-1)); x_set.insert(x); x_set.insert(min(100000,x+1)); }\n            if (y>=cy1 && y<=cy2) { y_set.insert(max(0,y-1)); y_set.insert(y); y_set.insert(min(100000,y+1)); }\n        }\n        vector<int> all_x(x_set.begin(),x_set.end()), all_y(y_set.begin(),y_set.end());\n        int nx = all_x.size(), ny = all_y.size();\n        \n        const int MAX_SZ = 250;\n        if (nx > MAX_SZ) { vector<int> t; for(int i=0;i<nx;i+=(nx+MAX_SZ-1)/MAX_SZ) t.push_back(all_x[i]); t.push_back(all_x.back()); all_x=t; nx=all_x.size(); }\n        if (ny > MAX_SZ) { vector<int> t; for(int i=0;i<ny;i+=(ny+MAX_SZ-1)/MAX_SZ) t.push_back(all_y[i]); t.push_back(all_y.back()); all_y=t; ny=all_y.size(); }\n        \n        vector<vector<int>> fg(nx, vector<int>(ny, 0));\n        for (int i = 0; i < N; i++) { \n            int xi = lower_bound(all_x.begin(),all_x.end(),mx[i])-all_x.begin(); \n            int yi = lower_bound(all_y.begin(),all_y.end(),my[i])-all_y.begin(); \n            if(xi<nx && yi<ny && all_x[xi]==mx[i] && all_y[yi]==my[i]) fg[xi][yi]++; \n        }\n        for (int i = 0; i < N; i++) { \n            int xi = lower_bound(all_x.begin(),all_x.end(),sx[i])-all_x.begin(); \n            int yi = lower_bound(all_y.begin(),all_y.end(),sy[i])-all_y.begin(); \n            if(xi<nx && yi<ny && all_x[xi]==sx[i] && all_y[yi]==sy[i]) fg[xi][yi]--; \n        }\n        \n        int fb = 0, fx1 = 0, fx2 = 0, fy1 = 0, fy2 = 0;\n        for (int x1 = 0; x1 < nx; x1++) { \n            vector<int> col(ny, 0); \n            for (int x2 = x1; x2 < nx; x2++) { \n                for (int y = 0; y < ny; y++) col[y] += fg[x2][y]; \n                int cur = 0, start = 0; \n                for (int y = 0; y < ny; y++) { \n                    if (cur <= 0) { cur = col[y]; start = y; } else cur += col[y]; \n                    if (cur > fb) { fb = cur; fx1 = x1; fx2 = x2; fy1 = start; fy2 = y; } \n                } \n            } \n        }\n        \n        int ax1, ay1, ax2, ay2;\n        if (fb > 0) {\n            ax1 = max(0, all_x[fx1]); ay1 = max(0, all_y[fy1]);\n            ax2 = min(100000, all_x[fx2]); ay2 = min(100000, all_y[fy2]);\n        } else {\n            ax1 = cx1; ay1 = cy1; ax2 = cx2; ay2 = cy2;\n        }\n        if (ax2 <= ax1) ax2 = ax1 + 1; if (ay2 <= ay1) ay2 = ay1 + 1;\n        \n        int actual = count_rect(ax1, ay1, ax2, ay2);\n        if (actual > best_score) {\n            best_score = actual;\n            best_x1 = ax1; best_y1 = ay1; best_x2 = ax2; best_y2 = ay2;\n        }\n    };\n    \n    grid_search(50, 2001);\n    grid_search(100, 1001);\n    grid_search(200, 501);\n    \n    if (best_score <= 0) {\n        for (int i = 0; i < N; i++) {\n            for (int r = 0; r <= 10; r++) {\n                int x1 = max(0, mx[i] - r), y1 = max(0, my[i] - r);\n                int x2 = min(100000, mx[i] + r), y2 = min(100000, my[i] + r);\n                if (x2 <= x1 || y2 <= y1) continue;\n                int net = count_rect(x1, y1, x2, y2);\n                if (net > 0 && net > best_score) {\n                    best_score = net;\n                    best_x1 = x1; best_y1 = y1; best_x2 = x2; best_y2 = y2;\n                }\n            }\n        }\n    }\n    \n    if (best_score <= 0) {\n        cout << \"4\\n0 0\\n1 0\\n1 1\\n0 1\\n\";\n    } else {\n        cout << 4 << \"\\n\" << best_x1 << \" \" << best_y1 << \"\\n\" \n             << best_x2 << \" \" << best_y1 << \"\\n\" \n             << best_x2 << \" \" << best_y2 << \"\\n\" \n             << best_x1 << \" \" << best_y2 << \"\\n\";\n    }\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    auto start_time = chrono::high_resolution_clock::now();\n    auto get_elapsed = [&]() {\n        return chrono::duration<double>(chrono::high_resolution_clock::now() - start_time).count();\n    };\n    \n    int N, T;\n    double sigma;\n    cin >> N >> T >> sigma;\n    \n    vector<double> w(N), h(N);\n    for (int i = 0; i < N; i++) {\n        int wo, ho;\n        cin >> wo >> ho;\n        w[i] = wo;\n        h[i] = ho;\n    }\n    \n    double w_ratio = 1.0, h_ratio = 1.0;\n    \n    for (int t = 0; t < T; t++) {\n        double elapsed = get_elapsed();\n        \n        vector<double> aw(N), ah(N);\n        for (int i = 0; i < N; i++) {\n            aw[i] = w[i] * w_ratio;\n            ah[i] = h[i] * h_ratio;\n        }\n        \n        vector<tuple<int,int,char,int>> solution;\n        double final_W = 0, final_H = 0;\n        \n        auto greedy_solve = [&]() {\n            vector<tuple<double,double,double,double,int>> placed;\n            solution.clear();\n            \n            auto find_y = [&](double x, double ww) -> double {\n                double y = 0;\n                for (auto& [px,py,pw,ph,idx] : placed)\n                    if (px < x+ww && x < px+pw) y = max(y, py+ph);\n                return y;\n            };\n            auto find_x = [&](double y, double hh) -> double {\n                double x = 0;\n                for (auto& [px,py,pw,ph,idx] : placed)\n                    if (py < y+hh && y < py+ph) x = max(x, px+pw);\n                return x;\n            };\n            auto get_ref_x = [&](int idx) -> double {\n                for (auto& [px,py,pw,ph,i] : placed) if (i==idx) return px+pw;\n                return 0.0;\n            };\n            auto get_ref_y = [&](int idx) -> double {\n                for (auto& [px,py,pw,ph,i] : placed) if (i==idx) return py+ph;\n                return 0.0;\n            };\n            \n            for (int i = 0; i < N; i++) {\n                double best_score = 1e18;\n                int best_rot = 0; char best_d = 'U'; int best_b = -1;\n                \n                for (int rot = 0; rot < 2; rot++) {\n                    double rw = rot ? ah[i] : aw[i], rh = rot ? aw[i] : ah[i];\n                    auto try_place = [&](double x, double y, char d, int b) {\n                        double W = x+rw, H = y+rh;\n                        for (auto& [px,py,pw,ph,idx] : placed) { W = max(W,px+pw); H = max(H,py+ph); }\n                        if (W+H < best_score) { best_score = W+H; best_rot = rot; best_d = d; best_b = b; }\n                    };\n                    try_place(0, find_y(0,rw), 'U', -1);\n                    for (auto& [px,py,pw,ph,idx] : placed)\n                        try_place(px+pw, find_y(px+pw,rw), 'U', idx);\n                    try_place(find_x(0,rh), 0, 'L', -1);\n                    for (auto& [px,py,pw,ph,idx] : placed)\n                        try_place(find_x(py+ph,rh), py+ph, 'L', idx);\n                }\n                \n                double cur_W = 0, cur_H = 0;\n                for (auto& [px,py,pw,ph,idx] : placed) { cur_W = max(cur_W, px+pw); cur_H = max(cur_H, py+ph); }\n                if (cur_W + cur_H + aw[i] + ah[i] < best_score) continue;\n                \n                double rw = best_rot ? ah[i] : aw[i], rh = best_rot ? aw[i] : ah[i];\n                double x, y;\n                if (best_d == 'U') { x = best_b==-1 ? 0 : get_ref_x(best_b); y = find_y(x,rw); }\n                else { y = best_b==-1 ? 0 : get_ref_y(best_b); x = find_x(y,rh); }\n                placed.emplace_back(x, y, rw, rh, i);\n                solution.emplace_back(i, best_rot, best_d, best_b);\n            }\n            final_W = 0; final_H = 0;\n            for (auto& [px,py,pw,ph,idx] : placed) { final_W = max(final_W, px+pw); final_H = max(final_H, py+ph); }\n        };\n        \n        if (elapsed > 2.3) {\n            greedy_solve();\n        } else {\n            int BEAM = 12, MAX_OPTS = 4;\n            if (elapsed > 1.6) { BEAM = 10; MAX_OPTS = 4; }\n            if (elapsed > 1.9) { BEAM = 8; MAX_OPTS = 3; }\n            \n            struct State {\n                int parent, idx, rot, ref;\n                char dir;\n                double placed_sum, W, H, x, y, rw, rh;\n                bool skipped;\n            };\n            \n            vector<State> states;\n            states.push_back({-1, -1, 0, -1, 'U', 0, 0, 0, 0, 0, 0, 0, true});\n            vector<int> beam = {0};\n            \n            for (int i = 0; i < N; i++) {\n                vector<pair<double, int>> candidates;\n                \n                for (int bi : beam) {\n                    vector<tuple<double,double,double,double,int>> placed;\n                    for (int cur = bi; cur != -1 && states[cur].idx >= 0; cur = states[cur].parent) {\n                        auto& s = states[cur];\n                        if (!s.skipped) placed.emplace_back(s.x, s.y, s.rw, s.rh, s.idx);\n                    }\n                    reverse(placed.begin(), placed.end());\n                    \n                    auto& st = states[bi];\n                    double new_sum = st.placed_sum + aw[i] + ah[i];\n                    \n                    candidates.push_back({st.W + st.H - st.placed_sum, (int)states.size()});\n                    states.push_back({bi, i, 0, -1, 'U', st.placed_sum, st.W, st.H, 0, 0, 0, 0, true});\n                    \n                    vector<tuple<double,double,double,int,char,int>> opts;\n                    \n                    for (int rot = 0; rot < 2; rot++) {\n                        double rw = rot ? ah[i] : aw[i], rh = rot ? aw[i] : ah[i];\n                        auto find_y = [&](double x, double ww) -> double {\n                            double y = 0;\n                            for (auto& [px,py,pw,ph,idx] : placed)\n                                if (px < x+ww && x < px+pw) y = max(y, py+ph);\n                            return y;\n                        };\n                        auto find_x = [&](double y, double hh) -> double {\n                            double x = 0;\n                            for (auto& [px,py,pw,ph,idx] : placed)\n                                if (py < y+hh && y < py+ph) x = max(x, px+pw);\n                            return x;\n                        };\n                        \n                        auto add_opt = [&](double x, double y, char d, int b) {\n                            double nW = max(st.W, x+rw), nH = max(st.H, y+rh);\n                            opts.emplace_back(nW+nH-new_sum, x, y, rot, d, b);\n                        };\n                        \n                        add_opt(0, find_y(0,rw), 'U', -1);\n                        for (auto& [px,py,pw,ph,idx] : placed)\n                            add_opt(px+pw, find_y(px+pw,rw), 'U', idx);\n                        add_opt(find_x(0,rh), 0, 'L', -1);\n                        for (auto& [px,py,pw,ph,idx] : placed)\n                            add_opt(find_x(py+ph,rh), py+ph, 'L', idx);\n                    }\n                    \n                    sort(opts.begin(), opts.end());\n                    opts.erase(unique(opts.begin(), opts.end()), opts.end());\n                    \n                    int kept = min((int)opts.size(), MAX_OPTS - 1);\n                    for (int j = 0; j < kept; j++) {\n                        auto& [cost, x, y, rot, d, b] = opts[j];\n                        double rw = rot ? ah[i] : aw[i], rh = rot ? aw[i] : ah[i];\n                        double nW = max(st.W, x+rw), nH = max(st.H, y+rh);\n                        candidates.push_back({cost, (int)states.size()});\n                        states.push_back({bi, i, rot, b, d, new_sum, nW, nH, x, y, rw, rh, false});\n                    }\n                }\n                \n                int select = min(BEAM, (int)candidates.size());\n                partial_sort(candidates.begin(), candidates.begin() + select, candidates.end());\n                candidates.resize(select);\n                beam.clear();\n                for (auto& [c, idx] : candidates) beam.push_back(idx);\n            }\n            \n            for (int cur = beam[0]; cur != -1 && states[cur].idx >= 0; cur = states[cur].parent) {\n                auto& s = states[cur];\n                if (!s.skipped) solution.push_back({s.idx, s.rot, s.dir, s.ref});\n            }\n            reverse(solution.begin(), solution.end());\n            final_W = states[beam[0]].W;\n            final_H = states[beam[0]].H;\n        }\n        \n        cout << solution.size() << \"\\n\";\n        for (auto& [idx, rot, dir, ref] : solution)\n            cout << idx << \" \" << rot << \" \" << dir << \" \" << ref << \"\\n\";\n        cout.flush();\n        \n        int W_meas, H_meas;\n        cin >> W_meas >> H_meas;\n        \n        if (final_W > 0 && final_H > 0 && !solution.empty()) {\n            double wr = W_meas / final_W, hr = H_meas / final_H;\n            double alpha = 0.2 / (1 + t * 0.015);\n            w_ratio = w_ratio * (1-alpha) + wr * alpha;\n            h_ratio = h_ratio * (1-alpha) + hr * alpha;\n        }\n    }\n    \n    return 0;\n}","ahc041":"#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, H;\n    cin >> N >> M >> H;\n    \n    vector<int> A(N);\n    for (int i = 0; i < N; i++) cin >> A[i];\n    \n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    \n    vector<int> tmp(N);\n    for (int i = 0; i < N; i++) cin >> tmp[i] >> tmp[i];\n    \n    vector<vector<int>> dist_mat(N, vector<int>(N, H + 1));\n    for (int s = 0; s < N; s++) {\n        dist_mat[s][s] = 0;\n        queue<int> q;\n        q.push(s);\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int v : adj[u]) {\n                if (dist_mat[s][v] == H + 1) {\n                    dist_mat[s][v] = dist_mat[s][u] + 1;\n                    q.push(v);\n                }\n            }\n        }\n    }\n    \n    vector<bitset<1000>> cover(N);\n    for (int v = 0; v < N; v++) {\n        for (int u = 0; u < N; u++) {\n            if (dist_mat[v][u] <= H) cover[v].set(u);\n        }\n    }\n    \n    vector<vector<int>> dist2(N);\n    for (int v = 0; v < N; v++) {\n        set<int> s;\n        for (int u : adj[v]) {\n            s.insert(u);\n            for (int w : adj[u]) s.insert(w);\n        }\n        dist2[v].assign(s.begin(), s.end());\n    }\n    \n    auto is_valid = [&](const vector<bool>& is_root) -> bool {\n        bitset<1000> covered;\n        for (int v = 0; v < N; v++) {\n            if (is_root[v]) covered |= cover[v];\n        }\n        return covered.count() == N;\n    };\n    \n    auto compute_score = [&](const vector<bool>& is_root) -> long long {\n        long long score = 0;\n        for (int v = 0; v < N; v++) {\n            int min_d = H + 1;\n            for (int u = 0; u < N; u++) {\n                if (is_root[u]) min_d = min(min_d, dist_mat[v][u]);\n            }\n            if (min_d <= H) score += (long long)(min_d + 1) * A[v];\n        }\n        return score;\n    };\n    \n    auto local_search = [&](vector<bool>& is_root) -> void {\n        bool changed = true;\n        while (changed) {\n            changed = false;\n            for (int v = 0; v < N; v++) {\n                if (!is_root[v]) continue;\n                is_root[v] = false;\n                if (is_valid(is_root)) changed = true;\n                else is_root[v] = true;\n            }\n        }\n        \n        changed = true;\n        while (changed) {\n            changed = false;\n            for (int v = 0; v < N; v++) {\n                if (!is_root[v]) continue;\n                for (int u : dist2[v]) {\n                    if (is_root[u] || A[u] >= A[v]) continue;\n                    is_root[v] = false;\n                    is_root[u] = true;\n                    if (is_valid(is_root)) { changed = true; break; }\n                    is_root[v] = true;\n                    is_root[u] = false;\n                }\n                if (changed) break;\n            }\n        }\n    };\n    \n    vector<bool> best_roots(N, false);\n    long long best_score = -1;\n    \n    mt19937 rng(42);\n    \n    for (int trial = 0; trial < 150; trial++) {\n        bitset<1000> uncovered;\n        for (int i = 0; i < N; i++) uncovered.set(i);\n        \n        vector<bool> is_root(N, false);\n        \n        while (uncovered.any()) {\n            int best_count = 0;\n            vector<int> candidates;\n            \n            for (int v = 0; v < N; v++) {\n                int count = (cover[v] & uncovered).count();\n                if (count > best_count) {\n                    best_count = count;\n                    candidates = {v};\n                } else if (count == best_count) {\n                    candidates.push_back(v);\n                }\n            }\n            \n            if (best_count == 0) break;\n            \n            uniform_int_distribution<int> dist(0, candidates.size() - 1);\n            int chosen = candidates[dist(rng)];\n            \n            is_root[chosen] = true;\n            uncovered &= ~cover[chosen];\n        }\n        \n        local_search(is_root);\n        \n        long long score = compute_score(is_root);\n        if (score > best_score) {\n            best_score = score;\n            best_roots = is_root;\n        }\n    }\n    \n    for (int iter = 0; iter < 100; iter++) {\n        long long current_score = compute_score(best_roots);\n        int best_v = -1, best_u = -1;\n        long long best_new_score = current_score;\n        bool do_swap = false;\n        \n        for (int v = 0; v < N; v++) {\n            if (!best_roots[v]) continue;\n            best_roots[v] = false;\n            if (is_valid(best_roots)) {\n                long long new_score = compute_score(best_roots);\n                if (new_score > best_new_score) {\n                    best_new_score = new_score;\n                    best_v = v;\n                    best_u = -1;\n                    do_swap = false;\n                }\n            }\n            best_roots[v] = true;\n        }\n        \n        for (int v = 0; v < N; v++) {\n            if (!best_roots[v]) continue;\n            for (int u : adj[v]) {\n                if (best_roots[u]) continue;\n                best_roots[v] = false;\n                best_roots[u] = true;\n                if (is_valid(best_roots)) {\n                    long long new_score = compute_score(best_roots);\n                    if (new_score > best_new_score) {\n                        best_new_score = new_score;\n                        best_v = v;\n                        best_u = u;\n                        do_swap = true;\n                    }\n                }\n                best_roots[v] = true;\n                best_roots[u] = false;\n            }\n        }\n        \n        if (best_v == -1) break;\n        best_roots[best_v] = false;\n        if (do_swap) best_roots[best_u] = true;\n    }\n    \n    vector<int> parent(N, -1);\n    vector<int> height(N, -1);\n    queue<int> q;\n    \n    for (int v = 0; v < N; v++) {\n        if (best_roots[v]) {\n            height[v] = 0;\n            q.push(v);\n        }\n    }\n    \n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : adj[u]) {\n            if (height[v] == -1 && height[u] < H) {\n                height[v] = height[u] + 1;\n                parent[v] = u;\n                q.push(v);\n            }\n        }\n    }\n    \n    for (int v = 0; v < N; v++) {\n        if (height[v] == -1) {\n            height[v] = 0;\n            q.push(v);\n            while (!q.empty()) {\n                int u = q.front(); q.pop();\n                for (int w : adj[u]) {\n                    if (height[w] == -1 && height[u] < H) {\n                        height[w] = height[u] + 1;\n                        parent[w] = u;\n                        q.push(w);\n                    }\n                }\n            }\n        }\n    }\n    \n    for (int v = 0; v < N; v++) {\n        cout << parent[v];\n        if (v < N - 1) cout << \" \";\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N; cin >> N;\n    vector<string> board(N);\n    for (int i = 0; i < N; i++) cin >> board[i];\n    \n    vector<int> fmin_r(N,N), fmax_r(N,-1), fmin_c(N,N), fmax_c(N,-1);\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (board[i][j]=='o') {\n        fmin_r[i]=min(fmin_r[i],j); fmax_r[i]=max(fmax_r[i],j);\n        fmin_c[j]=min(fmin_c[j],i); fmax_c[j]=max(fmax_c[j],i);\n    }\n    \n    map<pair<int,int>,int> md;\n    \n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (board[i][j]=='x') {\n        int best_d = -1, best_dist = N+1;\n        if (fmin_c[j]>i||fmin_c[j]==N) { int d=i+1; if(d<best_dist){best_dist=d;best_d=0;} }\n        if (fmax_c[j]<i||fmax_c[j]==-1) { int d=N-i; if(d<best_dist){best_dist=d;best_d=1;} }\n        if (fmin_r[i]>j||fmin_r[i]==N) { int d=j+1; if(d<best_dist){best_dist=d;best_d=2;} }\n        if (fmax_r[i]<j||fmax_r[i]==-1) { int d=N-j; if(d<best_dist){best_dist=d;best_d=3;} }\n        int idx = (best_d<=1)?j:i;\n        md[{idx,best_d}] = max(md[{idx,best_d}], best_dist);\n    }\n    \n    for(auto&[key,dist]:md) {\n        auto[idx,d]=key;\n        char c=\"UDLR\"[d], cr=\"DULR\"[d];\n        for(int t=0;t<dist;t++) cout<<c<<\" \"<<idx<<\"\\n\";\n        for(int t=0;t<dist;t++) cout<<cr<<\" \"<<idx<<\"\\n\";\n    }\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, L;\n    cin >> N >> L;\n    \n    vector<int> T(N);\n    for (int i = 0; i < N; i++) {\n        cin >> T[i];\n    }\n    \n    vector<int> a(N, -1), b(N, -1);\n    vector<int> cnt(N, 0);\n    cnt[0] = 1;\n    \n    vector<int> remain = T;\n    remain[0]--;\n    \n    auto choose_next = [&](int current, int week) -> int {\n        double best_deficit = -1e18;\n        int best_remain = -1;\n        int best = -1;\n        \n        for (int i = 0; i < N; i++) {\n            if (i == current) continue;\n            if (remain[i] <= 0) continue;\n            \n            double expected = (double)T[i] * week / L;\n            double deficit = expected - cnt[i];\n            \n            if (deficit > best_deficit + 1e-9 || (abs(deficit - best_deficit) < 1e-9 && remain[i] > best_remain)) {\n                best_deficit = deficit;\n                best_remain = remain[i];\n                best = i;\n            }\n        }\n        \n        if (best == -1) {\n            best = current;\n        }\n        \n        return best;\n    };\n    \n    int current = 0;\n    for (int week = 2; week <= L; week++) {\n        int k = cnt[current];\n        \n        int next;\n        if (k % 2 == 1) {\n            if (a[current] == -1) {\n                a[current] = choose_next(current, week);\n            }\n            next = a[current];\n        } else {\n            if (b[current] == -1) {\n                b[current] = choose_next(current, week);\n            }\n            next = b[current];\n        }\n        \n        cnt[next]++;\n        remain[next]--;\n        current = next;\n    }\n    \n    for (int i = 0; i < N; i++) {\n        if (a[i] == -1) a[i] = 0;\n        if (b[i] == -1) b[i] = 0;\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    vector<int> parent, sz;\n    DSU(int n) : parent(n), sz(n, 1) { 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) return false;\n        if (sz[x] < sz[y]) swap(x, y);\n        parent[y] = x; sz[x] += sz[y]; return true;\n    }\n};\n\nint N, M, Q, L, W;\nvector<int> G, cx, cy;\ndouble estDist(int i, int j) { double dx=cx[i]-cx[j], dy=cy[i]-cy[j]; return sqrt(dx*dx+dy*dy); }\n\nvector<pair<int,int>> doQuery(vector<int>& cities) {\n    cout << \"? \" << cities.size();\n    for (int c : cities) cout << \" \" << c;\n    cout << \"\\n\" << flush;\n    vector<pair<int,int>> edges(cities.size() - 1);\n    for (int i = 0; i < (int)cities.size() - 1; i++) cin >> edges[i].first >> edges[i].second;\n    return edges;\n}\n\nvoid findMST(vector<int>& cities, vector<pair<int,int>>& edges, int& queriesLeft) {\n    int n = cities.size();\n    if (n <= 1) return;\n    if (n == 2) { edges.push_back({min(cities[0],cities[1]), max(cities[0],cities[1])}); return; }\n    sort(cities.begin(), cities.end(), [](int a, int b) { return cx[a]!=cx[b] ? cx[a]<cx[b] : cy[a]<cy[b]; });\n    if (n <= L && queriesLeft > 0) { auto r = doQuery(cities); edges.insert(edges.end(), r.begin(), r.end()); queriesLeft--; return; }\n    if (queriesLeft <= 0) { for (int i = 0; i < n-1; i++) edges.push_back({min(cities[i],cities[i+1]), max(cities[i],cities[i+1])}); return; }\n    \n    vector<vector<int>> chunks;\n    for (int i = 0; i < n; i += L) {\n        vector<int> chunk;\n        for (int j = i; j < min(i+L, n); j++) chunk.push_back(cities[j]);\n        chunks.push_back(chunk);\n    }\n    vector<int> reps;\n    for (auto& chunk : chunks) {\n        int sz = chunk.size();\n        if (sz >= 2 && queriesLeft > 0) {\n            auto result = doQuery(chunk);\n            edges.insert(edges.end(), result.begin(), result.end());\n            map<int,int> deg;\n            for (auto& [u,v] : result) { deg[u]++; deg[v]++; }\n            int bestRep = chunk[0], maxDeg = 0;\n            for (int c : chunk) if (deg[c] > maxDeg) { maxDeg = deg[c]; bestRep = c; }\n            reps.push_back(bestRep); queriesLeft--;\n        } else if (sz >= 2) {\n            for (int j = 0; j < sz-1; j++) edges.push_back({min(chunk[j],chunk[j+1]), max(chunk[j],chunk[j+1])});\n            double cX=0, cY=0; for (int c:chunk) { cX+=cx[c]; cY+=cy[c]; } cX/=sz; cY/=sz;\n            int bestRep=chunk[0]; double bd=1e18;\n            for (int c:chunk) { double d=(cx[c]-cX)*(cx[c]-cX)+(cy[c]-cY)*(cy[c]-cY); if(d<bd){bd=d;bestRep=c;} }\n            reps.push_back(bestRep);\n        } else reps.push_back(chunk[0]);\n    }\n    findMST(reps, edges, queriesLeft);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M); for (int i=0;i<M;i++) cin>>G[i];\n    cx.resize(N); cy.resize(N);\n    for (int i=0;i<N;i++) { int lx,rx,ly,ry; cin>>lx>>rx>>ly>>ry; cx[i]=(lx+rx)/2; cy[i]=(ly+ry)/2; }\n    \n    vector<tuple<double,int,int>> allEdges;\n    for (int i=0;i<N;i++) for (int j=i+1;j<N;j++) allEdges.push_back({estDist(i,j),i,j});\n    sort(allEdges.begin(), allEdges.end());\n    DSU dsu(N); vector<tuple<double,int,int>> mstEdges;\n    for (auto& [d,u,v] : allEdges) { if(dsu.unite(u,v)) mstEdges.push_back({d,u,v}); if((int)mstEdges.size()==N-1) break; }\n    \n    vector<vector<pair<double,int>>> adj(N);\n    for (auto& [d,u,v] : mstEdges) { adj[u].push_back({d,v}); adj[v].push_back({d,u}); }\n    \n    vector<int> dfsOrder; vector<bool> vis(N,false);\n    function<void(int)> dfs = [&](int u) {\n        vis[u]=true; dfsOrder.push_back(u);\n        vector<pair<double,int>> nb; for (auto& [d,v]:adj[u]) if(!vis[v]) nb.push_back({d,v});\n        sort(nb.begin(), nb.end());\n        for (auto& [d,v]:nb) if(!vis[v]) dfs(v);\n    };\n    dfs(0);\n    \n    vector<vector<int>> groups(M); int idx=0;\n    for (int i=0;i<M;i++) for (int j=0;j<G[i];j++) groups[i].push_back(dfsOrder[idx++]);\n    \n    vector<int> gOrder(M); iota(gOrder.begin(),gOrder.end(),0);\n    sort(gOrder.begin(),gOrder.end(),[](int a,int b){return G[a]>G[b];});\n    \n    int queriesLeft = Q; vector<vector<pair<int,int>>> allEdgesOut(M);\n    for (int gi : gOrder) findMST(groups[gi], allEdgesOut[gi], queriesLeft);\n    \n    cout << \"!\\n\";\n    for (int i=0;i<M;i++) {\n        for (int j=0;j<(int)groups[i].size();j++) { if(j>0) cout<<\" \"; cout<<groups[i][j]; }\n        cout<<\"\\n\";\n        for (auto& e : allEdgesOut[i]) cout<<e.first<<\" \"<<e.second<<\"\\n\";\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nbool grid[20][20];\nint ci, cj;\nvector<string> actions;\n\nint dx[] = {-1, 1, 0, 0};\nint dy[] = {0, 0, -1, 1};\nchar dirChar[] = {'U', 'D', 'L', 'R'};\n\nbool inBounds(int i, int j) { return i >= 0 && i < N && j >= 0 && j < N; }\n\nvoid addMove(int d) {\n    actions.push_back(string(\"M \") + dirChar[d]);\n    ci += dx[d]; cj += dy[d];\n}\n\nvoid addSlide(int d) {\n    actions.push_back(string(\"S \") + dirChar[d]);\n    while (inBounds(ci + dx[d], cj + dy[d]) && !grid[ci + dx[d]][cj + dy[d]]) {\n        ci += dx[d]; cj += dy[d];\n    }\n}\n\npair<int,int> getSlideDest(int d) {\n    int ni = ci, nj = cj;\n    while (inBounds(ni + dx[d], nj + dy[d]) && !grid[ni + dx[d]][nj + dy[d]]) {\n        ni += dx[d]; nj += dy[d];\n    }\n    return make_pair(ni, nj);\n}\n\nvoid goTo(int ti, int tj) {\n    while (ci != ti || cj != tj) {\n        bool targetOnTop = (ti == 0);\n        bool targetOnBottom = (ti == N - 1);\n        bool targetOnLeft = (tj == 0);\n        bool targetOnRight = (tj == N - 1);\n        \n        bool slid = false;\n        if (cj == tj && ci != ti) {\n            int slideDir = -1;\n            if (targetOnTop && ci > ti) slideDir = 0;\n            else if (targetOnBottom && ci < ti) slideDir = 1;\n            if (slideDir >= 0) {\n                pair<int,int> dest = getSlideDest(slideDir);\n                if (dest.first == ti) { addSlide(slideDir); slid = true; }\n            }\n        }\n        if (!slid && ci == ti && cj != tj) {\n            int slideDir = -1;\n            if (targetOnLeft && cj > tj) slideDir = 2;\n            else if (targetOnRight && cj < tj) slideDir = 3;\n            if (slideDir >= 0) {\n                pair<int,int> dest = getSlideDest(slideDir);\n                if (dest.second == tj) { addSlide(slideDir); slid = true; }\n            }\n        }\n        if (slid) continue;\n        \n        int manhattan = abs(ci - ti) + abs(cj - tj);\n        int bestDir = -1;\n        int bestSavings = 0;\n        \n        // Prefer alignment with higher savings\n        if ((targetOnTop || targetOnBottom) && cj != tj) {\n            int alignCost = abs(cj - tj);\n            int slideBenefit = abs(ci - ti);\n            int savings = slideBenefit - 1;\n            if (savings > bestSavings && alignCost < manhattan) {\n                bestSavings = savings;\n                bestDir = (cj < tj) ? 3 : 2;\n            }\n        }\n        if ((targetOnLeft || targetOnRight) && ci != ti) {\n            int alignCost = abs(ci - ti);\n            int slideBenefit = abs(cj - tj);\n            int savings = slideBenefit - 1;\n            if (savings > bestSavings && alignCost < manhattan) {\n                bestSavings = savings;\n                bestDir = (ci < ti) ? 1 : 0;\n            }\n        }\n        \n        if (bestDir == -1) {\n            if (ci < ti) bestDir = 1;\n            else if (ci > ti) bestDir = 0;\n            else if (cj < tj) bestDir = 3;\n            else bestDir = 2;\n        }\n        \n        addMove(bestDir);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> ci >> cj;\n    // FIX: Only M-1 targets after start position\n    int numTargets = M - 1;\n    vector<pair<int,int>> targets(numTargets);\n    for (int i = 0; i < numTargets; i++) {\n        cin >> targets[i].first >> targets[i].second;\n    }\n    \n    memset(grid, 0, sizeof(grid));\n    \n    for (int i = 0; i < numTargets; i++) {\n        goTo(targets[i].first, targets[i].second);\n    }\n    \n    for (size_t i = 0; i < actions.size(); i++) {\n        cout << actions[i] << \"\\n\";\n    }\n    \n    return 0;\n}"},"8":{"ahc001":"#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\n\nstruct Company { int x, y, r; };\nstruct Rect { int a, b, c, d; };\n\ninline double calcScore(int count, long long capacity, long long required) {\n    if (count <= 0 || capacity <= 0) return -1e18;\n    double ratio = (double)capacity / required;\n    double r = (ratio <= 1) ? ratio : 1.0/ratio;\n    return count * (2.0 - r) * r;\n}\n\nvoid solve(Rect R, vector<int> ids, vector<Company>& C, vector<Rect>& res, mt19937& rng, int depth, bool doRand) {\n    if (ids.empty()) return;\n    if ((int)ids.size() == 1) { res[ids[0]] = R; return; }\n    \n    int w = R.c - R.a, h = R.d - R.b;\n    long long total = 0;\n    for (int i : ids) total += C[i].r;\n    \n    double bestScore = -1e18;\n    int bestSplit = -1, bestIdx = -1;\n    bool bestVert = true;\n    \n    int d0 = 0, d1 = 1;\n    if (doRand && depth < 4 && rng() % 3 == 0) swap(d0, d1);\n    \n    for (int vert : {d0, d1}) {\n        sort(ids.begin(), ids.end(), [&](int a, int b) {\n            return vert ? C[a].x < C[b].x : C[a].y < C[b].y;\n        });\n        long long acc = 0;\n        for (int i = 0; i < (int)ids.size()-1; i++) {\n            acc += C[ids[i]].r;\n            int c1 = vert ? C[ids[i]].x : C[ids[i]].y;\n            int c2 = vert ? C[ids[i+1]].x : C[ids[i+1]].y;\n            if (c1 == c2) continue;\n            int lo, hi;\n            if (vert) { lo = max(R.a+1, c1+1); hi = min(R.c-1, c2); }\n            else { lo = max(R.b+1, c1+1); hi = min(R.d-1, c2); }\n            if (lo > hi) continue;\n            \n            long long leftA = acc, rightA = total - acc;\n            int lCnt = i + 1, rCnt = (int)ids.size() - i - 1;\n            double ratio = (double)leftA / rightA;\n            int opt = vert ? R.a + (int)((w * ratio) / (1 + ratio))\n                           : R.b + (int)((h * ratio) / (1 + ratio));\n            opt = max(lo, min(hi, opt));\n            \n            int spread = (depth < 3) ? 18 : (depth < 6) ? 8 : 2;\n            vector<int> cands;\n            for (int d = -spread; d <= spread; d++) cands.push_back(max(lo, min(hi, opt + d)));\n            \n            if (doRand && depth < 5) {\n                uniform_int_distribution<int> dist(lo, hi);\n                int numRand = (depth < 3) ? 6 : 3;\n                for (int j = 0; j < numRand; j++) cands.push_back(dist(rng));\n            }\n            \n            sort(cands.begin(), cands.end());\n            cands.erase(unique(cands.begin(), cands.end()), cands.end());\n            \n            for (int s : cands) {\n                long long leftC = vert ? (long long)(s-R.a)*h : (long long)w*(s-R.b);\n                long long rightC = vert ? (long long)(R.c-s)*h : (long long)w*(R.d-s);\n                double score = calcScore(lCnt, leftC, leftA) + calcScore(rCnt, rightC, rightA);\n                bool accept = score > bestScore;\n                if (!accept && doRand && depth < 5 && bestScore > -1e17 && \n                    score > bestScore - 0.03 * (lCnt + rCnt) && rng() % 30 == 0)\n                    accept = true;\n                if (accept) { bestScore = score; bestSplit = s; bestVert = vert; bestIdx = i; }\n            }\n        }\n    }\n    \n    if (bestSplit == -1) {\n        for (int i : ids) res[i] = {C[i].x, C[i].y, C[i].x+1, C[i].y+1};\n        return;\n    }\n    sort(ids.begin(), ids.end(), [&](int a, int b) {\n        return bestVert ? C[a].x < C[b].x : C[a].y < C[b].y;\n    });\n    vector<int> left(ids.begin(), ids.begin()+bestIdx+1);\n    vector<int> right(ids.begin()+bestIdx+1, ids.end());\n    if (bestVert) {\n        solve({R.a, R.b, bestSplit, R.d}, left, C, res, rng, depth + 1, doRand);\n        solve({bestSplit, R.b, R.c, R.d}, right, C, res, rng, depth + 1, doRand);\n    } else {\n        solve({R.a, R.b, R.c, bestSplit}, left, C, res, rng, depth + 1, doRand);\n        solve({R.a, bestSplit, R.c, R.d}, right, C, res, rng, depth + 1, doRand);\n    }\n}\n\ndouble totalSat(const vector<Rect>& res, const vector<Company>& C) {\n    double score = 0;\n    for (size_t i = 0; i < res.size(); i++) {\n        int s = (res[i].c - res[i].a) * (res[i].d - res[i].b);\n        double r = (double)min(C[i].r, s) / max(C[i].r, s);\n        score += (2.0 - r) * r;\n    }\n    return score;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(nullptr);\n    int n; cin >> n;\n    vector<Company> C(n);\n    unsigned int h = 12345;\n    for (int i = 0; i < n; i++) {\n        cin >> C[i].x >> C[i].y >> C[i].r;\n        h ^= (unsigned)C[i].x * 0x9e3779b9;\n        h ^= (unsigned)C[i].y * 0x517cc1b7;\n        h ^= (unsigned)C[i].r * 0x27d4eb2d;\n    }\n    \n    vector<Rect> bestRes(n);\n    double bestScore = -1;\n    \n    auto start = chrono::steady_clock::now();\n    mt19937 rng(h);\n    int trial = 0;\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start).count() > 4500) break;\n        \n        if (trial > 0 && trial % 50 == 0) rng.seed(h + trial);\n        \n        vector<Rect> res(n);\n        vector<int> ids(n); iota(ids.begin(), ids.end(), 0);\n        solve({0,0,10000,10000}, ids, C, res, rng, 0, trial > 0);\n        double score = totalSat(res, C);\n        if (score > bestScore) { bestScore = score; bestRes = res; }\n        trial++;\n    }\n    \n    for (int i = 0; i < n; i++)\n        cout << bestRes[i].a << \" \" << bestRes[i].b << \" \" << bestRes[i].c << \" \" << bestRes[i].d << \"\\n\";\n    return 0;\n}","ahc002":"#include <iostream>\n#include <string>\n#include <algorithm>\n#include <chrono>\n#include <cstring>\n#include <random>\n\nusing namespace std;\n\nconst int DEPTH_LIMIT = 120; // Balanced for speed vs exploration accuracy\nconst int MAX_TILES = 2500;\n\nint cell_to_tile[50][50];\nint p_val[50][50];\nbool vis[MAX_TILES];\n\nint temp_vis[2500];\nint dfs_stack[2500];\nint current_stamp = 0;\n\nint dr[4] = {-1, 1, 0, 0};\nint dc[4] = {0, 0, -1, 1};\n\nstruct DFSResult {\n    int cnt;\n    int sum_p;\n};\n\nDFSResult cell_dfs(int start_cell, int f1, int f2, int f3) {\n    current_stamp++;\n    int cnt = 0;\n    int sum_p = 0;\n    int stack_ptr = 0;\n    dfs_stack[stack_ptr++] = start_cell;\n    temp_vis[start_cell] = current_stamp;\n    \n    while (stack_ptr > 0) {\n        int node = dfs_stack[--stack_ptr];\n        int r = node / 50, c = node % 50;\n        cnt++;\n        sum_p += p_val[r][c];\n        if (cnt >= DEPTH_LIMIT) break;\n        \n        for (int d = 0; d < 4; ++d) {\n            int nr = r + dr[d], nc = c + dc[d];\n            if (nr < 0 || nr >= 50 || nc < 0 || nc >= 50) continue;\n            int n_node = nr * 50 + nc;\n            if (temp_vis[n_node] == current_stamp) continue;\n            \n            int T = cell_to_tile[nr][nc];\n            // Exclude current tile (f1), previous tile (f2), and candidate tile (f3)\n            if (T == f1 || T == f2 || T == f3 || vis[T]) continue;\n            \n            temp_vis[n_node] = current_stamp;\n            dfs_stack[stack_ptr++] = n_node;\n        }\n    }\n    return {cnt, sum_p};\n}\n\nint get_2hop_cell(int start_cell, int f1, int f2, int f3) {\n    int score = 0;\n    int r = start_cell / 50, c = start_cell % 50;\n    for (int d = 0; d < 4; ++d) {\n        int nr = r + dr[d], nc = c + dc[d];\n        if (nr < 0 || nr >= 50 || nc < 0 || nc >= 50) continue;\n        int T = cell_to_tile[nr][nc];\n        if (T == f1 || T == f2 || T == f3 || vis[T]) continue;\n        \n        for (int d2 = 0; d2 < 4; ++d2) {\n            int nnr = nr + dr[d2], nnc = nc + dc[d2];\n            if (nnr < 0 || nnr >= 50 || nnc < 0 || nnc >= 50) continue;\n            int T2 = cell_to_tile[nnr][nnc];\n            if (T2 == f1 || T2 == f2 || T2 == f3 || vis[T2]) continue;\n            score++;\n        }\n    }\n    return score;\n}\n\nstruct Candidate {\n    int ni, nj;\n    int p;\n    int c_w;\n    int comp_size;\n    int sum_p;\n    int hop2;\n    int w;\n};\n\nchar get_dir(int i, int j, int ni, int nj) {\n    if (ni == i - 1) return 'U';\n    if (ni == i + 1) return 'D';\n    if (nj == j - 1) return 'L';\n    if (nj == j + 1) return 'R';\n    return '?';\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int si, sj;\n    if (!(cin >> si >> sj)) return 0;\n\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            cin >> cell_to_tile[i][j];\n        }\n    }\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            cin >> p_val[i][j];\n        }\n    }\n\n    auto cmp = [&](const Candidate& a, const Candidate& b) {\n        if (a.comp_size != b.comp_size) return a.comp_size > b.comp_size;\n        \n        bool both_fully_explored = (a.comp_size < DEPTH_LIMIT);\n        \n        if (both_fully_explored) {\n            // Both components are completely known. Safely maximize value density!\n            if (a.sum_p != b.sum_p) return a.sum_p > b.sum_p;\n            if (a.hop2 != b.hop2) return a.hop2 > b.hop2;\n            if (a.c_w != b.c_w) return a.c_w > b.c_w;\n        } else {\n            // Both components are CAPPED (size >= DEPTH_LIMIT). We are blind to their true size.\n            // ONLY avoid guaranteed immediate traps. Otherwise, intentionally leave them EQUAL\n            // so the initial random shuffle of directions makes the choice (Monte Carlo)!\n            if (a.c_w == 0 && b.c_w != 0) return false;\n            if (b.c_w == 0 && a.c_w != 0) return true;\n            if (a.hop2 == 0 && b.hop2 != 0) return false;\n            if (b.hop2 == 0 && a.hop2 != 0) return true;\n            return false; \n        }\n        \n        if (a.p != b.p) return a.p > b.p;\n        return false; \n    };\n\n    std::mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    string best_path = \"\";\n    int best_score = -1;\n\n    int dirs_idx[4] = {0, 1, 2, 3};\n\n    // 25 runs provides excellent coverage for the Monte Carlo tie-breaker\n    for (int run = 0; run < 25; ++run) {\n        std::shuffle(begin(dirs_idx), end(dirs_idx), rng);\n        memset(vis, false, sizeof(vis));\n        \n        int u = cell_to_tile[si][sj];\n        vis[u] = true;\n        int i = si, j = sj;\n        int v = -1; \n        int curr_score = p_val[si][sj];\n        string curr_path = \"\";\n        curr_path.reserve(2500);\n        \n        while (true) {\n            Candidate candidates[4];\n            int num_candidates = 0;\n            \n            for (int d_id = 0; d_id < 4; ++d_id) {\n                int ni = i + dr[dirs_idx[d_id]], nj = j + dc[dirs_idx[d_id]];\n                if (ni < 0 || ni >= 50 || nj < 0 || nj >= 50) continue;\n                int w = cell_to_tile[ni][nj];\n                if (w == u || w == v || vis[w]) continue;\n                \n                int c_w = 0;\n                for (int dd = 0; dd < 4; ++dd) {\n                    int nni = ni + dr[dd], nnj = nj + dc[dd];\n                    if (nni < 0 || nni >= 50 || nnj < 0 || nnj >= 50) continue;\n                    int T = cell_to_tile[nni][nnj];\n                    if (T != u && T != v && T != w && !vis[T]) c_w++;\n                }\n                \n                candidates[num_candidates++] = {ni, nj, p_val[ni][nj], c_w, 0, 0, 0, w};\n            }\n            \n            if (num_candidates == 0) break;\n            \n            if (num_candidates > 1) {\n                for (int idx = 0; idx < num_candidates; ++idx) {\n                    DFSResult res = cell_dfs(candidates[idx].ni * 50 + candidates[idx].nj, u, v, candidates[idx].w);\n                    candidates[idx].comp_size = res.cnt;\n                    candidates[idx].sum_p = res.sum_p;\n                    candidates[idx].hop2 = get_2hop_cell(candidates[idx].ni * 50 + candidates[idx].nj, u, v, candidates[idx].w);\n                }\n            }\n            \n            sort(candidates, candidates + num_candidates, cmp);\n            \n            Candidate& best = candidates[0];\n            vis[best.w] = true;\n            curr_path += get_dir(i, j, best.ni, best.nj);\n            curr_score += best.p;\n            \n            v = u;\n            u = best.w;\n            i = best.ni;\n            j = best.nj;\n        }\n        \n        if (curr_score > best_score) {\n            best_score = curr_score;\n            best_path = curr_path;\n        }\n    }\n    \n    cout << best_path << \"\\n\";\n\n    return 0;\n}","ahc003":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <cmath>\n#include <tuple>\n#include <algorithm>\n\nusing namespace std;\n\nconst int N = 30;\nbool visited_h[N][N-1] = {false};\nbool visited_v[N-1][N] = {false};\ndouble W_h[N][N-1], W_v[N-1][N];\n\ndouble row_sum_h[N] = {0}, row_cnt_h[N] = {0};\ndouble col_sum_v[N] = {0}, col_cnt_v[N] = {0};\n\nvector<vector<double>> dist(N, vector<double>(N));\nvector<vector<pair<int, int>>> prev_node(N, vector<pair<int, int>>(N));\n\ndouble get_w_h(int i, int j) {\n    if (visited_h[i][j]) return W_h[i][j];\n    \n    // If the row has NO visits, return the safe neutral baseline 5000\n    if (row_cnt_h[i] < 0.1) return 5000.0;\n    \n    double row_w = row_sum_h[i] / row_cnt_h[i];\n    // Smoothly blend with 5000 based on how many edge-visits the row has\n    double alpha_row = min(1.0, row_cnt_h[i] * 0.1);\n    return 5000.0 + alpha_row * (row_w - 5000.0);\n}\n\ndouble get_w_v(int i, int j) {\n    if (visited_v[i][j]) return W_v[i][j];\n    \n    if (col_cnt_v[j] < 0.1) return 5000.0;\n    \n    double col_w = col_sum_v[j] / col_cnt_v[j];\n    double alpha_col = min(1.0, col_cnt_v[j] * 0.1);\n    return 5000.0 + alpha_col * (col_w - 5000.0);\n}\n\nstring dijkstra(int si, int sj, int ti, int tj) {\n    for (int i = 0; i < N; ++i) {\n        fill(dist[i].begin(), dist[i].end(), 1e18);\n        fill(prev_node[i].begin(), prev_node[i].end(), make_pair(-1, -1));\n    }\n    \n    priority_queue<pair<double, pair<int, int>>, vector<pair<double, pair<int, int>>>, greater<>> pq;\n    dist[si][sj] = 0;\n    pq.push({0.0, {si, sj}});\n\n    while (!pq.empty()) {\n        auto [d, u] = pq.top();\n        pq.pop();\n        int i = u.first, j = u.second;\n        \n        if (d > dist[i][j] + 1e-9) continue;\n        if (i == ti && j == tj) break;\n\n        if (i > 0) {\n            double w = get_w_v(i - 1, j);\n            if (dist[i][j] + w < dist[i - 1][j] - 1e-9) {\n                dist[i - 1][j] = dist[i][j] + w;\n                prev_node[i - 1][j] = {i, j};\n                pq.push({dist[i - 1][j], {i - 1, j}});\n            }\n        }\n        if (i < N - 1) {\n            double w = get_w_v(i, j);\n            if (dist[i][j] + w < dist[i + 1][j] - 1e-9) {\n                dist[i + 1][j] = dist[i][j] + w;\n                prev_node[i + 1][j] = {i, j};\n                pq.push({dist[i + 1][j], {i + 1, j}});\n            }\n        }\n        if (j > 0) {\n            double w = get_w_h(i, j - 1);\n            if (dist[i][j] + w < dist[i][j - 1] - 1e-9) {\n                dist[i][j - 1] = dist[i][j] + w;\n                prev_node[i][j - 1] = {i, j};\n                pq.push({dist[i][j - 1], {i, j - 1}});\n            }\n        }\n        if (j < N - 1) {\n            double w = get_w_h(i, j);\n            if (dist[i][j] + w < dist[i][j + 1] - 1e-9) {\n                dist[i][j + 1] = dist[i][j] + w;\n                prev_node[i][j + 1] = {i, j};\n                pq.push({dist[i][j + 1], {i, j + 1}});\n            }\n        }\n    }\n\n    string path = \"\";\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        auto p = prev_node[ci][cj];\n        int pi = p.first, pj = p.second;\n        if (pi == ci - 1) path += 'D';\n        else if (pi == ci + 1) path += 'U';\n        else if (pj == cj - 1) path += 'R';\n        else if (pj == cj + 1) path += 'L';\n        ci = pi;\n        cj = pj;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N - 1; ++j) W_h[i][j] = 5000.0;\n    }\n    for (int i = 0; i < N - 1; ++i) {\n        for (int j = 0; j < N; ++j) W_v[i][j] = 5000.0;\n    }\n\n    for (int k = 0; k < 1000; ++k) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n\n        string path = dijkstra(si, sj, ti, tj);\n        cout << path << \"\\n\" << flush;\n\n        long long result;\n        cin >> result;\n\n        double L = 0;\n        int m = path.length();\n        vector<tuple<int, int, int>> edges;\n        \n        int ci = si, cj = sj;\n        for (char c : path) {\n            if (c == 'U') {\n                edges.push_back({1, ci - 1, cj});\n                L += get_w_v(ci - 1, cj);\n                ci--;\n            } else if (c == 'D') {\n                edges.push_back({1, ci, cj});\n                L += get_w_v(ci, cj);\n                ci++;\n            } else if (c == 'L') {\n                edges.push_back({0, ci, cj - 1});\n                L += get_w_h(ci, cj - 1);\n                cj--;\n            } else if (c == 'R') {\n                edges.push_back({0, ci, cj});\n                L += get_w_h(ci, cj);\n                cj++;\n            }\n        }\n\n        if (m > 0) {\n            double delta = (result - L) / m;\n            for (auto& [type, i, j] : edges) {\n                if (type == 0) {\n                    if (!visited_h[i][j]) {\n                        visited_h[i][j] = true;\n                        // Initialize to the best hierarchical prior guess\n                        W_h[i][j] = get_w_h(i, j);\n                    }\n                    // Asymmetric learning: fast upward (bottlenecks), slow downward\n                    if (delta > 0) W_h[i][j] += 1.0 * delta;\n                    else W_h[i][j] += 0.2 * delta;\n                    \n                    W_h[i][j] = max(100.0, min(9000.0, W_h[i][j]));\n                    \n                    // Update row average with the new weight\n                    row_sum_h[i] += W_h[i][j];\n                    row_cnt_h[i] += 1.0;\n                } else {\n                    if (!visited_v[i][j]) {\n                        visited_v[i][j] = true;\n                        W_v[i][j] = get_w_v(i, j);\n                    }\n                    if (delta > 0) W_v[i][j] += 1.0 * delta;\n                    else W_v[i][j] += 0.2 * delta;\n                    \n                    W_v[i][j] = max(100.0, min(9000.0, W_v[i][j]));\n                    \n                    // Update column average with the new weight\n                    col_sum_v[j] += W_v[i][j];\n                    col_cnt_v[j] += 1.0;\n                }\n            }\n        }\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    cin >> N >> M;\n    vector<string> s(M);\n    for (int i = 0; i < M; i++) cin >> s[i];\n    \n    struct Placement { int type, row, col, len, str_idx; };\n    vector<Placement> all_placements;\n    for (int m = 0; m < M; m++) {\n        int k = s[m].size();\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++)\n            all_placements.push_back({0, i, j, k, m});\n        for (int j = 0; j < N; j++) for (int i = 0; i < N; i++)\n            all_placements.push_back({1, i, j, k, m});\n    }\n    int P = all_placements.size();\n    \n    vector<vector<pair<int,int>>> placement_cells(P), cell_placements(N*N);\n    for (int p = 0; p < P; p++) {\n        auto& pl = all_placements[p];\n        for (int q = 0; q < pl.len; q++) {\n            int r = pl.type==0 ? pl.row : (pl.row+q)%N;\n            int c = pl.type==0 ? (pl.col+q)%N : pl.col;\n            placement_cells[p].push_back({r,c});\n            cell_placements[r*N+c].push_back({p,q});\n        }\n    }\n    \n    mt19937 rng(42);\n    vector<int> order(M); iota(order.begin(), order.end(), 0);\n    \n    auto init_mismatch = [&](vector<string>& grid, vector<int16_t>& mc) {\n        fill(mc.begin(), mc.end(), 0);\n        for (int ci = 0; ci < N*N; ci++) {\n            int r = ci/N, c = ci%N; char g = grid[r][c];\n            for (auto [p, q] : cell_placements[ci])\n                if (g != s[all_placements[p].str_idx][q]) mc[p]++;\n        }\n    };\n    \n    auto local_search = [&](vector<string>& grid, vector<int16_t>& mc, double deadline) -> int {\n        vector<int> smc(M, 0);\n        for (int p = 0; p < P; p++) if (mc[p] == 0) smc[all_placements[p].str_idx]++;\n        int sc = 0; for (int m = 0; m < M; m++) if (smc[m] > 0) sc++;\n        vector<int> temp_chg(M, 0), affected; affected.reserve(200);\n        for (int iter = 0; iter < 50; iter++) {\n            if ((double)(clock()) / CLOCKS_PER_SEC > deadline) break;\n            bool imp = false;\n            for (int ci = 0; ci < N*N; ci++) {\n                int r = ci/N, c = ci%N; char oc = grid[r][c]; int bd = 0; char bc = oc;\n                for (int ch = 0; ch < 8; ch++) {\n                    char nc = 'A'+ch; if (nc == oc) continue; affected.clear();\n                    for (auto [p,q] : cell_placements[ci]) {\n                        int m = all_placements[p].str_idx; char ex = s[m][q];\n                        bool wm = (oc==ex), im = (nc==ex); if (wm == im) continue;\n                        if (wm && !im) { if (!temp_chg[m]) affected.push_back(m); temp_chg[m]--; }\n                        else if (mc[p] == 1) { if (!temp_chg[m]) affected.push_back(m); temp_chg[m]++; }\n                    }\n                    int d = 0;\n                    for (int m : affected) {\n                        bool was = smc[m] > 0, is = smc[m] + temp_chg[m] > 0;\n                        if (!was && is) d++; else if (was && !is) d--; temp_chg[m] = 0;\n                    }\n                    if (d > bd) { bd = d; bc = nc; }\n                }\n                if (bd > 0) {\n                    grid[r][c] = bc;\n                    for (auto [p,q] : cell_placements[ci]) {\n                        int m = all_placements[p].str_idx; char ex = s[m][q];\n                        bool wm = (oc==ex), im = (bc==ex); if (wm == im) continue;\n                        if (wm && !im) { mc[p]++; if (mc[p]==1) smc[m]--; }\n                        else { mc[p]--; if (mc[p]==0) smc[m]++; }\n                    }\n                    sc += bd; imp = true;\n                }\n            }\n            if (!imp) break;\n        }\n        return sc;\n    };\n    \n    auto greedy_init = [&](vector<string>& grid) {\n        fill(grid.begin(), grid.end(), string(N, '.'));\n        for (int idx : order) {\n            int k = s[idx].size(); char fc = s[idx][0];\n            vector<int> free_pl, other_pl;\n            for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n                if (grid[i][j] != '.' && grid[i][j] != fc) continue;\n                bool ok_h = true, free_h = true;\n                for (int q = 0; q < k && ok_h; q++) {\n                    int c = (j+q)%N; if (grid[i][c] != '.' && grid[i][c] != s[idx][q]) ok_h = false;\n                    if (grid[i][c] == '.') free_h = false;\n                }\n                if (ok_h) { if (free_h) free_pl.push_back(i*N+j); else other_pl.push_back(i*N+j); }\n                bool ok_v = true, free_v = true;\n                for (int q = 0; q < k && ok_v; q++) {\n                    int r = (i+q)%N; if (grid[r][j] != '.' && grid[r][j] != s[idx][q]) ok_v = false;\n                    if (grid[r][j] == '.') free_v = false;\n                }\n                if (ok_v) { if (free_v) free_pl.push_back(N*N+i*N+j); else other_pl.push_back(N*N+i*N+j); }\n            }\n            int chosen = -1;\n            if (!free_pl.empty()) chosen = free_pl[rng() % free_pl.size()];\n            else if (!other_pl.empty()) chosen = other_pl[rng() % other_pl.size()];\n            if (chosen >= 0) {\n                int type = chosen/N/N, i = (chosen%(N*N))/N, j = chosen%N;\n                for (int q = 0; q < k; q++) {\n                    int r = type==0 ? i : (i+q)%N, c = type==0 ? (j+q)%N : j;\n                    grid[r][c] = s[idx][q];\n                }\n            }\n        }\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++)\n            if (grid[i][j] == '.') grid[i][j] = 'A' + rng() % 8;\n    };\n    \n    vector<string> best_grid(N); int best_score = -1;\n    double t0 = (double)(clock()) / CLOCKS_PER_SEC;\n    \n    for (int trial = 0; trial < 5; trial++) {\n        if ((double)(clock()) / CLOCKS_PER_SEC - t0 > 1.2) break;\n        shuffle(order.begin(), order.end(), rng);\n        stable_sort(order.begin(), order.end(), [&](int a, int b) { return s[a].size() > s[b].size(); });\n        vector<string> grid(N); greedy_init(grid);\n        vector<int16_t> mc(P); init_mismatch(grid, mc);\n        int sc = local_search(grid, mc, t0 + 0.25);\n        if (sc > best_score) { best_score = sc; best_grid = grid; }\n    }\n    for (int perturb = 0; perturb < 15; perturb++) {\n        if ((double)(clock()) / CLOCKS_PER_SEC - t0 > 2.2) break;\n        vector<string> grid = best_grid;\n        for (int i = 0; i < 8 + rng()%10; i++) { int r = rng()%N, c = rng()%N; grid[r][c] = 'A'+rng()%8; }\n        vector<int16_t> mc(P); init_mismatch(grid, mc);\n        int sc = local_search(grid, mc, t0 + 0.15);\n        if (sc > best_score) { best_score = sc; best_grid = grid; }\n    }\n    vector<int16_t> mc(P); init_mismatch(best_grid, mc);\n    local_search(best_grid, mc, t0 + 2.85);\n    for (int i = 0; i < N; i++) cout << best_grid[i] << \"\\n\";\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\nusing namespace chrono;\n\nint N, si, sj;\nvector<string> grid;\nint cost[70][70];\nvector<pair<int,int>> roads;\nint seg_id[70][70][2];\nint num_segs;\n\nvoid find_segments() {\n    memset(seg_id, -1, sizeof(seg_id));\n    num_segs = 0;\n    for (int i = 0; i < N; i++) {\n        int j = 0;\n        while (j < N) {\n            if (grid[i][j] == '#') { j++; continue; }\n            int start = j;\n            while (j < N && grid[i][j] != '#') j++;\n            for (int k = start; k < j; k++) seg_id[i][k][0] = num_segs++;\n        }\n    }\n    for (int j = 0; j < N; j++) {\n        int i = 0;\n        while (i < N) {\n            if (grid[i][j] == '#') { i++; continue; }\n            int start = i;\n            while (i < N && grid[i][j] != '#') i++;\n            for (int k = start; k < i; k++) seg_id[k][j][1] = num_segs++;\n        }\n    }\n}\n\nvector<int> dist_arr, prev_arr;\nvoid dijkstra(int sx, int sy) {\n    int V = N * N;\n    dist_arr.assign(V, INT_MAX);\n    prev_arr.assign(V, -1);\n    dist_arr[sx * N + sy] = 0;\n    priority_queue<pair<int,int>, vector<pair<int,int>>, greater<>> pq;\n    pq.push({0, sx * N + sy});\n    const int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, -1, 1};\n    while (!pq.empty()) {\n        auto [d, u] = pq.top(); pq.pop();\n        if (d > dist_arr[u]) continue;\n        int x = u / N, y = u % N;\n        for (int k = 0; k < 4; k++) {\n            int nx = x + dx[k], ny = y + dy[k];\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N || grid[nx][ny] == '#') continue;\n            int v = nx * N + ny, nd = d + cost[nx][ny];\n            if (nd < dist_arr[v]) { dist_arr[v] = nd; prev_arr[v] = u; pq.push({nd, v}); }\n        }\n    }\n}\n\nstring get_path(int sx, int sy, int ex, int ey) {\n    if (sx == ex && sy == ey) return \"\";\n    vector<int> trace;\n    for (int u = ex * N + ey; u != sx * N + sy && u != -1; u = prev_arr[u]) trace.push_back(u);\n    reverse(trace.begin(), trace.end());\n    string path;\n    int cur = sx * N + sy;\n    for (int next : trace) {\n        int cx = cur/N, cy = cur%N, nx = next/N, ny = next%N;\n        path += (nx==cx-1) ? 'U' : (nx==cx+1) ? 'D' : (ny==cy-1) ? 'L' : 'R';\n        cur = next;\n    }\n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    auto total_start = steady_clock::now();\n    \n    cin >> N >> si >> sj;\n    grid.resize(N);\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] != '#') { cost[i][j] = grid[i][j] - '0'; roads.push_back({i, j}); }\n    }\n    find_segments();\n    \n    vector<bool> covered(num_segs, false);\n    covered[seg_id[si][sj][0]] = covered[seg_id[si][sj][1]] = true;\n    vector<pair<int,int>> selected = {{si, sj}};\n    while (true) {\n        int best_count = 0, best_dist = INT_MAX;\n        pair<int,int> best_cell = {-1, -1};\n        for (auto& [i, j] : roads) {\n            int count = (seg_id[i][j][0]!=-1 && !covered[seg_id[i][j][0]]) + (seg_id[i][j][1]!=-1 && !covered[seg_id[i][j][1]]);\n            if (count > best_count) { best_count = count; best_dist = INT_MAX; best_cell = {i, j}; }\n            if (count == best_count && count > 0) {\n                int min_d = abs(i-si) + abs(j-sj);\n                for (auto& [r, c] : selected) min_d = min(min_d, abs(i-r) + abs(j-c));\n                if (min_d < best_dist) { best_dist = min_d; best_cell = {i, j}; }\n            }\n        }\n        if (best_count == 0) break;\n        selected.push_back(best_cell);\n        covered[seg_id[best_cell.first][best_cell.second][0]] = covered[seg_id[best_cell.first][best_cell.second][1]] = true;\n    }\n    \n    int orig_m = selected.size();\n    vector<int> seg_count(num_segs, 0);\n    for (int i = 0; i < orig_m; i++) {\n        int s0 = seg_id[selected[i].first][selected[i].second][0];\n        int s1 = seg_id[selected[i].first][selected[i].second][1];\n        if (s0 != -1) seg_count[s0]++;\n        if (s1 != -1) seg_count[s1]++;\n    }\n    vector<pair<int,int>> pruned;\n    for (int i = 0; i < orig_m; i++) {\n        int s0 = seg_id[selected[i].first][selected[i].second][0];\n        int s1 = seg_id[selected[i].first][selected[i].second][1];\n        bool can_remove = (i > 0);\n        if (s0 != -1 && seg_count[s0] <= 1) can_remove = false;\n        if (s1 != -1 && seg_count[s1] <= 1) can_remove = false;\n        if (!can_remove) pruned.push_back(selected[i]);\n        else { if (s0 != -1) seg_count[s0]--; if (s1 != -1) seg_count[s1]--; }\n    }\n    \n    int m = pruned.size();\n    if (m <= 1) { cout << \"\" << endl; return 0; }\n    \n    vector<vector<int>> dist(m, vector<int>(m));\n    for (int i = 0; i < m; i++) {\n        dijkstra(pruned[i].first, pruned[i].second);\n        for (int j = 0; j < m; j++) dist[i][j] = dist_arr[pruned[j].first * N + pruned[j].second];\n    }\n    \n    vector<int> tour(m);\n    iota(tour.begin(), tour.end(), 0);\n    { vector<bool> vis(m, false); vis[0] = true; int cur = 0;\n      for (int iter = 1; iter < m; iter++) {\n          int best = -1, best_d = INT_MAX;\n          for (int i = 0; i < m; i++) if (!vis[i] && dist[cur][i] < best_d) { best_d = dist[cur][i]; best = i; }\n          vis[best] = true; tour[iter] = best; cur = best;\n      }\n    }\n    \n    auto time_ok = [&]() { return duration_cast<duration<double>>(steady_clock::now() - total_start).count() < 2.5; };\n    \n    bool improved = true;\n    while (improved && time_ok()) {\n        improved = false;\n        for (int i = 0; i < m - 1 && !improved; i++)\n            for (int j = i + 2; j < m && !improved; j++) {\n                if (i == 0 && j == m - 1) continue;\n                int saving = dist[tour[i]][tour[i+1]] + dist[tour[j]][tour[(j+1)%m]] - dist[tour[i]][tour[j]] - dist[tour[i+1]][tour[(j+1)%m]];\n                if (saving > 0) { reverse(tour.begin() + i + 1, tour.begin() + j + 1); improved = true; }\n            }\n        if (improved) continue;\n        if (m > 2) for (int i = 0; i < m && !improved; i++) {\n            int node = tour[i], prev_i = (i - 1 + m) % m, next_i = (i + 1) % m;\n            int remove_saving = dist[tour[prev_i]][node] + dist[node][tour[next_i]] - dist[tour[prev_i]][tour[next_i]];\n            vector<int> base; for (int k = 0; k < m; k++) if (k != i) base.push_back(tour[k]);\n            int orig_pos = (prev_i < i) ? prev_i : prev_i - 1;\n            for (int pos = 0; pos < m - 1 && !improved; pos++) {\n                if (pos == orig_pos) continue;\n                int insert_cost = dist[base[pos]][node] + dist[node][base[(pos+1)%(m-1)]] - dist[base[pos]][base[(pos+1)%(m-1)]];\n                if (insert_cost < remove_saving) { base.insert(base.begin() + pos + 1, node); tour = base; improved = true; }\n            }\n        }\n    }\n    \n    string result; int cx = si, cy = sj;\n    for (int i = 1; i < m; i++) { dijkstra(cx, cy); result += get_path(cx, cy, pruned[tour[i]].first, pruned[tour[i]].second); cx = pruned[tour[i]].first; cy = pruned[tour[i]].second; }\n    if (cx != si || cy != sj) { dijkstra(cx, cy); result += get_path(cx, cy, si, sj); }\n    cout << result << endl;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K, R;\n    cin >> N >> M >> K >> R;\n    \n    vector<vector<int>> d(N, vector<int>(K));\n    for (int i = 0; i < N; i++)\n        for (int k = 0; k < K; k++) cin >> d[i][k];\n    \n    vector<vector<int>> deps(N), rdeps(N);\n    for (int i = 0; i < R; i++) {\n        int u, v; cin >> u >> v; u--; v--;\n        deps[v].push_back(u); rdeps[u].push_back(v);\n    }\n    \n    vector<int> topo;\n    { vector<int> indeg(N,0);\n      for(int v=0;v<N;v++) for(int u:deps[v]) indeg[v]++;\n      queue<int> q;\n      for(int i=0;i<N;i++) if(indeg[i]==0) q.push(i);\n      while(!q.empty()) { int u=q.front(); q.pop(); topo.push_back(u);\n        for(int v:rdeps[u]) if(--indeg[v]==0) q.push(v); } }\n    \n    vector<int> crit(N, 1);\n    for(int u:topo) for(int v:rdeps[u]) crit[u]=max(crit[u], 1+crit[v]);\n    \n    vector<vector<int>> proven(M, vector<int>(K, 0));\n    vector<vector<int>> est(M, vector<int>(K, 0));\n    vector<int> tstatus(N, -1), mtask(M, -1), tstart(N, -1), tcount(M, 0);\n    \n    auto can_start = [&](int t) {\n        if(tstatus[t] != -1) return false;\n        for(int dep: deps[t]) if(tstatus[dep] != 1) return false;\n        return true;\n    };\n    \n    auto est_w = [&](int t, int m) {\n        int w = 0;\n        for(int k = 0; k < K; k++) w += max(0, d[t][k] - est[m][k]);\n        return w;\n    };\n    \n    auto can_1day = [&](int t, int m) {\n        for(int k = 0; k < K; k++) if(d[t][k] > proven[m][k]) return false;\n        return true;\n    };\n    \n    for(int day = 1; day <= 2000; day++) {\n        vector<int> avail;\n        for(int i = 0; i < N; i++) if(can_start(i)) avail.push_back(i);\n        sort(avail.begin(), avail.end(), [&](int a, int b) { return crit[a] > crit[b]; });\n        \n        vector<int> freem;\n        for(int j = 0; j < M; j++) if(mtask[j] == -1) freem.push_back(j);\n        \n        vector<pair<int,int>> assign;\n        vector<bool> tused(N, false), mused(M, false);\n        \n        for(int t: avail) {\n            if(tused[t]) continue;\n            for(int m: freem) {\n                if(mused[m]) continue;\n                if(can_1day(t, m)) {\n                    assign.push_back({m, t});\n                    tused[t] = mused[m] = true;\n                    mtask[m] = t; tstatus[t] = 0; tstart[t] = day; tcount[m]++;\n                    break;\n                }\n            }\n        }\n        \n        for(int t: avail) {\n            if(tused[t]) continue;\n            int best = -1; long long best_score = LLONG_MAX;\n            for(int m: freem) {\n                if(mused[m]) continue;\n                int w = est_w(t, m);\n                long long score = (long long)w * 10000 + tcount[m];\n                if(score < best_score) { best_score = score; best = m; }\n            }\n            if(best != -1) {\n                assign.push_back({best, t});\n                tused[t] = mused[best] = true;\n                mtask[best] = t; tstatus[t] = 0; tstart[t] = day; tcount[best]++;\n            }\n        }\n        \n        cout << assign.size();\n        for(auto [m,t]: assign) cout << \" \" << m+1 << \" \" << t+1;\n        cout << \"\\n\"; cout.flush();\n        \n        int n; cin >> n;\n        if(n == -1) break;\n        \n        for(int i = 0; i < n; i++) {\n            int m; cin >> m; m--;\n            int t = mtask[m], actual = day - tstart[t] + 1;\n            tstatus[t] = 1; mtask[m] = -1;\n            \n            if(actual == 1) {\n                for(int k = 0; k < K; k++)\n                    proven[m][k] = est[m][k] = max(proven[m][k], max(est[m][k], d[t][k]));\n            } else {\n                int pred_w = est_w(t, m);\n                int w_lo = max(1, actual - 3);\n                int w_hi = actual + 3;\n                \n                if(pred_w < w_lo || pred_w > w_hi) {\n                    int target_w;\n                    if(pred_w < w_lo) target_w = (4 * pred_w + 6 * w_lo + 5) / 10;\n                    else target_w = (4 * pred_w + 6 * w_hi + 5) / 10;\n                    \n                    int diff = target_w - pred_w;\n                    \n                    vector<int> weight(K);\n                    int total_weight = 0;\n                    for(int k = 0; k < K; k++) {\n                        int gap = max(0, d[t][k] - est[m][k]);\n                        weight[k] = max(1, d[t][k] + gap);\n                        total_weight += weight[k];\n                    }\n                    \n                    for(int k = 0; k < K; k++) {\n                        int adj = (diff * weight[k] + total_weight/2) / total_weight;\n                        est[m][k] = max(proven[m][k], est[m][k] - adj);\n                    }\n                }\n            }\n        }\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    vector<array<int, 4>> orders(1000);\n    for (int i = 0; i < 1000; i++)\n        cin >> orders[i][0] >> orders[i][1] >> orders[i][2] >> orders[i][3];\n    \n    vector<pair<double, int>> scored(1000);\n    for (int i = 0; i < 1000; i++) {\n        int a = orders[i][0], b = orders[i][1], c = orders[i][2], d = orders[i][3];\n        scored[i] = {(abs(400-(a+c)/2.0) + abs(400-(b+d)/2.0)) * 2.0 + (abs(a-c)+abs(b-d)) * 0.5, i};\n    }\n    sort(scored.begin(), scored.end());\n    \n    vector<int> selected(50);\n    for (int i = 0; i < 50; i++) selected[i] = scored[i].second;\n    \n    int cx[50][2], cy[50][2];\n    for (int i = 0; i < 50; i++) {\n        cx[i][0] = orders[selected[i]][0]; cy[i][0] = orders[selected[i]][1];\n        cx[i][1] = orders[selected[i]][2]; cy[i][1] = orders[selected[i]][3];\n    }\n    \n    auto build_route = [&](vector<int>& ord) {\n        vector<pair<int, bool>> route;\n        for (int t = 0; t < 50; t++) {\n            int idx = ord[t], n = route.size();\n            int a = cx[idx][0], b = cy[idx][0], c = cx[idx][1], d = cy[idx][1];\n            int best_cost = INT_MAX, best_pick = -1, best_del = -1;\n            for (int p = 0; p <= n; p++) for (int q = p; q <= n; q++) {\n                int cost = 0, px = 400, py = 400;\n                for (int i = 0; i < p; i++) { int nx = cx[route[i].first][route[i].second], ny = cy[route[i].first][route[i].second]; cost += abs(px-nx)+abs(py-ny); px = nx; py = ny; }\n                cost += abs(px-a)+abs(py-b); px = a; py = b;\n                for (int i = p; i < q; i++) { int nx = cx[route[i].first][route[i].second], ny = cy[route[i].first][route[i].second]; cost += abs(px-nx)+abs(py-ny); px = nx; py = ny; }\n                cost += abs(px-c)+abs(py-d); px = c; py = d;\n                for (int i = q; i < n; i++) { int nx = cx[route[i].first][route[i].second], ny = cy[route[i].first][route[i].second]; cost += abs(px-nx)+abs(py-ny); px = nx; py = ny; }\n                cost += abs(px-400)+abs(py-400);\n                if (cost < best_cost) { best_cost = cost; best_pick = p; best_del = q; }\n            }\n            route.insert(route.begin() + best_del, {idx, true});\n            route.insert(route.begin() + best_pick, {idx, false});\n        }\n        return route;\n    };\n    \n    auto find_pos = [](vector<pair<int, bool>>& r) {\n        vector<int> pu(50), de(50);\n        for (int i = 0; i < (int)r.size(); i++) r[i].second ? de[r[i].first] = i : pu[r[i].first] = i;\n        return make_pair(pu, de);\n    };\n    \n    vector<int> ord(50); iota(ord.begin(), ord.end(), 0);\n    vector<pair<int, bool>> best_route; int best_cost = INT_MAX;\n    \n    for (int trial = 0; trial < 50; trial++) {\n        if (trial > 0) shuffle(ord.begin(), ord.end(), rng);\n        auto route = build_route(ord);\n        int cost = 0, px = 400, py = 400;\n        for (auto& [i, d] : route) { int nx = cx[i][d], ny = cy[i][d]; cost += abs(px-nx)+abs(py-ny); px = nx; py = ny; }\n        cost += abs(px-400)+abs(py-400);\n        if (cost < best_cost) { best_cost = cost; best_route = route; }\n    }\n    \n    auto [pu_pos, de_pos] = find_pos(best_route);\n    for (int iter = 0; iter < 500; iter++) {\n        bool imp = false;\n        for (int i = 0; i < (int)best_route.size() && !imp; i++) {\n            int idx = best_route[i].first; bool is_d = best_route[i].second;\n            int n = best_route.size();\n            int ex = cx[idx][is_d], ey = cy[idx][is_d];\n            int pvx = 400, pvy = 400, nx = 400, ny = 400;\n            if (i > 0) { pvx = cx[best_route[i-1].first][best_route[i-1].second]; pvy = cy[best_route[i-1].first][best_route[i-1].second]; }\n            if (i < n-1) { nx = cx[best_route[i+1].first][best_route[i+1].second]; ny = cy[best_route[i+1].first][best_route[i+1].second]; }\n            int base = -(abs(pvx-ex)+abs(pvy-ey))-(abs(ex-nx)+abs(ey-ny))+(abs(pvx-nx)+abs(pvy-ny));\n            for (int j = 0; j <= n-1 && !imp; j++) {\n                if (j == i) continue;\n                if (is_d) { if (j <= pu_pos[idx]) continue; }\n                else { int mj = de_pos[idx]-(de_pos[idx]>i?1:0); if (j > mj) continue; }\n                int ipx, ipy, inx, iny;\n                if (j == 0) { ipx = 400; ipy = 400; } else { int o = j < i ? j-1 : j; ipx = cx[best_route[o].first][best_route[o].second]; ipy = cy[best_route[o].first][best_route[o].second]; }\n                if (j == n-1) { inx = 400; iny = 400; } else { int o = j < i ? j : j+1; inx = cx[best_route[o].first][best_route[o].second]; iny = cy[best_route[o].first][best_route[o].second]; }\n                int delta = base-(abs(ipx-inx)+abs(ipy-iny))+(abs(ipx-ex)+abs(ipy-ey))+(abs(ex-inx)+abs(ey-iny));\n                if (delta < 0) { auto e = best_route[i]; best_route.erase(best_route.begin()+i); best_route.insert(best_route.begin()+j,e); best_cost += delta; auto [p,d] = find_pos(best_route); pu_pos=p; de_pos=d; imp=true; }\n            }\n        }\n        if (!imp) break;\n    }\n    \n    for (int iter = 0; iter < 100; iter++) {\n        bool imp = false; int n = best_route.size();\n        for (int i = 0; i < n-1 && !imp; i++) {\n            for (int j = i+1; j < n && !imp; j++) {\n                int idx_i = best_route[i].first, idx_j = best_route[j].first;\n                if (idx_i == idx_j) continue;\n                int np_i = best_route[i].second ? pu_pos[idx_i] : -1, nd_i = best_route[i].second ? j : de_pos[idx_i];\n                int np_j = best_route[j].second ? pu_pos[idx_j] : i, nd_j = best_route[j].second ? -1 : de_pos[idx_j];\n                if (best_route[i].second) { if (j <= pu_pos[idx_i]) continue; nd_i = j; np_i = pu_pos[idx_i]; }\n                else { nd_i = de_pos[idx_i]-(de_pos[idx_i]>j?1:0); np_i = j; if (np_i >= nd_i) continue; }\n                if (best_route[j].second) { if (i <= pu_pos[idx_j]) continue; nd_j = i; np_j = pu_pos[idx_j]; }\n                else { nd_j = de_pos[idx_j]-(de_pos[idx_j]>i?1:0); np_j = i; if (np_j >= nd_j) continue; }\n                int pv_i = i>0 ? cx[best_route[i-1].first][best_route[i-1].second] : 400, py_i = i>0 ? cy[best_route[i-1].first][best_route[i-1].second] : 400;\n                int nx_i = i<n-1 ? cx[best_route[i+1].first][best_route[i+1].second] : 400, ny_i = i<n-1 ? cy[best_route[i+1].first][best_route[i+1].second] : 400;\n                int pv_j = j>0 ? cx[best_route[j-1].first][best_route[j-1].second] : 400, py_j = j>0 ? cy[best_route[j-1].first][best_route[j-1].second] : 400;\n                int nx_j = j<n-1 ? cx[best_route[j+1].first][best_route[j+1].second] : 400, ny_j = j<n-1 ? cy[best_route[j+1].first][best_route[j+1].second] : 400;\n                int ei = cx[idx_i][best_route[i].second], fi = cy[idx_i][best_route[i].second];\n                int ej = cx[idx_j][best_route[j].second], fj = cy[idx_j][best_route[j].second];\n                int old_c, new_c;\n                if (j == i+1) { old_c = abs(pv_i-ei)+abs(py_i-fi)+abs(ei-ej)+abs(fi-fj)+abs(ej-nx_j)+abs(fj-ny_j); new_c = abs(pv_i-ej)+abs(py_i-fj)+abs(ej-ei)+abs(fj-fi)+abs(ei-nx_j)+abs(fi-ny_j); }\n                else { old_c = abs(pv_i-ei)+abs(py_i-fi)+abs(ei-nx_i)+abs(fi-ny_i)+abs(pv_j-ej)+abs(py_j-fj)+abs(ej-nx_j)+abs(fj-ny_j); new_c = abs(pv_i-ej)+abs(py_i-fj)+abs(ej-nx_i)+abs(fj-ny_i)+abs(pv_j-ei)+abs(py_j-fi)+abs(ei-nx_j)+abs(fi-ny_j); }\n                if (new_c < old_c) { swap(best_route[i],best_route[j]); best_cost += new_c-old_c; auto [p,d] = find_pos(best_route); pu_pos=p; de_pos=d; imp=true; }\n            }\n        }\n        if (!imp) break;\n    }\n    \n    cout << 50; for (int i = 0; i < 50; i++) cout << \" \" << selected[i]+1; cout << \"\\n\";\n    cout << best_route.size()+2 << \" 400 400\";\n    for (auto& [i,d] : best_route) cout << \" \" << cx[i][d] << \" \" << cy[i][d];\n    cout << \" 400 400\\n\";\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n\nusing namespace std;\n\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 x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n    bool merge(int x, int y) {\n        x = find(x); y = find(y);\n        if (x == y) return false;\n        if (rank_[x] < rank_[y]) swap(x, y);\n        parent[y] = x;\n        if (rank_[x] == rank_[y]) rank_[x]++;\n        return true;\n    }\n};\n\nint main() {\n    // Fast I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N = 400, M = 1995;\n    vector<double> x(N), y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> x[i] >> y[i];\n    }\n\n    vector<int> u(M), v(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> u[i] >> v[i];\n    }\n\n    DSU dsu(N);\n    int accepted = 0;\n    \n    // Static threshold optimized for high score vs low failure probability\n    double T = 2.8;\n    // Safety buffer fallback to guarantee connectivity against statistical anomalies\n    int K = 500;\n\n    for (int i = 0; i < M; ++i) {\n        int l;\n        cin >> l;\n        \n        int r1 = dsu.find(u[i]);\n        int r2 = dsu.find(v[i]);\n        \n        // If already connected, reject\n        if (r1 == r2) {\n            cout << \"0\\n\" << flush;\n            continue;\n        }\n\n        int remaining = M - i - 1;\n        int needed = (N - 1) - accepted;\n        \n        bool accept = false;\n        \n        // SAFETY FALLBACK: If we are running out of edges, accept any connection\n        if (remaining <= needed + K) {\n            accept = true;\n        } else {\n            // Calculate base distance d_i\n            double dx = x[u[i]] - x[v[i]];\n            double dy = y[u[i]] - y[v[i]];\n            int d = std::round(std::sqrt(dx * dx + dy * dy));\n            \n            // Apply static threshold\n            if (l <= T * d) {\n                accept = true;\n            }\n        }\n\n        if (accept) {\n            cout << \"1\\n\" << flush;\n            dsu.merge(r1, r2);\n            accepted++;\n        } else {\n            cout << \"0\\n\" << flush;\n        }\n    }\n\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 30, W = 30;\nint N, M;\nint px[25], py[25], pt[25];\nint hx[15], hy[15];\nbool wall[H][W];\nint pet_dist[25][H][W];\nint human_dist[15][H][W];\n\nint dx[] = {-1, 1, 0, 0};\nint dy[] = {0, 0, -1, 1};\nchar dir_char[] = \"UDLR\";\nchar wall_char[] = \"udlr\";\n\nbool in_bounds(int x, int y) { return 0 <= x && x < H && 0 <= y < W; }\n\nbool has_pet_at(int x, int y) {\n    for (int i = 0; i < N; i++) if (px[i] == x && py[i] == y) return true;\n    return false;\n}\n\nbool has_human_at(int x, int y) {\n    for (int i = 0; i < M; i++) if (hx[i] == x && hy[i] == y) return true;\n    return false;\n}\n\nbool pet_adjacent(int x, int y) {\n    for (int d = 0; d < 4; d++) if (has_pet_at(x + dx[d], y + dy[d])) return true;\n    return false;\n}\n\nbool can_place_wall(int x, int y) {\n    if (!in_bounds(x, y) || wall[x][y]) return false;\n    if (has_pet_at(x, y) || has_human_at(x, y)) return false;\n    if (pet_adjacent(x, y)) return false;\n    return true;\n}\n\nvoid compute_distances() {\n    for (int p = 0; p < N; p++) {\n        queue<pair<int,int>> q;\n        memset(pet_dist[p], -1, sizeof(pet_dist[p]));\n        q.push({px[p], py[p]});\n        pet_dist[p][px[p]][py[p]] = 0;\n        while (!q.empty()) {\n            auto [x, y] = q.front(); q.pop();\n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (in_bounds(nx, ny) && !wall[nx][ny] && pet_dist[p][nx][ny] == -1) {\n                    pet_dist[p][nx][ny] = pet_dist[p][x][y] + 1;\n                    q.push({nx, ny});\n                }\n            }\n        }\n    }\n    for (int h = 0; h < M; h++) {\n        queue<pair<int,int>> q;\n        memset(human_dist[h], -1, sizeof(human_dist[h]));\n        q.push({hx[h], hy[h]});\n        human_dist[h][hx[h]][hy[h]] = 0;\n        while (!q.empty()) {\n            auto [x, y] = q.front(); q.pop();\n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (in_bounds(nx, ny) && !wall[nx][ny] && human_dist[h][nx][ny] == -1) {\n                    human_dist[h][nx][ny] = human_dist[h][x][y] + 1;\n                    q.push({nx, ny});\n                }\n            }\n        }\n    }\n}\n\nint wall_value(int wx, int wy, int hi) {\n    int val = 0;\n    for (int p = 0; p < N; p++) {\n        int weight = (pt[p] == 4) ? 20 : (pt[p] == 3) ? 3 : (pt[p] == 5) ? 2 : 1;\n        int dph = pet_dist[p][hx[hi]][hy[hi]];\n        if (dph < 0) continue;\n        int dpw = pet_dist[p][wx][wy];\n        if (dpw <= 0) continue;\n        int dwh = human_dist[hi][wx][wy];\n        if (dwh <= 0) continue;\n        if (dpw + dwh == dph) {\n            val += 100 * weight;\n            if (dpw < 6) val += (7 - dpw) * 10 * weight;\n        }\n        if (dpw < 10) val += (11 - dpw) * weight;\n    }\n    return val;\n}\n\nstring pet_moves[25];\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++) { cin >> px[i] >> py[i] >> pt[i]; px[i]--; py[i]--; }\n    cin >> M;\n    for (int i = 0; i < M; i++) { cin >> hx[i] >> hy[i]; hx[i]--; hy[i]--; }\n    \n    memset(wall, false, sizeof(wall));\n    \n    for (int turn = 0; turn < 300; turn++) {\n        compute_distances();\n        \n        int closest_dog_dist[15], closest_dog_toward[15];\n        for (int i = 0; i < M; i++) {\n            closest_dog_dist[i] = 1000;\n            closest_dog_toward[i] = -1;\n            for (int p = 0; p < N; p++) {\n                if (pt[p] == 4) {\n                    int d = pet_dist[p][hx[i]][hy[i]];\n                    if (d >= 0 && d < closest_dog_dist[i]) {\n                        closest_dog_dist[i] = d;\n                        for (int dd = 0; dd < 4; dd++) {\n                            int nx = hx[i] + dx[dd], ny = hy[i] + dy[dd];\n                            if (in_bounds(nx, ny) && pet_dist[p][nx][ny] == d - 1) {\n                                closest_dog_toward[i] = dd;\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        bool panic[15];\n        for (int i = 0; i < M; i++) panic[i] = (closest_dog_dist[i] <= 2);\n        \n        vector<tuple<int, int, int>> wall_candidates;\n        for (int i = 0; i < M; i++) {\n            if (panic[i]) continue;\n            for (int d = 0; d < 4; d++) {\n                int wx = hx[i] + dx[d], wy = hy[i] + dy[d];\n                if (can_place_wall(wx, wy)) {\n                    int val = wall_value(wx, wy, i);\n                    if (val > 10) wall_candidates.push_back({val, i, d});\n                }\n            }\n        }\n        sort(wall_candidates.rbegin(), wall_candidates.rend());\n        \n        set<int> assigned;\n        set<pair<int,int>> wall_positions;\n        vector<pair<int,int>> planned_walls(M, {-1, -1});\n        \n        for (auto& [val, hi, d] : wall_candidates) {\n            if (assigned.count(hi)) continue;\n            int wx = hx[hi] + dx[d], wy = hy[hi] + dy[d];\n            if (wall_positions.count({wx, wy})) continue;\n            assigned.insert(hi);\n            wall_positions.insert({wx, wy});\n            planned_walls[hi] = {wx, wy};\n        }\n        \n        string actions(M, '.');\n        for (int i = 0; i < M; i++) {\n            if (panic[i]) {\n                int away_dir = -1;\n                double best_score = -1000;\n                for (int d = 0; d < 4; d++) {\n                    int nx = hx[i]+dx[d], ny = hy[i]+dy[d];\n                    if (!in_bounds(nx,ny) || wall[nx][ny] || wall_positions.count({nx,ny})) continue;\n                    double score = 0;\n                    if (closest_dog_toward[i] >= 0) {\n                        if (d == (closest_dog_toward[i] ^ 1)) score += 10;\n                        else if (d == closest_dog_toward[i]) score -= 10;\n                        else score += 3;\n                    }\n                    for (int p = 0; p < N; p++) {\n                        double dist = max(1.0, (double)(abs(nx-px[p]) + abs(ny-py[p])));\n                        score += (nx - px[p]) / (dist * dist) + (ny - py[p]) / (dist * dist);\n                    }\n                    if (pet_adjacent(nx, ny)) score -= 5;\n                    if (score > best_score) { best_score = score; away_dir = d; }\n                }\n                if (away_dir >= 0) actions[i] = dir_char[away_dir];\n            } else if (planned_walls[i].first != -1) {\n                for (int d = 0; d < 4; d++) {\n                    if (planned_walls[i] == make_pair(hx[i]+dx[d], hy[i]+dy[d])) {\n                        actions[i] = wall_char[d]; break;\n                    }\n                }\n            } else {\n                double gx = 0, gy = 0;\n                for (int p = 0; p < N; p++) {\n                    double w = (pt[p] == 4) ? 3.0 : 1.0;\n                    double dist = max(1.0, (double)(abs(hx[i]-px[p]) + abs(hy[i]-py[p])));\n                    gx += w * (hx[i] - px[p]) / (dist * dist);\n                    gy += w * (hy[i] - py[p]) / (dist * dist);\n                }\n                int bm = -1, bm_safe = -1; \n                double bd = 0.01, bd_safe = 0.01;\n                for (int d = 0; d < 4; d++) {\n                    int nx = hx[i]+dx[d], ny = hy[i]+dy[d];\n                    if (!in_bounds(nx,ny) || wall[nx][ny] || wall_positions.count({nx,ny})) continue;\n                    double dot = dx[d]*gx + dy[d]*gy;\n                    if (dot > bd) { bd = dot; bm = d; }\n                    if (!pet_adjacent(nx, ny) && dot > bd_safe) { bd_safe = dot; bm_safe = d; }\n                }\n                if (bm_safe != -1) bm = bm_safe;\n                if (bm != -1) actions[i] = dir_char[bm];\n            }\n        }\n        \n        cout << actions << endl;\n        for (int i = 0; i < N; i++) cin >> pet_moves[i];\n        \n        for (int i = 0; i < M; i++) {\n            if (actions[i] != '.' && islower(actions[i])) {\n                for (int d = 0; d < 4; d++) if (actions[i] == wall_char[d]) {\n                    int nx=hx[i]+dx[d], ny=hy[i]+dy[d];\n                    if (in_bounds(nx,ny)) wall[nx][ny] = true;\n                }\n            }\n        }\n        for (int i = 0; i < M; i++) {\n            if (actions[i] != '.' && isupper(actions[i])) {\n                for (int d = 0; d < 4; d++) if (actions[i] == dir_char[d]) {\n                    int nx=hx[i]+dx[d], ny=hy[i]+dy[d];\n                    if (in_bounds(nx,ny) && !wall[nx][ny]) { hx[i]=nx; hy[i]=ny; }\n                    break;\n                }\n            }\n        }\n        for (int i = 0; i < N; i++) {\n            for (char c : pet_moves[i]) for (int d = 0; d < 4; d++) if (c == dir_char[d]) {\n                px[i]+=dx[d]; py[i]+=dy[d]; break;\n            }\n        }\n    }\n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cstring>\n#include <algorithm>\n#include <queue>\n\nusing namespace std;\n\nint si, sj, ti, tj;\ndouble p;\nchar h[20][19];\nchar v[19][20];\n\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\nchar dirs[] = {'U', 'D', 'L', 'R'};\n\nint dist[20][20];\nbool can[20][20][4];\ndouble move_prob_table[20][20][4];\ndouble stay_prob_table[20][20][4];\ndouble remaining_sq[201][41];\ndouble reach_score_table[201];\n\nvoid compute_distances() {\n    memset(dist, -1, sizeof(dist));\n    dist[ti][tj] = 0;\n    queue<pair<int, int>> q;\n    q.push({ti, tj});\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int dir = 0; dir < 4; ++dir) {\n            if (can[i][j][dir]) {\n                int ni = i + dr[dir], nj = j + dc[dir];\n                if (dist[ni][nj] == -1) {\n                    dist[ni][nj] = dist[i][j] + 1;\n                    q.push({ni, nj});\n                }\n            }\n        }\n    }\n}\n\nstruct Node {\n    vector<char> seq;\n    double exact_score;\n    double dp[400]; // Flattened 20x20 grid for fast copy\n    double value;\n};\n\nint main() {\n    // Fast I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    if (!(cin >> si >> sj >> ti >> tj >> p)) return 0;\n    \n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 19; ++j) {\n            cin >> h[i][j];\n        }\n    }\n    for (int i = 0; i < 19; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            cin >> v[i][j];\n        }\n    }\n    \n    // Precompute transition dynamics\n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            for (int dir = 0; dir < 4; ++dir) {\n                if (dir == 0) can[i][j][dir] = i > 0 && v[i-1][j] == '0';\n                else if (dir == 1) can[i][j][dir] = i < 19 && v[i][j] == '0';\n                else if (dir == 2) can[i][j][dir] = j > 0 && h[i][j-1] == '0';\n                else can[i][j][dir] = j < 19 && h[i][j] == '0';\n                \n                bool wall = !can[i][j][dir];\n                move_prob_table[i][j][dir] = (1.0 - p) * (1.0 - wall);\n                stay_prob_table[i][j][dir] = 1.0 - move_prob_table[i][j][dir];\n            }\n        }\n    }\n    \n    compute_distances();\n    \n    // Precompute scores and heuristic components\n    for (int t = 1; t <= 200; ++t) {\n        reach_score_table[t] = 401.0 - t;\n        for (int d = 0; d <= 40; ++d) {\n            int rem = 400 - t - d;\n            remaining_sq[t][d] = rem > 0 ? (double)rem * rem : 0.0;\n        }\n    }\n    \n    int L = 200;\n    int W = 100; // Beam width\n    \n    vector<Node> beam;\n    beam.resize(1);\n    beam[0].seq.clear();\n    beam[0].exact_score = 0.0;\n    memset(beam[0].dp, 0, sizeof(beam[0].dp));\n    beam[0].dp[si * 20 + sj] = 1.0;\n    beam[0].value = 0.0;\n    \n    vector<Node> next_beam_candidates;\n    next_beam_candidates.reserve(W * 4);\n    \n    for (int t = 1; t <= L; ++t) {\n        next_beam_candidates.clear();\n        \n        for (auto& node : beam) {\n            for (int dir = 0; dir < 4; ++dir) {\n                Node new_node;\n                new_node.seq = node.seq;\n                new_node.seq.push_back(dirs[dir]);\n                new_node.exact_score = node.exact_score;\n                memset(new_node.dp, 0, sizeof(new_node.dp));\n                \n                double reach_prob = 0.0;\n                double heuristic = 0.0;\n                \n                // Fast inner loop over distribution\n                for (int i = 0; i < 20; ++i) {\n                    for (int j = 0; j < 20; ++j) {\n                        double prob = node.dp[i * 20 + j];\n                        if (prob < 1e-15) continue;\n                        \n                        double move_prob = move_prob_table[i][j][dir];\n                        double stay_prob = stay_prob_table[i][j][dir];\n                        \n                        if (move_prob > 1e-15) {\n                            int ni = i + dr[dir], nj = j + dc[dir];\n                            if (ni == ti && nj == tj) {\n                                reach_prob += prob * move_prob;\n                            } else {\n                                new_node.dp[ni * 20 + nj] += prob * move_prob;\n                            }\n                        }\n                        \n                        if (stay_prob > 1e-15) {\n                            new_node.dp[i * 20 + j] += prob * stay_prob;\n                        }\n                    }\n                }\n                \n                // Exact lower bound score for reaching target\n                new_node.exact_score += reach_prob * reach_score_table[t];\n                \n                // Squared distance heuristic to aggressively pull mass towards target\n                for (int i = 0; i < 20; ++i) {\n                    for (int j = 0; j < 20; ++j) {\n                        if (i == ti && j == tj) continue;\n                        double prob = new_node.dp[i * 20 + j];\n                        if (prob < 1e-15) continue;\n                        heuristic += prob * remaining_sq[t][dist[i][j]];\n                    }\n                }\n                \n                // Balanced scaling between exact achievement and future potential\n                new_node.value = new_node.exact_score * 400.0 + heuristic;\n                next_beam_candidates.push_back(new_node);\n            }\n        }\n        \n        // Keep top W candidates\n        sort(next_beam_candidates.begin(), next_beam_candidates.end(), [](const Node& a, const Node& b) {\n            return a.value > b.value;\n        });\n        \n        int new_W = min(W, (int)next_beam_candidates.size());\n        beam.assign(next_beam_candidates.begin(), next_beam_candidates.begin() + new_W);\n    }\n    \n    cout << string(beam[0].seq.begin(), beam[0].seq.end()) << \"\\n\";\n    \n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <string>\n#include <set>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <ctime>\n\nusing namespace std;\n\nint to_table[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1},\n};\n\nint di[4] = {0, -1, 0, 1};\nint dj[4] = {-1, 0, 1, 0};\n\nint valid_out[8][4];\n\nstruct TraceResult {\n    int len;\n    bool is_cycle;\n    int ret_d;\n};\n\ninline int get_to_fast(int t, int r, int in_d) {\n    int orig_out = to_table[t][(in_d + r) % 4];\n    if (orig_out == -1) return -1;\n    return (orig_out - r + 4) % 4;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    for (int t = 0; t < 8; ++t) {\n        for (int r = 0; r < 4; ++r) {\n            int mask = 0;\n            for (int d = 0; d < 4; ++d) {\n                int orig_out = to_table[t][(d + r) % 4];\n                if (orig_out != -1) {\n                    int out_d = (orig_out - r + 4) % 4;\n                    mask |= (1 << out_d);\n                }\n            }\n            valid_out[t][r] = mask;\n        }\n    }\n\n    vector<int> tiles(900);\n    for (int i = 0; i < 30; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < 30; ++j) {\n            tiles[i * 30 + j] = row[j] - '0';\n        }\n    }\n\n    vector<int> rot(900, 0);\n    \n    for (int i = 0; i < 30; ++i) {\n        for (int j = 0; j < 30; ++j) {\n            int idx = i * 30 + j;\n            int t = tiles[idx];\n            int best_r = 0, best_matches = -1;\n            for (int r = 0; r < 4; ++r) {\n                rot[idx] = r;\n                int matches = 0;\n                if (i > 0) {\n                    int top_idx = (i - 1) * 30 + j;\n                    if ((valid_out[tiles[top_idx]][rot[top_idx]] >> 3) & 1) { \n                        if ((valid_out[t][r] >> 1) & 1) matches++; \n                    }\n                }\n                if (j > 0) {\n                    int left_idx = i * 30 + (j - 1);\n                    if ((valid_out[tiles[left_idx]][rot[left_idx]] >> 2) & 1) { \n                        if ((valid_out[t][r] >> 0) & 1) matches++; \n                    }\n                }\n                if (matches > best_matches) {\n                    best_matches = matches;\n                    best_r = r;\n                }\n            }\n            rot[idx] = best_r;\n        }\n    }\n\n    multiset<int> cycles;\n    int pos_x = 0, pos_y = 0;\n\n    auto trace = [&](int start_x, int start_y, int start_d) -> TraceResult {\n        int cx = start_x, cy = start_y;\n        int curr_in_d = (start_d + 2) % 4;\n        int len = 0;\n        while (true) {\n            int idx = cx * 30 + cy;\n            int out_d = get_to_fast(tiles[idx], rot[idx], curr_in_d);\n            if (out_d == -1) return {len, false, -1};\n            \n            int nx = cx + di[out_d];\n            int ny = cy + dj[out_d];\n            if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30) return {len, false, -1};\n            \n            len++;\n            if (nx == pos_x && ny == pos_y) {\n                return {len, true, out_d};\n            }\n            \n            cx = nx; cy = ny;\n            curr_in_d = (out_d + 2) % 4;\n        }\n    };\n\n    auto extract_and_remove_cycles = [&](int idx, int r) {\n        vector<int> found_cycles;\n        found_cycles.reserve(4);\n        pos_x = idx / 30; pos_y = idx % 30;\n        int t = tiles[idx];\n        int curr_out_mask = valid_out[t][r];\n        for (int d = 0; d < 4; ++d) {\n            if (!(curr_out_mask & (1 << d))) continue;\n            int nx = pos_x + di[d], ny = pos_y + dj[d];\n            if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30) continue;\n            int neighbor_idx = nx * 30 + ny;\n            if (!((valid_out[tiles[neighbor_idx]][rot[neighbor_idx]] >> ((d + 2) % 4)) & 1)) continue;\n            \n            TraceResult res = trace(nx, ny, d);\n            if (res.is_cycle && res.ret_d >= d) {\n                found_cycles.push_back(res.len + 1);\n            }\n        }\n        for (int c : found_cycles) {\n            auto it = cycles.find(c);\n            if (it != cycles.end()) cycles.erase(it);\n        }\n        return found_cycles;\n    };\n\n    auto apply_and_insert_cycles = [&](int idx, int r) {\n        vector<int> found_cycles;\n        found_cycles.reserve(4);\n        pos_x = idx / 30; pos_y = idx % 30;\n        int t = tiles[idx];\n        int curr_out_mask = valid_out[t][r];\n        for (int d = 0; d < 4; ++d) {\n            if (!(curr_out_mask & (1 << d))) continue;\n            int nx = pos_x + di[d], ny = pos_y + dj[d];\n            if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30) continue;\n            int neighbor_idx = nx * 30 + ny;\n            if (!((valid_out[tiles[neighbor_idx]][rot[neighbor_idx]] >> ((d + 2) % 4)) & 1)) continue;\n            \n            TraceResult res = trace(nx, ny, d);\n            if (res.is_cycle && res.ret_d >= d) {\n                found_cycles.push_back(res.len + 1);\n            }\n        }\n        for (int c : found_cycles) {\n            cycles.insert(c);\n        }\n        return found_cycles;\n    };\n\n    for (int i = 0; i < 30; ++i) {\n        for (int j = 0; j < 30; ++j) {\n            int idx = i * 30 + j;\n            pos_x = i; pos_y = j;\n            int curr_out_mask = valid_out[tiles[idx]][rot[idx]];\n            for (int d = 0; d < 4; ++d) {\n                if (!(curr_out_mask & (1 << d))) continue;\n                int nx = i + di[d], ny = j + dj[d];\n                if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30) continue;\n                int neighbor_idx = nx * 30 + ny;\n                if (!((valid_out[tiles[neighbor_idx]][rot[neighbor_idx]] >> ((d + 2) % 4)) & 1)) continue;\n                \n                TraceResult res = trace(nx, ny, d);\n                if (res.is_cycle && res.ret_d >= d) {\n                    cycles.insert(res.len + 1);\n                }\n            }\n        }\n    }\n\n    long long sum_sq = 0;\n    for (int len : cycles) sum_sq += (long long)len * len;\n    long long current_sum_sq = sum_sq;\n\n    random_device rd;\n    mt19937 rng(rd());\n    uniform_int_distribution<int> rand_tile(0, 899);\n    uniform_int_distribution<int> rand_rot_diff(1, 3);\n    uniform_real_distribution<double> rand_prob(0.0, 1.0);\n\n    auto start_time = clock();\n    double temp = 80000.0;\n    double cool = 0.999997;\n\n    // Phase 1: SA with Sum of Squares to aggressively merge loops\n    while (clock() - start_time < 1.5 * CLOCKS_PER_SEC) {\n        int idx = rand_tile(rng);\n        int old_r = rot[idx];\n        int new_r = (old_r + rand_rot_diff(rng)) % 4;\n\n        vector<int> old_cycles = extract_and_remove_cycles(idx, old_r);\n        rot[idx] = new_r;\n        vector<int> new_cycles = apply_and_insert_cycles(idx, new_r);\n\n        long long new_sum_sq = sum_sq;\n        for (int c : old_cycles) new_sum_sq -= (long long)c * c;\n        for (int c : new_cycles) new_sum_sq += (long long)c * c;\n\n        if (new_sum_sq > current_sum_sq || exp((new_sum_sq - current_sum_sq) / temp) > rand_prob(rng)) {\n            current_sum_sq = new_sum_sq;\n            sum_sq = new_sum_sq;\n        } else {\n            rot[idx] = old_r;\n            for (int c : new_cycles) {\n                auto it = cycles.find(c);\n                if (it != cycles.end()) cycles.erase(it);\n            }\n            for (int c : old_cycles) {\n                cycles.insert(c);\n            }\n        }\n        temp *= cool;\n    }\n\n    // Phase 2: Strict Hill Climbing with True Score to balance top two loops\n    long long true_score = 0;\n    if (cycles.size() >= 2) {\n        auto it = cycles.rbegin();\n        true_score = (long long)*it * (long long)*std::next(it);\n    }\n\n    while (clock() - start_time < 1.95 * CLOCKS_PER_SEC) {\n        int idx = rand_tile(rng);\n        int old_r = rot[idx];\n        int new_r = (old_r + rand_rot_diff(rng)) % 4;\n\n        vector<int> old_cycles = extract_and_remove_cycles(idx, old_r);\n        rot[idx] = new_r;\n        vector<int> new_cycles = apply_and_insert_cycles(idx, new_r);\n\n        long long new_true_score = 0;\n        if (cycles.size() >= 2) {\n            auto it = cycles.rbegin();\n            new_true_score = (long long)*it * (long long)*std::next(it);\n        }\n\n        if (new_true_score > true_score) {\n            true_score = new_true_score;\n        } else {\n            rot[idx] = old_r;\n            for (int c : new_cycles) {\n                auto it = cycles.find(c);\n                if (it != cycles.end()) cycles.erase(it);\n            }\n            for (int c : old_cycles) {\n                cycles.insert(c);\n            }\n        }\n    }\n\n    string ans = \"\";\n    for (int i = 0; i < 900; ++i) {\n        ans += (char)('0' + rot[i]);\n    }\n    cout << ans << \"\\n\";\n\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nchar board[12][12];\nint ei, ej;\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst char dc[] = {'U', 'D', 'L', 'R'};\nconst int lm[] = {2, 8, 1, 4};\nconst int om[] = {8, 2, 4, 1};\n\ninline int gt(int i, int j) {\n    char c = board[i][j];\n    return (c == '0') ? -1 : ((c >= 'a') ? (c - 'a' + 10) : (c - '0'));\n}\n\nint vis[100], comp[100];\n\nint lts() {\n    int best = 0;\n    for (int i = 0; i < N * N; i++) vis[i] = 0;\n    for (int si = 0; si < N * N; si++) {\n        if (vis[si] || gt(si/N, si%N) < 0) continue;\n        int h = 0, t = 0;\n        comp[t++] = si; vis[si] = 1;\n        while (h < t) {\n            int c = comp[h++], ci = c/N, cj = c%N, ct = gt(ci, cj);\n            for (int d = 0; d < 4; d++) {\n                int ni = ci+di[d], nj = cj+dj[d];\n                if (ni<0||ni>=N||nj<0||nj>=N) continue;\n                int nx = ni*N+nj;\n                if (vis[nx]) continue;\n                int nt = gt(ni, nj);\n                if (nt>=0 && (ct&lm[d]) && (nt&om[d])) { vis[nx]=1; comp[t++]=nx; }\n            }\n        }\n        if (t <= best) continue;\n        int e = 0;\n        for (int k = 0; k < t; k++) {\n            int ci=comp[k]/N, cj=comp[k]%N, ct=gt(ci,cj);\n            if (cj+1<N && (ct&4)) { int nt=gt(ci,cj+1); if (nt>=0&&(nt&1)) e++; }\n            if (ci+1<N && (ct&8)) { int nt=gt(ci+1,cj); if (nt>=0&&(nt&2)) e++; }\n        }\n        if (e == t-1) best = t;\n        if (best == N*N-1) return best;\n    }\n    return best;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> T;\n    for (int i = 0; i < N; i++) cin >> board[i];\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++)\n        if (board[i][j] == '0') { ei = i; ej = j; }\n    \n    string moves;\n    mt19937 rng(42);\n    int cur_tree = lts();\n    int stuck = 0;\n    double rp = 0.4;\n    double cool = pow(0.01, 1.0/T);\n    \n    for (int step = 0; step < T; step++) {\n        int valid[4], vc = 0;\n        for (int d = 0; d < 4; d++) {\n            int ni = ei+di[d], nj = ej+dj[d];\n            if (ni>=0 && ni<N && nj>=0 && nj<N) valid[vc++] = d;\n        }\n        \n        int best = valid[0], best_tree = -1, best_delta = -100;\n        vector<int> ties;\n        \n        for (int v = 0; v < vc; v++) {\n            int d = valid[v], ni = ei+di[d], nj = ej+dj[d];\n            int t = gt(ni, nj);\n            if (t < 0) continue;\n            \n            int delta = 0;\n            for (int dd = 0; dd < 4; dd++) {\n                int nni=ei+di[dd], nnj=ej+dj[dd];\n                if (nni>=0&&nni<N&&nnj>=0&&nnj<N) {\n                    int nt=gt(nni,nnj);\n                    if (nt>=0&&(t&lm[dd])&&(nt&om[dd])) delta++;\n                }\n            }\n            for (int dd = 0; dd < 4; dd++) {\n                int nni=ni+di[dd], nnj=nj+dj[dd];\n                if (nni>=0&&nni<N&&nnj>=0&&nnj<N) {\n                    int nt=gt(nni,nnj);\n                    if (nt>=0&&(t&lm[dd])&&(nt&om[dd])) delta--;\n                }\n            }\n            \n            int tree = cur_tree;\n            if (delta > 0 || stuck > 20) {\n                swap(board[ei][ej], board[ni][nj]);\n                tree = lts();\n                swap(board[ei][ej], board[ni][nj]);\n            }\n            \n            if (tree > best_tree || (tree == best_tree && delta > best_delta)) {\n                best_tree = tree; best_delta = delta; best = d; ties = {d};\n            } else if (tree == best_tree && delta == best_delta) {\n                ties.push_back(d);\n            }\n        }\n        \n        if ((double)(rng()%1000)/1000.0 < rp) best = valid[rng()%vc];\n        else best = ties[rng()%ties.size()];\n        \n        int ni = ei+di[best], nj = ej+dj[best];\n        swap(board[ei][ej], board[ni][nj]);\n        ei = ni; ej = nj;\n        moves += dc[best];\n        \n        if (step % 20 == 0) {\n            int new_tree = lts();\n            if (new_tree >= cur_tree) { stuck = 0; cur_tree = new_tree; }\n            else stuck += 20;\n        } else if (best_tree > cur_tree) {\n            cur_tree = best_tree; stuck = 0;\n        } else {\n            stuck++;\n        }\n        \n        rp *= cool;\n    }\n    cout << moves << endl;\n}","ahc012":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <numeric>\n#include <random>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N;\n    if (!(cin >> N)) return 0;\n    int K_input;\n    cin >> K_input;\n    \n    int a[11] = {0};\n    for (int d = 1; d <= 10; d++) cin >> a[d];\n    \n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n    \n    if (N <= 1) {\n        cout << 0 << \"\\n\";\n        return 0;\n    }\n    \n    int active_V = min((int)sqrt(N) + 1, 50);\n    int active_H = min((int)sqrt(N) + 1, 50);\n    int total_V = 50;\n    int total_H = 50;\n    int actual_K = 100;\n    int active_K = active_V + active_H;\n    \n    vector<int> sorted_idx_x(N), sorted_idx_y(N);\n    iota(sorted_idx_x.begin(), sorted_idx_x.end(), 0);\n    sort(sorted_idx_x.begin(), sorted_idx_x.end(), [&](int i, int j) { return x[i] < x[j]; });\n    iota(sorted_idx_y.begin(), sorted_idx_y.end(), 0);\n    sort(sorted_idx_y.begin(), sorted_idx_y.end(), [&](int i, int j) { return y[i] < y[j]; });\n    \n    vector<int> ix(N), iy(N);\n    for (int i = 0; i < N; i++) {\n        ix[sorted_idx_x[i]] = i;\n        iy[sorted_idx_y[i]] = i;\n    }\n    \n    vector<int> pts_by_x(N), pts_by_y(N);\n    for (int i = 0; i < N; i++) {\n        pts_by_x[i] = sorted_idx_x[i];\n        pts_by_y[i] = sorted_idx_y[i];\n    }\n    \n    vector<int> first_of_rank_x(N, -1), last_of_rank_x(N, -1);\n    for (int i = 0; i < N; i++) {\n        int rank = ix[pts_by_x[i]];\n        if (first_of_rank_x[rank] == -1) first_of_rank_x[rank] = i;\n        last_of_rank_x[rank] = i;\n    }\n    \n    vector<int> first_of_rank_y(N, -1), last_of_rank_y(N, -1);\n    for (int i = 0; i < N; i++) {\n        int rank = iy[pts_by_y[i]];\n        if (first_of_rank_y[rank] == -1) first_of_rank_y[rank] = i;\n        last_of_rank_y[rank] = i;\n    }\n    \n    vector<int> k_v(total_V, 0), k_h(total_H, 0);\n    \n    for (int i = 0; i < active_V; i++) {\n        k_v[i] = (long long)(i + 1) * (N - 1) / (active_V + 1);\n    }\n    for (int i = 0; i < active_H; i++) {\n        k_h[i] = (long long)(i + 1) * (N - 1) / (active_H + 1);\n    }\n    \n    vector<int> V(N), H(N);\n    int cnt[51][51] = {0};\n    \n    for (int i = 0; i < N; i++) {\n        V[i] = 0;\n        for (int j = 0; j < total_V; j++) {\n            if (k_v[j] < ix[i]) V[i]++;\n        }\n        H[i] = 0;\n        for (int j = 0; j < total_H; j++) {\n            if (k_h[j] < iy[i]) H[i]++;\n        }\n        cnt[V[i]][H[i]]++;\n    }\n    \n    int b[11] = {0};\n    for (int v = 0; v <= 50; v++) {\n        for (int h = 0; h <= 50; h++) {\n            if (cnt[v][h] <= 10 && cnt[v][h] > 0) b[cnt[v][h]]++;\n        }\n    }\n    int current_score = 0;\n    for (int d = 1; d <= 10; d++) current_score += min(a[d], b[d]);\n    \n    int best_score = current_score;\n    vector<int> best_k_v = k_v, best_k_h = k_h;\n    \n    mt19937 mt(42);\n    uniform_int_distribution<int> rand_idx(0, active_K - 1);\n    uniform_real_distribution<double> rand_prob(0.0, 1.0);\n    \n    double temp = 2.0;\n    \n    auto apply_move = [&](int j, int from_k, int to_k, bool is_vert) -> int {\n        int delta_score = 0;\n        int l = min(from_k, to_k);\n        int r = max(from_k, to_k);\n        int v_change = (to_k > from_k) ? -1 : 1;\n        \n        int L = l + 1;\n        int R = r;\n        if (L > R) return 0;\n        \n        int start_idx, end_idx;\n        if (is_vert) {\n            start_idx = first_of_rank_x[L];\n            end_idx = last_of_rank_x[R];\n        } else {\n            start_idx = first_of_rank_y[L];\n            end_idx = last_of_rank_y[R];\n        }\n        \n        if (start_idx == -1) return 0;\n        \n        for (int idx = start_idx; idx <= end_idx; idx++) {\n            int i = is_vert ? pts_by_x[idx] : pts_by_y[idx];\n            int old_v = is_vert ? V[i] : H[i];\n            int new_v = old_v + v_change;\n            int h = is_vert ? H[i] : V[i];\n            \n            int S_old = is_vert ? cnt[old_v][h] : cnt[h][old_v];\n            if (S_old <= 10) {\n                if (b[S_old] <= a[S_old]) delta_score--;\n                b[S_old]--;\n            }\n            if (is_vert) cnt[old_v][h]--;\n            else cnt[h][old_v]--;\n            \n            if (S_old > 1 && S_old - 1 <= 10) {\n                if (b[S_old - 1] + 1 <= a[S_old - 1]) delta_score++;\n                b[S_old - 1]++;\n            }\n            \n            int S_new = is_vert ? cnt[new_v][h] : cnt[h][new_v];\n            if (S_new > 0 && S_new <= 10) {\n                if (b[S_new] <= a[S_new]) delta_score--;\n                b[S_new]--;\n            }\n            if (is_vert) cnt[new_v][h]++;\n            else cnt[h][new_v]++;\n            \n            if (S_new + 1 <= 10) {\n                if (b[S_new + 1] + 1 <= a[S_new + 1]) delta_score++;\n                b[S_new + 1]++;\n            }\n            \n            if (is_vert) V[i] = new_v;\n            else H[i] = new_v;\n        }\n        return delta_score;\n    };\n    \n    for (int iter = 0; iter < 20000000; iter++) {\n        temp *= 0.9999999;\n        \n        int j = rand_idx(mt);\n        int delta;\n        int r_val = mt() % 100;\n        if (r_val < 70) delta = (mt() % 2 == 0) ? 1 : -1;\n        else if (r_val < 90) delta = (mt() % 2 == 0) ? 2 : -2;\n        else {\n            int s = 3 + mt() % 15;\n            delta = (mt() % 2 == 0) ? s : -s;\n        }\n        \n        int k_old, k_new;\n        bool is_vertical = (j < active_V);\n        \n        if (is_vertical) {\n            k_old = k_v[j];\n            k_new = k_old + delta;\n            if (k_new < 0) k_new = 0;\n            if (k_new > N - 2) k_new = N - 2;\n        } else {\n            k_old = k_h[j - active_V];\n            k_new = k_old + delta;\n            if (k_new < 0) k_new = 0;\n            if (k_new > N - 2) k_new = N - 2;\n        }\n        \n        if (k_new == k_old) continue;\n        \n        int delta_score = apply_move(j, k_old, k_new, is_vertical);\n        \n        int diff = delta_score;\n        if (diff > 0 || rand_prob(mt) < exp(diff / temp)) {\n            current_score += diff;\n            if (is_vertical) k_v[j] = k_new;\n            else k_h[j - active_V] = k_new;\n            \n            if (current_score > best_score) {\n                best_score = current_score;\n                best_k_v = k_v;\n                best_k_h = k_h;\n            }\n        } else {\n            apply_move(j, k_new, k_old, is_vertical);\n        }\n    }\n    \n    k_v = best_k_v;\n    k_h = best_k_h;\n    \n    cout << actual_K << \"\\n\";\n    for (int j = 0; j < total_V; j++) {\n        int k = k_v[j];\n        int x_left = x[sorted_idx_x[k]];\n        int x_right = x[sorted_idx_x[k+1]];\n        int C_int = (x_left + x_right) / 2;\n        \n        long long px1 = C_int;\n        long long py1 = 0;\n        long long px2 = px1;\n        long long py2 = 1;\n        \n        cout << px1 << \" \" << py1 << \" \" << px2 << \" \" << py2 << \"\\n\";\n    }\n    for (int j = 0; j < total_H; j++) {\n        int k = k_h[j];\n        int y_left = y[sorted_idx_y[k]];\n        int y_right = y[sorted_idx_y[k+1]];\n        int C_int = (y_left + y_right) / 2;\n        \n        long long px1 = 0;\n        long long py1 = C_int;\n        long long px2 = 1;\n        long long py2 = py1;\n        \n        cout << px1 << \" \" << py1 << \" \" << px2 << \" \" << py2 << \"\\n\";\n    }\n\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\nusing namespace chrono;\n\nint N, M, c;\nbool dot[64][64];\nbool inFrontier[64][64][4];\nvector<tuple<int,int,int,int,int,int,int,int>> ops;\nmap<int, set<pair<int,int>>> segMap[4];\nset<tuple<int,int,int,int>,greater<>> frontier;\nconst int MAX_DIST = 6;\nconst int MAX_LEVEL = 3;\nconst int INF = 1e9;\n\nint getLineType(int x1, int y1, int x2, int y2) {\n    if (x1 == x2) return 1; if (y1 == y2) return 0;\n    if (x1 + y1 == x2 + y2) return 2; return 3;\n}\nint getLineId(int type, int x, int y) {\n    if (type == 0) return y; if (type == 1) return x;\n    if (type == 2) return x + y; return x - y;\n}\nint getCoord(int type, int x, int y) { return (type == 1) ? y : x; }\n\nbool chk(int x1, int y1, int x2, int y2) {\n    int type = getLineType(x1, y1, x2, y2);\n    int line = getLineId(type, x1, y1);\n    int lo = getCoord(type, x1, y1), hi = getCoord(type, x2, y2);\n    if (lo > hi) swap(lo, hi);\n    auto it = segMap[type].find(line);\n    if (it == segMap[type].end()) return true;\n    auto& s = it->second;\n    auto it2 = s.upper_bound({lo, INF});\n    if (it2 != s.begin()) { auto prev = it2; --prev; if (prev->second > lo) return false; }\n    if (it2 != s.end() && it2->first < hi) return false;\n    return true;\n}\n\nvoid addSeg(int x1, int y1, int x2, int y2) {\n    int type = getLineType(x1, y1, x2, y2);\n    int line = getLineId(type, x1, y1);\n    int lo = getCoord(type, x1, y1), hi = getCoord(type, x2, y2);\n    if (lo > hi) swap(lo, hi);\n    auto& s = segMap[type][line];\n    auto it = s.upper_bound({lo, INF});\n    if (it != s.begin()) { auto prev = it; --prev; if (prev->second > lo) { lo = prev->first; it = s.erase(prev); } }\n    while (it != s.end() && it->first < hi) { hi = max(hi, it->second); it = s.erase(it); }\n    s.emplace(lo, hi);\n}\n\nint wt(int x, int y) { int dx=x-c, dy=y-c; return dx*dx+dy*dy+1; }\nbool inBounds(int x, int y) { return x>=0 && x<N && y>=0 && y<N; }\n\nbool tryR(int tx, int ty, int x2, int y2, int x3, int y3, int x4, int y4) {\n    if (!inBounds(x2,y2) || !inBounds(x3,y3) || !inBounds(x4,y4)) return false;\n    if (!dot[x2][y2] || !dot[x3][y3] || !dot[x4][y4]) return false;\n    int xs[4]={tx,x2,x3,x4}, ys[4]={ty,y2,y3,y4};\n    for (int i=0;i<4;i++) { int ni=(i+1)%4, ni2=(i+2)%4;\n        if ((xs[ni]-xs[i])*(xs[ni2]-xs[ni])+(ys[ni]-ys[i])*(ys[ni2]-ys[ni]) != 0) return false; }\n    for (int i=0;i<4;i++) { int ni=(i+1)%4; if (!chk(xs[i],ys[i],xs[ni],ys[ni])) return false; }\n    for (int i=0;i<4;i++) { int ni=(i+1)%4; addSeg(xs[i],ys[i],xs[ni],ys[ni]); }\n    dot[tx][ty]=true; ops.emplace_back(tx,ty,x2,y2,x3,y3,x4,y4); return true;\n}\n\nbool tryUnitSquare(int tx, int ty) {\n    for (int dx=-1;dx<=1;dx+=2) for (int dy=-1;dy<=1;dy+=2)\n        if (tryR(tx,ty,tx+dx,ty,tx+dx,ty+dy,tx,ty+dy)) return true;\n    return false;\n}\n\nbool tryRect(int tx, int ty, int w, int h) {\n    for (int sw=-1;sw<=1;sw+=2) for (int sh=-1;sh<=1;sh+=2) {\n        int x2=tx+w*sw, y4=ty+h*sh;\n        if (!inBounds(x2,ty)||!inBounds(x2,y4)||!inBounds(tx,y4)) continue;\n        if (!dot[x2][ty]||!dot[x2][y4]||!dot[tx][y4]) continue;\n        bool ok=true;\n        for(int k=1;k<w&&ok;k++) if(dot[tx+k*sw][ty]||dot[tx+k*sw][y4]) ok=false;\n        for(int k=1;k<h&&ok;k++) if(dot[tx][ty+k*sh]||dot[x2][ty+k*sh]) ok=false;\n        if(ok && tryR(tx,ty,x2,ty,x2,y4,tx,y4)) return true;\n    }\n    return false;\n}\n\nbool tryUnitDiamond(int tx, int ty) {\n    int ddx[]={1,0,-1,0}, ddy[]={0,1,0,-1};\n    for (int d=0;d<4;d++) {\n        int cx=tx-ddx[d], cy=ty-ddy[d], ox[3], oy[3]; bool valid=true;\n        for (int i=0;i<3;i++) { int dir=(d+1+i)%4; ox[i]=cx+ddx[dir]; oy[i]=cy+ddy[dir];\n            if (!inBounds(ox[i],oy[i]) || !dot[ox[i]][oy[i]]) { valid=false; break; } }\n        if (valid && tryR(tx,ty,ox[0],oy[0],ox[1],oy[1],ox[2],oy[2])) return true;\n    }\n    return false;\n}\n\nbool tryDiamond(int tx, int ty, int s) {\n    int ddx[]={1,0,-1,0}, ddy[]={0,1,0,-1};\n    for (int d=0;d<4;d++) {\n        int cx=tx-s*ddx[d], cy=ty-s*ddy[d], vx[4], vy[4];\n        for(int i=0;i<4;i++) { vx[i]=cx+s*ddx[i]; vy[i]=cy+s*ddy[i]; }\n        bool valid=true; int nt[3];\n        for(int i=0;i<3;i++) { nt[i]=(d+1+i)%4;\n            if(!inBounds(vx[nt[i]],vy[nt[i]])||!dot[vx[nt[i]],vy[nt[i]]]) { valid=false; break; } }\n        if(!valid) continue;\n        bool edgeClear=true;\n        for(int e=0;e<4&&edgeClear;e++) { int e2=(e+1)%4;\n            for(int k=1;k<s&&edgeClear;k++) { int mx=vx[e]+k*(vx[e2]-vx[e])/s, my=vy[e]+k*(vy[e2]-vy[e])/s;\n                if(inBounds(mx,my)&&dot[mx][my]) edgeClear=false; } }\n        if(edgeClear && tryR(tx,ty,vx[nt[0]],vy[nt[0]],vx[nt[1]],vy[nt[1]],vx[nt[2]],vy[nt[2]])) return true;\n    }\n    return false;\n}\n\nbool tryLevel0(int tx, int ty) { return tryUnitSquare(tx, ty) || tryUnitDiamond(tx, ty); }\nbool tryLevel1(int tx, int ty) { return tryLevel0(tx, ty) || tryRect(tx, ty, 2, 2) || tryDiamond(tx, ty, 2); }\nbool tryLevel2(int tx, int ty) {\n    if (tryLevel1(tx, ty)) return true;\n    if (tryRect(tx, ty, 3, 3) || tryDiamond(tx, ty, 3)) return true;\n    int mix[][2] = {{1,2},{2,1},{1,3},{3,1},{2,3},{3,2}};\n    for (auto& m : mix) if (tryRect(tx, ty, m[0], m[1])) return true;\n    return false;\n}\nbool tryLevel3(int tx, int ty) {\n    if (tryLevel2(tx, ty)) return true;\n    for (int s=4;s<=MAX_DIST;s++) { if (tryRect(tx, ty, s, s) || tryDiamond(tx, ty, s)) return true; }\n    int mix[][2] = {{1,4},{4,1},{2,4},{4,2},{3,4},{4,3},{1,5},{5,1},{2,5},{5,2},{3,5},{5,3},{4,5},{5,4},{1,6},{6,1},{2,6},{6,2}};\n    for (auto& m : mix) if (tryRect(tx, ty, m[0], m[1])) return true;\n    return false;\n}\n\nbool tryLevelShapes(int tx, int ty, int level) {\n    if (level <= 0) return tryLevel0(tx, ty);\n    if (level == 1) return tryLevel1(tx, ty);\n    if (level == 2) return tryLevel2(tx, ty);\n    return tryLevel3(tx, ty);\n}\n\nvoid addToFrontier(int x, int y, int level = 0) {\n    for (int dx=-MAX_DIST;dx<=MAX_DIST;dx++) for (int dy=-MAX_DIST;dy<=MAX_DIST;dy++) {\n        int d=max(abs(dx),abs(dy));\n        if (d==0||d>MAX_DIST) continue;\n        int nx=x+dx, ny=y+dy;\n        if (inBounds(nx,ny) && !dot[nx][ny] && !inFrontier[nx][ny][level]) {\n            inFrontier[nx][ny][level] = true;\n            frontier.emplace(wt(nx,ny), -level, nx, ny);\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    auto start=steady_clock::now();\n    cin>>N>>M; c=(N-1)/2;\n    for (int i=0;i<M;i++) { int x,y; cin>>x>>y; dot[x][y]=true; }\n    for (int x=0;x<N;x++) for (int y=0;y<N;y++) if (dot[x][y]) addToFrontier(x,y,0);\n    \n    while (!frontier.empty()) {\n        if (duration_cast<milliseconds>(steady_clock::now()-start).count()>4500) break;\n        auto [w, negLevel, x, y] = *frontier.begin();\n        frontier.erase(frontier.begin());\n        if (dot[x][y]) continue;\n        for(int l=0;l<=MAX_LEVEL;l++) inFrontier[x][y][l]=false;\n        int level = -negLevel;\n        if (tryLevelShapes(x, y, level)) {\n            addToFrontier(x, y, 0);\n        } else if (level < MAX_LEVEL && !inFrontier[x][y][level+1]) {\n            inFrontier[x][y][level+1] = true;\n            frontier.emplace(w, -(level+1), x, y);\n        }\n    }\n    \n    cout<<ops.size()<<\"\\n\";\n    for (auto& op:ops) cout<<get<0>(op)<<\" \"<<get<1>(op)<<\" \"<<get<2>(op)<<\" \"<<get<3>(op)<<\" \"<<get<4>(op)<<\" \"<<get<5>(op)<<\" \"<<get<6>(op)<<\" \"<<get<7>(op)<<\"\\n\";\n    return 0;\n}","ahc015":"#include <iostream>\n#include <cstring>\n#include <vector>\n\nusing namespace std;\n\nconst int N = 10;\nint grid[N][N];\nconst int dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1};\nconst char dirs[] = {'F', 'B', 'L', 'R'};\n\nvoid tilt(char dir) {\n    if (dir == 'F') {\n        for (int c = 0; c < N; c++) { int w = 0; for (int r = 0; r < N; r++) if (grid[r][c]) { int f = grid[r][c]; grid[r][c] = 0; grid[w++][c] = f; } }\n    } else if (dir == 'B') {\n        for (int c = 0; c < N; c++) { int w = N - 1; for (int r = N - 1; r >= 0; r--) if (grid[r][c]) { int f = grid[r][c]; grid[r][c] = 0; grid[w--][c] = f; } }\n    } else if (dir == 'L') {\n        for (int r = 0; r < N; r++) { int w = 0; for (int c = 0; c < N; c++) if (grid[r][c]) { int f = grid[r][c]; grid[r][c] = 0; grid[r][w++] = f; } }\n    } else {\n        for (int r = 0; r < N; r++) { int w = N - 1; for (int c = N - 1; c >= 0; c--) if (grid[r][c]) { int f = grid[r][c]; grid[r][c] = 0; grid[r][w--] = f; } }\n    }\n}\n\nint computeSumSq() {\n    static int vis[N][N], stk[100];\n    memset(vis, 0, sizeof(vis));\n    int sumSq = 0;\n    for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) if (grid[r][c] && !vis[r][c]) {\n        int sz = 0, f = grid[r][c], top = 0;\n        stk[top++] = r * N + c; vis[r][c] = 1;\n        while (top > 0) {\n            int p = stk[--top], cr = p / N, cc = p % N; sz++;\n            for (int d = 0; d < 4; d++) {\n                int nr = cr + dr[d], nc = cc + dc[d];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N && !vis[nr][nc] && grid[nr][nc] == f) { vis[nr][nc] = 1; stk[top++] = nr * N + nc; }\n            }\n        }\n        sumSq += sz * sz;\n    }\n    return sumSq;\n}\n\nvector<pair<int,int>> getSampledCells(int flavor, int maxSamples) {\n    vector<pair<int,int>> mergeCells, extendCells, otherCells;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (!grid[i][j]) {\n        int adjCount = 0;\n        for (int d = 0; d < 4; d++) {\n            int ni = i + dr[d], nj = j + dc[d];\n            if (ni >= 0 && ni < N && nj >= 0 && nj < N && grid[ni][nj] == flavor) adjCount++;\n        }\n        if (adjCount >= 2) mergeCells.push_back({i, j});\n        else if (adjCount == 1) extendCells.push_back({i, j});\n        else otherCells.push_back({i, j});\n    }\n    int totalCells = mergeCells.size() + extendCells.size() + otherCells.size();\n    if (totalCells <= maxSamples) {\n        vector<pair<int,int>> result = mergeCells;\n        result.insert(result.end(), extendCells.begin(), extendCells.end());\n        result.insert(result.end(), otherCells.begin(), otherCells.end());\n        return result;\n    }\n    vector<pair<int,int>> result;\n    for (auto& c : mergeCells) result.push_back(c);\n    for (auto& c : extendCells) if ((int)result.size() < maxSamples) result.push_back(c);\n    int remaining = maxSamples - result.size();\n    if (remaining > 0 && !otherCells.empty()) {\n        int step = max(1, (int)otherCells.size() / remaining);\n        for (int i = 0; i < (int)otherCells.size() && (int)result.size() < maxSamples; i += step)\n            result.push_back(otherCells[i]);\n    }\n    return result;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int flavors[100];\n    for (int i = 0; i < 100; i++) cin >> flavors[i];\n    memset(grid, 0, sizeof(grid));\n    for (int t = 0; t < 100; t++) {\n        int p; cin >> p;\n        int cnt = 0, r = -1, c = -1;\n        for (int i = 0; i < N && r < 0; i++) for (int j = 0; j < N && r < 0; j++) if (!grid[i][j] && ++cnt == p) { r = i; c = j; }\n        grid[r][c] = flavors[t];\n        if (t < 99) {\n            char bestDir = 'F'; int bestScore = -1;\n            int nextFlavor = flavors[t + 1];\n            int numEmpty = 100 - t - 1;\n            int maxSamples = numEmpty <= 20 ? numEmpty : (numEmpty <= 40 ? 18 : 15);\n            for (int di = 0; di < 4; di++) {\n                int saved0[N][N]; memcpy(saved0, grid, sizeof(grid));\n                tilt(dirs[di]);\n                int currentScore = computeSumSq();\n                vector<pair<int,int>> cells1 = getSampledCells(nextFlavor, maxSamples);\n                int sampleCount1 = cells1.size();\n                int totalFutureBest = 0;\n                for (auto& [er, ec] : cells1) {\n                    int saved1[N][N]; memcpy(saved1, grid, sizeof(grid));\n                    grid[er][ec] = nextFlavor;\n                    int bestFuture1 = 0;\n                    for (int d = 0; d < 4; d++) {\n                        int saved2[N][N]; memcpy(saved2, grid, sizeof(grid));\n                        tilt(dirs[d]);\n                        int score = computeSumSq();\n                        if (score > bestFuture1) bestFuture1 = score;\n                        memcpy(grid, saved2, sizeof(grid));\n                    }\n                    totalFutureBest += bestFuture1;\n                    memcpy(grid, saved1, sizeof(grid));\n                }\n                int score = currentScore * sampleCount1 * 3 + totalFutureBest * 2;\n                memcpy(grid, saved0, sizeof(grid));\n                if (score > bestScore) { bestScore = score; bestDir = dirs[di]; }\n            }\n            tilt(bestDir); cout << bestDir << endl;\n        }\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int M;\n    double eps;\n    cin >> M >> eps;\n    \n    int N;\n    if (eps <= 0.01) N = 8;\n    else if (eps <= 0.03) N = 10;\n    else if (eps <= 0.06) N = 12;\n    else if (eps <= 0.10) N = 16;\n    else if (eps <= 0.15) N = 22;\n    else if (eps <= 0.20) N = 28;\n    else if (eps <= 0.30) N = 40;\n    else if (eps <= 0.40) N = 60;\n    else N = 80;\n    \n    N = max(N, 4);\n    N = min(N, 100);\n    \n    int total_pairs = N * (N - 1) / 2;\n    \n    mt19937 rng(42);\n    \n    vector<string> graphs(M);\n    vector<vector<int>> sorted_deg(M, vector<int>(N));\n    \n    for (int i = 0; i < M; i++) {\n        int num_edges = (int)((i + 0.5) * total_pairs / M);\n        string g(total_pairs, '0');\n        vector<int> indices(total_pairs);\n        iota(indices.begin(), indices.end(), 0);\n        shuffle(indices.begin(), indices.end(), rng);\n        for (int j = 0; j < num_edges; j++) g[indices[j]] = '1';\n        graphs[i] = g;\n        \n        int idx = 0;\n        for (int v = 0; v < N; v++) {\n            for (int u = v + 1; u < N; u++) {\n                if (g[idx++] == '1') {\n                    sorted_deg[i][v]++;\n                    sorted_deg[i][u]++;\n                }\n            }\n        }\n        sort(sorted_deg[i].begin(), sorted_deg[i].end());\n    }\n    \n    cout << N << \"\\n\";\n    for (auto& g : graphs) cout << g << \"\\n\";\n    cout << flush;\n    \n    for (int q = 0; q < 100; q++) {\n        string H;\n        cin >> H;\n        \n        vector<int> h_deg(N);\n        int idx = 0;\n        for (int v = 0; v < N; v++) {\n            for (int u = v + 1; u < N; u++) {\n                if (H[idx++] == '1') {\n                    h_deg[v]++;\n                    h_deg[u]++;\n                }\n            }\n        }\n        sort(h_deg.begin(), h_deg.end());\n        \n        int best = 0;\n        double best_dist = 1e18;\n        for (int i = 0; i < M; i++) {\n            double dist = 0;\n            for (int j = 0; j < N; j++) {\n                double diff = h_deg[j] - sorted_deg[i][j];\n                dist += diff * diff;\n            }\n            if (dist < best_dist) {\n                best_dist = dist;\n                best = i;\n            }\n        }\n        cout << best << \"\\n\" << 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    cin >> N >> M >> D >> K;\n    \n    vector<tuple<int, int, int>> edges(M);\n    vector<vector<pair<int, int>>> adj(N);\n    \n    unsigned long long seed = N * 1000000007ULL + M * 1000003ULL + D * 1009ULL + K;\n    \n    for (int i = 0; i < M; i++) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        u--; v--;\n        edges[i] = {u, v, w};\n        adj[u].push_back({v, i});\n        adj[v].push_back({u, i});\n        seed ^= (unsigned long long)(u + 1) * 1000000007ULL + (v + 1) * 1000003ULL + w;\n    }\n    \n    for (int i = 0; i < N; i++) { int x, y; cin >> x >> y; seed ^= (unsigned long long)x * 10007ULL + y; }\n    \n    vector<long long> betweenness(M, 0);\n    mt19937 rng(seed);\n    int S = min(200, N);\n    vector<int> sources(S);\n    iota(sources.begin(), sources.end(), 0);\n    shuffle(sources.begin(), sources.end(), rng);\n    \n    for (int s : sources) {\n        vector<long long> dist(N, 1e18);\n        vector<int> parent_edge(N, -1);\n        dist[s] = 0;\n        priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> pq;\n        pq.push({0, s});\n        \n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u]) continue;\n            for (auto [v, ei] : adj[u]) {\n                if (dist[u] + get<2>(edges[ei]) < dist[v]) {\n                    dist[v] = dist[u] + get<2>(edges[ei]);\n                    parent_edge[v] = ei;\n                    pq.push({dist[v], v});\n                }\n            }\n        }\n        \n        vector<vector<int>> children(N);\n        for (int v = 0; v < N; v++) {\n            if (parent_edge[v] != -1) {\n                auto [pu, pv, pw] = edges[parent_edge[v]];\n                children[(pu == v) ? pv : pu].push_back(v);\n            }\n        }\n        \n        vector<int> subtree_size(N, 1);\n        function<void(int)> dfs = [&](int u) {\n            for (int v : children[u]) {\n                dfs(v);\n                subtree_size[u] += subtree_size[v];\n            }\n            if (parent_edge[u] != -1) betweenness[parent_edge[u]] += subtree_size[u];\n        };\n        dfs(s);\n    }\n    \n    vector<int> edge_order(M);\n    iota(edge_order.begin(), edge_order.end(), 0);\n    sort(edge_order.begin(), edge_order.end(), [&](int a, int b) {\n        return betweenness[a] > betweenness[b];\n    });\n    \n    vector<int> day_assignment(M, -1), day_count(D, 0);\n    vector<vector<int>> day_edges_list(D);\n    vector<long long> vertex_day_importance(N * D, 0);\n    \n    for (int e : edge_order) {\n        auto [u, v, w] = edges[e];\n        long long imp = betweenness[e];\n        \n        int best_day = -1;\n        long long best_conflict = LLONG_MAX;\n        for (int d = 0; d < D; d++) {\n            if (day_count[d] >= K) continue;\n            long long conflict = vertex_day_importance[u * D + d] + vertex_day_importance[v * D + d];\n            if (conflict < best_conflict) { best_conflict = conflict; best_day = d; }\n        }\n        if (best_day == -1) {\n            for (int d = 0; d < D; d++) {\n                long long conflict = vertex_day_importance[u * D + d] + vertex_day_importance[v * D + d];\n                if (conflict < best_conflict) { best_conflict = conflict; best_day = d; }\n            }\n        }\n        day_assignment[e] = best_day;\n        day_count[best_day]++;\n        day_edges_list[best_day].push_back(e);\n        vertex_day_importance[u * D + best_day] += imp;\n        vertex_day_importance[v * D + best_day] += imp;\n    }\n    \n    double temperature = 500.0;\n    for (int iter = 0; iter < 2000000; iter++) {\n        temperature *= 0.999997;\n        int d1 = rng() % D, d2 = rng() % D;\n        if (d1 == d2 || day_edges_list[d1].empty() || day_edges_list[d2].empty()) continue;\n        \n        int idx1 = rng() % day_edges_list[d1].size(), idx2 = rng() % day_edges_list[d2].size();\n        int e1 = day_edges_list[d1][idx1], e2 = day_edges_list[d2][idx2];\n        auto [u1, v1, w1] = edges[e1];\n        auto [u2, v2, w2] = edges[e2];\n        long long imp1 = betweenness[e1], imp2 = betweenness[e2];\n        \n        long long c1 = vertex_day_importance[u1 * D + d1] + vertex_day_importance[v1 * D + d1] - 2 * imp1;\n        long long c2 = vertex_day_importance[u2 * D + d2] + vertex_day_importance[v2 * D + d2] - 2 * imp2;\n        \n        long long e2_at_u1 = (u2 == u1 || v2 == u1) ? imp2 : 0;\n        long long e2_at_v1 = (u2 == v1 || v2 == v1) ? imp2 : 0;\n        long long e1_at_u2 = (u1 == u2 || v1 == u2) ? imp1 : 0;\n        long long e1_at_v2 = (u1 == v2 || v1 == v2) ? imp1 : 0;\n        \n        long long n1 = vertex_day_importance[u1 * D + d2] + vertex_day_importance[v1 * D + d2] - e2_at_u1 - e2_at_v1;\n        long long n2 = vertex_day_importance[u2 * D + d1] + vertex_day_importance[v2 * D + d1] - e1_at_u2 - e1_at_v2;\n        \n        long long delta = (n1 + n2) - (c1 + c2);\n        \n        if (delta < 0 || (temperature > 0.001 && (double)(rng() % 100000) / 100000.0 < exp(-(double)delta / max(temperature, 1.0)))) {\n            day_assignment[e1] = d2; day_assignment[e2] = d1;\n            vertex_day_importance[u1 * D + d1] -= imp1; vertex_day_importance[v1 * D + d1] -= imp1;\n            vertex_day_importance[u1 * D + d2] += imp1; vertex_day_importance[v1 * D + d2] += imp1;\n            vertex_day_importance[u2 * D + d2] -= imp2; vertex_day_importance[v2 * D + d2] -= imp2;\n            vertex_day_importance[u2 * D + d1] += imp2; vertex_day_importance[v2 * D + d1] += imp2;\n            day_edges_list[d1][idx1] = e2; day_edges_list[d2][idx2] = e1;\n        }\n    }\n    \n    for (int i = 0; i < M; i++) cout << day_assignment[i] + 1 << \" \\n\"[i == M - 1];\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\nusing namespace chrono;\n\nint D, b[2][15][15][15], n, rots[24][3][3], numRots=0;\nhigh_resolution_clock::time_point start_time;\n\nstruct TupleHash {\n    size_t operator()(const tuple<int,int,int>& t) const {\n        auto [x, y, z] = t;\n        return x * 225 + y * 15 + z;\n    }\n};\nusing PointSet = unordered_set<tuple<int,int,int>, TupleHash>;\nPointSet V[2];\n\nvoid generateRotations() {\n    set<vector<int>> seen; queue<vector<int>> q;\n    vector<int> id={1,0,0,0,1,0,0,0,1},rx={1,0,0,0,0,-1,0,1,0},ry={0,0,1,0,1,0,-1,0,0},rz={0,-1,0,1,0,0,0,0,1};\n    q.push(id); seen.insert(id);\n    auto mul=[](vector<int> a,vector<int> b){vector<int> c(9);for(int i=0;i<3;i++)for(int j=0;j<3;j++){c[i*3+j]=0;for(int k=0;k<3;k++)c[i*3+j]+=a[i*3+k]*b[k*3+j];}return c;};\n    while(!q.empty()){auto cur=q.front();q.pop();for(int i=0;i<9;i++)rots[numRots][i/3][i%3]=cur[i];numRots++;for(auto&base:{rx,ry,rz}){auto nx=mul(cur,base);if(!seen.count(nx)){seen.insert(nx);q.push(nx);}}}\n}\n\nstring canonical(const vector<tuple<int,int,int>>& cubes) {\n    string best;\n    for(int r=0;r<24;r++){vector<tuple<int,int,int>> rot;int mx=INT_MAX,my=INT_MAX,mz=INT_MAX;\n        for(auto&[x,y,z]:cubes){int nx=rots[r][0][0]*x+rots[r][0][1]*y+rots[r][0][2]*z,ny=rots[r][1][0]*x+rots[r][1][1]*y+rots[r][1][2]*z,nz=rots[r][2][0]*x+rots[r][2][1]*y+rots[r][2][2]*z;mx=min(mx,nx);my=min(my,ny);mz=min(mz,nz);rot.push_back({nx,ny,nz});}\n        sort(rot.begin(),rot.end());string s;for(auto&[x,y,z]:rot){s+=char(x-mx+'a');s+=char(y-my+'a');s+=char(z-mz+'a');}if(best.empty()||s<best)best=s;}return best;\n}\n\nvoid findComponents(PointSet& V, vector<vector<tuple<int,int,int>>>& comps) {\n    PointSet rem=V; int dx[]={1,-1,0,0,0,0},dy[]={0,0,1,-1,0,0},dz[]={0,0,0,0,1,-1};\n    while(!rem.empty()){auto[sx,sy,sz]=*rem.begin();rem.erase(rem.begin());vector<tuple<int,int,int>> comp;comp.push_back({sx,sy,sz});queue<tuple<int,int,int>> q;q.push({sx,sy,sz});\n    while(!q.empty()){auto[x,y,z]=q.front();q.pop();for(int d=0;d<6;d++){int nx=x+dx[d],ny=y+dy[d],nz=z+dz[d];auto np=make_tuple(nx,ny,nz);if(rem.count(np)){rem.erase(np);comp.push_back(np);q.push(np);}}}comps.push_back(comp);}\n}\n\nvoid extractAndAssign(PointSet rem[2], int rot, tuple<int,int,int> trans) {\n    PointSet m0;\n    for(auto&[x,y,z]:rem[0]){int rx=rots[rot][0][0]*(x-get<0>(trans))+rots[rot][1][0]*(y-get<1>(trans))+rots[rot][2][0]*(z-get<2>(trans)),ry=rots[rot][0][1]*(x-get<0>(trans))+rots[rot][1][1]*(y-get<1>(trans))+rots[rot][2][1]*(z-get<2>(trans)),rz=rots[rot][0][2]*(x-get<0>(trans))+rots[rot][1][2]*(y-get<1>(trans))+rots[rot][2][2]*(z-get<2>(trans));if(rem[1].count({rx,ry,rz}))m0.insert({x,y,z});}\n    vector<vector<tuple<int,int,int>>> comps;findComponents(m0,comps);\n    for(auto&comp:comps){n++;for(auto&[x,y,z]:comp){b[0][x][y][z]=n;int rx=rots[rot][0][0]*(x-get<0>(trans))+rots[rot][1][0]*(y-get<1>(trans))+rots[rot][2][0]*(z-get<2>(trans)),ry=rots[rot][0][1]*(x-get<0>(trans))+rots[rot][1][1]*(y-get<1>(trans))+rots[rot][2][1]*(z-get<2>(trans)),rz=rots[rot][0][2]*(x-get<0>(trans))+rots[rot][1][2]*(y-get<1>(trans))+rots[rot][2][2]*(z-get<2>(trans));b[1][rx][ry][rz]=n;rem[0].erase({x,y,z});rem[1].erase({rx,ry,rz});}}\n}\n\npair<int,tuple<int,int,int>> findBestAlignmentScored(PointSet& V0, PointSet& V1) {\n    vector<tuple<int,int,int>> v0(V0.begin(),V0.end()),v1(V1.begin(),V1.end());\n    vector<tuple<int,int,tuple<int,int,int>>> top_rotations;\n    for(int rot=0;rot<24;rot++){unordered_map<tuple<int,int,int>,int,TupleHash> tc;\n        for(auto&[x0,y0,z0]:v0)for(auto&[x,y,z]:v1){int bx=rots[rot][0][0]*x+rots[rot][0][1]*y+rots[rot][0][2]*z,by=rots[rot][1][0]*x+rots[rot][1][1]*y+rots[rot][1][2]*z,bz=rots[rot][2][0]*x+rots[rot][2][1]*y+rots[rot][2][2]*z;tc[{x0-bx,y0-by,z0-bz}]++;}\n        int best_count=0;tuple<int,int,int> best_trans;\n        for(auto&[trans,count]:tc)if(count>best_count){best_count=count;best_trans=trans;}\n        top_rotations.push_back({best_count,rot,best_trans});}\n    sort(top_rotations.rbegin(),top_rotations.rend());\n    int best_rot=-1;tuple<int,int,int> best_trans;double best_score=-1;\n    for(int i=0;i<min(8,(int)top_rotations.size());i++){auto[count,rot,trans]=top_rotations[i];if(count<2)break;\n        PointSet matched;for(auto&[x,y,z]:v0){int rx=rots[rot][0][0]*(x-get<0>(trans))+rots[rot][1][0]*(y-get<1>(trans))+rots[rot][2][0]*(z-get<2>(trans)),ry=rots[rot][0][1]*(x-get<0>(trans))+rots[rot][1][1]*(y-get<1>(trans))+rots[rot][2][1]*(z-get<2>(trans)),rz=rots[rot][0][2]*(x-get<0>(trans))+rots[rot][1][2]*(y-get<1>(trans))+rots[rot][2][2]*(z-get<2>(trans));if(V1.count({rx,ry,rz}))matched.insert({x,y,z});}\n        vector<vector<tuple<int,int,int>>> comps;findComponents(matched,comps);\n        double score=0;for(auto&comp:comps){int v=comp.size();score+=2.0*v-1.0/v;}\n        if(score>best_score){best_score=score;best_rot=rot;best_trans=trans;}}\n    return {best_rot,best_trans};\n}\n\nbool tryCompAlignment(PointSet rem[2], vector<tuple<int,int,int>>& comp, int dir) {\n    PointSet& src = rem[dir];\n    PointSet& dst = rem[1-dir];\n    vector<tuple<int,int,int>> vdst(dst.begin(), dst.end());\n    int best_count=0,best_rot=-1;tuple<int,int,int> best_trans;\n    for(int rot=0;rot<24;rot++){unordered_map<tuple<int,int,int>,int,TupleHash> tc;\n        for(auto&[x,y,z]:comp){if(!src.count({x,y,z}))continue;\n            int nx=rots[rot][0][0]*x+rots[rot][0][1]*y+rots[rot][0][2]*z,ny=rots[rot][1][0]*x+rots[rot][1][1]*y+rots[rot][1][2]*z,nz=rots[rot][2][0]*x+rots[rot][2][1]*y+rots[rot][2][2]*z;\n            for(auto&[px,py,pz]:vdst)tc[{px-nx,py-ny,pz-nz}]++;}\n        for(auto&[trans,count]:tc)if(count>best_count){best_count=count;best_rot=rot;best_trans=trans;}}\n    if(best_count<1)return false;\n    PointSet msrc;\n    for(auto&[x,y,z]:comp){if(!src.count({x,y,z}))continue;\n        int qx=rots[best_rot][0][0]*x+rots[best_rot][0][1]*y+rots[best_rot][0][2]*z+get<0>(best_trans),qy=rots[best_rot][1][0]*x+rots[best_rot][1][1]*y+rots[best_rot][1][2]*z+get<1>(best_trans),qz=rots[best_rot][2][0]*x+rots[best_rot][2][1]*y+rots[best_rot][2][2]*z+get<2>(best_trans);\n        if(dst.count({qx,qy,qz}))msrc.insert({x,y,z});}\n    if(msrc.empty())return false;\n    vector<vector<tuple<int,int,int>>> comps;findComponents(msrc,comps);\n    for(auto&c:comps){n++;for(auto&[x,y,z]:c){b[dir][x][y][z]=n;int qx=rots[best_rot][0][0]*x+rots[best_rot][0][1]*y+rots[best_rot][0][2]*z+get<0>(best_trans),qy=rots[best_rot][1][0]*x+rots[best_rot][1][1]*y+rots[best_rot][1][2]*z+get<1>(best_trans),qz=rots[best_rot][2][0]*x+rots[best_rot][2][1]*y+rots[best_rot][2][2]*z+get<2>(best_trans);b[1-dir][qx][qy][qz]=n;src.erase({x,y,z});dst.erase({qx,qy,qz});}}return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr); start_time=high_resolution_clock::now();\n    generateRotations(); cin>>D; int f[2][15][15],r[2][15][15];\n    for(int i=0;i<2;i++){for(int z=0;z<D;z++){string s;cin>>s;for(int x=0;x<D;x++)f[i][z][x]=s[x]-'0';}for(int z=0;z<D;z++){string s;cin>>s;for(int y=0;y<D;y++)r[i][z][y]=s[y]-'0';}}\n    for(int i=0;i<2;i++)for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++)if(f[i][z][x]&&r[i][z][y])V[i].insert({x,y,z});\n    memset(b,0,sizeof(b)); n=0; PointSet rem[2]; rem[0]=V[0]; rem[1]=V[1];\n    auto ct=[&](){return duration_cast<milliseconds>(high_resolution_clock::now()-start_time).count();};\n    while(!rem[0].empty()&&!rem[1].empty()){if(ct()>2500)break;auto[rot,trans]=findBestAlignmentScored(rem[0],rem[1]);if(rot<0)break;extractAndAssign(rem,rot,trans);}\n    for(int dir=0;dir<2;dir++){if(rem[dir].empty()||rem[1-dir].empty())continue;\n        vector<vector<tuple<int,int,int>>> c;findComponents(rem[dir],c);sort(c.begin(),c.end(),[](auto&a,auto&b){return a.size()>b.size();});\n        for(auto&comp:c){if(ct()>4500)break;if(rem[1-dir].empty())break;tryCompAlignment(rem,comp,dir);}}\n    vector<vector<tuple<int,int,int>>> comps[2];findComponents(rem[0],comps[0]);findComponents(rem[1],comps[1]);\n    map<string,vector<pair<int,int>>> cm;vector<bool> cu[2];cu[0].resize(comps[0].size());cu[1].resize(comps[1].size());\n    for(int i=0;i<2;i++)for(int j=0;j<(int)comps[i].size();j++){auto&comp=comps[i][j];vector<tuple<int,int,int>> norm=comp;int mx=INT_MAX,my=INT_MAX,mz=INT_MAX;for(auto&[x,y,z]:norm){mx=min(mx,x);my=min(my,y);mz=min(mz,z);}for(auto&[x,y,z]:norm){x-=mx;y-=my;z-=mz;}cm[canonical(norm)].push_back({i,j});}\n    for(auto&[c,entries]:cm){vector<int> idx[2];for(auto&[obj,comp]:entries)idx[obj].push_back(comp);int p=min(idx[0].size(),idx[1].size());for(int k=0;k<p;k++){int i0=idx[0][k],i1=idx[1][k];cu[0][i0]=cu[1][i1]=true;n++;for(auto&[x,y,z]:comps[0][i0])b[0][x][y][z]=n;for(auto&[x,y,z]:comps[1][i1])b[1][x][y][z]=n;}}\n    for(int i=0;i<2;i++)for(int j=0;j<(int)comps[i].size();j++)if(!cu[i][j])for(auto&[x,y,z]:comps[i][j]){n++;b[i][x][y][z]=n;}\n    cout<<n<<'\\n';for(int i=0;i<2;i++){string out;for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){if(!out.empty())out+=' ';out+=to_string(b[i][x][y][z]);}cout<<out<<'\\n';}\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\ntypedef long long ll;\n\nstruct EdgeInfo { int to, idx; ll w; };\n\nint min_power(ll d2) {\n    if (d2 <= 0) return 0;\n    int r = (int)sqrt((double)d2);\n    while ((ll)r * r < d2) r++;\n    return r;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K;\n    cin >> N >> M >> K;\n    \n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    \n    vector<tuple<int, int, ll>> edges(M);\n    vector<vector<EdgeInfo>> adj(N);\n    for (int j = 0; j < M; j++) {\n        int u, v; ll w;\n        cin >> u >> v >> w;\n        u--; v--;\n        edges[j] = {u, v, w};\n        adj[u].push_back({v, j, w});\n        adj[v].push_back({u, j, w});\n    }\n    \n    vector<int> a(K), b(K);\n    for (int k = 0; k < K; k++) cin >> a[k] >> b[k];\n    \n    vector<vector<ll>> dist2(K, vector<ll>(N));\n    for (int k = 0; k < K; k++)\n        for (int i = 0; i < N; i++) {\n            ll dx = (ll)(x[i] - a[k]), dy = (ll)(y[i] - b[k]);\n            dist2[k][i] = dx * dx + dy * dy;\n        }\n    \n    vector<int> closest(K);\n    for (int k = 0; k < K; k++) {\n        ll min_d2 = LLONG_MAX; int mv = 0;\n        for (int i = 0; i < N; i++)\n            if (dist2[k][i] <= (ll)5000 * 5000 && dist2[k][i] < min_d2)\n                { min_d2 = dist2[k][i]; mv = i; }\n        closest[k] = mv;\n    }\n    \n    vector<bool> needed(N, false);\n    for (int k = 0; k < K; k++) needed[closest[k]] = true;\n    needed[0] = true;\n    \n    // Shortest path tree from vertex 0 (guaranteed connectivity)\n    vector<int> prev_edge(N, -1);\n    {\n        vector<ll> shortest_dist(N, LLONG_MAX);\n        shortest_dist[0] = 0;\n        priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<>> pq;\n        pq.push({0, 0});\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > shortest_dist[u]) continue;\n            for (auto& e : adj[u])\n                if (shortest_dist[u] + e.w < shortest_dist[e.to]) {\n                    shortest_dist[e.to] = shortest_dist[u] + e.w;\n                    prev_edge[e.to] = e.idx;\n                    pq.push({shortest_dist[e.to], e.to});\n                }\n        }\n    }\n    \n    // All-pairs shortest paths (for Steiner tree attempt)\n    vector<vector<ll>> sp_dist(N, vector<ll>(N, LLONG_MAX));\n    vector<vector<int>> sp_next(N, vector<int>(N, -1));\n    for (int s = 0; s < N; s++) {\n        sp_dist[s][s] = 0;\n        priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<>> pq;\n        pq.push({0, s});\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > sp_dist[s][u]) continue;\n            for (auto& e : adj[u])\n                if (sp_dist[s][u] + e.w < sp_dist[s][e.to]) {\n                    sp_dist[s][e.to] = sp_dist[s][u] + e.w;\n                    sp_next[s][e.to] = e.idx;\n                    pq.push({sp_dist[s][e.to], e.to});\n                }\n        }\n    }\n    \n    vector<int> needed_list;\n    for (int i = 0; i < N; i++) if (needed[i]) needed_list.push_back(i);\n    int nn = needed_list.size();\n    \n    // Build Steiner tree\n    vector<tuple<ll, int, int>> mst_edges;\n    for (int i = 0; i < nn; i++)\n        for (int j = i + 1; j < nn; j++)\n            if (sp_dist[needed_list[i]][needed_list[j]] < LLONG_MAX)\n                mst_edges.push_back({sp_dist[needed_list[i]][needed_list[j]], i, j});\n    \n    sort(mst_edges.begin(), mst_edges.end());\n    \n    vector<int> par(nn);\n    iota(par.begin(), par.end(), 0);\n    function<int(int)> find = [&](int x) { return par[x] == x ? x : par[x] = find(par[x]); };\n    \n    vector<tuple<ll, int, int>> mst_result;\n    for (auto& [d, i, j] : mst_edges)\n        if (find(i) != find(j)) {\n            par[find(i)] = find(j);\n            mst_result.push_back({d, i, j});\n        }\n    \n    vector<bool> edge_used(M, false);\n    for (auto& [d, i, j] : mst_result) {\n        int u = needed_list[i], v = needed_list[j];\n        int curr = u;\n        while (curr != v) {\n            int ei = sp_next[curr][v];\n            if (ei == -1) break;\n            edge_used[ei] = true;\n            curr = (get<0>(edges[ei]) == curr) ? get<1>(edges[ei]) : get<0>(edges[ei]);\n        }\n    }\n    \n    // Compute keep from Steiner tree\n    vector<bool> keep(N, false);\n    keep[0] = true;\n    bool changed = true;\n    while (changed) {\n        changed = false;\n        for (int idx = 0; idx < M; idx++)\n            if (edge_used[idx]) {\n                int u = get<0>(edges[idx]), v = get<1>(edges[idx]);\n                if (keep[u] && !keep[v]) { keep[v] = true; changed = true; }\n                if (keep[v] && !keep[u]) { keep[u] = true; changed = true; }\n            }\n    }\n    \n    // Check if all needed vertices are reachable\n    bool all_connected = true;\n    for (int i = 0; i < N; i++) {\n        if (needed[i] && !keep[i]) {\n            all_connected = false;\n            break;\n        }\n    }\n    \n    // Fallback to shortest path tree if not all connected\n    if (!all_connected) {\n        edge_used.assign(M, false);\n        for (int i = 0; i < N; i++)\n            if (needed[i] && i != 0) {\n                int v = i;\n                while (v != 0 && prev_edge[v] != -1) {\n                    edge_used[prev_edge[v]] = true;\n                    int ei = prev_edge[v];\n                    v = (get<0>(edges[ei]) == v) ? get<1>(edges[ei]) : get<0>(edges[ei]);\n                }\n            }\n        keep.assign(N, false);\n        keep[0] = true;\n        changed = true;\n        while (changed) {\n            changed = false;\n            for (int idx = 0; idx < M; idx++)\n                if (edge_used[idx]) {\n                    int u = get<0>(edges[idx]), v = get<1>(edges[idx]);\n                    if (keep[u] && !keep[v]) { keep[v] = true; changed = true; }\n                    if (keep[v] && !keep[u]) { keep[u] = true; changed = true; }\n                }\n        }\n    }\n    \n    // Compute power values\n    vector<int> P(N, 0);\n    for (int k = 0; k < K; k++) {\n        ll min_d2 = LLONG_MAX; int mv = -1;\n        for (int i = 0; i < N; i++)\n            if (keep[i] && dist2[k][i] <= (ll)5000 * 5000 && dist2[k][i] < min_d2)\n                { min_d2 = dist2[k][i]; mv = i; }\n        if (mv != -1) P[mv] = max(P[mv], min_power(min_d2) + 1);\n    }\n    \n    // Cap all power values at 5000\n    for (int i = 0; i < N; i++) P[i] = min(P[i], 5000);\n    \n    for (int i = 0; i < N; i++) cout << P[i] << \" \\n\"[i == N - 1];\n    for (int j = 0; j < M; j++) cout << edge_used[j] << \" \\n\"[j == M - 1];\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N = 30;\nint grid[30][30];\n\nvoid sift_down(int x, int y, vector<tuple<int,int,int,int>>& ops) {\n    while (x < N - 1 && ops.size() < 10000) {\n        int v = grid[x][y];\n        int c1 = grid[x+1][y];\n        int c2 = grid[x+1][y+1];\n        \n        if (v < c1 && v < c2) break;\n        \n        if (c1 <= c2) {\n            swap(grid[x][y], grid[x+1][y]);\n            ops.push_back({x, y, x+1, y});\n            x++;\n        } else {\n            swap(grid[x][y], grid[x+1][y+1]);\n            ops.push_back({x, y, x+1, y+1});\n            x++;\n            y++;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \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    vector<tuple<int,int,int,int>> ops;\n    \n    for (int pass = 0; pass < 50 && ops.size() < 10000; pass++) {\n        bool changed = false;\n        for (int x = N - 2; x >= 0 && ops.size() < 10000; x--) {\n            for (int y = 0; y <= x && ops.size() < 10000; y++) {\n                int v = grid[x][y];\n                if (v < grid[x+1][y] && v < grid[x+1][y+1]) continue;\n                sift_down(x, y, ops);\n                changed = true;\n            }\n        }\n        if (!changed) break;\n    }\n    \n    cout << ops.size() << \"\\n\";\n    for (auto& [x1, y1, x2, y2] : ops) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << \"\\n\";\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D, N;\nint grid[9][9];\nint container_num[9][9];\nint bfs_dist[9][9];\nint di[] = {0, 0, 1, -1}, dj[] = {1, -1, 0, 0};\nint entrance_i = 0, entrance_j;\nvector<pair<int,int>> all_cells;\n\nvoid compute_bfs_dist() {\n    queue<pair<int,int>> q;\n    memset(bfs_dist, -1, sizeof(bfs_dist));\n    bfs_dist[entrance_i][entrance_j] = 0;\n    q.push({entrance_i, entrance_j});\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int ni = i + di[d], nj = j + dj[d];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && bfs_dist[ni][nj] == -1 && grid[ni][nj] != 1) {\n                bfs_dist[ni][nj] = bfs_dist[i][j] + 1;\n                q.push({ni, nj});\n            }\n        }\n    }\n    for (int i = 0; i < D; i++)\n        for (int j = 0; j < D; j++)\n            if ((i != entrance_i || j != entrance_j) && grid[i][j] != 1)\n                all_cells.push_back({i, j});\n    sort(all_cells.begin(), all_cells.end(), [](auto& a, auto& b) {\n        return tie(bfs_dist[a.first][a.second], a.first, a.second) < tie(bfs_dist[b.first][b.second], b.first, b.second);\n    });\n}\n\nvoid bfs_empty(int visited[9][9]) {\n    queue<pair<int,int>> q;\n    visited[entrance_i][entrance_j] = 1;\n    q.push({entrance_i, entrance_j});\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int ni = i + di[d], nj = j + dj[d];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && !visited[ni][nj] && grid[ni][nj] == 0) {\n                visited[ni][nj] = 1;\n                q.push({ni, nj});\n            }\n        }\n    }\n}\n\nvector<pair<int,int>> get_reachable_empty() {\n    int visited[9][9] = {};\n    bfs_empty(visited);\n    vector<pair<int,int>> cells;\n    for (int i = 0; i < D; i++)\n        for (int j = 0; j < D; j++)\n            if (visited[i][j] && !(i == entrance_i && j == entrance_j))\n                cells.push_back({i, j});\n    return cells;\n}\n\nvector<pair<int,int>> get_reachable_containers() {\n    int visited[9][9] = {};\n    bfs_empty(visited);\n    vector<pair<int,int>> cells;\n    for (int i = 0; i < D; i++)\n        for (int j = 0; j < D; j++)\n            if (grid[i][j] == 2)\n                for (int d = 0; d < 4; d++) {\n                    int ni = i + di[d], nj = j + dj[d];\n                    if (ni >= 0 && ni < D && nj >= 0 && nj < D && visited[ni][nj]) {\n                        cells.push_back({i, j});\n                        break;\n                    }\n                }\n    return cells;\n}\n\nbool is_safe(int pi, int pj, int orig_empty_count) {\n    grid[pi][pj] = 2;\n    int visited[9][9] = {};\n    bfs_empty(visited);\n    grid[pi][pj] = 0;\n    int new_empty = 0;\n    for (int i = 0; i < D; i++)\n        for (int j = 0; j < D; j++)\n            if (visited[i][j] && !(i == entrance_i && j == entrance_j))\n                new_empty++;\n    return new_empty == orig_empty_count - 1;\n}\n\npair<int,int> find_placement(int t) {\n    auto empty_cells = get_reachable_empty();\n    int orig_empty_count = empty_cells.size();\n    int ideal_dist = bfs_dist[all_cells[t].first][all_cells[t].second];\n    \n    auto cmp = [&](const auto& a, const auto& b) {\n        int da = abs(bfs_dist[a.first][a.second] - ideal_dist);\n        int db = abs(bfs_dist[b.first][b.second] - ideal_dist);\n        return da != db ? da < db : a < b;\n    };\n    \n    vector<pair<int,int>> safe_cells;\n    for (auto& cell : empty_cells)\n        if (is_safe(cell.first, cell.second, orig_empty_count))\n            safe_cells.push_back(cell);\n    \n    if (safe_cells.empty()) return empty_cells[0];\n    \n    sort(safe_cells.begin(), safe_cells.end(), cmp);\n    return safe_cells[0];\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> D >> N;\n    entrance_j = (D - 1) / 2;\n    memset(grid, 0, sizeof(grid));\n    memset(container_num, -1, sizeof(container_num));\n    for (int i = 0; i < N; i++) { int ri, rj; cin >> ri >> rj; grid[ri][rj] = 1; }\n    int total = D * D - 1 - N;\n    compute_bfs_dist();\n    for (int d = 0; d < total; d++) {\n        int t; cin >> t;\n        auto [pi, pj] = find_placement(t);\n        grid[pi][pj] = 2;\n        container_num[pi][pj] = t;\n        cout << pi << \" \" << pj << \"\\n\" << flush;\n    }\n    for (int d = 0; d < total; d++) {\n        auto containers = get_reachable_containers();\n        int best_num = INT_MAX;\n        pair<int,int> best_pos = containers[0];\n        for (auto& [i, j] : containers)\n            if (container_num[i][j] < best_num) { best_num = container_num[i][j]; best_pos = {i, j}; }\n        grid[best_pos.first][best_pos.second] = 0;\n        cout << best_pos.first << \" \" << best_pos.second << \"\\n\" << flush;\n    }\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n, m;\nint grid[50][50], original_grid[50][50];\nset<int> adj_set[101];\nset<pair<int,int>> original_adj;\nvector<pair<int,int>> color_pos[101];\nint adj_cnt[101][101], color_cnt[101];\nint dr[] = {0, 0, 1, -1}, dc[] = {1, -1, 0, 0};\nint vis_gen[50][50], cur_gen = 0;\n\nbool is_connected(int color, int er, int ec) {\n    int cnt = color_cnt[color] - 1;\n    if (cnt <= 1) return true;\n    cur_gen++;\n    int sr = -1, sc = -1;\n    for (auto& [i, j] : color_pos[color]) {\n        if (grid[i][j] != color || (i == er && j == ec)) continue;\n        sr = i; sc = j; break;\n    }\n    if (sr == -1) return true;\n    queue<pair<int,int>> q;\n    q.push({sr, sc}); vis_gen[sr][sc] = cur_gen; int vc = 1;\n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nr = r + dr[d], nc = c + dc[d];\n            if (nr < 0 || nr >= n || nc < 0 || nc >= n) continue;\n            if (vis_gen[nr][nc] == cur_gen || (nr == er && nc == ec)) continue;\n            if (grid[nr][nc] == color) { vis_gen[nr][nc] = cur_gen; vc++; q.push({nr, nc}); }\n        }\n    }\n    return vc == cnt;\n}\n\nbool can_remove(int r, int c) {\n    int color = grid[r][c];\n    if (color == 0 || color_cnt[color] <= 1) return false;\n    int same = 0, zero_here = 0, diff_nb[101] = {};\n    for (int d = 0; d < 4; d++) {\n        int nr = r + dr[d], nc = c + dc[d];\n        if (nr < 0 || nr >= n || nc < 0 || nc >= n) zero_here++;\n        else if (grid[nr][nc] == color) same++;\n        else if (grid[nr][nc] == 0) zero_here++;\n        else diff_nb[grid[nr][nc]]++;\n    }\n    if (same == 0 || !adj_set[0].count(color)) return false;\n    if (r != 0 && r != n-1 && c != 0 && c != n-1) {\n        bool conn = false;\n        for (int d = 0; d < 4; d++) { int nr = r+dr[d], nc = c+dc[d]; if (nr>=0&&nr<n&&nc>=0&&nc<n&&grid[nr][nc]==0) { conn=true; break; } }\n        if (!conn) return false;\n    }\n    if (adj_cnt[color][0] + same - zero_here <= 0) return false;\n    if (!is_connected(color, r, c)) return false;\n    for (int nb = 1; nb <= m; nb++) {\n        if (diff_nb[nb] == 0) continue;\n        if (!adj_set[0].count(nb) || adj_cnt[color][nb] - diff_nb[nb] <= 0) return false;\n    }\n    return true;\n}\n\nvoid remove_tile(int r, int c) {\n    int color = grid[r][c];\n    for (int d = 0; d < 4; d++) {\n        int nr = r + dr[d], nc = c + dc[d];\n        if (nr < 0 || nr >= n || nc < 0 || nc >= n) adj_cnt[color][0]--;\n        else {\n            int nb = grid[nr][nc];\n            if (nb == color) adj_cnt[color][0]++;\n            else if (nb == 0) adj_cnt[color][0]--;\n            else { adj_cnt[color][nb]--; adj_cnt[nb][color]--; adj_cnt[nb][0]++; }\n        }\n    }\n    grid[r][c] = 0; color_cnt[color]--;\n}\n\nbool verify() {\n    set<pair<int,int>> out;\n    for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) {\n        int c = grid[i][j];\n        for (int d = 0; d < 4; d++) { int nr=i+dr[d],nc=j+dc[d]; int nb=(nr<0||nr>=n||nc<0||nc>=n)?0:grid[nr][nc]; if(nb!=c) out.insert({min(c,nb),max(c,nb)}); }\n    }\n    if (original_adj != out) return false;\n    for (int c = 1; c <= m; c++) {\n        cur_gen++; int cnt=0,sr=-1,sc=-1;\n        for (auto& [i,j] : color_pos[c]) { if(grid[i][j]!=c) continue; if(sr<0){sr=i;sc=j;} cnt++; }\n        if (!cnt) return false;\n        if (cnt == 1) continue;\n        queue<pair<int,int>> q; q.push({sr,sc}); vis_gen[sr][sc]=cur_gen; int vc=1;\n        while (!q.empty()) { auto[r,cc]=q.front(); q.pop(); for(int d=0;d<4;d++){int nr=r+dr[d],nc=cc+dc[d]; if(nr<0||nr>=n||nc<0||nc>=n||vis_gen[nr][nc]==cur_gen) continue; if(grid[nr][nc]==c){vis_gen[nr][nc]=cur_gen;vc++;q.push({nr,nc});}} }\n        if (vc != cnt) return false;\n    }\n    cur_gen++; queue<pair<int,int>> q; int zcnt=0;\n    for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) if(grid[i][j]==0){zcnt++; if(i==0||i==n-1||j==0||j==n-1){q.push({i,j});vis_gen[i][j]=cur_gen;}}\n    while(!q.empty()){auto[r,c]=q.front();q.pop();zcnt--;for(int d=0;d<4;d++){int nr=r+dr[d],nc=c+dc[d];if(nr<0||nr>=n||nc<0||nc>=n||vis_gen[nr][nc]==cur_gen||grid[nr][nc]!=0)continue;vis_gen[nr][nc]=cur_gen;q.push({nr,nc});}}\n    return zcnt == 0;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(NULL);\n    cin >> n >> m;\n    for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { cin >> grid[i][j]; original_grid[i][j]=grid[i][j]; color_pos[grid[i][j]].push_back({i,j}); }\n    for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) {\n        int c = grid[i][j];\n        for (int d = 0; d < 4; d++) { int nr=i+dr[d],nc=j+dc[d]; int nb=(nr<0||nr>=n||nc<0||nc>=n)?0:grid[nr][nc]; if(nb!=c){adj_cnt[c][nb]++;adj_set[c].insert(nb);adj_set[nb].insert(c);original_adj.insert({min(c,nb),max(c,nb)});} }\n    }\n    memset(color_cnt,0,sizeof(color_cnt));\n    for(int i=0;i<n;i++) for(int j=0;j<n;j++) color_cnt[grid[i][j]]++;\n    bool changed = true;\n    while (changed) {\n        changed = false;\n        for (int c = 1; c <= m; c++) {\n            if (!adj_set[0].count(c)) continue;\n            vector<tuple<int,int,int>> tiles;\n            for (auto& [i,j] : color_pos[c]) { if(grid[i][j]!=c) continue; int s=0; for(int d=0;d<4;d++){int nr=i+dr[d],nc=j+dc[d]; if(nr>=0&&nr<n&&nc>=0&&nc<n&&grid[nr][nc]==c)s++;} tiles.push_back({s,i,j}); }\n            sort(tiles.begin(), tiles.end());\n            for (auto& [_,r,cc] : tiles) { if(grid[r][cc]!=c) continue; if(can_remove(r,cc)){remove_tile(r,cc);changed=true;} }\n        }\n    }\n    if (!verify()) memcpy(grid, original_grid, sizeof(grid));\n    for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { cout << grid[i][j]; if(j<n-1) cout<<\" \"; } cout<<\"\\n\"; }\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <numeric>\n\nusing namespace std;\n\nint N, D, Q;\n\nchar query(int x, int y) {\n    cout << \"1 1 \" << x << \" \" << y << \"\\n\" << flush;\n    char res;\n    cin >> res;\n    return res;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    if (!(cin >> N >> D >> Q)) return 0;\n    \n    // Distribute queries equally among all items to guarantee none are left unqueried\n    int B = Q / N;\n    if (B == 0) B = 1; // Safety check for edge cases\n    \n    vector<vector<int>> adj(N);\n    vector<int> sorted_items;\n    vector<int> unsorted_items;\n    for (int i = 0; i < N; ++i) {\n        unsorted_items.push_back(i);\n    }\n    \n    int q_left = Q;\n    \n    while (!unsorted_items.empty()) {\n        int x = unsorted_items.back();\n        unsorted_items.pop_back();\n        \n        if (!sorted_items.empty()) {\n            int lo = 0, hi = sorted_items.size();\n            int steps = 0;\n            // Bounded binary insertion: strictly limit to B queries per item\n            while (steps < B && lo < hi) {\n                int mid = (lo + hi) / 2;\n                int y = sorted_items[mid];\n                q_left--;\n                steps++;\n                char res = query(x, y);\n                if (res == '>') {\n                    adj[y].push_back(x); // x is heavier than y\n                    lo = mid + 1;\n                } else if (res == '<') {\n                    adj[x].push_back(y); // x is lighter than y\n                    hi = mid;\n                } else {\n                    break;\n                }\n            }\n            sorted_items.insert(sorted_items.begin() + lo, x);\n        } else {\n            if (!unsorted_items.empty()) {\n                int y = unsorted_items.back();\n                unsorted_items.pop_back();\n                q_left--;\n                char res = query(x, y);\n                if (res == '>') {\n                    adj[y].push_back(x);\n                    sorted_items.push_back(y);\n                    sorted_items.push_back(x);\n                } else if (res == '<') {\n                    adj[x].push_back(y);\n                    sorted_items.push_back(x);\n                    sorted_items.push_back(y);\n                } else {\n                    sorted_items.push_back(x);\n                    sorted_items.push_back(y);\n                }\n            } else {\n                sorted_items.push_back(x);\n            }\n        }\n    }\n    \n    // Fulfill remaining query quota with dummy queries if B was generous\n    while (q_left > 0) {\n        query(0, 1);\n        q_left--;\n    }\n    \n    // Compute longest path from sources in the DAG using Kahn's algorithm\n    vector<int> in_degree(N, 0);\n    for (int i = 0; i < N; ++i) {\n        for (int j : adj[i]) {\n            in_degree[j]++;\n        }\n    }\n    \n    queue<int> q;\n    for (int i = 0; i < N; ++i) {\n        if (in_degree[i] == 0) q.push(i);\n    }\n    \n    vector<int> dp(N, 0);\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : adj[u]) {\n            if (dp[v] < dp[u] + 1) {\n                dp[v] = dp[u] + 1;\n            }\n            in_degree[v]--;\n            if (in_degree[v] == 0) {\n                q.push(v);\n            }\n        }\n    }\n    \n    // Sort all items by their longest path value (ascending)\n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n    sort(items.begin(), items.end(), [&](int a, int b) {\n        if (dp[a] != dp[b]) return dp[a] < dp[b];\n        return a < b; // Tie-breaker\n    });\n    \n    // Map ranks to expected weights of exponential distribution order statistics\n    double W_max = 100000.0 * N / D;\n    vector<double> expected_w(N);\n    double sum = 0;\n    for (int i = 0; i < N; ++i) {\n        sum += 100000.0 / (N - i);\n        expected_w[i] = min(sum, W_max);\n    }\n    \n    // Greedy partitioning based on expected weights\n    vector<double> set_sums(D, 0);\n    vector<int> partition(N);\n    double total_sum = accumulate(expected_w.begin(), expected_w.end(), 0.0);\n    double target_sum = total_sum / D;\n    \n    // Process from largest expected weight to smallest\n    for (int i = N - 1; i >= 0; --i) {\n        int item = items[i];\n        double w = expected_w[i];\n        \n        int best_set = -1;\n        double max_deficit = 0;\n        for (int j = 0; j < D; ++j) {\n            double deficit = target_sum - set_sums[j];\n            if (deficit > max_deficit) {\n                max_deficit = deficit;\n                best_set = j;\n            }\n        }\n        \n        // Fallback if all sets exceed the target sum\n        if (best_set == -1) {\n            best_set = 0;\n            for (int j = 1; j < D; ++j) {\n                if (set_sums[j] < set_sums[best_set]) {\n                    best_set = j;\n                }\n            }\n        }\n        \n        set_sums[best_set] += w;\n        partition[item] = best_set;\n    }\n    \n    // Output the final division mapping\n    for (int i = 0; i < N; ++i) {\n        cout << partition[i] << (i == N - 1 ? \"\" : \" \");\n    }\n    cout << \"\\n\" << flush;\n    \n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> stacks(m);\n    vector<int> pos(n + 1), idx(n + 1);\n    \n    for (int i = 0; i < m; i++) {\n        stacks[i].resize(n / m);\n        for (int j = 0; j < n / m; j++) {\n            cin >> stacks[i][j];\n            pos[stacks[i][j]] = i;\n            idx[stacks[i][j]] = j;\n        }\n    }\n    \n    vector<bool> isClean(m, true);\n    for (int i = 0; i < m; i++) {\n        for (int j = 0; j < (int)stacks[i].size() - 1; j++) {\n            if (stacks[i][j] < stacks[i][j + 1]) { isClean[i] = false; break; }\n        }\n    }\n    \n    auto updateClean = [&](int s) {\n        isClean[s] = true;\n        for (int j = 0; j < (int)stacks[s].size() - 1; j++) {\n            if (stacks[s][j] < stacks[s][j + 1]) { isClean[s] = false; break; }\n        }\n    };\n    \n    vector<pair<int, int>> operations;\n    int nextBox = 1;\n    \n    while (nextBox <= n) {\n        int si = pos[nextBox], pi = idx[nextBox];\n        \n        if (pi == (int)stacks[si].size() - 1) {\n            operations.push_back({nextBox, 0});\n            stacks[si].pop_back();\n            updateClean(si);\n            nextBox++;\n        } else {\n            vector<int> seq(stacks[si].begin() + pi + 1, stacks[si].end());\n            \n            vector<int> splitAfter;\n            for (int i = 0; i < (int)seq.size() - 1; i++) {\n                if (seq[i] < seq[i + 1]) splitAfter.push_back(i);\n            }\n            \n            vector<vector<int>> pieces;\n            int start = 0;\n            for (int sp : splitAfter) {\n                pieces.push_back(vector<int>(seq.begin() + start, seq.begin() + sp + 1));\n                start = sp + 1;\n            }\n            pieces.push_back(vector<int>(seq.begin() + start, seq.end()));\n            reverse(pieces.begin(), pieces.end());\n            \n            for (auto& piece : pieces) {\n                int moveFrom = piece[0];\n                int origStack = pos[moveFrom];\n                \n                int bestDest = -1, bestScore = -1e9;\n                for (int i = 0; i < m; i++) {\n                    if (i == origStack) continue;\n                    int score;\n                    if (stacks[i].empty()) {\n                        score = 350;\n                    } else if (isClean[i] && stacks[i].back() >= moveFrom) {\n                        score = 601 - stacks[i].back();\n                    } else if (stacks[i].back() >= moveFrom) {\n                        score = 201 - stacks[i].back();\n                    } else {\n                        score = -999 + stacks[i].back();\n                    }\n                    if (score > bestScore || (score == bestScore && bestDest != -1 && stacks[i].size() < stacks[bestDest].size())) {\n                        bestScore = score; bestDest = i;\n                    }\n                }\n                \n                bool wasEmpty = stacks[bestDest].empty();\n                bool wasCleanDest = isClean[bestDest];\n                int oldBack = wasEmpty ? -1 : stacks[bestDest].back();\n                bool compatible = wasEmpty || (oldBack >= moveFrom);\n                \n                operations.push_back({moveFrom, bestDest + 1});\n                \n                int origIdx = idx[moveFrom];\n                for (int j = origIdx; j < (int)stacks[origStack].size(); j++) {\n                    int v = stacks[origStack][j];\n                    stacks[bestDest].push_back(v);\n                    pos[v] = bestDest;\n                    idx[v] = stacks[bestDest].size() - 1;\n                }\n                stacks[origStack].resize(origIdx);\n                \n                isClean[bestDest] = wasEmpty ? true : (wasCleanDest && compatible);\n                updateClean(origStack);\n            }\n        }\n    }\n    \n    for (auto& op : operations) cout << op.first << \" \" << op.second << \"\\n\";\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> h, v;\nint di[] = {0, 1, 0, -1};\nint dj[] = {1, 0, -1, 0};\nchar dc[] = \"RDLU\";\n\nbool can_move(int i, int j, int dir) {\n    int ni = i + di[dir], nj = j + dj[dir];\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    if (dir == 0) return v[i][j] == '0';\n    if (dir == 1) return h[i][j] == '0';\n    if (dir == 2) return v[i][nj] == '0';\n    return h[ni][j] == '0';\n}\n\nvoid dfs(int i, int j, string& route, vector<vector<bool>>& visited) {\n    visited[i][j] = true;\n    for (int dir = 0; dir < 4; dir++) {\n        if (can_move(i, j, dir)) {\n            int ni = i + di[dir], nj = j + dj[dir];\n            if (!visited[ni][nj]) {\n                route += dc[dir];\n                dfs(ni, nj, route, visited);\n                route += dc[(dir + 2) % 4];\n            }\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N;\n    h.resize(N-1); v.resize(N);\n    for (int i = 0; i < N-1; i++) cin >> h[i];\n    for (int i = 0; i < N; i++) cin >> v[i];\n    vector<vector<int>> d(N, vector<int>(N));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cin >> d[i][j];\n    \n    string route;\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    dfs(0, 0, route, visited);\n    cout << route << endl;\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n, m, si, sj;\nchar grid[16][16];\nstring words[205];\nint cx[26][16][16], cy[26][16][16], cd[26][16][16];\nvector<pair<int,int>> cells[26];\n\nconst int MAXN = 1100;\nint trie[MAXN][26], fail_link[MAXN], node_cnt;\nvector<int> out[MAXN];\n\nvoid insert(const string& s, int id) {\n    int cur = 0;\n    for (char c : s) {\n        int ch = c - 'A';\n        if (!trie[cur][ch]) trie[cur][ch] = ++node_cnt;\n        cur = trie[cur][ch];\n    }\n    out[cur].push_back(id);\n}\n\nvoid build() {\n    queue<int> q;\n    for (int c = 0; c < 26; c++) {\n        if (trie[0][c]) { fail_link[trie[0][c]] = 0; q.push(trie[0][c]); }\n        else trie[0][c] = 0;\n    }\n    while (!q.empty()) {\n        int v = q.front(); q.pop();\n        for (int c = 0; c < 26; c++) {\n            if (trie[v][c]) {\n                fail_link[trie[v][c]] = trie[fail_link[v]][c];\n                for (int id : out[fail_link[trie[v][c]]]) out[trie[v][c]].push_back(id);\n                q.push(trie[v][c]);\n            } else trie[v][c] = trie[fail_link[v]][c];\n        }\n    }\n}\n\nbool was[MAXN][205]; int overlap[MAXN][205];\nvoid precompute() {\n    for (int st = 0; st <= node_cnt; st++) {\n        for (int id : out[st]) was[st][id] = true;\n        for (int w = 0; w < m; w++) {\n            int cur = st, need = 0; bool found = false;\n            for (int i = 0; i < 5; i++) {\n                cur = trie[cur][words[w][i]-'A']; need++;\n                if (was[cur][w]) { found = true; break; }\n            }\n            overlap[st][w] = found ? need : 6;\n        }\n    }\n}\n\nint dp[6][16][16];\npair<int,int> from_arr[6][16][16];\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> n >> m >> si >> sj;\n    for (int i = 0; i < n; i++) { string r; cin >> r; for (int j = 0; j < n; j++) { grid[i][j] = r[j]; cells[r[j]-'A'].push_back({i, j}); } }\n    for (int i = 0; i < m; i++) { cin >> words[i]; insert(words[i], i); }\n    build(); precompute();\n    const int INF = 1e9;\n    for (int c = 0; c < 26; c++) for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) {\n        cd[c][i][j] = INF;\n        for (auto& [x, y] : cells[c]) { int d = abs(i-x)+abs(j-y); if (d < cd[c][i][j]) { cd[c][i][j]=d; cx[c][i][j]=x; cy[c][i][j]=y; } }\n    }\n    \n    int ci=si, cj=sj, st=0, done_cnt=0; \n    vector<bool> done(m,false); \n    vector<pair<int,int>> ops;\n    \n    while (done_cnt < m && (int)ops.size() < 5000) {\n        int best_w = -1, best_k = -1, best_end_x = -1, best_end_y = -1;\n        double best_score = 1e18;\n        \n        for (int w = 0; w < m; w++) {\n            if (done[w]) continue;\n            int k = overlap[st][w];\n            if (k < 1 || k > 5) continue;\n            \n            int new_st = st;\n            bool completed[205] = {};\n            for (int i = 0; i < k; i++) {\n                new_st = trie[new_st][words[w][5-k+i]-'A'];\n                for (int id : out[new_st]) completed[id] = true;\n            }\n            \n            for(int step=0; step<=k; step++) for(int i=0; i<n; i++) for(int j=0; j<n; j++) dp[step][i][j] = INF;\n            dp[0][ci][cj] = 0;\n            for (int step = 1; step <= k; step++) {\n                int c = words[w][5 - k + step - 1] - 'A';\n                for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) {\n                    if (dp[step-1][i][j] == INF) continue;\n                    for (auto& [nx, ny] : cells[c]) {\n                        int nc = dp[step-1][i][j] + abs(i-nx) + abs(j-ny) + 1;\n                        if (nc < dp[step][nx][ny]) dp[step][nx][ny] = nc;\n                    }\n                }\n            }\n            \n            for (auto& [ex, ey] : cells[words[w][4]-'A']) {\n                if (dp[k][ex][ey] >= INF) continue;\n                int cost1 = dp[k][ex][ey];\n                \n                int min_future = INF;\n                for (int w2 = 0; w2 < m; w2++) {\n                    if (done[w2] || completed[w2]) continue;\n                    int k2 = overlap[new_st][w2];\n                    int start_idx = (k2 >= 1 && k2 <= 5) ? (5 - k2) : 0;\n                    int num_chars = (k2 >= 1 && k2 <= 5) ? k2 : 5;\n                    int est = 0, tx = ex, ty = ey;\n                    for (int i = 0; i < num_chars; i++) {\n                        int c = words[w2][start_idx + i] - 'A';\n                        if (cd[c][tx][ty] >= INF) { est = INF; break; }\n                        est += cd[c][tx][ty] + 1;\n                        tx = cx[c][tx][ty]; ty = cy[c][tx][ty];\n                    }\n                    min_future = min(min_future, est);\n                }\n                \n                double score = cost1 + 0.4 * min_future;\n                if (score < best_score) {\n                    best_score = score;\n                    best_w = w; best_k = k; best_end_x = ex; best_end_y = ey;\n                }\n            }\n        }\n        \n        if (best_w == -1) {\n            int best_fw = -1, best_fc = INF;\n            for (int w = 0; w < m; w++) { \n                if (done[w]) continue; \n                int est = 0, tx = ci, ty = cj;\n                for (int i = 0; i < 5; i++) {\n                    int c = words[w][i]-'A';\n                    if (cd[c][tx][ty] >= INF) { est = INF; break; }\n                    est += cd[c][tx][ty] + 1;\n                    tx = cx[c][tx][ty]; ty = cy[c][tx][ty];\n                }\n                if (est < best_fc) { best_fc = est; best_fw = w; }\n            }\n            if (best_fw == -1) break;\n            best_w = best_fw; best_k = 5;\n        }\n        \n        if (best_w == -1) break;\n        \n        int k = best_k;\n        for(int step=0; step<=k; step++) for(int i=0; i<n; i++) for(int j=0; j<n; j++) dp[step][i][j] = INF;\n        dp[0][ci][cj] = 0;\n        for (int step = 1; step <= k; step++) { \n            int c = words[best_w][5 - k + step - 1] - 'A';\n            for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { \n                if (dp[step-1][i][j] == INF) continue;\n                for (auto& [nx, ny] : cells[c]) { \n                    int nc = dp[step-1][i][j] + abs(i-nx) + abs(j-ny) + 1;\n                    if (nc < dp[step][nx][ny]) { dp[step][nx][ny] = nc; from_arr[step][nx][ny] = {i, j}; } \n                } \n            } \n        }\n        \n        if (best_end_x == -1) {\n            int min_cost = INF;\n            for (auto& [nx, ny] : cells[words[best_w][4]-'A']) {\n                if (dp[k][nx][ny] < min_cost) { min_cost = dp[k][nx][ny]; best_end_x = nx; best_end_y = ny; }\n            }\n        }\n        \n        vector<pair<int,int>> path; \n        int cur_x = best_end_x, cur_y = best_end_y;\n        for (int step = k; step >= 1; step--) { path.push_back({cur_x, cur_y}); auto [px, py] = from_arr[step][cur_x][cur_y]; cur_x = px; cur_y = py; }\n        reverse(path.begin(), path.end());\n        \n        if ((int)ops.size() + (int)path.size() > 5000) { int rem = 5000 - ops.size(); for (int i = 0; i < rem; i++) ops.push_back(path[i]); break; }\n        \n        for (auto& [x, y] : path) { ops.push_back({x, y}); st = trie[st][grid[x][y]-'A']; for (int id : out[st]) if (!done[id]) { done[id] = true; done_cnt++; } }\n        ci = best_end_x; cj = best_end_y;\n    }\n    \n    for (auto& [x,y] : ops) cout << x << \" \" << y << \"\\n\";\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M; double eps;\n    cin >> N >> M >> eps;\n    \n    vector<vector<pair<int,int>>> norm_fields(M);\n    vector<int> field_w(M), field_h(M);\n    for (int k = 0; k < M; k++) {\n        int d; cin >> d;\n        vector<pair<int,int>> raw(d);\n        int mi = N, mj = N;\n        for (int i = 0; i < d; i++) {\n            cin >> raw[i].first >> raw[i].second;\n            mi = min(mi, raw[i].first);\n            mj = min(mj, raw[i].second);\n        }\n        for (int i = 0; i < d; i++) {\n            norm_fields[k].push_back({raw[i].first - mi, raw[i].second - mj});\n            field_w[k] = max(field_w[k], raw[i].first - mi);\n            field_h[k] = max(field_h[k], raw[i].second - mj);\n        }\n    }\n    \n    vector<vector<int>> known(N, vector<int>(N, -1));\n    vector<pair<int,int>> has_oil;\n    \n    auto drill = [&](int i, int j) -> int {\n        if (known[i][j] != -1) return known[i][j];\n        cout << \"q 1 \" << i << \" \" << j << \"\\n\" << flush;\n        int r; cin >> r;\n        known[i][j] = r;\n        if (r > 0) has_oil.push_back({i, j});\n        return r;\n    };\n    \n    auto divine = [&](vector<pair<int,int>> &sq) -> int {\n        if (sq.size() < 2) return -1;\n        cout << \"q \" << sq.size();\n        for (auto [i, j] : sq) cout << \" \" << i << \" \" << j;\n        cout << \"\\n\" << flush;\n        int r; cin >> r;\n        return r;\n    };\n    \n    int bs = (N >= 15) ? 7 : 5;\n    int nbi = (N + bs - 1) / bs, nbj = (N + bs - 1) / bs;\n    vector<vector<bool>> skip(nbi, vector<bool>(nbj, false));\n    \n    for (int bi = 0; bi < nbi; bi++) for (int bj = 0; bj < nbj; bj++) {\n        vector<pair<int,int>> blk;\n        for (int i = bi*bs; i < min(N,(bi+1)*bs); i++)\n            for (int j = bj*bs; j < min(N,(bj+1)*bs); j++)\n                blk.push_back({i, j});\n        if (blk.size() < 2) continue;\n        if (divine(blk) == 0) skip[bi][bj] = true;\n    }\n    \n    for (int bi = 0; bi < nbi; bi++) for (int bj = 0; bj < nbj; bj++) {\n        if (skip[bi][bj]) continue;\n        for (int i = bi*bs; i < min(N,(bi+1)*bs); i++)\n            for (int j = bj*bs; j < min(N,(bj+1)*bs); j++)\n                drill(i, j);\n    }\n    \n    for (int iter = 0; iter < 3 && !has_oil.empty(); iter++) {\n        vector<vector<int>> cnt(N, vector<int>(N, 0));\n        for (int k = 0; k < M; k++) {\n            for (int di = 0; di <= N - 1 - field_w[k]; di++) {\n                for (int dj = 0; dj <= N - 1 - field_h[k]; dj++) {\n                    bool ok = true;\n                    for (auto [si, sj] : norm_fields[k])\n                        if (known[di+si][dj+sj] == 0) { ok = false; break; }\n                    if (!ok) continue;\n                    for (auto [si, sj] : norm_fields[k])\n                        if (known[di+si][dj+sj] == -1) cnt[di+si][dj+sj]++;\n                }\n            }\n        }\n        vector<pair<int,pair<int,int>>> todo;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++)\n            if (cnt[i][j] > 0) todo.push_back({-cnt[i][j], {i, j}});\n        sort(todo.begin(), todo.end());\n        for (auto [_, p] : todo) drill(p.first, p.second);\n    }\n    \n    cout << \"a \" << has_oil.size();\n    for (auto [i, j] : has_oil) cout << \" \" << i << \" \" << j;\n    cout << \"\\n\" << flush;\n    int resp; cin >> resp;\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W, D, N;\n    cin >> W >> D >> N;\n    \n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; d++)\n        for (int k = 0; k < N; k++) cin >> a[d][k];\n    \n    if (N == 1) {\n        for (int d = 0; d < D; d++) cout << \"0 0 \" << W << \" \" << W << \"\\n\";\n        return 0;\n    }\n    \n    auto compute_parts = [&](const vector<int>& areas) {\n        vector<int> req(N);\n        for (int k = 0; k < N; k++) req[k] = (areas[k] + W - 1) / W;\n        vector<int> heights = req;\n        long long total = accumulate(heights.begin(), heights.end(), 0LL);\n        long long excess = total - W;\n        if (excess > 0) {\n            for (int k = N-1; k >= 0 && excess > 0; k--) {\n                int min_h = (k == 0) ? 1 : heights[k-1];\n                long long reduce = min(excess, (long long)(heights[k] - min_h));\n                heights[k] -= reduce;\n                excess -= reduce;\n            }\n        }\n        vector<int> parts(N-1);\n        long long cum = 0;\n        for (int k = 0; k < N-1; k++) { cum += heights[k]; parts[k] = cum; }\n        return parts;\n    };\n    \n    auto get_heights = [&](const vector<int>& parts) {\n        vector<int> h(N);\n        h[0] = parts[0];\n        for (int k = 1; k < N-1; k++) h[k] = parts[k] - parts[k-1];\n        h[N-1] = W - parts[N-2];\n        return h;\n    };\n    \n    auto deficit_sorted = [&](const vector<int>& areas, vector<int> heights) {\n        sort(heights.begin(), heights.end());\n        long long def = 0;\n        for (int k = 0; k < N; k++)\n            def += max(0LL, (long long)areas[k] - (long long)heights[k] * W);\n        return def;\n    };\n    \n    auto output_new = [&](const vector<int>& parts) {\n        for (int k = 0; k < N; k++) {\n            int s = k == 0 ? 0 : parts[k-1];\n            int e = k < N-1 ? parts[k] : W;\n            cout << s << \" 0 \" << e << \" \" << W << \"\\n\";\n        }\n    };\n    \n    auto output_keep = [&](const vector<int>& parts) {\n        auto heights = get_heights(parts);\n        vector<pair<int,int>> hp(N);\n        for (int k = 0; k < N; k++) hp[k] = {heights[k], k};\n        sort(hp.begin(), hp.end());\n        for (int i = 0; i < N; i++) {\n            int s = hp[i].second;\n            int s0 = s == 0 ? 0 : parts[s-1];\n            int s1 = s < N-1 ? parts[s] : W;\n            cout << s0 << \" 0 \" << s1 << \" \" << W << \"\\n\";\n        }\n    };\n    \n    vector<int> parts = compute_parts(a[0]);\n    output_new(parts);\n    \n    for (int d = 1; d < D; d++) {\n        long long cost_keep = deficit_sorted(a[d], get_heights(parts)) * 100;\n        auto new_parts = compute_parts(a[d]);\n        long long new_def = deficit_sorted(a[d], get_heights(new_parts)) * 100;\n        \n        set<int> s1(parts.begin(), parts.end()), s2(new_parts.begin(), new_parts.end());\n        vector<int> diff;\n        set_symmetric_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),back_inserter(diff));\n        long long cost_change = (long long)diff.size() * W + new_def;\n        \n        if (cost_change < cost_keep) { parts = new_parts; output_new(parts); }\n        else output_keep(parts);\n    }\n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <algorithm>\n#include <chrono>\n\nusing namespace std;\n\nconst int P = 998244353;\nint N, M, K;\nint T_mod[9][9];\nint initial_T_mod[9][9];\nvector<int> S_flat;\nvector<long long> sum_S;\n\n#define APPLY_STAMP(m, p, q) \\\n    do { int* s = &S_flat[(m) * 9]; \\\n    if (s[0]) { int t = T_mod[(p)][(q)] + s[0]; if (t >= P) t -= P; T_mod[(p)][(q)] = t; } \\\n    if (s[1]) { int t = T_mod[(p)][(q)+1] + s[1]; if (t >= P) t -= P; T_mod[(p)][(q)+1] = t; } \\\n    if (s[2]) { int t = T_mod[(p)][(q)+2] + s[2]; if (t >= P) t -= P; T_mod[(p)][(q)+2] = t; } \\\n    if (s[3]) { int t = T_mod[(p)+1][(q)] + s[3]; if (t >= P) t -= P; T_mod[(p)+1][(q)] = t; } \\\n    if (s[4]) { int t = T_mod[(p)+1][(q)+1] + s[4]; if (t >= P) t -= P; T_mod[(p)+1][(q)+1] = t; } \\\n    if (s[5]) { int t = T_mod[(p)+1][(q)+2] + s[5]; if (t >= P) t -= P; T_mod[(p)+1][(q)+2] = t; } \\\n    if (s[6]) { int t = T_mod[(p)+2][(q)] + s[6]; if (t >= P) t -= P; T_mod[(p)+2][(q)] = t; } \\\n    if (s[7]) { int t = T_mod[(p)+2][(q)+1] + s[7]; if (t >= P) t -= P; T_mod[(p)+2][(q)+1] = t; } \\\n    if (s[8]) { int t = T_mod[(p)+2][(q)+2] + s[8]; if (t >= P) t -= P; T_mod[(p)+2][(q)+2] = t; } \\\n    } while(0)\n\n#define REMOVE_STAMP(m, p, q, loss_var) \\\n    do { int* s = &S_flat[(m) * 9]; \\\n    if (s[0]) { int old = T_mod[(p)][(q)]; int nv = old - s[0]; if (nv < 0) nv += P; T_mod[(p)][(q)] = nv; (loss_var) += nv - old; } \\\n    if (s[1]) { int old = T_mod[(p)][(q)+1]; int nv = old - s[1]; if (nv < 0) nv += P; T_mod[(p)][(q)+1] = nv; (loss_var) += nv - old; } \\\n    if (s[2]) { int old = T_mod[(p)][(q)+2]; int nv = old - s[2]; if (nv < 0) nv += P; T_mod[(p)][(q)+2] = nv; (loss_var) += nv - old; } \\\n    if (s[3]) { int old = T_mod[(p)+1][(q)]; int nv = old - s[3]; if (nv < 0) nv += P; T_mod[(p)+1][(q)] = nv; (loss_var) += nv - old; } \\\n    if (s[4]) { int old = T_mod[(p)+1][(q)+1]; int nv = old - s[4]; if (nv < 0) nv += P; T_mod[(p)+1][(q)+1] = nv; (loss_var) += nv - old; } \\\n    if (s[5]) { int old = T_mod[(p)+1][(q)+2]; int nv = old - s[5]; if (nv < 0) nv += P; T_mod[(p)+1][(q)+2] = nv; (loss_var) += nv - old; } \\\n    if (s[6]) { int old = T_mod[(p)+2][(q)]; int nv = old - s[6]; if (nv < 0) nv += P; T_mod[(p)+2][(q)] = nv; (loss_var) += nv - old; } \\\n    if (s[7]) { int old = T_mod[(p)+2][(q)+1]; int nv = old - s[7]; if (nv < 0) nv += P; T_mod[(p)+2][(q)+1] = nv; (loss_var) += nv - old; } \\\n    if (s[8]) { int old = T_mod[(p)+2][(q)+2]; int nv = old - s[8]; if (nv < 0) nv += P; T_mod[(p)+2][(q)+2] = nv; (loss_var) += nv - old; } \\\n    } while(0)\n\n#define REVERT_STAMP(m, p, q) \\\n    do { int* s = &S_flat[(m) * 9]; \\\n    if (s[0]) { int t = T_mod[(p)][(q)] - s[0]; if (t < 0) t += P; T_mod[(p)][(q)] = t; } \\\n    if (s[1]) { int t = T_mod[(p)][(q)+1] - s[1]; if (t < 0) t += P; T_mod[(p)][(q)+1] = t; } \\\n    if (s[2]) { int t = T_mod[(p)][(q)+2] - s[2]; if (t < 0) t += P; T_mod[(p)][(q)+2] = t; } \\\n    if (s[3]) { int t = T_mod[(p)+1][(q)] - s[3]; if (t < 0) t += P; T_mod[(p)+1][(q)] = t; } \\\n    if (s[4]) { int t = T_mod[(p)+1][(q)+1] - s[4]; if (t < 0) t += P; T_mod[(p)+1][(q)+1] = t; } \\\n    if (s[5]) { int t = T_mod[(p)+1][(q)+2] - s[5]; if (t < 0) t += P; T_mod[(p)+1][(q)+2] = t; } \\\n    if (s[6]) { int t = T_mod[(p)+2][(q)] - s[6]; if (t < 0) t += P; T_mod[(p)+2][(q)] = t; } \\\n    if (s[7]) { int t = T_mod[(p)+2][(q)+1] - s[7]; if (t < 0) t += P; T_mod[(p)+2][(q)+1] = t; } \\\n    if (s[8]) { int t = T_mod[(p)+2][(q)+2] - s[8]; if (t < 0) t += P; T_mod[(p)+2][(q)+2] = t; } \\\n    } while(0)\n\nstruct Move {\n    int rem_size = 0;\n    int rem_ids[3] = {-1, -1, -1};\n    int add_size = 0;\n    tuple<int,int,int> add_ops[3];\n};\n\nvector<tuple<int, int, int>> ops;\n\nbool run_3opt() {\n    long long best_net_gain = 0;\n    Move best_move;\n    \n    vector<int> ops_at[7][7];\n    for(int idx=0; idx<ops.size(); ++idx) {\n        ops_at[get<1>(ops[idx])][get<2>(ops[idx])].push_back(idx);\n    }\n    \n    auto find_best_addition = [&]() -> tuple<long long, int, int, int> {\n        long long max_gain = 0;\n        int bm = -1, bp = -1, bq = -1;\n        for(int p = 0; p <= 6; ++p) {\n            for(int q = 0; q <= 6; ++q) {\n                int t00 = T_mod[p][q], t01 = T_mod[p][q+1], t02 = T_mod[p][q+2];\n                int t10 = T_mod[p+1][q], t11 = T_mod[p+1][q+1], t12 = T_mod[p+1][q+2];\n                int t20 = T_mod[p+2][q], t21 = T_mod[p+2][q+1], t22 = T_mod[p+2][q+2];\n                for(int m = 0; m < M; ++m) {\n                    int* s = &S_flat[m * 9];\n                    int overflow = 0;\n                    if (s[0] && t00 + s[0] >= P) overflow++;\n                    if (s[1] && t01 + s[1] >= P) overflow++;\n                    if (s[2] && t02 + s[2] >= P) overflow++;\n                    if (s[3] && t10 + s[3] >= P) overflow++;\n                    if (s[4] && t11 + s[4] >= P) overflow++;\n                    if (s[5] && t12 + s[5] >= P) overflow++;\n                    if (s[6] && t20 + s[6] >= P) overflow++;\n                    if (s[7] && t21 + s[7] >= P) overflow++;\n                    if (s[8] && t22 + s[8] >= P) overflow++;\n                    long long gain = sum_S[m] - (long long)P * overflow;\n                    if (gain > max_gain) { max_gain = gain; bm = m; bp = p; bq = q; }\n                }\n            }\n        }\n        return {max_gain, bm, bp, bq};\n    };\n\n    for (int r = 0; r < 9; ++r) {\n        for (int c = 0; c < 9; ++c) {\n            vector<int> local_ops;\n            for (int p = max(0, r-2); p <= min(6, r); ++p)\n                for (int q = max(0, c-2); q <= min(6, c); ++q)\n                    for (int idx : ops_at[p][q]) local_ops.push_back(idx);\n            \n            if (local_ops.size() > 15) local_ops.erase(local_ops.begin(), local_ops.end() - 15);\n            int num_local_ops = local_ops.size();\n            int rem_indices[15];\n            for(int i=0; i<num_local_ops; ++i) rem_indices[i] = local_ops[i];\n            \n            int rems[600][3]; int rem_sizes[600]; int num_rems = 0;\n            rems[num_rems][0] = -1; rem_sizes[num_rems] = 0; num_rems++;\n            for(int i=0; i<num_local_ops; ++i) { rems[num_rems][0] = rem_indices[i]; rem_sizes[num_rems] = 1; num_rems++; }\n            for(int i=0; i<num_local_ops; ++i) for(int j=i+1; j<num_local_ops; ++j) { rems[num_rems][0] = rem_indices[i]; rems[num_rems][1] = rem_indices[j]; rem_sizes[num_rems] = 2; num_rems++; }\n            for(int i=0; i<num_local_ops; ++i) for(int j=i+1; j<num_local_ops; ++j) for(int k=j+1; k<num_local_ops; ++k) { rems[num_rems][0] = rem_indices[i]; rems[num_rems][1] = rem_indices[j]; rems[num_rems][2] = rem_indices[k]; rem_sizes[num_rems] = 3; num_rems++; }\n            \n            for (int r_idx = 0; r_idx < num_rems; ++r_idx) {\n                if ((int)ops.size() - rem_sizes[r_idx] > K) continue;\n                long long loss = 0;\n                for (int i = 0; i < rem_sizes[r_idx]; ++i) {\n                    int idx = rems[r_idx][i];\n                    REMOVE_STAMP(get<0>(ops[idx]), get<1>(ops[idx]), get<2>(ops[idx]), loss);\n                }\n                \n                if (loss > best_net_gain) {\n                    best_net_gain = loss; best_move.rem_size = rem_sizes[r_idx];\n                    for(int i=0; i<rem_sizes[r_idx]; ++i) best_move.rem_ids[i] = rems[r_idx][i];\n                    best_move.add_size = 0;\n                }\n                \n                auto [gain1, m1, p1, q1] = find_best_addition();\n                if (loss + gain1 > best_net_gain && (int)ops.size() - rem_sizes[r_idx] + 1 <= K) {\n                    best_net_gain = loss + gain1; best_move.rem_size = rem_sizes[r_idx];\n                    for(int i=0; i<rem_sizes[r_idx]; ++i) best_move.rem_ids[i] = rems[r_idx][i];\n                    best_move.add_size = 1; best_move.add_ops[0] = {m1, p1, q1};\n                }\n                \n                if (gain1 > 0 && (int)ops.size() - rem_sizes[r_idx] + 2 <= K) {\n                    APPLY_STAMP(m1, p1, q1);\n                    auto [gain2, m2, p2, q2] = find_best_addition();\n                    if (loss + gain1 + gain2 > best_net_gain) {\n                        best_net_gain = loss + gain1 + gain2; best_move.rem_size = rem_sizes[r_idx];\n                        for(int i=0; i<rem_sizes[r_idx]; ++i) best_move.rem_ids[i] = rems[r_idx][i];\n                        best_move.add_size = 2; best_move.add_ops[0] = {m1, p1, q1}; best_move.add_ops[1] = {m2, p2, q2};\n                    }\n                    if (gain2 > 0 && (int)ops.size() - rem_sizes[r_idx] + 3 <= K) {\n                        APPLY_STAMP(m2, p2, q2);\n                        auto [gain3, m3, p3, q3] = find_best_addition();\n                        if (loss + gain1 + gain2 + gain3 > best_net_gain) {\n                            best_net_gain = loss + gain1 + gain2 + gain3; best_move.rem_size = rem_sizes[r_idx];\n                            for(int i=0; i<rem_sizes[r_idx]; ++i) best_move.rem_ids[i] = rems[r_idx][i];\n                            best_move.add_size = 3; best_move.add_ops[0] = {m1, p1, q1}; best_move.add_ops[1] = {m2, p2, q2}; best_move.add_ops[2] = {m3, p3, q3};\n                        }\n                        REVERT_STAMP(m2, p2, q2);\n                    }\n                    REVERT_STAMP(m1, p1, q1);\n                }\n                for (int i = 0; i < rem_sizes[r_idx]; ++i) {\n                    int idx = rems[r_idx][i];\n                    APPLY_STAMP(get<0>(ops[idx]), get<1>(ops[idx]), get<2>(ops[idx]));\n                }\n            }\n        }\n    }\n    if (best_net_gain > 0) {\n        vector<bool> removed(ops.size(), false);\n        for(int i=0; i<best_move.rem_size; ++i) removed[best_move.rem_ids[i]] = true;\n        vector<tuple<int,int,int>> new_ops;\n        for(int i=0; i<ops.size(); ++i) if (!removed[i]) new_ops.push_back(ops[i]);\n        for(int i=0; i<best_move.add_size; ++i) new_ops.push_back(best_move.add_ops[i]);\n        ops = new_ops;\n        return true;\n    }\n    return false;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    if (!(cin >> N >> M >> K)) return 0;\n    for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) { cin >> T_mod[i][j]; initial_T_mod[i][j] = T_mod[i][j]; }\n    S_flat.assign(M * 9, 0); sum_S.assign(M, 0);\n    for (int m = 0; m < M; ++m) for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) { int idx = m * 9 + i * 3 + j; cin >> S_flat[idx]; sum_S[m] += S_flat[idx]; }\n\n    long long best_gain_at_pos[7][7]; int best_m_at_pos[7][7];\n    auto update_pos = [&](int p, int q) {\n        long long best_g = -1; int best_m = 0; int t[9];\n        for(int i=0; i<3; ++i) for(int j=0; j<3; ++j) t[i*3+j] = T_mod[p+i][q+j];\n        for (int m = 0; m < M; ++m) {\n            int* s = &S_flat[m * 9]; int overflow = 0;\n            for(int k=0; k<9; ++k) if (s[k] && t[k] + s[k] >= P) overflow++;\n            long long gain = sum_S[m] - (long long)P * overflow;\n            if (gain > best_g) { best_g = gain; best_m = m; }\n        }\n        best_gain_at_pos[p][q] = best_g; best_m_at_pos[p][q] = best_m;\n    };\n    auto update_affected = [&](int p_old, int q_old) { for (int p = max(0, p_old - 2); p <= min(6, p_old + 2); ++p) for (int q = max(0, q_old - 2); q <= min(6, q_old + 2); ++q) update_pos(p, q); };\n    auto update_all = [&]() { for (int p = 0; p <= 6; ++p) for (int q = 0; q <= 6; ++q) update_pos(p, q); };\n    \n    update_all();\n    for (int step = 0; step < K; ++step) {\n        long long best_gain = 0; int best_p = -1, best_q = -1;\n        for (int p = 0; p <= 6; ++p) for (int q = 0; q <= 6; ++q) if (best_gain_at_pos[p][q] > best_gain) { best_gain = best_gain_at_pos[p][q]; best_p = p; best_q = q; }\n        if (best_gain <= 0) break;\n        int best_m = best_m_at_pos[best_p][best_q]; ops.emplace_back(best_m, best_p, best_q);\n        APPLY_STAMP(best_m, best_p, best_q); update_affected(best_p, best_q);\n    }\n\n    if (run_3opt()) {\n        for(int i=0; i<9; ++i) for(int j=0; j<9; ++j) T_mod[i][j] = initial_T_mod[i][j];\n        for(auto& op : ops) APPLY_STAMP(get<0>(op), get<1>(op), get<2>(op));\n        update_all();\n    }\n\n    auto start_time = std::chrono::high_resolution_clock::now();\n    bool improved = true;\n    while (improved) {\n        auto current_time = std::chrono::high_resolution_clock::now();\n        if (std::chrono::duration<double>(current_time - start_time).count() > 1.8) break;\n        improved = false; update_all(); long long best_net_gain = 0;\n        int best_i = -1, best_j = -1, ls_best_m1 = -1, ls_best_p1 = -1, ls_best_q1 = -1, ls_best_m2 = -1, ls_best_p2 = -1, ls_best_q2 = -1; bool add_two = false;\n        for (int i = 0; i <= ops.size(); ++i) {\n            int j_start = (i < ops.size()) ? i + 1 : i; bool is_i_valid = (i < ops.size()); long long loss_i = 0;\n            if (is_i_valid) { const auto& [mi, pi, qi] = ops[i]; REVERT_STAMP(mi, pi, qi); update_affected(pi, qi); int* s_i = &S_flat[mi*9]; for(int k=0;k<9;++k) if(s_i[k]){int o=T_mod[pi+k/3][qi+k%3]; int nv=o+s_i[k]; if(nv>=P) nv-=P; loss_i+=nv-o;} }\n            for (int j = j_start; j <= ops.size(); ++j) {\n                bool is_j_valid = (j < ops.size()); long long loss_j = 0;\n                if (is_j_valid) { const auto& [mj, pj, qj] = ops[j]; REVERT_STAMP(mj, pj, qj); update_affected(pj, qj); int* s_j = &S_flat[mj*9]; for(int k=0;k<9;++k) if(s_j[k]){int o=T_mod[pj+k/3][qj+k%3]; int nv=o+s_j[k]; if(nv>=P) nv-=P; loss_j+=nv-o;} }\n                long long total_loss = loss_i + loss_j; int current_sim_size = ops.size() - (is_i_valid ? 1 : 0) - (is_j_valid ? 1 : 0);\n                long long max_gain_1 = 0; int bm1 = -1, bp1 = -1, bq1 = -1;\n                for (int p = 0; p <= 6; ++p) for (int q = 0; q <= 6; ++q) if (best_gain_at_pos[p][q] > max_gain_1) { max_gain_1 = best_gain_at_pos[p][q]; bm1 = best_m_at_pos[p][q]; bp1 = p; bq1 = q; }\n                if (current_sim_size + 1 <= K && max_gain_1 - total_loss > best_net_gain) { best_net_gain = max_gain_1 - total_loss; best_i = i; best_j = j; ls_best_m1 = bm1; ls_best_p1 = bp1; ls_best_q1 = bq1; ls_best_m2 = -1; add_two = false; }\n                if (current_sim_size + 2 <= K && bm1 != -1) {\n                    APPLY_STAMP(bm1, bp1, bq1); update_affected(bp1, bq1);\n                    long long max_gain_2 = 0; int bm2 = -1, bp2 = -1, bq2 = -1;\n                    for (int p = 0; p <= 6; ++p) for (int q = 0; q <= 6; ++q) if (best_gain_at_pos[p][q] > max_gain_2) { max_gain_2 = best_gain_at_pos[p][q]; bm2 = best_m_at_pos[p][q]; bp2 = p; bq2 = q; }\n                    if (max_gain_1 + max_gain_2 - total_loss > best_net_gain) { best_net_gain = max_gain_1 + max_gain_2 - total_loss; best_i = i; best_j = j; ls_best_m1 = bm1; ls_best_p1 = bp1; ls_best_q1 = bq1; ls_best_m2 = bm2; ls_best_p2 = bp2; ls_best_q2 = bq2; add_two = true; }\n                    REVERT_STAMP(bm1, bp1, bq1); update_affected(bp1, bq1);\n                }\n                if (is_j_valid) { const auto& [mj, pj, qj] = ops[j]; APPLY_STAMP(mj, pj, qj); update_affected(pj, qj); }\n            }\n            if (is_i_valid) { const auto& [mi, pi, qi] = ops[i]; APPLY_STAMP(mi, pi, qi); update_affected(pi, qi); }\n        }\n        if (best_net_gain > 0) {\n            improved = true;\n            if (best_i < ops.size()) { const auto& [mi, pi, qi] = ops[best_i]; REVERT_STAMP(mi, pi, qi); update_affected(pi, qi); }\n            if (best_j < ops.size()) { const auto& [mj, pj, qj] = ops[best_j]; REVERT_STAMP(mj, pj, qj); update_affected(pj, qj); }\n            if (ls_best_m1 != -1) { APPLY_STAMP(ls_best_m1, ls_best_p1, ls_best_q1); update_affected(ls_best_p1, ls_best_q1); }\n            if (add_two && ls_best_m2 != -1) { APPLY_STAMP(ls_best_m2, ls_best_p2, ls_best_q2); update_affected(ls_best_p2, ls_best_q2); }\n            vector<tuple<int,int,int>> new_ops; for(int k=0; k<ops.size(); ++k) if(k!=best_i && k!=best_j) new_ops.push_back(ops[k]);\n            if (ls_best_m1 != -1) new_ops.emplace_back(ls_best_m1, ls_best_p1, ls_best_q1);\n            if (add_two && ls_best_m2 != -1) new_ops.emplace_back(ls_best_m2, ls_best_p2, ls_best_q2);\n            ops = new_ops;\n        }\n    }\n    cout << ops.size() << \"\\n\";\n    for (const auto& [m, p, q] : ops) cout << m << \" \" << p << \" \" << q << \"\\n\";\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 5;\nint A[N][N], cont_row[25], cont_order[25];\nint grid[N][N], crx, cry, cr_held, recv_idx[N], next_dispatch[N];\nbool cr_carry, dispatched[25];\nstring cmds[N];\n\npair<int,int> find_cont(int id) {\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++)\n        if (grid[i][j] == id) return {i, j};\n    return {-1, -1};\n}\n\nint find_empty(int r, int mode) {\n    for (int j = 1; j < N-1; j++) if (grid[r][j] == -1) return j;\n    if (mode >= 1 && recv_idx[r] >= N && grid[r][0] == -1) return 0;\n    if (mode >= 2 && grid[r][N-1] == -1) return N-1;\n    return -1;\n}\n\nvoid move_to(int tx, int ty, char& a) {\n    if (crx < tx) a = 'D'; else if (crx > tx) a = 'U';\n    else if (cry < ty) a = 'R'; else if (cry > ty) a = 'L'; else a = '.';\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        cin >> A[i][j]; cont_row[A[i][j]] = A[i][j] / N; cont_order[A[i][j]] = A[i][j] % N;\n    }\n    memset(grid, -1, sizeof(grid)); crx = cry = 0; cr_carry = false; cr_held = -1;\n    memset(recv_idx, 0, sizeof(recv_idx)); memset(dispatched, false, sizeof(dispatched));\n    memset(next_dispatch, 0, sizeof(next_dispatch));\n    int target = -1;\n    for (int turn = 0; turn < 10000; turn++) {\n        for (int i = 0; i < N; i++) if (recv_idx[i] < N && grid[i][0] == -1 && !(crx == i && cry == 0 && cr_carry))\n            grid[i][0] = A[i][recv_idx[i]++];\n        char act[N]; fill(act, act + N, '.');\n        if (turn == 0) { for (int i = 1; i < N; i++) act[i] = 'R'; act[0] = 'D'; }\n        else if (turn == 1) { for (int i = 1; i < N; i++) act[i] = 'B'; }\n        else {\n            bool all_recv = true; for (int i = 0; i < N; i++) if (recv_idx[i] < N) all_recv = false;\n            if (!cr_carry) {\n                if (!all_recv) {\n                    int bx = -1, by = -1, bd = 1000;\n                    for (int i = 0; i < N; i++) if (grid[i][0] != -1) { int d = abs(i-crx)+abs(cry); if (d < bd) { bd = d; bx = i; by = 0; } }\n                    if (bx < 0) for (int i = 0; i < N; i++) for (int j = 1; j < N-1; j++) if (grid[i][j] != -1) { int d = abs(i-crx)+abs(j-cry); if (d < bd) { bd = d; bx = i; by = j; } }\n                    if (bx >= 0) { if (crx == bx && cry == by) { act[0] = 'P'; target = grid[bx][by]; } else move_to(bx, by, act[0]); }\n                } else {\n                    int best_cid = -1, best_d = 1000;\n                    for (int r = 0; r < N; r++) while (next_dispatch[r] < N) {\n                        int cid = r * N + next_dispatch[r]; auto [cx, cy] = find_cont(cid);\n                        if (cx >= 0) { int d = abs(cx-crx)+abs(cy-cry); if (d < best_d) { best_d = d; best_cid = cid; } break; } else next_dispatch[r]++;\n                    }\n                    if (best_cid >= 0) { auto [cx, cy] = find_cont(best_cid); if (crx == cx && cry == cy) { act[0] = 'P'; target = best_cid; } else move_to(cx, cy, act[0]); }\n                }\n            } else {\n                int tr = cont_row[target];\n                if (!all_recv) { int ty = find_empty(tr, 0); if (ty < 0) ty = find_empty(tr, 1); if (ty < 0) ty = find_empty(tr, 2); if (ty >= 0) { if (crx == tr && cry == ty) act[0] = 'Q'; else move_to(tr, ty, act[0]); } }\n                else { if (crx == tr && cry == N-1) act[0] = 'Q'; else move_to(tr, N-1, act[0]); }\n            }\n        }\n        for (int i = 0; i < N; i++) cmds[i] += act[i];\n        if (act[0] == 'P') { cr_held = grid[crx][cry]; grid[crx][cry] = -1; cr_carry = true; }\n        else if (act[0] == 'Q') { grid[crx][cry] = cr_held; cr_held = -1; cr_carry = false; }\n        else if (act[0] == 'U') crx--; else if (act[0] == 'D') crx++; else if (act[0] == 'L') cry--; else if (act[0] == 'R') cry++;\n        for (int i = 0; i < N; i++) if (grid[i][N-1] != -1) { int c = grid[i][N-1]; dispatched[c] = true; grid[i][N-1] = -1; if (i == cont_row[c] && cont_order[c] == next_dispatch[i]) next_dispatch[i]++; }\n        bool done = true; for (int i = 0; i < 25; i++) if (!dispatched[i]) { done = false; break; } if (done) break;\n    }\n    for (int i = 0; i < N; i++) cout << cmds[i] << endl;\n    return 0;\n}","ahc034":"#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;\n    cin >> N;\n    vector<vector<int>> h(N, vector<int>(N));\n    vector<pair<int, int>> cells;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            cin >> h[i][j];\n            if (h[i][j] != 0) cells.push_back({i, j});\n        }\n    \n    int M = cells.size();\n    if (M == 0) return 0;\n    \n    vector<vector<bool>> is_cell(N, vector<bool>(N, false));\n    map<pair<int, int>, int> pos_to_idx;\n    for (int k = 0; k < M; k++) {\n        is_cell[cells[k].first][cells[k].second] = true;\n        pos_to_idx[cells[k]] = k;\n    }\n    \n    vector<int> tour;\n    vector<bool> used(M, false);\n    int ci = 0, cj = 0, load = 0;\n    \n    for (int step = 0; step < M; step++) {\n        int best = -1;\n        double best_score = 1e18;\n        int radius = 15;\n        \n        for (int ni = max(0, ci - radius); ni <= min(N-1, ci + radius); ni++) {\n            for (int nj = max(0, cj - radius); nj <= min(N-1, cj + radius); nj++) {\n                if (!is_cell[ni][nj]) continue;\n                int idx = pos_to_idx[{ni, nj}];\n                if (used[idx]) continue;\n                int hv = h[ni][nj];\n                if (hv < 0 && load < -hv) continue;\n                \n                int d = abs(ci - ni) + abs(cj - nj);\n                double s = d * 100.0 + load * d;\n                \n                if (hv < 0 && load > 0)\n                    s -= min((double)load, (double)(-hv)) * 1.5 * (M - step);\n                if (hv > 0 && load < 0)\n                    s -= min((double)(-load), (double)hv) * 1.0 * (M - step);\n                \n                if (s < best_score) { best_score = s; best = idx; }\n            }\n        }\n        \n        if (best == -1) {\n            for (int k = 0; k < M; k++) {\n                if (used[k]) continue;\n                int ni = cells[k].first, nj = cells[k].second;\n                int hv = h[ni][nj];\n                if (hv < 0 && load < -hv) continue;\n                int d = abs(ci - ni) + abs(cj - nj);\n                double s = d * 100.0 + load * d;\n                if (hv < 0 && load > 0)\n                    s -= min((double)load, (double)(-hv)) * 1.5 * (M - step);\n                if (hv > 0 && load < 0)\n                    s -= min((double)(-load), (double)hv) * 1.0 * (M - step);\n                if (s < best_score) { best_score = s; best = k; }\n            }\n        }\n        \n        tour.push_back(best);\n        used[best] = true;\n        load += h[cells[best].first][cells[best].second];\n        ci = cells[best].first; cj = cells[best].second;\n    }\n    \n    auto valid = [&](const vector<int>& t) -> bool {\n        int ld = 0;\n        for (int idx : t) {\n            int v = h[cells[idx].first][cells[idx].second];\n            if (v < 0 && ld < -v) return false;\n            ld += v;\n        }\n        return true;\n    };\n    \n    auto cost_fn = [&](const vector<int>& t) -> double {\n        double c = 0; int li = 0, lj = 0, ld = 0;\n        for (int idx : t) {\n            int ni = cells[idx].first, nj = cells[idx].second;\n            int d = abs(li - ni) + abs(lj - nj);\n            c += d * 100.0 + ld * d;\n            ld += h[ni][nj]; li = ni; lj = nj;\n        }\n        return c;\n    };\n    \n    double cur = cost_fn(tour);\n    \n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (int i = 0; i + 1 < M; i++) {\n            swap(tour[i], tour[i+1]);\n            if (valid(tour)) {\n                double nc = cost_fn(tour);\n                if (nc < cur - 0.01) { cur = nc; improved = true; }\n                else swap(tour[i], tour[i+1]);\n            } else swap(tour[i], tour[i+1]);\n        }\n    }\n    \n    for (int max_len = 10; max_len <= 30; max_len += 10) {\n        improved = true;\n        while (improved) {\n            improved = false;\n            for (int i = 0; i < M - 1; i++) {\n                for (int j = i + 2; j < min(i + max_len + 1, M); j++) {\n                    reverse(tour.begin() + i, tour.begin() + j + 1);\n                    if (valid(tour)) {\n                        double nc = cost_fn(tour);\n                        if (nc < cur - 0.01) { cur = nc; improved = true; }\n                        else reverse(tour.begin() + i, tour.begin() + j + 1);\n                    } else reverse(tour.begin() + i, tour.begin() + j + 1);\n                }\n            }\n        }\n    }\n    \n    vector<string> ops;\n    ci = 0; cj = 0;\n    for (int idx : tour) {\n        int ni = cells[idx].first, nj = cells[idx].second;\n        while (ci < ni) { ops.push_back(\"D\"); ci++; }\n        while (ci > ni) { ops.push_back(\"U\"); ci--; }\n        while (cj < nj) { ops.push_back(\"R\"); cj++; }\n        while (cj > nj) { ops.push_back(\"L\"); cj--; }\n        int v = h[ni][nj];\n        ops.push_back((v > 0 ? \"+\" : \"-\") + to_string(abs(v)));\n    }\n    for (const auto& op : ops) cout << op << \"\\n\";\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, T;\n    cin >> N >> M >> T;\n\n    const int seed_count = 2 * N * (N - 1);\n    const int grid_size = N * N;\n    vector<vector<int>> X(seed_count, vector<int>(M, 0));\n    vector<int> V(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    const int dr[] = {-1, 1, 0, 0};\n    const int dc[] = {0, 0, -1, 1};\n    vector<vector<int>> nbrs(grid_size);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int pos = i * N + j;\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dr[d], nj = j + dc[d];\n                if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                    nbrs[pos].push_back(ni * N + nj);\n                }\n            }\n        }\n    }\n\n    mt19937 rng(42);\n\n    for (int t = 0; t < T; t++) {\n        vector<vector<int>> allEP(seed_count, vector<int>(seed_count, 0));\n        for (int i = 0; i < seed_count; i++) {\n            for (int j = i + 1; j < seed_count; j++) {\n                int s = 0;\n                for (int l = 0; l < M; l++) s += max(X[i][l], X[j][l]);\n                allEP[i][j] = allEP[j][i] = s;\n            }\n        }\n        \n        int bestA = 0, bestB = 1, bestPot = 0;\n        for (int i = 0; i < seed_count; i++) {\n            for (int j = i + 1; j < seed_count; j++) {\n                if (allEP[i][j] > bestPot) {\n                    bestPot = allEP[i][j];\n                    bestA = i;\n                    bestB = j;\n                }\n            }\n        }\n        \n        vector<int> selected;\n        vector<bool> used(seed_count, false);\n        selected.push_back(bestA);\n        selected.push_back(bestB);\n        used[bestA] = used[bestB] = true;\n        \n        vector<long long> sumEP(seed_count, 0);\n        for (int s = 0; s < seed_count; s++) {\n            if (!used[s]) sumEP[s] = (long long)allEP[s][bestA] + allEP[s][bestB];\n        }\n        \n        for (int k = 2; k < grid_size; k++) {\n            int bestSeed = -1;\n            long long bestScore = -1;\n            for (int s = 0; s < seed_count; s++) {\n                if (used[s]) continue;\n                long long score = sumEP[s] * 10000LL + V[s];\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestSeed = s;\n                }\n            }\n            selected.push_back(bestSeed);\n            used[bestSeed] = true;\n            for (int s = 0; s < seed_count; s++) {\n                if (!used[s]) sumEP[s] += allEP[s][bestSeed];\n            }\n        }\n        \n        vector<int> perm = selected;\n        \n        vector<int> unselectedSeeds;\n        for (int s = 0; s < seed_count; s++) {\n            if (!used[s]) unselectedSeeds.push_back(s);\n        }\n        \n        vector<vector<int>> ep(grid_size, vector<int>(grid_size, 0));\n        for (int i = 0; i < grid_size; i++) {\n            for (int j = i + 1; j < grid_size; j++) {\n                ep[i][j] = ep[j][i] = allEP[perm[i]][perm[j]];\n            }\n        }\n        \n        double temp = 700.0;\n        double cooling = 0.99993;\n        uniform_real_distribution<double> dist(0.0, 1.0);\n        uniform_int_distribution<int> posDist(0, grid_size - 1);\n        \n        for (int iter = 0; iter < 320000; iter++) {\n            if ((rng() % 10) < 3 && !unselectedSeeds.empty()) {\n                int p = posDist(rng);\n                \n                int bestIdx = -1, bestDelta = -999999999;\n                int trials = min(3, (int)unselectedSeeds.size());\n                for (int trial = 0; trial < trials; trial++) {\n                    int idx = rng() % unselectedSeeds.size();\n                    int s = unselectedSeeds[idx];\n                    int delta = 0;\n                    for (int nb : nbrs[p]) {\n                        delta += allEP[s][perm[nb]] - allEP[perm[p]][perm[nb]];\n                    }\n                    if (delta > bestDelta) {\n                        bestDelta = delta;\n                        bestIdx = idx;\n                    }\n                }\n                \n                double acceptProb = bestDelta >= 0 ? 1.0 : exp(bestDelta / temp);\n                if (dist(rng) < acceptProb) {\n                    int s = unselectedSeeds[bestIdx];\n                    int oldSeed = perm[p];\n                    perm[p] = s;\n                    unselectedSeeds[bestIdx] = unselectedSeeds.back();\n                    unselectedSeeds.pop_back();\n                    unselectedSeeds.push_back(oldSeed);\n                    for (int k = 0; k < grid_size; k++) {\n                        if (k != p) {\n                            ep[p][k] = ep[k][p] = allEP[s][perm[k]];\n                        }\n                    }\n                }\n            } else {\n                int p1 = posDist(rng);\n                int p2 = posDist(rng);\n                if (p1 == p2) continue;\n                \n                int delta = 0;\n                for (int nb : nbrs[p1]) {\n                    if (nb != p2) delta += ep[p2][nb] - ep[p1][nb];\n                }\n                for (int nb : nbrs[p2]) {\n                    if (nb != p1) delta += ep[p1][nb] - ep[p2][nb];\n                }\n                \n                double acceptProb = delta >= 0 ? 1.0 : exp(delta / temp);\n                if (dist(rng) < acceptProb) {\n                    swap(perm[p1], perm[p2]);\n                    swap(ep[p1], ep[p2]);\n                    for (int k = 0; k < grid_size; k++) {\n                        swap(ep[k][p1], ep[k][p2]);\n                    }\n                }\n            }\n            temp *= cooling;\n        }\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << perm[i * N + j];\n                if (j < N - 1) cout << \" \";\n                else cout << \"\\n\";\n            }\n        }\n        cout.flush();\n\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    }\n\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint dx[] = {0, 1, 0, -1};\nint dy[] = {1, 0, -1, 0};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, V;\n    cin >> N >> M >> V;\n    \n    vector<string> s(N), t(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    cout << V << \"\\n\";\n    for (int i = 1; i < V; i++) cout << 0 << \" \" << 1 << \"\\n\";\n    \n    int rx = 0, ry = 0;\n    cout << rx << \" \" << ry << \"\\n\";\n    \n    vector<int> dir(V, 0);\n    for (int i = 1; i < V; i++) dir[i] = (i - 1) % 4;\n    \n    string S1(V * 2, '.'), S2(V * 2, '.');\n    for (int i = 1; i < V; i++) {\n        int d = dir[i];\n        if (d == 1) S1[i] = 'R';\n        else if (d == 2) { S1[i] = 'R'; S2[i] = 'R'; }\n        else if (d == 3) S1[i] = 'L';\n    }\n    \n    int initialTurns = 0;\n    if (S1.find_first_not_of('.') != string::npos) { cout << S1 << \"\\n\"; initialTurns++; }\n    if (S2.find_first_not_of('.') != string::npos) { cout << S2 << \"\\n\"; initialTurns++; }\n    \n    vector<bool> holding(V, false);\n    \n    set<pair<int,int>> srcSet, dstSet;\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') srcSet.insert({i, j});\n            if (s[i][j] == '0' && t[i][j] == '1') dstSet.insert({i, j});\n        }\n    \n    auto inGrid = [&](int x, int y) { return x >= 0 && x < N && y >= 0 && y < N; };\n    \n    int maxTurns = 100000 - initialTurns;\n    int vertDir = 1;\n    int horizDir = 1;\n    \n    for (int turn = 0; turn < maxTurns && (!srcSet.empty() || !dstSet.empty()); turn++) {\n        string S(V * 2, '.');\n        \n        char move = '.';\n        if (horizDir == 1 && ry < N - 1) move = 'R';\n        else if (horizDir == -1 && ry > 0) move = 'L';\n        else if (vertDir == 1 && rx < N - 1) { move = 'D'; horizDir *= -1; }\n        else if (vertDir == -1 && rx > 0) { move = 'U'; horizDir *= -1; }\n        else {\n            vertDir *= -1;\n            horizDir *= -1;\n            cout << S << \"\\n\";\n            continue;\n        }\n        \n        S[0] = move;\n        if (move == 'D') rx++;\n        else if (move == 'U') rx--;\n        else if (move == 'L') ry--;\n        else if (move == 'R') ry++;\n        \n        for (int i = 1; i < V; i++) {\n            int fx = rx + dx[dir[i]], fy = ry + dy[dir[i]];\n            if (!inGrid(fx, fy)) continue;\n            if (holding[i] && dstSet.count({fx, fy})) {\n                S[V + i] = 'P'; holding[i] = false; dstSet.erase({fx, fy});\n            } else if (!holding[i] && srcSet.count({fx, fy})) {\n                S[V + i] = 'P'; holding[i] = true; srcSet.erase({fx, fy});\n            }\n        }\n        \n        cout << S << \"\\n\";\n    }\n    \n    return 0;\n}","ahc039":"#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;\n    cin >> N;\n    \n    vector<int> mx(N), my(N), sx(N), sy(N);\n    for (int i = 0; i < N; i++) cin >> mx[i] >> my[i];\n    for (int i = 0; i < N; i++) cin >> sx[i] >> sy[i];\n    \n    auto count_rect = [&](int x1, int y1, int x2, int y2) -> int {\n        int net = 0;\n        for (int i = 0; i < N; i++) if (mx[i] >= x1 && mx[i] <= x2 && my[i] >= y1 && my[i] <= y2) net++;\n        for (int i = 0; i < N; i++) if (sx[i] >= x1 && sx[i] <= x2 && sy[i] >= y1 && sy[i] <= y2) net--;\n        return net;\n    };\n    \n    int best_score = 0, best_x1 = 0, best_y1 = 0, best_x2 = 1, best_y2 = 1;\n    \n    auto try_rect = [&](int x1, int y1, int x2, int y2) {\n        if (x2 <= x1 || y2 <= y1) return;\n        int actual = count_rect(x1, y1, x2, y2);\n        if (actual > best_score) {\n            best_score = actual;\n            best_x1 = x1; best_y1 = y1; best_x2 = x2; best_y2 = y2;\n        }\n    };\n    \n    auto grid_search = [&](int GRID, int CELL) {\n        auto cell = [&](int x) { return min(x / CELL, GRID - 1); };\n        vector<vector<int>> grid(GRID, vector<int>(GRID, 0));\n        for (int i = 0; i < N; i++) grid[cell(mx[i])][cell(my[i])]++;\n        for (int i = 0; i < N; i++) grid[cell(sx[i])][cell(sy[i])]--;\n        \n        int best = 0, bx1 = 0, bx2 = 0, by1 = 0, by2 = 0;\n        for (int x1 = 0; x1 < GRID; x1++) {\n            vector<int> col(GRID, 0);\n            for (int x2 = x1; x2 < GRID; x2++) {\n                for (int y = 0; y < GRID; y++) col[y] += grid[x2][y];\n                int cur = 0, start = 0;\n                for (int y = 0; y < GRID; y++) {\n                    if (cur <= 0) { cur = col[y]; start = y; } else cur += col[y];\n                    if (cur > best) { best = cur; bx1 = x1; bx2 = x2; by1 = start; by2 = y; }\n                }\n            }\n        }\n        \n        if (best <= 0) return;\n        \n        int cx1 = bx1 * CELL, cy1 = by1 * CELL;\n        int cx2 = min((bx2 + 1) * CELL - 1, 100000), cy2 = min((by2 + 1) * CELL - 1, 100000);\n        try_rect(cx1, cy1, cx2, cy2);\n        \n        set<int> x_set, y_set;\n        x_set.insert(cx1); x_set.insert(cx2); y_set.insert(cy1); y_set.insert(cy2);\n        for (int i = 0; i < 2*N; i++) {\n            int x = (i<N)?mx[i]:sx[i], y = (i<N)?my[i]:sy[i];\n            if (x >= cx1 && x <= cx2) { x_set.insert(max(0,x-1)); x_set.insert(x); x_set.insert(min(100000,x+1)); }\n            if (y >= cy1 && y <= cy2) { y_set.insert(max(0,y-1)); y_set.insert(y); y_set.insert(min(100000,y+1)); }\n        }\n        vector<int> all_x(x_set.begin(),x_set.end()), all_y(y_set.begin(),y_set.end());\n        int nx = all_x.size(), ny = all_y.size();\n        \n        int fish_count = 0;\n        for (int i = 0; i < 2*N; i++) {\n            int x = (i<N)?mx[i]:sx[i], y = (i<N)?my[i]:sy[i];\n            if (x >= cx1 && x <= cx2 && y >= cy1 && y <= cy2) fish_count++;\n        }\n        \n        int MAX_SZ = (fish_count < 150) ? 2000 : (fish_count < 400) ? 1000 : (fish_count < 800) ? 700 : 500;\n        \n        auto subsample = [&](vector<int>& v) {\n            if ((int)v.size() <= MAX_SZ) return;\n            vector<int> t;\n            int step = ((int)v.size() + MAX_SZ - 1) / MAX_SZ;\n            for (int i = 0; i < (int)v.size(); i += step) t.push_back(v[i]);\n            if (t.back() != v.back()) t.push_back(v.back());\n            v = t;\n        };\n        subsample(all_x); nx = all_x.size();\n        subsample(all_y); ny = all_y.size();\n        \n        vector<vector<int>> fg(nx, vector<int>(ny, 0));\n        for (int i = 0; i < N; i++) { \n            int xi = lower_bound(all_x.begin(),all_x.end(),mx[i])-all_x.begin(); \n            int yi = lower_bound(all_y.begin(),all_y.end(),my[i])-all_y.begin(); \n            if(xi<nx && yi<ny && all_x[xi]==mx[i] && all_y[yi]==my[i]) fg[xi][yi]++; \n        }\n        for (int i = 0; i < N; i++) { \n            int xi = lower_bound(all_x.begin(),all_x.end(),sx[i])-all_x.begin(); \n            int yi = lower_bound(all_y.begin(),all_y.end(),sy[i])-all_y.begin(); \n            if(xi<nx && yi<ny && all_x[xi]==sx[i] && all_y[yi]==sy[i]) fg[xi][yi]--; \n        }\n        \n        int fb = 0, fx1 = 0, fx2 = 0, fy1 = 0, fy2 = 0;\n        for (int x1 = 0; x1 < nx; x1++) { \n            vector<int> col(ny, 0); \n            for (int x2 = x1; x2 < nx; x2++) { \n                for (int y = 0; y < ny; y++) col[y] += fg[x2][y]; \n                int cur = 0, start = 0; \n                for (int y = 0; y < ny; y++) { \n                    if (cur <= 0) { cur = col[y]; start = y; } else cur += col[y]; \n                    if (cur > fb) { fb = cur; fx1 = x1; fx2 = x2; fy1 = start; fy2 = y; } \n                } \n            } \n        }\n        \n        if (fb > 0) {\n            int ax1 = max(0, all_x[fx1]), ay1 = max(0, all_y[fy1]);\n            int ax2 = min(100000, all_x[fx2]), ay2 = min(100000, all_y[fy2]);\n            if (ax2 > ax1 && ay2 > ay1) try_rect(ax1, ay1, ax2, ay2);\n        }\n    };\n    \n    grid_search(25, 4001);\n    grid_search(33, 3031);\n    grid_search(50, 2001);\n    grid_search(67, 1493);\n    grid_search(100, 1001);\n    grid_search(125, 801);\n    grid_search(167, 599);\n    grid_search(200, 501);\n    grid_search(250, 401);\n    \n    if (best_score > 0) {\n        for (int iter = 0; iter < 50; iter++) {\n            int cx1 = best_x1, cy1 = best_y1, cx2 = best_x2, cy2 = best_y2;\n            set<int> near_x, near_y;\n            for (int i = 0; i < 2*N; i++) {\n                int x = (i<N)?mx[i]:sx[i], y = (i<N)?my[i]:sy[i];\n                if (x >= cx1-2 && x <= cx1+2) near_x.insert(x);\n                if (x >= cx2-2 && x <= cx2+2) near_x.insert(x);\n                if (y >= cy1-2 && y <= cy1+2) near_y.insert(y);\n                if (y >= cy2-2 && y <= cy2+2) near_y.insert(y);\n            }\n            for (int x : near_x) for (int dx : {x-1,x,x+1}) { if(dx>=0&&dx<=cx2) try_rect(dx,cy1,cx2,cy2); if(dx>=cx1&&dx<=100000) try_rect(cx1,cy1,dx,cy2); }\n            for (int y : near_y) for (int dy : {y-1,y,y+1}) { if(dy>=0&&dy<=cy2) try_rect(cx1,dy,cx2,cy2); if(dy>=cy1&&dy<=100000) try_rect(cx1,cy1,cx2,dy); }\n            try_rect(max(0,cx1-1),cy1,cx2,cy2); try_rect(cx1,cy1,min(100000,cx2+1),cy2);\n            try_rect(cx1,max(0,cy1-1),cx2,cy2); try_rect(cx1,cy1,cx2,min(100000,cy2+1));\n            if(cx2>cx1+1) { try_rect(cx1+1,cy1,cx2,cy2); try_rect(cx1,cy1,cx2-1,cy2); }\n            if(cy2>cy1+1) { try_rect(cx1,cy1+1,cx2,cy2); try_rect(cx1,cy1,cx2,cy2-1); }\n            if (best_x1 == cx1 && best_y1 == cy1 && best_x2 == cx2 && best_y2 == cy2) break;\n        }\n    }\n    \n    if (best_score <= 0) { cout << \"4\\n0 0\\n1 0\\n1 1\\n0 1\\n\"; }\n    else { cout << 4 << \"\\n\" << best_x1 << \" \" << best_y1 << \"\\n\" << best_x2 << \" \" << best_y1 << \"\\n\" << best_x2 << \" \" << best_y2 << \"\\n\" << best_x1 << \" \" << best_y2 << \"\\n\"; }\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    auto start_time = chrono::high_resolution_clock::now();\n    auto get_elapsed = [&]() {\n        return chrono::duration<double>(chrono::high_resolution_clock::now() - start_time).count();\n    };\n    \n    int N, T;\n    double sigma;\n    cin >> N >> T >> sigma;\n    \n    vector<double> w(N), h(N);\n    for (int i = 0; i < N; i++) {\n        int wo, ho;\n        cin >> wo >> ho;\n        w[i] = wo;\n        h[i] = ho;\n    }\n    \n    double w_ratio = 1.0, h_ratio = 1.0;\n    \n    for (int t = 0; t < T; t++) {\n        double elapsed = get_elapsed();\n        \n        vector<double> aw(N), ah(N);\n        for (int i = 0; i < N; i++) {\n            aw[i] = w[i] * w_ratio;\n            ah[i] = h[i] * h_ratio;\n        }\n        \n        vector<tuple<int,int,char,int>> solution;\n        double final_W = 0, final_H = 0;\n        \n        auto greedy_solve = [&]() {\n            vector<tuple<double,double,double,double,int>> placed;\n            solution.clear();\n            double placed_sum = 0;\n            \n            auto find_y = [&](double x, double ww) -> double {\n                double y = 0;\n                for (auto& [px,py,pw,ph,idx] : placed)\n                    if (px < x+ww && x < px+pw) y = max(y, py+ph);\n                return y;\n            };\n            auto find_x = [&](double y, double hh) -> double {\n                double x = 0;\n                for (auto& [px,py,pw,ph,idx] : placed)\n                    if (py < y+hh && y < py+ph) x = max(x, px+pw);\n                return x;\n            };\n            auto get_ref_x = [&](int idx) -> double {\n                for (auto& [px,py,pw,ph,i] : placed) if (i==idx) return px+pw;\n                return 0.0;\n            };\n            auto get_ref_y = [&](int idx) -> double {\n                for (auto& [px,py,pw,ph,i] : placed) if (i==idx) return py+ph;\n                return 0.0;\n            };\n            \n            for (int i = 0; i < N; i++) {\n                double best_score = 1e18;\n                int best_rot = 0; char best_d = 'U'; int best_b = -1;\n                \n                for (int rot = 0; rot < 2; rot++) {\n                    double rw = rot ? ah[i] : aw[i], rh = rot ? aw[i] : ah[i];\n                    auto try_place = [&](double x, double y, char d, int b) {\n                        double W = x+rw, H = y+rh;\n                        for (auto& [px,py,pw,ph,idx] : placed) { W = max(W,px+pw); H = max(H,py+ph); }\n                        double cost = W + H - placed_sum - (aw[i] + ah[i]);\n                        if (cost < best_score) { best_score = cost; best_rot = rot; best_d = d; best_b = b; }\n                    };\n                    try_place(0, find_y(0,rw), 'U', -1);\n                    for (auto& [px,py,pw,ph,idx] : placed)\n                        try_place(px+pw, find_y(px+pw,rw), 'U', idx);\n                    try_place(find_x(0,rh), 0, 'L', -1);\n                    for (auto& [px,py,pw,ph,idx] : placed)\n                        try_place(find_x(py+ph,rh), py+ph, 'L', idx);\n                }\n                \n                double cur_W = 0, cur_H = 0;\n                for (auto& [px,py,pw,ph,idx] : placed) { cur_W = max(cur_W, px+pw); cur_H = max(cur_H, py+ph); }\n                double skip_cost = cur_W + cur_H - placed_sum;\n                if (skip_cost < best_score) continue;\n                \n                double rw = best_rot ? ah[i] : aw[i], rh = best_rot ? aw[i] : ah[i];\n                double x, y;\n                if (best_d == 'U') { x = best_b==-1 ? 0 : get_ref_x(best_b); y = find_y(x,rw); }\n                else { y = best_b==-1 ? 0 : get_ref_y(best_b); x = find_x(y,rh); }\n                placed.emplace_back(x, y, rw, rh, i);\n                placed_sum += aw[i] + ah[i];\n                solution.emplace_back(i, best_rot, best_d, best_b);\n            }\n            final_W = 0; final_H = 0;\n            for (auto& [px,py,pw,ph,idx] : placed) { final_W = max(final_W, px+pw); final_H = max(final_H, py+ph); }\n        };\n        \n        if (elapsed > 2.2) {\n            greedy_solve();\n        } else {\n            // Adaptive beam width based on N and elapsed time\n            double time_per_item = (elapsed > 0.01) ? elapsed / ((t + 1) * N) : 0.0001;\n            int BEAM, MAX_OPTS;\n            \n            if (elapsed < 0.8) { BEAM = 25; MAX_OPTS = 6; }\n            else if (elapsed < 1.2) { BEAM = 20; MAX_OPTS = 5; }\n            else if (elapsed < 1.5) { BEAM = 16; MAX_OPTS = 5; }\n            else if (elapsed < 1.8) { BEAM = 12; MAX_OPTS = 4; }\n            else if (elapsed < 2.0) { BEAM = 10; MAX_OPTS = 4; }\n            else { BEAM = 8; MAX_OPTS = 3; }\n            \n            // Reduce for large N\n            if (N > 70) { BEAM = min(BEAM, 18); MAX_OPTS = min(MAX_OPTS, 5); }\n            if (N > 85) { BEAM = min(BEAM, 14); MAX_OPTS = min(MAX_OPTS, 4); }\n            \n            struct State {\n                int parent, idx, rot, ref;\n                char dir;\n                double placed_sum, W, H, x, y, rw, rh;\n                bool skipped;\n            };\n            \n            vector<State> states;\n            states.reserve(N * BEAM * (MAX_OPTS + 1));\n            states.push_back({-1, -1, 0, -1, 'U', 0, 0, 0, 0, 0, 0, 0, true});\n            vector<int> beam = {0};\n            \n            for (int i = 0; i < N; i++) {\n                vector<pair<double, int>> candidates;\n                candidates.reserve(beam.size() * (MAX_OPTS + 1));\n                \n                for (int bi : beam) {\n                    vector<tuple<double,double,double,double,int>> placed;\n                    for (int cur = bi; cur != -1 && states[cur].idx >= 0; cur = states[cur].parent) {\n                        auto& s = states[cur];\n                        if (!s.skipped) placed.emplace_back(s.x, s.y, s.rw, s.rh, s.idx);\n                    }\n                    reverse(placed.begin(), placed.end());\n                    \n                    auto& st = states[bi];\n                    double new_sum = st.placed_sum + aw[i] + ah[i];\n                    \n                    // Skip option\n                    double skip_cost = st.W + st.H - st.placed_sum;\n                    candidates.push_back({skip_cost, (int)states.size()});\n                    states.push_back({bi, i, 0, -1, 'U', st.placed_sum, st.W, st.H, 0, 0, 0, 0, true});\n                    \n                    vector<tuple<double,double,double,int,char,int>> opts;\n                    opts.reserve(2 * (placed.size() + 1) + 2);\n                    \n                    for (int rot = 0; rot < 2; rot++) {\n                        double rw = rot ? ah[i] : aw[i], rh = rot ? aw[i] : ah[i];\n                        auto find_y = [&](double x, double ww) -> double {\n                            double y = 0;\n                            for (auto& [px,py,pw,ph,idx] : placed)\n                                if (px < x+ww && x < px+pw) y = max(y, py+ph);\n                            return y;\n                        };\n                        auto find_x = [&](double y, double hh) -> double {\n                            double x = 0;\n                            for (auto& [px,py,pw,ph,idx] : placed)\n                                if (py < y+hh && y < py+ph) x = max(x, px+pw);\n                            return x;\n                        };\n                        \n                        auto add_opt = [&](double x, double y, char d, int b) {\n                            double nW = max(st.W, x+rw), nH = max(st.H, y+rh);\n                            double cost = nW + nH - new_sum;\n                            opts.emplace_back(cost, x, y, rot, d, b);\n                        };\n                        \n                        add_opt(0, find_y(0,rw), 'U', -1);\n                        for (auto& [px,py,pw,ph,idx] : placed)\n                            add_opt(px+pw, find_y(px+pw,rw), 'U', idx);\n                        add_opt(find_x(0,rh), 0, 'L', -1);\n                        for (auto& [px,py,pw,ph,idx] : placed)\n                            add_opt(find_x(py+ph,rh), py+ph, 'L', idx);\n                    }\n                    \n                    sort(opts.begin(), opts.end());\n                    opts.erase(unique(opts.begin(), opts.end()), opts.end());\n                    \n                    int kept = min((int)opts.size(), MAX_OPTS);\n                    for (int j = 0; j < kept; j++) {\n                        auto& [cost, x, y, rot, d, b] = opts[j];\n                        double rw = rot ? ah[i] : aw[i], rh = rot ? aw[i] : ah[i];\n                        double nW = max(st.W, x+rw), nH = max(st.H, y+rh);\n                        candidates.push_back({cost, (int)states.size()});\n                        states.push_back({bi, i, rot, b, d, new_sum, nW, nH, x, y, rw, rh, false});\n                    }\n                }\n                \n                int select = min(BEAM, (int)candidates.size());\n                partial_sort(candidates.begin(), candidates.begin() + select, candidates.end());\n                candidates.resize(select);\n                beam.clear();\n                beam.reserve(select);\n                for (auto& [c, idx] : candidates) beam.push_back(idx);\n            }\n            \n            for (int cur = beam[0]; cur != -1 && states[cur].idx >= 0; cur = states[cur].parent) {\n                auto& s = states[cur];\n                if (!s.skipped) solution.push_back({s.idx, s.rot, s.dir, s.ref});\n            }\n            reverse(solution.begin(), solution.end());\n            final_W = states[beam[0]].W;\n            final_H = states[beam[0]].H;\n        }\n        \n        cout << solution.size() << \"\\n\";\n        for (auto& [idx, rot, dir, ref] : solution)\n            cout << idx << \" \" << rot << \" \" << dir << \" \" << ref << \"\\n\";\n        cout.flush();\n        \n        int W_meas, H_meas;\n        cin >> W_meas >> H_meas;\n        \n        if (final_W > 0 && final_H > 0 && !solution.empty()) {\n            double wr = W_meas / final_W;\n            double hr = H_meas / final_H;\n            // Adaptive learning: higher rate when measurement is reliable\n            double noise_w = sigma / final_W;\n            double noise_h = sigma / final_H;\n            double alpha = 0.35 / (1 + t * 0.02 + 10 * (noise_w * noise_w + noise_h * noise_h));\n            w_ratio = w_ratio * (1 - alpha) + wr * alpha;\n            h_ratio = h_ratio * (1 - alpha) + hr * alpha;\n        }\n    }\n    \n    return 0;\n}","ahc041":"#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, H;\n    cin >> N >> M >> H;\n    \n    vector<int> A(N);\n    for (int i = 0; i < N; i++) cin >> A[i];\n    \n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    \n    vector<int> tmp(N);\n    for (int i = 0; i < N; i++) cin >> tmp[i] >> tmp[i];\n    \n    vector<vector<int>> dist_mat(N, vector<int>(N, H + 1));\n    for (int s = 0; s < N; s++) {\n        dist_mat[s][s] = 0;\n        queue<int> q;\n        q.push(s);\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int v : adj[u]) {\n                if (dist_mat[s][v] == H + 1) {\n                    dist_mat[s][v] = dist_mat[s][u] + 1;\n                    q.push(v);\n                }\n            }\n        }\n    }\n    \n    vector<bitset<1000>> cover(N);\n    vector<vector<int>> cover_list(N);\n    for (int v = 0; v < N; v++) {\n        for (int u = 0; u < N; u++) {\n            if (dist_mat[v][u] <= H) {\n                cover[v].set(u);\n                cover_list[v].push_back(u);\n            }\n        }\n    }\n    \n    vector<vector<int>> dist2(N);\n    for (int v = 0; v < N; v++) {\n        set<int> s;\n        for (int u : adj[v]) {\n            s.insert(u);\n            for (int w : adj[u]) s.insert(w);\n        }\n        dist2[v].assign(s.begin(), s.end());\n    }\n    \n    auto is_valid = [&](const vector<bool>& is_root) -> bool {\n        bitset<1000> covered;\n        for (int v = 0; v < N; v++) {\n            if (is_root[v]) covered |= cover[v];\n        }\n        return covered.count() == N;\n    };\n    \n    auto compute_score = [&](const vector<bool>& is_root) -> long long {\n        vector<int> roots;\n        for (int v = 0; v < N; v++) {\n            if (is_root[v]) roots.push_back(v);\n        }\n        long long score = 0;\n        for (int v = 0; v < N; v++) {\n            int min_d = H + 1;\n            for (int u : roots) {\n                min_d = min(min_d, dist_mat[v][u]);\n            }\n            if (min_d <= H) score += (long long)(min_d + 1) * A[v];\n        }\n        return score;\n    };\n    \n    auto simple_local_search = [&](vector<bool>& is_root) -> void {\n        vector<int> count(N, 0);\n        for (int v = 0; v < N; v++) {\n            if (!is_root[v]) continue;\n            for (int u : cover_list[v]) count[u]++;\n        }\n        \n        vector<int> root_list;\n        for (int v = 0; v < N; v++) {\n            if (is_root[v]) root_list.push_back(v);\n        }\n        sort(root_list.begin(), root_list.end(), [&](int a, int b) { return A[a] > A[b]; });\n        \n        bool changed = true;\n        while (changed) {\n            changed = false;\n            for (int v : root_list) {\n                if (!is_root[v]) continue;\n                bool can_remove = true;\n                for (int u : cover_list[v]) {\n                    if (count[u] <= 1) {\n                        can_remove = false;\n                        break;\n                    }\n                }\n                if (can_remove) {\n                    is_root[v] = false;\n                    for (int u : cover_list[v]) count[u]--;\n                    changed = true;\n                }\n            }\n        }\n    };\n    \n    auto full_local_search = [&](vector<bool>& is_root) -> void {\n        vector<int> count(N, 0);\n        for (int v = 0; v < N; v++) {\n            if (!is_root[v]) continue;\n            for (int u : cover_list[v]) count[u]++;\n        }\n        \n        auto remove_redundant = [&]() {\n            vector<int> rl;\n            for (int v = 0; v < N; v++) {\n                if (is_root[v]) rl.push_back(v);\n            }\n            sort(rl.begin(), rl.end(), [&](int a, int b) { return A[a] > A[b]; });\n            bool ch = true;\n            while (ch) {\n                ch = false;\n                for (int v : rl) {\n                    if (!is_root[v]) continue;\n                    bool can = true;\n                    for (int u : cover_list[v]) {\n                        if (count[u] <= 1) { can = false; break; }\n                    }\n                    if (can) {\n                        is_root[v] = false;\n                        for (int u : cover_list[v]) count[u]--;\n                        ch = true;\n                    }\n                }\n            }\n        };\n        \n        auto try_swap = [&](int v, int u) -> bool {\n            if (is_root[u] || A[u] >= A[v]) return false;\n            \n            for (int w : cover_list[v]) count[w]--;\n            \n            bool valid = true;\n            for (int w : cover_list[u]) {\n                if (count[w] <= 0) { valid = false; break; }\n            }\n            \n            if (valid) {\n                for (int w : cover_list[u]) count[w]++;\n                is_root[v] = false;\n                is_root[u] = true;\n                return true;\n            } else {\n                for (int w : cover_list[v]) count[w]++;\n                return false;\n            }\n        };\n        \n        remove_redundant();\n        \n        bool changed = true;\n        while (changed) {\n            changed = false;\n            vector<int> rl;\n            for (int v = 0; v < N; v++) {\n                if (is_root[v]) rl.push_back(v);\n            }\n            sort(rl.begin(), rl.end(), [&](int a, int b) { return A[a] > A[b]; });\n            \n            for (int v : rl) {\n                if (!is_root[v]) continue;\n                for (int u : dist2[v]) {\n                    if (try_swap(v, u)) { changed = true; break; }\n                }\n                if (changed) break;\n            }\n            if (changed) remove_redundant();\n        }\n        \n        for (int swap_count = 0; swap_count < 100; swap_count++) {\n            bool swapped = false;\n            vector<int> rl;\n            for (int v = 0; v < N; v++) {\n                if (is_root[v]) rl.push_back(v);\n            }\n            sort(rl.begin(), rl.end(), [&](int a, int b) { return A[a] > A[b]; });\n            \n            for (int v : rl) {\n                for (int u = 0; u < N; u++) {\n                    if (try_swap(v, u)) { \n                        swapped = true; \n                        remove_redundant();\n                        break; \n                    }\n                }\n                if (swapped) break;\n            }\n            if (!swapped) break;\n        }\n    };\n    \n    mt19937 rng(42);\n    \n    vector<bool> best_roots(N, false);\n    long long best_score = -1;\n    \n    for (int trial = 0; trial < 100; trial++) {\n        bitset<1000> uncovered;\n        for (int i = 0; i < N; i++) uncovered.set(i);\n        \n        vector<bool> is_root(N, false);\n        \n        while (uncovered.any()) {\n            int best_count = 0;\n            vector<int> candidates;\n            \n            for (int v = 0; v < N; v++) {\n                int count = (cover[v] & uncovered).count();\n                if (count > best_count) {\n                    best_count = count;\n                    candidates = {v};\n                } else if (count == best_count) {\n                    candidates.push_back(v);\n                }\n            }\n            \n            if (best_count == 0) break;\n            \n            uniform_int_distribution<int> dist(0, candidates.size() - 1);\n            int chosen = candidates[dist(rng)];\n            \n            is_root[chosen] = true;\n            uncovered &= ~cover[chosen];\n        }\n        \n        simple_local_search(is_root);\n        \n        long long score = compute_score(is_root);\n        if (score > best_score) {\n            best_score = score;\n            best_roots = is_root;\n        }\n    }\n    \n    full_local_search(best_roots);\n    \n    for (int iter = 0; iter < 100; iter++) {\n        int bv = -1, bu = -1;\n        long long bns = compute_score(best_roots);\n        bool sw = false;\n        \n        for (int v = 0; v < N; v++) {\n            if (!best_roots[v]) continue;\n            best_roots[v] = false;\n            if (is_valid(best_roots)) {\n                long long ns = compute_score(best_roots);\n                if (ns > bns) { bns = ns; bv = v; bu = -1; sw = false; }\n            }\n            best_roots[v] = true;\n        }\n        \n        for (int v = 0; v < N; v++) {\n            if (!best_roots[v]) continue;\n            for (int u : dist2[v]) {\n                if (best_roots[u]) continue;\n                best_roots[v] = false;\n                best_roots[u] = true;\n                if (is_valid(best_roots)) {\n                    long long ns = compute_score(best_roots);\n                    if (ns > bns) { bns = ns; bv = v; bu = u; sw = true; }\n                }\n                best_roots[v] = true;\n                best_roots[u] = false;\n            }\n        }\n        \n        if (bv == -1) break;\n        best_roots[bv] = false;\n        if (sw) best_roots[bu] = true;\n    }\n    \n    vector<int> parent(N, -1);\n    vector<int> height(N, -1);\n    queue<int> q;\n    for (int v = 0; v < N; v++) {\n        if (best_roots[v]) { height[v] = 0; q.push(v); }\n    }\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : adj[u]) {\n            if (height[v] == -1 && height[u] < H) {\n                height[v] = height[u] + 1;\n                parent[v] = u;\n                q.push(v);\n            }\n        }\n    }\n    for (int v = 0; v < N; v++) {\n        if (height[v] == -1) {\n            height[v] = 0;\n            q.push(v);\n            while (!q.empty()) {\n                int u = q.front(); q.pop();\n                for (int w : adj[u]) {\n                    if (height[w] == -1 && height[u] < H) {\n                        height[w] = height[u] + 1;\n                        parent[w] = u;\n                        q.push(w);\n                    }\n                }\n            }\n        }\n    }\n    for (int v = 0; v < N; v++) {\n        cout << parent[v];\n        if (v < N - 1) cout << \" \";\n    }\n    cout << \"\\n\";\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N; cin >> N;\n    vector<string> board(N);\n    for (int i = 0; i < N; i++) cin >> board[i];\n    \n    vector<int> fmin_r(N,N), fmax_r(N,-1), fmin_c(N,N), fmax_c(N,-1);\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (board[i][j]=='o') {\n        fmin_r[i]=min(fmin_r[i],j); fmax_r[i]=max(fmax_r[i],j);\n        fmin_c[j]=min(fmin_c[j],i); fmax_c[j]=max(fmax_c[j],i);\n    }\n    \n    map<pair<int,int>,int> md;\n    \n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (board[i][j]=='x') {\n        int best_d = -1, best_dist = N+1;\n        if (fmin_c[j]>i||fmin_c[j]==N) { int d=i+1; if(d<best_dist){best_dist=d;best_d=0;} }\n        if (fmax_c[j]<i||fmax_c[j]==-1) { int d=N-i; if(d<best_dist){best_dist=d;best_d=1;} }\n        if (fmin_r[i]>j||fmin_r[i]==N) { int d=j+1; if(d<best_dist){best_dist=d;best_d=2;} }\n        if (fmax_r[i]<j||fmax_r[i]==-1) { int d=N-j; if(d<best_dist){best_dist=d;best_d=3;} }\n        int idx = (best_d<=1)?j:i;\n        md[{idx,best_d}] = max(md[{idx,best_d}], best_dist);\n    }\n    \n    for(auto&[key,dist]:md) {\n        auto[idx,d]=key;\n        char c=\"UDLR\"[d], cr=\"DULR\"[d];\n        for(int t=0;t<dist;t++) cout<<c<<\" \"<<idx<<\"\\n\";\n        for(int t=0;t<dist;t++) cout<<cr<<\" \"<<idx<<\"\\n\";\n    }\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, L;\n    cin >> N >> L;\n    \n    vector<int> T(N);\n    for (int i = 0; i < N; i++) {\n        cin >> T[i];\n    }\n    \n    vector<int> a(N, -1), b(N, -1);\n    vector<int> cnt(N, 0);\n    cnt[0] = 1;\n    \n    vector<int> remain = T;\n    remain[0]--;\n    \n    vector<double> in_est(N, 0);\n    \n    auto choose_next = [&](int current, int week, bool is_a) -> int {\n        int remaining_weeks = L - week + 1;\n        double half_flow = T[current] / 2.0;\n        double best_score = -1e18;\n        int best = -1;\n        \n        for (int i = 0; i < N; i++) {\n            if (i == current) continue;\n            if (remain[i] <= 0) continue;\n            \n            double expected = (double)T[i] * (week - 1) / L;\n            double deficit = expected - cnt[i];\n            int unavoidable = max(0, remain[i] - remaining_weeks);\n            \n            double room = T[i] - in_est[i] - half_flow;\n            \n            double score = deficit + unavoidable * 1e6 + 0.005 * room;\n            \n            if (score > best_score) {\n                best_score = score;\n                best = i;\n            }\n        }\n        \n        return best == -1 ? current : best;\n    };\n    \n    int current = 0;\n    for (int week = 2; week <= L; week++) {\n        int k = cnt[current];\n        \n        int next;\n        if (k % 2 == 1) {\n            if (a[current] == -1) {\n                a[current] = choose_next(current, week, true);\n                in_est[a[current]] += T[current] / 2.0;\n            }\n            next = a[current];\n        } else {\n            if (b[current] == -1) {\n                b[current] = choose_next(current, week, false);\n                in_est[b[current]] += T[current] / 2.0;\n            }\n            next = b[current];\n        }\n        \n        cnt[next]++;\n        remain[next]--;\n        current = next;\n    }\n    \n    for (int i = 0; i < N; i++) {\n        if (a[i] == -1) a[i] = 0;\n        if (b[i] == -1) b[i] = 0;\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    vector<int> parent, sz;\n    DSU(int n) : parent(n), sz(n, 1) { 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) return false;\n        if (sz[x] < sz[y]) swap(x, y);\n        parent[y] = x; sz[x] += sz[y]; return true;\n    }\n};\n\nint N, M, Q, L, W;\nvector<int> G, cx, cy;\ndouble estDist(int i, int j) { double dx=cx[i]-cx[j], dy=cy[i]-cy[j]; return sqrt(dx*dx+dy*dy); }\n\nvector<pair<int,int>> doQuery(vector<int>& cities) {\n    cout << \"? \" << cities.size();\n    for (int c : cities) cout << \" \" << c;\n    cout << \"\\n\" << flush;\n    vector<pair<int,int>> edges(cities.size() - 1);\n    for (int i = 0; i < (int)cities.size() - 1; i++) cin >> edges[i].first >> edges[i].second;\n    return edges;\n}\n\nvoid primMST(vector<int>& cities, vector<pair<int,int>>& edges) {\n    int n = cities.size();\n    if (n <= 1) return;\n    vector<double> minDist(n, 1e18);\n    vector<int> parent(n, -1);\n    vector<bool> inMST(n, false);\n    minDist[0] = 0;\n    for (int i = 0; i < n; i++) {\n        int u = -1;\n        for (int j = 0; j < n; j++) {\n            if (!inMST[j] && (u == -1 || minDist[j] < minDist[u])) u = j;\n        }\n        inMST[u] = true;\n        if (parent[u] != -1)\n            edges.push_back({min(cities[parent[u]], cities[u]), max(cities[parent[u]], cities[u])});\n        for (int v = 0; v < n; v++) {\n            if (!inMST[v]) {\n                double d = estDist(cities[u], cities[v]);\n                if (d < minDist[v]) { minDist[v] = d; parent[v] = u; }\n            }\n        }\n    }\n}\n\nvoid findMSTHierarchical(vector<int>& cities, vector<pair<int,int>>& edges, int& queriesLeft) {\n    int n = cities.size();\n    if (n <= 1) return;\n    if (n == 2) { edges.push_back({min(cities[0],cities[1]), max(cities[0],cities[1])}); return; }\n    sort(cities.begin(), cities.end(), [](int a, int b) { return cx[a]!=cx[b] ? cx[a]<cx[b] : cy[a]<cy[b]; });\n    if (n <= L && queriesLeft > 0) { auto r = doQuery(cities); edges.insert(edges.end(), r.begin(), r.end()); queriesLeft--; return; }\n    if (n <= L || queriesLeft <= 0) { primMST(cities, edges); return; }\n    \n    vector<vector<int>> chunks;\n    for (int i = 0; i < n; i += L) {\n        vector<int> chunk;\n        for (int j = i; j < min(i+L, n); j++) chunk.push_back(cities[j]);\n        chunks.push_back(chunk);\n    }\n    \n    vector<vector<pair<int,int>>> chunkMSTs;\n    for (auto& chunk : chunks) {\n        int sz = chunk.size();\n        if (sz >= 2 && queriesLeft > 0) {\n            chunkMSTs.push_back(doQuery(chunk));\n            edges.insert(edges.end(), chunkMSTs.back().begin(), chunkMSTs.back().end());\n            queriesLeft--;\n        } else if (sz >= 2) {\n            vector<pair<int,int>> primEdges;\n            primMST(chunk, primEdges);\n            edges.insert(edges.end(), primEdges.begin(), primEdges.end());\n            chunkMSTs.push_back(primEdges);\n        } else {\n            chunkMSTs.push_back({});\n        }\n    }\n    \n    vector<int> reps;\n    for (int i = 0; i < (int)chunks.size(); i++) {\n        auto& chunk = chunks[i];\n        auto& mst = chunkMSTs[i];\n        if (chunk.size() == 1) reps.push_back(chunk[0]);\n        else if (!mst.empty()) {\n            map<int,int> deg;\n            for (auto& [u,v] : mst) { deg[u]++; deg[v]++; }\n            int bestRep = chunk[0], maxDeg = 0;\n            for (int c : chunk) if (deg[c] > maxDeg) { maxDeg = deg[c]; bestRep = c; }\n            reps.push_back(bestRep);\n        } else reps.push_back(chunk[0]);\n    }\n    findMSTHierarchical(reps, edges, queriesLeft);\n}\n\nvoid findMSTSlidingWindow(vector<int>& cities, vector<pair<int,int>>& edges, int& queriesLeft) {\n    int n = cities.size();\n    if (n <= 1) return;\n    if (n == 2) { edges.push_back({min(cities[0],cities[1]), max(cities[0],cities[1])}); return; }\n    \n    sort(cities.begin(), cities.end(), [](int a, int b) { \n        return cx[a]!=cx[b] ? cx[a]<cx[b] : cy[a]<cy[b]; \n    });\n    \n    if (n <= L && queriesLeft > 0) {\n        auto r = doQuery(cities);\n        edges.insert(edges.end(), r.begin(), r.end());\n        queriesLeft--;\n        return;\n    }\n    \n    if (n <= L || queriesLeft <= 0) {\n        primMST(cities, edges);\n        return;\n    }\n    \n    int overlap = 1;\n    int step = L - overlap;\n    int numQueries = (n - L + step - 1) / step + 1;\n    \n    if (queriesLeft < numQueries) {\n        findMSTHierarchical(cities, edges, queriesLeft);\n        return;\n    }\n    \n    vector<pair<int,int>> allEdges;\n    for (int i = 0; i < numQueries; i++) {\n        int start = i * step;\n        int end = min(start + L, n);\n        if (end - start < 2) break;\n        vector<int> window(cities.begin() + start, cities.begin() + end);\n        auto r = doQuery(window);\n        allEdges.insert(allEdges.end(), r.begin(), r.end());\n        queriesLeft--;\n    }\n    \n    unordered_map<int, int> cityToIdx;\n    for (int i = 0; i < n; i++) cityToIdx[cities[i]] = i;\n    \n    DSU dsu(n);\n    int edgeCount = 0;\n    for (auto& [u, v] : allEdges) {\n        int ui = cityToIdx[u], vi = cityToIdx[v];\n        if (dsu.unite(ui, vi)) {\n            edges.push_back({min(u, v), max(u, v)});\n            edgeCount++;\n        }\n    }\n    \n    if (edgeCount < n - 1) {\n        edges.clear();\n        primMST(cities, edges);\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M); for (int i=0;i<M;i++) cin>>G[i];\n    cx.resize(N); cy.resize(N);\n    for (int i=0;i<N;i++) { int lx,rx,ly,ry; cin>>lx>>rx>>ly>>ry; cx[i]=(lx+rx)/2; cy[i]=(ly+ry)/2; }\n    \n    double centroidX = 0, centroidY = 0;\n    for (int i = 0; i < N; i++) { centroidX += cx[i]; centroidY += cy[i]; }\n    centroidX /= N; centroidY /= N;\n    int startCity = 0; double minDistToCentroid = 1e18;\n    for (int i = 0; i < N; i++) {\n        double d = (cx[i] - centroidX) * (cx[i] - centroidX) + (cy[i] - centroidY) * (cy[i] - centroidY);\n        if (d < minDistToCentroid) { minDistToCentroid = d; startCity = i; }\n    }\n    \n    vector<tuple<double,int,int>> allEdges;\n    for (int i=0;i<N;i++) for (int j=i+1;j<N;j++) allEdges.push_back({estDist(i,j),i,j});\n    sort(allEdges.begin(), allEdges.end());\n    DSU dsu(N); vector<tuple<double,int,int>> mstEdges;\n    for (auto& [d,u,v] : allEdges) { if(dsu.unite(u,v)) mstEdges.push_back({d,u,v}); if((int)mstEdges.size()==N-1) break; }\n    \n    vector<vector<int>> adj(N);\n    for (auto& [d,u,v] : mstEdges) { adj[u].push_back(v); adj[v].push_back(u); }\n    \n    vector<int> dfsOrder; vector<bool> vis(N,false);\n    function<void(int)> dfs = [&](int u) {\n        vis[u]=true; dfsOrder.push_back(u);\n        vector<pair<double,int>> nb; for (int v:adj[u]) if(!vis[v]) nb.push_back({estDist(u,v),v});\n        sort(nb.begin(), nb.end());\n        for (auto& [d,v]:nb) if(!vis[v]) dfs(v);\n    };\n    dfs(startCity);\n    for (int i = 0; i < N; i++) if (!vis[i]) dfsOrder.push_back(i);\n    \n    vector<vector<int>> groups(M); int idx=0;\n    for (int i=0;i<M;i++) for (int j=0;j<G[i];j++) groups[i].push_back(dfsOrder[idx++]);\n    \n    vector<int> gOrder(M); iota(gOrder.begin(),gOrder.end(),0);\n    sort(gOrder.begin(),gOrder.end(),[](int a,int b){return G[a]>G[b];});\n    \n    int queriesLeft = Q; vector<vector<pair<int,int>>> allEdgesOut(M);\n    for (int gi : gOrder) findMSTSlidingWindow(groups[gi], allEdgesOut[gi], queriesLeft);\n    \n    cout << \"!\\n\";\n    for (int i=0;i<M;i++) {\n        for (int j=0;j<(int)groups[i].size();j++) { if(j>0) cout<<\" \"; cout<<groups[i][j]; }\n        cout<<\"\\n\";\n        for (auto& e : allEdgesOut[i]) cout<<e.first<<\" \"<<e.second<<\"\\n\";\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nbool grid[20][20];\nint ci, cj;\nvector<string> actions;\n\nint dx[] = {-1, 1, 0, 0};\nint dy[] = {0, 0, -1, 1};\nchar dirChar[] = {'U', 'D', 'L', 'R'};\n\nbool inBounds(int i, int j) { return i >= 0 && i < N && j >= 0 && j < N; }\n\nvoid addMove(int d) {\n    actions.push_back(string(\"M \") + dirChar[d]);\n    ci += dx[d]; cj += dy[d];\n}\n\nvoid addSlide(int d) {\n    actions.push_back(string(\"S \") + dirChar[d]);\n    while (inBounds(ci + dx[d], cj + dy[d]) && !grid[ci + dx[d]][cj + dy[d]]) {\n        ci += dx[d]; cj += dy[d];\n    }\n}\n\npair<int,int> getSlideDest(int d) {\n    int ni = ci, nj = cj;\n    while (inBounds(ni + dx[d], nj + dy[d]) && !grid[ni + dx[d]][nj + dy[d]]) {\n        ni += dx[d]; nj += dy[d];\n    }\n    return make_pair(ni, nj);\n}\n\nvoid postVisitSlide(int nti, int ntj) {\n    if (nti == -1) return;\n    while (true) {\n        int bestDir = -1, bestSavings = 1;\n        for (int d = 0; d < 4; d++) {\n            pair<int,int> dest = getSlideDest(d);\n            if (dest.first == ci && dest.second == cj) continue;\n            int curDist = abs(ci - nti) + abs(cj - ntj);\n            int newDist = abs(dest.first - nti) + abs(dest.second - ntj);\n            int savings = curDist - newDist - 1;\n            if (savings > bestSavings) { bestSavings = savings; bestDir = d; }\n        }\n        if (bestDir >= 0) addSlide(bestDir);\n        else break;\n    }\n}\n\nvoid goTo(int ti, int tj) {\n    bool onTop = (ti == 0), onBot = (ti == N-1), onLeft = (tj == 0), onRight = (tj == N-1);\n    bool isEdge = onTop || onBot || onLeft || onRight;\n    while (ci != ti || cj != tj) {\n        bool slid = false;\n        if (cj == tj && ci != ti) {\n            int sd = -1;\n            if (onTop && ci > ti) sd = 0;\n            else if (onBot && ci < ti) sd = 1;\n            if (sd >= 0 && getSlideDest(sd).first == ti) { addSlide(sd); slid = true; }\n        }\n        if (!slid && ci == ti && cj != tj) {\n            int sd = -1;\n            if (onLeft && cj > tj) sd = 2;\n            else if (onRight && cj < tj) sd = 3;\n            if (sd >= 0 && getSlideDest(sd).second == tj) { addSlide(sd); slid = true; }\n        }\n        if (slid) continue;\n        int manh = abs(ci - ti) + abs(cj - tj), bestDir = -1, bestSave = 0;\n        if (isEdge) {\n            if ((onTop || onBot) && cj != tj) {\n                int s = abs(ci - ti) - 1;\n                if (s > bestSave && abs(cj - tj) < manh) { bestSave = s; bestDir = (cj < tj) ? 3 : 2; }\n            }\n            if ((onLeft || onRight) && ci != ti) {\n                int s = abs(cj - tj) - 1;\n                if (s > bestSave && abs(ci - ti) < manh) { bestSave = s; bestDir = (ci < ti) ? 1 : 0; }\n            }\n        }\n        if (bestDir == -1) bestDir = (ci < ti) ? 1 : (ci > ti) ? 0 : (cj < tj) ? 3 : 2;\n        addMove(bestDir);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N >> M >> ci >> cj;\n    int numT = M - 1;\n    vector<pair<int,int>> tgt(numT);\n    for (int i = 0; i < numT; i++) cin >> tgt[i].first >> tgt[i].second;\n    memset(grid, 0, sizeof(grid));\n    for (int i = 0; i < numT; i++) {\n        goTo(tgt[i].first, tgt[i].second);\n        postVisitSlide(i+1 < numT ? tgt[i+1].first : -1, i+1 < numT ? tgt[i+1].second : -1);\n    }\n    for (const auto& a : actions) cout << a << \"\\n\";\n}"},"16":{"ahc001":"#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\n\nstruct Company { int x, y, r; };\nstruct Rect { int a, b, c, d; };\n\ninline double calcScore(int count, long long capacity, long long required) {\n    if (count <= 0 || capacity <= 0) return -1e18;\n    double ratio = (double)capacity / required;\n    double r = (ratio <= 1) ? ratio : 1.0/ratio;\n    return count * (2.0 - r) * r;\n}\n\nvoid solve(Rect R, vector<int> ids, vector<Company>& C, vector<Rect>& res, mt19937& rng, int depth, bool doRand) {\n    if (ids.empty()) return;\n    if ((int)ids.size() == 1) { res[ids[0]] = R; return; }\n    \n    int w = R.c - R.a, h = R.d - R.b;\n    long long total = 0;\n    for (int i : ids) total += C[i].r;\n    \n    double bestScore = -1e18;\n    int bestSplit = -1, bestIdx = -1;\n    bool bestVert = true;\n    \n    int d0 = 0, d1 = 1;\n    if (doRand && depth < 4 && rng() % 3 == 0) swap(d0, d1);\n    \n    for (int vert : {d0, d1}) {\n        sort(ids.begin(), ids.end(), [&](int a, int b) {\n            return vert ? C[a].x < C[b].x : C[a].y < C[b].y;\n        });\n        long long acc = 0;\n        for (int i = 0; i < (int)ids.size()-1; i++) {\n            acc += C[ids[i]].r;\n            int c1 = vert ? C[ids[i]].x : C[ids[i]].y;\n            int c2 = vert ? C[ids[i+1]].x : C[ids[i+1]].y;\n            if (c1 == c2) continue;\n            int lo, hi;\n            if (vert) { lo = max(R.a+1, c1+1); hi = min(R.c-1, c2); }\n            else { lo = max(R.b+1, c1+1); hi = min(R.d-1, c2); }\n            if (lo > hi) continue;\n            \n            long long leftA = acc, rightA = total - acc;\n            int lCnt = i + 1, rCnt = (int)ids.size() - i - 1;\n            double ratio = (double)leftA / rightA;\n            int opt = vert ? R.a + (int)((w * ratio) / (1 + ratio))\n                           : R.b + (int)((h * ratio) / (1 + ratio));\n            opt = max(lo, min(hi, opt));\n            \n            int spread = (depth < 3) ? 18 : (depth < 6) ? 8 : 2;\n            vector<int> cands;\n            for (int d = -spread; d <= spread; d++) cands.push_back(max(lo, min(hi, opt + d)));\n            \n            if (doRand && depth < 5) {\n                uniform_int_distribution<int> dist(lo, hi);\n                int numRand = (depth < 3) ? 6 : 3;\n                for (int j = 0; j < numRand; j++) cands.push_back(dist(rng));\n            }\n            \n            sort(cands.begin(), cands.end());\n            cands.erase(unique(cands.begin(), cands.end()), cands.end());\n            \n            for (int s : cands) {\n                long long leftC = vert ? (long long)(s-R.a)*h : (long long)w*(s-R.b);\n                long long rightC = vert ? (long long)(R.c-s)*h : (long long)w*(R.d-s);\n                double score = calcScore(lCnt, leftC, leftA) + calcScore(rCnt, rightC, rightA);\n                bool accept = score > bestScore;\n                if (!accept && doRand && depth < 5 && bestScore > -1e17 && \n                    score > bestScore - 0.03 * (lCnt + rCnt) && rng() % 30 == 0)\n                    accept = true;\n                if (accept) { bestScore = score; bestSplit = s; bestVert = vert; bestIdx = i; }\n            }\n        }\n    }\n    \n    if (bestSplit == -1) {\n        for (int i : ids) res[i] = {C[i].x, C[i].y, C[i].x+1, C[i].y+1};\n        return;\n    }\n    sort(ids.begin(), ids.end(), [&](int a, int b) {\n        return bestVert ? C[a].x < C[b].x : C[a].y < C[b].y;\n    });\n    vector<int> left(ids.begin(), ids.begin()+bestIdx+1);\n    vector<int> right(ids.begin()+bestIdx+1, ids.end());\n    if (bestVert) {\n        solve({R.a, R.b, bestSplit, R.d}, left, C, res, rng, depth + 1, doRand);\n        solve({bestSplit, R.b, R.c, R.d}, right, C, res, rng, depth + 1, doRand);\n    } else {\n        solve({R.a, R.b, R.c, bestSplit}, left, C, res, rng, depth + 1, doRand);\n        solve({R.a, bestSplit, R.c, R.d}, right, C, res, rng, depth + 1, doRand);\n    }\n}\n\ndouble totalSat(const vector<Rect>& res, const vector<Company>& C) {\n    double score = 0;\n    for (size_t i = 0; i < res.size(); i++) {\n        int s = (res[i].c - res[i].a) * (res[i].d - res[i].b);\n        double r = (double)min(C[i].r, s) / max(C[i].r, s);\n        score += (2.0 - r) * r;\n    }\n    return score;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(nullptr);\n    int n; cin >> n;\n    vector<Company> C(n);\n    unsigned int h = 12345;\n    for (int i = 0; i < n; i++) {\n        cin >> C[i].x >> C[i].y >> C[i].r;\n        h ^= (unsigned)C[i].x * 0x9e3779b9;\n        h ^= (unsigned)C[i].y * 0x517cc1b7;\n        h ^= (unsigned)C[i].r * 0x27d4eb2d;\n    }\n    \n    vector<Rect> bestRes(n);\n    double bestScore = -1;\n    \n    auto start = chrono::steady_clock::now();\n    mt19937 rng(h);\n    int trial = 0;\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start).count() > 4500) break;\n        \n        if (trial > 0 && trial % 50 == 0) rng.seed(h + trial);\n        \n        vector<Rect> res(n);\n        vector<int> ids(n); iota(ids.begin(), ids.end(), 0);\n        solve({0,0,10000,10000}, ids, C, res, rng, 0, trial > 0);\n        double score = totalSat(res, C);\n        if (score > bestScore) { bestScore = score; bestRes = res; }\n        trial++;\n    }\n    \n    for (int i = 0; i < n; i++)\n        cout << bestRes[i].a << \" \" << bestRes[i].b << \" \" << bestRes[i].c << \" \" << bestRes[i].d << \"\\n\";\n    return 0;\n}","ahc002":"#include <iostream>\n#include <algorithm>\n#include <chrono>\n#include <cstring>\n#include <random>\n\nusing namespace std;\n\nconst int DEPTH_LIMIT = 120; \nconst int MAX_TILES = 2500;\n\nint tile_of[2500];\nint val_of[2500];\nbool vis[MAX_TILES];\nbool can_left[2500];\nbool can_right[2500];\n\nint temp_vis[2500];\nint dfs_stack[2500];\nint current_stamp = 0;\n\nstruct DFSResult {\n    int cnt;\n    int sum_p;\n};\n\nDFSResult cell_dfs(int start_node, int f1, int f2, int f3) {\n    current_stamp++;\n    int cnt = 0;\n    int sum_p = 0;\n    int stack_ptr = 0;\n    dfs_stack[stack_ptr++] = start_node;\n    temp_vis[start_node] = current_stamp;\n    \n    while (stack_ptr > 0) {\n        int node = dfs_stack[--stack_ptr];\n        cnt++;\n        sum_p += val_of[node];\n        if (cnt >= DEPTH_LIMIT) break;\n        \n        int n_node;\n        if (node >= 50) {\n            n_node = node - 50;\n            if (temp_vis[n_node] != current_stamp) {\n                int T = tile_of[n_node];\n                if (T != f1 && T != f2 && T != f3 && !vis[T]) {\n                    temp_vis[n_node] = current_stamp;\n                    dfs_stack[stack_ptr++] = n_node;\n                }\n            }\n        }\n        if (node < 2450) {\n            n_node = node + 50;\n            if (temp_vis[n_node] != current_stamp) {\n                int T = tile_of[n_node];\n                if (T != f1 && T != f2 && T != f3 && !vis[T]) {\n                    temp_vis[n_node] = current_stamp;\n                    dfs_stack[stack_ptr++] = n_node;\n                }\n            }\n        }\n        if (can_left[node]) {\n            n_node = node - 1;\n            if (temp_vis[n_node] != current_stamp) {\n                int T = tile_of[n_node];\n                if (T != f1 && T != f2 && T != f3 && !vis[T]) {\n                    temp_vis[n_node] = current_stamp;\n                    dfs_stack[stack_ptr++] = n_node;\n                }\n            }\n        }\n        if (can_right[node]) {\n            n_node = node + 1;\n            if (temp_vis[n_node] != current_stamp) {\n                int T = tile_of[n_node];\n                if (T != f1 && T != f2 && T != f3 && !vis[T]) {\n                    temp_vis[n_node] = current_stamp;\n                    dfs_stack[stack_ptr++] = n_node;\n                }\n            }\n        }\n    }\n    return {cnt, sum_p};\n}\n\nstruct Candidate {\n    int p;\n    int c_w;\n    int comp_size;\n    int sum_p;\n    int w;\n    int start_node;\n    char dir;\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int si, sj;\n    if (!(cin >> si >> sj)) return 0;\n\n    for (int i = 0; i < 2500; ++i) cin >> tile_of[i];\n    for (int i = 0; i < 2500; ++i) cin >> val_of[i];\n    \n    for (int i = 0; i < 2500; ++i) {\n        can_left[i] = (i % 50) != 0;\n        can_right[i] = (i % 50) != 49;\n    }\n\n    auto cmp = [&](const Candidate& a, const Candidate& b) {\n        if (a.comp_size != b.comp_size) return a.comp_size > b.comp_size;\n        \n        if (a.comp_size < DEPTH_LIMIT) {\n            if (a.c_w != b.c_w) return a.c_w > b.c_w;\n            if (a.sum_p != b.sum_p) return a.sum_p > b.sum_p;\n            if (a.p != b.p) return a.p > b.p;\n        }\n        \n        return false; \n    };\n\n    std::mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    char best_path[2500];\n    int best_path_len = 0;\n    int best_score = -1;\n\n    // 150 raw C-style runs fits safely in ~12ms thanks to eliminating std::string\n    for (int run = 0; run < 150; ++run) {\n        memset(vis, false, sizeof(vis));\n        \n        int u = tile_of[si * 50 + sj];\n        vis[u] = true;\n        int curr_node = si * 50 + sj;\n        int v = -1; \n        int curr_score = val_of[curr_node];\n        \n        char curr_path[2500];\n        int path_len = 0;\n        \n        while (true) {\n            Candidate candidates[4];\n            int num_candidates = 0;\n            int n_node, w, c_w;\n            \n            if (curr_node >= 50) {\n                n_node = curr_node - 50; w = tile_of[n_node];\n                if (w != u && w != v && !vis[w]) {\n                    c_w = 0; \n                    if (n_node >= 50) { int T = tile_of[n_node - 50]; if (T != u && T != v && T != w && !vis[T]) c_w++; }\n                    if (n_node < 2450) { int T = tile_of[n_node + 50]; if (T != u && T != v && T != w && !vis[T]) c_w++; }\n                    if (can_left[n_node]) { int T = tile_of[n_node - 1]; if (T != u && T != v && T != w && !vis[T]) c_w++; }\n                    if (can_right[n_node]) { int T = tile_of[n_node + 1]; if (T != u && T != v && T != w && !vis[T]) c_w++; }\n                    candidates[num_candidates++] = {val_of[n_node], c_w, 0, 0, w, n_node, 'U'};\n                }\n            }\n            if (curr_node < 2450) {\n                n_node = curr_node + 50; w = tile_of[n_node];\n                if (w != u && w != v && !vis[w]) {\n                    c_w = 0; \n                    if (n_node >= 50) { int T = tile_of[n_node - 50]; if (T != u && T != v && T != w && !vis[T]) c_w++; }\n                    if (n_node < 2450) { int T = tile_of[n_node + 50]; if (T != u && T != v && T != w && !vis[T]) c_w++; }\n                    if (can_left[n_node]) { int T = tile_of[n_node - 1]; if (T != u && T != v && T != w && !vis[T]) c_w++; }\n                    if (can_right[n_node]) { int T = tile_of[n_node + 1]; if (T != u && T != v && T != w && !vis[T]) c_w++; }\n                    candidates[num_candidates++] = {val_of[n_node], c_w, 0, 0, w, n_node, 'D'};\n                }\n            }\n            if (can_left[curr_node]) {\n                n_node = curr_node - 1; w = tile_of[n_node];\n                if (w != u && w != v && !vis[w]) {\n                    c_w = 0; \n                    if (n_node >= 50) { int T = tile_of[n_node - 50]; if (T != u && T != v && T != w && !vis[T]) c_w++; }\n                    if (n_node < 2450) { int T = tile_of[n_node + 50]; if (T != u && T != v && T != w && !vis[T]) c_w++; }\n                    if (can_left[n_node]) { int T = tile_of[n_node - 1]; if (T != u && T != v && T != w && !vis[T]) c_w++; }\n                    if (can_right[n_node]) { int T = tile_of[n_node + 1]; if (T != u && T != v && T != w && !vis[T]) c_w++; }\n                    candidates[num_candidates++] = {val_of[n_node], c_w, 0, 0, w, n_node, 'L'};\n                }\n            }\n            if (can_right[curr_node]) {\n                n_node = curr_node + 1; w = tile_of[n_node];\n                if (w != u && w != v && !vis[w]) {\n                    c_w = 0; \n                    if (n_node >= 50) { int T = tile_of[n_node - 50]; if (T != u && T != v && T != w && !vis[T]) c_w++; }\n                    if (n_node < 2450) { int T = tile_of[n_node + 50]; if (T != u && T != v && T != w && !vis[T]) c_w++; }\n                    if (can_left[n_node]) { int T = tile_of[n_node - 1]; if (T != u && T != v && T != w && !vis[T]) c_w++; }\n                    if (can_right[n_node]) { int T = tile_of[n_node + 1]; if (T != u && T != v && T != w && !vis[T]) c_w++; }\n                    candidates[num_candidates++] = {val_of[n_node], c_w, 0, 0, w, n_node, 'R'};\n                }\n            }\n            \n            if (num_candidates == 0) break;\n            \n            if (num_candidates > 1) {\n                for (int it = 1; it < num_candidates; ++it) {\n                    int j_idx = rng() % (it + 1);\n                    swap(candidates[it], candidates[j_idx]);\n                }\n                \n                for (int idx = 0; idx < num_candidates; ++idx) {\n                    DFSResult res = cell_dfs(candidates[idx].start_node, u, v, candidates[idx].w);\n                    candidates[idx].comp_size = res.cnt;\n                    candidates[idx].sum_p = (res.cnt < DEPTH_LIMIT) ? res.sum_p : 0;\n                }\n                \n                for (int it = 1; it < num_candidates; ++it) {\n                    Candidate key = candidates[it];\n                    int j_idx = it - 1;\n                    while (j_idx >= 0 && cmp(key, candidates[j_idx])) {\n                        candidates[j_idx + 1] = candidates[j_idx];\n                        j_idx--;\n                    }\n                    candidates[j_idx + 1] = key;\n                }\n            }\n            \n            Candidate& best = candidates[0];\n            vis[best.w] = true;\n            curr_path[path_len++] = best.dir;\n            curr_score += best.p;\n            \n            v = u;\n            u = best.w;\n            curr_node = best.start_node;\n        }\n        \n        if (curr_score > best_score) {\n            best_score = curr_score;\n            memcpy(best_path, curr_path, path_len);\n            best_path_len = path_len;\n        }\n    }\n    \n    cout.write(best_path, best_path_len) << \"\\n\";\n\n    return 0;\n}","ahc003":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n\nusing namespace std;\n\nconst int N = 30;\nbool visited_h[N][N-1] = {false};\nbool visited_v[N-1][N] = {false};\ndouble W_h[N][N-1], W_v[N-1][N];\nint visit_count_h[N][N-1] = {0};\nint visit_count_v[N-1][N] = {0};\n\nint visited_cnt_h[N] = {0};\nint visited_cnt_v[N] = {0};\ndouble row_sum_h[N] = {0}, row_cnt_h[N] = {0};\ndouble col_sum_v[N] = {0}, col_cnt_v[N] = {0};\n\ndouble global_sum_h = 0, global_cnt_h = 0;\ndouble global_sum_v = 0, global_cnt_v = 0;\n\nvector<vector<double>> dist(N, vector<double>(N));\nvector<vector<pair<int, int>>> prev_node(N, vector<pair<int, int>>(N));\n\ndouble get_w_h(int i, int j) {\n    if (visited_h[i][j]) return W_h[i][j];\n    \n    double base_w = (global_cnt_h > 0) ? (global_sum_h / global_cnt_h) : 5000.0;\n    \n    if (visited_cnt_h[i] == 0) return base_w;\n    \n    double row_w = row_sum_h[i] / row_cnt_h[i];\n    double alpha_row = (double)visited_cnt_h[i] / 29.0;\n    return base_w + alpha_row * (row_w - base_w);\n}\n\ndouble get_w_v(int i, int j) {\n    if (visited_v[i][j]) return W_v[i][j];\n    \n    double base_w = (global_cnt_v > 0) ? (global_sum_v / global_cnt_v) : 5000.0;\n    \n    if (visited_cnt_v[j] == 0) return base_w;\n    \n    double col_w = col_sum_v[j] / col_cnt_v[j];\n    double alpha_col = (double)visited_cnt_v[j] / 29.0;\n    return base_w + alpha_col * (col_w - base_w);\n}\n\nstring dijkstra(int si, int sj, int ti, int tj) {\n    for (int i = 0; i < N; ++i) {\n        fill(dist[i].begin(), dist[i].end(), 1e18);\n        fill(prev_node[i].begin(), prev_node[i].end(), make_pair(-1, -1));\n    }\n    priority_queue<pair<double, pair<int, int>>, vector<pair<double, pair<int, int>>>, greater<>> pq;\n    dist[si][sj] = 0;\n    pq.push({0.0, {si, sj}});\n\n    while (!pq.empty()) {\n        auto [d, u] = pq.top();\n        pq.pop();\n        int i = u.first, j = u.second;\n        if (d > dist[i][j] + 1e-9) continue;\n        if (i == ti && j == tj) break;\n\n        if (i > 0) {\n            double w = get_w_v(i - 1, j);\n            if (dist[i][j] + w < dist[i - 1][j] - 1e-9) {\n                dist[i - 1][j] = dist[i][j] + w;\n                prev_node[i - 1][j] = {i, j};\n                pq.push({dist[i - 1][j], {i - 1, j}});\n            }\n        }\n        if (i < N - 1) {\n            double w = get_w_v(i, j);\n            if (dist[i][j] + w < dist[i + 1][j] - 1e-9) {\n                dist[i + 1][j] = dist[i][j] + w;\n                prev_node[i + 1][j] = {i, j};\n                pq.push({dist[i + 1][j], {i + 1, j}});\n            }\n        }\n        if (j > 0) {\n            double w = get_w_h(i, j - 1);\n            if (dist[i][j] + w < dist[i][j - 1] - 1e-9) {\n                dist[i][j - 1] = dist[i][j] + w;\n                prev_node[i][j - 1] = {i, j};\n                pq.push({dist[i][j - 1], {i, j - 1}});\n            }\n        }\n        if (j < N - 1) {\n            double w = get_w_h(i, j);\n            if (dist[i][j] + w < dist[i][j + 1] - 1e-9) {\n                dist[i][j + 1] = dist[i][j] + w;\n                prev_node[i][j + 1] = {i, j};\n                pq.push({dist[i][j + 1], {i, j + 1}});\n            }\n        }\n    }\n\n    string path = \"\";\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        auto p = prev_node[ci][cj];\n        int pi = p.first, pj = p.second;\n        if (pi == ci - 1) path += 'D';\n        else if (pi == ci + 1) path += 'U';\n        else if (pj == cj - 1) path += 'R';\n        else if (pj == cj + 1) path += 'L';\n        ci = pi;\n        cj = pj;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N - 1; ++j) W_h[i][j] = 5000.0;\n    }\n    for (int i = 0; i < N - 1; ++i) {\n        for (int j = 0; j < N; ++j) W_v[i][j] = 5000.0;\n    }\n\n    for (int k = 0; k < 1000; ++k) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n\n        string path = dijkstra(si, sj, ti, tj);\n        cout << path << \"\\n\" << flush;\n\n        long long result;\n        cin >> result;\n\n        double L = 0;\n        int m = path.length();\n        vector<tuple<int, int, int>> edges;\n        \n        int ci = si, cj = sj;\n        for (char c : path) {\n            if (c == 'U') {\n                edges.push_back({1, ci - 1, cj});\n                L += get_w_v(ci - 1, cj);\n                ci--;\n            } else if (c == 'D') {\n                edges.push_back({1, ci, cj});\n                L += get_w_v(ci, cj);\n                ci++;\n            } else if (c == 'L') {\n                edges.push_back({0, ci, cj - 1});\n                L += get_w_h(ci, cj - 1);\n                cj--;\n            } else if (c == 'R') {\n                edges.push_back({0, ci, cj});\n                L += get_w_h(ci, cj);\n                cj++;\n            }\n        }\n\n        if (m > 0) {\n            double delta = (result - L) / m;\n            for (auto& [type, i, j] : edges) {\n                if (type == 0) {\n                    visit_count_h[i][j]++;\n                    \n                    // Theoretically optimal symmetric learning rate: yields exact running average\n                    double lr = 1.0 / (double)visit_count_h[i][j];\n                    \n                    if (!visited_h[i][j]) {\n                        visited_h[i][j] = true;\n                        visited_cnt_h[i]++;\n                        W_h[i][j] = get_w_h(i, j); \n                    }\n                    \n                    W_h[i][j] = max(100.0, min(9000.0, W_h[i][j] + lr * delta));\n                    \n                    row_sum_h[i] += W_h[i][j];\n                    row_cnt_h[i] += 1.0;\n                    global_sum_h += W_h[i][j];\n                    global_cnt_h += 1.0;\n                } else {\n                    visit_count_v[i][j]++;\n                    \n                    double lr = 1.0 / (double)visit_count_v[i][j];\n                    \n                    if (!visited_v[i][j]) {\n                        visited_v[i][j] = true;\n                        visited_cnt_v[j]++;\n                        W_v[i][j] = get_w_v(i, j);\n                    }\n                    \n                    W_v[i][j] = max(100.0, min(9000.0, W_v[i][j] + lr * delta));\n                    \n                    col_sum_v[j] += W_v[i][j];\n                    col_cnt_v[j] += 1.0;\n                    global_sum_v += W_v[i][j];\n                    global_cnt_v += 1.0;\n                }\n            }\n        }\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    cin >> N >> M;\n    vector<string> s(M);\n    for (int i = 0; i < M; i++) cin >> s[i];\n    \n    struct Placement { int type, row, col, len, str_idx; };\n    vector<Placement> all_placements;\n    for (int m = 0; m < M; m++) {\n        int k = s[m].size();\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++)\n            all_placements.push_back({0, i, j, k, m});\n        for (int j = 0; j < N; j++) for (int i = 0; i < N; i++)\n            all_placements.push_back({1, i, j, k, m});\n    }\n    int P = all_placements.size();\n    \n    vector<vector<pair<int,int>>> placement_cells(P), cell_placements(N*N);\n    for (int p = 0; p < P; p++) {\n        auto& pl = all_placements[p];\n        for (int q = 0; q < pl.len; q++) {\n            int r = pl.type==0 ? pl.row : (pl.row+q)%N;\n            int c = pl.type==0 ? (pl.col+q)%N : pl.col;\n            placement_cells[p].push_back({r,c});\n            cell_placements[r*N+c].push_back({p,q});\n        }\n    }\n    \n    vector<int> order(M); iota(order.begin(), order.end(), 0);\n    vector<int> cell_order(N*N); iota(cell_order.begin(), cell_order.end(), 0);\n    \n    auto init_mismatch = [&](vector<string>& grid, vector<int16_t>& mc) {\n        fill(mc.begin(), mc.end(), 0);\n        for (int ci = 0; ci < N*N; ci++) {\n            int r = ci/N, c = ci%N; char g = grid[r][c];\n            for (auto [p, q] : cell_placements[ci])\n                if (g != s[all_placements[p].str_idx][q]) mc[p]++;\n        }\n    };\n    \n    auto local_search = [&](vector<string>& grid, vector<int16_t>& mc, double deadline, mt19937& rng, bool shuffle = false) -> int {\n        vector<int> smc(M, 0);\n        for (int p = 0; p < P; p++) if (mc[p] == 0) smc[all_placements[p].str_idx]++;\n        int sc = 0; for (int m = 0; m < M; m++) if (smc[m] > 0) sc++;\n        vector<int> temp_chg(M, 0), affected; affected.reserve(200);\n        for (int iter = 0; iter < 100; iter++) {\n            if ((double)(clock()) / CLOCKS_PER_SEC > deadline) break;\n            if (shuffle && iter % 2 == 0) std::shuffle(cell_order.begin(), cell_order.end(), rng);\n            bool imp = false;\n            for (int idx = 0; idx < N*N; idx++) {\n                if (idx % 10 == 0 && (double)(clock()) / CLOCKS_PER_SEC > deadline) { idx = N*N; break; }\n                int ci = cell_order[idx];\n                int r = ci/N, c = ci%N; char oc = grid[r][c]; int bd = 0; char bc = oc;\n                for (int ch = 0; ch < 8; ch++) {\n                    char nc = 'A'+ch; if (nc == oc) continue; affected.clear();\n                    for (auto [p,q] : cell_placements[ci]) {\n                        int m = all_placements[p].str_idx; char ex = s[m][q];\n                        bool wm = (oc==ex), im = (nc==ex); if (wm == im) continue;\n                        if (wm && !im) { if (mc[p]==0) { if (!temp_chg[m]) affected.push_back(m); temp_chg[m]--; } }\n                        else if (mc[p] == 1) { if (!temp_chg[m]) affected.push_back(m); temp_chg[m]++; }\n                    }\n                    int d = 0;\n                    for (int m : affected) {\n                        bool was = smc[m] > 0, is = smc[m] + temp_chg[m] > 0;\n                        if (!was && is) d++; else if (was && !is) d--; temp_chg[m] = 0;\n                    }\n                    if (d > bd) { bd = d; bc = nc; }\n                }\n                if (bd > 0) {\n                    grid[r][c] = bc;\n                    for (auto [p,q] : cell_placements[ci]) {\n                        int m = all_placements[p].str_idx; char ex = s[m][q];\n                        bool wm = (oc==ex), im = (bc==ex); if (wm == im) continue;\n                        if (wm && !im) { mc[p]++; if (mc[p]==1) smc[m]--; }\n                        else { mc[p]--; if (mc[p]==0) smc[m]++; }\n                    }\n                    sc += bd; imp = true;\n                }\n            }\n            if (!imp) break;\n        }\n        return sc;\n    };\n    \n    auto greedy_init = [&](vector<string>& grid, mt19937& rng) {\n        fill(grid.begin(), grid.end(), string(N, '.'));\n        for (int idx : order) {\n            int k = s[idx].size(); char fc = s[idx][0];\n            int best_overlap = -1; vector<int> candidates;\n            for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n                if (grid[i][j] != '.' && grid[i][j] != fc) continue;\n                bool ok_h = true; int ov_h = 0;\n                for (int q = 0; q < k; q++) {\n                    int c = (j+q)%N; char ex = grid[i][c];\n                    if (ex == '.') continue;\n                    if (ex == s[idx][q]) ov_h++; else { ok_h = false; break; }\n                }\n                if (ok_h) { if (ov_h > best_overlap) { best_overlap = ov_h; candidates.clear(); } if (ov_h >= best_overlap) candidates.push_back(i*N+j); }\n                bool ok_v = true; int ov_v = 0;\n                for (int q = 0; q < k; q++) {\n                    int r = (i+q)%N; char ex = grid[r][j];\n                    if (ex == '.') continue;\n                    if (ex == s[idx][q]) ov_v++; else { ok_v = false; break; }\n                }\n                if (ok_v) { if (ov_v > best_overlap) { best_overlap = ov_v; candidates.clear(); } if (ov_v >= best_overlap) candidates.push_back(N*N+i*N+j); }\n            }\n            if (!candidates.empty()) {\n                int ch = candidates[rng() % candidates.size()];\n                int type = ch/N/N, i = (ch%(N*N))/N, j = ch%N;\n                for (int q = 0; q < k; q++) { int r = type==0 ? i : (i+q)%N, c = type==0 ? (j+q)%N : j; grid[r][c] = s[idx][q]; }\n            }\n        }\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++)\n            if (grid[i][j] == '.') grid[i][j] = 'A' + rng() % 8;\n    };\n    \n    vector<string> best_grid(N); int best_score = -1;\n    double t0 = (double)(clock()) / CLOCKS_PER_SEC;\n    int seeds[] = {42, 137, 271, 499};\n    \n    for (int trial = 0; trial < 3; trial++) {\n        if ((double)(clock()) / CLOCKS_PER_SEC - t0 > 0.5) break;\n        mt19937 rng(seeds[trial]);\n        shuffle(order.begin(), order.end(), rng);\n        stable_sort(order.begin(), order.end(), [&](int a, int b) { return s[a].size() > s[b].size(); });\n        vector<string> grid(N); greedy_init(grid, rng);\n        vector<int16_t> mc(P); init_mismatch(grid, mc);\n        int sc = local_search(grid, mc, t0 + 0.17, rng);\n        if (sc > best_score) { best_score = sc; best_grid = grid; }\n    }\n    \n    mt19937 rng(42);\n    for (int perturb = 0; perturb < 20; perturb++) {\n        double now = (double)(clock()) / CLOCKS_PER_SEC;\n        if (now - t0 > 1.8) break;\n        vector<string> grid = best_grid;\n        int n_changes = 3 + rng() % 8;\n        for (int i = 0; i < n_changes; i++) { int r = rng()%N, c = rng()%N; grid[r][c] = 'A'+rng()%8; }\n        vector<int16_t> mc(P); init_mismatch(grid, mc);\n        int sc = local_search(grid, mc, now + 0.18, rng);\n        if (sc > best_score) { best_score = sc; best_grid = grid; }\n    }\n    \n    vector<int16_t> mc(P); init_mismatch(best_grid, mc);\n    local_search(best_grid, mc, t0 + 2.7, rng, true);\n    for (int i = 0; i < N; i++) cout << best_grid[i] << \"\\n\";\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\nusing namespace chrono;\n\nint N, si, sj;\nvector<string> grid;\nint cost[70][70];\nvector<pair<int,int>> roads;\nint seg_id[70][70][2];\nint num_segs;\n\nvoid find_segments() {\n    memset(seg_id, -1, sizeof(seg_id));\n    num_segs = 0;\n    for (int i = 0; i < N; i++) {\n        int j = 0;\n        while (j < N) {\n            if (grid[i][j] == '#') { j++; continue; }\n            int start = j;\n            while (j < N && grid[i][j] != '#') j++;\n            for (int k = start; k < j; k++) seg_id[i][k][0] = num_segs++;\n        }\n    }\n    for (int j = 0; j < N; j++) {\n        int i = 0;\n        while (i < N) {\n            if (grid[i][j] == '#') { i++; continue; }\n            int start = i;\n            while (i < N && grid[i][j] != '#') i++;\n            for (int k = start; k < i; k++) seg_id[k][j][1] = num_segs++;\n        }\n    }\n}\n\nvector<int> dist_arr, prev_arr;\nvoid dijkstra(int sx, int sy) {\n    int V = N * N;\n    dist_arr.assign(V, INT_MAX);\n    prev_arr.assign(V, -1);\n    dist_arr[sx * N + sy] = 0;\n    priority_queue<pair<int,int>, vector<pair<int,int>>, greater<>> pq;\n    pq.push({0, sx * N + sy});\n    const int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, -1, 1};\n    while (!pq.empty()) {\n        auto [d, u] = pq.top(); pq.pop();\n        if (d > dist_arr[u]) continue;\n        int x = u / N, y = u % N;\n        for (int k = 0; k < 4; k++) {\n            int nx = x + dx[k], ny = y + dy[k];\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N || grid[nx][ny] == '#') continue;\n            int v = nx * N + ny, nd = d + cost[nx][ny];\n            if (nd < dist_arr[v]) { dist_arr[v] = nd; prev_arr[v] = u; pq.push({nd, v}); }\n        }\n    }\n}\n\nint tour_cost(const vector<int>& tour, const vector<vector<int>>& dist) {\n    int c = 0, m = tour.size();\n    for (int i = 0; i < m; i++) c += dist[tour[i]][tour[(i+1)%m]];\n    return c;\n}\n\nvector<int> nn_tour(int m, const vector<vector<int>>& dist, mt19937& rng) {\n    vector<int> tour(m);\n    iota(tour.begin(), tour.end(), 0);\n    vector<bool> vis(m, false);\n    vis[0] = true;\n    int cur = 0;\n    for (int iter = 1; iter < m; iter++) {\n        int best_d = INT_MAX;\n        vector<int> bests;\n        for (int i = 0; i < m; i++) {\n            if (vis[i]) continue;\n            if (dist[cur][i] < best_d) { best_d = dist[cur][i]; bests = {i}; }\n            else if (dist[cur][i] == best_d) bests.push_back(i);\n        }\n        int choice = bests[rng() % bests.size()];\n        vis[choice] = true;\n        tour[iter] = choice;\n        cur = choice;\n    }\n    return tour;\n}\n\nvoid two_opt(vector<int>& tour, const vector<vector<int>>& dist, const function<bool()>& time_ok) {\n    int m = tour.size();\n    bool improved = true;\n    while (improved && time_ok()) {\n        improved = false;\n        for (int i = 0; i < m - 1 && !improved; i++)\n            for (int j = i + 2; j < m && !improved; j++) {\n                if (i == 0 && j == m - 1) continue;\n                if (dist[tour[i]][tour[i+1]] + dist[tour[j]][tour[(j+1)%m]] > dist[tour[i]][tour[j]] + dist[tour[i+1]][tour[(j+1)%m]])\n                    { reverse(tour.begin() + i + 1, tour.begin() + j + 1); improved = true; }\n            }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    auto total_start = steady_clock::now();\n    \n    cin >> N >> si >> sj;\n    grid.resize(N);\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] != '#') { cost[i][j] = grid[i][j] - '0'; roads.push_back({i, j}); }\n    }\n    find_segments();\n    \n    vector<bool> covered(num_segs, false);\n    covered[seg_id[si][sj][0]] = covered[seg_id[si][sj][1]] = true;\n    vector<pair<int,int>> selected = {{si, sj}};\n    while (true) {\n        int best_count = 0, best_dist = INT_MAX;\n        pair<int,int> best_cell = {-1, -1};\n        for (auto& [i, j] : roads) {\n            int count = (seg_id[i][j][0]!=-1 && !covered[seg_id[i][j][0]]) + (seg_id[i][j][1]!=-1 && !covered[seg_id[i][j][1]]);\n            if (count > best_count) { best_count = count; best_dist = INT_MAX; best_cell = {i, j}; }\n            if (count == best_count && count > 0) {\n                int min_d = abs(i-si) + abs(j-sj);\n                for (auto& [r, c] : selected) min_d = min(min_d, abs(i-r) + abs(j-c));\n                if (min_d < best_dist) { best_dist = min_d; best_cell = {i, j}; }\n            }\n        }\n        if (best_count == 0) break;\n        selected.push_back(best_cell);\n        covered[seg_id[best_cell.first][best_cell.second][0]] = covered[seg_id[best_cell.first][best_cell.second][1]] = true;\n    }\n    \n    int orig_m = selected.size();\n    vector<int> seg_count(num_segs, 0);\n    for (int i = 0; i < orig_m; i++) {\n        int s0 = seg_id[selected[i].first][selected[i].second][0];\n        int s1 = seg_id[selected[i].first][selected[i].second][1];\n        if (s0 != -1) seg_count[s0]++;\n        if (s1 != -1) seg_count[s1]++;\n    }\n    vector<pair<int,int>> pruned;\n    for (int i = 0; i < orig_m; i++) {\n        int s0 = seg_id[selected[i].first][selected[i].second][0];\n        int s1 = seg_id[selected[i].first][selected[i].second][1];\n        bool can_remove = (i > 0);\n        if (s0 != -1 && seg_count[s0] <= 1) can_remove = false;\n        if (s1 != -1 && seg_count[s1] <= 1) can_remove = false;\n        if (!can_remove) pruned.push_back(selected[i]);\n        else { if (s0 != -1) seg_count[s0]--; if (s1 != -1) seg_count[s1]--; }\n    }\n    \n    int m = pruned.size();\n    if (m <= 1) { cout << \"\" << endl; return 0; }\n    \n    vector<vector<int>> dist(m, vector<int>(m));\n    vector<vector<int>> all_prev(m);\n    for (int i = 0; i < m; i++) {\n        dijkstra(pruned[i].first, pruned[i].second);\n        all_prev[i] = prev_arr;\n        for (int j = 0; j < m; j++) dist[i][j] = dist_arr[pruned[j].first * N + pruned[j].second];\n    }\n    \n    auto time_ok = [&]() { return chrono::duration_cast<chrono::microseconds>(steady_clock::now() - total_start).count() < 2500000; };\n    \n    mt19937 rng(42);\n    vector<int> best_tour = nn_tour(m, dist, rng);\n    two_opt(best_tour, dist, time_ok);\n    int best_cost = tour_cost(best_tour, dist);\n    \n    for (int trial = 0; trial < 30 && time_ok(); trial++) {\n        vector<int> try_tour = nn_tour(m, dist, rng);\n        two_opt(try_tour, dist, time_ok);\n        int try_cost = tour_cost(try_tour, dist);\n        if (try_cost < best_cost) { best_tour = try_tour; best_cost = try_cost; }\n    }\n    \n    string result;\n    for (int idx = 0; idx < m; idx++) {\n        int from = best_tour[idx], to = best_tour[(idx + 1) % m];\n        if (from == to) continue;\n        int sx = pruned[from].first * N + pruned[from].second;\n        int ex = pruned[to].first * N + pruned[to].second;\n        vector<int> trace;\n        for (int u = ex; u != sx && u != -1; u = all_prev[from][u]) trace.push_back(u);\n        reverse(trace.begin(), trace.end());\n        int cur = sx;\n        for (int next : trace) {\n            int cx = cur/N, cy = cur%N, nx = next/N, ny = next%N;\n            result += (nx==cx-1) ? 'U' : (nx==cx+1) ? 'D' : (ny==cy-1) ? 'L' : 'R';\n            cur = next;\n        }\n    }\n    cout << result << endl;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K, R;\n    cin >> N >> M >> K >> R;\n    \n    vector<vector<int>> d(N, vector<int>(K));\n    for (int i = 0; i < N; i++)\n        for (int k = 0; k < K; k++) cin >> d[i][k];\n    \n    vector<vector<int>> deps(N), rdeps(N);\n    for (int i = 0; i < R; i++) {\n        int u, v; cin >> u >> v; u--; v--;\n        deps[v].push_back(u); rdeps[u].push_back(v);\n    }\n    \n    vector<int> topo;\n    { vector<int> indeg(N,0);\n      for(int v=0;v<N;v++) for(int u:deps[v]) indeg[v]++;\n      queue<int> q;\n      for(int i=0;i<N;i++) if(indeg[i]==0) q.push(i);\n      while(!q.empty()) { int u=q.front(); q.pop(); topo.push_back(u);\n        for(int v:rdeps[u]) if(--indeg[v]==0) q.push(v); } }\n    \n    vector<int> crit(N, 1);\n    for(int u:topo) for(int v:rdeps[u]) crit[u]=max(crit[u], 1+crit[v]);\n    \n    vector<int> unblock(N, 0);\n    for(int i = N-1; i >= 0; i--) {\n        int t = topo[i];\n        for(int v: rdeps[t]) unblock[t] += 1 + unblock[v];\n    }\n    \n    vector<vector<int>> proven(M, vector<int>(K, 0));\n    vector<vector<int>> est(M, vector<int>(K, 0));\n    vector<int> tstatus(N, -1), mtask(M, -1), tstart(N, -1), tcount(M, 0);\n    \n    auto can_start = [&](int t) {\n        if(tstatus[t] != -1) return false;\n        for(int dep: deps[t]) if(tstatus[dep] != 1) return false;\n        return true;\n    };\n    \n    auto est_w = [&](int t, int m) {\n        int w = 0;\n        for(int k = 0; k < K; k++) w += max(0, d[t][k] - est[m][k]);\n        return w;\n    };\n    \n    auto can_1day = [&](int t, int m) {\n        for(int k = 0; k < K; k++) if(d[t][k] > proven[m][k]) return false;\n        return true;\n    };\n    \n    for(int day = 1; day <= 2000; day++) {\n        vector<int> avail;\n        for(int i = 0; i < N; i++) if(can_start(i)) avail.push_back(i);\n        \n        vector<int> freem;\n        for(int j = 0; j < M; j++) if(mtask[j] == -1) freem.push_back(j);\n        \n        vector<int> num_1day(N, 0);\n        for(int t: avail) for(int m: freem) if(can_1day(t, m)) num_1day[t]++;\n        \n        vector<int> first_order = avail;\n        sort(first_order.begin(), first_order.end(), [&](int a, int b) {\n            if(num_1day[a] != num_1day[b]) return num_1day[a] < num_1day[b];\n            return crit[a] > crit[b]; });\n        \n        vector<int> second_order = avail;\n        sort(second_order.begin(), second_order.end(), [&](int a, int b) { \n            if(crit[a] != crit[b]) return crit[a] > crit[b];\n            return unblock[a] > unblock[b]; });\n        \n        vector<pair<int,int>> assign;\n        vector<bool> tused(N, false), mused(M, false);\n        \n        for(int t: first_order) {\n            if(tused[t]) continue;\n            for(int m: freem) {\n                if(mused[m]) continue;\n                if(can_1day(t, m)) {\n                    assign.push_back({m, t});\n                    tused[t] = mused[m] = true;\n                    mtask[m] = t; tstatus[t] = 0; tstart[t] = day; tcount[m]++;\n                    break;\n                }\n            }\n        }\n        \n        for(int t: second_order) {\n            if(tused[t]) continue;\n            int best = -1; long long best_score = LLONG_MAX;\n            for(int m: freem) {\n                if(mused[m]) continue;\n                long long score = (long long)est_w(t, m) * 10000 + tcount[m];\n                if(score < best_score) { best_score = score; best = m; }\n            }\n            if(best != -1) {\n                assign.push_back({best, t});\n                tused[t] = mused[best] = true;\n                mtask[best] = t; tstatus[t] = 0; tstart[t] = day; tcount[best]++;\n            }\n        }\n        \n        cout << assign.size();\n        for(auto [m,t]: assign) cout << \" \" << m+1 << \" \" << t+1;\n        cout << \"\\n\"; cout.flush();\n        \n        int n; cin >> n;\n        if(n == -1) break;\n        \n        for(int i = 0; i < n; i++) {\n            int m; cin >> m; m--;\n            int t = mtask[m], actual = day - tstart[t] + 1;\n            tstatus[t] = 1; mtask[m] = -1;\n            \n            if(actual == 1) {\n                for(int k = 0; k < K; k++)\n                    proven[m][k] = est[m][k] = max(proven[m][k], max(est[m][k], d[t][k]));\n            } else {\n                int pred_w = est_w(t, m);\n                int w_lo = max(1, actual - 3);\n                int w_hi = actual + 3;\n                \n                if(pred_w < w_lo || pred_w > w_hi) {\n                    double target_w;\n                    if(pred_w < w_lo) target_w = 0.3 * pred_w + 0.7 * w_lo;\n                    else target_w = 0.3 * pred_w + 0.7 * w_hi;\n                    \n                    vector<pair<int,int>> gaps;\n                    int total_gap = 0;\n                    for(int k = 0; k < K; k++) {\n                        int gap = max(0, d[t][k] - est[m][k]);\n                        if(gap > 0) { gaps.push_back({gap, k}); total_gap += gap; }\n                    }\n                    \n                    if(total_gap == 0) {\n                        vector<int> margin(K);\n                        int total_margin = 0;\n                        for(int k = 0; k < K; k++) {\n                            if(d[t][k] > 0 && est[m][k] >= d[t][k]) {\n                                margin[k] = est[m][k] - d[t][k] + 1;\n                                total_margin += margin[k];\n                            }\n                        }\n                        if(total_margin > 0) {\n                            for(int k = 0; k < K; k++) {\n                                if(margin[k] > 0) {\n                                    int reduce = (actual * margin[k] + total_margin/2) / total_margin;\n                                    est[m][k] = max(proven[m][k], est[m][k] - reduce);\n                                }\n                            }\n                        } else {\n                            int reduce = (actual + K - 1) / K;\n                            for(int k = 0; k < K; k++)\n                                if(d[t][k] > 0)\n                                    est[m][k] = max(proven[m][k], est[m][k] - reduce);\n                        }\n                    } else {\n                        double scale = target_w / total_gap;\n                        for(auto [gap,k]: gaps) {\n                            int new_gap = max(0, (int)(gap * scale + 0.5));\n                            est[m][k] = max(proven[m][k], d[t][k] - new_gap);\n                        }\n                    }\n                }\n            }\n        }\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    vector<array<int, 4>> orders(1000);\n    for (int i = 0; i < 1000; i++)\n        cin >> orders[i][0] >> orders[i][1] >> orders[i][2] >> orders[i][3];\n    \n    vector<pair<double, int>> scored(1000);\n    for (int i = 0; i < 1000; i++) {\n        int a = orders[i][0], b = orders[i][1], c = orders[i][2], d = orders[i][3];\n        int mx = (a + c) / 2, my = (b + d) / 2;\n        scored[i] = {(abs(400 - mx) + abs(400 - my)) * 2.0 + (abs(a - c) + abs(b - d)) * 0.5, i};\n    }\n    sort(scored.begin(), scored.end());\n    \n    vector<int> selected(50);\n    for (int i = 0; i < 50; i++) selected[i] = scored[i].second;\n    \n    int cx[50][2], cy[50][2];\n    for (int i = 0; i < 50; i++) {\n        cx[i][0] = orders[selected[i]][0]; cy[i][0] = orders[selected[i]][1];\n        cx[i][1] = orders[selected[i]][2]; cy[i][1] = orders[selected[i]][3];\n    }\n    \n    int prefx[202], prefy[202], prefc[202], suffc[202], edgepre[202];\n    \n    auto build_route = [&](vector<int>& ord) {\n        vector<pair<int, bool>> route;\n        for (int t = 0; t < 50; t++) {\n            int idx = ord[t], n = route.size();\n            int a = cx[idx][0], b = cy[idx][0], c = cx[idx][1], d = cy[idx][1];\n            \n            prefx[0] = 400; prefy[0] = 400; prefc[0] = 0;\n            for (int i = 0; i < n; i++) {\n                int nx = cx[route[i].first][route[i].second], ny = cy[route[i].first][route[i].second];\n                prefc[i+1] = prefc[i] + abs(prefx[i] - nx) + abs(prefy[i] - ny);\n                prefx[i+1] = nx; prefy[i+1] = ny;\n            }\n            suffc[n] = 0;\n            for (int i = n-1; i >= 0; i--) {\n                int nx = cx[route[i].first][route[i].second], ny = cy[route[i].first][route[i].second];\n                if (i == n-1) suffc[i] = abs(nx - 400) + abs(ny - 400);\n                else { int ntx = cx[route[i+1].first][route[i+1].second], nty = cy[route[i+1].first][route[i+1].second]; suffc[i] = abs(nx-ntx)+abs(ny-nty)+suffc[i+1]; }\n            }\n            edgepre[0] = 0;\n            for (int i = 0; i < n-1; i++) {\n                int x1=cx[route[i].first][route[i].second], y1=cy[route[i].first][route[i].second];\n                int x2=cx[route[i+1].first][route[i+1].second], y2=cy[route[i+1].first][route[i+1].second];\n                edgepre[i+1] = edgepre[i] + abs(x1-x2) + abs(y1-y2);\n            }\n            \n            int best_cost = INT_MAX, best_pick = -1, best_del = -1;\n            for (int p = 0; p <= n; p++) {\n                int cost_to_pickup = prefc[p] + abs(prefx[p] - a) + abs(prefy[p] - b);\n                for (int q = p; q <= n; q++) {\n                    int cost_p2d;\n                    if (q == p) { cost_p2d = abs(a - c) + abs(b - d); }\n                    else {\n                        int mc = edgepre[q-1] - edgepre[p];\n                        int fx=cx[route[p].first][route[p].second], fy=cy[route[p].first][route[p].second];\n                        int lx=cx[route[q-1].first][route[q-1].second], ly=cy[route[q-1].first][route[q-1].second];\n                        cost_p2d = abs(a-fx)+abs(b-fy)+mc+abs(lx-c)+abs(ly-d);\n                    }\n                    int cost_from_d = (q==n) ? abs(c-400)+abs(d-400) : abs(c-cx[route[q].first][route[q].second])+abs(d-cy[route[q].first][route[q].second])+suffc[q];\n                    int total = cost_to_pickup + cost_p2d + cost_from_d;\n                    if (total < best_cost) { best_cost = total; best_pick = p; best_del = q; }\n                }\n            }\n            route.insert(route.begin() + best_del, {idx, true});\n            route.insert(route.begin() + best_pick, {idx, false});\n        }\n        return route;\n    };\n    \n    auto find_pos = [](vector<pair<int, bool>>& r) {\n        vector<int> pu(50, -1), de(50, -1);\n        for (int i = 0; i < (int)r.size(); i++) r[i].second ? de[r[i].first] = i : pu[r[i].first] = i;\n        return make_pair(pu, de);\n    };\n    \n    vector<int> ord(50); iota(ord.begin(), ord.end(), 0);\n    vector<pair<int, bool>> best_route; int best_cost = INT_MAX;\n    \n    for (int trial = 0; trial < 2000; trial++) {\n        if (trial > 0) shuffle(ord.begin(), ord.end(), rng);\n        auto route = build_route(ord);\n        int cost = 0, px = 400, py = 400;\n        for (auto& [i, d] : route) { int nx=cx[i][d], ny=cy[i][d]; cost+=abs(px-nx)+abs(py-ny); px=nx; py=ny; }\n        cost += abs(px-400)+abs(py-400);\n        if (cost < best_cost) { best_cost = cost; best_route = route; }\n    }\n    \n    auto [pu_pos, de_pos] = find_pos(best_route);\n    for (int iter = 0; iter < 500; iter++) {\n        bool imp = false;\n        for (int i = 0; i < (int)best_route.size() && !imp; i++) {\n            int idx = best_route[i].first; bool is_d = best_route[i].second; int n = best_route.size();\n            int ex=cx[idx][is_d], ey=cy[idx][is_d], pvx=400, pvy=400, nxv=400, nyv=400;\n            if (i>0) { pvx=cx[best_route[i-1].first][best_route[i-1].second]; pvy=cy[best_route[i-1].first][best_route[i-1].second]; }\n            if (i<n-1) { nxv=cx[best_route[i+1].first][best_route[i+1].second]; nyv=cy[best_route[i+1].first][best_route[i+1].second]; }\n            int base = -(abs(pvx-ex)+abs(pvy-ey))-(abs(ex-nxv)+abs(ey-nyv))+(abs(pvx-nxv)+abs(pvy-nyv));\n            for (int j = 0; j <= n-1 && !imp; j++) {\n                if (j==i) continue;\n                if (is_d) { if (j<=pu_pos[idx]) continue; }\n                else { int nd=de_pos[idx]-(de_pos[idx]>i?1:0); if (j>nd) continue; }\n                int ipx,ipy,inx,iny;\n                if (j==0) { ipx=400; ipy=400; } else { int o=(j<i)?j-1:j; ipx=cx[best_route[o].first][best_route[o].second]; ipy=cy[best_route[o].first][best_route[o].second]; }\n                if (j==n-1) { inx=400; iny=400; } else { int o=(j<i)?j:j+1; inx=cx[best_route[o].first][best_route[o].second]; iny=cy[best_route[o].first][best_route[o].second]; }\n                int delta = base-(abs(ipx-inx)+abs(ipy-iny))+(abs(ipx-ex)+abs(ipy-ey))+(abs(ex-inx)+abs(ey-iny));\n                if (delta < 0) { auto e=best_route[i]; best_route.erase(best_route.begin()+i); best_route.insert(best_route.begin()+j,e); best_cost+=delta; auto [p,d]=find_pos(best_route); pu_pos=p; de_pos=d; imp=true; }\n            }\n        }\n        if (!imp) break;\n    }\n    \n    cout << 50; for (int i=0;i<50;i++) cout<<\" \"<<selected[i]+1;\n    cout << \"\\n\" << best_route.size()+2 << \" 400 400\";\n    for (auto& [i,d] : best_route) cout<<\" \"<<cx[i][d]<<\" \"<<cy[i][d];\n    cout << \" 400 400\\n\";\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nstruct Edge {\n    int u, v;\n    double d;\n    int id;\n};\n\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 x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n    bool merge(int x, int y) {\n        x = find(x); y = find(y);\n        if (x == y) return false;\n        if (rank_[x] < rank_[y]) swap(x, y);\n        parent[y] = x;\n        if (rank_[x] == rank_[y]) rank_[x]++;\n        return true;\n    }\n};\n\nint main() {\n    // Fast I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N = 400, M = 1995;\n    vector<double> x(N), y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> x[i] >> y[i];\n    }\n\n    vector<Edge> edges(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> edges[i].u >> edges[i].v;\n        // Calculate exact deterministic distance d_i\n        double dx = x[edges[i].u] - x[edges[i].v];\n        double dy = y[edges[i].u] - y[edges[i].v];\n        edges[i].d = std::round(std::sqrt(dx * dx + dy * dy));\n        edges[i].id = i;\n    }\n\n    // Sort edges by their deterministic distance d_i\n    sort(edges.begin(), edges.end(), [](const Edge& a, const Edge& b) {\n        return a.d < b.d;\n    });\n\n    DSU dsu(N);\n    vector<bool> in_mst(M, false);\n\n    // Compute Offline MST using d_i\n    for (const auto& e : edges) {\n        if (dsu.merge(e.u, e.v)) {\n            in_mst[e.id] = true;\n        }\n    }\n\n    // Online Phase: Strictly adopt ONLY the edges in our pre-computed MST\n    for (int i = 0; i < M; ++i) {\n        int l;\n        cin >> l;\n        if (in_mst[i]) {\n            cout << \"1\\n\" << flush;\n        } else {\n            cout << \"0\\n\" << flush;\n        }\n    }\n\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 30, W = 30;\nint N, M;\nint px[25], py[25], pt[25];\nint hx[15], hy[15];\nbool wall[H][W];\nint pet_dist[25][H][W];\nint human_dist[15][H][W];\nint reachable_count[H][W];\n\nint dx[] = {-1, 1, 0, 0};\nint dy[] = {0, 0, -1, 1};\nchar dir_char[] = \"UDLR\";\nchar wall_char[] = \"udlr\";\n\nbool in_bounds(int x, int y) { return 0 <= x && x < H && 0 <= y < W; }\n\nbool has_pet_at(int x, int y) {\n    for (int i = 0; i < N; i++) if (px[i] == x && py[i] == y) return true;\n    return false;\n}\n\nbool has_human_at(int x, int y) {\n    for (int i = 0; i < M; i++) if (hx[i] == x && hy[i] == y) return true;\n    return false;\n}\n\nbool pet_adjacent(int x, int y) {\n    for (int d = 0; d < 4; d++) if (has_pet_at(x + dx[d], y + dy[d])) return true;\n    return false;\n}\n\nbool can_place_wall(int x, int y) {\n    if (!in_bounds(x, y) || wall[x][y]) return false;\n    if (has_pet_at(x, y) || has_human_at(x, y)) return false;\n    if (pet_adjacent(x, y)) return false;\n    return true;\n}\n\nvoid compute_distances() {\n    for (int p = 0; p < N; p++) {\n        queue<pair<int,int>> q;\n        memset(pet_dist[p], -1, sizeof(pet_dist[p]));\n        q.push({px[p], py[p]});\n        pet_dist[p][px[p]][py[p]] = 0;\n        while (!q.empty()) {\n            auto [x, y] = q.front(); q.pop();\n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (in_bounds(nx, ny) && !wall[nx][ny] && pet_dist[p][nx][ny] == -1) {\n                    pet_dist[p][nx][ny] = pet_dist[p][x][y] + 1;\n                    q.push({nx, ny});\n                }\n            }\n        }\n    }\n    for (int h = 0; h < M; h++) {\n        queue<pair<int,int>> q;\n        memset(human_dist[h], -1, sizeof(human_dist[h]));\n        q.push({hx[h], hy[h]});\n        human_dist[h][hx[h]][hy[h]] = 0;\n        while (!q.empty()) {\n            auto [x, y] = q.front(); q.pop();\n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (in_bounds(nx, ny) && !wall[nx][ny] && human_dist[h][nx][ny] == -1) {\n                    human_dist[h][nx][ny] = human_dist[h][x][y] + 1;\n                    q.push({nx, ny});\n                }\n            }\n        }\n    }\n    memset(reachable_count, 0, sizeof(reachable_count));\n    for (int x = 0; x < H; x++) for (int y = 0; y < W; y++) {\n        if (wall[x][y] || has_pet_at(x, y)) continue;\n        bool visited[H][W] = {};\n        queue<pair<int,int>> q;\n        q.push({x, y});\n        visited[x][y] = true;\n        int cnt = 0;\n        while (!q.empty() && cnt < 100) {\n            auto [cx, cy] = q.front(); q.pop();\n            cnt++;\n            for (int d = 0; d < 4; d++) {\n                int nx = cx + dx[d], ny = cy + dy[d];\n                if (in_bounds(nx, ny) && !wall[nx][ny] && !has_pet_at(nx, ny) && !visited[nx][ny]) {\n                    visited[nx][ny] = true;\n                    q.push({nx, ny});\n                }\n            }\n        }\n        reachable_count[x][y] = cnt;\n    }\n}\n\nint wall_value(int wx, int wy, int hi) {\n    int val = 0;\n    for (int p = 0; p < N; p++) {\n        int weight = (pt[p] == 4) ? 20 : (pt[p] == 3) ? 3 : (pt[p] == 5) ? 2 : 1;\n        int dph = pet_dist[p][hx[hi]][hy[hi]];\n        if (dph < 0) continue;\n        int dpw = pet_dist[p][wx][wy];\n        if (dpw <= 0) continue;\n        int dwh = human_dist[hi][wx][wy];\n        if (dwh <= 0) continue;\n        if (dpw + dwh == dph) {\n            val += 100 * weight;\n            if (dpw < 6) val += (7 - dpw) * 10 * weight;\n        }\n        if (dpw < 10) val += (11 - dpw) * weight;\n    }\n    return val;\n}\n\nstring pet_moves[25];\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++) { cin >> px[i] >> py[i] >> pt[i]; px[i]--; py[i]--; }\n    cin >> M;\n    for (int i = 0; i < M; i++) { cin >> hx[i] >> hy[i]; hx[i]--; hy[i]--; }\n    \n    memset(wall, false, sizeof(wall));\n    \n    for (int turn = 0; turn < 300; turn++) {\n        compute_distances();\n        \n        int closest_dog_dist[15], closest_dog_toward[15];\n        for (int i = 0; i < M; i++) {\n            closest_dog_dist[i] = 1000;\n            closest_dog_toward[i] = -1;\n            for (int p = 0; p < N; p++) {\n                if (pt[p] == 4) {\n                    int d = pet_dist[p][hx[i]][hy[i]];\n                    if (d >= 0 && d < closest_dog_dist[i]) {\n                        closest_dog_dist[i] = d;\n                        for (int dd = 0; dd < 4; dd++) {\n                            int nx = hx[i] + dx[dd], ny = hy[i] + dy[dd];\n                            if (in_bounds(nx, ny) && pet_dist[p][nx][ny] == d - 1) {\n                                closest_dog_toward[i] = dd;\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        bool panic[15];\n        for (int i = 0; i < M; i++) panic[i] = (closest_dog_dist[i] <= 2);\n        \n        vector<tuple<int, int, int>> wall_candidates;\n        for (int i = 0; i < M; i++) {\n            if (panic[i]) continue;\n            for (int d = 0; d < 4; d++) {\n                int wx = hx[i] + dx[d], wy = hy[i] + dy[d];\n                if (can_place_wall(wx, wy)) {\n                    int val = wall_value(wx, wy, i);\n                    if (val > 10) wall_candidates.push_back({val, i, d});\n                }\n            }\n        }\n        sort(wall_candidates.rbegin(), wall_candidates.rend());\n        \n        set<int> assigned;\n        set<pair<int,int>> wall_positions;\n        vector<pair<int,int>> planned_walls(M, {-1, -1});\n        \n        for (auto& [val, hi, d] : wall_candidates) {\n            if (assigned.count(hi)) continue;\n            int wx = hx[hi] + dx[d], wy = hy[hi] + dy[d];\n            if (wall_positions.count({wx, wy})) continue;\n            assigned.insert(hi);\n            wall_positions.insert({wx, wy});\n            planned_walls[hi] = {wx, wy};\n        }\n        \n        string actions(M, '.');\n        for (int i = 0; i < M; i++) {\n            if (panic[i]) {\n                int away_dir = -1;\n                double best_score = -1000;\n                for (int d = 0; d < 4; d++) {\n                    int nx = hx[i]+dx[d], ny = hy[i]+dy[d];\n                    if (!in_bounds(nx,ny) || wall[nx][ny] || wall_positions.count({nx,ny})) continue;\n                    double score = 0;\n                    if (closest_dog_toward[i] >= 0) {\n                        if (d == (closest_dog_toward[i] ^ 1)) score += 10;\n                        else if (d == closest_dog_toward[i]) score -= 10;\n                        else score += 3;\n                    }\n                    if (score > best_score) { best_score = score; away_dir = d; }\n                }\n                if (away_dir >= 0) actions[i] = dir_char[away_dir];\n            } else if (planned_walls[i].first != -1) {\n                for (int d = 0; d < 4; d++) {\n                    if (planned_walls[i] == make_pair(hx[i]+dx[d], hy[i]+dy[d])) {\n                        actions[i] = wall_char[d]; break;\n                    }\n                }\n            } else {\n                double gx = 0, gy = 0;\n                for (int p = 0; p < N; p++) {\n                    double w = (pt[p] == 4) ? 3.0 : 1.0;\n                    double dist = max(1.0, (double)(abs(hx[i]-px[p]) + abs(hy[i]-py[p])));\n                    gx += w * (hx[i] - px[p]) / (dist * dist);\n                    gy += w * (hy[i] - py[p]) / (dist * dist);\n                }\n                int bm = -1, bm_safe = -1; \n                double bd = 0.01, bd_safe = 0.01;\n                int best_reach = -1, best_reach_safe = -1;\n                for (int d = 0; d < 4; d++) {\n                    int nx = hx[i]+dx[d], ny = hy[i]+dy[d];\n                    if (!in_bounds(nx,ny) || wall[nx][ny] || wall_positions.count({nx,ny})) continue;\n                    double dot = dx[d]*gx + dy[d]*gy;\n                    int reach = reachable_count[nx][ny];\n                    double score = dot + reach * 0.001;\n                    if (score > bd) { bd = score; bm = d; best_reach = reach; }\n                    if (!pet_adjacent(nx, ny) && score > bd_safe) { bd_safe = score; bm_safe = d; best_reach_safe = reach; }\n                }\n                if (bm_safe != -1 && best_reach_safe >= best_reach * 0.9) bm = bm_safe;\n                if (bm != -1) actions[i] = dir_char[bm];\n            }\n        }\n        \n        cout << actions << endl;\n        for (int i = 0; i < N; i++) cin >> pet_moves[i];\n        \n        for (int i = 0; i < M; i++) {\n            if (actions[i] != '.' && islower(actions[i])) {\n                for (int d = 0; d < 4; d++) if (actions[i] == wall_char[d]) {\n                    int nx=hx[i]+dx[d], ny=hy[i]+dy[d];\n                    if (in_bounds(nx,ny)) wall[nx][ny] = true;\n                }\n            }\n        }\n        for (int i = 0; i < M; i++) {\n            if (actions[i] != '.' && isupper(actions[i])) {\n                for (int d = 0; d < 4; d++) if (actions[i] == dir_char[d]) {\n                    int nx=hx[i]+dx[d], ny=hy[i]+dy[d];\n                    if (in_bounds(nx,ny) && !wall[nx][ny]) { hx[i]=nx; hy[i]=ny; }\n                    break;\n                }\n            }\n        }\n        for (int i = 0; i < N; i++) {\n            for (char c : pet_moves[i]) for (int d = 0; d < 4; d++) if (c == dir_char[d]) {\n                px[i]+=dx[d]; py[i]+=dy[d]; break;\n            }\n        }\n    }\n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cstring>\n#include <algorithm>\n#include <queue>\n\nusing namespace std;\n\nint si, sj, ti, tj;\ndouble p;\nchar h[20][19];\nchar v[19][20];\n\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\nchar dirs[] = {'U', 'D', 'L', 'R'};\n\nint dist[20][20];\nbool can[20][20][4];\ndouble move_prob_table[20][20][4];\ndouble stay_prob_table[20][20][4];\ndouble remaining_sq[201][41];\ndouble reach_score_table[201];\n\nvoid compute_distances() {\n    memset(dist, -1, sizeof(dist));\n    dist[ti][tj] = 0;\n    queue<pair<int, int>> q;\n    q.push({ti, tj});\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int dir = 0; dir < 4; ++dir) {\n            if (can[i][j][dir]) {\n                int ni = i + dr[dir], nj = j + dc[dir];\n                if (dist[ni][nj] == -1) {\n                    dist[ni][nj] = dist[i][j] + 1;\n                    q.push({ni, nj});\n                }\n            }\n        }\n    }\n}\n\nstruct Node {\n    vector<char> seq;\n    double exact_score;\n    double dp[400]; // Flattened 20x20 grid for fast copy\n    double value;\n};\n\nint main() {\n    // Fast I/O\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    if (!(cin >> si >> sj >> ti >> tj >> p)) return 0;\n    \n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 19; ++j) {\n            cin >> h[i][j];\n        }\n    }\n    for (int i = 0; i < 19; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            cin >> v[i][j];\n        }\n    }\n    \n    // Precompute transition dynamics\n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            for (int dir = 0; dir < 4; ++dir) {\n                if (dir == 0) can[i][j][dir] = i > 0 && v[i-1][j] == '0';\n                else if (dir == 1) can[i][j][dir] = i < 19 && v[i][j] == '0';\n                else if (dir == 2) can[i][j][dir] = j > 0 && h[i][j-1] == '0';\n                else can[i][j][dir] = j < 19 && h[i][j] == '0';\n                \n                bool wall = !can[i][j][dir];\n                move_prob_table[i][j][dir] = (1.0 - p) * (1.0 - wall);\n                stay_prob_table[i][j][dir] = 1.0 - move_prob_table[i][j][dir];\n            }\n        }\n    }\n    \n    compute_distances();\n    \n    // Precompute scores and heuristic components\n    for (int t = 1; t <= 200; ++t) {\n        reach_score_table[t] = 401.0 - t;\n        for (int d = 0; d <= 40; ++d) {\n            int rem = 400 - t - d;\n            remaining_sq[t][d] = rem > 0 ? (double)rem * rem : 0.0;\n        }\n    }\n    \n    int L = 200;\n    int W = 100; // Beam width\n    \n    vector<Node> beam;\n    beam.resize(1);\n    beam[0].seq.clear();\n    beam[0].exact_score = 0.0;\n    memset(beam[0].dp, 0, sizeof(beam[0].dp));\n    beam[0].dp[si * 20 + sj] = 1.0;\n    beam[0].value = 0.0;\n    \n    vector<Node> next_beam_candidates;\n    next_beam_candidates.reserve(W * 4);\n    \n    for (int t = 1; t <= L; ++t) {\n        next_beam_candidates.clear();\n        \n        for (auto& node : beam) {\n            for (int dir = 0; dir < 4; ++dir) {\n                Node new_node;\n                new_node.seq = node.seq;\n                new_node.seq.push_back(dirs[dir]);\n                new_node.exact_score = node.exact_score;\n                memset(new_node.dp, 0, sizeof(new_node.dp));\n                \n                double reach_prob = 0.0;\n                double heuristic = 0.0;\n                \n                // Fast inner loop over distribution\n                for (int i = 0; i < 20; ++i) {\n                    for (int j = 0; j < 20; ++j) {\n                        double prob = node.dp[i * 20 + j];\n                        if (prob < 1e-15) continue;\n                        \n                        double move_prob = move_prob_table[i][j][dir];\n                        double stay_prob = stay_prob_table[i][j][dir];\n                        \n                        if (move_prob > 1e-15) {\n                            int ni = i + dr[dir], nj = j + dc[dir];\n                            if (ni == ti && nj == tj) {\n                                reach_prob += prob * move_prob;\n                            } else {\n                                new_node.dp[ni * 20 + nj] += prob * move_prob;\n                            }\n                        }\n                        \n                        if (stay_prob > 1e-15) {\n                            new_node.dp[i * 20 + j] += prob * stay_prob;\n                        }\n                    }\n                }\n                \n                // Exact lower bound score for reaching target\n                new_node.exact_score += reach_prob * reach_score_table[t];\n                \n                // Squared distance heuristic to aggressively pull mass towards target\n                for (int i = 0; i < 20; ++i) {\n                    for (int j = 0; j < 20; ++j) {\n                        if (i == ti && j == tj) continue;\n                        double prob = new_node.dp[i * 20 + j];\n                        if (prob < 1e-15) continue;\n                        heuristic += prob * remaining_sq[t][dist[i][j]];\n                    }\n                }\n                \n                // Balanced scaling between exact achievement and future potential\n                new_node.value = new_node.exact_score * 400.0 + heuristic;\n                next_beam_candidates.push_back(new_node);\n            }\n        }\n        \n        // Keep top W candidates\n        sort(next_beam_candidates.begin(), next_beam_candidates.end(), [](const Node& a, const Node& b) {\n            return a.value > b.value;\n        });\n        \n        int new_W = min(W, (int)next_beam_candidates.size());\n        beam.assign(next_beam_candidates.begin(), next_beam_candidates.begin() + new_W);\n    }\n    \n    cout << string(beam[0].seq.begin(), beam[0].seq.end()) << \"\\n\";\n    \n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <string>\n#include <set>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <ctime>\n\nusing namespace std;\n\nint to_table[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1},\n};\n\nint di[4] = {0, -1, 0, 1};\nint dj[4] = {-1, 0, 1, 0};\n\nint valid_out[8][4];\n\nstruct TraceResult {\n    int len;\n    bool is_cycle;\n    int ret_d;\n};\n\ninline int get_to_fast(int t, int r, int in_d) {\n    int orig_out = to_table[t][(in_d + r) % 4];\n    if (orig_out == -1) return -1;\n    return (orig_out - r + 4) % 4;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    for (int t = 0; t < 8; ++t) {\n        for (int r = 0; r < 4; ++r) {\n            int mask = 0;\n            for (int d = 0; d < 4; ++d) {\n                int orig_out = to_table[t][(d + r) % 4];\n                if (orig_out != -1) {\n                    int out_d = (orig_out - r + 4) % 4;\n                    mask |= (1 << out_d);\n                }\n            }\n            valid_out[t][r] = mask;\n        }\n    }\n\n    vector<int> tiles(900);\n    for (int i = 0; i < 30; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < 30; ++j) {\n            tiles[i * 30 + j] = row[j] - '0';\n        }\n    }\n\n    vector<int> rot(900, 0);\n    \n    for (int i = 0; i < 30; ++i) {\n        for (int j = 0; j < 30; ++j) {\n            int idx = i * 30 + j;\n            int t = tiles[idx];\n            int best_r = 0, best_matches = -1;\n            for (int r = 0; r < 4; ++r) {\n                rot[idx] = r;\n                int matches = 0;\n                if (i > 0) {\n                    int top_idx = (i - 1) * 30 + j;\n                    if ((valid_out[tiles[top_idx]][rot[top_idx]] >> 3) & 1) { \n                        if ((valid_out[t][r] >> 1) & 1) matches++; \n                    }\n                }\n                if (j > 0) {\n                    int left_idx = i * 30 + (j - 1);\n                    if ((valid_out[tiles[left_idx]][rot[left_idx]] >> 2) & 1) { \n                        if ((valid_out[t][r] >> 0) & 1) matches++; \n                    }\n                }\n                if (matches > best_matches) {\n                    best_matches = matches;\n                    best_r = r;\n                }\n            }\n            rot[idx] = best_r;\n        }\n    }\n\n    multiset<int> cycles;\n    int pos_x = 0, pos_y = 0;\n\n    auto trace = [&](int start_x, int start_y, int start_d) -> TraceResult {\n        int cx = start_x, cy = start_y;\n        int curr_in_d = (start_d + 2) % 4;\n        int len = 0;\n        while (true) {\n            int idx = cx * 30 + cy;\n            int out_d = get_to_fast(tiles[idx], rot[idx], curr_in_d);\n            if (out_d == -1) return {len, false, -1};\n            \n            int nx = cx + di[out_d];\n            int ny = cy + dj[out_d];\n            if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30) return {len, false, -1};\n            \n            len++;\n            if (nx == pos_x && ny == pos_y) {\n                return {len, true, out_d};\n            }\n            \n            cx = nx; cy = ny;\n            curr_in_d = (out_d + 2) % 4;\n        }\n    };\n\n    auto extract_and_remove_cycles = [&](int idx, int r) {\n        vector<int> found_cycles;\n        found_cycles.reserve(4);\n        pos_x = idx / 30; pos_y = idx % 30;\n        int t = tiles[idx];\n        int curr_out_mask = valid_out[t][r];\n        for (int d = 0; d < 4; ++d) {\n            if (!(curr_out_mask & (1 << d))) continue;\n            int nx = pos_x + di[d], ny = pos_y + dj[d];\n            if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30) continue;\n            int neighbor_idx = nx * 30 + ny;\n            if (!((valid_out[tiles[neighbor_idx]][rot[neighbor_idx]] >> ((d + 2) % 4)) & 1)) continue;\n            \n            TraceResult res = trace(nx, ny, d);\n            if (res.is_cycle && res.ret_d >= d) {\n                found_cycles.push_back(res.len + 1);\n            }\n        }\n        for (int c : found_cycles) {\n            auto it = cycles.find(c);\n            if (it != cycles.end()) cycles.erase(it);\n        }\n        return found_cycles;\n    };\n\n    auto apply_and_insert_cycles = [&](int idx, int r) {\n        vector<int> found_cycles;\n        found_cycles.reserve(4);\n        pos_x = idx / 30; pos_y = idx % 30;\n        int t = tiles[idx];\n        int curr_out_mask = valid_out[t][r];\n        for (int d = 0; d < 4; ++d) {\n            if (!(curr_out_mask & (1 << d))) continue;\n            int nx = pos_x + di[d], ny = pos_y + dj[d];\n            if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30) continue;\n            int neighbor_idx = nx * 30 + ny;\n            if (!((valid_out[tiles[neighbor_idx]][rot[neighbor_idx]] >> ((d + 2) % 4)) & 1)) continue;\n            \n            TraceResult res = trace(nx, ny, d);\n            if (res.is_cycle && res.ret_d >= d) {\n                found_cycles.push_back(res.len + 1);\n            }\n        }\n        for (int c : found_cycles) {\n            cycles.insert(c);\n        }\n        return found_cycles;\n    };\n\n    for (int i = 0; i < 30; ++i) {\n        for (int j = 0; j < 30; ++j) {\n            int idx = i * 30 + j;\n            pos_x = i; pos_y = j;\n            int curr_out_mask = valid_out[tiles[idx]][rot[idx]];\n            for (int d = 0; d < 4; ++d) {\n                if (!(curr_out_mask & (1 << d))) continue;\n                int nx = i + di[d], ny = j + dj[d];\n                if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30) continue;\n                int neighbor_idx = nx * 30 + ny;\n                if (!((valid_out[tiles[neighbor_idx]][rot[neighbor_idx]] >> ((d + 2) % 4)) & 1)) continue;\n                \n                TraceResult res = trace(nx, ny, d);\n                if (res.is_cycle && res.ret_d >= d) {\n                    cycles.insert(res.len + 1);\n                }\n            }\n        }\n    }\n\n    long long sum_sq = 0;\n    for (int len : cycles) sum_sq += (long long)len * len;\n    long long current_sum_sq = sum_sq;\n\n    random_device rd;\n    mt19937 rng(rd());\n    uniform_int_distribution<int> rand_tile(0, 899);\n    uniform_int_distribution<int> rand_rot_diff(1, 3);\n    uniform_real_distribution<double> rand_prob(0.0, 1.0);\n\n    auto start_time = clock();\n    double temp = 80000.0;\n    double cool = 0.999997;\n\n    // Phase 1: SA with Sum of Squares to aggressively merge loops\n    while (clock() - start_time < 1.5 * CLOCKS_PER_SEC) {\n        int idx = rand_tile(rng);\n        int old_r = rot[idx];\n        int new_r = (old_r + rand_rot_diff(rng)) % 4;\n\n        vector<int> old_cycles = extract_and_remove_cycles(idx, old_r);\n        rot[idx] = new_r;\n        vector<int> new_cycles = apply_and_insert_cycles(idx, new_r);\n\n        long long new_sum_sq = sum_sq;\n        for (int c : old_cycles) new_sum_sq -= (long long)c * c;\n        for (int c : new_cycles) new_sum_sq += (long long)c * c;\n\n        if (new_sum_sq > current_sum_sq || exp((new_sum_sq - current_sum_sq) / temp) > rand_prob(rng)) {\n            current_sum_sq = new_sum_sq;\n            sum_sq = new_sum_sq;\n        } else {\n            rot[idx] = old_r;\n            for (int c : new_cycles) {\n                auto it = cycles.find(c);\n                if (it != cycles.end()) cycles.erase(it);\n            }\n            for (int c : old_cycles) {\n                cycles.insert(c);\n            }\n        }\n        temp *= cool;\n    }\n\n    // Phase 2: Strict Hill Climbing with True Score to balance top two loops\n    long long true_score = 0;\n    if (cycles.size() >= 2) {\n        auto it = cycles.rbegin();\n        true_score = (long long)*it * (long long)*std::next(it);\n    }\n\n    while (clock() - start_time < 1.95 * CLOCKS_PER_SEC) {\n        int idx = rand_tile(rng);\n        int old_r = rot[idx];\n        int new_r = (old_r + rand_rot_diff(rng)) % 4;\n\n        vector<int> old_cycles = extract_and_remove_cycles(idx, old_r);\n        rot[idx] = new_r;\n        vector<int> new_cycles = apply_and_insert_cycles(idx, new_r);\n\n        long long new_true_score = 0;\n        if (cycles.size() >= 2) {\n            auto it = cycles.rbegin();\n            new_true_score = (long long)*it * (long long)*std::next(it);\n        }\n\n        if (new_true_score > true_score) {\n            true_score = new_true_score;\n        } else {\n            rot[idx] = old_r;\n            for (int c : new_cycles) {\n                auto it = cycles.find(c);\n                if (it != cycles.end()) cycles.erase(it);\n            }\n            for (int c : old_cycles) {\n                cycles.insert(c);\n            }\n        }\n    }\n\n    string ans = \"\";\n    for (int i = 0; i < 900; ++i) {\n        ans += (char)('0' + rot[i]);\n    }\n    cout << ans << \"\\n\";\n\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nchar orig_board[12][12];\nint orig_ei, orig_ej;\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst char dc[] = {'U', 'D', 'L', 'R'};\nconst int lm[] = {2, 8, 1, 4};\nconst int om[] = {8, 2, 4, 1};\n\nchar board[12][12];\nint vis[100], comp[100];\n\ninline int gt(int i, int j) {\n    char c = board[i][j];\n    return (c == '0') ? -1 : ((c >= 'a') ? (c - 'a' + 10) : (c - '0'));\n}\n\nint lts() {\n    int best = 0;\n    for (int i = 0; i < N * N; i++) vis[i] = 0;\n    for (int si = 0; si < N * N; si++) {\n        if (vis[si] || gt(si/N, si%N) < 0) continue;\n        int h = 0, t = 0;\n        comp[t++] = si; vis[si] = 1;\n        while (h < t) {\n            int c = comp[h++], ci = c/N, cj = c%N, ct = gt(ci, cj);\n            for (int d = 0; d < 4; d++) {\n                int ni = ci+di[d], nj = cj+dj[d];\n                if (ni<0||ni>=N||nj<0||nj>=N) continue;\n                int nx = ni*N+nj;\n                if (vis[nx]) continue;\n                int nt = gt(ni, nj);\n                if (nt>=0 && (ct&lm[d]) && (nt&om[d])) { vis[nx]=1; comp[t++]=nx; }\n            }\n        }\n        if (t <= best) continue;\n        int e = 0;\n        for (int k = 0; k < t; k++) {\n            int ci=comp[k]/N, cj=comp[k]%N, ct=gt(ci,cj);\n            if (cj+1<N && (ct&4)) { int nt=gt(ci,cj+1); if (nt>=0&&(nt&1)) e++; }\n            if (ci+1<N && (ct&8)) { int nt=gt(ci+1,cj); if (nt>=0&&(nt&2)) e++; }\n        }\n        if (e == t-1) best = t;\n        if (best == N*N-1) return best;\n    }\n    return best;\n}\n\npair<string, int> solve(int seed) {\n    memcpy(board, orig_board, sizeof(orig_board));\n    int ei = orig_ei, ej = orig_ej;\n    \n    mt19937 rng(seed);\n    int cur_tree = lts();\n    int best_tree = cur_tree;\n    string best_moves;\n    string moves;\n    double rp = 0.45;\n    double cool = pow(0.008, 1.0/T);\n    int max_tiles = N * N - 1;\n    \n    for (int step = 0; step < T; step++) {\n        if (cur_tree == max_tiles) return {moves, max_tiles};\n        \n        int valid[4], vc = 0;\n        for (int d = 0; d < 4; d++) {\n            int ni = ei+di[d], nj = ej+dj[d];\n            if (ni>=0 && ni<N && nj>=0 && nj<N) valid[vc++] = d;\n        }\n        \n        if ((double)(rng()%1000)/1000.0 < rp) {\n            int d = valid[rng() % vc];\n            int ni = ei+di[d], nj = ej+dj[d];\n            swap(board[ei][ej], board[ni][nj]);\n            ei = ni; ej = nj;\n            moves += dc[d];\n            cur_tree = lts();\n            rp *= cool;\n        } else {\n            int best = valid[0], best_tree_move = -1;\n            vector<int> ties;\n            \n            for (int v = 0; v < vc; v++) {\n                int d = valid[v], ni = ei+di[d], nj = ej+dj[d];\n                if (gt(ni, nj) < 0) continue;\n                \n                swap(board[ei][ej], board[ni][nj]);\n                int tree = lts();\n                swap(board[ei][ej], board[ni][nj]);\n                \n                if (tree > best_tree_move) {\n                    best_tree_move = tree; best = d; ties = {d};\n                } else if (tree == best_tree_move) {\n                    ties.push_back(d);\n                }\n            }\n            \n            best = ties[rng() % ties.size()];\n            int ni = ei+di[best], nj = ej+dj[best];\n            swap(board[ei][ej], board[ni][nj]);\n            ei = ni; ej = nj;\n            moves += dc[best];\n            cur_tree = best_tree_move;\n            rp *= cool;\n        }\n        \n        if (cur_tree > best_tree) {\n            best_tree = cur_tree;\n            best_moves = moves;\n        }\n    }\n    \n    if (best_moves.empty()) best_moves = moves;\n    return {best_moves, best_tree};\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> T;\n    for (int i = 0; i < N; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; j++) {\n            orig_board[i][j] = s[j];\n            if (s[j] == '0') { orig_ei = i; orig_ej = j; }\n        }\n    }\n    \n    pair<string, int> best_result = {\"\", 0};\n    \n    for (int seed : {42, 137, 271, 401, 577, 719, 881, 1049, 1237, 1429, 1601, 1787, 1999, 2203, 2411}) {\n        auto result = solve(seed);\n        if (result.second == N * N - 1) {\n            best_result = result;\n            break;\n        }\n        if (result.second > best_result.second || \n            (result.second == best_result.second && result.first.size() < best_result.first.size())) {\n            best_result = result;\n        }\n    }\n    \n    cout << best_result.first << endl;\n    return 0;\n}","ahc012":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <numeric>\n#include <random>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N;\n    if (!(cin >> N)) return 0;\n    int K_input;\n    cin >> K_input;\n    \n    int a[11] = {0};\n    for (int d = 1; d <= 10; d++) cin >> a[d];\n    \n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n    \n    if (N <= 1) {\n        cout << 0 << \"\\n\";\n        return 0;\n    }\n    \n    int active_V = min((int)sqrt(N) + 1, 50);\n    int active_H = min((int)sqrt(N) + 1, 50);\n    int total_V = 50;\n    int total_H = 50;\n    int actual_K = 100;\n    int active_K = active_V + active_H;\n    \n    vector<int> sorted_idx_x(N), sorted_idx_y(N);\n    iota(sorted_idx_x.begin(), sorted_idx_x.end(), 0);\n    sort(sorted_idx_x.begin(), sorted_idx_x.end(), [&](int i, int j) { return x[i] < x[j]; });\n    iota(sorted_idx_y.begin(), sorted_idx_y.end(), 0);\n    sort(sorted_idx_y.begin(), sorted_idx_y.end(), [&](int i, int j) { return y[i] < y[j]; });\n    \n    vector<int> ix(N), iy(N);\n    for (int i = 0; i < N; i++) {\n        ix[sorted_idx_x[i]] = i;\n        iy[sorted_idx_y[i]] = i;\n    }\n    \n    vector<int> pts_by_x(N), pts_by_y(N);\n    for (int i = 0; i < N; i++) {\n        pts_by_x[i] = sorted_idx_x[i];\n        pts_by_y[i] = sorted_idx_y[i];\n    }\n    \n    vector<int> first_of_rank_x(N, -1), last_of_rank_x(N, -1);\n    for (int i = 0; i < N; i++) {\n        int rank = ix[pts_by_x[i]];\n        if (first_of_rank_x[rank] == -1) first_of_rank_x[rank] = i;\n        last_of_rank_x[rank] = i;\n    }\n    \n    vector<int> first_of_rank_y(N, -1), last_of_rank_y(N, -1);\n    for (int i = 0; i < N; i++) {\n        int rank = iy[pts_by_y[i]];\n        if (first_of_rank_y[rank] == -1) first_of_rank_y[rank] = i;\n        last_of_rank_y[rank] = i;\n    }\n    \n    // Dummy cuts at N, active cuts uniformly distributed\n    vector<int> k_v(total_V, N), k_h(total_H, N);\n    for(int i = 0; i < active_V; i++) {\n        k_v[i] = (long long)(i + 1) * (N - 1) / (active_V + 1);\n    }\n    for(int i = 0; i < active_H; i++) {\n        k_h[i] = (long long)(i + 1) * (N - 1) / (active_H + 1);\n    }\n    \n    vector<int> V(N), H(N);\n    int cnt[51][51] = {0};\n    int b[11] = {0};\n    \n    for (int i = 0; i < N; i++) {\n        V[i] = 0;\n        for (int j = 0; j < total_V; j++) {\n            if (ix[i] >= k_v[j]) V[i]++;\n        }\n        H[i] = 0;\n        for (int j = 0; j < total_H; j++) {\n            if (iy[i] >= k_h[j]) H[i]++;\n        }\n        cnt[V[i]][H[i]]++;\n    }\n    \n    for(int v = 0; v <= 50; v++) {\n        for(int h = 0; h <= 50; h++) {\n            if (cnt[v][h] <= 10 && cnt[v][h] > 0) b[cnt[v][h]]++;\n        }\n    }\n    int current_score = 0;\n    for (int d = 1; d <= 10; d++) current_score += min(a[d], b[d]);\n    \n    int best_score = current_score;\n    vector<int> best_k_v = k_v, best_k_h = k_h;\n    \n    mt19937 mt(42);\n    uniform_int_distribution<int> rand_idx(0, active_K - 1);\n    uniform_real_distribution<double> rand_prob(0.0, 1.0);\n    \n    double temp = 1.0;\n    \n    auto apply_move = [&](int j, int from_k, int to_k, bool is_vert) -> int {\n        int delta_score = 0;\n        int l = min(from_k, to_k);\n        int r = max(from_k, to_k);\n        int v_change = (to_k > from_k) ? -1 : 1;\n        \n        int L = l;\n        int R = r - 1;\n        if (L > R) return 0;\n        \n        int start_idx, end_idx;\n        if (is_vert) {\n            start_idx = first_of_rank_x[L];\n            end_idx = last_of_rank_x[R];\n        } else {\n            start_idx = first_of_rank_y[L];\n            end_idx = last_of_rank_y[R];\n        }\n        \n        if (start_idx == -1) return 0;\n        \n        for (int idx = start_idx; idx <= end_idx; idx++) {\n            int i = is_vert ? pts_by_x[idx] : pts_by_y[idx];\n            int old_v = is_vert ? V[i] : H[i];\n            int new_v = old_v + v_change;\n            int h = is_vert ? H[i] : V[i];\n            \n            int S_old = is_vert ? cnt[old_v][h] : cnt[h][old_v];\n            if (S_old <= 10) {\n                if (b[S_old] <= a[S_old]) delta_score--;\n                b[S_old]--;\n            }\n            if (is_vert) cnt[old_v][h]--;\n            else cnt[h][old_v]--;\n            \n            if (S_old > 1 && S_old - 1 <= 10) {\n                if (b[S_old - 1] + 1 <= a[S_old - 1]) delta_score++;\n                b[S_old - 1]++;\n            }\n            \n            int S_new = is_vert ? cnt[new_v][h] : cnt[h][new_v];\n            if (S_new > 0 && S_new <= 10) {\n                if (b[S_new] <= a[S_new]) delta_score--;\n                b[S_new]--;\n            }\n            if (is_vert) cnt[new_v][h]++;\n            else cnt[h][new_v]++;\n            \n            if (S_new + 1 <= 10) {\n                if (b[S_new + 1] + 1 <= a[S_new + 1]) delta_score++;\n                b[S_new + 1]++;\n            }\n            \n            if (is_vert) V[i] = new_v;\n            else H[i] = new_v;\n        }\n        return delta_score;\n    };\n    \n    for (int iter = 0; iter < 25000000; iter++) {\n        temp *= 0.9999999;\n        \n        int j = rand_idx(mt);\n        int delta;\n        int r_val = mt() % 100;\n        if (r_val < 70) delta = (mt() % 2 == 0) ? 1 : -1;\n        else if (r_val < 90) delta = (mt() % 2 == 0) ? 2 : -2;\n        else {\n            int s = 3 + mt() % 15;\n            delta = (mt() % 2 == 0) ? s : -s;\n        }\n        \n        int k_old, k_new;\n        bool is_vertical = (j < active_V);\n        \n        if (is_vertical) {\n            k_old = k_v[j];\n            k_new = k_old + delta;\n            if (k_new < 0) k_new = 0;\n            if (k_new > N) k_new = N;\n        } else {\n            k_old = k_h[j - active_V];\n            k_new = k_old + delta;\n            if (k_new < 0) k_new = 0;\n            if (k_new > N) k_new = N;\n        }\n        \n        if (k_new == k_old) continue;\n        \n        int delta_score = apply_move(j, k_old, k_new, is_vertical);\n        \n        int diff = delta_score;\n        if (diff > 0 || rand_prob(mt) < exp(diff / temp)) {\n            current_score += diff;\n            if (is_vertical) k_v[j] = k_new;\n            else k_h[j - active_V] = k_new;\n            \n            if (current_score > best_score) {\n                best_score = current_score;\n                best_k_v = k_v;\n                best_k_h = k_h;\n            }\n        } else {\n            apply_move(j, k_new, k_old, is_vertical);\n        }\n    }\n    \n    k_v = best_k_v;\n    k_h = best_k_h;\n    \n    cout << actual_K << \"\\n\";\n    for (int j = 0; j < total_V; j++) {\n        int k = k_v[j];\n        long long px1, py1, px2, py2;\n        if (k <= 0) {\n            px1 = -15000; py1 = 0;\n            px2 = -15000; py2 = 1;\n        } else if (k >= N) {\n            px1 = 15000; py1 = 0;\n            px2 = 15000; py2 = 1;\n        } else {\n            int x_left = x[pts_by_x[k - 1]];\n            int x_right = x[pts_by_x[k]];\n            int C_int = (x_left + x_right) / 2;\n            px1 = C_int; py1 = 0;\n            px2 = C_int; py2 = 1;\n        }\n        cout << px1 << \" \" << py1 << \" \" << px2 << \" \" << py2 << \"\\n\";\n    }\n    for (int j = 0; j < total_H; j++) {\n        int k = k_h[j];\n        long long px1, py1, px2, py2;\n        if (k <= 0) {\n            px1 = 0; py1 = -15000;\n            px2 = 1; py2 = -15000;\n        } else if (k >= N) {\n            px1 = 0; py1 = 15000;\n            px2 = 1; py2 = 15000;\n        } else {\n            int y_left = y[pts_by_y[k - 1]];\n            int y_right = y[pts_by_y[k]];\n            int C_int = (y_left + y_right) / 2;\n            px1 = 0; py1 = C_int;\n            px2 = 1; py2 = C_int;\n        }\n        cout << px1 << \" \" << py1 << \" \" << px2 << \" \" << py2 << \"\\n\";\n    }\n\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\nusing namespace chrono;\n\nint N, M, c;\nint initX[4000], initY[4000];\nbool dot[64][64];\nint curLevel[64][64];\nvector<tuple<int,int,int,int,int,int,int,int>> ops;\nmap<int, set<pair<int,int>>> segMap[4];\nset<tuple<int,int,int,int>,greater<>> frontier;\nconst int MAX_DIST = 7, MAX_LEVEL = 5, INF = 1e9;\nmt19937 rng;\nbool useNoise;\n\nint getLineType(int x1, int y1, int x2, int y2) {\n    if (x1 == x2) return 1; if (y1 == y2) return 0;\n    if (x1 + y1 == x2 + y2) return 2; return 3;\n}\nint getLineId(int t, int x, int y) {\n    if (t == 0) return y; if (t == 1) return x;\n    if (t == 2) return x + y; return x - y;\n}\nint getCoord(int t, int x, int y) { return (t == 1) ? y : x; }\n\nbool chk(int x1, int y1, int x2, int y2) {\n    int t = getLineType(x1, y1, x2, y2), ln = getLineId(t, x1, y1);\n    int lo = getCoord(t, x1, y1), hi = getCoord(t, x2, y2);\n    if (lo > hi) swap(lo, hi);\n    auto it = segMap[t].find(ln);\n    if (it == segMap[t].end()) return true;\n    set<pair<int,int>>& s = it->second;\n    auto it2 = s.upper_bound({lo, INF});\n    if (it2 != s.begin()) { auto p = it2; --p; if (p->second > lo) return false; }\n    if (it2 != s.end() && it2->first < hi) return false;\n    return true;\n}\nvoid addSeg(int x1, int y1, int x2, int y2) {\n    int t = getLineType(x1, y1, x2, y2), ln = getLineId(t, x1, y1);\n    int lo = getCoord(t, x1, y1), hi = getCoord(t, x2, y2);\n    if (lo > hi) swap(lo, hi);\n    set<pair<int,int>>& s = segMap[t][ln];\n    auto it = s.upper_bound({lo, INF});\n    if (it != s.begin()) { auto p = it; --p; if (p->second > lo) { lo = p->first; it = s.erase(p); } }\n    while (it != s.end() && it->first < hi) { hi = max(hi, it->second); it = s.erase(it); }\n    s.emplace(lo, hi);\n}\nint wt(int x, int y) { int dx = x - c, dy = y - c; return dx * dx + dy * dy + 1; }\nbool inB(int x, int y) { return x >= 0 && x < N && y >= 0 && y < N; }\n\nbool tryR(int tx, int ty, int x2, int y2, int x3, int y3, int x4, int y4) {\n    if (!inB(x2, y2) || !inB(x3, y3) || !inB(x4, y4)) return false;\n    if (!dot[x2][y2] || !dot[x3][y3] || !dot[x4][y4]) return false;\n    int xs[4] = {tx, x2, x3, x4}, ys[4] = {ty, y2, y3, y4};\n    for (int i = 0; i < 4; i++) {\n        int ni = (i + 1) % 4, n2 = (i + 2) % 4;\n        if ((xs[ni] - xs[i]) * (xs[n2] - xs[ni]) + (ys[ni] - ys[i]) * (ys[n2] - ys[ni])) return false;\n    }\n    for (int i = 0; i < 4; i++) { int ni = (i + 1) % 4; if (!chk(xs[i], ys[i], xs[ni], ys[ni])) return false; }\n    for (int i = 0; i < 4; i++) { int ni = (i + 1) % 4; addSeg(xs[i], ys[i], xs[ni], ys[ni]); }\n    dot[tx][ty] = true; ops.emplace_back(tx, ty, x2, y2, x3, y3, x4, y4); return true;\n}\n\nbool tryUS(int tx, int ty) {\n    for (int a = -1; a <= 1; a += 2) for (int b = -1; b <= 1; b += 2)\n        if (tryR(tx, ty, tx + a, ty, tx + a, ty + b, tx, ty + b)) return true;\n    return false;\n}\nbool tryRect(int tx, int ty, int w, int h) {\n    for (int sw = -1; sw <= 1; sw += 2) for (int sh = -1; sh <= 1; sh += 2) {\n        int x2 = tx + w * sw, y4 = ty + h * sh;\n        if (!inB(x2, ty) || !inB(x2, y4) || !inB(tx, y4)) continue;\n        if (!dot[x2][ty] || !dot[x2][y4] || !dot[tx][y4]) continue;\n        bool ok = true;\n        for (int k = 1; k < w && ok; k++) if (dot[tx + k * sw][ty] || dot[tx + k * sw][y4]) ok = false;\n        for (int k = 1; k < h && ok; k++) if (dot[tx][ty + k * sh] || dot[x2][ty + k * sh]) ok = false;\n        if (ok && tryR(tx, ty, x2, ty, x2, y4, tx, y4)) return true;\n    }\n    return false;\n}\nbool tryUD(int tx, int ty) {\n    int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};\n    for (int i = 0; i < 4; i++) {\n        int cx = tx - dx[i], cy = ty - dy[i], ox[3], oy[3]; bool valid = true;\n        for (int j = 0; j < 3; j++) { int k = (i + 1 + j) % 4; ox[j] = cx + dx[k]; oy[j] = cy + dy[k];\n            if (!inB(ox[j], oy[j]) || !dot[ox[j]][oy[j]]) valid = false; }\n        if (valid && tryR(tx, ty, ox[0], oy[0], ox[1], oy[1], ox[2], oy[2])) return true;\n    }\n    return false;\n}\nbool tryDiam(int tx, int ty, int s) {\n    int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};\n    for (int i = 0; i < 4; i++) {\n        int cx = tx - s * dx[i], cy = ty - s * dy[i], vx[4], vy[4];\n        for (int j = 0; j < 4; j++) { vx[j] = cx + s * dx[j]; vy[j] = cy + s * dy[j]; }\n        bool ok = true; int nt[3];\n        for (int j = 0; j < 3; j++) { nt[j] = (i + 1 + j) % 4;\n            if (!inB(vx[nt[j]], vy[nt[j]]) || !dot[vx[nt[j]]][vy[nt[j]]]) ok = false; }\n        if (!ok) continue; bool ec = true;\n        for (int e = 0; e < 4 && ec; e++) { int e2 = (e + 1) % 4;\n            for (int k = 1; k < s && ec; k++) { int mx = vx[e] + k * (vx[e2] - vx[e]) / s, my = vy[e] + k * (vy[e2] - vy[e]) / s;\n                if (inB(mx, my) && dot[mx][my]) ec = false; } }\n        if (ec && tryR(tx, ty, vx[nt[0]], vy[nt[0]], vx[nt[1]], vy[nt[1]], vx[nt[2]], vy[nt[2]])) return true;\n    }\n    return false;\n}\nbool tryMD(int tx, int ty, int a, int b) {\n    for (int sa = -1; sa <= 1; sa += 2) for (int sb = -1; sb <= 1; sb += 2) {\n        int x1 = tx + a * sa, y1 = ty + a * sa, x2 = x1 + b * sb, y2 = y1 - b * sb, x3 = tx + b * sb, y3 = ty - b * sb;\n        if (!inB(x1, y1) || !inB(x2, y2) || !inB(x3, y3)) continue;\n        if (!dot[x1][y1] || !dot[x2][y2] || !dot[x3][y3]) continue;\n        bool ec = true;\n        for (int k = 1; k < a && ec; k++) { int mx = tx + k * sa, my = ty + k * sa; if (inB(mx, my) && dot[mx][my]) ec = false; }\n        for (int k = 1; k < b && ec; k++) { int mx = x1 + k * sb, my = y1 - k * sb; if (inB(mx, my) && dot[mx][my]) ec = false; }\n        for (int k = 1; k < a && ec; k++) { int mx = x2 - k * sa, my = y2 - k * sa; if (inB(mx, my) && dot[mx][my]) ec = false; }\n        for (int k = 1; k < b && ec; k++) { int mx = x3 - k * sb, my = y3 + k * sb; if (inB(mx, my) && dot[mx][my]) ec = false; }\n        if (ec && tryR(tx, ty, x1, y1, x2, y2, x3, y3)) return true;\n    }\n    return false;\n}\n\nbool tryL0(int x, int y) { return tryUS(x, y) || tryUD(x, y); }\nbool tryL1(int x, int y) { return tryRect(x, y, 2, 2) || tryDiam(x, y, 2); }\nbool tryL2(int x, int y) {\n    if (tryRect(x, y, 3, 3) || tryDiam(x, y, 3)) return true;\n    int mix[] = {23, 32, 12, 21, 13, 31, 34, 43};\n    for (int m : mix) if (tryRect(x, y, m / 10, m % 10)) return true;\n    for (int m : mix) if (tryMD(x, y, m / 10, m % 10)) return true;\n    return false;\n}\nbool tryL3(int x, int y) {\n    if (tryRect(x, y, 4, 4) || tryDiam(x, y, 4)) return true;\n    int mix[] = {45, 54, 24, 42, 35, 53, 14, 41, 15, 51, 25, 52};\n    for (int m : mix) if (tryRect(x, y, m / 10, m % 10)) return true;\n    for (int m : mix) if (tryMD(x, y, m / 10, m % 10)) return true;\n    return false;\n}\nbool tryL4(int x, int y) {\n    if (tryRect(x, y, 5, 5) || tryDiam(x, y, 5) || tryRect(x, y, 6, 6) || tryDiam(x, y, 6)) return true;\n    int mix[] = {56, 65, 46, 64, 36, 63, 26, 62, 16, 61};\n    for (int m : mix) if (tryRect(x, y, m / 10, m % 10)) return true;\n    for (int m : mix) if (tryMD(x, y, m / 10, m % 10)) return true;\n    return false;\n}\nbool tryL5(int x, int y) {\n    if (tryRect(x, y, 7, 7) || tryDiam(x, y, 7)) return true;\n    int mix[] = {57, 75, 47, 74, 37, 73, 27, 72, 17, 71, 67, 76};\n    for (int m : mix) if (tryRect(x, y, m / 10, m % 10)) return true;\n    for (int m : mix) if (tryMD(x, y, m / 10, m % 10)) return true;\n    return false;\n}\nbool tryL(int x, int y, int l) {\n    if (l == 0) return tryL0(x, y); if (l == 1) return tryL1(x, y);\n    if (l == 2) return tryL2(x, y); if (l == 3) return tryL3(x, y);\n    if (l == 4) return tryL4(x, y);\n    return tryL5(x, y);\n}\n\nvoid addFront(int x, int y, int lv = 0) {\n    for (int dx = -MAX_DIST; dx <= MAX_DIST; dx++) for (int dy = -MAX_DIST; dy <= MAX_DIST; dy++) {\n        int d = max(abs(dx), abs(dy)); if (d == 0 || d > MAX_DIST) continue;\n        int nx = x + dx, ny = y + dy;\n        if (inB(nx, ny) && !dot[nx][ny] && (curLevel[nx][ny] == -1 || lv < curLevel[nx][ny])) {\n            curLevel[nx][ny] = lv;\n            int noise = useNoise ? ((int)(rng() % 101) - 50) : 0;\n            frontier.emplace(wt(nx, ny) + noise, -lv, nx, ny);\n        }\n    }\n}\n\nvoid resetState() {\n    memset(dot, 0, sizeof(dot));\n    memset(curLevel, -1, sizeof(curLevel));\n    for (int i = 0; i < 4; i++) segMap[i].clear();\n    ops.clear();\n    frontier.clear();\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    auto start = steady_clock::now();\n    cin >> N >> M; c = (N - 1) / 2;\n    for (int i = 0; i < M; i++) cin >> initX[i] >> initY[i];\n    \n    long long bestWeightSum = 0;\n    vector<tuple<int,int,int,int,int,int,int,int>> bestOps;\n    \n    for (int run = 0; ; run++) {\n        auto elapsed = duration_cast<milliseconds>(steady_clock::now() - start).count();\n        if (elapsed > 4300) break;\n        auto runStart = steady_clock::now();\n        \n        useNoise = (run > 0);\n        if (useNoise) rng.seed(run * 1234567 + 7654321);\n        resetState();\n        for (int i = 0; i < M; i++) dot[initX[i]][initY[i]] = true;\n        for (int x = 0; x < N; x++) for (int y = 0; y < N; y++) if (dot[x][y]) addFront(x, y, 0);\n        \n        while (!frontier.empty()) {\n            if (duration_cast<milliseconds>(steady_clock::now() - runStart).count() > 200) break;\n            auto [w, nl, x, y] = *frontier.begin(); frontier.erase(frontier.begin());\n            if (dot[x][y] || -nl != curLevel[x][y]) continue;\n            int lv = -nl;\n            if (tryL(x, y, lv)) { curLevel[x][y] = -1; addFront(x, y, 0); }\n            else if (lv < MAX_LEVEL) { curLevel[x][y] = lv + 1; frontier.emplace(w, -(lv + 1), x, y); }\n            else curLevel[x][y] = -1;\n        }\n        \n        long long weightSum = 0;\n        for (int x = 0; x < N; x++) for (int y = 0; y < N; y++) if (dot[x][y]) weightSum += wt(x, y);\n        \n        if (weightSum > bestWeightSum) {\n            bestWeightSum = weightSum;\n            bestOps = ops;\n        }\n    }\n    \n    cout << bestOps.size() << \"\\n\";\n    for (auto& o : bestOps) cout << get<0>(o) << \" \" << get<1>(o) << \" \" << get<2>(o) << \" \" << get<3>(o) << \" \" << get<4>(o) << \" \" << get<5>(o) << \" \" << get<6>(o) << \" \" << get<7>(o) << \"\\n\";\n    return 0;\n}","ahc015":"#include <iostream>\n#include <cstring>\n#include <vector>\n\nusing namespace std;\n\nconst int N = 10;\nint grid[N][N];\nconst int dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1};\nconst char dirs[] = {'F', 'B', 'L', 'R'};\n\nvoid tilt(char dir) {\n    if (dir == 'F') {\n        for (int c = 0; c < N; c++) { int w = 0; for (int r = 0; r < N; r++) if (grid[r][c]) { int f = grid[r][c]; grid[r][c] = 0; grid[w++][c] = f; } }\n    } else if (dir == 'B') {\n        for (int c = 0; c < N; c++) { int w = N - 1; for (int r = N - 1; r >= 0; r--) if (grid[r][c]) { int f = grid[r][c]; grid[r][c] = 0; grid[w--][c] = f; } }\n    } else if (dir == 'L') {\n        for (int r = 0; r < N; r++) { int w = 0; for (int c = 0; c < N; c++) if (grid[r][c]) { int f = grid[r][c]; grid[r][c] = 0; grid[r][w++] = f; } }\n    } else {\n        for (int r = 0; r < N; r++) { int w = N - 1; for (int c = N - 1; c >= 0; c--) if (grid[r][c]) { int f = grid[r][c]; grid[r][c] = 0; grid[r][w--] = f; } }\n    }\n}\n\nint computeSumSq() {\n    static int vis[N][N], stk[100];\n    memset(vis, 0, sizeof(vis));\n    int sumSq = 0;\n    for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) if (grid[r][c] && !vis[r][c]) {\n        int sz = 0, f = grid[r][c], top = 0;\n        stk[top++] = r * N + c; vis[r][c] = 1;\n        while (top > 0) {\n            int p = stk[--top], cr = p / N, cc = p % N; sz++;\n            for (int d = 0; d < 4; d++) {\n                int nr = cr + dr[d], nc = cc + dc[d];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N && !vis[nr][nc] && grid[nr][nc] == f) { vis[nr][nc] = 1; stk[top++] = nr * N + nc; }\n            }\n        }\n        sumSq += sz * sz;\n    }\n    return sumSq;\n}\n\nvector<pair<int,int>> getSampledCells(int flavor, int maxSamples) {\n    vector<pair<int,int>> mergeCells, extendCells, otherCells;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (!grid[i][j]) {\n        int adjCount = 0;\n        for (int d = 0; d < 4; d++) {\n            int ni = i + dr[d], nj = j + dc[d];\n            if (ni >= 0 && ni < N && nj >= 0 && nj < N && grid[ni][nj] == flavor) adjCount++;\n        }\n        if (adjCount >= 2) mergeCells.push_back({i, j});\n        else if (adjCount == 1) extendCells.push_back({i, j});\n        else otherCells.push_back({i, j});\n    }\n    int totalCells = mergeCells.size() + extendCells.size() + otherCells.size();\n    if (totalCells <= maxSamples) {\n        vector<pair<int,int>> result = mergeCells;\n        result.insert(result.end(), extendCells.begin(), extendCells.end());\n        result.insert(result.end(), otherCells.begin(), otherCells.end());\n        return result;\n    }\n    vector<pair<int,int>> result;\n    for (auto& c : mergeCells) result.push_back(c);\n    for (auto& c : extendCells) if ((int)result.size() < maxSamples) result.push_back(c);\n    int remaining = maxSamples - result.size();\n    if (remaining > 0 && !otherCells.empty()) {\n        int step = max(1, (int)otherCells.size() / remaining);\n        for (int i = 0; i < (int)otherCells.size() && (int)result.size() < maxSamples; i += step)\n            result.push_back(otherCells[i]);\n    }\n    return result;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int flavors[100];\n    for (int i = 0; i < 100; i++) cin >> flavors[i];\n    memset(grid, 0, sizeof(grid));\n    for (int t = 0; t < 100; t++) {\n        int p; cin >> p;\n        int cnt = 0, r = -1, c = -1;\n        for (int i = 0; i < N && r < 0; i++) for (int j = 0; j < N && r < 0; j++) if (!grid[i][j] && ++cnt == p) { r = i; c = j; }\n        grid[r][c] = flavors[t];\n        if (t < 99) {\n            char bestDir = 'F'; int bestScore = -1;\n            int nextFlavor = flavors[t + 1];\n            int numEmpty = 100 - t - 1;\n            int maxSamples = numEmpty <= 20 ? numEmpty : (numEmpty <= 40 ? 18 : 15);\n            for (int di = 0; di < 4; di++) {\n                int saved0[N][N]; memcpy(saved0, grid, sizeof(grid));\n                tilt(dirs[di]);\n                int currentScore = computeSumSq();\n                vector<pair<int,int>> cells1 = getSampledCells(nextFlavor, maxSamples);\n                int sampleCount1 = cells1.size();\n                int totalFutureBest = 0;\n                for (auto& [er, ec] : cells1) {\n                    int saved1[N][N]; memcpy(saved1, grid, sizeof(grid));\n                    grid[er][ec] = nextFlavor;\n                    int bestFuture1 = 0;\n                    for (int d = 0; d < 4; d++) {\n                        int saved2[N][N]; memcpy(saved2, grid, sizeof(grid));\n                        tilt(dirs[d]);\n                        int score = computeSumSq();\n                        if (score > bestFuture1) bestFuture1 = score;\n                        memcpy(grid, saved2, sizeof(grid));\n                    }\n                    totalFutureBest += bestFuture1;\n                    memcpy(grid, saved1, sizeof(grid));\n                }\n                int score = currentScore * sampleCount1 * 3 + totalFutureBest * 2;\n                memcpy(grid, saved0, sizeof(grid));\n                if (score > bestScore) { bestScore = score; bestDir = dirs[di]; }\n            }\n            tilt(bestDir); cout << bestDir << endl;\n        }\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int M;\n    double eps;\n    cin >> M >> eps;\n    \n    int N;\n    bool use_edge_count;\n    \n    if (eps > 0.35) {\n        N = 4;\n        use_edge_count = true;\n    } else {\n        use_edge_count = false;\n        int min_n = 4;\n        while (min_n * (min_n - 1) / 2 < M && min_n < 100) min_n++;\n        \n        if (eps <= 0.12) {\n            N = max(min_n, min(100, (int)(min_n * (1.0 + 5.0 * eps))));\n        } else {\n            N = max(min_n, min(100, (int)(M * (0.2 + 2.0 * eps))));\n        }\n    }\n    \n    int total_pairs = N * (N - 1) / 2;\n    \n    mt19937 rng(42);\n    \n    vector<string> graphs(M);\n    vector<int> edge_counts(M);\n    vector<vector<int>> sorted_deg(M, vector<int>(N));\n    \n    for (int i = 0; i < M; i++) {\n        edge_counts[i] = (int)((i + 0.5) * total_pairs / M);\n        string g(total_pairs, '0');\n        vector<int> indices(total_pairs);\n        iota(indices.begin(), indices.end(), 0);\n        shuffle(indices.begin(), indices.end(), rng);\n        for (int j = 0; j < edge_counts[i]; j++) g[indices[j]] = '1';\n        graphs[i] = g;\n        \n        int idx = 0;\n        for (int v = 0; v < N; v++) {\n            for (int u = v + 1; u < N; u++) {\n                if (g[idx++] == '1') {\n                    sorted_deg[i][v]++;\n                    sorted_deg[i][u]++;\n                }\n            }\n        }\n        sort(sorted_deg[i].begin(), sorted_deg[i].end());\n    }\n    \n    cout << N << \"\\n\";\n    for (auto& g : graphs) cout << g << \"\\n\";\n    cout << flush;\n    \n    for (int q = 0; q < 100; q++) {\n        string H;\n        cin >> H;\n        \n        if (use_edge_count) {\n            int h_edges = count(H.begin(), H.end(), '1');\n            int best = 0;\n            int best_dist = abs(h_edges - edge_counts[0]);\n            for (int i = 1; i < M; i++) {\n                int dist = abs(h_edges - edge_counts[i]);\n                if (dist < best_dist) {\n                    best_dist = dist;\n                    best = i;\n                }\n            }\n            cout << best << \"\\n\" << flush;\n        } else {\n            vector<int> h_deg(N);\n            int idx = 0;\n            for (int v = 0; v < N; v++) {\n                for (int u = v + 1; u < N; u++) {\n                    if (H[idx++] == '1') {\n                        h_deg[v]++;\n                        h_deg[u]++;\n                    }\n                }\n            }\n            sort(h_deg.begin(), h_deg.end());\n            \n            int best = 0;\n            double best_dist = 1e18;\n            for (int i = 0; i < M; i++) {\n                double dist = 0;\n                for (int j = 0; j < N; j++) {\n                    double diff = h_deg[j] - sorted_deg[i][j];\n                    dist += diff * diff;\n                }\n                if (dist < best_dist) {\n                    best_dist = dist;\n                    best = i;\n                }\n            }\n            cout << best << \"\\n\" << flush;\n        }\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    cin >> N >> M >> D >> K;\n    \n    vector<tuple<int, int, int>> edges(M);\n    vector<vector<pair<int, int>>> adj(N);\n    vector<int> degree(N, 0);\n    vector<int> xv(N), yv(N);\n    \n    unsigned long long seed = N * 1000000007ULL + M * 998244353ULL + D * 1000003ULL + K;\n    \n    for (int i = 0; i < M; i++) {\n        int u, v, w; cin >> u >> v >> w; u--; v--;\n        edges[i] = {u, v, w};\n        adj[u].push_back({v, i}); adj[v].push_back({u, i});\n        degree[u]++; degree[v]++;\n        seed ^= (unsigned long long)(u+1) * 1000000007ULL + (unsigned long long)(v+1) * 998244353ULL + w;\n    }\n    for (int i = 0; i < N; i++) { cin >> xv[i] >> yv[i]; seed ^= (unsigned long long)xv[i] * 10007ULL + yv[i]; }\n    \n    mt19937 rng(seed);\n    \n    vector<long long> importance(M, 0);\n    int S = min(100, N);\n    vector<int> sources(S); iota(sources.begin(), sources.end(), 0);\n    shuffle(sources.begin(), sources.end(), rng);\n    \n    for (int s : sources) {\n        vector<long long> dist(N, 1e18); vector<int> parent_edge(N, -1);\n        dist[s] = 0;\n        priority_queue<pair<long long,int>,vector<pair<long long,int>>,greater<>> pq; pq.push({0,s});\n        while (!pq.empty()) {\n            auto [d,u] = pq.top(); pq.pop(); if (d > dist[u]) continue;\n            for (auto [v,ei] : adj[u]) if (dist[u]+get<2>(edges[ei]) < dist[v]) { dist[v]=dist[u]+get<2>(edges[ei]); parent_edge[v]=ei; pq.push({dist[v],v}); }\n        }\n        vector<vector<int>> children(N);\n        for (int v=0; v<N; v++) if (parent_edge[v]!=-1) { auto [pu,pv,pw]=edges[parent_edge[v]]; children[(pu==v)?pv:pu].push_back(v); }\n        vector<int> sz(N,1);\n        function<void(int)> dfs=[&](int u){ for(int v:children[u]){dfs(v);sz[u]+=sz[v];} if(parent_edge[u]!=-1)importance[parent_edge[u]]+=(long long)sz[u]*get<2>(edges[parent_edge[u]]); };\n        dfs(s);\n    }\n    \n    auto hilbert = [](int n, int xp, int yp) -> long long {\n        long long d = 0;\n        for (int s = 1 << (n-1); s > 0; s >>= 1) {\n            int rx = (xp & s) > 0, ry = (yp & s) > 0;\n            d += (long long)s * s * ((3 * rx) ^ ry);\n            if (ry == 0) { if (rx == 1) { xp = s-1-xp; yp = s-1-yp; } swap(xp, yp); }\n        }\n        return d;\n    };\n    \n    vector<long long> hval(M);\n    for (int i = 0; i < M; i++) {\n        int mx = (xv[get<0>(edges[i])] + xv[get<1>(edges[i])]) / 2;\n        int my = (yv[get<0>(edges[i])] + yv[get<1>(edges[i])]) / 2;\n        hval[i] = hilbert(10, mx, my);\n    }\n    \n    vector<int> order(M); iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) { return hval[a] < hval[b]; });\n    \n    vector<int> day_assignment(M), day_count(D, 0), vdc(N*D, 0);\n    vector<long long> vdi(N*D, 0);\n    vector<vector<int>> day_edges(D);\n    int day_ptr = 0;\n    \n    for (int e : order) {\n        auto [u, v, w] = edges[e];\n        int assigned = -1; long long best_imp = LLONG_MAX;\n        for (int att = 0; att < D; att++) {\n            int d = (day_ptr + att) % D;\n            if (day_count[d] >= K || vdc[u*D+d]+1 >= degree[u] || vdc[v*D+d]+1 >= degree[v]) continue;\n            long long imp = vdi[u*D+d] + vdi[v*D+d];\n            if (imp < best_imp) { best_imp = imp; assigned = d; }\n        }\n        if (assigned == -1) for (int d = 0; d < D; d++) {\n            if (day_count[d] >= K || vdc[u*D+d]+1 >= degree[u] || vdc[v*D+d]+1 >= degree[v]) continue;\n            long long imp = vdi[u*D+d] + vdi[v*D+d];\n            if (imp < best_imp) { best_imp = imp; assigned = d; }\n        }\n        if (assigned == -1) assigned = 0;\n        day_ptr = (assigned + 1) % D;\n        day_assignment[e] = assigned; day_count[assigned]++; day_edges[assigned].push_back(e);\n        vdc[u*D+assigned]++; vdc[v*D+assigned]++;\n        vdi[u*D+assigned] += importance[e]; vdi[v*D+assigned] += importance[e];\n    }\n    \n    auto get_components = [&](int d, vector<int>& comp) {\n        comp.assign(N, -1);\n        vector<int> par(N); iota(par.begin(), par.end(), 0);\n        function<int(int)> find = [&](int x) { return par[x]==x ? x : par[x]=find(par[x]); };\n        for (int e = 0; e < M; e++) { if (day_assignment[e]==d) continue; par[find(get<0>(edges[e]))]=find(get<1>(edges[e])); }\n        int nc = 0;\n        for (int i = 0; i < N; i++) if (par[i]==i) comp[i] = nc++;\n        for (int i = 0; i < N; i++) comp[i] = comp[find(i)];\n        return nc;\n    };\n    \n    auto move_edge = [&](int e, int from_d, int to_d) {\n        auto [u, v, w] = edges[e];\n        day_assignment[e]=to_d; day_count[from_d]--; day_count[to_d]++;\n        day_edges[from_d].erase(find(day_edges[from_d].begin(),day_edges[from_d].end(),e));\n        day_edges[to_d].push_back(e);\n        vdc[u*D+from_d]--; vdc[u*D+to_d]++; vdc[v*D+from_d]--; vdc[v*D+to_d]++;\n        vdi[u*D+from_d]-=importance[e]; vdi[u*D+to_d]+=importance[e];\n        vdi[v*D+from_d]-=importance[e]; vdi[v*D+to_d]+=importance[e];\n    };\n    \n    auto can_move = [&](int e, int to_d) {\n        auto [u, v, w] = edges[e];\n        return day_count[to_d] < K && vdc[u*D+to_d]+1 < degree[u] && vdc[v*D+to_d]+1 < degree[v];\n    };\n    \n    auto fix_connectivity = [&]() -> int {\n        int fixed = 0;\n        for (int iter = 0; iter < 1000; iter++) {\n            bool any_fixed = false;\n            for (int d = 0; d < D; d++) {\n                vector<int> comp;\n                int nc = get_components(d, comp);\n                if (nc <= 1) continue;\n                vector<int> bridge_edges;\n                for (int e : day_edges[d]) if (comp[get<0>(edges[e])] != comp[get<1>(edges[e])]) bridge_edges.push_back(e);\n                shuffle(bridge_edges.begin(), bridge_edges.end(), rng);\n                for (int e : bridge_edges) {\n                    if (day_assignment[e] != d) continue;\n                    auto [u, v, w] = edges[e];\n                    vector<int> ds(D); iota(ds.begin(), ds.end(), 0); shuffle(ds.begin(), ds.end(), rng);\n                    for (int d2 : ds) { if (d2 != d && can_move(e, d2)) { move_edge(e, d, d2); fixed++; any_fixed = true; break; } }\n                    if (any_fixed) break;\n                    for (int d2 : ds) {\n                        if (d2 == d) continue;\n                        vector<int> idx(day_edges[d2].size()); iota(idx.begin(), idx.end(), 0); shuffle(idx.begin(), idx.end(), rng);\n                        for (int ii : idx) {\n                            int e2 = day_edges[d2][ii];\n                            auto [u2, v2, w2] = edges[e2];\n                            int e2u=(u2==u||v2==u)?1:0, e2v=(u2==v||v2==v)?1:0, eu2=(u==u2||v==u2)?1:0, ev2=(u==v2||v==v2)?1:0;\n                            if (vdc[u*D+d2]+1-e2u>=degree[u]||vdc[v*D+d2]+1-e2v>=degree[v]) continue;\n                            if (vdc[u2*D+d]+1-eu2>=degree[u2]||vdc[v2*D+d]+1-ev2>=degree[v2]) continue;\n                            day_assignment[e]=d2; day_assignment[e2]=d;\n                            vdc[u*D+d]--;vdc[u*D+d2]++;vdc[v*D+d]--;vdc[v*D+d2]++;\n                            vdc[u2*D+d2]--;vdc[u2*D+d]++;vdc[v2*D+d2]--;vdc[v2*D+d]++;\n                            vdi[u*D+d]-=importance[e];vdi[u*D+d2]+=importance[e];vdi[v*D+d]-=importance[e];vdi[v*D+d2]+=importance[e];\n                            vdi[u2*D+d2]-=importance[e2];vdi[u2*D+d]+=importance[e2];vdi[v2*D+d2]-=importance[e2];vdi[v2*D+d]+=importance[e2];\n                            day_edges[d].erase(find(day_edges[d].begin(),day_edges[d].end(),e));\n                            day_edges[d2].erase(day_edges[d2].begin()+ii);day_edges[d].push_back(e2);day_edges[d2].push_back(e);\n                            fixed++; any_fixed = true; break;\n                        }\n                        if (any_fixed) break;\n                    }\n                    if (any_fixed) break;\n                }\n                if (any_fixed) break;\n            }\n            if (!any_fixed) break;\n        }\n        return fixed;\n    };\n    \n    fix_connectivity();\n    \n    auto start = chrono::high_resolution_clock::now(); double temp = 50.0;\n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration<double>(now-start).count() > 4.2) break;\n        temp *= 0.999997;\n        int d1=rng()%D, d2=rng()%D;\n        if (d1==d2||day_edges[d1].empty()||day_edges[d2].empty()) continue;\n        int i1=rng()%day_edges[d1].size(), i2=rng()%day_edges[d2].size();\n        int e1=day_edges[d1][i1], e2=day_edges[d2][i2];\n        auto [u1,v1,w1]=edges[e1]; auto [u2,v2,w2]=edges[e2];\n        long long imp1=importance[e1], imp2=importance[e2];\n        int e2u1=(u2==u1||v2==u1)?1:0, e2v1=(u2==v1||v2==v1)?1:0, e1u2=(u1==u2||v1==u2)?1:0, e1v2=(u1==v2||v1==v2)?1:0;\n        if (vdc[u1*D+d2]+1-e2u1>=degree[u1]||vdc[v1*D+d2]+1-e2v1>=degree[v1]) continue;\n        if (vdc[u2*D+d1]+1-e1u2>=degree[u2]||vdc[v2*D+d1]+1-e1v2>=degree[v2]) continue;\n        long long c1=vdi[u1*D+d1]+vdi[v1*D+d1]-2*imp1, c2=vdi[u2*D+d2]+vdi[v2*D+d2]-2*imp2;\n        long long n1=vdi[u1*D+d2]+vdi[v1*D+d2]-(e2u1?imp2:0)-(e2v1?imp2:0);\n        long long n2=vdi[u2*D+d1]+vdi[v2*D+d1]-(e1u2?imp1:0)-(e1v2?imp1:0);\n        long long delta=(n1+n2)-(c1+c2);\n        if (delta<0||(temp>0.01&&(double)(rng()%10000)/10000.0<exp(-(double)delta/max(temp,1.0)))) {\n            day_assignment[e1]=d2; day_assignment[e2]=d1;\n            vdc[u1*D+d1]--;vdc[v1*D+d1]--;vdc[u1*D+d2]++;vdc[v1*D+d2]++;\n            vdc[u2*D+d2]--;vdc[v2*D+d2]--;vdc[u2*D+d1]++;vdc[v2*D+d1]++;\n            vdi[u1*D+d1]-=imp1;vdi[v1*D+d1]-=imp1;vdi[u1*D+d2]+=imp1;vdi[v1*D+d2]+=imp1;\n            vdi[u2*D+d2]-=imp2;vdi[v2*D+d2]-=imp2;vdi[u2*D+d1]+=imp2;vdi[v2*D+d1]+=imp2;\n            day_edges[d1][i1]=e2; day_edges[d2][i2]=e1;\n        }\n    }\n    \n    fix_connectivity();\n    for (int i=0;i<M;i++) cout<<day_assignment[i]+1<<\" \\n\"[i==M-1];\n}","ahc019":"#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\nusing namespace chrono;\n\nint D, b[2][15][15][15], n, rots[24][3][3], numRots=0;\nhigh_resolution_clock::time_point start_time;\n\nstruct TupleHash {\n    size_t operator()(const tuple<int,int,int>& t) const {\n        auto [x, y, z] = t;\n        return x * 225 + y * 15 + z;\n    }\n};\nusing PointSet = unordered_set<tuple<int,int,int>, TupleHash>;\nPointSet V[2];\n\nvoid generateRotations() {\n    set<vector<int>> seen; queue<vector<int>> q;\n    vector<int> id={1,0,0,0,1,0,0,0,1},rx={1,0,0,0,0,-1,0,1,0},ry={0,0,1,0,1,0,-1,0,0},rz={0,-1,0,1,0,0,0,0,1};\n    q.push(id); seen.insert(id);\n    auto mul=[](vector<int> a,vector<int> b){vector<int> c(9);for(int i=0;i<3;i++)for(int j=0;j<3;j++){c[i*3+j]=0;for(int k=0;k<3;k++)c[i*3+j]+=a[i*3+k]*b[k*3+j];}return c;};\n    while(!q.empty()){auto cur=q.front();q.pop();for(int i=0;i<9;i++)rots[numRots][i/3][i%3]=cur[i];numRots++;for(auto&base:{rx,ry,rz}){auto nx=mul(cur,base);if(!seen.count(nx)){seen.insert(nx);q.push(nx);}}}\n}\n\nstring canonical(const vector<tuple<int,int,int>>& cubes) {\n    string best;\n    for(int r=0;r<24;r++){vector<tuple<int,int,int>> rot;int mx=INT_MAX,my=INT_MAX,mz=INT_MAX;\n        for(auto&[x,y,z]:cubes){int nx=rots[r][0][0]*x+rots[r][0][1]*y+rots[r][0][2]*z,ny=rots[r][1][0]*x+rots[r][1][1]*y+rots[r][1][2]*z,nz=rots[r][2][0]*x+rots[r][2][1]*y+rots[r][2][2]*z;mx=min(mx,nx);my=min(my,ny);mz=min(mz,nz);rot.push_back({nx,ny,nz});}\n        sort(rot.begin(),rot.end());string s;for(auto&[x,y,z]:rot){s+=char(x-mx+'a');s+=char(y-my+'a');s+=char(z-mz+'a');}if(best.empty()||s<best)best=s;}return best;\n}\n\nvoid findComponents(PointSet& V, vector<vector<tuple<int,int,int>>>& comps) {\n    PointSet rem=V; int dx[]={1,-1,0,0,0,0},dy[]={0,0,1,-1,0,0},dz[]={0,0,0,0,1,-1};\n    while(!rem.empty()){auto[sx,sy,sz]=*rem.begin();rem.erase(rem.begin());vector<tuple<int,int,int>> comp;comp.push_back({sx,sy,sz});queue<tuple<int,int,int>> q;q.push({sx,sy,sz});\n    while(!q.empty()){auto[x,y,z]=q.front();q.pop();for(int d=0;d<6;d++){int nx=x+dx[d],ny=y+dy[d],nz=z+dz[d];auto np=make_tuple(nx,ny,nz);if(rem.count(np)){rem.erase(np);comp.push_back(np);q.push(np);}}}comps.push_back(comp);}\n}\n\nvoid extractAndAssign(PointSet rem[2], int rot, tuple<int,int,int> trans) {\n    PointSet m0;\n    for(auto&[x,y,z]:rem[0]){int rx=rots[rot][0][0]*(x-get<0>(trans))+rots[rot][1][0]*(y-get<1>(trans))+rots[rot][2][0]*(z-get<2>(trans)),ry=rots[rot][0][1]*(x-get<0>(trans))+rots[rot][1][1]*(y-get<1>(trans))+rots[rot][2][1]*(z-get<2>(trans)),rz=rots[rot][0][2]*(x-get<0>(trans))+rots[rot][1][2]*(y-get<1>(trans))+rots[rot][2][2]*(z-get<2>(trans));if(rem[1].count({rx,ry,rz}))m0.insert({x,y,z});}\n    vector<vector<tuple<int,int,int>>> comps;findComponents(m0,comps);\n    for(auto&comp:comps){n++;for(auto&[x,y,z]:comp){b[0][x][y][z]=n;int rx=rots[rot][0][0]*(x-get<0>(trans))+rots[rot][1][0]*(y-get<1>(trans))+rots[rot][2][0]*(z-get<2>(trans)),ry=rots[rot][0][1]*(x-get<0>(trans))+rots[rot][1][1]*(y-get<1>(trans))+rots[rot][2][1]*(z-get<2>(trans)),rz=rots[rot][0][2]*(x-get<0>(trans))+rots[rot][1][2]*(y-get<1>(trans))+rots[rot][2][2]*(z-get<2>(trans));b[1][rx][ry][rz]=n;rem[0].erase({x,y,z});rem[1].erase({rx,ry,rz});}}\n}\n\npair<int,tuple<int,int,int>> findBestAlignmentScored(PointSet& V0, PointSet& V1) {\n    vector<tuple<int,int,int>> v0(V0.begin(),V0.end()),v1(V1.begin(),V1.end());\n    vector<tuple<int,int,tuple<int,int,int>>> top_rotations;\n    for(int rot=0;rot<24;rot++){unordered_map<tuple<int,int,int>,int,TupleHash> tc;\n        for(auto&[x0,y0,z0]:v0)for(auto&[x,y,z]:v1){int bx=rots[rot][0][0]*x+rots[rot][0][1]*y+rots[rot][0][2]*z,by=rots[rot][1][0]*x+rots[rot][1][1]*y+rots[rot][1][2]*z,bz=rots[rot][2][0]*x+rots[rot][2][1]*y+rots[rot][2][2]*z;tc[{x0-bx,y0-by,z0-bz}]++;}\n        int best_count=0;tuple<int,int,int> best_trans;\n        for(auto&[trans,count]:tc)if(count>best_count){best_count=count;best_trans=trans;}\n        top_rotations.push_back({best_count,rot,best_trans});}\n    sort(top_rotations.rbegin(),top_rotations.rend());\n    int best_rot=-1;tuple<int,int,int> best_trans;double best_score=-1;\n    for(int i=0;i<min(8,(int)top_rotations.size());i++){auto[count,rot,trans]=top_rotations[i];if(count<2)break;\n        PointSet matched;for(auto&[x,y,z]:v0){int rx=rots[rot][0][0]*(x-get<0>(trans))+rots[rot][1][0]*(y-get<1>(trans))+rots[rot][2][0]*(z-get<2>(trans)),ry=rots[rot][0][1]*(x-get<0>(trans))+rots[rot][1][1]*(y-get<1>(trans))+rots[rot][2][1]*(z-get<2>(trans)),rz=rots[rot][0][2]*(x-get<0>(trans))+rots[rot][1][2]*(y-get<1>(trans))+rots[rot][2][2]*(z-get<2>(trans));if(V1.count({rx,ry,rz}))matched.insert({x,y,z});}\n        vector<vector<tuple<int,int,int>>> comps;findComponents(matched,comps);\n        double score=0;for(auto&comp:comps){int v=comp.size();score+=2.0*v-1.0/v;}\n        if(score>best_score){best_score=score;best_rot=rot;best_trans=trans;}}\n    return {best_rot,best_trans};\n}\n\nbool tryCompAlignment(PointSet rem[2], vector<tuple<int,int,int>>& comp, int dir) {\n    PointSet& src = rem[dir];\n    PointSet& dst = rem[1-dir];\n    vector<tuple<int,int,int>> vdst(dst.begin(), dst.end());\n    int best_count=0,best_rot=-1;tuple<int,int,int> best_trans;\n    for(int rot=0;rot<24;rot++){unordered_map<tuple<int,int,int>,int,TupleHash> tc;\n        for(auto&[x,y,z]:comp){if(!src.count({x,y,z}))continue;\n            int nx=rots[rot][0][0]*x+rots[rot][0][1]*y+rots[rot][0][2]*z,ny=rots[rot][1][0]*x+rots[rot][1][1]*y+rots[rot][1][2]*z,nz=rots[rot][2][0]*x+rots[rot][2][1]*y+rots[rot][2][2]*z;\n            for(auto&[px,py,pz]:vdst)tc[{px-nx,py-ny,pz-nz}]++;}\n        for(auto&[trans,count]:tc)if(count>best_count){best_count=count;best_rot=rot;best_trans=trans;}}\n    if(best_count<1)return false;\n    PointSet msrc;\n    for(auto&[x,y,z]:comp){if(!src.count({x,y,z}))continue;\n        int qx=rots[best_rot][0][0]*x+rots[best_rot][0][1]*y+rots[best_rot][0][2]*z+get<0>(best_trans),qy=rots[best_rot][1][0]*x+rots[best_rot][1][1]*y+rots[best_rot][1][2]*z+get<1>(best_trans),qz=rots[best_rot][2][0]*x+rots[best_rot][2][1]*y+rots[best_rot][2][2]*z+get<2>(best_trans);\n        if(dst.count({qx,qy,qz}))msrc.insert({x,y,z});}\n    if(msrc.empty())return false;\n    vector<vector<tuple<int,int,int>>> comps;findComponents(msrc,comps);\n    for(auto&c:comps){n++;for(auto&[x,y,z]:c){b[dir][x][y][z]=n;int qx=rots[best_rot][0][0]*x+rots[best_rot][0][1]*y+rots[best_rot][0][2]*z+get<0>(best_trans),qy=rots[best_rot][1][0]*x+rots[best_rot][1][1]*y+rots[best_rot][1][2]*z+get<1>(best_trans),qz=rots[best_rot][2][0]*x+rots[best_rot][2][1]*y+rots[best_rot][2][2]*z+get<2>(best_trans);b[1-dir][qx][qy][qz]=n;src.erase({x,y,z});dst.erase({qx,qy,qz});}}return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr); start_time=high_resolution_clock::now();\n    generateRotations(); cin>>D; int f[2][15][15],r[2][15][15];\n    for(int i=0;i<2;i++){for(int z=0;z<D;z++){string s;cin>>s;for(int x=0;x<D;x++)f[i][z][x]=s[x]-'0';}for(int z=0;z<D;z++){string s;cin>>s;for(int y=0;y<D;y++)r[i][z][y]=s[y]-'0';}}\n    for(int i=0;i<2;i++)for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++)if(f[i][z][x]&&r[i][z][y])V[i].insert({x,y,z});\n    memset(b,0,sizeof(b)); n=0; PointSet rem[2]; rem[0]=V[0]; rem[1]=V[1];\n    auto ct=[&](){return duration_cast<milliseconds>(high_resolution_clock::now()-start_time).count();};\n    while(!rem[0].empty()&&!rem[1].empty()){if(ct()>2500)break;auto[rot,trans]=findBestAlignmentScored(rem[0],rem[1]);if(rot<0)break;extractAndAssign(rem,rot,trans);}\n    for(int dir=0;dir<2;dir++){if(rem[dir].empty()||rem[1-dir].empty())continue;\n        vector<vector<tuple<int,int,int>>> c;findComponents(rem[dir],c);sort(c.begin(),c.end(),[](auto&a,auto&b){return a.size()>b.size();});\n        for(auto&comp:c){if(ct()>4500)break;if(rem[1-dir].empty())break;tryCompAlignment(rem,comp,dir);}}\n    vector<vector<tuple<int,int,int>>> comps[2];findComponents(rem[0],comps[0]);findComponents(rem[1],comps[1]);\n    map<string,vector<pair<int,int>>> cm;vector<bool> cu[2];cu[0].resize(comps[0].size());cu[1].resize(comps[1].size());\n    for(int i=0;i<2;i++)for(int j=0;j<(int)comps[i].size();j++){auto&comp=comps[i][j];vector<tuple<int,int,int>> norm=comp;int mx=INT_MAX,my=INT_MAX,mz=INT_MAX;for(auto&[x,y,z]:norm){mx=min(mx,x);my=min(my,y);mz=min(mz,z);}for(auto&[x,y,z]:norm){x-=mx;y-=my;z-=mz;}cm[canonical(norm)].push_back({i,j});}\n    for(auto&[c,entries]:cm){vector<int> idx[2];for(auto&[obj,comp]:entries)idx[obj].push_back(comp);int p=min(idx[0].size(),idx[1].size());for(int k=0;k<p;k++){int i0=idx[0][k],i1=idx[1][k];cu[0][i0]=cu[1][i1]=true;n++;for(auto&[x,y,z]:comps[0][i0])b[0][x][y][z]=n;for(auto&[x,y,z]:comps[1][i1])b[1][x][y][z]=n;}}\n    for(int i=0;i<2;i++)for(int j=0;j<(int)comps[i].size();j++)if(!cu[i][j])for(auto&[x,y,z]:comps[i][j]){n++;b[i][x][y][z]=n;}\n    cout<<n<<'\\n';for(int i=0;i<2;i++){string out;for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){if(!out.empty())out+=' ';out+=to_string(b[i][x][y][z]);}cout<<out<<'\\n';}\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\ntypedef long long ll;\n\nint min_power(ll d2) {\n    if (d2 <= 0) return 0;\n    int r = (int)sqrt((double)d2);\n    while ((ll)r * r < d2) r++;\n    return r;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K;\n    cin >> N >> M >> K;\n    \n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    \n    vector<tuple<int, int, ll>> edges(M);\n    vector<vector<pair<int, int>>> adj(N);\n    for (int j = 0; j < M; j++) {\n        int u, v; ll w;\n        cin >> u >> v >> w;\n        u--; v--;\n        edges[j] = {u, v, w};\n        adj[u].push_back({v, j});\n        adj[v].push_back({u, j});\n    }\n    \n    vector<int> a(K), b(K);\n    for (int k = 0; k < K; k++) cin >> a[k] >> b[k];\n    \n    vector<vector<ll>> dist2(K, vector<ll>(N));\n    for (int k = 0; k < K; k++)\n        for (int i = 0; i < N; i++) {\n            ll dx = (ll)(x[i] - a[k]), dy = (ll)(y[i] - b[k]);\n            dist2[k][i] = dx * dx + dy * dy;\n        }\n    \n    vector<int> closest(K);\n    for (int k = 0; k < K; k++) {\n        ll min_d2 = LLONG_MAX; int mv = 0;\n        for (int i = 0; i < N; i++)\n            if (dist2[k][i] <= (ll)5000*5000 && dist2[k][i] < min_d2)\n                { min_d2 = dist2[k][i]; mv = i; }\n        closest[k] = mv;\n    }\n    \n    vector<bool> needed(N, false);\n    for (int k = 0; k < K; k++) needed[closest[k]] = true;\n    needed[0] = true;\n    \n    vector<vector<ll>> sp_dist(N, vector<ll>(N, LLONG_MAX));\n    vector<vector<int>> sp_next(N, vector<int>(N, -1));\n    for (int s = 0; s < N; s++) {\n        sp_dist[s][s] = 0;\n        priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<>> pq;\n        pq.push({0, s});\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > sp_dist[s][u]) continue;\n            for (auto& [to, j] : adj[u]) {\n                ll w = get<2>(edges[j]);\n                if (sp_dist[s][u] + w < sp_dist[s][to]) {\n                    sp_dist[s][to] = sp_dist[s][u] + w;\n                    sp_next[s][to] = j;\n                    pq.push({sp_dist[s][to], to});\n                }\n            }\n        }\n    }\n    \n    auto compute_keep = [&](const vector<bool>& eu) -> vector<bool> {\n        vector<bool> k(N, false); k[0] = true; bool ch = true;\n        while (ch) { ch = false;\n            for (int j = 0; j < M; j++) if (eu[j]) {\n                int u = get<0>(edges[j]), v = get<1>(edges[j]);\n                if (k[u] && !k[v]) { k[v] = true; ch = true; }\n                if (k[v] && !k[u]) { k[u] = true; ch = true; }\n            }\n        }\n        return k;\n    };\n    \n    auto calc_powers = [&](const vector<bool>& k) -> vector<int> {\n        vector<int> P(N, 0);\n        for (int k2 = 0; k2 < K; k2++) {\n            ll min_d2 = LLONG_MAX;\n            for (int i = 0; i < N; i++) if (k[i] && dist2[k2][i] <= (ll)5000*5000) min_d2 = min(min_d2, dist2[k2][i]);\n            if (min_d2 < LLONG_MAX) {\n                int p = min_power(min_d2);\n                for (int i = 0; i < N; i++) if (k[i] && dist2[k2][i] == min_d2) P[i] = max(P[i], p);\n            }\n        }\n        return P;\n    };\n    \n    auto calc_cost = [&](const vector<bool>& eu, const vector<int>& p) -> ll {\n        ll c = 0; for (int i = 0; i < N; i++) c += (ll)p[i] * p[i];\n        for (int j = 0; j < M; j++) if (eu[j]) c += get<2>(edges[j]); return c;\n    };\n    \n    auto check_coverage = [&](const vector<bool>& k, const vector<int>& P) -> bool {\n        for (int k2 = 0; k2 < K; k2++) {\n            bool covered = false;\n            for (int i = 0; i < N; i++)\n                if (k[i] && P[i] > 0 && dist2[k2][i] <= (ll)P[i] * P[i]) { covered = true; break; }\n            if (!covered) return false;\n        }\n        return true;\n    };\n    \n    auto prune_tree = [&](const vector<bool>& eu) -> vector<bool> {\n        vector<vector<pair<int, int>>> tree_adj(N);\n        for (int j = 0; j < M; j++) if (eu[j]) {\n            int u = get<0>(edges[j]), v = get<1>(edges[j]);\n            tree_adj[u].push_back({v, j});\n            tree_adj[v].push_back({u, j});\n        }\n        vector<bool> keep(N, false), visited(N, false);\n        function<void(int)> dfs = [&](int u) {\n            visited[u] = true; if (needed[u]) keep[u] = true;\n            for (auto& [v, j] : tree_adj[u]) if (!visited[v]) { dfs(v); if (keep[v]) keep[u] = true; }\n        };\n        dfs(0);\n        vector<bool> result(M, false);\n        for (int j = 0; j < M; j++) if (eu[j]) {\n            int u = get<0>(edges[j]), v = get<1>(edges[j]);\n            if (keep[u] && keep[v]) result[j] = true;\n        }\n        return result;\n    };\n    \n    auto remove_redundant = [&](vector<bool> eu) -> vector<bool> {\n        bool changed = true;\n        while (changed) {\n            changed = false;\n            for (int j = 0; j < M; j++) {\n                if (!eu[j]) continue;\n                eu[j] = false;\n                auto k = compute_keep(eu);\n                bool ok = true;\n                for (int i = 0; i < N; i++) if (needed[i] && !k[i]) { ok = false; break; }\n                if (!ok) eu[j] = true; else changed = true;\n            }\n        }\n        return eu;\n    };\n    \n    auto build_steiner = [&]() -> tuple<vector<bool>, vector<int>, ll> {\n        vector<int> nl; for (int i = 0; i < N; i++) if (needed[i]) nl.push_back(i);\n        int nn = nl.size();\n        vector<tuple<ll, int, int>> me;\n        for (int i = 0; i < nn; i++) for (int j = i+1; j < nn; j++)\n            if (sp_dist[nl[i]][nl[j]] < LLONG_MAX) me.push_back({sp_dist[nl[i]][nl[j]], i, j});\n        sort(me.begin(), me.end());\n        vector<int> par(nn); iota(par.begin(), par.end(), 0);\n        function<int(int)> find = [&](int x) { return par[x] == x ? x : par[x] = find(par[x]); };\n        vector<bool> eu(M, false);\n        for (auto& [d, i, j] : me) if (find(i) != find(j)) {\n            par[find(i)] = find(j);\n            int u = nl[i], v = nl[j], curr = u;\n            while (curr != v) { int ei = sp_next[curr][v]; if (ei == -1) break; eu[ei] = true; curr = (get<0>(edges[ei]) == curr) ? get<1>(edges[ei]) : get<0>(edges[ei]); }\n        }\n        vector<bool> k = compute_keep(eu);\n        bool ok = true; for (int i = 0; i < N; i++) if (needed[i] && !k[i]) { ok = false; break; }\n        if (!ok) { eu.assign(M, false);\n            for (int i = 0; i < N; i++) if (needed[i] && i != 0) { int v = i; while (v != 0) { int ei = sp_next[0][v]; if (ei == -1) break; eu[ei] = true; v = (get<0>(edges[ei]) == v) ? get<1>(edges[ei]) : get<0>(edges[ei]); } }\n        }\n        eu = remove_redundant(eu);\n        k = compute_keep(eu);\n        auto P = calc_powers(k);\n        return {eu, P, calc_cost(eu, P)};\n    };\n    \n    auto build_mst = [&]() -> tuple<vector<bool>, vector<int>, ll> {\n        vector<tuple<ll, int>> ae;\n        for (int j = 0; j < M; j++) ae.push_back({get<2>(edges[j]), j});\n        sort(ae.begin(), ae.end());\n        vector<int> par(N); iota(par.begin(), par.end(), 0);\n        function<int(int)> find = [&](int x) { return par[x] == x ? x : par[x] = find(par[x]); };\n        vector<bool> eu(M, false);\n        for (auto& [w, j] : ae) { int u = get<0>(edges[j]), v = get<1>(edges[j]); if (find(u) != find(v)) { par[find(u)] = find(v); eu[j] = true; } }\n        eu = prune_tree(eu);\n        auto k = compute_keep(eu);\n        auto P = calc_powers(k);\n        return {eu, P, calc_cost(eu, P)};\n    };\n    \n    auto build_spt = [&]() -> tuple<vector<bool>, vector<int>, ll> {\n        vector<bool> eu(M, false);\n        for (int i = 0; i < N; i++) if (needed[i] && i != 0) { int v = i; while (v != 0) { int ei = sp_next[0][v]; if (ei == -1) break; eu[ei] = true; v = (get<0>(edges[ei]) == v) ? get<1>(edges[ei]) : get<0>(edges[ei]); } }\n        eu = prune_tree(eu);\n        auto k = compute_keep(eu);\n        auto P = calc_powers(k);\n        return {eu, P, calc_cost(eu, P)};\n    };\n    \n    auto [eu1, P1, c1] = build_steiner();\n    auto [eu2, P2, c2] = build_mst();\n    auto [eu3, P3, c3] = build_spt();\n    \n    ll best_c = min({c1, c2, c3});\n    vector<bool> best_eu, best_keep;\n    vector<int> best_P;\n    if (best_c == c1) { best_eu = eu1; best_P = P1; }\n    else if (best_c == c2) { best_eu = eu2; best_P = P2; }\n    else { best_eu = eu3; best_P = P3; }\n    best_keep = compute_keep(best_eu);\n    \n    // Vertex removal optimization\n    for (int iter = 0; iter < N; iter++) {\n        bool improved = false;\n        for (int v = 1; v < N; v++) {\n            if (!best_keep[v]) continue;\n            vector<bool> new_eu = best_eu;\n            for (int j = 0; j < M; j++) {\n                if (!new_eu[j]) continue;\n                int u = get<0>(edges[j]), v2 = get<1>(edges[j]);\n                if (u == v || v2 == v) new_eu[j] = false;\n            }\n            auto new_keep = compute_keep(new_eu);\n            auto new_P = calc_powers(new_keep);\n            if (!check_coverage(new_keep, new_P)) continue;\n            ll new_cost = calc_cost(new_eu, new_P);\n            if (new_cost < best_c) {\n                best_eu = new_eu; best_keep = new_keep; best_P = new_P; best_c = new_cost;\n                improved = true; break;\n            }\n        }\n        if (!improved) break;\n    }\n    \n    // Vertex addition optimization\n    vector<ll> curr_min_arr(K);\n    for (int k = 0; k < K; k++) {\n        curr_min_arr[k] = LLONG_MAX;\n        for (int i = 0; i < N; i++) if (best_keep[i] && dist2[k][i] <= (ll)5000*5000) curr_min_arr[k] = min(curr_min_arr[k], dist2[k][i]);\n    }\n    \n    for (int iter = 0; iter < 10; iter++) {\n        bool improved = false;\n        for (int v = 0; v < N; v++) {\n            if (best_keep[v]) continue;\n            bool has_closer = false;\n            for (int k = 0; k < K && !has_closer; k++)\n                if (dist2[k][v] <= (ll)5000*5000 && dist2[k][v] < curr_min_arr[k]) has_closer = true;\n            if (!has_closer) continue;\n            ll min_d = LLONG_MAX; int target = -1;\n            for (int u = 0; u < N; u++) if (best_keep[u] && sp_dist[v][u] < min_d) { min_d = sp_dist[v][u]; target = u; }\n            if (target == -1) continue;\n            vector<bool> new_eu = best_eu;\n            int curr = v;\n            while (curr != target) { int ei = sp_next[curr][target]; if (ei == -1) break; new_eu[ei] = true; curr = (get<0>(edges[ei]) == curr) ? get<1>(edges[ei]) : get<0>(edges[ei]); }\n            auto new_keep = compute_keep(new_eu);\n            auto new_P = calc_powers(new_keep);\n            ll new_cost = calc_cost(new_eu, new_P);\n            if (new_cost < best_c) {\n                best_eu = new_eu; best_keep = new_keep; best_P = new_P; best_c = new_cost;\n                for (int k = 0; k < K; k++) if (dist2[k][v] <= (ll)5000*5000) curr_min_arr[k] = min(curr_min_arr[k], dist2[k][v]);\n                improved = true; break;\n            }\n        }\n        if (!improved) break;\n    }\n    \n    for (int i = 0; i < N; i++) cout << best_P[i] << \" \\n\"[i == N - 1];\n    for (int j = 0; j < M; j++) cout << best_eu[j] << \" \\n\"[j == M - 1];\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N = 30;\nint grid[30][30];\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \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    vector<tuple<int,int,int,int>> ops;\n    ops.reserve(10000);\n    \n    for (int pass = 0; pass < 50 && ops.size() < 10000; pass++) {\n        bool changed = false;\n        for (int x = N - 2; x >= 0 && ops.size() < 10000; x--) {\n            vector<pair<int,int>> to_process;\n            for (int y = 0; y <= x; y++) {\n                int v = grid[x][y];\n                int c1 = grid[x+1][y], c2 = grid[x+1][y+1];\n                if (v >= c1 || v >= c2) {\n                    int s1 = max(v - c1, 0);\n                    int s2 = max(v - c2, 0);\n                    int severity = (s1 + s2 + s1 * s2) * (100 + v) / 100;\n                    to_process.push_back({-severity, y});\n                }\n            }\n            sort(to_process.begin(), to_process.end());\n            for (auto& [_, y] : to_process) {\n                if (ops.size() >= 10000) break;\n                int v = grid[x][y];\n                if (v < grid[x+1][y] && v < grid[x+1][y+1]) continue;\n                \n                int cx = x, cy = y;\n                while (cx < N - 1 && ops.size() < 10000) {\n                    v = grid[cx][cy];\n                    int c1 = grid[cx+1][cy];\n                    int c2 = grid[cx+1][cy+1];\n                    if (v < c1 && v < c2) break;\n                    \n                    if (c1 <= c2) {\n                        swap(grid[cx][cy], grid[cx+1][cy]);\n                        ops.push_back({cx, cy, cx+1, cy});\n                        cx++;\n                    } else {\n                        swap(grid[cx][cy], grid[cx+1][cy+1]);\n                        ops.push_back({cx, cy, cx+1, cy+1});\n                        cx++;\n                        cy++;\n                    }\n                    changed = true;\n                }\n            }\n        }\n        if (!changed) break;\n    }\n    \n    cout << ops.size() << \"\\n\";\n    for (auto& [x1, y1, x2, y2] : ops) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << \"\\n\";\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D, N;\nint grid[9][9];\nint container_num[9][9];\nint bfs_dist[9][9];\nint di[] = {0, 0, 1, -1}, dj[] = {1, -1, 0, 0};\nint entrance_i = 0, entrance_j;\nvector<pair<int,int>> all_cells;\n\nvoid compute_bfs_dist() {\n    queue<pair<int,int>> q;\n    memset(bfs_dist, -1, sizeof(bfs_dist));\n    bfs_dist[entrance_i][entrance_j] = 0;\n    q.push({entrance_i, entrance_j});\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int ni = i + di[d], nj = j + dj[d];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && bfs_dist[ni][nj] == -1 && grid[ni][nj] != 1) {\n                bfs_dist[ni][nj] = bfs_dist[i][j] + 1;\n                q.push({ni, nj});\n            }\n        }\n    }\n    for (int i = 0; i < D; i++)\n        for (int j = 0; j < D; j++)\n            if ((i != entrance_i || j != entrance_j) && grid[i][j] != 1)\n                all_cells.push_back({i, j});\n    sort(all_cells.begin(), all_cells.end(), [](auto& a, auto& b) {\n        return tie(bfs_dist[a.first][a.second], a.first, a.second) < tie(bfs_dist[b.first][b.second], b.first, b.second);\n    });\n}\n\nvoid bfs_empty(int visited[9][9]) {\n    queue<pair<int,int>> q;\n    visited[entrance_i][entrance_j] = 1;\n    q.push({entrance_i, entrance_j});\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int ni = i + di[d], nj = j + dj[d];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && !visited[ni][nj] && grid[ni][nj] == 0) {\n                visited[ni][nj] = 1;\n                q.push({ni, nj});\n            }\n        }\n    }\n}\n\nvector<pair<int,int>> get_reachable_empty() {\n    int visited[9][9] = {};\n    bfs_empty(visited);\n    vector<pair<int,int>> cells;\n    for (int i = 0; i < D; i++)\n        for (int j = 0; j < D; j++)\n            if (visited[i][j] && !(i == entrance_i && j == entrance_j))\n                cells.push_back({i, j});\n    return cells;\n}\n\nvector<pair<int,int>> get_reachable_containers() {\n    int visited[9][9] = {};\n    bfs_empty(visited);\n    vector<pair<int,int>> cells;\n    for (int i = 0; i < D; i++)\n        for (int j = 0; j < D; j++)\n            if (grid[i][j] == 2)\n                for (int d = 0; d < 4; d++) {\n                    int ni = i + di[d], nj = j + dj[d];\n                    if (ni >= 0 && ni < D && nj >= 0 && nj < D && visited[ni][nj]) {\n                        cells.push_back({i, j});\n                        break;\n                    }\n                }\n    return cells;\n}\n\nbool is_safe(int pi, int pj, int orig_empty_count) {\n    grid[pi][pj] = 2;\n    int visited[9][9] = {};\n    bfs_empty(visited);\n    grid[pi][pj] = 0;\n    int new_empty = 0;\n    for (int i = 0; i < D; i++)\n        for (int j = 0; j < D; j++)\n            if (visited[i][j] && !(i == entrance_i && j == entrance_j))\n                new_empty++;\n    return new_empty == orig_empty_count - 1;\n}\n\nint count_empty_neighbors(int i, int j) {\n    int cnt = 0;\n    for (int d = 0; d < 4; d++) {\n        int ni = i + di[d], nj = j + dj[d];\n        if (ni >= 0 && ni < D && nj >= 0 && nj < D && grid[ni][nj] == 0 && !(ni == entrance_i && nj == entrance_j))\n            cnt++;\n    }\n    return cnt;\n}\n\npair<int,int> find_placement(int t) {\n    auto empty_cells = get_reachable_empty();\n    int orig_empty_count = empty_cells.size();\n    int ideal_dist = bfs_dist[all_cells[t].first][all_cells[t].second];\n    \n    vector<pair<int,int>> safe_cells;\n    map<pair<int,int>, int> neighbor_count;\n    for (auto& cell : empty_cells) {\n        if (is_safe(cell.first, cell.second, orig_empty_count)) {\n            safe_cells.push_back(cell);\n            neighbor_count[cell] = count_empty_neighbors(cell.first, cell.second);\n        }\n    }\n    \n    if (safe_cells.empty()) return empty_cells[0];\n    \n    auto cmp = [&](const auto& a, const auto& b) {\n        int da = abs(bfs_dist[a.first][a.second] - ideal_dist);\n        int db = abs(bfs_dist[b.first][b.second] - ideal_dist);\n        if (da != db) return da < db;\n        int ea = neighbor_count[a];\n        int eb = neighbor_count[b];\n        if (ea != eb) return ea < eb;\n        return a < b;\n    };\n    \n    sort(safe_cells.begin(), safe_cells.end(), cmp);\n    return safe_cells[0];\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> D >> N;\n    entrance_j = (D - 1) / 2;\n    memset(grid, 0, sizeof(grid));\n    memset(container_num, -1, sizeof(container_num));\n    for (int i = 0; i < N; i++) { int ri, rj; cin >> ri >> rj; grid[ri][rj] = 1; }\n    int total = D * D - 1 - N;\n    compute_bfs_dist();\n    for (int d = 0; d < total; d++) {\n        int t; cin >> t;\n        auto [pi, pj] = find_placement(t);\n        grid[pi][pj] = 2;\n        container_num[pi][pj] = t;\n        cout << pi << \" \" << pj << \"\\n\" << flush;\n    }\n    for (int d = 0; d < total; d++) {\n        auto containers = get_reachable_containers();\n        int best_num = INT_MAX;\n        pair<int,int> best_pos = containers[0];\n        for (auto& [i, j] : containers)\n            if (container_num[i][j] < best_num) { best_num = container_num[i][j]; best_pos = {i, j}; }\n        grid[best_pos.first][best_pos.second] = 0;\n        cout << best_pos.first << \" \" << best_pos.second << \"\\n\" << flush;\n    }\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\nusing namespace std::chrono;\n\nint n, m;\nint grid[50][50], original_grid[50][50], best_grid[50][50];\nset<int> adj_set[101];\nset<pair<int,int>> original_adj;\nvector<pair<int,int>> color_pos[101];\nint adj_cnt[101][101], color_cnt[101];\nint dr[] = {0, 0, 1, -1}, dc[] = {1, -1, 0, 0};\nint vis_gen[50][50], cur_gen = 0;\n\nbool is_connected_except(int color, set<pair<int,int>>& excl) {\n    int cnt = 0, sr = -1, sc = -1;\n    for (auto& [i, j] : color_pos[color]) {\n        if (grid[i][j] != color || excl.count({i, j})) continue;\n        if (sr == -1) { sr = i; sc = j; } cnt++;\n    }\n    if (cnt <= 1) return cnt >= 1;\n    cur_gen++;\n    queue<pair<int,int>> q; q.push({sr,sc}); vis_gen[sr][sc]=cur_gen; int vc=1;\n    while (!q.empty()) {\n        auto [r,c] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nr=r+dr[d],nc=c+dc[d];\n            if (nr<0||nr>=n||nc<0||nc>=n||vis_gen[nr][nc]==cur_gen||excl.count({nr,nc})) continue;\n            if (grid[nr][nc]==color) { vis_gen[nr][nc]=cur_gen; vc++; q.push({nr,nc}); }\n        }\n    }\n    return vc == cnt;\n}\n\nbool check_batch(int color, set<pair<int,int>>& batch) {\n    if (color_cnt[color] <= (int)batch.size()) return false;\n    if (!is_connected_except(color, batch)) return false;\n    for (int nb = 1; nb <= m; nb++) {\n        if (!adj_set[color].count(nb)) continue;\n        if (!adj_set[0].count(nb)) return false;\n        int lost = 0;\n        for (auto& [r,c] : batch) for (int d = 0; d < 4; d++) { int nr=r+dr[d],nc=c+dc[d]; if(nr>=0&&nr<n&&nc>=0&&nc<n&&grid[nr][nc]==nb) lost++; }\n        if (adj_cnt[color][nb] - lost <= 0) return false;\n    }\n    int bnd=0, sg=0, zl=0;\n    for (auto& [r,c] : batch) for (int d = 0; d < 4; d++) {\n        int nr=r+dr[d],nc=c+dc[d];\n        if (nr<0||nr>=n||nc<0||nc>=n) bnd++;\n        else if (grid[nr][nc]==color) sg++;\n        else if (grid[nr][nc]==0) zl++;\n    }\n    return adj_cnt[color][0] - bnd + sg - zl > 0;\n}\n\nvoid remove_batch(int color, set<pair<int,int>>& batch) {\n    for (auto& [r,c] : batch) {\n        for (int d = 0; d < 4; d++) {\n            int nr=r+dr[d],nc=c+dc[d];\n            if (nr<0||nr>=n||nc<0||nc>=n) adj_cnt[color][0]--;\n            else { int nb=grid[nr][nc]; if(nb==color) adj_cnt[color][0]++; else if(nb==0) adj_cnt[color][0]--; else {adj_cnt[color][nb]--;adj_cnt[nb][color]--;adj_cnt[nb][0]++;} }\n        }\n        grid[r][c] = 0; color_cnt[color]--;\n    }\n}\n\nbool is_connected(int color, int er, int ec) {\n    int cnt = color_cnt[color] - 1; if (cnt <= 1) return true;\n    cur_gen++; int sr=-1,sc=-1;\n    for (auto& [i,j] : color_pos[color]) { if(grid[i][j]!=color||(i==er&&j==ec)) continue; sr=i;sc=j; break; }\n    if (sr==-1) return true;\n    queue<pair<int,int>> q; q.push({sr,sc}); vis_gen[sr][sc]=cur_gen; int vc=1;\n    while (!q.empty()) {\n        auto [r,c] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) { int nr=r+dr[d],nc=c+dc[d]; if(nr<0||nr>=n||nc<0||nc>=n||vis_gen[nr][nc]==cur_gen||(nr==er&&nc==ec)) continue; if(grid[nr][nc]==color){vis_gen[nr][nc]=cur_gen;vc++;q.push({nr,nc});} }\n    }\n    return vc == cnt;\n}\n\nbool can_remove(int r, int c) {\n    int color = grid[r][c]; if (color==0||color_cnt[color]<=1) return false;\n    int same=0,zh=0,diff[101]={};\n    for (int d = 0; d < 4; d++) { int nr=r+dr[d],nc=c+dc[d]; if(nr<0||nr>=n||nc<0||nc>=n) zh++; else if(grid[nr][nc]==color) same++; else if(grid[nr][nc]==0) zh++; else diff[grid[nr][nc]]++; }\n    if (same==0||!adj_set[0].count(color)) return false;\n    if (r!=0&&r!=n-1&&c!=0&&c!=n-1) { bool conn=false; for(int d=0;d<4;d++){int nr=r+dr[d],nc=c+dc[d];if(nr>=0&&nr<n&&nc>=0&&nc<n&&grid[nr][nc]==0){conn=true;break;}} if(!conn) return false; }\n    if (adj_cnt[color][0]+same-zh<=0) return false;\n    if (same<4&&!is_connected(color,r,c)) return false;\n    for (int nb=1;nb<=m;nb++) { if(!diff[nb]) continue; if(!adj_set[0].count(nb)||adj_cnt[color][nb]-diff[nb]<=0) return false; }\n    return true;\n}\n\nvoid remove_tile(int r, int c) {\n    int color = grid[r][c];\n    for (int d = 0; d < 4; d++) { int nr=r+dr[d],nc=c+dc[d]; if(nr<0||nr>=n||nc<0||nc>=n) adj_cnt[color][0]--; else {int nb=grid[nr][nc];if(nb==color)adj_cnt[color][0]++;else if(nb==0)adj_cnt[color][0]--;else{adj_cnt[color][nb]--;adj_cnt[nb][color]--;adj_cnt[nb][0]++;}} }\n    grid[r][c]=0; color_cnt[color]--;\n}\n\nvoid reset_state() {\n    memcpy(grid,original_grid,sizeof(grid)); memset(adj_cnt,0,sizeof(adj_cnt)); memset(color_cnt,0,sizeof(color_cnt));\n    for(int i=0;i<n;i++) for(int j=0;j<n;j++) {int c=grid[i][j];color_cnt[c]++;for(int d=0;d<4;d++){int nr=i+dr[d],nc=j+dc[d];int nb=(nr<0||nr>=n||nc<0||nc>=n)?0:grid[nr][nc];if(nb!=c)adj_cnt[c][nb]++;}}\n}\n\nvoid run_full(mt19937& rng) {\n    bool changed = true;\n    while (changed) { changed=false; for(int c=1;c<=m;c++){if(!adj_set[0].count(c))continue;vector<tuple<int,int,int,int>> tiles;for(auto&[i,j]:color_pos[c]){if(grid[i][j]!=c)continue;int s=0,z=0;for(int d=0;d<4;d++){int nr=i+dr[d],nc=j+dc[d];if(nr<0||nr>=n||nc<0||nc>=n)z++;else if(grid[nr][nc]==c)s++;else if(grid[nr][nc]==0)z++;}if(s>0)tiles.push_back({s,-z,i,j});}sort(tiles.begin(),tiles.end());for(auto&[a,b,r,cc]:tiles){if(grid[r][cc]!=c)continue;if(can_remove(r,cc)){remove_tile(r,cc);changed=true;}}} }\n    for (int color=1;color<=m;color++) {\n        if(!adj_set[0].count(color)||color_cnt[color]<=1) continue;\n        vector<pair<int,int>> cands;\n        for(auto&[i,j]:color_pos[color]){if(grid[i][j]!=color)continue;int same=0;bool cn=(i==0||i==n-1||j==0||j==n-1);for(int d=0;d<4;d++){int nr=i+dr[d],nc=j+dc[d];if(nr<0||nr>=n||nc<0||nc>=n)continue;if(grid[nr][nc]==color)same++;else if(grid[nr][nc]==0)cn=true;}if(same>0&&cn)cands.push_back({i,j});}\n        for(int trial=0;trial<20;trial++){shuffle(cands.begin(),cands.end(),rng);set<pair<int,int>> batch;for(auto&[i,j]:cands){batch.insert({i,j});if(!check_batch(color,batch))batch.erase({i,j});}if(!batch.empty()){remove_batch(color,batch);cands.erase(remove_if(cands.begin(),cands.end(),[&](auto&p){return batch.count(p);}),cands.end());}else break;}\n    }\n}\n\nbool verify() {\n    set<pair<int,int>> out;\n    for(int i=0;i<n;i++) for(int j=0;j<n;j++){int c=grid[i][j];for(int d=0;d<4;d++){int nr=i+dr[d],nc=j+dc[d];int nb=(nr<0||nr>=n||nc<0||nc>=n)?0:grid[nr][nc];if(nb!=c)out.insert({min(c,nb),max(c,nb)});}}\n    if(original_adj!=out) return false;\n    for(int c=1;c<=m;c++){cur_gen++;int cnt=0,sr=-1,sc=-1;for(auto&[i,j]:color_pos[c]){if(grid[i][j]!=c)continue;if(sr<0){sr=i;sc=j;}cnt++;}if(!cnt)return false;if(cnt==1)continue;queue<pair<int,int>>q;q.push({sr,sc});vis_gen[sr][sc]=cur_gen;int vc=1;while(!q.empty()){auto[r,cc]=q.front();q.pop();for(int d=0;d<4;d++){int nr=r+dr[d],nc=cc+dc[d];if(nr<0||nr>=n||nc<0||nc>=n||vis_gen[nr][nc]==cur_gen)continue;if(grid[nr][nc]==c){vis_gen[nr][nc]=cur_gen;vc++;q.push({nr,nc});}}}if(vc!=cnt)return false;}\n    cur_gen++;queue<pair<int,int>>q;int zcnt=0;for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(grid[i][j]==0){zcnt++;if(i==0||i==n-1||j==0||j==n-1){q.push({i,j});vis_gen[i][j]=cur_gen;}}\n    while(!q.empty()){auto[r,c]=q.front();q.pop();zcnt--;for(int d=0;d<4;d++){int nr=r+dr[d],nc=c+dc[d];if(nr<0||nr>=n||nc<0||nc>=n||vis_gen[nr][nc]==cur_gen||grid[nr][nc]!=0)continue;vis_gen[nr][nc]=cur_gen;q.push({nr,nc});}}\n    return zcnt==0;\n}\n\nint count_zeros(){int cnt=0;for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(grid[i][j]==0) cnt++;return cnt;}\n\nint main() {\n    auto start=high_resolution_clock::now();ios_base::sync_with_stdio(false);cin.tie(NULL);cin>>n>>m;\n    for(int i=0;i<n;i++) for(int j=0;j<n;j++){cin>>grid[i][j];original_grid[i][j]=grid[i][j];color_pos[grid[i][j]].push_back({i,j});}\n    for(int i=0;i<n;i++) for(int j=0;j<n;j++){int c=grid[i][j];for(int d=0;d<4;d++){int nr=i+dr[d],nc=j+dc[d];int nb=(nr<0||nr>=n||nc<0||nc>=n)?0:grid[nr][nc];if(nb!=c){adj_set[c].insert(nb);adj_set[nb].insert(c);original_adj.insert({min(c,nb),max(c,nb)});}}}\n    int best=n*n+1;memcpy(best_grid,original_grid,sizeof(best_grid));\n    auto try_s=[&](auto fn){reset_state();fn();if(verify()){int s=count_zeros();if(s<best){best=s;memcpy(best_grid,grid,sizeof(grid));}}};\n    mt19937 rng(42);try_s([&](){run_full(rng);});\n    while(duration_cast<milliseconds>(high_resolution_clock::now()-start).count()<1700){try_s([&](){run_full(rng);});}\n    for(int i=0;i<n;i++){for(int j=0;j<n;j++){cout<<best_grid[i][j];if(j<n-1)cout<<\" \";}cout<<\"\\n\";}\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <numeric>\n#include <set>\n\nusing namespace std;\n\nint N, D, Q;\n\nchar query(int x, int y) {\n    cout << \"1 1 \" << x << \" \" << y << \"\\n\" << flush;\n    char res;\n    cin >> res;\n    return res;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    if (!(cin >> N >> D >> Q)) return 0;\n    \n    int B = Q / N;\n    \n    vector<vector<int>> adj(N);\n    vector<int> sorted_items;\n    vector<int> unsorted_items;\n    unsorted_items.reserve(N);\n    sorted_items.reserve(N);\n    for (int i = 0; i < N; ++i) {\n        unsorted_items.push_back(i);\n    }\n    \n    int q_left = Q;\n    set<pair<int,int>> queried;\n    \n    // Phase 1: Strict Fair Budget Insertion + Sparse DAG\n    while (!unsorted_items.empty()) {\n        int x = unsorted_items.back();\n        unsorted_items.pop_back();\n        \n        if (!sorted_items.empty()) {\n            int lo = 0, hi = sorted_items.size();\n            int steps = 0;\n            while (steps < B && lo < hi) {\n                int mid = (lo + hi) / 2;\n                int y = sorted_items[mid];\n                q_left--;\n                steps++;\n                char res = query(x, y);\n                if (res == '>') {\n                    adj[y].push_back(x);\n                    lo = mid + 1;\n                } else if (res == '<') {\n                    adj[x].push_back(y);\n                    hi = mid;\n                } else {\n                    queried.insert({min(x, y), max(x, y)});\n                    break; \n                }\n            }\n            sorted_items.insert(sorted_items.begin() + lo, x);\n        } else {\n            if (!unsorted_items.empty()) {\n                int y = unsorted_items.back();\n                unsorted_items.pop_back();\n                q_left--;\n                char res = query(x, y);\n                if (res == '>') {\n                    adj[y].push_back(x);\n                    sorted_items.push_back(y);\n                    sorted_items.push_back(x);\n                } else if (res == '<') {\n                    adj[x].push_back(y);\n                    sorted_items.push_back(x);\n                    sorted_items.push_back(y);\n                } else {\n                    queried.insert({min(x, y), max(x, y)});\n                    sorted_items.push_back(x);\n                    sorted_items.push_back(y);\n                }\n            } else {\n                sorted_items.push_back(x);\n            }\n        }\n    }\n    \n    // Compute initial dp (Phase 1 DAG)\n    vector<int> in_degree(N, 0);\n    for (int i = 0; i < N; ++i) {\n        for (int j : adj[i]) {\n            in_degree[j]++;\n        }\n    }\n    \n    queue<int> q;\n    for (int i = 0; i < N; ++i) {\n        if (in_degree[i] == 0) q.push(i);\n    }\n    \n    vector<int> dp(N, 0);\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : adj[u]) {\n            if (dp[v] < dp[u] + 1) {\n                dp[v] = dp[u] + 1;\n            }\n            in_degree[v]--;\n            if (in_degree[v] == 0) {\n                q.push(v);\n            }\n        }\n    }\n    \n    // Sort by dp DESCENDING so Phase 2 naturally prioritizes top items\n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n    sort(items.begin(), items.end(), [&](int a, int b) {\n        if (dp[a] != dp[b]) return dp[a] > dp[b];\n        return a > b;\n    });\n    \n    // Phase 2: Targeted Bubble Sort with ZERO redundant queries\n    for (int i = 0; i < N - 1 && q_left > 0; ++i) {\n        int a = items[i];\n        int b = items[i + 1];\n        if (dp[a] == dp[b]) {\n            if (queried.count({a, b}) || queried.count({b, a})) {\n                continue; \n            }\n            q_left--;\n            char res = query(a, b);\n            queried.insert({a, b});\n            if (res == '>') {\n                adj[b].push_back(a);\n            } else if (res == '<') {\n                adj[a].push_back(b);\n                swap(items[i], items[i + 1]);\n                if (i > 0) i -= 2;\n            }\n        }\n    }\n    \n    // Fulfill any strictly remaining quota with dummy queries\n    while (q_left > 0) {\n        query(0, 1);\n        q_left--;\n    }\n    \n    // Phase 3: Re-compute dp perfectly cascading Phase 2 updates\n    in_degree.assign(N, 0);\n    for (int i = 0; i < N; ++i) {\n        for (int j : adj[i]) {\n            in_degree[j]++;\n        }\n    }\n    \n    queue<int> q2;\n    for (int i = 0; i < N; ++i) {\n        if (in_degree[i] == 0) q2.push(i);\n    }\n    \n    dp.assign(N, 0);\n    while (!q2.empty()) {\n        int u = q2.front(); q2.pop();\n        for (int v : adj[u]) {\n            if (dp[v] < dp[u] + 1) {\n                dp[v] = dp[u] + 1;\n            }\n            in_degree[v]--;\n            if (in_degree[v] == 0) {\n                q2.push(v);\n            }\n        }\n    }\n    \n    // Re-sort ASCENDING for expected weight mapping\n    sort(items.begin(), items.end(), [&](int a, int b) {\n        if (dp[a] != dp[b]) return dp[a] < dp[b];\n        return a < b;\n    });\n    \n    // Map expected weights of exponential distribution order statistics\n    double W_max = 100000.0 * N / D;\n    vector<double> expected_w(N);\n    double sum = 0;\n    for (int i = 0; i < N; ++i) {\n        sum += 100000.0 / (N - i);\n        expected_w[i] = min(sum, W_max);\n    }\n    \n    // Phase 4: Adaptive Plateau Average\n    for (int i = 0; i < N; ) {\n        int j = i;\n        double group_sum = 0;\n        while (j < N && dp[items[j]] == dp[items[i]]) {\n            group_sum += expected_w[j];\n            j++;\n        }\n        int K = j - i;\n        // ONLY average if block is larger than D (neutralizes false info in minimum swamp)\n        if (K > D) {\n            double group_avg = group_sum / K;\n            for (int k = i; k < j; ++k) {\n                expected_w[k] = group_avg;\n            }\n        }\n        i = j;\n    }\n    \n    // Greedy partitioning based on expected weights\n    vector<double> set_sums(D, 0);\n    vector<int> partition(N);\n    double total_sum = accumulate(expected_w.begin(), expected_w.end(), 0.0);\n    double target_sum = total_sum / D;\n    \n    // Process from largest expected weight to smallest\n    for (int i = N - 1; i >= 0; --i) {\n        int item = items[i];\n        double w = expected_w[i];\n        \n        int best_set = -1;\n        double max_deficit = 0;\n        for (int j = 0; j < D; ++j) {\n            double deficit = target_sum - set_sums[j];\n            if (deficit > max_deficit) {\n                max_deficit = deficit;\n                best_set = j;\n            }\n        }\n        \n        // Fallback if all sets exceed the target sum\n        if (best_set == -1) {\n            best_set = 0;\n            for (int j = 1; j < D; ++j) {\n                if (set_sums[j] < set_sums[best_set]) {\n                    best_set = j;\n                }\n            }\n        }\n        \n        set_sums[best_set] += w;\n        partition[item] = best_set;\n    }\n    \n    // Output the final division mapping\n    for (int i = 0; i < N; ++i) {\n        cout << partition[i] << (i == N - 1 ? \"\" : \" \");\n    }\n    cout << \"\\n\" << flush;\n    \n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\nint solve(vector<vector<int>> stacks, int n, int m, int emptyScore, vector<pair<int, int>>& ops) {\n    vector<int> pos(n + 1), idx(n + 1);\n    \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;\n            idx[stacks[i][j]] = j;\n        }\n    }\n    \n    vector<bool> isClean(m, true);\n    for (int i = 0; i < m; i++) {\n        for (int j = 0; j < (int)stacks[i].size() - 1; j++) {\n            if (stacks[i][j] < stacks[i][j + 1]) { isClean[i] = false; break; }\n        }\n    }\n    \n    auto updateClean = [&](int s) {\n        isClean[s] = true;\n        for (int j = 0; j < (int)stacks[s].size() - 1; j++) {\n            if (stacks[s][j] < stacks[s][j + 1]) { isClean[s] = false; break; }\n        }\n    };\n    \n    ops.clear();\n    int energy = 0;\n    int nextBox = 1;\n    \n    while (nextBox <= n) {\n        int si = pos[nextBox], pi = idx[nextBox];\n        \n        if (pi == (int)stacks[si].size() - 1) {\n            ops.push_back({nextBox, 0});\n            stacks[si].pop_back();\n            updateClean(si);\n            nextBox++;\n        } else {\n            vector<int> seq(stacks[si].begin() + pi + 1, stacks[si].end());\n            \n            vector<int> splitAfter;\n            for (int i = 0; i < (int)seq.size() - 1; i++) {\n                if (seq[i] < seq[i + 1]) splitAfter.push_back(i);\n            }\n            \n            vector<vector<int>> pieces;\n            int start = 0;\n            for (int sp : splitAfter) {\n                pieces.push_back(vector<int>(seq.begin() + start, seq.begin() + sp + 1));\n                start = sp + 1;\n            }\n            pieces.push_back(vector<int>(seq.begin() + start, seq.end()));\n            reverse(pieces.begin(), pieces.end());\n            \n            for (auto& piece : pieces) {\n                int moveFrom = piece[0];\n                int origStack = pos[moveFrom];\n                \n                int bestDest = -1, bestScore = -1e9;\n                for (int i = 0; i < m; i++) {\n                    if (i == origStack) continue;\n                    int score;\n                    if (stacks[i].empty()) {\n                        score = emptyScore;\n                    } else if (isClean[i] && stacks[i].back() >= moveFrom) {\n                        score = 601 - stacks[i].back();\n                    } else if (!isClean[i] && stacks[i].back() >= moveFrom) {\n                        score = 201 - stacks[i].back();\n                    } else {\n                        score = -999 + stacks[i].back();\n                    }\n                    if (score > bestScore || (score == bestScore && bestDest != -1 && stacks[i].size() < stacks[bestDest].size())) {\n                        bestScore = score; bestDest = i;\n                    }\n                }\n                \n                bool wasEmpty = stacks[bestDest].empty();\n                bool wasCleanDest = isClean[bestDest];\n                int oldBack = wasEmpty ? -1 : stacks[bestDest].back();\n                bool compatible = wasEmpty || (oldBack >= moveFrom);\n                \n                ops.push_back({moveFrom, bestDest + 1});\n                energy += piece.size() + 1;\n                \n                int origIdx = idx[moveFrom];\n                for (int j = origIdx; j < (int)stacks[origStack].size(); j++) {\n                    int v = stacks[origStack][j];\n                    stacks[bestDest].push_back(v);\n                    pos[v] = bestDest;\n                    idx[v] = stacks[bestDest].size() - 1;\n                }\n                stacks[origStack].resize(origIdx);\n                \n                isClean[bestDest] = wasEmpty ? true : (wasCleanDest && compatible);\n                updateClean(origStack);\n            }\n        }\n    }\n    \n    return energy;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> initialStacks(m);\n    for (int i = 0; i < m; i++) {\n        initialStacks[i].resize(n / m);\n        for (int j = 0; j < n / m; j++) {\n            cin >> initialStacks[i][j];\n        }\n    }\n    \n    vector<pair<int, int>> bestOps;\n    int bestEnergy = 1e9;\n    \n    for (int emptyScore : {300, 350, 400, 450, 500}) {\n        vector<pair<int, int>> ops;\n        int energy = solve(initialStacks, n, m, emptyScore, ops);\n        if (energy < bestEnergy) {\n            bestEnergy = energy;\n            bestOps = move(ops);\n        }\n    }\n    \n    for (auto& op : bestOps) cout << op.first << \" \" << op.second << \"\\n\";\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\nint di[] = {0, 1, 0, -1};\nint dj[] = {1, 0, -1, 0};\nchar dc[] = \"RDLU\";\nmt19937 rng(42);\nvector<vector<int>> dist_to_origin;\n\nbool can_move(int i, int j, int dir) {\n    int ni = i + di[dir], nj = j + dj[dir];\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    if (dir == 0) return v[i][j] == '0';\n    if (dir == 1) return h[i][j] == '0';\n    if (dir == 2) return v[i][nj] == '0';\n    return h[ni][j] == '0';\n}\n\npair<string, int> find_path(int si, int sj, int ti, int tj) {\n    if (si == ti && sj == tj) return {\"\", 0};\n    vector<vector<pair<int,int>>> par(N, vector<pair<int,int>>(N, {-1, -1}));\n    vector<vector<int>> pd(N, vector<int>(N, -1));\n    vector<vector<int>> dist(N, vector<int>(N, -1));\n    queue<pair<int,int>> q;\n    q.push({si, sj}); par[si][sj] = {si, sj}; dist[si][sj] = 0;\n    while (!q.empty()) {\n        auto [ci, cj] = q.front(); q.pop();\n        if (ci == ti && cj == tj) break;\n        for (int dir = 0; dir < 4; dir++)\n            if (can_move(ci, cj, dir)) {\n                int ni = ci + di[dir], nj = cj + dj[dir];\n                if (dist[ni][nj] == -1) { par[ni][nj] = {ci, cj}; pd[ni][nj] = dir; dist[ni][nj] = dist[ci][cj] + 1; q.push({ni, nj}); }\n            }\n    }\n    if (dist[ti][tj] == -1) return {\"\", INT_MAX};\n    string path; int ci = ti, cj = tj;\n    while (ci != si || cj != sj) { path += dc[pd[ci][cj]]; auto [pi, pj] = par[ci][cj]; ci = pi; cj = pj; }\n    reverse(path.begin(), path.end());\n    return {path, dist[ti][tj]};\n}\n\npair<string, int> greedy_bfs() {\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    string route; int ci = 0, cj = 0; visited[0][0] = true;\n    while (true) {\n        int best_dist = INT_MAX, bi = -1, bj = -1;\n        vector<vector<int>> dist(N, vector<int>(N, -1));\n        queue<pair<int,int>> q; q.push({ci, cj}); dist[ci][cj] = 0;\n        while (!q.empty()) {\n            auto [qi, qj] = q.front(); q.pop();\n            if (!visited[qi][qj] && dist[qi][qj] < best_dist) { best_dist = dist[qi][qj]; bi = qi; bj = qj; }\n            if (dist[qi][qj] >= best_dist) continue;\n            for (int dir = 0; dir < 4; dir++)\n                if (can_move(qi, qj, dir)) { int ni = qi+di[dir], nj = qj+dj[dir]; if (dist[ni][nj] == -1) { dist[ni][nj] = dist[qi][qj]+1; q.push({ni, nj}); } }\n        }\n        if (bi == -1) break;\n        auto [path, d_val] = find_path(ci, cj, bi, bj);\n        route += path; int ti = ci, tj = cj;\n        for (char c : path) { int dir = (c=='R')?0:(c=='D')?1:(c=='L')?2:3; ti += di[dir]; tj += dj[dir]; visited[ti][tj] = true; }\n        ci = bi; cj = bj;\n    }\n    auto [ret, rd] = find_path(ci, cj, 0, 0); route += ret;\n    return {route, (int)route.size()};\n}\n\nint count_unvisited(int i, int j, vector<vector<bool>>& visited) {\n    int cnt = 0;\n    for (int dir = 0; dir < 4; dir++) if (can_move(i, j, dir) && !visited[i+di[dir]][j+dj[dir]]) cnt++;\n    return cnt;\n}\n\nvoid dfs(int i, int j, string& route, vector<vector<bool>>& visited) {\n    visited[i][j] = true;\n    for (int dir = 0; dir < 4; dir++)\n        if (can_move(i, j, dir)) { int ni = i+di[dir], nj = j+dj[dir]; if (!visited[ni][nj]) { route += dc[dir]; dfs(ni, nj, route, visited); route += dc[(dir+2)%4]; } }\n}\n\npair<string, int> try_warnsdorff(function<int(int,int)> tie_func) {\n    string route; vector<vector<bool>> vis(N, vector<bool>(N, false));\n    int ci = 0, cj = 0; vis[0][0] = true;\n    for (int step = 0; step < N*N-1; step++) {\n        vector<tuple<int,int,int>> neighbors;\n        for (int dir = 0; dir < 4; dir++)\n            if (can_move(ci, cj, dir)) { int ni = ci+di[dir], nj = cj+dj[dir]; if (!vis[ni][nj]) { int cnt = count_unvisited(ni, nj, vis); neighbors.push_back({cnt, tie_func(ni, nj), dir}); } }\n        if (neighbors.empty()) return {\"\", INT_MAX};\n        sort(neighbors.begin(), neighbors.end());\n        ci += di[get<2>(neighbors[0])]; cj += dj[get<2>(neighbors[0])]; vis[ci][cj] = true; route += dc[get<2>(neighbors[0])];\n    }\n    auto [ret, rd] = find_path(ci, cj, 0, 0); route += ret;\n    return {route, (int)route.size()};\n}\n\npair<string, int> try_warnsdorff_dynamic(double threshold) {\n    string route; vector<vector<bool>> vis(N, vector<bool>(N, false));\n    int ci = 0, cj = 0; vis[0][0] = true; int vc = 1;\n    for (int step = 0; step < N*N-1; step++) {\n        vector<tuple<int,int,int>> neighbors; double progress = (double)vc/(N*N);\n        for (int dir = 0; dir < 4; dir++)\n            if (can_move(ci, cj, dir)) { int ni = ci+di[dir], nj = cj+dj[dir]; if (!vis[ni][nj]) { int cnt = count_unvisited(ni, nj, vis); int score = (progress < threshold) ? (-dist_to_origin[ni][nj]+(int)(rng()%10)) : (dist_to_origin[ni][nj]+(int)(rng()%10)); neighbors.push_back({cnt, score, dir}); } }\n        if (neighbors.empty()) return {\"\", INT_MAX};\n        sort(neighbors.begin(), neighbors.end());\n        ci += di[get<2>(neighbors[0])]; cj += dj[get<2>(neighbors[0])]; vis[ci][cj] = true; route += dc[get<2>(neighbors[0])]; vc++;\n    }\n    auto [ret, rd] = find_path(ci, cj, 0, 0); route += ret;\n    return {route, (int)route.size()};\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N; h.resize(N-1); v.resize(N);\n    for (int i = 0; i < N-1; i++) cin >> h[i];\n    for (int i = 0; i < N; i++) cin >> v[i];\n    d.resize(N, vector<int>(N)); for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cin >> d[i][j];\n    dist_to_origin.assign(N, vector<int>(N, -1));\n    queue<pair<int,int>> q; q.push({0, 0}); dist_to_origin[0][0] = 0;\n    while (!q.empty()) { auto [ci, cj] = q.front(); q.pop(); for (int dir = 0; dir < 4; dir++) if (can_move(ci, cj, dir)) { int ni = ci+di[dir], nj = cj+dj[dir]; if (dist_to_origin[ni][nj] == -1) { dist_to_origin[ni][nj] = dist_to_origin[ci][cj]+1; q.push({ni, nj}); } } }\n    \n    string best_route; int best_len = INT_MAX;\n    string dfs_route; { vector<vector<bool>> vis(N, vector<bool>(N, false)); dfs(0, 0, dfs_route, vis); }\n    if ((int)dfs_route.size() < best_len) { best_route = dfs_route; best_len = dfs_route.size(); }\n    auto [gbfs_route, gbfs_len] = greedy_bfs();\n    if (gbfs_len < best_len) { best_route = gbfs_route; best_len = gbfs_len; }\n    \n    vector<function<int(int,int)>> tie_funcs = { [](int i, int j) { return d[i][j]; }, [](int i, int j) { return -d[i][j]; }, [](int i, int j) { return i+j; }, [](int i, int j) { return -i-j; }, [](int i, int j) { return i; }, [](int i, int j) { return -i; }, [](int i, int j) { return j; }, [](int i, int j) { return -j; }, [&](int i, int j) { return dist_to_origin[i][j]; }, [&](int i, int j) { return -dist_to_origin[i][j]; } };\n    for (auto& func : tie_funcs) { auto [route, len] = try_warnsdorff(func); if (!route.empty() && len < best_len) { best_route = route; best_len = len; } }\n    for (double th : {0.3, 0.5, 0.7}) for (int i = 0; i < 30; i++) { auto [route, len] = try_warnsdorff_dynamic(th); if (!route.empty() && len < best_len) { best_route = route; best_len = len; } }\n    for (int i = 0; i < 2000; i++) { auto [route, len] = try_warnsdorff([](int i, int j) { return rng(); }); if (!route.empty() && len < best_len) { best_route = route; best_len = len; } }\n    cout << best_route << endl;\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n, m, si, sj;\nchar grid[16][16];\nstring words[205];\nint cx[26][16][16], cy[26][16][16], cd[26][16][16];\nvector<pair<int,int>> cells[26];\n\nconst int MAXN = 1100;\nint trie[MAXN][26], fail_link[MAXN], node_cnt;\nvector<int> out[MAXN];\n\nvoid insert(const string& s, int id) {\n    int cur = 0;\n    for (char c : s) { int ch = c - 'A'; if (!trie[cur][ch]) trie[cur][ch] = ++node_cnt; cur = trie[cur][ch]; }\n    out[cur].push_back(id);\n}\n\nvoid build() {\n    queue<int> q;\n    for (int c = 0; c < 26; c++) { if (trie[0][c]) { fail_link[trie[0][c]] = 0; q.push(trie[0][c]); } else trie[0][c] = 0; }\n    while (!q.empty()) {\n        int v = q.front(); q.pop();\n        for (int c = 0; c < 26; c++) {\n            if (trie[v][c]) { fail_link[trie[v][c]] = trie[fail_link[v]][c]; for (int id : out[fail_link[trie[v][c]]]) out[trie[v][c]].push_back(id); q.push(trie[v][c]); }\n            else trie[v][c] = trie[fail_link[v]][c];\n        }\n    }\n}\n\nbool was[MAXN][205]; int overlap[MAXN][205];\nvoid precompute() {\n    for (int st = 0; st <= node_cnt; st++) {\n        for (int id : out[st]) was[st][id] = true;\n        for (int w = 0; w < m; w++) { int cur = st, need = 0; bool found = false;\n            for (int i = 0; i < 5; i++) { cur = trie[cur][words[w][i]-'A']; need++; if (was[cur][w]) { found = true; break; } }\n            overlap[st][w] = found ? need : 6;\n        }\n    }\n}\n\nint dp[6][16][16]; \npair<int,int> from_arr[6][16][16];\nint cached_dp[205][6][16][16];\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> n >> m >> si >> sj;\n    for (int i = 0; i < n; i++) { string r; cin >> r; for (int j = 0; j < n; j++) { grid[i][j] = r[j]; cells[r[j]-'A'].push_back({i, j}); } }\n    for (int i = 0; i < m; i++) { cin >> words[i]; insert(words[i], i); }\n    build(); precompute();\n    const int INF = 1e9;\n    for (int c = 0; c < 26; c++) for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) {\n        cd[c][i][j] = INF;\n        for (auto& [x, y] : cells[c]) { int d = abs(i-x)+abs(j-y); if (d < cd[c][i][j]) { cd[c][i][j]=d; cx[c][i][j]=x; cy[c][i][j]=y; } }\n    }\n    int ci=si, cj=sj, st=0, done_cnt=0; vector<bool> done(m,false); vector<pair<int,int>> ops;\n    \n    while (done_cnt < m && (int)ops.size() < 5000) {\n        vector<tuple<double, int, int>> cands;\n        for (int w = 0; w < m; w++) {\n            if (done[w]) continue;\n            int k = overlap[st][w]; if (k < 1 || k > 5) k = 5;\n            int si0 = (overlap[st][w] >= 1 && overlap[st][w] <= 5) ? (5-k) : 0;\n            \n            for(int step=0;step<=k;step++) for(int i=0;i<n;i++) for(int j=0;j<n;j++) cached_dp[w][step][i][j]=INF;\n            cached_dp[w][0][ci][cj] = 0;\n            for (int step = 1; step <= k; step++) {\n                int c = words[w][si0+step-1]-'A';\n                for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) {\n                    if (cached_dp[w][step-1][i][j]==INF) continue;\n                    for (auto& [nx, ny] : cells[c]) {\n                        int nc = cached_dp[w][step-1][i][j]+abs(i-nx)+abs(j-ny)+1;\n                        if (nc < cached_dp[w][step][nx][ny]) cached_dp[w][step][nx][ny] = nc;\n                    }\n                }\n            }\n            int min_cost = INF;\n            for (auto& [ex, ey] : cells[words[w][4]-'A']) min_cost = min(min_cost, cached_dp[w][k][ex][ey]);\n            if (min_cost >= INF) continue;\n            \n            int new_st = st; bool comp[205] = {};\n            for (int i = 0; i < k; i++) { new_st = trie[new_st][words[w][si0+i]-'A']; for (int id : out[new_st]) comp[id] = true; }\n            int bonus = 0; for (int i = 0; i < m; i++) if (comp[i] && !done[i]) bonus++;\n            int tx = ci, ty = cj;\n            for (int i = 0; i < k; i++) { int c = words[w][si0+i]-'A'; tx = cx[c][tx][ty]; ty = cy[c][tx][ty]; }\n            int fmin = INF;\n            for (int w2 = 0; w2 < m; w2++) { if (done[w2]||comp[w2]) continue; int k2=overlap[new_st][w2]; if(k2<1||k2>5) k2=5;\n                int s2=(k2<=5)?(5-k2):0, est=0, tx2=tx, ty2=ty;\n                for (int i = 0; i < k2; i++) { int c=words[w2][s2+i]-'A'; if(cd[c][tx2][ty2]>=INF){est=INF;break;} est+=cd[c][tx2][ty2]+1; tx2=cx[c][tx2][ty2]; ty2=cy[c][tx2][ty2]; }\n                fmin = min(fmin, est); }\n            cands.push_back({min_cost - 18.0*bonus + 0.3*fmin, w, k});\n        }\n        sort(cands.begin(), cands.end());\n        \n        int best_w=-1, best_k=-1, best_ex=-1, best_ey=-1; double best_sc = 1e18;\n        for (int idx = 0; idx < min(25, (int)cands.size()); idx++) {\n            auto [_, w, k] = cands[idx];\n            int si0 = (overlap[st][w]>=1&&overlap[st][w]<=5) ? (5-k) : 0;\n            int new_st = st; bool comp[205] = {};\n            for (int i = 0; i < k; i++) { new_st = trie[new_st][words[w][si0+i]-'A']; for (int id : out[new_st]) comp[id] = true; }\n            int bonus = 0; for (int i = 0; i < m; i++) if (comp[i] && !done[i]) bonus++;\n            for (auto& [ex, ey] : cells[words[w][4]-'A']) {\n                int c1 = cached_dp[w][k][ex][ey]; if (c1 >= INF) continue;\n                int fmin = INF;\n                for (int w2 = 0; w2 < m; w2++) { if (done[w2]||comp[w2]) continue; int k2=overlap[new_st][w2]; if(k2<1||k2>5) k2=5;\n                    int s2=(k2<=5)?(5-k2):0, est=0, tx2=ex, ty2=ey;\n                    for (int i = 0; i < k2; i++) { int c=words[w2][s2+i]-'A'; if(cd[c][tx2][ty2]>=INF){est=INF;break;} est+=cd[c][tx2][ty2]+1; tx2=cx[c][tx2][ty2]; ty2=cy[c][tx2][ty2]; }\n                    fmin = min(fmin, est); }\n                double sc = c1 - 18.0*bonus + 0.25*fmin;\n                if (sc < best_sc) { best_sc = sc; best_w = w; best_k = k; best_ex = ex; best_ey = ey; }\n            }\n        }\n        if (best_w == -1) break;\n        int k = best_k; int si0 = (overlap[st][best_w]>=1&&overlap[st][best_w]<=5) ? (5-k) : 0;\n        for(int step=0;step<=k;step++) for(int i=0;i<n;i++) for(int j=0;j<n;j++) dp[step][i][j]=INF;\n        dp[0][ci][cj] = 0;\n        for (int step = 1; step <= k; step++) { int c = words[best_w][si0+step-1]-'A';\n            for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { if (dp[step-1][i][j]==INF) continue;\n                for (auto& [nx, ny] : cells[c]) { int nc = dp[step-1][i][j]+abs(i-nx)+abs(j-ny)+1;\n                    if (nc < dp[step][nx][ny]) { dp[step][nx][ny] = nc; from_arr[step][nx][ny] = {i, j}; } } } }\n        vector<pair<int,int>> path; int cx2=best_ex, cy2=best_ey;\n        for (int step = k; step >= 1; step--) { path.push_back({cx2,cy2}); auto [px,py] = from_arr[step][cx2][cy2]; cx2=px; cy2=py; }\n        reverse(path.begin(), path.end());\n        if ((int)ops.size()+(int)path.size() > 5000) { int rem = 5000 - ops.size(); for (int i = 0; i < rem; i++) ops.push_back(path[i]); break; }\n        for (auto& [x, y] : path) { ops.push_back({x, y}); st = trie[st][grid[x][y]-'A']; for (int id : out[st]) if (!done[id]) { done[id] = true; done_cnt++; } }\n        ci = best_ex; cj = best_ey;\n    }\n    for (auto& [x,y] : ops) cout << x << \" \" << y << \"\\n\";\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M; double eps;\n    cin >> N >> M >> eps;\n    \n    vector<vector<pair<int,int>>> norm_fields(M);\n    vector<int> field_w(M), field_h(M);\n    for (int k = 0; k < M; k++) {\n        int d; cin >> d;\n        vector<pair<int,int>> raw(d);\n        int mi = N, mj = N;\n        for (int i = 0; i < d; i++) {\n            cin >> raw[i].first >> raw[i].second;\n            mi = min(mi, raw[i].first);\n            mj = min(mj, raw[i].second);\n        }\n        for (int i = 0; i < d; i++) {\n            norm_fields[k].push_back({raw[i].first - mi, raw[i].second - mj});\n            field_w[k] = max(field_w[k], raw[i].first - mi);\n            field_h[k] = max(field_h[k], raw[i].second - mj);\n        }\n    }\n    \n    vector<vector<int>> known(N, vector<int>(N, -1));\n    vector<pair<int,int>> has_oil;\n    \n    auto drill = [&](int i, int j) -> int {\n        if (known[i][j] != -1) return known[i][j];\n        cout << \"q 1 \" << i << \" \" << j << \"\\n\" << flush;\n        int r; cin >> r;\n        known[i][j] = r;\n        if (r > 0) has_oil.push_back({i, j});\n        return r;\n    };\n    \n    auto divine = [&](vector<pair<int,int>> &sq) -> int {\n        if (sq.size() < 2) return -1;\n        cout << \"q \" << sq.size();\n        for (auto [i, j] : sq) cout << \" \" << i << \" \" << j;\n        cout << \"\\n\" << flush;\n        int r; cin >> r;\n        return r;\n    };\n    \n    int bs = 4;\n    int nbi = (N + bs - 1) / bs, nbj = (N + bs - 1) / bs;\n    vector<vector<bool>> skip_4x4(nbi, vector<bool>(nbj, false));\n    vector<vector<vector<bool>>> skip_2x2(nbi, vector<vector<bool>>(nbj, vector<bool>(4, false)));\n    vector<vector<bool>> skip_edge(nbi, vector<bool>(nbj, false));\n    \n    // Phase 1: Divine all blocks\n    for (int bi = 0; bi < nbi; bi++) for (int bj = 0; bj < nbj; bj++) {\n        int bw = min(bs, N - bi*bs), bh = min(bs, N - bj*bs);\n        vector<pair<int,int>> blk;\n        for (int i = bi*bs; i < bi*bs + bw; i++)\n            for (int j = bj*bs; j < bj*bs + bh; j++)\n                blk.push_back({i, j});\n        if (blk.size() < 2) continue;\n        if (divine(blk) == 0) skip_4x4[bi][bj] = true;\n    }\n    \n    // Phase 2: Subdivide non-skipped 4x4 blocks into 2x2\n    for (int bi = 0; bi < nbi; bi++) for (int bj = 0; bj < nbj; bj++) {\n        if (skip_4x4[bi][bj]) continue;\n        int bw = min(bs, N - bi*bs), bh = min(bs, N - bj*bs);\n        if (bw != 4 || bh != 4) continue;\n        \n        for (int si = 0; si < 2; si++) for (int sj = 0; sj < 2; sj++) {\n            vector<pair<int,int>> sub;\n            for (int i = bi*bs + si*2; i < bi*bs + (si+1)*2; i++)\n                for (int j = bj*bs + sj*2; j < bj*bs + (sj+1)*2; j++)\n                    sub.push_back({i, j});\n            if (divine(sub) == 0) skip_2x2[bi][bj][si*2 + sj] = true;\n        }\n    }\n    \n    // Phase 3: Divine edge blocks (non-4x4, not skipped in Phase 1)\n    for (int bi = 0; bi < nbi; bi++) for (int bj = 0; bj < nbj; bj++) {\n        if (skip_4x4[bi][bj]) continue;\n        int bw = min(bs, N - bi*bs), bh = min(bs, N - bj*bs);\n        if (bw == 4 && bh == 4) continue;\n        \n        vector<pair<int,int>> blk;\n        for (int i = bi*bs; i < bi*bs + bw; i++)\n            for (int j = bj*bs; j < bj*bs + bh; j++)\n                blk.push_back({i, j});\n        if (blk.size() >= 2 && divine(blk) == 0) skip_edge[bi][bj] = true;\n    }\n    \n    // Phase 4: Drill remaining squares\n    for (int bi = 0; bi < nbi; bi++) for (int bj = 0; bj < nbj; bj++) {\n        if (skip_4x4[bi][bj] || skip_edge[bi][bj]) continue;\n        int bw = min(bs, N - bi*bs), bh = min(bs, N - bj*bs);\n        \n        if (bw == 4 && bh == 4) {\n            for (int si = 0; si < 2; si++) for (int sj = 0; sj < 2; sj++) {\n                if (skip_2x2[bi][bj][si*2 + sj]) continue;\n                for (int i = bi*bs + si*2; i < bi*bs + (si+1)*2; i++)\n                    for (int j = bj*bs + sj*2; j < bj*bs + (sj+1)*2; j++)\n                        drill(i, j);\n            }\n        } else {\n            for (int i = bi*bs; i < bi*bs + bw; i++)\n                for (int j = bj*bs; j < bj*bs + bh; j++)\n                    drill(i, j);\n        }\n    }\n    \n    // Phase 5: Shape matching\n    if (!has_oil.empty()) {\n        set<pair<int,int>> todo;\n        for (auto [oi, oj] : has_oil) for (int k = 0; k < M; k++)\n            for (auto [si, sj] : norm_fields[k]) {\n                int di = oi - si, dj = oj - sj;\n                if (di < 0 || dj < 0 || di + field_w[k] >= N || dj + field_h[k] >= N) continue;\n                bool ok = true;\n                for (auto [fi, fj] : norm_fields[k])\n                    if (known[di+fi][dj+fj] == 0) { ok = false; break; }\n                if (!ok) continue;\n                for (auto [fi, fj] : norm_fields[k])\n                    if (known[di+fi][dj+fj] == -1) todo.insert({di+fi, dj+fj});\n            }\n        for (auto [i, j] : todo) drill(i, j);\n    }\n    \n    cout << \"a \" << has_oil.size();\n    for (auto [i, j] : has_oil) cout << \" \" << i << \" \" << j;\n    cout << \"\\n\" << flush;\n    int resp; cin >> resp;\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W, D, N;\n    cin >> W >> D >> N;\n    \n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; d++)\n        for (int k = 0; k < N; k++) cin >> a[d][k];\n    \n    if (N == 1) {\n        for (int d = 0; d < D; d++) cout << \"0 0 \" << W << \" \" << W << \"\\n\";\n        return 0;\n    }\n    \n    auto compute_parts = [&](const vector<int>& areas) {\n        vector<int> req(N);\n        for (int k = 0; k < N; k++) req[k] = (areas[k] + W - 1) / W;\n        vector<int> heights = req;\n        long long total = accumulate(heights.begin(), heights.end(), 0LL);\n        if (total > W) {\n            vector<pair<int,int>> indexed(N);\n            for (int k = 0; k < N; k++) indexed[k] = {heights[k], k};\n            sort(indexed.begin(), indexed.end(), greater<pair<int,int>>());\n            long long excess = total - W;\n            for (auto& [h, idx] : indexed) {\n                if (excess <= 0) break;\n                long long reduce = min(excess, (long long)(h - 1));\n                heights[idx] -= reduce;\n                excess -= reduce;\n            }\n        } else if (total < W) {\n            int max_idx = max_element(heights.begin(), heights.end()) - heights.begin();\n            heights[max_idx] += (W - total);\n        }\n        vector<int> parts(N-1);\n        long long cum = 0;\n        for (int k = 0; k < N-1; k++) { cum += heights[k]; parts[k] = cum; }\n        return parts;\n    };\n    \n    auto get_heights = [&](const vector<int>& parts) {\n        vector<int> h(N);\n        h[0] = parts[0];\n        for (int k = 1; k < N-1; k++) h[k] = parts[k] - parts[k-1];\n        h[N-1] = W - parts[N-2];\n        return h;\n    };\n    \n    auto deficit_sorted = [&](const vector<int>& areas, vector<int> heights) {\n        sort(heights.begin(), heights.end());\n        long long def = 0;\n        for (int k = 0; k < N; k++)\n            def += max(0LL, (long long)areas[k] - (long long)heights[k] * W);\n        return def;\n    };\n    \n    auto change_cost = [&](const vector<int>& p1, const vector<int>& p2) {\n        set<int> s1(p1.begin(), p1.end()), s2(p2.begin(), p2.end());\n        vector<int> diff;\n        set_symmetric_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),back_inserter(diff));\n        return (long long)diff.size() * W;\n    };\n    \n    auto output_parts = [&](const vector<int>& parts) {\n        auto heights = get_heights(parts);\n        vector<pair<int,int>> hp(N);\n        for (int k = 0; k < N; k++) hp[k] = {heights[k], k};\n        sort(hp.begin(), hp.end());\n        for (int i = 0; i < N; i++) {\n            int s = hp[i].second;\n            int s0 = s == 0 ? 0 : parts[s-1];\n            int s1 = s < N-1 ? parts[s] : W;\n            cout << s0 << \" 0 \" << s1 << \" \" << W << \"\\n\";\n        }\n    };\n    \n    auto eval = [&](const vector<int>& p) {\n        long long def = 0;\n        for (int d = 0; d < D; d++) def += deficit_sorted(a[d], get_heights(p)) * 100;\n        return def;\n    };\n    \n    auto local_search = [&](vector<int> start, int seed, int max_iter) {\n        long long best_def = eval(start);\n        mt19937 rng(seed);\n        for (int iter = 0; iter < max_iter; iter++) {\n            int k = rng() % (N-1);\n            int left = (k == 0) ? 1 : start[k-1] + 1;\n            int right = (k == N-2) ? W - 1 : start[k+1] - 1;\n            int range = min(200, (right - left) / 2);\n            if (range <= 0) continue;\n            int pos = start[k] + (rng() % (2 * range + 1)) - range;\n            if (pos >= left && pos <= right) {\n                vector<int> test = start; test[k] = pos;\n                long long def = eval(test);\n                if (def < best_def) { best_def = def; start = test; }\n            }\n        }\n        return start;\n    };\n    \n    set<vector<int>> candidate_set;\n    \n    vector<vector<int>> day_optimal(D);\n    for (int d = 0; d < D; d++) {\n        day_optimal[d] = compute_parts(a[d]);\n        candidate_set.insert(day_optimal[d]);\n    }\n    \n    // Local search from each day's optimal\n    for (int d = 0; d < D; d++) {\n        auto parts = local_search(day_optimal[d], d * 100, 500);\n        candidate_set.insert(parts);\n    }\n    \n    // Best global partition with extended search\n    vector<int> global_best = day_optimal[0];\n    long long global_best_def = eval(global_best);\n    for (int d = 1; d < D; d++) {\n        long long def = eval(day_optimal[d]);\n        if (def < global_best_def) { global_best_def = def; global_best = day_optimal[d]; }\n    }\n    global_best = local_search(global_best, 99999, 2000);\n    candidate_set.insert(global_best);\n    \n    // Interpolated partitions between consecutive days\n    for (int d = 0; d < D - 1; d++) {\n        auto& p1 = day_optimal[d], &p2 = day_optimal[d+1];\n        for (int alpha = 1; alpha <= 3; alpha++) {\n            vector<int> interp(N-1);\n            for (int k = 0; k < N-1; k++)\n                interp[k] = (p1[k] * (4 - alpha) + p2[k] * alpha + 2) / 4;\n            for (int k = 1; k < N-1; k++)\n                if (interp[k] <= interp[k-1]) interp[k] = interp[k-1] + 1;\n            if (interp[0] < 1) interp[0] = 1;\n            if (interp[N-2] > W-1) interp[N-2] = W-1;\n            candidate_set.insert(interp);\n        }\n    }\n    \n    vector<vector<int>> candidates(candidate_set.begin(), candidate_set.end());\n    int C = candidates.size();\n    \n    vector<vector<long long>> def_cost(D, vector<long long>(C));\n    for (int d = 0; d < D; d++)\n        for (int c = 0; c < C; c++)\n            def_cost[d][c] = deficit_sorted(a[d], get_heights(candidates[c])) * 100;\n    \n    vector<vector<long long>> cc(C, vector<long long>(C));\n    for (int c1 = 0; c1 < C; c1++)\n        for (int c2 = 0; c2 < C; c2++)\n            cc[c1][c2] = change_cost(candidates[c1], candidates[c2]);\n    \n    vector<vector<long long>> dp(D, vector<long long>(C, LLONG_MAX));\n    vector<vector<int>> parent(D, vector<int>(C, -1));\n    for (int c = 0; c < C; c++) dp[0][c] = def_cost[0][c];\n    \n    for (int d = 1; d < D; d++)\n        for (int c = 0; c < C; c++)\n            for (int c_prev = 0; c_prev < C; c_prev++) {\n                long long cost = dp[d-1][c_prev] + cc[c_prev][c] + def_cost[d][c];\n                if (cost < dp[d][c]) {\n                    dp[d][c] = cost;\n                    parent[d][c] = c_prev;\n                }\n            }\n    \n    int best_c = min_element(dp[D-1].begin(), dp[D-1].end()) - dp[D-1].begin();\n    \n    vector<int> choice(D);\n    choice[D-1] = best_c;\n    for (int d = D-2; d >= 0; d--) choice[d] = parent[d+1][choice[d+1]];\n    \n    for (int d = 0; d < D; d++) output_parts(candidates[choice[d]]);\n    \n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <algorithm>\n#include <chrono>\n#include <random>\n\nusing namespace std;\n\nconst int P = 998244353;\nint N, M, K;\nint T_mod[9][9];\nint initial_T_mod[9][9];\nvector<int> S_flat;\nvector<long long> sum_S;\n\n#define APPLY_STAMP(m, p, q) \\\n    do { int* s = &S_flat[(m) * 9]; \\\n    if (s[0]) { int t = T_mod[(p)][(q)] + s[0]; if (t >= P) t -= P; T_mod[(p)][(q)] = t; } \\\n    if (s[1]) { int t = T_mod[(p)][(q)+1] + s[1]; if (t >= P) t -= P; T_mod[(p)][(q)+1] = t; } \\\n    if (s[2]) { int t = T_mod[(p)][(q)+2] + s[2]; if (t >= P) t -= P; T_mod[(p)][(q)+2] = t; } \\\n    if (s[3]) { int t = T_mod[(p)+1][(q)] + s[3]; if (t >= P) t -= P; T_mod[(p)+1][(q)] = t; } \\\n    if (s[4]) { int t = T_mod[(p)+1][(q)+1] + s[4]; if (t >= P) t -= P; T_mod[(p)+1][(q)+1] = t; } \\\n    if (s[5]) { int t = T_mod[(p)+1][(q)+2] + s[5]; if (t >= P) t -= P; T_mod[(p)+1][(q)+2] = t; } \\\n    if (s[6]) { int t = T_mod[(p)+2][(q)] + s[6]; if (t >= P) t -= P; T_mod[(p)+2][(q)] = t; } \\\n    if (s[7]) { int t = T_mod[(p)+2][(q)+1] + s[7]; if (t >= P) t -= P; T_mod[(p)+2][(q)+1] = t; } \\\n    if (s[8]) { int t = T_mod[(p)+2][(q)+2] + s[8]; if (t >= P) t -= P; T_mod[(p)+2][(q)+2] = t; } \\\n    } while(0)\n\n#define REMOVE_STAMP(m, p, q, loss_var) \\\n    do { int* s = &S_flat[(m) * 9]; \\\n    if (s[0]) { int old = T_mod[(p)][(q)]; int nv = old - s[0]; if (nv < 0) nv += P; T_mod[(p)][(q)] = nv; (loss_var) += nv - old; } \\\n    if (s[1]) { int old = T_mod[(p)][(q)+1]; int nv = old - s[1]; if (nv < 0) nv += P; T_mod[(p)][(q)+1] = nv; (loss_var) += nv - old; } \\\n    if (s[2]) { int old = T_mod[(p)][(q)+2]; int nv = old - s[2]; if (nv < 0) nv += P; T_mod[(p)][(q)+2] = nv; (loss_var) += nv - old; } \\\n    if (s[3]) { int old = T_mod[(p)+1][(q)]; int nv = old - s[3]; if (nv < 0) nv += P; T_mod[(p)+1][(q)] = nv; (loss_var) += nv - old; } \\\n    if (s[4]) { int old = T_mod[(p)+1][(q)+1]; int nv = old - s[4]; if (nv < 0) nv += P; T_mod[(p)+1][(q)+1] = nv; (loss_var) += nv - old; } \\\n    if (s[5]) { int old = T_mod[(p)+1][(q)+2]; int nv = old - s[5]; if (nv < 0) nv += P; T_mod[(p)+1][(q)+2] = nv; (loss_var) += nv - old; } \\\n    if (s[6]) { int old = T_mod[(p)+2][(q)]; int nv = old - s[6]; if (nv < 0) nv += P; T_mod[(p)+2][(q)] = nv; (loss_var) += nv - old; } \\\n    if (s[7]) { int old = T_mod[(p)+2][(q)+1]; int nv = old - s[7]; if (nv < 0) nv += P; T_mod[(p)+2][(q)+1] = nv; (loss_var) += nv - old; } \\\n    if (s[8]) { int old = T_mod[(p)+2][(q)+2]; int nv = old - s[8]; if (nv < 0) nv += P; T_mod[(p)+2][(q)+2] = nv; (loss_var) += nv - old; } \\\n    } while(0)\n\n#define REVERT_STAMP(m, p, q) \\\n    do { int* s = &S_flat[(m) * 9]; \\\n    if (s[0]) { int t = T_mod[(p)][(q)] - s[0]; if (t < 0) t += P; T_mod[(p)][(q)] = t; } \\\n    if (s[1]) { int t = T_mod[(p)][(q)+1] - s[1]; if (t < 0) t += P; T_mod[(p)][(q)+1] = t; } \\\n    if (s[2]) { int t = T_mod[(p)][(q)+2] - s[2]; if (t < 0) t += P; T_mod[(p)][(q)+2] = t; } \\\n    if (s[3]) { int t = T_mod[(p)+1][(q)] - s[3]; if (t < 0) t += P; T_mod[(p)+1][(q)] = t; } \\\n    if (s[4]) { int t = T_mod[(p)+1][(q)+1] - s[4]; if (t < 0) t += P; T_mod[(p)+1][(q)+1] = t; } \\\n    if (s[5]) { int t = T_mod[(p)+1][(q)+2] - s[5]; if (t < 0) t += P; T_mod[(p)+1][(q)+2] = t; } \\\n    if (s[6]) { int t = T_mod[(p)+2][(q)] - s[6]; if (t < 0) t += P; T_mod[(p)+2][(q)] = t; } \\\n    if (s[7]) { int t = T_mod[(p)+2][(q)+1] - s[7]; if (t < 0) t += P; T_mod[(p)+2][(q)+1] = t; } \\\n    if (s[8]) { int t = T_mod[(p)+2][(q)+2] - s[8]; if (t < 0) t += P; T_mod[(p)+2][(q)+2] = t; } \\\n    } while(0)\n\nstruct Move {\n    int rem_size = 0;\n    int rem_ids[3] = {-1, -1, -1};\n    int add_size = 0;\n    tuple<int,int,int> add_ops[3];\n};\n\nvector<tuple<int, int, int>> ops;\nchrono::high_resolution_clock::time_point start_time;\n\nbool run_k_opt(double time_limit, Move& out_move, long long& out_gain) {\n    long long best_net_gain = 0;\n    Move best_move;\n    \n    vector<int> ops_at[7][7];\n    for(int idx=0; idx<(int)ops.size(); ++idx) {\n        ops_at[get<1>(ops[idx])][get<2>(ops[idx])].push_back(idx);\n    }\n    \n    int rem_indices[20];\n    int rems[1500][3]; int rem_sizes[1500]; int num_rems;\n    \n    auto find_best_addition = [&]() -> tuple<long long, int, int, int> {\n        long long max_gain = 0; int bm = -1, bp = -1, bq = -1;\n        for(int p = 0; p <= 6; ++p) {\n            for(int q = 0; q <= 6; ++q) {\n                int t0 = T_mod[p][q], t1 = T_mod[p][q+1], t2 = T_mod[p][q+2];\n                int t3 = T_mod[p+1][q], t4 = T_mod[p+1][q+1], t5 = T_mod[p+1][q+2];\n                int t6 = T_mod[p+2][q], t7 = T_mod[p+2][q+1], t8 = T_mod[p+2][q+2];\n                for(int m = 0; m < M; ++m) {\n                    int* s = &S_flat[m * 9];\n                    int overflow = (t0 + s[0]) >= P;\n                    overflow += (t1 + s[1]) >= P;\n                    overflow += (t2 + s[2]) >= P;\n                    overflow += (t3 + s[3]) >= P;\n                    overflow += (t4 + s[4]) >= P;\n                    overflow += (t5 + s[5]) >= P;\n                    overflow += (t6 + s[6]) >= P;\n                    overflow += (t7 + s[7]) >= P;\n                    overflow += (t8 + s[8]) >= P;\n                    long long gain = sum_S[m] - (long long)P * overflow;\n                    if (gain > max_gain) { max_gain = gain; bm = m; bp = p; bq = q; }\n                }\n            }\n        }\n        return {max_gain, bm, bp, bq};\n    };\n\n    for (int r = 0; r < 9; ++r) {\n        if (std::chrono::duration<double>(std::chrono::high_resolution_clock::now() - start_time).count() > time_limit) {\n            out_move = best_move; out_gain = best_net_gain;\n            return best_net_gain > 0;\n        }\n        for (int c = 0; c < 9; ++c) {\n            vector<int> local_ops;\n            local_ops.reserve(20);\n            for (int p = max(0, r-2); p <= min(6, r); ++p)\n                for (int q = max(0, c-2); q <= min(6, c); ++q)\n                    for (int idx : ops_at[p][q]) local_ops.push_back(idx);\n            \n            if ((int)local_ops.size() > 20) local_ops.erase(local_ops.begin(), local_ops.end() - 20);\n            int num_local_ops = (int)local_ops.size();\n            for(int i=0; i<num_local_ops; ++i) rem_indices[i] = local_ops[i];\n            \n            num_rems = 0;\n            rems[num_rems][0] = -1; rem_sizes[num_rems] = 0; num_rems++;\n            for(int i=0; i<num_local_ops; ++i) { rems[num_rems][0] = rem_indices[i]; rem_sizes[num_rems] = 1; num_rems++; }\n            for(int i=0; i<num_local_ops; ++i) for(int j=i+1; j<num_local_ops; ++j) { rems[num_rems][0] = rem_indices[i]; rems[num_rems][1] = rem_indices[j]; rem_sizes[num_rems] = 2; num_rems++; }\n            for(int i=0; i<num_local_ops; ++i) for(int j=i+1; j<num_local_ops; ++j) for(int k=j+1; k<num_local_ops; ++k) { rems[num_rems][0] = rem_indices[i]; rems[num_rems][1] = rem_indices[j]; rems[num_rems][2] = rem_indices[k]; rem_sizes[num_rems] = 3; num_rems++; }\n            \n            for (int r_idx = 0; r_idx < num_rems; ++r_idx) {\n                if ((int)ops.size() - rem_sizes[r_idx] > K) continue;\n                long long loss = 0;\n                for (int i = 0; i < rem_sizes[r_idx]; ++i) {\n                    int idx = rems[r_idx][i];\n                    REMOVE_STAMP(get<0>(ops[idx]), get<1>(ops[idx]), get<2>(ops[idx]), loss);\n                }\n                \n                if (loss > best_net_gain) {\n                    best_net_gain = loss; best_move.rem_size = rem_sizes[r_idx];\n                    for(int i=0; i<rem_sizes[r_idx]; ++i) best_move.rem_ids[i] = rems[r_idx][i];\n                    best_move.add_size = 0;\n                }\n                \n                auto [gain1, m1, p1, q1] = find_best_addition();\n                if (loss + gain1 > best_net_gain && (int)ops.size() - rem_sizes[r_idx] + 1 <= K) {\n                    best_net_gain = loss + gain1; best_move.rem_size = rem_sizes[r_idx];\n                    for(int i=0; i<rem_sizes[r_idx]; ++i) best_move.rem_ids[i] = rems[r_idx][i];\n                    best_move.add_size = 1; best_move.add_ops[0] = {m1, p1, q1};\n                }\n                \n                if (gain1 > 0 && (int)ops.size() - rem_sizes[r_idx] + 2 <= K) {\n                    APPLY_STAMP(m1, p1, q1);\n                    auto [gain2, m2, p2, q2] = find_best_addition();\n                    if (loss + gain1 + gain2 > best_net_gain) {\n                        best_net_gain = loss + gain1 + gain2; best_move.rem_size = rem_sizes[r_idx];\n                        for(int i=0; i<rem_sizes[r_idx]; ++i) best_move.rem_ids[i] = rems[r_idx][i];\n                        best_move.add_size = 2; best_move.add_ops[0] = {m1, p1, q1}; best_move.add_ops[1] = {m2, p2, q2};\n                    }\n                    if (m2 != -1 && (int)ops.size() - rem_sizes[r_idx] + 3 <= K) {\n                        APPLY_STAMP(m2, p2, q2);\n                        auto [gain3, m3, p3, q3] = find_best_addition();\n                        if (loss + gain1 + gain2 + gain3 > best_net_gain) {\n                            best_net_gain = loss + gain1 + gain2 + gain3; best_move.rem_size = rem_sizes[r_idx];\n                            for(int i=0; i<rem_sizes[r_idx]; ++i) best_move.rem_ids[i] = rems[r_idx][i];\n                            best_move.add_size = 3; best_move.add_ops[0] = {m1, p1, q1}; best_move.add_ops[1] = {m2, p2, q2}; best_move.add_ops[2] = {m3, p3, q3};\n                        }\n                        REVERT_STAMP(m2, p2, q2);\n                    }\n                    REVERT_STAMP(m1, p1, q1);\n                }\n                for (int i = 0; i < rem_sizes[r_idx]; ++i) {\n                    int idx = rems[r_idx][i];\n                    APPLY_STAMP(get<0>(ops[idx]), get<1>(ops[idx]), get<2>(ops[idx]));\n                }\n            }\n        }\n    }\n    out_move = best_move; out_gain = best_net_gain;\n    return best_net_gain > 0;\n}\n\nlong long compute_score() {\n    long long score = 0;\n    for(int i=0; i<9; ++i) for(int j=0; j<9; ++j) score += T_mod[i][j];\n    return score;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    if (!(cin >> N >> M >> K)) return 0;\n    for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) { cin >> T_mod[i][j]; initial_T_mod[i][j] = T_mod[i][j]; }\n    S_flat.assign(M * 9, 0); sum_S.assign(M, 0);\n    for (int m = 0; m < M; ++m) for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) { int idx = m * 9 + i * 3 + j; cin >> S_flat[idx]; sum_S[m] += S_flat[idx]; }\n\n    long long best_gain_at_pos[7][7]; int best_m_at_pos[7][7];\n    auto update_pos = [&](int p, int q) {\n        long long best_g = -1; int best_m = 0;\n        int t0 = T_mod[p][q], t1 = T_mod[p][q+1], t2 = T_mod[p][q+2];\n        int t3 = T_mod[p+1][q], t4 = T_mod[p+1][q+1], t5 = T_mod[p+1][q+2];\n        int t6 = T_mod[p+2][q], t7 = T_mod[p+2][q+1], t8 = T_mod[p+2][q+2];\n        for (int m = 0; m < M; ++m) {\n            int* s = &S_flat[m * 9];\n            int overflow = (t0 + s[0]) >= P;\n            overflow += (t1 + s[1]) >= P;\n            overflow += (t2 + s[2]) >= P;\n            overflow += (t3 + s[3]) >= P;\n            overflow += (t4 + s[4]) >= P;\n            overflow += (t5 + s[5]) >= P;\n            overflow += (t6 + s[6]) >= P;\n            overflow += (t7 + s[7]) >= P;\n            overflow += (t8 + s[8]) >= P;\n            long long gain = sum_S[m] - (long long)P * overflow;\n            if (gain > best_g) { best_g = gain; best_m = m; }\n        }\n        best_gain_at_pos[p][q] = best_g; best_m_at_pos[p][q] = best_m;\n    };\n    auto update_affected = [&](int p_old, int q_old) { for (int p = max(0, p_old - 2); p <= min(6, p_old + 2); ++p) for (int q = max(0, q_old - 2); q <= min(6, q_old + 2); ++q) update_pos(p, q); };\n    auto update_all = [&]() { for (int p = 0; p <= 6; ++p) for (int q = 0; q <= 6; ++q) update_pos(p, q); };\n    \n    update_all();\n    for (int step = 0; step < K; ++step) {\n        long long best_gain = 0; int best_p = -1, best_q = -1;\n        for (int p = 0; p <= 6; ++p) for (int q = 0; q <= 6; ++q) if (best_gain_at_pos[p][q] > best_gain) { best_gain = best_gain_at_pos[p][q]; best_p = p; best_q = q; }\n        if (best_gain <= 0) break;\n        int best_m = best_m_at_pos[best_p][best_q]; ops.emplace_back(best_m, best_p, best_q);\n        APPLY_STAMP(best_m, best_p, best_q); update_affected(best_p, best_q);\n    }\n\n    start_time = std::chrono::high_resolution_clock::now();\n    Move m; long long g;\n    while (true) {\n        bool found = run_k_opt(1.4, m, g);\n        if (g > 0) {\n            vector<bool> removed(ops.size(), false);\n            for(int i=0; i<m.rem_size; ++i) removed[m.rem_ids[i]] = true;\n            vector<tuple<int,int,int>> new_ops;\n            for(int i=0; i<(int)ops.size(); ++i) if (!removed[i]) new_ops.push_back(ops[i]);\n            for(int i=0; i<m.add_size; ++i) new_ops.push_back(m.add_ops[i]);\n            ops = new_ops;\n            for(int i=0; i<9; ++i) for(int j=0; j<9; ++j) T_mod[i][j] = initial_T_mod[i][j];\n            for(auto& op : ops) APPLY_STAMP(get<0>(op), get<1>(op), get<2>(op));\n        }\n        if (!found) break;\n    }\n\n    auto best_ops = ops;\n    long long best_score = compute_score();\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    while (std::chrono::duration<double>(std::chrono::high_resolution_clock::now() - start_time).count() < 1.75) {\n        auto perturbed_ops = best_ops;\n        int num_remove = 3 + (int)(rng() % 6);\n        if ((int)perturbed_ops.size() <= num_remove) continue;\n        \n        shuffle(perturbed_ops.begin(), perturbed_ops.end(), rng);\n        perturbed_ops.resize(perturbed_ops.size() - num_remove);\n        \n        ops = perturbed_ops;\n        \n        for(int i=0; i<9; ++i) for(int j=0; j<9; ++j) T_mod[i][j] = initial_T_mod[i][j];\n        for(auto& op : ops) APPLY_STAMP(get<0>(op), get<1>(op), get<2>(op));\n        \n        update_all();\n        for (int step = (int)ops.size(); step < K; ++step) {\n            long long best_gain = 0; int best_p = -1, best_q = -1;\n            for (int p = 0; p <= 6; ++p) for (int q = 0; q <= 6; ++q) if (best_gain_at_pos[p][q] > best_gain) { best_gain = best_gain_at_pos[p][q]; best_p = p; best_q = q; }\n            if (best_gain <= 0) break;\n            int best_m = best_m_at_pos[best_p][best_q]; ops.emplace_back(best_m, best_p, best_q);\n            APPLY_STAMP(best_m, best_p, best_q); update_affected(best_p, best_q);\n        }\n        \n        double perturb_time_limit = std::chrono::duration<double>(std::chrono::high_resolution_clock::now() - start_time).count() + 0.15;\n        while (true) {\n            bool found = run_k_opt(perturb_time_limit, m, g);\n            if (g > 0) {\n                vector<bool> removed(ops.size(), false);\n                for(int i=0; i<m.rem_size; ++i) removed[m.rem_ids[i]] = true;\n                vector<tuple<int,int,int>> new_ops;\n                for(int i=0; i<(int)ops.size(); ++i) if (!removed[i]) new_ops.push_back(ops[i]);\n                for(int i=0; i<m.add_size; ++i) new_ops.push_back(m.add_ops[i]);\n                ops = new_ops;\n                for(int i=0; i<9; ++i) for(int j=0; j<9; ++j) T_mod[i][j] = initial_T_mod[i][j];\n                for(auto& op : ops) APPLY_STAMP(get<0>(op), get<1>(op), get<2>(op));\n            }\n            if (!found) break;\n        }\n        \n        long long new_score = compute_score();\n        if (new_score > best_score) {\n            best_score = new_score;\n            best_ops = ops;\n        }\n    }\n    \n    ops = best_ops;\n    for(int i=0; i<9; ++i) for(int j=0; j<9; ++j) T_mod[i][j] = initial_T_mod[i][j];\n    for(auto& op : ops) APPLY_STAMP(get<0>(op), get<1>(op), get<2>(op));\n\n    update_all();\n    bool improved = true;\n    while (improved) {\n        auto current_time = std::chrono::high_resolution_clock::now();\n        if (std::chrono::duration<double>(current_time - start_time).count() > 1.95) break;\n        improved = false; update_all(); long long best_net_gain = 0;\n        int best_i = -1, best_j = -1, ls_best_m1 = -1, ls_best_p1 = -1, ls_best_q1 = -1, ls_best_m2 = -1, ls_best_p2 = -1, ls_best_q2 = -1; bool add_two = false;\n        int ops_size = (int)ops.size();\n        for (int i = 0; i <= ops_size; ++i) {\n            int j_start = (i < ops_size) ? i + 1 : i; bool is_i_valid = (i < ops_size); long long loss_i = 0;\n            if (is_i_valid) { const auto& [mi, pi, qi] = ops[i]; REMOVE_STAMP(mi, pi, qi, loss_i); update_affected(pi, qi); }\n            for (int j = j_start; j <= ops_size; ++j) {\n                bool is_j_valid = (j < ops_size); long long loss_j = 0;\n                if (is_j_valid) { const auto& [mj, pj, qj] = ops[j]; REMOVE_STAMP(mj, pj, qj, loss_j); update_affected(pj, qj); }\n                long long total_loss = loss_i + loss_j; int current_sim_size = ops_size - (is_i_valid ? 1 : 0) - (is_j_valid ? 1 : 0);\n                long long max_gain_1 = 0; int bm1 = -1, bp1 = -1, bq1 = -1;\n                for (int p = 0; p <= 6; ++p) for (int q = 0; q <= 6; ++q) if (best_gain_at_pos[p][q] > max_gain_1) { max_gain_1 = best_gain_at_pos[p][q]; bm1 = best_m_at_pos[p][q]; bp1 = p; bq1 = q; }\n                if (current_sim_size + 1 <= K && max_gain_1 - total_loss > best_net_gain) { best_net_gain = max_gain_1 - total_loss; best_i = i; best_j = j; ls_best_m1 = bm1; ls_best_p1 = bp1; ls_best_q1 = bq1; ls_best_m2 = -1; add_two = false; }\n                if (current_sim_size + 2 <= K && bm1 != -1) {\n                    APPLY_STAMP(bm1, bp1, bq1); update_affected(bp1, bq1);\n                    long long max_gain_2 = 0; int bm2 = -1, bp2 = -1, bq2 = -1;\n                    for (int p = 0; p <= 6; ++p) for (int q = 0; q <= 6; ++q) if (best_gain_at_pos[p][q] > max_gain_2) { max_gain_2 = best_gain_at_pos[p][q]; bm2 = best_m_at_pos[p][q]; bp2 = p; bq2 = q; }\n                    if (max_gain_1 + max_gain_2 - total_loss > best_net_gain) { best_net_gain = max_gain_1 + max_gain_2 - total_loss; best_i = i; best_j = j; ls_best_m1 = bm1; ls_best_p1 = bp1; ls_best_q1 = bq1; ls_best_m2 = bm2; ls_best_p2 = bp2; ls_best_q2 = bq2; add_two = true; }\n                    REVERT_STAMP(bm1, bp1, bq1); update_affected(bp1, bq1);\n                }\n                if (is_j_valid) { const auto& [mj, pj, qj] = ops[j]; APPLY_STAMP(mj, pj, qj); update_affected(pj, qj); }\n            }\n            if (is_i_valid) { const auto& [mi, pi, qi] = ops[i]; APPLY_STAMP(mi, pi, qi); update_affected(pi, qi); }\n        }\n        if (best_net_gain > 0) {\n            improved = true;\n            long long dummy = 0;\n            if (best_i < ops_size) { const auto& [mi, pi, qi] = ops[best_i]; REMOVE_STAMP(mi, pi, qi, dummy); update_affected(pi, qi); }\n            if (best_j < ops_size) { const auto& [mj, pj, qj] = ops[best_j]; REMOVE_STAMP(mj, pj, qj, dummy); update_affected(pj, qj); }\n            if (ls_best_m1 != -1) { APPLY_STAMP(ls_best_m1, ls_best_p1, ls_best_q1); update_affected(ls_best_p1, ls_best_q1); }\n            if (add_two && ls_best_m2 != -1) { APPLY_STAMP(ls_best_m2, ls_best_p2, ls_best_q2); update_affected(ls_best_p2, ls_best_q2); }\n            vector<tuple<int,int,int>> new_ops; for(int k=0; k<ops_size; ++k) if(k!=best_i && k!=best_j) new_ops.push_back(ops[k]);\n            if (ls_best_m1 != -1) new_ops.emplace_back(ls_best_m1, ls_best_p1, ls_best_q1);\n            if (add_two && ls_best_m2 != -1) new_ops.emplace_back(ls_best_m2, ls_best_p2, ls_best_q2);\n            ops = new_ops;\n        }\n    }\n    cout << ops.size() << \"\\n\";\n    for (const auto& [m, p, q] : ops) cout << m << \" \" << p << \" \" << q << \"\\n\";\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 5;\nint A[N][N], cont_row[25], cont_order[25];\nint grid[N][N], crx, cry, recv_idx[N], next_dispatch[N];\nbool dispatched[25];\nstring cmds[N];\n\nvoid move_to(int tx, int ty, char& a) {\n    if (crx < tx) a = 'D'; else if (crx > tx) a = 'U';\n    else if (cry < ty) a = 'R'; else if (cry > ty) a = 'L'; else a = '.';\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        cin >> A[i][j]; cont_row[A[i][j]] = A[i][j] / N; cont_order[A[i][j]] = A[i][j] % N;\n    }\n    cmds[0] = \"..\"; for (int i = 1; i < N; i++) cmds[i] = \"RB\";\n    memset(grid, -1, sizeof(grid));\n    for (int i = 1; i < N; i++) grid[i][0] = A[i][0];\n    crx = 0; cry = 0; bool cr_carry = false; int cr_held = -1;\n    memset(recv_idx, 0, sizeof(recv_idx));\n    recv_idx[1] = recv_idx[2] = recv_idx[3] = recv_idx[4] = 1;\n    memset(dispatched, false, sizeof(dispatched));\n    memset(next_dispatch, 0, sizeof(next_dispatch));\n    int target = -1;\n    \n    for (int turn = 2; turn < 10000; turn++) {\n        for (int i = 0; i < N; i++)\n            if (recv_idx[i] < N && grid[i][0] == -1 && !(crx == i && cry == 0 && cr_carry))\n                grid[i][0] = A[i][recv_idx[i]++];\n        \n        char act = '.';\n        for (int r = 0; r < N; r++)\n            while (next_dispatch[r] < N && dispatched[r * N + next_dispatch[r]]) next_dispatch[r]++;\n        \n        if (!cr_carry) {\n            int px = -1, py = -1, pd = 1000;\n            // Priority 1: \"next to dispatch\" anywhere on grid\n            for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n                if (grid[i][j] != -1) {\n                    int cid = grid[i][j];\n                    if (cont_order[cid] == next_dispatch[cont_row[cid]]) {\n                        int d = abs(i - crx) + abs(j - cry);\n                        if (d < pd) { pd = d; px = i; py = j; }\n                    }\n                }\n            }\n            // Priority 2: column 0 (unblock receiving)\n            if (px < 0) {\n                for (int i = 0; i < N; i++) if (grid[i][0] != -1) {\n                    int d = abs(i - crx) + abs(cry);\n                    if (d < pd) { pd = d; px = i; py = 0; }\n                }\n            }\n            // Priority 3: any container anywhere (robust against desync)\n            if (px < 0) {\n                for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n                    if (grid[i][j] != -1) {\n                        int d = abs(i - crx) + abs(j - cry);\n                        if (d < pd) { pd = d; px = i; py = j; }\n                    }\n                }\n            }\n            if (px >= 0) {\n                if (crx == px && cry == py) { act = 'P'; target = grid[px][py]; }\n                else move_to(px, py, act);\n            }\n        } else {\n            // ALWAYS dispatch directly - no buffering\n            int tr = cont_row[target];\n            if (crx == tr && cry == N-1) { if (grid[tr][N-1] == -1) act = 'Q'; else act = '.'; }\n            else move_to(tr, N-1, act);\n        }\n        cmds[0] += act; for (int i = 1; i < N; i++) cmds[i] += '.';\n        if (act == 'P') { cr_held = grid[crx][cry]; grid[crx][cry] = -1; cr_carry = true; }\n        else if (act == 'Q') { grid[crx][cry] = cr_held; cr_held = -1; cr_carry = false; }\n        else if (act == 'U') crx--; else if (act == 'D') crx++;\n        else if (act == 'L') cry--; else if (act == 'R') cry++;\n        for (int i = 0; i < N; i++) if (grid[i][N-1] != -1) {\n            int c = grid[i][N-1]; dispatched[c] = true; grid[i][N-1] = -1;\n            if (i == cont_row[c] && cont_order[c] == next_dispatch[i]) next_dispatch[i]++;\n        }\n        bool done = true; for (int i = 0; i < 25; i++) if (!dispatched[i]) { done = false; break; }\n        if (done) break;\n    }\n    for (int i = 0; i < N; i++) cout << cmds[i] << endl;\n}","ahc034":"#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;\n    cin >> N;\n    vector<vector<int>> h(N, vector<int>(N));\n    vector<pair<int, int>> cells;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            cin >> h[i][j];\n            if (h[i][j] != 0) cells.push_back({i, j});\n        }\n    \n    int M = cells.size();\n    if (M == 0) return 0;\n    \n    vector<int> cell_idx(N * N, -1);\n    for (int k = 0; k < M; k++)\n        cell_idx[cells[k].first * N + cells[k].second] = k;\n    \n    vector<int> hv(M);\n    for (int k = 0; k < M; k++)\n        hv[k] = h[cells[k].first][cells[k].second];\n    \n    vector<int> tour;\n    vector<bool> used(M, false);\n    int ci = 0, cj = 0, load = 0;\n    \n    for (int step = 0; step < M; step++) {\n        int best = -1;\n        double best_score = 1e18;\n        int radius = 15;\n        \n        for (int ni = max(0, ci - radius); ni <= min(N-1, ci + radius); ni++) {\n            for (int nj = max(0, cj - radius); nj <= min(N-1, cj + radius); nj++) {\n                int idx = cell_idx[ni * N + nj];\n                if (idx == -1 || used[idx]) continue;\n                if (hv[idx] < 0 && load < -hv[idx]) continue;\n                \n                int d = abs(ci - ni) + abs(cj - nj);\n                double s = d * 100.0 + load * d;\n                if (hv[idx] < 0 && load > 0)\n                    s -= min((double)load, (double)(-hv[idx])) * 1.5 * (M - step);\n                if (hv[idx] > 0 && load < 0)\n                    s -= min((double)(-load), (double)hv[idx]) * 1.0 * (M - step);\n                if (s < best_score) { best_score = s; best = idx; }\n            }\n        }\n        \n        if (best == -1) {\n            for (int k = 0; k < M; k++) {\n                if (used[k]) continue;\n                if (hv[k] < 0 && load < -hv[k]) continue;\n                int ni = cells[k].first, nj = cells[k].second;\n                int d = abs(ci - ni) + abs(cj - nj);\n                double s = d * 100.0 + load * d;\n                if (hv[k] < 0 && load > 0)\n                    s -= min((double)load, (double)(-hv[k])) * 1.5 * (M - step);\n                if (hv[k] > 0 && load < 0)\n                    s -= min((double)(-load), (double)hv[k]) * 1.0 * (M - step);\n                if (s < best_score) { best_score = s; best = k; }\n            }\n        }\n        \n        tour.push_back(best);\n        used[best] = true;\n        load += hv[best];\n        ci = cells[best].first; cj = cells[best].second;\n    }\n    \n    auto valid = [&]() -> bool {\n        int ld = 0;\n        for (int idx : tour) {\n            if (hv[idx] < 0 && ld < -hv[idx]) return false;\n            ld += hv[idx];\n        }\n        return true;\n    };\n    \n    auto cost_fn = [&]() -> double {\n        double c = 0; int li = 0, lj = 0, ld = 0;\n        for (int idx : tour) {\n            int ni = cells[idx].first, nj = cells[idx].second;\n            int d = abs(li - ni) + abs(lj - nj);\n            c += d * 100.0 + ld * d;\n            ld += hv[idx]; li = ni; lj = nj;\n        }\n        return c;\n    };\n    \n    double cur = cost_fn();\n    \n    for (int round = 0; round < 3; round++) {\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            for (int i = 0; i + 1 < M; i++) {\n                swap(tour[i], tour[i+1]);\n                if (valid()) {\n                    double nc = cost_fn();\n                    if (nc < cur - 0.01) { cur = nc; improved = true; }\n                    else swap(tour[i], tour[i+1]);\n                } else swap(tour[i], tour[i+1]);\n            }\n        }\n        \n        for (int max_len = 10; max_len <= 30; max_len += 5) {\n            improved = true;\n            while (improved) {\n                improved = false;\n                for (int i = 0; i < M - 1; i++) {\n                    for (int j = i + 2; j < min(i + max_len + 1, M); j++) {\n                        reverse(tour.begin() + i, tour.begin() + j + 1);\n                        if (valid()) {\n                            double nc = cost_fn();\n                            if (nc < cur - 0.01) { cur = nc; improved = true; }\n                            else reverse(tour.begin() + i, tour.begin() + j + 1);\n                        } else reverse(tour.begin() + i, tour.begin() + j + 1);\n                    }\n                }\n            }\n        }\n        \n        // Or-opt for single elements \u00b114\n        bool found = true;\n        while (found) {\n            found = false;\n            for (int i = 0; i < M; i++) {\n                for (int delta = -14; delta <= 14; delta++) {\n                    if (delta == 0 || delta == 1 || delta == -1) continue;\n                    int new_pos = (delta > 0) ? i + delta - 1 : i + delta;\n                    if (new_pos < 0 || new_pos >= M) continue;\n                    \n                    int elem = tour[i];\n                    tour.erase(tour.begin() + i);\n                    tour.insert(tour.begin() + new_pos, elem);\n                    \n                    if (valid()) {\n                        double nc = cost_fn();\n                        if (nc < cur - 0.01) { cur = nc; found = true; break; }\n                    }\n                    \n                    tour.erase(tour.begin() + new_pos);\n                    tour.insert(tour.begin() + i, elem);\n                }\n                if (found) break;\n            }\n        }\n        \n        // Block-or-opt for pairs \u00b17\n        found = true;\n        while (found) {\n            found = false;\n            for (int i = 0; i + 1 < M; i++) {\n                for (int delta = -7; delta <= 7; delta++) {\n                    if (abs(delta) <= 2) continue;\n                    int new_pos = (delta > 0) ? i + delta - 2 : i + delta;\n                    if (new_pos < 0 || new_pos + 1 >= M) continue;\n                    if (new_pos >= i - 1 && new_pos <= i + 2) continue;\n                    \n                    int e1 = tour[i], e2 = tour[i+1];\n                    tour.erase(tour.begin() + i, tour.begin() + i + 2);\n                    tour.insert(tour.begin() + new_pos, {e1, e2});\n                    \n                    if (valid()) {\n                        double nc = cost_fn();\n                        if (nc < cur - 0.01) { cur = nc; found = true; break; }\n                    }\n                    \n                    tour.erase(tour.begin() + new_pos, tour.begin() + new_pos + 2);\n                    tour.insert(tour.begin() + i, {e1, e2});\n                }\n                if (found) break;\n            }\n        }\n        \n        // Block-or-opt for triplets \u00b14\n        found = true;\n        while (found) {\n            found = false;\n            for (int i = 0; i + 2 < M; i++) {\n                for (int delta = -4; delta <= 4; delta++) {\n                    if (abs(delta) <= 3) continue;\n                    int new_pos = (delta > 0) ? i + delta - 3 : i + delta;\n                    if (new_pos < 0 || new_pos + 2 >= M) continue;\n                    if (new_pos >= i - 2 && new_pos <= i + 3) continue;\n                    \n                    int e1 = tour[i], e2 = tour[i+1], e3 = tour[i+2];\n                    tour.erase(tour.begin() + i, tour.begin() + i + 3);\n                    tour.insert(tour.begin() + new_pos, {e1, e2, e3});\n                    \n                    if (valid()) {\n                        double nc = cost_fn();\n                        if (nc < cur - 0.01) { cur = nc; found = true; break; }\n                    }\n                    \n                    tour.erase(tour.begin() + new_pos, tour.begin() + new_pos + 3);\n                    tour.insert(tour.begin() + i, {e1, e2, e3});\n                }\n                if (found) break;\n            }\n        }\n    }\n    \n    // Final adjacent swaps\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (int i = 0; i + 1 < M; i++) {\n            swap(tour[i], tour[i+1]);\n            if (valid()) {\n                double nc = cost_fn();\n                if (nc < cur - 0.01) { cur = nc; improved = true; }\n                else swap(tour[i], tour[i+1]);\n            } else swap(tour[i], tour[i+1]);\n        }\n    }\n    \n    vector<string> ops;\n    ci = 0; cj = 0;\n    for (int idx : tour) {\n        int ni = cells[idx].first, nj = cells[idx].second;\n        while (ci < ni) { ops.push_back(\"D\"); ci++; }\n        while (ci > ni) { ops.push_back(\"U\"); ci--; }\n        while (cj < nj) { ops.push_back(\"R\"); cj++; }\n        while (cj > nj) { ops.push_back(\"L\"); cj--; }\n        ops.push_back((hv[idx] > 0 ? \"+\" : \"-\") + to_string(abs(hv[idx])));\n    }\n    for (const auto& op : ops) cout << op << \"\\n\";\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, T;\n    cin >> N >> M >> T;\n\n    const int seed_count = 2 * N * (N - 1);\n    const int grid_size = N * N;\n    vector<vector<int>> X(seed_count, vector<int>(M, 0));\n    vector<int> V(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    const int dr[] = {-1, 1, 0, 0};\n    const int dc[] = {0, 0, -1, 1};\n    vector<vector<int>> nbrs(grid_size);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int pos = i * N + j;\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dr[d], nj = j + dc[d];\n                if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                    nbrs[pos].push_back(ni * N + nj);\n                }\n            }\n        }\n    }\n\n    mt19937 rng(42);\n\n    for (int t = 0; t < T; t++) {\n        vector<vector<int>> allEP(seed_count, vector<int>(seed_count, 0));\n        for (int i = 0; i < seed_count; i++) {\n            for (int j = i + 1; j < seed_count; j++) {\n                int s = 0;\n                for (int l = 0; l < M; l++) s += max(X[i][l], X[j][l]);\n                allEP[i][j] = allEP[j][i] = s;\n            }\n        }\n        \n        vector<pair<int, pair<int,int>>> pairs;\n        for (int i = 0; i < seed_count; i++) {\n            for (int j = i + 1; j < seed_count; j++) {\n                pairs.push_back({allEP[i][j], {i, j}});\n            }\n        }\n        sort(pairs.rbegin(), pairs.rend());\n        \n        vector<bool> used(seed_count, false);\n        vector<int> selected;\n        \n        for (auto& [ep, p] : pairs) {\n            if (selected.size() >= grid_size) break;\n            int a = p.first, b = p.second;\n            if (used[a] || used[b]) continue;\n            \n            if (selected.size() + 2 <= grid_size) {\n                selected.push_back(a);\n                selected.push_back(b);\n                used[a] = used[b] = true;\n            } else if (selected.size() + 1 == grid_size) {\n                selected.push_back(V[a] >= V[b] ? a : b);\n                used[a] = used[b] = true;\n            }\n        }\n        \n        while (selected.size() < grid_size) {\n            int bestSeed = -1;\n            long long bestScore = -1;\n            for (int s = 0; s < seed_count; s++) {\n                if (used[s]) continue;\n                long long sumEP = 0;\n                for (int sel : selected) sumEP += allEP[s][sel];\n                long long score = sumEP * 10000LL + V[s];\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestSeed = s;\n                }\n            }\n            selected.push_back(bestSeed);\n            used[bestSeed] = true;\n        }\n        \n        vector<int> perm = selected;\n        \n        vector<int> unselectedSeeds;\n        for (int s = 0; s < seed_count; s++) {\n            if (!used[s]) unselectedSeeds.push_back(s);\n        }\n        \n        vector<vector<int>> ep(grid_size, vector<int>(grid_size, 0));\n        for (int i = 0; i < grid_size; i++) {\n            for (int j = i + 1; j < grid_size; j++) {\n                ep[i][j] = ep[j][i] = allEP[perm[i]][perm[j]];\n            }\n        }\n        \n        double temp = 800.0;\n        double cooling = 0.99997;\n        uniform_real_distribution<double> dist(0.0, 1.0);\n        uniform_int_distribution<int> posDist(0, grid_size - 1);\n        \n        for (int iter = 0; iter < 350000; iter++) {\n            if (rng() % 5 == 0 && !unselectedSeeds.empty()) {\n                int p = posDist(rng);\n                int idx = rng() % unselectedSeeds.size();\n                int s = unselectedSeeds[idx];\n                \n                int delta = 0;\n                for (int nb : nbrs[p]) {\n                    delta += allEP[s][perm[nb]] - allEP[perm[p]][perm[nb]];\n                }\n                \n                double acceptProb = delta >= 0 ? 1.0 : exp(delta / temp);\n                if (dist(rng) < acceptProb) {\n                    int oldSeed = perm[p];\n                    perm[p] = s;\n                    unselectedSeeds[idx] = unselectedSeeds.back();\n                    unselectedSeeds.pop_back();\n                    unselectedSeeds.push_back(oldSeed);\n                    for (int k = 0; k < grid_size; k++) {\n                        if (k != p) {\n                            ep[p][k] = ep[k][p] = allEP[s][perm[k]];\n                        }\n                    }\n                }\n            } else {\n                int p1 = posDist(rng);\n                int p2 = posDist(rng);\n                if (p1 == p2) continue;\n                \n                int delta = 0;\n                for (int nb : nbrs[p1]) {\n                    if (nb != p2) delta += ep[p2][nb] - ep[p1][nb];\n                }\n                for (int nb : nbrs[p2]) {\n                    if (nb != p1) delta += ep[p1][nb] - ep[p2][nb];\n                }\n                \n                double acceptProb = delta >= 0 ? 1.0 : exp(delta / temp);\n                if (dist(rng) < acceptProb) {\n                    swap(perm[p1], perm[p2]);\n                    swap(ep[p1], ep[p2]);\n                    for (int k = 0; k < grid_size; k++) {\n                        swap(ep[k][p1], ep[k][p2]);\n                    }\n                }\n            }\n            temp *= cooling;\n        }\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << perm[i * N + j];\n                if (j < N - 1) cout << \" \";\n                else cout << \"\\n\";\n            }\n        }\n        cout.flush();\n\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    }\n\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint dx[] = {0, 1, 0, -1};\nint dy[] = {1, 0, -1, 0};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, V;\n    cin >> N >> M >> V;\n    \n    vector<string> s(N), t(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    cout << V << \"\\n\";\n    for (int i = 1; i < V; i++) cout << 0 << \" \" << 1 << \"\\n\";\n    \n    int rx = 0, ry = 0;\n    cout << rx << \" \" << ry << \"\\n\";\n    \n    vector<int> dir(V, 0);\n    for (int i = 1; i < V; i++) dir[i] = (i - 1) % 4;\n    \n    string S1(V * 2, '.'), S2(V * 2, '.');\n    for (int i = 1; i < V; i++) {\n        int d = dir[i];\n        if (d == 1) S1[i] = 'R';\n        else if (d == 2) { S1[i] = 'R'; S2[i] = 'R'; }\n        else if (d == 3) S1[i] = 'L';\n    }\n    \n    int initialTurns = 0;\n    if (S1.find_first_not_of('.') != string::npos) { cout << S1 << \"\\n\"; initialTurns++; }\n    if (S2.find_first_not_of('.') != string::npos) { cout << S2 << \"\\n\"; initialTurns++; }\n    \n    vector<bool> holding(V, false);\n    \n    set<pair<int,int>> srcSet, dstSet;\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') srcSet.insert({i, j});\n            if (s[i][j] == '0' && t[i][j] == '1') dstSet.insert({i, j});\n        }\n    \n    auto inGrid = [&](int x, int y) { return x >= 0 && x < N && y >= 0 && y < N; };\n    \n    int maxTurns = 100000 - initialTurns;\n    int vertDir = 1, horizDir = 1;\n    \n    for (int turn = 0; turn < maxTurns && (!srcSet.empty() || !dstSet.empty()); turn++) {\n        string S(V * 2, '.');\n        \n        char move = '.';\n        if (horizDir == 1 && ry < N - 1) move = 'R';\n        else if (horizDir == -1 && ry > 0) move = 'L';\n        else if (vertDir == 1 && rx < N - 1) { move = 'D'; horizDir *= -1; }\n        else if (vertDir == -1 && rx > 0) { move = 'U'; horizDir *= -1; }\n        else {\n            vertDir *= -1;\n            horizDir *= -1;\n            cout << S << \"\\n\";\n            continue;\n        }\n        \n        S[0] = move;\n        if (move == 'D') rx++;\n        else if (move == 'U') rx--;\n        else if (move == 'L') ry--;\n        else if (move == 'R') ry++;\n        \n        // Phase 1: Deliver (with rotation to reach destinations)\n        for (int i = 1; i < V; i++) {\n            if (!holding[i]) continue;\n            \n            int fx = rx + dx[dir[i]], fy = ry + dy[dir[i]];\n            if (inGrid(fx, fy) && dstSet.count({fx, fy})) {\n                S[V + i] = 'P'; holding[i] = false; dstSet.erase({fx, fy});\n                continue;\n            }\n            \n            for (int rot : {1, 3}) {\n                int newDir = (dir[i] + rot) % 4;\n                fx = rx + dx[newDir]; fy = ry + dy[newDir];\n                if (inGrid(fx, fy) && dstSet.count({fx, fy})) {\n                    S[i] = rot == 1 ? 'R' : 'L';\n                    dir[i] = newDir;\n                    S[V + i] = 'P'; holding[i] = false; dstSet.erase({fx, fy});\n                    break;\n                }\n            }\n        }\n        \n        // Phase 2: Pickup (no rotation to preserve directions)\n        for (int i = 1; i < V; i++) {\n            if (holding[i]) continue;\n            int fx = rx + dx[dir[i]], fy = ry + dy[dir[i]];\n            if (inGrid(fx, fy) && srcSet.count({fx, fy})) {\n                S[V + i] = 'P'; holding[i] = true; srcSet.erase({fx, fy});\n            }\n        }\n        \n        cout << S << \"\\n\";\n    }\n    \n    return 0;\n}","ahc039":"#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;\n    cin >> N;\n    \n    vector<int> mx(N), my(N), sx(N), sy(N);\n    for (int i = 0; i < N; i++) cin >> mx[i] >> my[i];\n    for (int i = 0; i < N; i++) cin >> sx[i] >> sy[i];\n    \n    auto count_rect = [&](int x1, int y1, int x2, int y2) -> int {\n        int net = 0;\n        for (int i = 0; i < N; i++) if (mx[i] >= x1 && mx[i] <= x2 && my[i] >= y1 && my[i] <= y2) net++;\n        for (int i = 0; i < N; i++) if (sx[i] >= x1 && sx[i] <= x2 && sy[i] >= y1 && sy[i] <= y2) net--;\n        return net;\n    };\n    \n    vector<tuple<int,int,int,int,int>> candidates;\n    \n    auto try_rect = [&](int x1, int y1, int x2, int y2) {\n        x1 = max(0, x1); y1 = max(0, y1);\n        x2 = min(100000, x2); y2 = min(100000, y2);\n        if (x2 <= x1 || y2 <= y1) return;\n        int actual = count_rect(x1, y1, x2, y2);\n        if (actual > 0) candidates.push_back({actual, x1, y1, x2, y2});\n    };\n    \n    auto fine_search = [&](int cx1, int cy1, int cx2, int cy2) {\n        set<int> x_set, y_set;\n        x_set.insert(cx1); x_set.insert(cx2); y_set.insert(cy1); y_set.insert(cy2);\n        for (int i = 0; i < 2*N; i++) {\n            int x = (i<N)?mx[i]:sx[i], y = (i<N)?my[i]:sy[i];\n            if (x >= cx1 && x <= cx2) { x_set.insert(max(0,x-1)); x_set.insert(x); x_set.insert(min(100000,x+1)); }\n            if (y >= cy1 && y <= cy2) { y_set.insert(max(0,y-1)); y_set.insert(y); y_set.insert(min(100000,y+1)); }\n        }\n        vector<int> all_x(x_set.begin(),x_set.end()), all_y(y_set.begin(),y_set.end());\n        int nx = all_x.size(), ny = all_y.size();\n        if (nx < 2 || ny < 2) return;\n        \n        long long total = (long long)nx * ny;\n        int MAX_SZ = (total < 300000) ? 100000 : (total < 600000) ? 1000 : (total < 1200000) ? 700 : (total < 2500000) ? 500 : 350;\n        \n        auto subsample = [&](vector<int>& v) {\n            if ((int)v.size() <= MAX_SZ) return;\n            vector<int> t;\n            int step = ((int)v.size() + MAX_SZ - 1) / MAX_SZ;\n            for (int i = 0; i < (int)v.size(); i += step) t.push_back(v[i]);\n            if (t.back() != v.back()) t.push_back(v.back());\n            v = t;\n        };\n        subsample(all_x); subsample(all_y);\n        nx = all_x.size(); ny = all_y.size();\n        if (nx < 2 || ny < 2) return;\n        \n        vector<vector<int>> fg(nx, vector<int>(ny, 0));\n        for (int i = 0; i < N; i++) { \n            int xi = lower_bound(all_x.begin(),all_x.end(),mx[i])-all_x.begin(); \n            int yi = lower_bound(all_y.begin(),all_y.end(),my[i])-all_y.begin(); \n            if(xi<nx && yi<ny && all_x[xi]==mx[i] && all_y[yi]==my[i]) fg[xi][yi]++; \n        }\n        for (int i = 0; i < N; i++) { \n            int xi = lower_bound(all_x.begin(),all_x.end(),sx[i])-all_x.begin(); \n            int yi = lower_bound(all_y.begin(),all_y.end(),sy[i])-all_y.begin(); \n            if(xi<nx && yi<ny && all_x[xi]==sx[i] && all_y[yi]==sy[i]) fg[xi][yi]--; \n        }\n        \n        int fb = 0, fx1 = 0, fx2 = 0, fy1 = 0, fy2 = 0;\n        for (int x1 = 0; x1 < nx; x1++) { \n            vector<int> col(ny, 0); \n            for (int x2 = x1; x2 < nx; x2++) { \n                for (int y = 0; y < ny; y++) col[y] += fg[x2][y]; \n                int cur = 0, start = 0; \n                for (int y = 0; y < ny; y++) { \n                    if (cur <= 0) { cur = col[y]; start = y; } else cur += col[y]; \n                    if (cur > fb) { fb = cur; fx1 = x1; fx2 = x2; fy1 = start; fy2 = y; } \n                } \n            } \n        }\n        \n        if (fb > 0 && fx2 > fx1 && fy2 > fy1) {\n            try_rect(max(0,all_x[fx1]), max(0,all_y[fy1]), min(100000,all_x[fx2]), min(100000,all_y[fy2]));\n        }\n    };\n    \n    auto grid_search = [&](int GRID, int CELL) {\n        auto cell = [&](int x) { return min(x / CELL, GRID - 1); };\n        vector<vector<int>> grid(GRID, vector<int>(GRID, 0));\n        for (int i = 0; i < N; i++) grid[cell(mx[i])][cell(my[i])]++;\n        for (int i = 0; i < N; i++) grid[cell(sx[i])][cell(sy[i])]--;\n        \n        int best = 0, bx1 = 0, bx2 = 0, by1 = 0, by2 = 0;\n        for (int x1 = 0; x1 < GRID; x1++) {\n            vector<int> col(GRID, 0);\n            for (int x2 = x1; x2 < GRID; x2++) {\n                for (int y = 0; y < GRID; y++) col[y] += grid[x2][y];\n                int cur = 0, start = 0;\n                for (int y = 0; y < GRID; y++) {\n                    if (cur <= 0) { cur = col[y]; start = y; } else cur += col[y];\n                    if (cur > best) { best = cur; bx1 = x1; bx2 = x2; by1 = start; by2 = y; }\n                }\n            }\n        }\n        if (best <= 0) return;\n        \n        int cx1 = bx1 * CELL, cy1 = by1 * CELL;\n        int cx2 = min((bx2 + 1) * CELL - 1, 100000), cy2 = min((by2 + 1) * CELL - 1, 100000);\n        try_rect(cx1, cy1, cx2, cy2);\n        fine_search(cx1, cy1, cx2, cy2);\n    };\n    \n    grid_search(25, 4001);\n    grid_search(40, 2501);\n    grid_search(60, 1667);\n    grid_search(80, 1251);\n    grid_search(100, 1001);\n    grid_search(125, 801);\n    grid_search(150, 667);\n    grid_search(200, 501);\n    grid_search(250, 401);\n    \n    sort(candidates.begin(), candidates.end());\n    candidates.erase(unique(candidates.begin(), candidates.end()), candidates.end());\n    sort(candidates.rbegin(), candidates.rend());\n    if (candidates.size() > 5) candidates.resize(5);\n    \n    int best_score = 0, best_x1 = 0, best_y1 = 0, best_x2 = 1, best_y2 = 1;\n    \n    for (auto& [init_score, init_x1, init_y1, init_x2, init_y2] : candidates) {\n        int cs = init_score, cx1 = init_x1, cy1 = init_y1, cx2 = init_x2, cy2 = init_y2;\n        \n        for (int iter = 0; iter < 25; iter++) {\n            int px1 = cx1, py1 = cy1, px2 = cx2, py2 = cy2;\n            \n            for (int i = 0; i < 2*N; i++) {\n                int x = (i < N) ? mx[i] : sx[i], y = (i < N) ? my[i] : sy[i];\n                if (x >= cx1 - 100 && x <= cx1 + 100 && x >= 0 && x < cx2) { int ns = count_rect(x, cy1, cx2, cy2); if (ns > cs) { cs = ns; cx1 = x; } }\n                if (x >= cx2 - 100 && x <= cx2 + 100 && x > cx1 && x <= 100000) { int ns = count_rect(cx1, cy1, x, cy2); if (ns > cs) { cs = ns; cx2 = x; } }\n                if (y >= cy1 - 100 && y <= cy1 + 100 && y >= 0 && y < cy2) { int ns = count_rect(cx1, y, cx2, cy2); if (ns > cs) { cs = ns; cy1 = y; } }\n                if (y >= cy2 - 100 && y <= cy2 + 100 && y > cy1 && y <= 100000) { int ns = count_rect(cx1, cy1, cx2, y); if (ns > cs) { cs = ns; cy2 = y; } }\n            }\n            if (cx1 == px1 && cy1 == py1 && cx2 == px2 && cy2 == py2) break;\n        }\n        \n        // Expand search: try including nearby mackerels\n        for (int i = 0; i < N; i++) {\n            bool inside = (mx[i] >= cx1 && mx[i] <= cx2 && my[i] >= cy1 && my[i] <= cy2);\n            if (!inside && mx[i] >= cx1 - 200 && mx[i] <= cx2 + 200 && my[i] >= cy1 - 200 && my[i] <= cy2 + 200) {\n                int ns = count_rect(min(cx1, mx[i]), min(cy1, my[i]), max(cx2, mx[i]), max(cy2, my[i]));\n                if (ns > cs) { cs = ns; cx1 = min(cx1, mx[i]); cy1 = min(cy1, my[i]); cx2 = max(cx2, mx[i]); cy2 = max(cy2, my[i]); }\n            }\n        }\n        \n        if (cs > best_score) { best_score = cs; best_x1 = cx1; best_y1 = cy1; best_x2 = cx2; best_y2 = cy2; }\n    }\n    \n    best_x1 = max(0, best_x1); best_y1 = max(0, best_y1);\n    best_x2 = min(100000, best_x2); best_y2 = min(100000, best_y2);\n    if (best_x2 <= best_x1) best_x2 = best_x1 + 1;\n    if (best_y2 <= best_y1) best_y2 = best_y1 + 1;\n    \n    if (best_score <= 0) { cout << \"4\\n0 0\\n1 0\\n1 1\\n0 1\\n\"; }\n    else { cout << 4 << \"\\n\" << best_x1 << \" \" << best_y1 << \"\\n\" << best_x2 << \" \" << best_y1 << \"\\n\" << best_x2 << \" \" << best_y2 << \"\\n\" << best_x1 << \" \" << best_y2 << \"\\n\"; }\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    auto start_time = chrono::high_resolution_clock::now();\n    auto get_elapsed = [&]() {\n        return chrono::duration<double>(chrono::high_resolution_clock::now() - start_time).count();\n    };\n    \n    int N, T;\n    double sigma;\n    cin >> N >> T >> sigma;\n    \n    vector<double> w(N), h(N);\n    for (int i = 0; i < N; i++) {\n        int wo, ho;\n        cin >> wo >> ho;\n        w[i] = wo;\n        h[i] = ho;\n    }\n    \n    double w_ratio = 1.0, h_ratio = 1.0;\n    \n    for (int t = 0; t < T; t++) {\n        double elapsed = get_elapsed();\n        \n        vector<double> aw(N), ah(N);\n        for (int i = 0; i < N; i++) {\n            aw[i] = w[i] * w_ratio;\n            ah[i] = h[i] * h_ratio;\n        }\n        \n        vector<tuple<int,int,char,int>> solution;\n        double final_W = 0, final_H = 0;\n        \n        auto greedy_solve = [&]() {\n            vector<tuple<double,double,double,double,int>> placed;\n            solution.clear();\n            double placed_sum = 0;\n            \n            auto find_y = [&](double x, double ww) -> double {\n                double y = 0;\n                for (auto& [px,py,pw,ph,idx] : placed)\n                    if (px < x+ww && x < px+pw) y = max(y, py+ph);\n                return y;\n            };\n            auto find_x = [&](double y, double hh) -> double {\n                double x = 0;\n                for (auto& [px,py,pw,ph,idx] : placed)\n                    if (py < y+hh && y < py+ph) x = max(x, px+pw);\n                return x;\n            };\n            auto get_ref_x = [&](int idx) -> double {\n                for (auto& [px,py,pw,ph,i] : placed) if (i==idx) return px+pw;\n                return 0.0;\n            };\n            auto get_ref_y = [&](int idx) -> double {\n                for (auto& [px,py,pw,ph,i] : placed) if (i==idx) return py+ph;\n                return 0.0;\n            };\n            \n            for (int i = 0; i < N; i++) {\n                double best_score = 1e18;\n                int best_rot = 0; char best_d = 'U'; int best_b = -1;\n                \n                for (int rot = 0; rot < 2; rot++) {\n                    double rw = rot ? ah[i] : aw[i], rh = rot ? aw[i] : ah[i];\n                    auto try_place = [&](double x, double y, char d, int b) {\n                        double W = x+rw, H = y+rh;\n                        for (auto& [px,py,pw,ph,idx] : placed) { W = max(W,px+pw); H = max(H,py+ph); }\n                        double cost = W + H - placed_sum - (aw[i] + ah[i]);\n                        if (cost < best_score) { best_score = cost; best_rot = rot; best_d = d; best_b = b; }\n                    };\n                    try_place(0, find_y(0,rw), 'U', -1);\n                    for (auto& [px,py,pw,ph,idx] : placed)\n                        try_place(px+pw, find_y(px+pw,rw), 'U', idx);\n                    try_place(find_x(0,rh), 0, 'L', -1);\n                    for (auto& [px,py,pw,ph,idx] : placed)\n                        try_place(find_x(py+ph,rh), py+ph, 'L', idx);\n                }\n                \n                double cur_W = 0, cur_H = 0;\n                for (auto& [px,py,pw,ph,idx] : placed) { cur_W = max(cur_W, px+pw); cur_H = max(cur_H, py+ph); }\n                double skip_cost = cur_W + cur_H - placed_sum;\n                if (skip_cost < best_score) continue;\n                \n                double rw = best_rot ? ah[i] : aw[i], rh = best_rot ? aw[i] : ah[i];\n                double x, y;\n                if (best_d == 'U') { x = best_b==-1 ? 0 : get_ref_x(best_b); y = find_y(x,rw); }\n                else { y = best_b==-1 ? 0 : get_ref_y(best_b); x = find_x(y,rh); }\n                placed.emplace_back(x, y, rw, rh, i);\n                placed_sum += aw[i] + ah[i];\n                solution.emplace_back(i, best_rot, best_d, best_b);\n            }\n            final_W = 0; final_H = 0;\n            for (auto& [px,py,pw,ph,idx] : placed) { final_W = max(final_W, px+pw); final_H = max(final_H, py+ph); }\n        };\n        \n        if (elapsed > 2.2) {\n            greedy_solve();\n        } else {\n            // Adaptive beam width based on N and elapsed time\n            double time_per_item = (elapsed > 0.01) ? elapsed / ((t + 1) * N) : 0.0001;\n            int BEAM, MAX_OPTS;\n            \n            if (elapsed < 0.8) { BEAM = 25; MAX_OPTS = 6; }\n            else if (elapsed < 1.2) { BEAM = 20; MAX_OPTS = 5; }\n            else if (elapsed < 1.5) { BEAM = 16; MAX_OPTS = 5; }\n            else if (elapsed < 1.8) { BEAM = 12; MAX_OPTS = 4; }\n            else if (elapsed < 2.0) { BEAM = 10; MAX_OPTS = 4; }\n            else { BEAM = 8; MAX_OPTS = 3; }\n            \n            // Reduce for large N\n            if (N > 70) { BEAM = min(BEAM, 18); MAX_OPTS = min(MAX_OPTS, 5); }\n            if (N > 85) { BEAM = min(BEAM, 14); MAX_OPTS = min(MAX_OPTS, 4); }\n            \n            struct State {\n                int parent, idx, rot, ref;\n                char dir;\n                double placed_sum, W, H, x, y, rw, rh;\n                bool skipped;\n            };\n            \n            vector<State> states;\n            states.reserve(N * BEAM * (MAX_OPTS + 1));\n            states.push_back({-1, -1, 0, -1, 'U', 0, 0, 0, 0, 0, 0, 0, true});\n            vector<int> beam = {0};\n            \n            for (int i = 0; i < N; i++) {\n                vector<pair<double, int>> candidates;\n                candidates.reserve(beam.size() * (MAX_OPTS + 1));\n                \n                for (int bi : beam) {\n                    vector<tuple<double,double,double,double,int>> placed;\n                    for (int cur = bi; cur != -1 && states[cur].idx >= 0; cur = states[cur].parent) {\n                        auto& s = states[cur];\n                        if (!s.skipped) placed.emplace_back(s.x, s.y, s.rw, s.rh, s.idx);\n                    }\n                    reverse(placed.begin(), placed.end());\n                    \n                    auto& st = states[bi];\n                    double new_sum = st.placed_sum + aw[i] + ah[i];\n                    \n                    // Skip option\n                    double skip_cost = st.W + st.H - st.placed_sum;\n                    candidates.push_back({skip_cost, (int)states.size()});\n                    states.push_back({bi, i, 0, -1, 'U', st.placed_sum, st.W, st.H, 0, 0, 0, 0, true});\n                    \n                    vector<tuple<double,double,double,int,char,int>> opts;\n                    opts.reserve(2 * (placed.size() + 1) + 2);\n                    \n                    for (int rot = 0; rot < 2; rot++) {\n                        double rw = rot ? ah[i] : aw[i], rh = rot ? aw[i] : ah[i];\n                        auto find_y = [&](double x, double ww) -> double {\n                            double y = 0;\n                            for (auto& [px,py,pw,ph,idx] : placed)\n                                if (px < x+ww && x < px+pw) y = max(y, py+ph);\n                            return y;\n                        };\n                        auto find_x = [&](double y, double hh) -> double {\n                            double x = 0;\n                            for (auto& [px,py,pw,ph,idx] : placed)\n                                if (py < y+hh && y < py+ph) x = max(x, px+pw);\n                            return x;\n                        };\n                        \n                        auto add_opt = [&](double x, double y, char d, int b) {\n                            double nW = max(st.W, x+rw), nH = max(st.H, y+rh);\n                            double cost = nW + nH - new_sum;\n                            opts.emplace_back(cost, x, y, rot, d, b);\n                        };\n                        \n                        add_opt(0, find_y(0,rw), 'U', -1);\n                        for (auto& [px,py,pw,ph,idx] : placed)\n                            add_opt(px+pw, find_y(px+pw,rw), 'U', idx);\n                        add_opt(find_x(0,rh), 0, 'L', -1);\n                        for (auto& [px,py,pw,ph,idx] : placed)\n                            add_opt(find_x(py+ph,rh), py+ph, 'L', idx);\n                    }\n                    \n                    sort(opts.begin(), opts.end());\n                    opts.erase(unique(opts.begin(), opts.end()), opts.end());\n                    \n                    int kept = min((int)opts.size(), MAX_OPTS);\n                    for (int j = 0; j < kept; j++) {\n                        auto& [cost, x, y, rot, d, b] = opts[j];\n                        double rw = rot ? ah[i] : aw[i], rh = rot ? aw[i] : ah[i];\n                        double nW = max(st.W, x+rw), nH = max(st.H, y+rh);\n                        candidates.push_back({cost, (int)states.size()});\n                        states.push_back({bi, i, rot, b, d, new_sum, nW, nH, x, y, rw, rh, false});\n                    }\n                }\n                \n                int select = min(BEAM, (int)candidates.size());\n                partial_sort(candidates.begin(), candidates.begin() + select, candidates.end());\n                candidates.resize(select);\n                beam.clear();\n                beam.reserve(select);\n                for (auto& [c, idx] : candidates) beam.push_back(idx);\n            }\n            \n            for (int cur = beam[0]; cur != -1 && states[cur].idx >= 0; cur = states[cur].parent) {\n                auto& s = states[cur];\n                if (!s.skipped) solution.push_back({s.idx, s.rot, s.dir, s.ref});\n            }\n            reverse(solution.begin(), solution.end());\n            final_W = states[beam[0]].W;\n            final_H = states[beam[0]].H;\n        }\n        \n        cout << solution.size() << \"\\n\";\n        for (auto& [idx, rot, dir, ref] : solution)\n            cout << idx << \" \" << rot << \" \" << dir << \" \" << ref << \"\\n\";\n        cout.flush();\n        \n        int W_meas, H_meas;\n        cin >> W_meas >> H_meas;\n        \n        if (final_W > 0 && final_H > 0 && !solution.empty()) {\n            double wr = W_meas / final_W;\n            double hr = H_meas / final_H;\n            // Adaptive learning: higher rate when measurement is reliable\n            double noise_w = sigma / final_W;\n            double noise_h = sigma / final_H;\n            double alpha = 0.35 / (1 + t * 0.02 + 10 * (noise_w * noise_w + noise_h * noise_h));\n            w_ratio = w_ratio * (1 - alpha) + wr * alpha;\n            h_ratio = h_ratio * (1 - alpha) + hr * alpha;\n        }\n    }\n    \n    return 0;\n}","ahc041":"#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, H;\n    cin >> N >> M >> H;\n    \n    vector<int> A(N);\n    for (int i = 0; i < N; i++) cin >> A[i];\n    \n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    \n    vector<int> tmp(N);\n    for (int i = 0; i < N; i++) cin >> tmp[i] >> tmp[i];\n    \n    vector<vector<int>> dist_mat(N, vector<int>(N, H + 1));\n    for (int s = 0; s < N; s++) {\n        dist_mat[s][s] = 0;\n        queue<int> q;\n        q.push(s);\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int v : adj[u]) {\n                if (dist_mat[s][v] == H + 1) {\n                    dist_mat[s][v] = dist_mat[s][u] + 1;\n                    q.push(v);\n                }\n            }\n        }\n    }\n    \n    vector<bitset<1000>> cover(N);\n    vector<vector<int>> cover_list(N);\n    for (int v = 0; v < N; v++) {\n        for (int u = 0; u < N; u++) {\n            if (dist_mat[v][u] <= H) {\n                cover[v].set(u);\n                cover_list[v].push_back(u);\n            }\n        }\n    }\n    \n    vector<vector<int>> dist2(N);\n    for (int v = 0; v < N; v++) {\n        set<int> s;\n        for (int u : adj[v]) {\n            s.insert(u);\n            for (int w : adj[u]) s.insert(w);\n        }\n        dist2[v].assign(s.begin(), s.end());\n        sort(dist2[v].begin(), dist2[v].end(), [&](int a, int b) { return A[a] < A[b]; });\n    }\n    \n    auto is_valid = [&](const vector<bool>& is_root) -> bool {\n        bitset<1000> covered;\n        for (int v = 0; v < N; v++) if (is_root[v]) covered |= cover[v];\n        return covered.count() == N;\n    };\n    \n    auto compute_score = [&](const vector<bool>& is_root) -> long long {\n        vector<int> roots; for (int v = 0; v < N; v++) if (is_root[v]) roots.push_back(v);\n        long long score = 0;\n        for (int v = 0; v < N; v++) {\n            int min_d = H + 1;\n            for (int u : roots) min_d = min(min_d, dist_mat[v][u]);\n            if (min_d <= H) score += (long long)(min_d + 1) * A[v];\n        }\n        return score;\n    };\n    \n    auto simple_local_search = [&](vector<bool>& is_root) -> void {\n        vector<int> cnt(N, 0);\n        for (int v = 0; v < N; v++) if (is_root[v]) for (int u : cover_list[v]) cnt[u]++;\n        vector<int> rl; for (int v = 0; v < N; v++) if (is_root[v]) rl.push_back(v);\n        sort(rl.begin(), rl.end(), [&](int a, int b) { return A[a] > A[b]; });\n        bool ch = true;\n        while (ch) { ch = false; for (int v : rl) { if (!is_root[v]) continue; bool can = true;\n            for (int u : cover_list[v]) if (cnt[u] <= 1) { can = false; break; }\n            if (can) { is_root[v] = false; for (int u : cover_list[v]) cnt[u]--; ch = true; } } }\n    };\n    \n    auto full_local_search = [&](vector<bool>& is_root) -> void {\n        vector<int> cnt(N, 0);\n        for (int v = 0; v < N; v++) if (is_root[v]) for (int u : cover_list[v]) cnt[u]++;\n        auto rem = [&]() { vector<int> rl; for (int v = 0; v < N; v++) if (is_root[v]) rl.push_back(v);\n            sort(rl.begin(), rl.end(), [&](int a, int b) { return A[a] > A[b]; });\n            bool ch = true; while (ch) { ch = false; for (int v : rl) { if (!is_root[v]) continue; bool can = true;\n                for (int u : cover_list[v]) if (cnt[u] <= 1) { can = false; break; }\n                if (can) { is_root[v] = false; for (int u : cover_list[v]) cnt[u]--; ch = true; } } } };\n        auto sw = [&](int v, int u) -> bool { if (is_root[u] || A[u] >= A[v]) return false;\n            for (int w : cover_list[v]) cnt[w]--; bool ok = true;\n            for (int w : cover_list[u]) if (cnt[w] <= 0) { ok = false; break; }\n            if (ok) { for (int w : cover_list[u]) cnt[w]++; is_root[v] = false; is_root[u] = true; return true; }\n            for (int w : cover_list[v]) cnt[w]++; return false; };\n        rem();\n        bool ch = true; while (ch) { ch = false; vector<int> rl; for (int v = 0; v < N; v++) if (is_root[v]) rl.push_back(v);\n            sort(rl.begin(), rl.end(), [&](int a, int b) { return A[a] > A[b]; });\n            for (int v : rl) { if (!is_root[v]) continue; for (int u : dist2[v]) if (sw(v,u)) { ch = true; break; } if (ch) break; }\n            if (ch) rem(); }\n        for (int sc = 0; sc < 100; sc++) { bool done = false;\n            vector<int> rl; for (int v = 0; v < N; v++) if (is_root[v]) rl.push_back(v);\n            sort(rl.begin(), rl.end(), [&](int a, int b) { return A[a] > A[b]; });\n            vector<int> nr; for (int v = 0; v < N; v++) if (!is_root[v]) nr.push_back(v);\n            sort(nr.begin(), nr.end(), [&](int a, int b) { return A[a] < A[b]; });\n            for (int v : rl) { for (int u : nr) if (sw(v,u)) { done = true; rem(); break; } if (done) break; }\n            if (!done) break; }\n        // Add-and-remove phase\n        for (int ar = 0; ar < 100; ar++) {\n            vector<int> nr; for (int v = 0; v < N; v++) if (!is_root[v]) nr.push_back(v);\n            sort(nr.begin(), nr.end(), [&](int a, int b) { return A[a] < A[b]; });\n            bool done = false;\n            for (int u : nr) {\n                is_root[u] = true; for (int w : cover_list[u]) cnt[w]++;\n                vector<int> rl; for (int v = 0; v < N; v++) if (is_root[v] && A[v] > A[u]) rl.push_back(v);\n                sort(rl.begin(), rl.end(), [&](int a, int b) { return A[a] > A[b]; });\n                for (int v : rl) { bool can = true;\n                    for (int w : cover_list[v]) if (cnt[w] <= 1) { can = false; break; }\n                    if (can) { is_root[v] = false; for (int w : cover_list[v]) cnt[w]--;\n                        done = true; break; } }\n                if (done) break;\n                is_root[u] = false; for (int w : cover_list[u]) cnt[w]--;\n            }\n            if (!done) break;\n            rem();\n        }\n    };\n    \n    mt19937 rng(42);\n    vector<bool> best_roots(N, false);\n    long long best_score = -1;\n    \n    for (int trial = 0; trial < 100; trial++) {\n        bitset<1000> unc; for (int i = 0; i < N; i++) unc.set(i);\n        vector<bool> ir(N, false);\n        while (unc.any()) { int bc = 0; vector<int> cands;\n            for (int v = 0; v < N; v++) { int c = (cover[v] & unc).count();\n                if (c > bc) { bc = c; cands = {v}; } else if (c == bc) cands.push_back(v); }\n            if (bc == 0) break;\n            uniform_int_distribution<int> d(0, cands.size()-1); int ch = cands[d(rng)];\n            ir[ch] = true; unc &= ~cover[ch]; }\n        simple_local_search(ir);\n        long long sc = compute_score(ir);\n        if (sc > best_score) { best_score = sc; best_roots = ir; }\n    }\n    \n    full_local_search(best_roots);\n    \n    for (int iter = 0; iter < 100; iter++) {\n        int bv = -1, bu = -1; long long bns = compute_score(best_roots); bool do_swap = false;\n        for (int v = 0; v < N; v++) { if (!best_roots[v]) continue; best_roots[v] = false;\n            if (is_valid(best_roots)) { long long ns = compute_score(best_roots);\n                if (ns > bns) { bns = ns; bv = v; bu = -1; do_swap = false; } } best_roots[v] = true; }\n        for (int v = 0; v < N; v++) { if (!best_roots[v]) continue;\n            for (int u : dist2[v]) { if (best_roots[u]) continue; best_roots[v] = false; best_roots[u] = true;\n                if (is_valid(best_roots)) { long long ns = compute_score(best_roots);\n                    if (ns > bns) { bns = ns; bv = v; bu = u; do_swap = true; } }\n                best_roots[v] = true; best_roots[u] = false; } }\n        if (bv == -1) break; best_roots[bv] = false; if (do_swap) best_roots[bu] = true;\n    }\n    \n    vector<int> parent(N, -1), height(N, -1); queue<int> q;\n    for (int v = 0; v < N; v++) if (best_roots[v]) { height[v] = 0; q.push(v); }\n    while (!q.empty()) { int u = q.front(); q.pop();\n        for (int v : adj[u]) if (height[v] == -1 && height[u] < H) { height[v] = height[u] + 1; parent[v] = u; q.push(v); } }\n    for (int v = 0; v < N; v++) if (height[v] == -1) { height[v] = 0; q.push(v);\n        while (!q.empty()) { int u = q.front(); q.pop();\n            for (int w : adj[u]) if (height[w] == -1 && height[u] < H) { height[w] = height[u] + 1; parent[w] = u; q.push(w); } } }\n    for (int v = 0; v < N; v++) { cout << parent[v]; if (v < N - 1) cout << \" \"; }\n    cout << \"\\n\";\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N; cin >> N;\n    vector<string> board(N);\n    for (int i = 0; i < N; i++) cin >> board[i];\n    \n    vector<int> fmin_r(N,N), fmax_r(N,-1), fmin_c(N,N), fmax_c(N,-1);\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (board[i][j]=='o') {\n        fmin_r[i]=min(fmin_r[i],j); fmax_r[i]=max(fmax_r[i],j);\n        fmin_c[j]=min(fmin_c[j],i); fmax_c[j]=max(fmax_c[j],i);\n    }\n    \n    map<pair<int,int>,int> col_ops, row_ops;\n    \n    for (int i = 0; i < N; i++) {\n        vector<array<int,5>> row_onis; // j, col_d, col_dist, row_d, row_dist\n        bool has_only_col = false, has_only_row = false;\n        \n        for (int j = 0; j < N; j++) if (board[i][j]=='x') {\n            array<int,5> ro = {j, -1, N+1, -1, N+1};\n            if (fmin_c[j]>i||fmin_c[j]==N) { int d=i+1; if(d<ro[2]){ro[2]=d;ro[1]=0;} }\n            if (fmax_c[j]<i||fmax_c[j]==-1) { int d=N-i; if(d<ro[2]){ro[2]=d;ro[1]=1;} }\n            if (fmin_r[i]>j||fmin_r[i]==N) { int d=j+1; if(d<ro[4]){ro[4]=d;ro[3]=2;} }\n            if (fmax_r[i]<j||fmax_r[i]==-1) { int d=N-j; if(d<ro[4]){ro[4]=d;ro[3]=3;} }\n            if (ro[1]>=0 && ro[3]<0) has_only_col = true;\n            if (ro[1]<0 && ro[3]>=0) has_only_row = true;\n            row_onis.push_back(ro);\n        }\n        \n        bool use_col = !(has_only_row) || has_only_col;\n        \n        for (auto& ro : row_onis) {\n            if (use_col && ro[1]>=0) col_ops[{ro[0], ro[1]}] = max(col_ops[{ro[0], ro[1]}], ro[2]);\n            else if (!use_col && ro[3]>=0) row_ops[{i, ro[3]}] = max(row_ops[{i, ro[3]}], ro[4]);\n        }\n    }\n    \n    const char* fwd = \"UDLR\", *rev = \"DULR\";\n    for (auto& [key, dist] : col_ops) {\n        auto [idx, d] = key;\n        for (int t = 0; t < dist; t++) cout << fwd[d] << \" \" << idx << \"\\n\";\n        for (int t = 0; t < dist; t++) cout << rev[d] << \" \" << idx << \"\\n\";\n    }\n    for (auto& [key, dist] : row_ops) {\n        auto [idx, d] = key;\n        for (int t = 0; t < dist; t++) cout << fwd[d] << \" \" << idx << \"\\n\";\n        for (int t = 0; t < dist; t++) cout << rev[d] << \" \" << idx << \"\\n\";\n    }\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\npair<int, pair<vector<int>, vector<int>>> solve(int N, int L, const vector<int>& T, unsigned seed) {\n    mt19937 rng(seed);\n    \n    vector<int> a(N, -1), b(N, -1);\n    vector<int> cnt(N, 0);\n    cnt[0] = 1;\n    \n    vector<int> remain = T;\n    remain[0]--;\n    \n    vector<double> in_est(N, 0);\n    \n    auto choose = [&](int current, int week) -> int {\n        double half_flow = T[current] / 2.0;\n        int remaining_weeks = L - week + 1;\n        \n        vector<pair<double, int>> candidates;\n        for (int i = 0; i < N; i++) {\n            if (i == current || remain[i] <= 0) continue;\n            double expected = (double)T[i] * (week - 1) / L;\n            double deficit = expected - cnt[i];\n            int unavoidable = max(0, remain[i] - remaining_weeks);\n            double room = T[i] - in_est[i] - half_flow;\n            double score = deficit + unavoidable * 1e6 + 0.005 * room;\n            candidates.push_back({score, i});\n        }\n        if (candidates.empty()) return current;\n        \n        sort(candidates.rbegin(), candidates.rend());\n        \n        if (seed == 0) return candidates[0].second;\n        \n        double threshold = candidates[0].first - 0.15;\n        vector<int> top;\n        for (auto& [score, idx] : candidates) {\n            if (score >= threshold) top.push_back(idx);\n        }\n        return top[uniform_int_distribution<int>(0, (int)top.size()-1)(rng)];\n    };\n    \n    int current = 0;\n    for (int week = 2; week <= L; week++) {\n        int k = cnt[current];\n        int next;\n        if (k % 2 == 1) {\n            if (a[current] == -1) {\n                a[current] = choose(current, week);\n                in_est[a[current]] += T[current] / 2.0;\n            }\n            next = a[current];\n        } else {\n            if (b[current] == -1) {\n                b[current] = choose(current, week);\n                in_est[b[current]] += T[current] / 2.0;\n            }\n            next = b[current];\n        }\n        cnt[next]++;\n        remain[next]--;\n        current = next;\n    }\n    \n    int error = 0;\n    for (int i = 0; i < N; i++) error += abs(cnt[i] - T[i]);\n    return {error, {a, b}};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, L;\n    cin >> N >> L;\n    \n    vector<int> T(N);\n    for (int i = 0; i < N; i++) cin >> T[i];\n    \n    int best_error = INT_MAX;\n    vector<int> best_a, best_b;\n    \n    for (int seed = 0; seed < 50; seed++) {\n        auto [error, ab] = solve(N, L, T, seed);\n        if (error < best_error) {\n            best_error = error;\n            best_a = ab.first;\n            best_b = ab.second;\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        if (best_a[i] == -1) best_a[i] = 0;\n        if (best_b[i] == -1) best_b[i] = 0;\n        cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    vector<int> parent, sz;\n    DSU(int n) : parent(n), sz(n, 1) { 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) return false;\n        if (sz[x] < sz[y]) swap(x, y);\n        parent[y] = x; sz[x] += sz[y]; return true;\n    }\n};\n\nint N, M, Q, L, W;\nvector<int> G, cx, cy;\ndouble estDist(int i, int j) { double dx=cx[i]-cx[j], dy=cy[i]-cy[j]; return sqrt(dx*dx+dy*dy); }\n\nvector<pair<int,int>> doQuery(vector<int>& cities) {\n    cout << \"? \" << cities.size();\n    for (int c : cities) cout << \" \" << c;\n    cout << \"\\n\" << flush;\n    vector<pair<int,int>> edges(cities.size() - 1);\n    for (int i = 0; i < (int)cities.size() - 1; i++) cin >> edges[i].first >> edges[i].second;\n    return edges;\n}\n\nvoid primMST(vector<int>& cities, vector<pair<int,int>>& edges) {\n    int n = cities.size();\n    if (n <= 1) return;\n    vector<double> minDist(n, 1e18);\n    vector<int> parent(n, -1);\n    vector<bool> inMST(n, false);\n    minDist[0] = 0;\n    for (int i = 0; i < n; i++) {\n        int u = -1;\n        for (int j = 0; j < n; j++) {\n            if (!inMST[j] && (u == -1 || minDist[j] < minDist[u])) u = j;\n        }\n        inMST[u] = true;\n        if (parent[u] != -1)\n            edges.push_back({min(cities[parent[u]], cities[u]), max(cities[parent[u]], cities[u])});\n        for (int v = 0; v < n; v++) {\n            if (!inMST[v]) {\n                double d = estDist(cities[u], cities[v]);\n                if (d < minDist[v]) { minDist[v] = d; parent[v] = u; }\n            }\n        }\n    }\n}\n\nvoid findMSTHierarchical(vector<int>& cities, vector<pair<int,int>>& edges, int& queriesLeft) {\n    int n = cities.size();\n    if (n <= 1) return;\n    if (n == 2) { edges.push_back({min(cities[0],cities[1]), max(cities[0],cities[1])}); return; }\n    sort(cities.begin(), cities.end(), [](int a, int b) { return cx[a]!=cx[b] ? cx[a]<cx[b] : cy[a]<cy[b]; });\n    if (n <= L && queriesLeft > 0) { auto r = doQuery(cities); edges.insert(edges.end(), r.begin(), r.end()); queriesLeft--; return; }\n    if (n <= L || queriesLeft <= 0) { primMST(cities, edges); return; }\n    \n    vector<vector<int>> chunks;\n    for (int i = 0; i < n; i += L) {\n        vector<int> chunk;\n        for (int j = i; j < min(i+L, n); j++) chunk.push_back(cities[j]);\n        chunks.push_back(chunk);\n    }\n    \n    vector<vector<pair<int,int>>> chunkMSTs;\n    for (auto& chunk : chunks) {\n        int sz = chunk.size();\n        if (sz >= 2 && queriesLeft > 0) {\n            chunkMSTs.push_back(doQuery(chunk));\n            edges.insert(edges.end(), chunkMSTs.back().begin(), chunkMSTs.back().end());\n            queriesLeft--;\n        } else if (sz >= 2) {\n            vector<pair<int,int>> primEdges;\n            primMST(chunk, primEdges);\n            edges.insert(edges.end(), primEdges.begin(), primEdges.end());\n            chunkMSTs.push_back(primEdges);\n        } else {\n            chunkMSTs.push_back({});\n        }\n    }\n    \n    vector<int> reps;\n    for (int i = 0; i < (int)chunks.size(); i++) {\n        auto& chunk = chunks[i];\n        auto& mst = chunkMSTs[i];\n        if (chunk.size() == 1) reps.push_back(chunk[0]);\n        else if (!mst.empty()) {\n            map<int,int> deg;\n            for (auto& [u,v] : mst) { deg[u]++; deg[v]++; }\n            int bestRep = chunk[0], maxDeg = 0;\n            for (int c : chunk) if (deg[c] > maxDeg) { maxDeg = deg[c]; bestRep = c; }\n            reps.push_back(bestRep);\n        } else reps.push_back(chunk[0]);\n    }\n    findMSTHierarchical(reps, edges, queriesLeft);\n}\n\nvoid findMSTSlidingWindow(vector<int>& cities, vector<pair<int,int>>& edges, int& queriesLeft) {\n    int n = cities.size();\n    if (n <= 1) return;\n    if (n == 2) { edges.push_back({min(cities[0],cities[1]), max(cities[0],cities[1])}); return; }\n    \n    sort(cities.begin(), cities.end(), [](int a, int b) { \n        return cx[a]!=cx[b] ? cx[a]<cx[b] : cy[a]<cy[b]; \n    });\n    \n    if (n <= L && queriesLeft > 0) {\n        auto r = doQuery(cities);\n        edges.insert(edges.end(), r.begin(), r.end());\n        queriesLeft--;\n        return;\n    }\n    \n    if (n <= L || queriesLeft <= 0) {\n        primMST(cities, edges);\n        return;\n    }\n    \n    int overlap = 1;\n    int step = L - overlap;\n    int numQueries = (n - L + step - 1) / step + 1;\n    \n    if (queriesLeft < numQueries) {\n        findMSTHierarchical(cities, edges, queriesLeft);\n        return;\n    }\n    \n    vector<pair<int,int>> allEdges;\n    for (int i = 0; i < numQueries; i++) {\n        int start = i * step;\n        int end = min(start + L, n);\n        if (end - start < 2) break;\n        vector<int> window(cities.begin() + start, cities.begin() + end);\n        auto r = doQuery(window);\n        allEdges.insert(allEdges.end(), r.begin(), r.end());\n        queriesLeft--;\n    }\n    \n    unordered_map<int, int> cityToIdx;\n    for (int i = 0; i < n; i++) cityToIdx[cities[i]] = i;\n    \n    DSU dsu(n);\n    int edgeCount = 0;\n    for (auto& [u, v] : allEdges) {\n        int ui = cityToIdx[u], vi = cityToIdx[v];\n        if (dsu.unite(ui, vi)) {\n            edges.push_back({min(u, v), max(u, v)});\n            edgeCount++;\n        }\n    }\n    \n    if (edgeCount < n - 1) {\n        edges.clear();\n        primMST(cities, edges);\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M); for (int i=0;i<M;i++) cin>>G[i];\n    cx.resize(N); cy.resize(N);\n    for (int i=0;i<N;i++) { int lx,rx,ly,ry; cin>>lx>>rx>>ly>>ry; cx[i]=(lx+rx)/2; cy[i]=(ly+ry)/2; }\n    \n    double centroidX = 0, centroidY = 0;\n    for (int i = 0; i < N; i++) { centroidX += cx[i]; centroidY += cy[i]; }\n    centroidX /= N; centroidY /= N;\n    int startCity = 0; double minDistToCentroid = 1e18;\n    for (int i = 0; i < N; i++) {\n        double d = (cx[i] - centroidX) * (cx[i] - centroidX) + (cy[i] - centroidY) * (cy[i] - centroidY);\n        if (d < minDistToCentroid) { minDistToCentroid = d; startCity = i; }\n    }\n    \n    vector<tuple<double,int,int>> allEdges;\n    for (int i=0;i<N;i++) for (int j=i+1;j<N;j++) allEdges.push_back({estDist(i,j),i,j});\n    sort(allEdges.begin(), allEdges.end());\n    DSU dsu(N); vector<tuple<double,int,int>> mstEdges;\n    for (auto& [d,u,v] : allEdges) { if(dsu.unite(u,v)) mstEdges.push_back({d,u,v}); if((int)mstEdges.size()==N-1) break; }\n    \n    vector<vector<int>> adj(N);\n    for (auto& [d,u,v] : mstEdges) { adj[u].push_back(v); adj[v].push_back(u); }\n    \n    vector<int> dfsOrder; vector<bool> vis(N,false);\n    function<void(int)> dfs = [&](int u) {\n        vis[u]=true; dfsOrder.push_back(u);\n        vector<pair<double,int>> nb; for (int v:adj[u]) if(!vis[v]) nb.push_back({estDist(u,v),v});\n        sort(nb.begin(), nb.end());\n        for (auto& [d,v]:nb) if(!vis[v]) dfs(v);\n    };\n    dfs(startCity);\n    for (int i = 0; i < N; i++) if (!vis[i]) dfsOrder.push_back(i);\n    \n    vector<vector<int>> groups(M); int idx=0;\n    for (int i=0;i<M;i++) for (int j=0;j<G[i];j++) groups[i].push_back(dfsOrder[idx++]);\n    \n    vector<int> gOrder(M); iota(gOrder.begin(),gOrder.end(),0);\n    sort(gOrder.begin(),gOrder.end(),[](int a,int b){return G[a]>G[b];});\n    \n    int queriesLeft = Q; vector<vector<pair<int,int>>> allEdgesOut(M);\n    for (int gi : gOrder) findMSTSlidingWindow(groups[gi], allEdgesOut[gi], queriesLeft);\n    \n    cout << \"!\\n\";\n    for (int i=0;i<M;i++) {\n        for (int j=0;j<(int)groups[i].size();j++) { if(j>0) cout<<\" \"; cout<<groups[i][j]; }\n        cout<<\"\\n\";\n        for (auto& e : allEdgesOut[i]) cout<<e.first<<\" \"<<e.second<<\"\\n\";\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nbool grid[20][20];\nint ci, cj;\nvector<string> actions;\n\nint dx[] = {-1, 1, 0, 0};\nint dy[] = {0, 0, -1, 1};\nchar dirChar[] = {'U', 'D', 'L', 'R'};\n\nbool inBounds(int i, int j) { return i >= 0 && i < N && j >= 0 && j < N; }\n\nvoid addMove(int d) {\n    actions.push_back(string(\"M \") + dirChar[d]);\n    ci += dx[d]; cj += dy[d];\n}\n\nvoid addSlide(int d) {\n    actions.push_back(string(\"S \") + dirChar[d]);\n    while (inBounds(ci + dx[d], cj + dy[d]) && !grid[ci + dx[d]][cj + dy[d]]) {\n        ci += dx[d]; cj += dy[d];\n    }\n}\n\npair<int,int> getSlideDest(int d) {\n    int ni = ci, nj = cj;\n    while (inBounds(ni + dx[d], nj + dy[d]) && !grid[ni + dx[d]][nj + dy[d]]) {\n        ni += dx[d]; nj += dy[d];\n    }\n    return make_pair(ni, nj);\n}\n\nvoid postVisitSlide(int nti, int ntj) {\n    if (nti == -1) return;\n    while (true) {\n        int bestDir = -1, bestSavings = 0;  // Changed from 1 to 0\n        for (int d = 0; d < 4; d++) {\n            pair<int,int> dest = getSlideDest(d);\n            if (dest.first == ci && dest.second == cj) continue;\n            int curDist = abs(ci - nti) + abs(cj - ntj);\n            int newDist = abs(dest.first - nti) + abs(dest.second - ntj);\n            int savings = curDist - newDist - 1;\n            if (savings > bestSavings) { bestSavings = savings; bestDir = d; }\n        }\n        if (bestDir >= 0) addSlide(bestDir);\n        else break;\n    }\n}\n\nvoid goTo(int ti, int tj) {\n    bool onTop = (ti == 0), onBot = (ti == N-1), onLeft = (tj == 0), onRight = (tj == N-1);\n    bool isEdge = onTop || onBot || onLeft || onRight;\n    while (ci != ti || cj != tj) {\n        bool slid = false;\n        if (cj == tj && ci != ti) {\n            int sd = -1;\n            if (onTop && ci > ti) sd = 0;\n            else if (onBot && ci < ti) sd = 1;\n            if (sd >= 0 && getSlideDest(sd).first == ti) { addSlide(sd); slid = true; }\n        }\n        if (!slid && ci == ti && cj != tj) {\n            int sd = -1;\n            if (onLeft && cj > tj) sd = 2;\n            else if (onRight && cj < tj) sd = 3;\n            if (sd >= 0 && getSlideDest(sd).second == tj) { addSlide(sd); slid = true; }\n        }\n        if (slid) continue;\n        int manh = abs(ci - ti) + abs(cj - tj), bestDir = -1, bestSave = 0;\n        if (isEdge) {\n            if ((onTop || onBot) && cj != tj) {\n                int s = abs(ci - ti) - 1;\n                if (s > bestSave && abs(cj - tj) < manh) { bestSave = s; bestDir = (cj < tj) ? 3 : 2; }\n            }\n            if ((onLeft || onRight) && ci != ti) {\n                int s = abs(cj - tj) - 1;\n                if (s > bestSave && abs(ci - ti) < manh) { bestSave = s; bestDir = (ci < ti) ? 1 : 0; }\n            }\n        }\n        if (bestDir == -1) bestDir = (ci < ti) ? 1 : (ci > ti) ? 0 : (cj < tj) ? 3 : 2;\n        addMove(bestDir);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N >> M >> ci >> cj;\n    int numT = M - 1;\n    vector<pair<int,int>> tgt(numT);\n    for (int i = 0; i < numT; i++) cin >> tgt[i].first >> tgt[i].second;\n    memset(grid, 0, sizeof(grid));\n    \n    // Initial position slide towards first target\n    postVisitSlide(tgt[0].first, tgt[0].second);\n    \n    for (int i = 0; i < numT; i++) {\n        goTo(tgt[i].first, tgt[i].second);\n        postVisitSlide(i+1 < numT ? tgt[i+1].first : -1, i+1 < numT ? tgt[i+1].second : -1);\n    }\n    for (const auto& a : actions) cout << a << \"\\n\";\n}"}}}