{"model_name":"kimi-k2-0905","codes":{"1":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nstruct Rect {\n    int a, b, c, d;\n    ll area() const { return (ll)(c - a) * (d - b); }\n    bool contains(double x, double y) const {\n        return a <= x && x <= c && b <= y && y <= d;\n    }\n};\n\nstruct Company {\n    int x, y, r;\n    Rect rect;\n    double desired_x, desired_y;\n};\n\nint n;\nvector<Company> companies;\n\ndouble compute_pi(const Company& co) {\n    double dx = co.desired_x, dy = co.desired_y;\n    if (!co.rect.contains(dx, dy)) return 0.0;\n    ll s = co.rect.area();\n    ll ri = co.r;\n    if (s == ri) return 1.0;\n    double ratio = min((double)s, (double)ri) / max((double)s, (double)ri);\n    return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n}\n\nbool is_overlap(const Rect& r1, const Rect& r2) {\n    return !(r1.c <= r2.a || r2.c <= r1.a || r1.d <= r2.b || r2.d <= r1.b);\n}\n\nvoid resolve_overlaps() {\n    // Simple greedy overlap resolution: shrink rectangles randomly\n    for (int i = 0; i < n; ++i) {\n        for (int j = i + 1; j < n; ++j) {\n            auto& ri = companies[i].rect;\n            auto& rj = companies[j].rect;\n            if (!is_overlap(ri, rj)) continue;\n            // Shrink the one with larger area\n            if (ri.area() > rj.area()) {\n                // Shrink ri\n                ll target = companies[i].r;\n                ll current = ri.area();\n                if (current > target) {\n                    ll reduce = (current - target + 1) / 2;\n                    // Try to reduce from right or top\n                    if (ri.c - ri.a > ri.d - ri.b) {\n                        ri.c = max(ri.c - (int)reduce, ri.a + 1);\n                    } else {\n                        ri.d = max(ri.d - (int)reduce, ri.b + 1);\n                    }\n                }\n            } else {\n                // Shrink rj\n                ll target = companies[j].r;\n                ll current = rj.area();\n                if (current > target) {\n                    ll reduce = (current - target + 1) / 2;\n                    if (rj.c - rj.a > rj.d - rj.b) {\n                        rj.c = max(rj.c - (int)reduce, rj.a + 1);\n                    } else {\n                        rj.d = max(rj.d - (int)reduce, rj.b + 1);\n                    }\n                }\n            }\n        }\n    }\n}\n\nvoid initial_placement() {\n    for (int i = 0; i < n; ++i) {\n        auto& co = companies[i];\n        co.desired_x = co.x + 0.5;\n        co.desired_y = co.y + 0.5;\n        // Start with minimal rect containing desired point\n        co.rect = {co.x, co.y, co.x + 1, co.y + 1};\n        // Expand to r_i if possible\n        ll target = co.r;\n        ll current = 1;\n        int expand_steps = 0;\n        while (current < target && expand_steps < 10000) {\n            expand_steps++;\n            // Prefer expanding in the direction with more space\n            int dx = co.rect.c - co.rect.a;\n            int dy = co.rect.d - co.rect.b;\n            if (dx < dy) {\n                if (co.rect.c < 10000) {\n                    co.rect.c++;\n                    current += dy;\n                } else if (co.rect.a > 0) {\n                    co.rect.a--;\n                    current += dy;\n                } else if (co.rect.d < 10000) {\n                    co.rect.d++;\n                    current += dx;\n                } else if (co.rect.b > 0) {\n                    co.rect.b--;\n                    current += dx;\n                } else break;\n            } else {\n                if (co.rect.d < 10000) {\n                    co.rect.d++;\n                    current += dx;\n                } else if (co.rect.b > 0) {\n                    co.rect.b--;\n                    current += dx;\n                } else if (co.rect.c < 10000) {\n                    co.rect.c++;\n                    current += dy;\n                } else if (co.rect.a > 0) {\n                    co.rect.a--;\n                    current += dy;\n                } else break;\n            }\n        }\n    }\n}\n\nvoid optimize() {\n    // Hill climbing: try to adjust rectangles to improve score\n    const int iterations = 1000;\n    for (int iter = 0; iter < iterations; ++iter) {\n        for (int i = 0; i < n; ++i) {\n            auto& co = companies[i];\n            double best_pi = compute_pi(co);\n            Rect best_rect = co.rect;\n            // Try small adjustments\n            for (int da = -1; da <= 1; ++da) {\n                for (int db = -1; db <= 1; ++db) {\n                    for (int dc = -1; dc <= 1; ++dc) {\n                        for (int dd = -1; dd <= 1; ++dd) {\n                            if (da == 0 && db == 0 && dc == 0 && dd == 0) continue;\n                            Rect tmp = co.rect;\n                            tmp.a += da; tmp.b += db; tmp.c += dc; tmp.d += dd;\n                            if (tmp.a >= tmp.c || tmp.b >= tmp.d) continue;\n                            if (tmp.a < 0 || tmp.b < 0 || tmp.c > 10000 || tmp.d > 10000) continue;\n                            // Check overlap\n                            bool ok = true;\n                            for (int j = 0; j < n; ++j) {\n                                if (i == j) continue;\n                                if (is_overlap(tmp, companies[j].rect)) {\n                                    ok = false;\n                                    break;\n                                }\n                            }\n                            if (!ok) continue;\n                            // Check if desired point is inside\n                            if (!tmp.contains(co.desired_x, co.desired_y)) continue;\n                            // Compute new pi\n                            co.rect = tmp;\n                            double new_pi = compute_pi(co);\n                            if (new_pi > best_pi) {\n                                best_pi = new_pi;\n                                best_rect = tmp;\n                            }\n                        }\n                    }\n                }\n            }\n            co.rect = best_rect;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> n;\n    companies.resize(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> companies[i].x >> companies[i].y >> companies[i].r;\n    }\n\n    initial_placement();\n    resolve_overlaps();\n    optimize();\n\n    for (int i = 0; i < n; ++i) {\n        const auto& r = companies[i].rect;\n        cout << r.a << ' ' << r.b << ' ' << r.c << ' ' << r.d << '\\n';\n    }\n\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nint si, sj;\nint t[50][50];\nint p[50][50];\nint M;                       // number of distinct tiles\nvector<vector<pair<int,int>>> tileSquares; // tile id -> its squares\nint bestScore;\nstring bestPath;\n\n// 4 directions\nconst int dx[4] = {-1,1,0,0};\nconst int dy[4] = {0,0,-1,1};\nconst char dc[4] = {'U','D','L','R'};\n\n// order of directions, we will shuffle it sometimes\nint order[4] = {0,1,2,3};\n\nvoid dfs(int i, int j, vector<bool>& used, int score, string& path, int depth){\n    if(score > bestScore){\n        bestScore = score;\n        bestPath = path;\n    }\n    // try neighbours\n    for(int k = 0; k < 4; k++){\n        int d = order[k];\n        int ni = i + dx[d];\n        int nj = j + dy[d];\n        if(ni<0||ni>=50||nj<0||nj>=50) continue;\n        int nt = t[ni][nj];\n        if(used[nt]) continue;\n        // step on this tile\n        used[nt] = true;\n        path.push_back(dc[d]);\n        dfs(ni, nj, used, score + p[ni][nj], path, depth+1);\n        path.pop_back();\n        used[nt] = false;\n    }\n}\n\nstring solveOne(int starti, int startj){\n    bestScore = p[starti][startj];\n    bestPath.clear();\n    vector<bool> used(M, false);\n    used[t[starti][startj]] = true;\n    string path;\n    dfs(starti, startj, used, bestScore, path, 0);\n    return bestPath;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> si >> sj;\n    for(int i=0;i<50;i++)for(int j=0;j<50;j++) cin >> t[i][j];\n    for(int i=0;i<50;i++)for(int j=0;j<50;j++) cin >> p[i][j];\n\n    // build tileSquares and find M\n    int maxt = 0;\n    for(int i=0;i<50;i++)for(int j=0;j<50;j++) maxt = max(maxt, t[i][j]);\n    M = maxt + 1;\n    tileSquares.assign(M, {});\n    for(int i=0;i<50;i++)for(int j=0;j<50;j++) tileSquares[t[i][j]].emplace_back(i,j);\n\n    // try both squares of the initial tile (if 2 squares)\n    vector<pair<int,int>> starts;\n    int st = t[si][sj];\n    for(auto [i,j]: tileSquares[st]) starts.emplace_back(i,j);\n\n    string globalBest;\n    int globalScore = -1;\n\n    // several random restarts with shuffled direction order\n    for(int rep=0; rep<10; rep++){\n        // shuffle direction order\n        shuffle(order, order+4, mt19937(rep));\n        for(auto [i,j]: starts){\n            string cand = solveOne(i, j);\n            if(bestScore > globalScore){\n                globalScore = bestScore;\n                globalBest = cand;\n            }\n        }\n    }\n    cout << globalBest << '\\n';\n    return 0;\n}","ahc003":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <string>\n#include <algorithm>\n#include <cmath>\n#include <iomanip>\n#include <unordered_map>\n\nusing namespace std;\n\nconst int GRID_SIZE = 30;\nconst int NUM_QUERIES = 1000;\n\n// Directions: U, D, L, R\nconst int dr[] = {-1, 1, 0, 0};\nconst int dc[] = {0, 0, -1, 1};\nconst char dir_chars[] = {'U', 'D', 'L', 'R'};\n\nstruct Edge {\n    int r1, c1, r2, c2;\n    double length;\n    int count;\n    double sum_observed;\n\n    Edge(int r1, int c1, int r2, int c2) : r1(r1), c1(c1), r2(r2), c2(c2), length(5000.0), count(0), sum_observed(0.0) {}\n};\n\nvector<vector<Edge>> horizontal_edges; // horizontal_edges[i][j] is between (i,j) and (i,j+1)\nvector<vector<Edge>> vertical_edges;   // vertical_edges[i][j] is between (i,j) and (i+1,j)\n\nvoid initialize_edges() {\n    horizontal_edges.resize(GRID_SIZE, vector<Edge>(GRID_SIZE - 1));\n    vertical_edges.resize(GRID_SIZE - 1, vector<Edge>(GRID_SIZE));\n\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        for (int j = 0; j < GRID_SIZE - 1; ++j) {\n            horizontal_edges[i][j] = Edge(i, j, i, j + 1);\n        }\n    }\n    for (int i = 0; i < GRID_SIZE - 1; ++i) {\n        for (int j = 0; j < GRID_SIZE; ++j) {\n            vertical_edges[i][j] = Edge(i, j, i + 1, j);\n        }\n    }\n}\n\nstring generate_manhattan_path(int si, int sj, int ti, int tj) {\n    string path;\n    int dr = ti - si;\n    int dc = tj - sj;\n    if (dr > 0) {\n        path += string(dr, 'D');\n    } else {\n        path += string(-dr, 'U');\n    }\n    if (dc > 0) {\n        path += string(dc, 'R');\n    } else {\n        path += string(-dc, 'L');\n    }\n    return path;\n}\n\nvector<pair<int, int>> parse_path(int si, int sj, const string& path) {\n    vector<pair<int, int>> vertices;\n    int r = si, c = sj;\n    vertices.emplace_back(r, c);\n    for (char d : path) {\n        if (d == 'U') r--;\n        else if (d == 'D') r++;\n        else if (d == 'L') c--;\n        else if (d == 'R') c++;\n        vertices.emplace_back(r, c);\n    }\n    return vertices;\n}\n\ndouble compute_path_length(const vector<pair<int, int>>& vertices) {\n    double length = 0.0;\n    for (int i = 0; i + 1 < vertices.size(); ++i) {\n        int r1 = vertices[i].first, c1 = vertices[i].second;\n        int r2 = vertices[i + 1].first, c2 = vertices[i + 1].second;\n        if (r1 == r2 && abs(c1 - c2) == 1) {\n            int j = min(c1, c2);\n            length += horizontal_edges[r1][j].length;\n        } else if (c1 == c2 && abs(r1 - r2) == 1) {\n            int i = min(r1, r2);\n            length += vertical_edges[i][c1].length;\n        } else {\n            // invalid edge\n            length += 1e9;\n        }\n    }\n    return length;\n}\n\nvoid update_edges(const vector<pair<int, int>>& vertices, int observed) {\n    double observed_length = observed;\n    // De-noise: assume the true length is around observed / 1.0 (since noise is 0.9-1.1)\n    // But we can average over multiple observations\n    for (int i = 0; i + 1 < vertices.size(); ++i) {\n        int r1 = vertices[i].first, c1 = vertices[i].second;\n        int r2 = vertices[i + 1].first, c2 = vertices[i + 1].second;\n        Edge* edge = nullptr;\n        if (r1 == r2 && abs(c1 - c2) == 1) {\n            int j = min(c1, c2);\n            edge = &horizontal_edges[r1][j];\n        } else if (c1 == c2 && abs(r1 - r2) == 1) {\n            int i = min(r1, r2);\n            edge = &vertical_edges[i][c1];\n        }\n        if (edge) {\n            edge->count++;\n            edge->sum_observed += observed_length;\n            edge->length = edge->sum_observed / edge->count;\n        }\n    }\n}\n\nstring dijkstra(int si, int sj, int ti, int tj) {\n    // Dijkstra's algorithm to find the shortest path in the current estimates\n    vector<vector<double>> dist(GRID_SIZE, vector<double>(GRID_SIZE, 1e18));\n    vector<vector<pair<int, int>>> parent(GRID_SIZE, vector<pair<int, int>>(GRID_SIZE, {-1, -1}));\n    priority_queue<pair<double, pair<int, int>>, vector<pair<double, pair<int, int>>>, greater<pair<double, pair<int, int>>>> pq;\n    dist[si][sj] = 0.0;\n    pq.push({0.0, {si, sj}});\n\n    while (!pq.empty()) {\n        auto [d, pos] = pq.top(); pq.pop();\n        int r = pos.first, c = pos.second;\n        if (d > dist[r][c]) continue;\n        if (r == ti && c == tj) break;\n\n        for (int k = 0; k < 4; ++k) {\n            int nr = r + dr[k], nc = c + dc[k];\n            if (nr < 0 || nr >= GRID_SIZE || nc < 0 || nc >= GRID_SIZE) continue;\n            double edge_len = 0.0;\n            if (k == 0) { // U\n                edge_len = vertical_edges[nr][nc].length;\n            } else if (k == 1) { // D\n                edge_len = vertical_edges[r][c].length;\n            } else if (k == 2) { // L\n                edge_len = horizontal_edges[r][nc].length;\n            } else if (k == 3) { // R\n                edge_len = horizontal_edges[r][c].length;\n            }\n            if (dist[nr][nc] > d + edge_len) {\n                dist[nr][nc] = d + edge_len;\n                parent[nr][nc] = {r, c};\n                pq.push({dist[nr][nc], {nr, nc}});\n            }\n        }\n    }\n\n    // Reconstruct path\n    string path;\n    int r = ti, c = tj;\n    while (parent[r][c].first != -1) {\n        int pr = parent[r][c].first, pc = parent[r][c].second;\n        if (pr == r - 1) path += 'D';\n        else if (pr == r + 1) path += 'U';\n        else if (pc == c - 1) path += 'R';\n        else if (pc == c + 1) path += 'L';\n        r = pr; c = pc;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    initialize_edges();\n\n    for (int k = 0; k < NUM_QUERIES; ++k) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n\n        string path;\n        if (k < 100) {\n            // Early queries: use Manhattan path for exploration\n            path = generate_manhattan_path(si, sj, ti, tj);\n        } else {\n            // Later queries: use Dijkstra with current estimates\n            path = dijkstra(si, sj, ti, tj);\n            if (path.empty()) {\n                // Fallback to Manhattan if Dijkstra fails\n                path = generate_manhattan_path(si, sj, ti, tj);\n            }\n        }\n\n        cout << path << endl;\n        cout.flush();\n\n        int observed;\n        cin >> observed;\n        auto vertices = parse_path(si, sj, path);\n        update_edges(vertices, observed);\n    }\n\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\n#include \"atcoder/xoshiro256.h\"\nusing namespace std;\nusing ll = long long;\n\nstatic const int N = 20;\nstatic const int AL = 8;          // A..H\nstatic const char LET[] = \"ABCDEFGH\";\nstatic atcoder::xoshiro256 rng;\n\nint M;\nvector<string> S;\nint bestC;\nvector<string> bestGrid;\nint evalCalls = 0;\n\n// ---------- evaluation ----------\ninline int index(char c) { return c - 'A'; }\n\n// returns number of matched strings\nint evaluate(const vector<string>& g) {\n    ++evalCalls;\n    int cnt = 0;\n    for (const auto& s : S) {\n        int L = (int)s.size();\n        bool ok = false;\n        // horizontal\n        for (int i = 0; i < N && !ok; ++i) {\n            for (int st = 0; st < N; ++st) {\n                bool match = true;\n                for (int p = 0; p < L; ++p) {\n                    if (g[i][(st + p) % N] != s[p]) { match = false; break; }\n                }\n                if (match) { ok = true; break; }\n            }\n        }\n        if (ok) { ++cnt; continue; }\n        // vertical\n        for (int j = 0; j < N && !ok; ++j) {\n            for (int st = 0; st < N; ++st) {\n                bool match = true;\n                for (int p = 0; p < L; ++p) {\n                    if (g[(st + p) % N][j] != s[p]) { match = false; break; }\n                }\n                if (match) { ok = true; break; }\n            }\n        }\n        if (ok) ++cnt;\n    }\n    return cnt;\n}\n\n// ---------- utility ----------\nint fillCount(const vector<string>& g) {\n    int c = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (g[i][j] != '.') ++c;\n    return c;\n}\n\nvoid printGrid(const vector<string>& g) {\n    for (const auto& row : g) cout << row << '\\n';\n}\n\n// ---------- random grid ----------\nvector<string> randomGrid() {\n    vector<string> g(N, string(N, '.'));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            g[i][j] = LET[rng() % AL];\n    return g;\n}\n\n// ---------- mutation ----------\n// change one cell\nvoid mutate1(vector<string>& g) {\n    int i = rng() % N;\n    int j = rng() % N;\n    char old = g[i][j];\n    // with 10 % chance try '.' once c==M\n    char nu;\n    if (bestC == M && rng() % 10 == 0) {\n        nu = '.';\n    } else {\n        nu = LET[rng() % AL];\n    }\n    g[i][j] = nu;\n    int c = evaluate(g);\n    if (c > bestC || (c == bestC && rng() % 2)) {\n        bestC = c;\n        bestGrid = g;\n    } else {\n        g[i][j] = old;\n    }\n}\n\n// fix an entire row to a random string that needs it\nvoid mutateRow(vector<string>& g) {\n    int i = rng() % N;\n    string old = g[i];\n    // pick a random unsatisfied string\n    static vector<int> unsat;\n    unsat.clear();\n    for (int idx = 0; idx < M; ++idx) {\n        // quick check: does it fit in row i?\n        bool any = false;\n        const string& s = S[idx];\n        int L = s.size();\n        for (int st = 0; st < N; ++st) {\n            bool ok = true;\n            for (int p = 0; p < L; ++p)\n                if (g[i][(st + p) % N] != s[p]) { ok = false; break; }\n            if (ok) { any = true; break; }\n        }\n        if (!any) unsat.push_back(idx);\n    }\n    if (unsat.empty()) return;\n    int pick = unsat[rng() % unsat.size()];\n    const string& tgt = S[pick];\n    int L = tgt.size();\n    int st = rng() % N;\n    for (int p = 0; p < L; ++p)\n        g[i][(st + p) % N] = tgt[p];\n    int c = evaluate(g);\n    if (c > bestC || (c == bestC && rng() % 2)) {\n        bestC = c;\n        bestGrid = g;\n    } else {\n        g[i] = old;\n    }\n}\n\n// ---------- main ----------\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M;\n    S.resize(M);\n    for (int i = 0; i < M; ++i) cin >> S[i];\n\n    bestGrid = randomGrid();\n    bestC = evaluate(bestGrid);\n\n    // Hill-climb with random walks\n    const double TIME_LIMIT = 2.8;\n    auto start = chrono::steady_clock::now();\n    int iter = 0;\n    while (true) {\n        ++iter;\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > TIME_LIMIT) break;\n\n        // once we reach M, try to fill more\n        if (bestC < M) {\n            if (rng() % 4 == 0) mutateRow(bestGrid);\n            else                  mutate1(bestGrid);\n        } else {\n            // maximize fill\n            mutate1(bestGrid);\n        }\n    }\n\n    // final greedy fill pass\n    if (bestC == M) {\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                if (bestGrid[i][j] == '.') {\n                    for (char c : LET) {\n                        bestGrid[i][j] = c;\n                        if (evaluate(bestGrid) == M) break;\n                    }\n                    if (bestGrid[i][j] == '.') {\n                        // revert\n                        bestGrid[i][j] = '.';\n                    }\n                }\n    }\n\n    printGrid(bestGrid);\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 70;\nconst int INF = 1e9;\n\nint N, si, sj;\nchar grid[MAXN][MAXN];\nint cost[MAXN][MAXN];\nbool is_road[MAXN][MAXN];\n\n// Visibility: vis[i][j] = set of squares visible from (i,j)\n// We store it as a bitset per position, but we can't store 70x70x70x70 bits.\n// Instead, we precompute for each (i,j) the list of visible squares, and\n// we will use a global coverage bitset.\n\n// We will represent coverage as a 1D bitset: flatten (i,j) -> i*N + j\nbitset<MAXN*MAXN> coverage;\nbitset<MAXN*MAXN> vis_from[MAXN][MAXN]; // vis_from[i][j]: what is visible from (i,j)\n\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\nchar move_char[] = {'U', 'D', 'L', 'R'};\n\n// Precompute visibility from every position\nvoid precompute_visibility() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (!is_road[i][j]) continue;\n            auto &bs = vis_from[i][j];\n            // Row left\n            for (int jj = j; jj >= 0; jj--) {\n                if (!is_road[i][jj]) break;\n                bs.set(i*N + jj);\n            }\n            // Row right\n            for (int jj = j; jj < N; jj++) {\n                if (!is_road[i][jj]) break;\n                bs.set(i*N + jj);\n            }\n            // Col up\n            for (int ii = i; ii >= 0; ii--) {\n                if (!is_road[ii][j]) break;\n                bs.set(ii*N + j);\n            }\n            // Col down\n            for (int ii = i; ii < N; ii++) {\n                if (!is_road[ii][j]) break;\n                bs.set(ii*N + j);\n            }\n        }\n    }\n}\n\n// Dijkstra state: (cost, r, c)\nusing State = tuple<int, int, int>;\n\n// Find shortest path from (sr,sc) to (tr,tc) with move costs\nvector<pair<int,int>> shortest_path(int sr, int sc, int tr, int tc) {\n    static int dist[MAXN][MAXN];\n    static pair<int,int> parent[MAXN][MAXN];\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            dist[i][j] = INF;\n        }\n    }\n    priority_queue<State, vector<State>, greater<State>> pq;\n    dist[sr][sc] = 0;\n    parent[sr][sc] = {-1, -1};\n    pq.emplace(0, sr, sc);\n    while (!pq.empty()) {\n        auto [d, r, c] = pq.top(); pq.pop();\n        if (d > dist[r][c]) continue;\n        if (r == tr && c == tc) break;\n        for (int k = 0; k < 4; k++) {\n            int nr = r + dr[k], nc = c + dc[k];\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n            if (!is_road[nr][nc]) continue;\n            int nd = d + cost[nr][nc];\n            if (nd < dist[nr][nc]) {\n                dist[nr][nc] = nd;\n                parent[nr][nc] = {r, c};\n                pq.emplace(nd, nr, nc);\n            }\n        }\n    }\n    if (dist[tr][tc] == INF) return {};\n    vector<pair<int,int>> path;\n    int r = tr, c = tc;\n    while (r != -1) {\n        path.emplace_back(r, c);\n        auto [pr, pc] = parent[r][c];\n        r = pr; c = pc;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n// Convert path to move string\nstring path_to_moves(const vector<pair<int,int>>& path) {\n    string seq;\n    for (int i = 1; i < path.size(); i++) {\n        int dr = path[i].first - path[i-1].first;\n        int dc = path[i].second - path[i-1].second;\n        if (dr == -1) seq += 'U';\n        else if (dr == 1) seq += 'D';\n        else if (dc == -1) seq += 'L';\n        else if (dc == 1) seq += 'R';\n    }\n    return seq;\n}\n\n// Greedy coverage: always go to the nearest position that sees the most unseen squares per unit cost\nstring greedy_cover() {\n    coverage.reset();\n    int r = si, c = sj;\n    string route;\n\n    // Initial coverage\n    coverage |= vis_from[r][c];\n\n    int total_road = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (is_road[i][j]) total_road++;\n        }\n    }\n\n    while (coverage.count() < total_road) {\n        // Find best next position\n        int best_nr = -1, best_nc = -1;\n        double best_score = -1;\n        int best_cost = INF;\n\n        // Candidate: all road squares (we can limit to a subset for speed)\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (!is_road[i][j]) continue;\n                auto path = shortest_path(r, c, i, j);\n                if (path.empty()) continue;\n                int path_cost = 0;\n                for (int k = 1; k < path.size(); k++) {\n                    path_cost += cost[path[k].first][path[k].second];\n                }\n                auto new_vis = vis_from[i][j];\n                new_vis &= ~coverage;\n                int gain = new_vis.count();\n                if (gain == 0) continue;\n                double score = (double)gain / path_cost;\n                if (score > best_score || (score == best_score && path_cost < best_cost)) {\n                    best_score = score;\n                    best_cost = path_cost;\n                    best_nr = i;\n                    best_nc = j;\n                }\n            }\n        }\n\n        if (best_nr == -1) {\n            // No gain found? just break (should not happen)\n            break;\n        }\n\n        // Move to best_nr, best_nc\n        auto path = shortest_path(r, c, best_nr, best_nc);\n        string moves = path_to_moves(path);\n        route += moves;\n        r = best_nr; c = best_nc;\n        coverage |= vis_from[r][c];\n    }\n\n    // Return to start\n    auto path_back = shortest_path(r, c, si, sj);\n    string moves_back = path_to_moves(path_back);\n    route += moves_back;\n\n    return route;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> si >> sj;\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] == '#') {\n                is_road[i][j] = false;\n                cost[i][j] = 0;\n            } else {\n                is_road[i][j] = true;\n                cost[i][j] = grid[i][j] - '0';\n            }\n        }\n    }\n\n    precompute_visibility();\n\n    string ans = greedy_cover();\n\n    // Output the route\n    cout << ans << endl;\n\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const int INF = 1e9;\nstatic const int MAX_DAY = 2000;\nstatic const int K_MAX   = 20;\n\nint N, M, K, R;\nvector<array<int, K_MAX>> d;\nvector<vector<int>> adj, radj;          // precedence graph\nvector<int> level;                      // longest path from sources\nvector<int> remPred;                    // #unfinished preds\nvector<char> done;\nvector<int> memberTask;                 // current task of member (-1 if idle)\nvector<int> taskMember;                 // member doing task (-1 if none)\nvector<vector<int>> finishedList;       // per member: list of task indices finished\nvector<vector<int>> finishedDur;        // corresponding durations\n\n// belief intervals [L,U] for every member and skill\narray<array<int, K_MAX>, 20> L, U;\n\n// exploration counters: member j , skill bucket b\narray<array<int, 101>, 20> expCount;\n\n// ready tasks\nvector<int> ready;\nchar readyDirty = false;\n\nvoid build_level(){\n    level.assign(N,0);\n    for(int i = 0; i < N; i++){\n        for(int v : adj[i]) level[v] = max(level[v], level[i]+1);\n    }\n}\n\nvoid mark_done(int task){\n    if(done[task]) return;\n    done[task] = 1;\n    for(int v : adj[task]){\n        remPred[v]--;\n        if(remPred[v]==0){\n            ready.push_back(v);\n            readyDirty = true;\n        }\n    }\n}\n\n// quick greedy update of belief intervals after (j,task,dur)\nvoid update_belief(int j, int task, int dur){\n    int low = max(0, dur - 3);\n    int high = dur + 3;\n    // current sum estimate\n    int sumLo = 0, sumHi = 0;\n    for(int k = 0; k < K; k++){\n        int dk = d[task][k];\n        // sjk in [Ljk, Ujk]\n        sumLo += max(0, dk - U[j][k]);\n        sumHi += max(0, dk - L[j][k]);\n    }\n    // we need sumLo <= high and sumHi >= low\n    // tighten only if violated\n    if(sumLo > high){\n        // must increase some U[j][k] -> decrease sumLo\n        int need = sumLo - high;\n        int cnt = 0;\n        for(int k = 0; k < K; k++){\n            int dk = d[task][k];\n            if(dk > L[j][k] && dk < U[j][k]) cnt++;\n        }\n        if(cnt==0) cnt=1;\n        int each = (need + cnt - 1)/cnt;\n        for(int k = 0; k < K; k++){\n            int dk = d[task][k];\n            if(dk > L[j][k] && dk < U[j][k]){\n                U[j][k] = min(U[j][k], dk);\n                need -= each;\n                if(need <= 0) break;\n            }\n        }\n    }\n    if(sumHi < low){\n        // must decrease some L[j][k] -> increase sumHi\n        int need = low - sumHi;\n        int cnt = 0;\n        for(int k = 0; k < K; k++){\n            int dk = d[task][k];\n            if(dk > L[j][k]) cnt++;\n        }\n        if(cnt==0) cnt=1;\n        int each = (need + cnt - 1)/cnt;\n        for(int k = 0; k < K; k++){\n            int dk = d[task][k];\n            if(dk > L[j][k]){\n                L[j][k] = max(L[j][k], dk - each);\n                need -= each;\n                if(need <= 0) break;\n            }\n        }\n    }\n}\n\n// optimistic and pessimistic durations\npair<int,int> est_duration(int task, int j){\n    int optGap = 0, pesGap = 0;\n    for(int k = 0; k < K; k++){\n        int dk = d[task][k];\n        optGap += max(0, dk - U[j][k]);\n        pesGap += max(0, dk - L[j][k]);\n    }\n    int opt = max(1, optGap - 3);\n    int pes = max(1, pesGap + 3);\n    return {opt, pes};\n}\n\n// exploration bonus: bucket = average d over skills\nint bucket(int task){\n    int s = 0;\n    for(int k = 0; k < K; k++) s += d[task][k];\n    return s / K;\n}\n\n// greedy matching: smallest weight\nvector<pair<int,int>> assign(){\n    if(readyDirty){\n        // remove already done tasks\n        vector<int> tmp;\n        for(int t : ready) if(!done[t]) tmp.push_back(t);\n        ready.swap(tmp);\n        readyDirty = false;\n    }\n    vector<int> avail;\n    for(int j = 0; j < M; j++) if(memberTask[j]<0) avail.push_back(j);\n    if(avail.empty() || ready.empty()) return {};\n\n    // build cost matrix\n    int A = avail.size(), T = ready.size();\n    vector<vector<int>> cost(A, vector<int>(T, INF));\n    for(int a = 0; a < A; a++){\n        int j = avail[a];\n        for(int t = 0; t < T; t++){\n            int i = ready[t];\n            auto [opt, pes] = est_duration(i, j);\n            int b = bucket(i);\n            int bonus = expCount[j][b];\n            // weight = 3*opt + 1*pes - 5*bonus + 2*level[i]\n            int w = 3*opt + pes - 5*bonus + 2*level[i];\n            cost[a][t] = w;\n        }\n    }\n    // greedy: smallest cost first\n    vector<tuple<int,int,int>> edges;\n    for(int a = 0; a < A; a++)\n        for(int t = 0; t < T; t++)\n            edges.emplace_back(cost[a][t], a, t);\n    sort(edges.begin(), edges.end());\n    vector<char> usedA(A,0), usedT(T,0);\n    vector<pair<int,int>> ans;\n    for(auto [w,a,t] : edges){\n        if(usedA[a] || usedT[t]) continue;\n        usedA[a] = usedT[t] = 1;\n        int j = avail[a];\n        int i = ready[t];\n        ans.emplace_back(j, i);\n    }\n    return ans;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> K >> R;\n    d.assign(N, array<int, K_MAX>{});\n    for(int i = 0; i < N; i++){\n        for(int k = 0; k < K; k++) cin >> d[i][k];\n    }\n    adj.assign(N, {});\n    radj.assign(N, {});\n    for(int i = 0; i < R; i++){\n        int u,v; cin >> u >> v; u--; v--;\n        adj[u].push_back(v);\n        radj[v].push_back(u);\n    }\n    // initial ready\n    remPred.assign(N,0);\n    for(int i = 0; i < N; i++){\n        remPred[i] = radj[i].size();\n        if(remPred[i]==0) ready.push_back(i);\n    }\n    done.assign(N,0);\n    memberTask.assign(M, -1);\n    taskMember.assign(N, -1);\n    finishedList.assign(M, {});\n    finishedDur.assign(M, {});\n\n    build_level();\n\n    // init belief: L=0, U=large\n    for(int j = 0; j < M; j++){\n        for(int k = 0; k < K; k++){\n            L[j][k] = 0;\n            U[j][k] = 200;\n        }\n    }\n    for(int j = 0; j < M; j++){\n        for(int b = 0; b <= 100; b++) expCount[j][b] = 0;\n    }\n\n    int day = 0;\n    while(day < MAX_DAY){\n        day++;\n        // 1. assign\n        auto match = assign();\n        // build output\n        cout << match.size();\n        for(auto [j,i] : match){\n            cout << ' ' << (j+1) << ' ' << (i+1);\n            // update state\n            memberTask[j] = i;\n            taskMember[i] = j;\n            // exploration count\n            int b = bucket(i);\n            expCount[j][b]++;\n            // remove from ready\n            auto it = find(ready.begin(), ready.end(), i);\n            if(it != ready.end()) ready.erase(it);\n        }\n        cout << '\\n';\n        cout.flush();\n\n        // 2. read finished\n        int nFin; \n        if(!(cin >> nFin)) break;\n        if(nFin == -1) break;\n        vector<int> fins(nFin);\n        for(int i = 0; i < nFin; i++){\n            cin >> fins[i]; fins[i]--;\n        }\n        // process finishes\n        for(int j : fins){\n            int task = memberTask[j];\n            if(task < 0) continue;\n            // read duration (hidden, but tester gives it in local mode)\n            // we simulate by recomputing w and adding noise, but here\n            // we assume the *real* duration is given via stdin in the\n            // same line after fins (local tester does that)\n            int dur; cin >> dur;\n            finishedList[j].push_back(task);\n            finishedDur[j].push_back(dur);\n            update_belief(j, task, dur);\n            mark_done(task);\n            memberTask[j] = -1;\n            taskMember[task] = -1;\n        }\n        // check global finish\n        bool allDone = true;\n        for(int i = 0; i < N; i++) if(!done[i]){ allDone=false; break; }\n        if(allDone) break;\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nstruct Point {\n    int x, y;\n    Point() = default;\n    Point(int x, int y) : x(x), y(y) {}\n};\ninline int man(const Point& a, const Point& b) {\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\nstruct Order {\n    Point p, d;          // pickup, delivery\n    int id;\n};\n\nint N = 1000;\nvector<Order> orders;\nvector<int> bestTourIdx;\nvector<Point> bestTour;\nll bestT = 1e18;\n\n// current working tour\nvector<Point> tour;\nvector<int>   taskId;   // 0..49  -> pickup, 50..99 -> delivery, -1 -> office\nvector<int>   posInTour; // for each task (0..99) its index in tour\n\n// feasibility checker: for every order i, pos[pickup_i] < pos[delivery_i]\nbool feasible() {\n    for (int i = 0; i < 50; ++i) {\n        if (posInTour[i] >= posInTour[i+50]) return false;\n    }\n    return true;\n}\n\nll tourLength() {\n    ll len = 0;\n    for (int i = 0; i + 1 < (int)tour.size(); ++i)\n        len += man(tour[i], tour[i+1]);\n    return len;\n}\n\n// insert task t (0..99) at position ins (0..tour.size())\nvoid insertTask(int t, int ins) {\n    Point pt = (t < 50 ? orders[t].p : orders[t-50].d);\n    tour.insert(tour.begin() + ins, pt);\n    taskId.insert(taskId.begin() + ins, t);\n    // update posInTour\n    for (int i = ins; i < (int)tour.size(); ++i) {\n        int tt = taskId[i];\n        if (tt >= 0) posInTour[tt] = i;\n    }\n}\n\n// remove task t from tour\nvoid removeTask(int t) {\n    int at = posInTour[t];\n    tour.erase(tour.begin() + at);\n    taskId.erase(taskId.begin() + at);\n    // update posInTour\n    for (int i = at; i < (int)tour.size(); ++i) {\n        int tt = taskId[i];\n        if (tt >= 0) posInTour[tt] = i;\n    }\n}\n\n// try to improve by relocating single task\nbool relocateImprove() {\n    bool improved = false;\n    for (int t = 0; t < 100; ++t) {\n        int oldpos = posInTour[t];\n        removeTask(t);\n        int bestpos = -1;\n        ll bestinc = 1e18;\n        // try all possible insert positions\n        for (int ins = 0; ins <= (int)tour.size(); ++ins) {\n            // check feasibility: if t is pickup, must stay before its delivery\n            if (t < 50) {\n                int delpos = posInTour[t+50];\n                if (ins > delpos) continue;\n            } else {\n                int pickpos = posInTour[t-50];\n                if (ins <= pickpos) continue;\n            }\n            // compute delta\n            Point pt = (t < 50 ? orders[t].p : orders[t-50].d);\n            ll delta = 0;\n            if (ins == 0) {\n                delta += man(pt, tour[0]) - man(Point(400,400), tour[0]);\n            } else if (ins == (int)tour.size()) {\n                delta += man(tour.back(), pt) - man(tour.back(), Point(400,400));\n            } else {\n                delta += man(tour[ins-1], pt) + man(pt, tour[ins])\n                       - man(tour[ins-1], tour[ins]);\n            }\n            if (delta < bestinc) {\n                bestinc = delta;\n                bestpos = ins;\n            }\n        }\n        if (bestpos >= 0 && bestinc < -1e-9) {\n            insertTask(t, bestpos);\n            improved = true;\n        } else {\n            // put it back where it was\n            insertTask(t, oldpos);\n        }\n    }\n    return improved;\n}\n\n// 2-opt segment reversal\nbool twoOptImprove() {\n    bool improved = false;\n    int n = tour.size();\n    for (int i = 0; i + 1 < n; ++i) {\n        for (int j = i + 2; j + 1 < n; ++j) {\n            // reverse segment [i+1 .. j]\n            ll old = man(tour[i], tour[i+1]) + man(tour[j], tour[j+1]);\n            ll nw  = man(tour[i], tour[j]) + man(tour[i+1], tour[j+1]);\n            if (nw >= old) continue;\n            // check feasibility after reversal\n            // build pos map quickly\n            vector<int> oldpos = posInTour;\n            // do reversal\n            reverse(tour.begin() + i + 1, tour.begin() + j + 1);\n            reverse(taskId.begin() + i + 1, taskId.begin() + j + 1);\n            // rebuild posInTour\n            for (int k = 0; k < n; ++k) {\n                int t = taskId[k];\n                if (t >= 0) posInTour[t] = k;\n            }\n            if (feasible()) {\n                improved = true;\n                goto out;\n            } else {\n                // rollback\n                reverse(tour.begin() + i + 1, tour.begin() + j + 1);\n                reverse(taskId.begin() + i + 1, taskId.begin() + j + 1);\n                posInTour = oldpos;\n            }\n        }\n    }\nout:\n    return improved;\n}\n\nvoid localSearch() {\n    bool improved;\n    do {\n        improved = false;\n        improved |= relocateImprove();\n        improved |= twoOptImprove();\n    } while (improved);\n}\n\nvoid buildGreedyTour(const vector<int>& sel) {\n    tour.clear();\n    taskId.clear();\n    tour.emplace_back(400, 400);\n    taskId.push_back(-1);\n    // task 0..49 pickup, 50..99 delivery\n    posInTour.assign(100, -1);\n\n    // random order of insertion\n    vector<int> ord = sel;\n    shuffle(ord.begin(), ord.end(), mt19937(random_device{}()));\n\n    for (int idx : ord) {\n        int pick = idx;\n        int del  = idx + 50;\n        Point pp = orders[pick].p;\n        Point pd = orders[del].d;\n        // find best pair of positions\n        ll bestinc = 1e18;\n        int bestpi = -1, bestdi = -1;\n        for (int pi = 0; pi <= (int)tour.size(); ++pi) {\n            for (int di = pi + 1; di <= (int)tour.size() + 1; ++di) {\n                // compute delta\n                ll inc = 0;\n                // insert pickup at pi\n                if (pi == 0) {\n                    inc += man(Point(400,400), pp) + man(pp, tour[0])\n                         - man(Point(400,400), tour[0]);\n                } else if (pi == (int)tour.size()) {\n                    inc += man(tour.back(), pp) + man(pp, Point(400,400))\n                         - man(tour.back(), Point(400,400));\n                } else {\n                    inc += man(tour[pi-1], pp) + man(pp, tour[pi])\n                         - man(tour[pi-1], tour[pi]);\n                }\n                // insert delivery at di (after pi)\n                Point afterpick = (di <= pi ? pp : (di-1 <= pi ? pp : tour[di-1]));\n                if (di == 0) {\n                    inc += man(Point(400,400), pd) + man(pd, tour[0])\n                         - man(Point(400,400), tour[0]);\n                } else if (di == (int)tour.size() + 1) {\n                    inc += man(tour.back(), pd) + man(pd, Point(400,400))\n                         - man(tour.back(), Point(400,400));\n                } else {\n                    int realdi = (di > pi ? di - 1 : di);\n                    inc += man(tour[realdi-1], pd) + man(pd, tour[realdi])\n                         - man(tour[realdi-1], tour[realdi]);\n                }\n                if (inc < bestinc) {\n                    bestinc = inc;\n                    bestpi = pi;\n                    bestdi = di;\n                }\n            }\n        }\n        // do insertion\n        insertTask(pick, bestpi);\n        int realdi = (bestdi > bestpi ? bestdi : bestdi);\n        insertTask(del, realdi);\n    }\n    // close tour\n    tour.emplace_back(400, 400);\n    taskId.push_back(-1);\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    orders.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> orders[i].p.x >> orders[i].p.y\n            >> orders[i].d.x >> orders[i].d.y;\n        orders[i].id = i;\n    }\n\n    auto start = chrono::steady_clock::now();\n    int iter = 0;\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > 1.95) break;\n\n        // random subset\n        vector<int> perm(N);\n        iota(perm.begin(), perm.end(), 0);\n        shuffle(perm.begin(), perm.end(), mt19937(iter++));\n        vector<int> sel(perm.begin(), perm.begin() + 50);\n\n        buildGreedyTour(sel);\n        localSearch();\n        ll curT = tourLength();\n        if (curT < bestT) {\n            bestT = curT;\n            bestTour = tour;\n            bestTourIdx = sel;\n        }\n    }\n\n    // output\n    cout << 50;\n    for (int i = 0; i < 50; ++i) cout << ' ' << bestTourIdx[i] + 1;\n    cout << '\\n';\n    cout << bestTour.size();\n    for (auto &p : bestTour) cout << ' ' << p.x << ' ' << p.y;\n    cout << '\\n';\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct UnionFind {\n    vector<int> parent, rank;\n    \n    UnionFind(int n) : parent(n), rank(n, 0) {\n        for (int i = 0; i < n; i++) {\n            parent[i] = i;\n        }\n    }\n    \n    int find(int x) {\n        if (parent[x] != x) {\n            parent[x] = find(parent[x]);\n        }\n        return parent[x];\n    }\n    \n    bool unite(int x, int y) {\n        int px = find(x), py = find(y);\n        if (px == py) return false;\n        \n        if (rank[px] < rank[py]) {\n            parent[px] = py;\n        } else {\n            parent[py] = px;\n            if (rank[px] == rank[py]) {\n                rank[px]++;\n            }\n        }\n        return true;\n    }\n    \n    bool connected() {\n        int root = find(0);\n        for (int i = 1; i < parent.size(); i++) {\n            if (find(i) != root) return false;\n        }\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 400, M = 1995;\n    \n    // Read coordinates\n    vector<pair<int, int>> coords(N);\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    // Read edges and calculate expected lengths\n    vector<int> u(M), v(M);\n    vector<double> expected(M);\n    \n    for (int i = 0; i < M; i++) {\n        cin >> u[i] >> v[i];\n        \n        // Calculate Euclidean distance\n        double dx = coords[u[i]].first - coords[v[i]].first;\n        double dy = coords[u[i]].second - coords[v[i]].second;\n        double dist = sqrt(dx*dx + dy*dy);\n        int d = round(dist);\n        \n        // Expected length for uniform [d, 3d]\n        expected[i] = 2.0 * d;\n    }\n    \n    UnionFind uf(N);\n    int accepted = 0;\n    \n    // Process each edge\n    for (int i = 0; i < M; i++) {\n        int l;\n        cin >> l;\n        \n        // Calculate threshold based on current state\n        double threshold = expected[i];\n        \n        // Adjust threshold based on connectivity needs\n        if (!uf.connected()) {\n            // Need more edges to ensure connectivity\n            threshold *= 1.2;\n        } else {\n            // Already connected, can be more selective\n            threshold *= 0.9;\n        }\n        \n        // Adjust based on how many edges we've accepted\n        if (accepted < N - 1) {\n            // Still need edges for spanning tree\n            threshold *= 1.1;\n        } else if (accepted > N - 1 + 50) {\n            // Already accepted many edges, be more selective\n            threshold *= 0.85;\n        }\n        \n        bool adopt = false;\n        \n        // Always accept if it connects different components\n        if (uf.find(u[i]) != uf.find(v[i])) {\n            adopt = true;\n        }\n        // Otherwise, accept if it's a good deal\n        else if (l <= threshold) {\n            adopt = true;\n        }\n        \n        if (adopt) {\n            uf.unite(u[i], v[i]);\n            accepted++;\n            cout << \"1\" << endl;\n        } else {\n            cout << \"0\" << endl;\n        }\n        \n        cout.flush();\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 30, W = 30, TURNS = 300;\nconst int dx[4] = {-1, 1, 0, 0}, dy[4] = {0, 0, -1, 1};\nconst char *dir = \"UDLR\", *Dir = \"UDLR\", *block = \"udlr\";\n\nint N, M;\nstruct Pet {\n    int x, y, t;\n} pets[20];\nstruct Human {\n    int x, y;\n} humans[10];\n\nbool wall[H][W]; // wall[x][y] = true if blocked\nint pet_x[20], pet_y[20];\n\n// BFS reachable squares from (sx,sy), return count and pet count\npair<int, int> bfs_reachable(int sx, int sy) {\n    static bool vis[H][W];\n    memset(vis, 0, sizeof(vis));\n    queue<pair<int, int>> q;\n    if (wall[sx][sy]) return {0, 0};\n    vis[sx][sy] = true;\n    q.push({sx, sy});\n    int cnt = 0, pcnt = 0;\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        cnt++;\n        for (int i = 0; i < N; i++) {\n            if (pet_x[i] == x && pet_y[i] == pcnt++) pcnt--;\n            if (pet_x[i] == x && pet_y[i] == y) pcnt++;\n        }\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n            if (wall[nx][ny] || vis[nx][ny]) continue;\n            vis[nx][ny] = true;\n            q.push({nx, ny});\n        }\n    }\n    return {cnt, pcnt};\n}\n\n// Heuristic score for a human at (x,y)\ndouble heuristic(int x, int y) {\n    auto [r, p] = bfs_reachable(x, y);\n    return r - 900.0 * p / 2.0;\n}\n\n// Check if can block (bx,by) from human at (x,y)\nbool can_block(int x, int y, int bx, int by) {\n    if (abs(bx - x) + abs(by - y) != 1) return false;\n    if (wall[bx][by]) return true; // already blocked\n    // Check if any pet or human is on (bx,by) at start\n    for (int i = 0; i < N; i++) {\n        if (pet_x[i] == bx && pet_y[i] == by) return false;\n    }\n    for (int i = 0; i < M; i++) {\n        if (humans[i].x == bx && humans[i].y == by) return false;\n    }\n    // Check if any pet is adjacent to (bx,by)\n    for (int d = 0; d < 4; d++) {\n        int nx = bx + dx[d], ny = by + dy[d];\n        if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n        for (int i = 0; i < N; i++) {\n            if (pet_x[i] == nx && pet_y[i] == ny) return false;\n        }\n    }\n    return true;\n}\n\n// Simulate pet moves (simplified: assume random for 1-3, greedy for 4-5)\nvoid simulate_pets() {\n    // For types 1-3: random basic moves (here we just do random)\n    // For types 4-5: target and move closer\n    // This is a placeholder: in real code, use BFS and rules\n    for (int i = 0; i < N; i++) {\n        int t = pets[i].t;\n        int &x = pet_x[i], &y = pet_y[i];\n        if (t <= 3) {\n            int steps = t;\n            while (steps--) {\n                vector<int> dirs;\n                for (int d = 0; d < 4; d++) {\n                    int nx = x + dx[d], ny = y + dy[d];\n                    if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n                    if (wall[nx][ny]) continue;\n                    dirs.push_back(d);\n                }\n                if (dirs.empty()) break;\n                int d = dirs[rand() % dirs.size()];\n                x += dx[d]; y += dy[d];\n            }\n        } else if (t == 4) {\n            // Dog: target human, move closer\n            // Simplified: pick random human and move one step closer\n            int ti = rand() % M;\n            int hx = humans[ti].x, hy = humans[ti].y;\n            // BFS to find direction\n            // For now, just move randomly\n            vector<int> dirs;\n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n                if (wall[nx][ny]) continue;\n                dirs.push_back(d);\n            }\n            if (!dirs.empty()) {\n                int d = dirs[rand() % dirs.size()];\n                x += dx[d]; y += dy[d];\n            }\n        } else {\n            // Cat: target square, move closer\n            // Simplified: move randomly\n            vector<int> dirs;\n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n                if (wall[nx][ny]) continue;\n                dirs.push_back(d);\n            }\n            if (!dirs.empty()) {\n                int d = dirs[rand() % dirs.size()];\n                x += dx[d]; y += dy[d];\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    for (int i = 0; i < N; i++) {\n        cin >> pets[i].x >> pets[i].y >> pets[i].t;\n        pets[i].x--; pets[i].y--;\n        pet_x[i] = pets[i].x;\n        pet_y[i] = pets[i].y;\n    }\n    cin >> M;\n    for (int i = 0; i < M; i++) {\n        cin >> humans[i].x >> humans[i].y;\n        humans[i].x--; humans[i].y--;\n    }\n\n    memset(wall, 0, sizeof(wall));\n\n    for (int turn = 0; turn < TURNS; turn++) {\n        string act;\n        for (int i = 0; i < M; i++) {\n            int x = humans[i].x, y = humans[i].y;\n            double best = -1e9;\n            char best_act = '.';\n            // Try stay\n            double sc = heuristic(x, y);\n            if (sc > best) { best = sc; best_act = '.'; }\n            // Try move\n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n                if (wall[nx][ny]) continue;\n                humans[i].x = nx; humans[i].y = ny;\n                sc = heuristic(nx, ny);\n                if (sc > best) { best = sc; best_act = Dir[d]; }\n                humans[i].x = x; humans[i].y = y;\n            }\n            // Try block\n            for (int d = 0; d < 4; d++) {\n                int bx = x + dx[d], by = y + dy[d];\n                if (!can_block(x, y, bx, by)) continue;\n                bool old = wall[bx][by];\n                wall[bx][by] = true;\n                sc = heuristic(x, y);\n                if (sc > best) { best = sc; best_act = block[d]; }\n                wall[bx][by] = old;\n            }\n            act += best_act;\n            // Apply best action\n            if (best_act == '.') {\n                // stay\n            } else if (best_act >= 'U' && best_act <= 'R') {\n                int d = best_act - 'U';\n                humans[i].x += dx[d];\n                humans[i].y += dy[d];\n            } else if (best_act >= 'u' && best_act <= 'r') {\n                int d = best_act - 'u';\n                int bx = x + dx[d], by = y + dy[d];\n                wall[bx][by] = true;\n            }\n        }\n        cout << act << endl;\n        cout.flush();\n\n        // Read pet moves\n        for (int i = 0; i < N; i++) {\n            string s;\n            cin >> s;\n            // Apply pet moves\n            int &x = pet_x[i], &y = pet_y[i];\n            for (char c : s) {\n                int d = -1;\n                if (c == 'U') d = 0;\n                else if (c == 'D') d = 1;\n                else if (c == 'L') d = 2;\n                else if (c == 'R') d = 3;\n                else continue;\n                int nx = x + dx[d], ny = y + dy[d];\n                if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n                if (wall[nx][ny]) continue;\n                x = nx; y = ny;\n            }\n        }\n    }\n\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic uint64_t rng_state = 123456789123456789ULL;\ninline uint64_t xorshift64() {\n    uint64_t x = rng_state;\n    x ^= x << 13;\n    x ^= x >> 7;\n    x ^= x << 17;\n    rng_state = x;\n    return x;\n}\ninline int randint(int l, int r) {   // [l, r]\n    return l + (xorshift64() % (r - l + 1));\n}\ninline double rand01() {\n    return (xorshift64() & ((1ULL<<32)-1)) / double(1ULL<<32);\n}\n\nint si, sj, ti, tj;\ndouble pforget;\nbool wallh[20][19]; // wallh[i][j] blocks (i,j)-(i,j+1)\nbool wallv[19][20]; // wallv[i][j] blocks (i,j)-(i+1,j)\nint dist[20][20];\nint best_len;\nstring best_str;\ndouble best_score;\n\nconst int INF = 1000000;\n\nvoid bfs_dist() {\n    for(int i=0;i<20;i++)for(int j=0;j<20;j++) dist[i][j]=INF;\n    deque<pair<int,int>> dq;\n    dist[ti][tj]=0;\n    dq.push_back({ti,tj});\n    static int di[4]={-1,1,0,0}, dj[4]={0,0,-1,1};\n    while(!dq.empty()){\n        auto [i,j]=dq.front(); dq.pop_front();\n        for(int d=0;d<4;d++){\n            int ni=i+di[d], nj=j+dj[d];\n            if(ni<0||nj<0||ni>=20||nj>=20) continue;\n            if(d==0 && wallv[ni][j]) continue; // up\n            if(d==1 && wallv[i][j]) continue;   // down\n            if(d==2 && wallh[i][nj]) continue;  // left\n            if(d==3 && wallh[i][j]) continue;   // right\n            if(dist[ni][nj]>dist[i][j]+1){\n                dist[ni][nj]=dist[i][j]+1;\n                dq.push_back({ni,nj});\n            }\n        }\n    }\n}\n\ninline bool can_move(int i, int j, int d) {\n    if(d==0){ // U\n        if(i==0) return false;\n        return !wallv[i-1][j];\n    } else if(d==1){ // D\n        if(i==19) return false;\n        return !wallv[i][j];\n    } else if(d==2){ // L\n        if(j==0) return false;\n        return !wallh[i][j-1];\n    } else { // R\n        if(j==19) return false;\n        return !wallh[i][j];\n    }\n}\n\ninline int move_i(int i, int d) {\n    if(d==0) return i-1;\n    if(d==1) return i+1;\n    return i;\n}\ninline int move_j(int j, int d) {\n    if(d==2) return j-1;\n    if(d==3) return j+1;\n    return j;\n}\n\ndouble eval(const string &s) {\n    const int L = s.size();\n    static double cur[400], nxt[400];\n    for(int v=0;v<400;v++) cur[v]=0.0;\n    int start = si*20 + sj;\n    cur[start] = 1.0;\n    int goal = ti*20 + tj;\n    double succ = 0.0;\n    double et = 0.0;\n    for(int t=0;t<L;t++){\n        for(int v=0;v<400;v++) nxt[v]=0.0;\n        for(int v=0;v<400;v++){\n            if(cur[v]<1e-14) continue;\n            int i=v/20, j=v%20;\n            if(i==ti&&j==tj) continue; // already absorbed\n            int nopen=0;\n            for(int d=0;d<4;d++) if(can_move(i,j,d)) nopen++;\n            double p_stay = pforget;\n            if(nopen==0){\n                p_stay += (1-pforget);\n            } else {\n                p_stay += (1-pforget)*0; // no extra stay from walls\n            }\n            // forget \u2192 stay\n            nxt[v] += cur[v] * pforget;\n            // try to move\n            if(nopen>0){\n                double p_dir = (1-pforget) / nopen;\n                for(int d=0;d<4;d++){\n                    if(!can_move(i,j,d)) continue;\n                    int ni=move_i(i,d), nj=move_j(j,d);\n                    int u=ni*20+nj;\n                    if(ni==ti&&nj==tj){\n                        // absorbed at t+1\n                        double prob = cur[v] * p_dir;\n                        succ += prob;\n                        et += prob * (t+1);\n                    } else {\n                        nxt[u] += cur[v] * p_dir;\n                    }\n                }\n            } else {\n                // all directions blocked \u2192 forced stay\n                nxt[v] += cur[v] * (1-pforget);\n            }\n        }\n        swap(cur, nxt);\n    }\n    double left=0.0;\n    for(int v=0;v<400;v++) left+=cur[v];\n    succ = 1.0 - left;\n    // et already contains sum t*prob(t)\n    if(succ<1e-14) return 0.0;\n    double mean_t = et / succ;\n    double es = succ * (401.0 - mean_t);\n    return es;\n}\n\nstring greedy_random_walk(int want_len) {\n    string path;\n    int i=si, j=sj;\n    static int dirs[4]={0,1,2,3};\n    while((int)path.size() < want_len) {\n        if(i==ti && j==tj) break;\n        // shuffle directions\n        for(int k=0;k<4;k++){\n            int r=randint(k,3);\n            swap(dirs[k],dirs[r]);\n        }\n        double best_val=-1e9;\n        int best_d=-1;\n        for(int k=0;k<4;k++){\n            int d=dirs[k];\n            if(!can_move(i,j,d)) continue;\n            int ni=move_i(i,d), nj=move_j(j,d);\n            double val = -(dist[ni][nj]) + rand01()*0.3;\n            if(val>best_val){\n                best_val=val;\n                best_d=d;\n            }\n        }\n        if(best_d>=0){\n            path += \"UDLR\"[best_d];\n            i=move_i(i,best_d);\n            j=move_j(j,best_d);\n        } else {\n            // trapped \u2192 stay, any char\n            path += 'U';\n        }\n    }\n    // if we reached goal early, pad with something safe\n    while((int)path.size() < want_len){\n        if(i==ti&&j==tj){\n            path+='R'; // safe arbitrary\n        } else {\n            // greedy again\n            int dbest=-1, dbestv=INF;\n            for(int d=0;d<4;d++){\n                if(!can_move(i,j,d)) continue;\n                int ni=move_i(i,d), nj=move_j(j,d);\n                if(dist[ni][nj]<dbestv){\n                    dbestv=dist[ni][nj];\n                    dbest=d;\n                }\n            }\n            if(dbest>=0){\n                path+=\"UDLR\"[dbest];\n                i=move_i(i,dbest);\n                j=move_j(j,dbest);\n            } else {\n                path+='U';\n            }\n        }\n    }\n    return path;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin>>si>>sj>>ti>>tj>>pforget;\n    for(int i=0;i<20;i++){\n        string row; cin>>row;\n        for(int j=0;j<19;j++) wallh[i][j]=(row[j]=='1');\n    }\n    for(int i=0;i<19;i++){\n        string row; cin>>row;\n        for(int j=0;j<20;j++) wallv[i][j]=(row[j]=='1');\n    }\n\n    bfs_dist();\n\n    best_score=-1e9;\n    best_len=-1;\n\n    // spend ~1.8 seconds iterating\n    const auto start_time = chrono::steady_clock::now();\n    int attempt=0;\n    while(1){\n        attempt++;\n        auto now=chrono::steady_clock::now();\n        double elapsed=chrono::duration<double>(now-start_time).count();\n        if(elapsed>1.85) break;\n\n        int want_len = randint(60,180);\n        string cand = greedy_random_walk(want_len);\n        double sc = eval(cand);\n        if(sc>best_score){\n            best_score=sc;\n            best_str=cand;\n            best_len=want_len;\n        }\n    }\n\n    cout<<best_str<<\"\\n\";\n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <random>\n#include <algorithm>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\nconst int SIZE = 30;\nconst int DIR[4][2] = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}}; // left, up, right, down\n\n// to[tile_type][entry_direction] = exit_direction, -1 if invalid\nconst int to[8][4] = {\n    {1, 0, -1, -1},  // type 0\n    {3, -1, -1, 0},  // type 1\n    {-1, -1, 3, 2},  // type 2\n    {-1, 2, 1, -1},  // type 3\n    {1, 0, 3, 2},    // type 4\n    {3, 2, 1, 0},    // type 5\n    {2, -1, 0, -1},  // type 6\n    {-1, 3, -1, 1}   // type 7\n};\n\nint grid[SIZE][SIZE];\nint rotation[SIZE][SIZE];\nint best_rotation[SIZE][SIZE];\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint get_tile_type(int i, int j) {\n    int base_type = grid[i][j];\n    int rot = rotation[i][j];\n    if (base_type <= 3) { // single curve tiles\n        return (base_type + rot) % 4;\n    } else if (base_type <= 5) { // double curve tiles\n        return 4 + (base_type - 4 + rot) % 2;\n    } else { // straight tiles\n        return 6 + (base_type - 6 + rot) % 2;\n    }\n}\n\nint trace_loop(int si, int sj, int sd) {\n    int i = si, j = sj, d = sd;\n    int length = 0;\n    const int max_steps = 10000; // safety limit\n    \n    for (int step = 0; step < max_steps; step++) {\n        int tile_type = get_tile_type(i, j);\n        int d2 = to[tile_type][d];\n        if (d2 == -1) return 0;\n        \n        i += DIR[d2][0];\n        j += DIR[d2][1];\n        if (i < 0 || i >= SIZE || j < 0 || j >= SIZE) return 0;\n        \n        d = (d2 + 2) % 4;\n        length++;\n        \n        if (i == si && j == sj && d == sd) return length;\n    }\n    return 0;\n}\n\npair<int, int> find_loops() {\n    vector<int> loop_lengths;\n    vector<vector<vector<bool>>> visited(SIZE, vector<vector<bool>>(SIZE, vector<bool>(4, false)));\n    \n    for (int i = 0; i < SIZE; i++) {\n        for (int j = 0; j < SIZE; j++) {\n            for (int d = 0; d < 4; d++) {\n                if (!visited[i][j][d]) {\n                    int length = trace_loop(i, j, d);\n                    if (length > 0) {\n                        // Mark all positions in this loop as visited\n                        int ci = i, cj = j, cd = d;\n                        for (int step = 0; step < length; step++) {\n                            visited[ci][cj][cd] = true;\n                            int tile_type = get_tile_type(ci, cj);\n                            int d2 = to[tile_type][cd];\n                            ci += DIR[d2][0];\n                            cj += DIR[d2][1];\n                            cd = (d2 + 2) % 4;\n                        }\n                        loop_lengths.push_back(length);\n                    }\n                }\n            }\n        }\n    }\n    \n    sort(loop_lengths.rbegin(), loop_lengths.rend());\n    if (loop_lengths.size() < 2) return {0, 0};\n    return {loop_lengths[0], loop_lengths[1]};\n}\n\nint calculate_score() {\n    auto [l1, l2] = find_loops();\n    return l1 * l2;\n}\n\nvoid simulated_annealing() {\n    // Initialize with random rotations\n    for (int i = 0; i < SIZE; i++) {\n        for (int j = 0; j < SIZE; j++) {\n            rotation[i][j] = rng() % 4;\n            best_rotation[i][j] = rotation[i][j];\n        }\n    }\n    \n    int best_score = calculate_score();\n    int current_score = best_score;\n    \n    double temperature = 100.0;\n    double cooling_rate = 0.995;\n    const int iterations = 50000;\n    \n    for (int iter = 0; iter < iterations; iter++) {\n        // Randomly select a tile to rotate\n        int i = rng() % SIZE;\n        int j = rng() % SIZE;\n        int old_rot = rotation[i][j];\n        int new_rot = (old_rot + 1 + rng() % 3) % 4; // Try a different rotation\n        \n        rotation[i][j] = new_rot;\n        int new_score = calculate_score();\n        \n        int delta = new_score - current_score;\n        if (delta > 0 || exp(delta / temperature) > uniform_real_distribution<double>(0, 1)(rng)) {\n            current_score = new_score;\n            if (new_score > best_score) {\n                best_score = new_score;\n                for (int x = 0; x < SIZE; x++) {\n                    for (int y = 0; y < SIZE; y++) {\n                        best_rotation[x][y] = rotation[x][y];\n                    }\n                }\n            }\n        } else {\n            rotation[i][j] = old_rot; // Revert change\n        }\n        \n        temperature *= cooling_rate;\n        \n        // Occasionally try larger changes\n        if (iter % 1000 == 0 && iter > 0) {\n            for (int k = 0; k < 10; k++) {\n                int x = rng() % SIZE;\n                int y = rng() % SIZE;\n                rotation[x][y] = rng() % 4;\n            }\n            current_score = calculate_score();\n            if (current_score > best_score) {\n                best_score = current_score;\n                for (int x = 0; x < SIZE; x++) {\n                    for (int y = 0; y < SIZE; y++) {\n                        best_rotation[x][y] = rotation[x][y];\n                    }\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    for (int i = 0; i < SIZE; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < SIZE; j++) {\n            grid[i][j] = line[j] - '0';\n        }\n    }\n    \n    // Run simulated annealing\n    simulated_annealing();\n    \n    // Output best solution\n    for (int i = 0; i < SIZE; i++) {\n        for (int j = 0; j < SIZE; j++) {\n            cout << best_rotation[i][j];\n        }\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc011":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <unordered_set>\n#include <chrono>\n\nusing namespace std;\n\nconst int dx[4] = {-1, 0, 1, 0};\nconst int dy[4] = {0, 1, 0, -1};\nconst char dir_char[4] = {'U', 'R', 'D', 'L'};\n\nint N, T;\nvector<vector<int>> board;\nint empty_row, empty_col;\nstring solution;\n\nbool has_line(int tile, int direction) {\n    return (tile >> direction) & 1;\n}\n\nbool can_connect(int tile1, int tile2, int direction) {\n    // direction: 0=up, 1=right, 2=down, 3=left\n    int opposite = (direction + 2) % 4;\n    return has_line(tile1, direction) && has_line(tile2, opposite);\n}\n\nint count_connections() {\n    int connections = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0) continue;\n            \n            // Check down connection\n            if (i < N-1 && board[i+1][j] != 0) {\n                if (can_connect(board[i][j], board[i+1][j], 2)) {\n                    connections++;\n                }\n            }\n            \n            // Check right connection\n            if (j < N-1 && board[i][j+1] != 0) {\n                if (can_connect(board[i][j], board[i][j+1], 1)) {\n                    connections++;\n                }\n            }\n        }\n    }\n    return connections;\n}\n\nint find_largest_tree() {\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    int max_size = 0;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0 || visited[i][j]) continue;\n            \n            queue<pair<int, int>> q;\n            q.push({i, j});\n            visited[i][j] = true;\n            int size = 0;\n            \n            while (!q.empty()) {\n                auto [r, c] = q.front();\n                q.pop();\n                size++;\n                \n                // Check all 4 directions\n                for (int d = 0; d < 4; d++) {\n                    int nr = r + dx[d];\n                    int nc = c + dy[d];\n                    \n                    if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n                    if (board[nr][nc] == 0 || visited[nr][nc]) continue;\n                    if (!can_connect(board[r][c], board[nr][nc], d)) continue;\n                    \n                    visited[nr][nc] = true;\n                    q.push({nr, nc});\n                }\n            }\n            \n            max_size = max(max_size, size);\n        }\n    }\n    \n    return max_size;\n}\n\nbool is_valid_move(int r, int c) {\n    return r >= 0 && r < N && c >= 0 && c < N && board[r][c] != 0;\n}\n\nvoid make_move(int direction) {\n    int nr = empty_row + dx[direction];\n    int nc = empty_col + dy[direction];\n    \n    if (!is_valid_move(nr, nc)) return;\n    \n    swap(board[empty_row][empty_col], board[nr][nc]);\n    empty_row = nr;\n    empty_col = nc;\n    solution += dir_char[direction];\n}\n\nvoid solve_greedy() {\n    auto start_time = chrono::high_resolution_clock::now();\n    int best_tree = find_largest_tree();\n    \n    while (solution.size() < T) {\n        int best_improvement = 0;\n        int best_direction = -1;\n        \n        for (int d = 0; d < 4; d++) {\n            int nr = empty_row + dx[d];\n            int nc = empty_col + dy[d];\n            \n            if (!is_valid_move(nr, nc)) continue;\n            \n            // Try the move\n            swap(board[empty_row][empty_col], board[nr][nc]);\n            int new_tree = find_largest_tree();\n            int improvement = new_tree - best_tree;\n            \n            // Undo the move\n            swap(board[empty_row][empty_col], board[nr][nc]);\n            \n            if (improvement > best_improvement) {\n                best_improvement = improvement;\n                best_direction = d;\n            }\n        }\n        \n        if (best_direction == -1) {\n            // No improving move, try random\n            best_direction = rand() % 4;\n        }\n        \n        make_move(best_direction);\n        best_tree = find_largest_tree();\n        \n        // Check time limit\n        auto current_time = chrono::high_resolution_clock::now();\n        auto elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count();\n        if (elapsed > 2800) break; // Leave some margin\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> T;\n    board.assign(N, vector<int>(N));\n    \n    for (int i = 0; i < N; i++) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < N; j++) {\n            char c = row[j];\n            if (c == '0') {\n                board[i][j] = 0;\n                empty_row = i;\n                empty_col = j;\n            } else if (c >= '1' && c <= '9') {\n                board[i][j] = c - '0';\n            } else {\n                board[i][j] = c - 'a' + 10;\n            }\n        }\n    }\n    \n    solve_greedy();\n    \n    cout << solution << endl;\n    \n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\nusing int64 = long long;\nusing f64 = long double;\n\n/* ---------- geometry primitives ---------- */\nconst f64 EPS = 1e-9L;\ninline int sign(f64 x) { return (x > EPS) - (x < -EPS); }\n\nstruct Line {\n    f64 A, B, C;          // A x + B y + C = 0,  A\u00b2+B\u00b2=1\n    Line() = default;\n    Line(f64 a, f64 b, f64 c) : A(a), B(b), C(c) { norm(); }\n    // through (x1,y1)->(x2,y2)\n    Line(f64 x1, f64 y1, f64 x2, f64 y2) {\n        A = y2 - y1;\n        B = x1 - x2;\n        C = x2*y1 - x1*y2;\n        norm();\n    }\n    void norm() {\n        f64 s = sqrtl(A*A + B*B);\n        if (s > EPS) { A /= s; B /= s; C /= s; }\n    }\n    int side(f64 x, f64 y) const {\n        f64 v = A*x + B*y + C;\n        return sign(v);\n    }\n};\n\n/* ---------- global input ---------- */\nint N, K;\nvector<int> a(11);            // 1..10\nvector<f64> X, Y;\n\n/* ---------- current state ---------- */\nint kUsed = 0;                // lines used so far\nvector<Line> lines;\nusing Bits = bitset<100>;\nvector<Bits> regionCode;      // regionCode[r] = sign vector\nvector<int> regionCount;      // regionCount[r] = #strawberries inside\nunordered_map<uint64_t, int> regMap; // hash of sign vector -> index\n\nint have[11] = {};            // have[d] = #regions with d strawberries\nint objective = 0;\n\n/* ---------- evaluation ---------- */\nint eval() {\n    int obj = 0;\n    for (int d = 1; d <= 10; ++d) obj += min(a[d], have[d]);\n    return obj;\n}\n\n/* ---------- incremental add line ---------- */\nvoid addLine(const Line &L) {\n    if (kUsed == K) return;\n    int id = kUsed++;\n    lines[id] = L;\n\n    // re-index regions\n    unordered_map<uint64_t, int> newMap;\n    vector<Bits> newCode;\n    vector<int> newCount;\n    int newR = 0;\n\n    // helper: hash of bitset\n    auto hashBits = [&](const Bits &b) -> uint64_t {\n        return b._Get_hash(); // libstdc++ extension, fast\n    };\n\n    // split every existing region\n    for (int r = 0; r < (int)regionCode.size(); ++r) {\n        int cnt = regionCount[r];\n        if (cnt == 0) continue;\n\n        Bits oldSig = regionCode[r];\n        // count strawberries on each side\n        int cntP = 0, cntM = 0, cnt0 = 0;\n        // we need to know which strawberries belong to region r\n        // but we don't store per-region lists -> re-scan all points\n        // This is O(N) per region, but total regions <= 5051 and N<=1000 -> acceptable\n        Bits sigP = oldSig, sigM = oldSig;\n        sigP.set(id);        // +1 side\n        sigM.reset(id);      // -1 side\n\n        for (int i = 0; i < N; ++i) {\n            int s = L.side(X[i], Y[i]);\n            if (s == 0) { cnt0++; continue; }\n            if (s > 0) cntP++; else cntM++;\n        }\n        // two children\n        if (cntP > 0) {\n            uint64_t h = hashBits(sigP);\n            auto it = newMap.find(h);\n            if (it == newMap.end()) {\n                newMap[h] = newR;\n                newCode.push_back(sigP);\n                newCount.push_back(cntP);\n                ++newR;\n            } else {\n                newCount[it->second] += cntP;\n            }\n        }\n        if (cntM > 0) {\n            uint64_t h = hashBits(sigM);\n            auto it = newMap.find(h);\n            if (it == newMap.end()) {\n                newMap[h] = newR;\n                newCode.push_back(sigM);\n                newCount.push_back(cntM);\n                ++newR;\n            } else {\n                newCount[it->second] += cntM;\n            }\n        }\n        // strawberries on the line (cnt0) are lost\n    }\n\n    // rebuild global arrays\n    regMap.swap(newMap);\n    regionCode.swap(newCode);\n    regionCount.swap(newCount);\n\n    // rebuild have[] and objective\n    fill(have, have+11, 0);\n    for (int c : regionCount) if (c <= 10) have[c]++;\n    objective = eval();\n}\n\n/* ---------- greedy candidate generation ---------- */\nLine bestGreedyLine() {\n    static mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> distN(0, N-1);\n    uniform_int_distribution<int> distC(-100000, 100000);\n    uniform_real_distribution<f64> distA(0, M_PIl);\n\n    int bestGain = 0;\n    Line bestL;\n\n    auto tryLine = [&](const Line &L) {\n        // simulate addLine without really modifying state\n        unordered_map<uint64_t, int> tmpMap;\n        vector<int> tmpCount;\n        vector<Bits> tmpCode;\n        int tmpHave[11] = {};\n        int tmpObj = 0;\n\n        // copy current state\n        for (int r = 0; r < (int)regionCode.size(); ++r) {\n            int cnt = regionCount[r];\n            if (cnt == 0) continue;\n            int cntP = 0, cntM = 0;\n            Bits sigP = regionCode[r], sigM = regionCode[r];\n            sigP.set(kUsed);\n            sigM.reset(kUsed);\n            for (int i = 0; i < N; ++i) {\n                int s = L.side(X[i], Y[i]);\n                if (s == 0) continue;\n                if (s > 0) cntP++; else cntM++;\n            }\n            if (cntP > 0) {\n                tmpCount.push_back(cntP);\n                tmpCode.push_back(sigP);\n            }\n            if (cntM > 0) {\n                tmpCount.push_back(cntM);\n                tmpCode.push_back(sigM);\n            }\n        }\n        for (int c : tmpCount) if (c <= 10) tmpHave[c]++;\n        for (int d = 1; d <= 10; ++d) tmpObj += min(a[d], tmpHave[d]);\n        int gain = tmpObj - objective;\n        if (gain > bestGain) {\n            bestGain = gain;\n            bestL = L;\n        }\n    };\n\n    // try random point-pairs\n    const int TRIES = 400;\n    for (int t = 0; t < TRIES; ++t) {\n        int i = distN(rng), j = distN(rng);\n        if (i == j) continue;\n        Line L(X[i], Y[i], X[j], Y[j]);\n        tryLine(L);\n    }\n    // try random directions through random points\n    for (int t = 0; t < TRIES; ++t) {\n        int i = distN(rng);\n        f64 ang = distA(rng);\n        f64 dx = cosl(ang), dy = sinl(ang);\n        Line L(X[i], Y[i], X[i] + dx, Y[i] + dy);\n        tryLine(L);\n    }\n    // try a few axis-aligned\n    for (int t = 0; t < 20; ++t) {\n        f64 x = distC(rng) * 1000;\n        Line L(1, 0, -x);\n        tryLine(L);\n        Line L2(0, 1, -x);\n        tryLine(L2);\n    }\n    return bestL;\n}\n\n/* ---------- main ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    auto clk_start = chrono::steady_clock::now();\n\n    cin >> N >> K;\n    for (int d = 1; d <= 10; ++d) cin >> a[d];\n    X.resize(N); Y.resize(N);\n    for (int i = 0; i < N; ++i) cin >> X[i] >> Y[i];\n\n    // initial state: 1 region\n    lines.assign(K, Line());\n    regionCode.clear();\n    regionCount.clear();\n    regMap.clear();\n    Bits initialSig;\n    initialSig.reset();\n    regionCode.push_back(initialSig);\n    regionCount.push_back(N);\n    regMap[initialSig._Get_hash()] = 0;\n    fill(have, have+11, 0);\n    have[min(N, 10)] = 1;\n    objective = eval();\n\n    // iterated greedy + local search\n    int bestEver = objective;\n    vector<Line> bestLines;\n    int bestK = 0;\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - clk_start).count();\n        if (elapsed > 2.85) break;\n\n        // greedy addition pass\n        while (kUsed < K) {\n            Line L = bestGreedyLine();\n            if (objective >= bestEver) {\n                bestEver = objective;\n                bestLines = vector<Line>(lines.begin(), lines.begin() + kUsed);\n                bestK = kUsed;\n            }\n            addLine(L);\n        }\n\n        // local perturbation: delete last 5 and re-add greedily\n        if (kUsed >= 5) {\n            for (int del = 0; del < 5; ++del) {\n                // remove last line\n                kUsed--;\n                // rebuild entire state from scratch (simplest)\n                regionCode.clear();\n                regionCount.clear();\n                regMap.clear();\n                Bits init;\n                init.reset();\n                regionCode.push_back(init);\n                regionCount.push_back(0);\n                regMap[init._Get_hash()] = 0;\n                // recount\n                fill(have, have+11, 0);\n                for (int i = 0; i < N; ++i) {\n                    Bits sig;\n                    sig.reset();\n                    for (int j = 0; j < kUsed; ++j) {\n                        int s = lines[j].side(X[i], Y[i]);\n                        if (s > 0) sig.set(j);\n                    }\n                    uint64_t h = sig._Get_hash();\n                    auto it = regMap.find(h);\n                    int r;\n                    if (it == regMap.end()) {\n                        r = regionCode.size();\n                        regMap[h] = r;\n                        regionCode.push_back(sig);\n                        regionCount.push_back(0);\n                    } else {\n                        r = it->second;\n                    }\n                    regionCount[r]++;\n                }\n                fill(have, have+11, 0);\n                for (int c : regionCount) if (c <= 10) have[c]++;\n                objective = eval();\n            }\n        }\n    }\n\n    // output best\n    cout << bestK << '\\n';\n    cout << fixed << setprecision(0);\n    for (int i = 0; i < bestK; ++i) {\n        // pick two integer points on the line\n        f64 A = bestLines[i].A, B = bestLines[i].B, C = bestLines[i].C;\n        // choose x1,y1,x2,y2 integers\n        int64_t x1, y1, x2, y2;\n        if (fabs(B) > EPS) {\n            x1 = 0;\n            y1 = llround(-C / B);\n            x2 = 1;\n            y2 = llround((-C - A) / B);\n        } else {\n            y1 = 0;\n            x1 = llround(-C / A);\n            y2 = 1;\n            x2 = llround((-C) / A);\n        }\n        cout << x1 << ' ' << y1 << ' ' << x2 << ' ' << y2 << '\\n';\n    }\n    return 0;\n}","ahc014":"#pragma GCC target(\"avx2\")\n#pragma GCC optimize(\"O3\")\n#pragma GCC optimize(\"unroll-loops\")\n#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing ll = long long;\n#define rep(i, n) for (int i = 0; i < (int)(n); i++)\n\n// ---------- \u8fba\u306e\u7b26\u53f7\u5316 ----------\ninline uint64_t ecode(int x1, int y1, int x2, int y2) {\n    if (x1 > x2 || (x1 == x2 && y1 > y2)) {\n        swap(x1, x2); swap(y1, y2);\n    }\n    return ((uint64_t)(uint16_t)x1 << 48) | ((uint64_t)(uint16_t)y1 << 32) |\n           ((uint64_t)(uint16_t)x2 << 16) | (uint64_t)(uint16_t)y2;\n}\n\n// ---------- \u30b0\u30ed\u30fc\u30d0\u30eb ----------\nint N, M;\nint c;\nvector<vector<int>> w;               // \u91cd\u307f\nvector<vector<bool>> dot;            // dot[x][y]\nrobin_hood::unordered_set<uint64_t> used_edge;\nvector<tuple<int,int,int,int,int,int,int,int>> ops;  // \u64cd\u4f5c\u5c65\u6b74\n\n// ---------- \u65b9\u5411 ----------\nconst int dx45[4] = {1, 1, -1, -1};\nconst int dy45[4] = {1, -1, -1, 1};\nconst int dxax[4] = {1, 0, -1, 0};\nconst int dyax[4] = {0, 1, 0, -1};\n\n// ---------- \u77e9\u5f62\u3092\u8a66\u3059 ----------\nbool try_rect(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    // 4\u9802\u70b9\u306e\u9806\u5e8f\u3092\u6b63\u3057\u304f\u56de\u3057\u3001p1=(x1,y1) \u304c\u7a7a\u3001\u4ed6\u304c dot \u3067\u3042\u308b\u3053\u3068\n    if (!dot[x2][y2] || !dot[x3][y3] || !dot[x4][y4]) return false;\n    if (dot[x1][y1]) return false;\n    // 4\u8fba\u306e\u7b26\u53f7\u5316\n    uint64_t e1 = ecode(x1,y1,x2,y2);\n    uint64_t e2 = ecode(x2,y2,x3,y3);\n    uint64_t e3 = ecode(x3,y3,x4,y4);\n    uint64_t e4 = ecode(x4,y4,x1,y1);\n    if (used_edge.count(e1) || used_edge.count(e2) ||\n        used_edge.count(e3) || used_edge.count(e4)) return false;\n    // \u8fba\u4e0a\u306b\u4ed6\u30c9\u30c3\u30c8\u304c\u306a\u3044\u304b\uff08\u7c21\u6613\uff1agcd \u3067\u7b49\u5206\u70b9\u30c1\u30a7\u30c3\u30af\uff09\n    auto check_edge = [&](int ax, int ay, int bx, int by) {\n        int dx = bx - ax, dy = by - ay;\n        int g = gcd(abs(dx), abs(dy));\n        int stepx = dx / g, stepy = dy / g;\n        for (int t = 1; t < g; t++) {\n            int xx = ax + t * stepx, yy = ay + t * stepy;\n            if (dot[xx][yy]) return false;\n        }\n        return true;\n    };\n    if (!check_edge(x1,y1,x2,y2)) return false;\n    if (!check_edge(x2,y2,x3,y3)) return false;\n    if (!check_edge(x3,y3,x4,y4)) return false;\n    if (!check_edge(x4,y4,x1,y1)) return false;\n    // \u5b9f\u884c\n    dot[x1][y1] = true;\n    used_edge.insert(e1);\n    used_edge.insert(e2);\n    used_edge.insert(e3);\n    used_edge.insert(e4);\n    ops.emplace_back(x1,y1,x2,y2,x3,y3,x4,y4);\n    return true;\n}\n\n// ---------- \u30e1\u30a4\u30f3 ----------\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    auto clk_st = chrono::steady_clock::now();\n\n    cin >> N >> M;\n    c = (N - 1) / 2;\n    w.assign(N, vector<int>(N));\n    dot.assign(N, vector<bool>(N, false));\n    ll S = 0;\n    rep(x,N) rep(y,N) {\n        int wx = (x - c) * (x - c) + (y - c) * (y - c) + 1;\n        w[x][y] = wx;\n        S += wx;\n    }\n    rep(i,M){\n        int x,y; cin >> x >> y;\n        dot[x][y] = true;\n    }\n\n    // \u9ad8\u91cd\u307f\u9806\u306b\u7a7a\u30de\u30b9\u3092\u62fe\u3046\u305f\u3081\u306e\u30ea\u30b9\u30c8\n    vector<pair<int,int>> cells;\n    rep(x,N) rep(y,N) if (!dot[x][y]) cells.emplace_back(x,y);\n    // \u91cd\u307f\u5927\u304d\u3044\u9806\u306b\u30bd\u30fc\u30c8\n    sort(cells.begin(), cells.end(), [&](auto &a, auto &b){\n        return w[a.first][a.second] > w[b.first][b.second];\n    });\n\n    // \u8caa\u6b32\u30e1\u30a4\u30f3\n    const double TIME_LIMIT = 4.8;\n    int iter = 0, total = cells.size();\n    while (1) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - clk_st).count();\n        if (elapsed > TIME_LIMIT) break;\n\n        // \u30e9\u30f3\u30c0\u30e0\u306b\u30d0\u30c3\u30c1\u3092\u62fe\u3046\uff08\u91cd\u3044\u9806\u306b\u3057\u3064\u3064\u30e9\u30f3\u30c0\u30e0\u30cd\u30b9\uff09\n        int batch = min(500, total);\n        vector<int> idx(batch);\n        rep(i,batch) idx[i] = (iter + i) % total;\n        shuffle(idx.begin(), idx.end(), mt19937(iter));\n\n        bool progress = false;\n        for (int i : idx) {\n            auto [x1,y1] = cells[i];\n            if (dot[x1][y1]) continue;\n            // \u8ef8\u5e73\u884c\u9577\u65b9\u5f62\u30924\u65b9\u5411\n            for (int d = 0; d < 4; d++) {\n                int len = 1;\n                while (1) {\n                    int x2 = x1 + len * dxax[d], y2 = y1 + len * dyax[d];\n                    int x3 = x2 + len * dxax[(d+1)&3], y3 = y2 + len * dyax[(d+1)&3];\n                    int x4 = x1 + len * dxax[(d+1)&3], y4 = y1 + len * dyax[(d+1)&3];\n                    if (x2<0||x2>=N||y2<0||y2>=N) break;\n                    if (x3<0||x3>=N||y3<0||y3>=N) break;\n                    if (x4<0||x4>=N||y4<0||y4>=N) break;\n                    if (try_rect(x1,y1,x2,y2,x3,y3,x4,y4)) { progress=true; goto NEXT; }\n                    len++;\n                }\n            }\n            // 45\u00b0\u9577\u65b9\u5f62\u30924\u65b9\u5411\n            for (int d = 0; d < 4; d++) {\n                int len = 1;\n                while (1) {\n                    int x2 = x1 + len * dx45[d], y2 = y1 + len * dy45[d];\n                    int x3 = x2 + len * dx45[(d+1)&3], y3 = y2 + len * dy45[(d+1)&3];\n                    int x4 = x1 + len * dx45[(d+1)&3], y4 = y1 + len * dy45[(d+1)&3];\n                    if (x2<0||x2>=N||y2<0||y2>=N) break;\n                    if (x3<0||x3>=N||y3<0||y3>=N) break;\n                    if (x4<0||x4>=N||y4<0||y4>=N) break;\n                    if (try_rect(x1,y1,x2,y2,x3,y3,x4,y4)) { progress=true; goto NEXT; }\n                    len++;\n                }\n            }\n        }\n        NEXT:\n        iter += batch;\n        if (!progress) break;\n    }\n\n    // \u51fa\u529b\n    cout << ops.size() << \"\\n\";\n    for (auto &[x1,y1,x2,y2,x3,y3,x4,y4] : ops) {\n        cout << x1 << \" \" << y1 << \" \"\n             << x2 << \" \" << y2 << \" \"\n             << x3 << \" \" << y3 << \" \"\n             << x4 << \" \" << y4 << \"\\n\";\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\nusing namespace std::chrono;\n\nstatic const int H = 10, W = 10, C = 3;\nint flavor[100];               // 0-indexed\nchar dirchar[4] = {'F','B','L','R'};\n\nmt19937 rng((uint64_t)(new char));\n\nint grid[H][W];\nint tmp [H][W];\n\nvoid gravity(int g[H][W], int d){\n    // d: 0=F(up),1=B(down),2=L(left),3=right\n    if(d==0){ // forward = up\n        for(int c=0;c<W;c++){\n            int write = 0;\n            for(int r=0;r<H;r++){\n                if(g[r][c]){\n                    if(write!=r) g[write][c] = g[r][c];\n                    write++;\n                }\n            }\n            for(int r=write;r<H;r++) g[r][c]=0;\n        }\n    }\n    else if(d==1){ // backward = down\n        for(int c=0;c<W;c++){\n            int write = H-1;\n            for(int r=H-1;r>=0;r--){\n                if(g[r][c]){\n                    if(write!=r) g[write][c] = g[r][c];\n                    write--;\n                }\n            }\n            for(int r=write;r>=0;r--) g[r][c]=0;\n        }\n    }\n    else if(d==2){ // left\n        for(int r=0;r<H;r++){\n            int write = 0;\n            for(int c=0;c<W;c++){\n                if(g[r][c]){\n                    if(write!=c) g[r][write] = g[r][c];\n                    write++;\n                }\n            }\n            for(int c=write;c<W;c++) g[r][c]=0;\n        }\n    }\n    else { // right\n        for(int r=0;r<H;r++){\n            int write = W-1;\n            for(int c=W-1;c>=0;c--){\n                if(g[r][c]){\n                    if(write!=c) g[r][write] = g[r][c];\n                    write--;\n                }\n            }\n            for(int c=write;c>=0;c--) g[r][c]=0;\n        }\n    }\n}\n\nint eval_once(int g[H][W]){\n    // return sum of squares of component sizes\n    static bool vis[H][W];\n    memset(vis,0,sizeof(vis));\n    int sum = 0;\n    for(int i=0;i<H;i++){\n        for(int j=0;j<W;j++){\n            if(!vis[i][j] && g[i][j]){\n                int col = g[i][j];\n                int sz  = 0;\n                // BFS\n                static deque<pair<int,int>> q;\n                q.emplace_back(i,j);\n                vis[i][j]=1;\n                while(!q.empty()){\n                    auto [r,c] = q.front(); q.pop_front();\n                    sz++;\n                    const int dr[4]={-1,1,0,0}, dc[4]={0,0,-1,1};\n                    for(int d=0;d<4;d++){\n                        int nr=r+dr[d], nc=c+dc[d];\n                        if(nr<0||nr>=H||nc<0||nc>=W) continue;\n                        if(!vis[nr][nc] && g[nr][nc]==col){\n                            vis[nr][nc]=1;\n                            q.emplace_back(nr,nc);\n                        }\n                    }\n                }\n                sum += sz*sz;\n            }\n        }\n    }\n    return sum;\n}\n\nint simulate_rollout(int g[H][W], int t){\n    // copy current state\n    memcpy(tmp, g, sizeof(tmp));\n    // random future\n    for(int k=t+1;k<100;k++){\n        // count empties\n        vector<int> empties;\n        empties.reserve(H*W);\n        for(int i=0;i<H*W;i++){\n            int r=i/W, c=i%W;\n            if(tmp[r][c]==0) empties.push_back(i);\n        }\n        if(empties.empty()) break;\n        uniform_int_distribution<int> uid(0,(int)empties.size()-1);\n        int pos = empties[uid(rng)];\n        int r=pos/W, c=pos%W;\n        tmp[r][c] = flavor[k];\n        // random tilt\n        uniform_int_distribution<int> did(0,3);\n        gravity(tmp, did(rng));\n    }\n    return eval_once(tmp);\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    for(int i=0;i<100;i++){\n        cin>>flavor[i];\n    }\n\n    memset(grid,0,sizeof(grid));\n\n    for(int t=0;t<100;t++){\n        int p; cin>>p; p--;\n        // place candy\n        int cnt=0,rr=-1,cc=-1;\n        for(int i=0;i<H*W;i++){\n            int r=i/W, c=i%W;\n            if(grid[r][c]==0){\n                if(cnt==p){ rr=r; cc=c; break; }\n                cnt++;\n            }\n        }\n        grid[rr][cc] = flavor[t];\n\n        int bestdir = 0, bestscore = -1;\n        const int K = 120; // roll-outs per candidate\n        for(int d=0;d<4;d++){\n            memcpy(tmp, grid, sizeof(tmp));\n            gravity(tmp, d);\n            int avg = 0;\n            for(int k=0;k<K;k++){\n                avg += simulate_rollout(tmp, t);\n            }\n            if(avg > bestscore){\n                bestscore = avg;\n                bestdir   = d;\n            }\n        }\n        // apply best to real grid\n        gravity(grid, bestdir);\n        cout << dirchar[bestdir] << '\\n';\n        cout.flush();\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\n// ---------------  \u57fa\u672c\u8a2d\u5b9a  ----------------\nint M; \ndouble eps;\nconst int MAX_N = 100;\nint N;                       // \u5b9f\u969b\u306b\u9078\u3076\u9802\u70b9\u6570\nint MAX_EDGES;               // N*(N-1)/2\n\n// \u5404 G_k \u306e\u8fba\u96c6\u5408\uff08bitmask \u3067\u3082 vector<bitset<>> \u3067\u3082\u53ef\uff09\n// \u3053\u3053\u3067\u306f\u96a3\u63a5\u884c\u5217\u3092 vector<bitset<MAX_N>> \u3067\u6301\u3064\nvector<bitset<MAX_N>> G[MAX_N*MAX_N]; // G[k][i][j] = 1 \u306a\u3089\u8fba (i,j) \u5b58\u5728\n\n// \u5404 G_k \u306e\u300c\u8fba\u6570\u300d\u304a\u3088\u3073\u300c\u6b21\u6570\u5217\uff08\u30bd\u30fc\u30c8\u6e08\u307f\uff09\u300d\nvector<int> target_edges;   // target_edges[k]\nvector<vector<int>> deg_seq; // deg_seq[k] : \u9577\u3055 N\u3001\u30bd\u30fc\u30c8\u6e08\u307f\n\n// --------------  \u4e8b\u524d\u8a08\u7b97\uff08Binomial \u5bfe\u6570\uff09 --------------\nconst int MAX_BINOM = MAX_N*MAX_N;\ndouble logfact[MAX_BINOM+1];\nvoid init_logfact(){\n    logfact[0] = 0.0;\n    for(int i=1;i<=MAX_BINOM;i++){\n        logfact[i] = logfact[i-1] + log(i);\n    }\n}\ninline double logbinom(int n, int k){\n    if(k<0||k>n) return -1e300;\n    return logfact[n] - logfact[k] - logfact[n-k];\n}\n\n// --------------  \u30b0\u30e9\u30d5\u51fa\u529b\u7528\u30a8\u30f3\u30b3\u30fc\u30c0 -----------------\nstring encode_graph(const vector<bitset<MAX_N>>& adj){\n    string s;\n    for(int i=0;i<N;i++){\n        for(int j=i+1;j<N;j++){\n            s += (adj[i][j] ? '1':'0');\n        }\n    }\n    return s;\n}\n\n// --------------  \u30e9\u30f3\u30c0\u30e0\u8fba\u751f\u6210 ------------------------\nvoid build_random_graph(vector<bitset<MAX_N>>& adj, int m){\n    adj.assign(N, bitset<MAX_N>());\n    int total = N*(N-1)/2;\n    vector<int> idx(total);\n    iota(idx.begin(), idx.end(), 0);\n    shuffle(idx.begin(), idx.end(), mt19937(12345));\n    for(int t=0;t<m;t++){\n        int e = idx[t];\n        int i = 0, j = 1;\n        // e \u756a\u76ee\u306e (i,j) (i<j) \u3092\u5fa9\u5143\n        int cnt = 0;\n        for(i=0;i<N;i++){\n            for(j=i+1;j<N;j++){\n                if(cnt==e) goto found;\n                cnt++;\n            }\n        }\n        found:\n        adj[i][j] = adj[j][i] = 1;\n    }\n}\n\n// --------------  \u6b21\u6570\u5217\u53d6\u5f97 --------------------------\nvector<int> get_degree_sequence(const vector<bitset<MAX_N>>& adj){\n    vector<int> deg(N);\n    for(int i=0;i<N;i++){\n        deg[i] = adj[i].count();\n    }\n    sort(deg.rbegin(), deg.rend());\n    return deg;\n}\n\n// --------------  \u5bfe\u6570\u5c24\u5ea6\u8fd1\u4f3c ------------------------\n// \u8fba\u6570 m \u306e\u307f\u3092\u898b\u308b\u7c21\u6613\u7248\ndouble loglikelihood_edge(int m, int k){\n    int total = N*(N-1)/2;\n    double p = (double)target_edges[k] / total;\n    // \u53cd\u8ee2\u5f8c\u306e\u671f\u5f85\u8fba\u6570\n    double mu = target_edges[k]*(1 - 2*eps) + eps*total;\n    double sigma2 = eps*(1 - eps)*total;\n    // \u6b63\u898f\u8fd1\u4f3c\n    double diff = m - mu;\n    return -0.5 * diff*diff / sigma2;\n}\n\n// --------------  \u30e1\u30a4\u30f3 --------------------------------\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // \u5165\u529b\n    cin >> M >> eps;\n\n    // N \u3092\u6c7a\u5b9a\uff08\u5c0f\u3055\u3044\u307b\u3046\u304c\u30b9\u30b3\u30a2\u500d\u7387\u304c\u9ad8\u3044\u304c\u3001\u8b58\u5225\u80fd\u529b\u304c\u843d\u3061\u308b\uff09\n    // \u3068\u308a\u3042\u3048\u305a N=20 \u3067\u56fa\u5b9a\n    N = 20;\n    MAX_EDGES = N*(N-1)/2;\n\n    // \u5bfe\u6570factorial \u521d\u671f\u5316\n    init_logfact();\n\n    // \u5404 G_k \u306e\u300c\u76ee\u6a19\u8fba\u6570\u300d\u3092\u7b49\u9593\u9694\u306b\n    target_edges.resize(M);\n    double step = (double)MAX_EDGES / (M-1);\n    for(int k=0;k<M;k++){\n        target_edges[k] = (int)round( k * step );\n    }\n\n    // \u5404 G_k \u3092\u751f\u6210 & \u6b21\u6570\u5217\u8a08\u7b97\n    for(int k=0;k<M;k++){\n        build_random_graph(G[k], target_edges[k]);\n        deg_seq.emplace_back( get_degree_sequence(G[k]) );\n    }\n\n    // \u51fa\u529b\n    cout << N << \"\\n\";\n    for(int k=0;k<M;k++){\n        cout << encode_graph(G[k]) << \"\\n\";\n    }\n    cout.flush();\n\n    // \u30af\u30a8\u30ea\u51e6\u7406\n    for(int q=0;q<100;q++){\n        string Hstr;\n        cin >> Hstr;\n        // H \u3092\u96a3\u63a5\u884c\u5217\u306b\n        vector<bitset<MAX_N>> H(N);\n        int ptr = 0;\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                if(Hstr[ptr++]=='1'){\n                    H[i][j] = H[j][i] = 1;\n                }\n            }\n        }\n        // \u8fba\u6570\n        int m = 0;\n        for(int i=0;i<N;i++) m += H[i].count();\n        m /= 2;\n\n        // \u5404 k \u306b\u3064\u3044\u3066\u5bfe\u6570\u5c24\u5ea6\uff08\u8fba\u6570\u306e\u307f\uff09\u3092\u8a08\u7b97\n        int best_k = 0;\n        double best_ll = -1e300;\n        for(int k=0;k<M;k++){\n            double ll = loglikelihood_edge(m, k);\n            if(ll > best_ll){\n                best_ll = ll;\n                best_k = k;\n            }\n        }\n        cout << best_k << \"\\n\";\n        cout.flush();\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\nconst int MAX_N = 1005;\nconst int MAX_M = 3005;\n\nint N, M, D, K;\nint u[MAX_M], v[MAX_M], w[MAX_M];\nint x[MAX_N], y[MAX_N];\nint assignment[MAX_M];\nint dist[MAX_N][MAX_N];\nint original_dist[MAX_N][MAX_N];\nvector<pair<int, int>> adj[MAX_N];\n\n// Calculate edge importance based on shortest path usage\nvector<int> calculate_edge_importance() {\n    vector<int> importance(M, 0);\n    \n    // Count how many shortest paths use each edge\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (i == j) continue;\n            int shortest_dist = original_dist[i][j];\n            \n            // Check if removing this edge would increase the distance\n            for (int e = 0; e < M; e++) {\n                // Simple heuristic: edges with low weight and high betweenness are important\n                if (original_dist[i][u[e]] + w[e] + original_dist[v[e]][j] == shortest_dist ||\n                    original_dist[i][v[e]] + w[e] + original_dist[u[e]][j] == shortest_dist) {\n                    importance[e]++;\n                }\n            }\n        }\n    }\n    \n    return importance;\n}\n\n// Calculate frustration for a given assignment\ndouble calculate_frustration() {\n    double total_frustration = 0.0;\n    \n    for (int day = 1; day <= D; day++) {\n        // Build graph for this day\n        vector<pair<int, int>> day_adj[MAX_N];\n        vector<bool> edge_removed(M, false);\n        \n        for (int e = 0; e < M; e++) {\n            if (assignment[e] == day) {\n                edge_removed[e] = true;\n            } else {\n                day_adj[u[e]].push_back({v[e], w[e]});\n                day_adj[v[e]].push_back({u[e], w[e]});\n            }\n        }\n        \n        // Calculate all-pairs shortest paths for this day\n        int day_dist[MAX_N][MAX_N];\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                day_dist[i][j] = (i == j) ? 0 : INF;\n            }\n        }\n        \n        // Use Dijkstra's algorithm for each vertex\n        for (int src = 0; src < N; src++) {\n            priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;\n            pq.push({0, src});\n            \n            while (!pq.empty()) {\n                auto [d, u_node] = pq.top();\n                pq.pop();\n                \n                if (d > day_dist[src][u_node]) continue;\n                \n                for (auto [v_node, weight] : day_adj[u_node]) {\n                    if (day_dist[src][v_node] > d + weight) {\n                        day_dist[src][v_node] = d + weight;\n                        pq.push({day_dist[src][v_node], v_node});\n                    }\n                }\n            }\n        }\n        \n        // Calculate frustration for this day\n        double day_frustration = 0.0;\n        int count = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (i != j) {\n                    int increase = day_dist[i][j] - original_dist[i][j];\n                    if (day_dist[i][j] == INF) increase = INF - original_dist[i][j];\n                    day_frustration += increase;\n                    count++;\n                }\n            }\n        }\n        \n        total_frustration += day_frustration / count;\n    }\n    \n    return total_frustration / D;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> D >> K;\n    \n    for (int i = 0; i < M; i++) {\n        cin >> u[i] >> v[i] >> w[i];\n        u[i]--; v[i]--;\n        adj[u[i]].push_back({v[i], w[i]});\n        adj[v[i]].push_back({u[i], w[i]});\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n    \n    // Calculate original shortest paths\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            original_dist[i][j] = (i == j) ? 0 : INF;\n        }\n    }\n    \n    for (int src = 0; src < N; src++) {\n        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;\n        pq.push({0, src});\n        \n        while (!pq.empty()) {\n            auto [d, u_node] = pq.top();\n            pq.pop();\n            \n            if (d > original_dist[src][u_node]) continue;\n            \n            for (auto [v_node, weight] : adj[u_node]) {\n                if (original_dist[src][v_node] > d + weight) {\n                    original_dist[src][v_node] = d + weight;\n                    pq.push({original_dist[src][v_node], v_node});\n                }\n            }\n        }\n    }\n    \n    // Calculate edge importance\n    vector<int> importance = calculate_edge_importance();\n    \n    // Sort edges by importance (descending)\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 importance[a] > importance[b];\n    });\n    \n    // Assign edges to days using a greedy approach\n    vector<int> day_load(D + 1, 0);\n    \n    // First, try to balance important edges across days\n    for (int e : edge_order) {\n        // Find the day with minimum load that can accommodate this edge\n        int best_day = 1;\n        int min_load = day_load[1];\n        \n        for (int day = 2; day <= D; day++) {\n            if (day_load[day] < min_load) {\n                min_load = day_load[day];\n                best_day = day;\n            }\n        }\n        \n        assignment[e] = best_day;\n        day_load[best_day]++;\n    }\n    \n    // Local search improvement\n    double best_frustration = calculate_frustration();\n    bool improved = true;\n    \n    while (improved) {\n        improved = false;\n        \n        // Try swapping edges between days\n        for (int e1 = 0; e1 < M; e1++) {\n            for (int e2 = e1 + 1; e2 < M; e2++) {\n                if (assignment[e1] != assignment[e2]) {\n                    // Try swapping\n                    int old_day1 = assignment[e1];\n                    int old_day2 = assignment[e2];\n                    \n                    assignment[e1] = old_day2;\n                    assignment[e2] = old_day1;\n                    \n                    double new_frustration = calculate_frustration();\n                    \n                    if (new_frustration < best_frustration) {\n                        best_frustration = new_frustration;\n                        improved = true;\n                    } else {\n                        // Revert\n                        assignment[e1] = old_day1;\n                        assignment[e2] = old_day2;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Output the assignment\n    for (int i = 0; i < M; i++) {\n        cout << assignment[i] << (i == M - 1 ? \"\\n\" : \" \");\n    }\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nusing ull = unsigned long long;\nusing int2 = __int128_t;\n\nstatic constexpr int MAXD = 14;\nstatic constexpr int MAXV = 16;               // max volume of generated blocks\nstatic constexpr int MAXB = 40000;            // max number of generated blocks\nstatic constexpr double TIME_LIMIT = 5.8;\n\nint D, DD, DDD;\nbitset<MAXD*MAXD*MAXD> mandatory[2], sharedMandatory;\nint mandatoryVol[2], sharedVol;\n\nstruct Block {\n    int vol;\n    vector<tuple<int,int,int>> cells;   // original coordinates\n    vector<vector<tuple<int,int,int>>> rot; // 24 rotations\n};\nint nBlocks = 0;\nBlock blocks[MAXB];\n\n// ---------- utilities ----------\ninline int idx(int x, int y, int z) { return x*D*D + y*D + z; }\ninline bool inside(int x, int y, int z) {\n    return 0 <= x && x < D && 0 <= y && y < D && 0 <= z && z < D;\n}\n\n// ---------- rotation ----------\nvector<vector<tuple<int,int,int>>> generateRotations(const vector<tuple<int,int,int>>& src) {\n    vector<vector<tuple<int,int,int>>> res;\n    set<vector<tuple<int,int,int>>> seen;\n    for (int rx = 0; rx < 4; ++rx)\n    for (int ry = 0; ry < 4; ++ry)\n    for (int rz = 0; rz < 4; ++rz) {\n        vector<tuple<int,int,int>> tmp;\n        for (auto [x,y,z] : src) {\n            int cx = x, cy = y, cz = z;\n            // rotate around X\n            for (int k = 0; k < rx; ++k) {\n                int ny = -cz, nz = cy;\n                cy = ny; cz = nz;\n            }\n            // rotate around Y\n            for (int k = 0; k < ry; ++k) {\n                int nx = cz, nz = -cx;\n                cx = nx; cz = nz;\n            }\n            // rotate around Z\n            for (int k = 0; k < rz; ++k) {\n                int nx = -cy, ny = cx;\n                cx = nx; cy = ny;\n            }\n            tmp.emplace_back(cx, cy, cz);\n        }\n        // normalize\n        int minx=INT_MAX, miny=INT_MAX, minz=INT_MAX;\n        for (auto [x,y,z] : tmp) {\n            minx = min(minx, x); miny = min(miny, y); minz = min(minz, z);\n        }\n        for (auto& [x,y,z] : tmp) {\n            x -= minx; y -= miny; z -= minz;\n        }\n        sort(tmp.begin(), tmp.end());\n        if (seen.insert(tmp).second) res.push_back(tmp);\n    }\n    return res;\n}\n\n// ---------- polycube generation ----------\nvoid generateBlocks() {\n    // BFS enumeration of all free polycubes up to volume MAXV\n    map<vector<tuple<int,int,int>>, int> canonicalId;\n    queue<pair<vector<tuple<int,int,int>>, int>> q;\n    q.push({{{0,0,0}}, 1});\n    canonicalId[{{{0,0,0}}}] = 1;\n    int dx[] = {1,-1,0,0,0,0}, dy[] = {0,0,1,-1,0,0}, dz[] = {0,0,0,0,1,-1};\n    while (!q.empty() && nBlocks < MAXB) {\n        auto [shape, vol] = q.front(); q.pop();\n        if (vol > MAXV) continue;\n        // store this shape\n        {\n            Block& B = blocks[nBlocks++];\n            B.vol = vol;\n            B.cells = shape;\n            B.rot = generateRotations(shape);\n        }\n        // expand\n        set<tuple<int,int,int>> frontier;\n        for (auto [x,y,z] : shape)\n        for (int d = 0; d < 6; ++d) {\n            int nx = x+dx[d], ny = y+dy[d], nz = z+dz[d];\n            if (!inside(nx,ny,nz)) continue;\n            if (find(shape.begin(), shape.end(), make_tuple(nx,ny,nz)) != shape.end()) continue;\n            frontier.emplace(nx,ny,nz);\n        }\n        for (auto [x,y,z] : frontier) {\n            auto ns = shape;\n            ns.emplace_back(x,y,z);\n            // normalize\n            int minx=INT_MAX,miny=INT_MAX,minz=INT_MAX;\n            for (auto [xx,yy,zz] : ns) {\n                minx=min(minx,xx); miny=min(miny,yy); minz=min(minz,zz);\n            }\n            for (auto& [xx,yy,zz] : ns) {\n                xx-=minx; yy-=miny; zz-=minz;\n            }\n            sort(ns.begin(), ns.end());\n            if (canonicalId.count(ns)) continue;\n            canonicalId[ns] = 1;\n            q.push({ns, vol+1});\n        }\n    }\n    cerr << \"generated \" << nBlocks << \" blocks up to volume \" << MAXV << \"\\n\";\n}\n\n// ---------- placement ----------\nstruct Placement {\n    bitset<MAXD*MAXD*MAXD> occ;\n    int usedVol;\n    vector<int> blockIds;\n    vector<vector<tuple<int,int,int>>> poses; // for each block, its rotated+translated cells\n};\nPlacement bestP[2];\ndouble bestScore = 1e18;\n\n// try to place block B with rotation r at (bx,by,bz) into grid g\nbool canPlace(const bitset<MAXD*MAXD*MAXD>& g, const Block& B, int r, int bx, int by, int bz) {\n    for (auto [x,y,z] : B.rot[r]) {\n        int xx = x+bx, yy = y+by, zz = z+bz;\n        if (!inside(xx,yy,zz)) return false;\n        if (g.test(idx(xx,yy,zz))) return false;\n    }\n    return true;\n}\nvoid place(bitset<MAXD*MAXD*MAXD>& g, const Block& B, int r, int bx, int by, int bz) {\n    for (auto [x,y,z] : B.rot[r]) {\n        int xx = x+bx, yy = y+by, zz = z+bz;\n        g.set(idx(xx,yy,zz));\n    }\n}\n\n// greedy cover for one silhouette\nPlacement greedyCover(const bitset<MAXD*MAXD*MAXD>& target, int which) {\n    Placement P;\n    P.occ.reset(); P.usedVol = 0;\n    vector<int> order(nBlocks);\n    iota(order.begin(), order.end(), 0);\n    // sort by 1/vol descending\n    sort(order.begin(), order.end(), [&](int a, int b){\n        return blocks[a].vol > blocks[b].vol;\n    });\n    bitset<MAXD*MAXD*MAXD> rem = target;\n    int remVol = target.count();\n    for (int id : order) {\n        if (remVol == 0) break;\n        const Block& B = blocks[id];\n        bool placed = false;\n        // try all rotations and positions\n        for (int r = 0; r < (int)B.rot.size() && !placed; ++r) {\n            int maxx=0,maxy=0,maxz=0;\n            for (auto [x,y,z] : B.rot[r]) {\n                maxx=max(maxx,x); maxy=max(maxy,y); maxz=max(maxz,z);\n            }\n            for (int bx = 0; bx + maxx < D && !placed; ++bx)\n            for (int by = 0; by + maxy < D && !placed; ++by)\n            for (int bz = 0; bz + maxz < D && !placed; ++bz) {\n                if (!canPlace(P.occ, B, r, bx,by,bz)) continue;\n                // check if it covers at least one remaining voxel\n                bool cov = false;\n                for (auto [x,y,z] : B.rot[r]) {\n                    int xx = x+bx, yy = y+by, zz = z+bz;\n                    if (rem.test(idx(xx,yy,zz))) { cov=true; break; }\n                }\n                if (!cov) continue;\n                // place it\n                place(P.occ, B, r, bx,by,bz);\n                P.blockIds.push_back(id);\n                vector<tuple<int,int,int>> pose;\n                for (auto [x,y,z] : B.rot[r]) pose.emplace_back(x+bx, y+by, z+bz);\n                P.poses.push_back(pose);\n                P.usedVol += B.vol;\n                // update rem\n                for (auto [x,y,z] : B.rot[r]) {\n                    int xx = x+bx, yy = y+by, zz = z+bz;\n                    rem.reset(idx(xx,yy,zz));\n                }\n                remVol = rem.count();\n                placed = true;\n            }\n        }\n    }\n    return P;\n}\n\n// ---------- scoring ----------\ndouble eval(const Placement& p1, const Placement& p2) {\n    // build set of used blocks\n    unordered_set<int> used1(p1.blockIds.begin(), p1.blockIds.end());\n    unordered_set<int> used2(p2.blockIds.begin(), p2.blockIds.end());\n    int r1 = 0, r2 = 0;\n    double sumInv = 0.0;\n    for (int i = 0; i < nBlocks; ++i) {\n        bool in1 = used1.count(i), in2 = used2.count(i);\n        if (!in1 && !in2) continue; // not allowed, but we prune earlier\n        if (!in1) r1 += blocks[i].vol;\n        if (!in2) r2 += blocks[i].vol;\n        if (in1 && in2) sumInv += 1.0 / blocks[i].vol;\n    }\n    double score = r1 + r2 + sumInv;\n    return score;\n}\n\n// ---------- output ----------\nvoid output(const Placement& p1, const Placement& p2) {\n    // build global block list\n    unordered_map<int,int> globalId;\n    int nOut = 0;\n    for (int id : p1.blockIds) if (!globalId.count(id)) globalId[id] = nOut++;\n    for (int id : p2.blockIds) if (!globalId.count(id)) globalId[id] = nOut++;\n    cout << nOut << \"\\n\";\n    // output b1\n    vector<int> flat1(D*D*D, 0);\n    for (int i = 0; i < (int)p1.blockIds.size(); ++i) {\n        int gid = globalId[p1.blockIds[i]];\n        for (auto [x,y,z] : p1.poses[i]) {\n            flat1[idx(x,y,z)] = gid+1;\n        }\n    }\n    for (int i = 0; i < DDD; ++i) {\n        if (i) cout << \" \";\n        cout << flat1[i];\n    }\n    cout << \"\\n\";\n    // output b2\n    vector<int> flat2(D*D*D, 0);\n    for (int i = 0; i < (int)p2.blockIds.size(); ++i) {\n        int gid = globalId[p2.blockIds[i]];\n        for (auto [x,y,z] : p2.poses[i]) {\n            flat2[idx(x,y,z)] = gid+1;\n        }\n    }\n    for (int i = 0; i < DDD; ++i) {\n        if (i) cout << \" \";\n        cout << flat2[i];\n    }\n    cout << \"\\n\";\n}\n\n// ---------- main ----------\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    auto clk = chrono::high_resolution_clock::now();\n\n    cin >> D;\n    DD = D*D; DDD = D*D*D;\n    // read silhouettes\n    vector<string> fstr[2], rstr[2];\n    for (int i = 0; i < 2; ++i) {\n        fstr[i].resize(D);\n        for (int z = 0; z < D; ++z) cin >> fstr[i][z];\n        rstr[i].resize(D);\n        for (int z = 0; z < D; ++z) cin >> rstr[i][z];\n    }\n    // build mandatory voxels\n    for (int i = 0; i < 2; ++i) {\n        mandatory[i].reset();\n        for (int x = 0; x < D; ++x)\n        for (int y = 0; y < D; ++y)\n        for (int z = 0; z < D; ++z) {\n            if (fstr[i][z][x]=='1' && rstr[i][z][y]=='1') {\n                mandatory[i].set(idx(x,y,z));\n            }\n        }\n        mandatoryVol[i] = mandatory[i].count();\n    }\n    sharedMandatory = mandatory[0] & mandatory[1];\n    sharedVol = sharedMandatory.count();\n\n    // generate block catalogue\n    generateBlocks();\n\n    // greedy cover for each silhouette\n    bestP[0] = greedyCover(mandatory[0], 0);\n    bestP[1] = greedyCover(mandatory[1], 1);\n    bestScore = eval(bestP[0], bestP[1]);\n\n    // simple iterative improvement: try to replace one block by a larger unused one\n    // (very fast, so we do many iterations)\n    int iter = 0;\n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - clk).count();\n        if (elapsed > TIME_LIMIT) break;\n        iter++;\n        // pick random placement\n        int w = rand()&1;\n        Placement& P = bestP[w];\n        if (P.blockIds.empty()) continue;\n        int k = rand() % P.blockIds.size();\n        int oldId = P.blockIds[k];\n        // try all bigger unused blocks\n        bool improved = false;\n        for (int cand = 0; cand < nBlocks && !improved; ++cand) {\n            if (blocks[cand].vol <= blocks[oldId].vol) continue;\n            // try to place cand instead of oldId\n            Placement tmp = P;\n            // remove oldId\n            tmp.occ.reset();\n            tmp.usedVol -= blocks[oldId].vol;\n            tmp.blockIds.erase(tmp.blockIds.begin()+k);\n            tmp.poses.erase(tmp.poses.begin()+k);\n            // rebuild occ\n            for (int i = 0; i < (int)tmp.blockIds.size(); ++i) {\n                const Block& B = blocks[tmp.blockIds[i]];\n                for (auto [x,y,z] : tmp.poses[i]) tmp.occ.set(idx(x,y,z));\n            }\n            // try to add cand somewhere\n            const Block& B = blocks[cand];\n            bool placed = false;\n            for (int r = 0; r < (int)B.rot.size() && !placed; ++r) {\n                int maxx=0,maxy=0,maxz=0;\n                for (auto [x,y,z] : B.rot[r]) {\n                    maxx=max(maxx,x); maxy=max(maxy,y); maxz=max(maxz,z);\n                }\n                for (int bx = 0; bx + maxx < D && !placed; ++bx)\n                for (int by = 0; by + maxy < D && !placed; ++by)\n                for (int bz = 0; bz + maxz < D && !placed; ++bz) {\n                    if (!canPlace(tmp.occ, B, r, bx,by,bz)) continue;\n                    // check it covers at least one missing voxel\n                    bitset<MAXD*MAXD*MAXD> need = mandatory[w];\n                    for (int i = 0; i < (int)tmp.blockIds.size(); ++i)\n                        for (auto [x,y,z] : tmp.poses[i]) need.reset(idx(x,y,z));\n                    bool cov = false;\n                    for (auto [x,y,z] : B.rot[r]) {\n                        int xx = x+bx, yy = y+by, zz = z+bz;\n                        if (need.test(idx(xx,yy,zz))) { cov=true; break; }\n                    }\n                    if (!cov) continue;\n                    // place it\n                    place(tmp.occ, B, r, bx,by,bz);\n                    tmp.blockIds.push_back(cand);\n                    vector<tuple<int,int,int>> pose;\n                    for (auto [x,y,z] : B.rot[r]) pose.emplace_back(x+bx, y+by, z+bz);\n                    tmp.poses.push_back(pose);\n                    tmp.usedVol += B.vol;\n                    placed = true;\n                }\n            }\n            if (!placed) continue;\n            // finish covering with greedy\n            bitset<MAXD*MAXD*MAXD> rem = mandatory[w];\n            for (int i = 0; i < (int)tmp.blockIds.size(); ++i)\n                for (auto [x,y,z] : tmp.poses[i]) rem.reset(idx(x,y,z));\n            if (rem.any()) {\n                Placement fill = greedyCover(rem, w);\n                for (int i = 0; i < (int)fill.blockIds.size(); ++i) {\n                    tmp.blockIds.push_back(fill.blockIds[i]);\n                    tmp.poses.push_back(fill.poses[i]);\n                    tmp.usedVol += blocks[fill.blockIds[i]].vol;\n                    for (auto [x,y,z] : fill.poses[i]) tmp.occ.set(idx(x,y,z));\n                }\n            }\n            // evaluate\n            double sc = eval(tmp, bestP[w^1]);\n            if (sc < bestScore) {\n                bestScore = sc;\n                bestP[w] = tmp;\n                improved = true;\n            }\n        }\n    }\n\n    cerr << \"iterations \" << iter << \" bestScore \" << bestScore << \"\\n\";\n    output(bestP[0], bestP[1]);\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing int64 = long long;\n\nstatic const int MAXN = 105;\nstatic const int MAXM = 305;\nstatic const int MAXK = 5005;\n\nint N, M, K;\ndouble x[MAXN], y[MAXN];\nint u_e[MAXM], v_e[MAXM], w_e[MAXM];\ndouble a[MAXK], b[MAXK];\n\n// for MST\nint parent[MAXN];\nint find_set(int v) {\n    if (v == parent[v]) return v;\n    return parent[v] = find_set(parent[v]);\n}\nbool union_set(int u, int v) {\n    u = find_set(u);\n    v = find_set(v);\n    if (u == v) return false;\n    parent[v] = u;\n    return true;\n}\n\n// graph\nvector<pair<int,int>> adj[MAXN]; // (neighbor, edge_index)\n\n// MST result\nbool in_mst[MAXM];\nint64 total_edge_cost = 0;\n\n// resident -> distance to each vertex\ndouble dist_ik[MAXK][MAXN];\n\n// current solution\nint P[MAXN];\nbool edge_on[MAXM];\n\n// ---------- helper: recompute vertex cost for a given reachable mask ----------\nint64 recompute_vertex_cost(const vector<char>& reachable,\n                            vector<int>& bestP)\n{\n    // for each resident, closest reachable vertex and distance\n    vector<int>   assign_i(K);\n    vector<double> assign_d(K);\n    for (int k = 0; k < K; k++) {\n        double best_d = 1e18;\n        int best_i = -1;\n        for (int i = 0; i < N; i++) if (reachable[i]) {\n            if (dist_ik[k][i] < best_d) {\n                best_d = dist_ik[k][i];\n                best_i = i;\n            }\n        }\n        assign_i[k] = best_i;\n        assign_d[k] = best_d;\n    }\n    // compute P_i\n    bestP.assign(N, 0);\n    for (int k = 0; k < K; k++) {\n        int i = assign_i[k];\n        int need = (int)ceil(assign_d[k]);\n        bestP[i] = max(bestP[i], need);\n    }\n    int64 cost = 0;\n    for (int i = 0; i < N; i++) cost += (int64)bestP[i] * bestP[i];\n    return cost;\n}\n\n// ---------- main ----------\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> K;\n    for(int i = 0; i < N; i++){\n        cin >> x[i] >> y[i];\n    }\n    for(int j = 0; j < M; j++){\n        cin >> u_e[j] >> v_e[j] >> w_e[j];\n        --u_e[j]; --v_e[j];\n    }\n    for(int k = 0; k < K; k++){\n        cin >> a[k] >> b[k];\n    }\n\n    // precompute resident->vertex distances\n    for(int k = 0; k < K; k++){\n        for(int i = 0; i < N; i++){\n            double dx = x[i] - a[k];\n            double dy = y[i] - b[k];\n            dist_ik[k][i] = sqrt(dx*dx + dy*dy);\n        }\n    }\n\n    // Kruskal MST\n    for(int i = 0; i < N; i++) parent[i] = i;\n    vector<int> edges_order(M);\n    iota(edges_order.begin(), edges_order.end(), 0);\n    sort(edges_order.begin(), edges_order.end(),\n         [&](int j1, int j2){ return w_e[j1] < w_e[j2]; });\n\n    fill(in_mst, in_mst + M, false);\n    for(int jj = 0; jj < M; jj++){\n        int j = edges_order[jj];\n        if (union_set(u_e[j], v_e[j])) {\n            in_mst[j] = true;\n            total_edge_cost += w_e[j];\n        }\n    }\n\n    // build adj for BFS later\n    for(int j = 0; j < M; j++){\n        if (in_mst[j]){\n            adj[u_e[j]].emplace_back(v_e[j], j);\n            adj[v_e[j]].emplace_back(u_e[j], j);\n        }\n    }\n\n    // initial full reachable\n    vector<char> fullReach(N, true);\n    vector<int>  bestP(N);\n    int64 vertex_cost = recompute_vertex_cost(fullReach, bestP);\n    // copy to solution\n    for(int i = 0; i < N; i++) P[i] = bestP[i];\n    for(int j = 0; j < M; j++) edge_on[j] = in_mst[j];\n\n    // greedy deletion pass: try removing tree edges, largest weight first\n    vector<int> tree_edges;\n    for(int j = 0; j < M; j++) if (in_mst[j]) tree_edges.push_back(j);\n    sort(tree_edges.begin(), tree_edges.end(),\n         [&](int j1, int j2){ return w_e[j1] > w_e[j2]; });\n\n    bool improved;\n    do {\n        improved = false;\n        for(int j_idx = 0; j_idx < (int)tree_edges.size(); j_idx++){\n            int j = tree_edges[j_idx];\n            if (!edge_on[j]) continue; // already removed\n\n            // temporarily remove edge j\n            edge_on[j] = false;\n            // BFS reachable\n            vector<char> reach(N, false);\n            queue<int> q;\n            reach[0] = true; q.push(0);\n            while(!q.empty()){\n                int u = q.front(); q.pop();\n                for(auto& [v, eidx] : adj[u]){\n                    if (!edge_on[eidx]) continue;\n                    if (!reach[v]){\n                        reach[v] = true;\n                        q.push(v);\n                    }\n                }\n            }\n            // recompute vertex cost\n            vector<int> newP(N);\n            int64 new_vertex_cost = recompute_vertex_cost(reach, newP);\n            int64 saved = w_e[j];\n            int64 extra = new_vertex_cost - vertex_cost;\n            if (extra < saved){\n                // accept deletion\n                vertex_cost = new_vertex_cost;\n                for(int i = 0; i < N; i++) P[i] = newP[i];\n                improved = true;\n            } else {\n                // revert\n                edge_on[j] = true;\n            }\n        }\n    } while(improved);\n\n    // output\n    for(int i = 0; i < N; i++){\n        cout << P[i] << (i+1<N?' ':'\\n');\n    }\n    for(int j = 0; j < M; j++){\n        cout << (edge_on[j]?1:0) << (j+1<M?' ':'\\n');\n    }\n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\nstruct Ball {\n    int value;\n    int x, y;\n};\n\nconst int N = 30;\nconst int MAX_SWAPS = 10000;\n\nint pyramid[N][N];\nvector<pair<pair<int,int>, pair<int,int>>> swaps;\n\n// Check if two positions are adjacent in 6 directions\nbool isAdjacent(int x1, int y1, int x2, int y2) {\n    if (x1 == x2-1 && (y1 == y2-1 || y1 == y2)) return true;\n    if (x1 == x2 && (y1 == y2-1 || y1 == y2+1)) return true;\n    if (x1 == x2+1 && (y1 == y2 || y1 == y2+1)) return true;\n    return false;\n}\n\n// Swap two balls and record the operation\nvoid performSwap(int x1, int y1, int x2, int y2) {\n    swap(pyramid[x1][y1], pyramid[x2][y2]);\n    swaps.push_back({{x1, y1}, {x2, y2}});\n}\n\n// Check if position (x,y) violates the heap property\nbool violatesHeap(int x, int y) {\n    if (x == N-1) return false; // Bottom tier doesn't violate\n    \n    int val = pyramid[x][y];\n    int leftChild = pyramid[x+1][y];\n    int rightChild = pyramid[x+1][y+1];\n    \n    return val > leftChild || val > rightChild;\n}\n\n// Find path to bring a small value up\nvector<pair<int,int>> findBubblePath(int targetX, int targetY) {\n    vector<pair<int,int>> path;\n    int x = targetX, y = targetY;\n    \n    while (x > 0) {\n        // Try to move up-left first\n        if (y > 0 && x-1 >= 0 && y-1 >= 0) {\n            path.push_back({x-1, y-1});\n            x--; y--;\n        }\n        // Then try up-right\n        else if (y < x && x-1 >= 0 && y < x-1) {\n            path.push_back({x-1, y});\n            x--;\n        }\n        else {\n            break;\n        }\n    }\n    \n    return path;\n}\n\n// Bubble a value up to its correct position\nvoid bubbleUp(int startX, int startY) {\n    int x = startX, y = startY;\n    \n    while (x > 0) {\n        int parentX = -1, parentY = -1;\n        \n        // Find parent position\n        if (y > 0 && pyramid[x-1][y-1] > pyramid[x][y]) {\n            parentX = x-1; parentY = y-1;\n        }\n        else if (y < x && pyramid[x-1][y] > pyramid[x][y]) {\n            parentX = x-1; parentY = y;\n        }\n        \n        if (parentX == -1) break;\n        \n        performSwap(x, y, parentX, parentY);\n        x = parentX; y = parentY;\n        \n        if (swaps.size() >= MAX_SWAPS) return;\n    }\n}\n\n// Main algorithm: iterative improvement\nvoid solve() {\n    // Read input\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j <= i; j++) {\n            cin >> pyramid[i][j];\n        }\n    }\n    \n    // Multiple passes to fix violations\n    for (int pass = 0; pass < 5 && swaps.size() < MAX_SWAPS; pass++) {\n        bool improved = false;\n        \n        // Process from bottom to top\n        for (int x = N-2; x >= 0; x--) {\n            for (int y = 0; y <= x; y++) {\n                if (violatesHeap(x, y)) {\n                    bubbleUp(x, y);\n                    improved = true;\n                    \n                    if (swaps.size() >= MAX_SWAPS) return;\n                }\n            }\n        }\n        \n        if (!improved) break;\n    }\n    \n    // Local optimization: fix remaining violations\n    for (int iter = 0; iter < 100 && swaps.size() < MAX_SWAPS; iter++) {\n        bool fixed = false;\n        \n        for (int x = 0; x < N-1 && !fixed; x++) {\n            for (int y = 0; y <= x && !fixed; y++) {\n                if (violatesHeap(x, y)) {\n                    int val = pyramid[x][y];\n                    \n                    // Try swapping with children\n                    if (val > pyramid[x+1][y]) {\n                        performSwap(x, y, x+1, y);\n                        fixed = true;\n                    }\n                    else if (val > pyramid[x+1][y+1]) {\n                        performSwap(x, y, x+1, y+1);\n                        fixed = true;\n                    }\n                    \n                    if (swaps.size() >= MAX_SWAPS) return;\n                }\n            }\n        }\n        \n        if (!fixed) break;\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    solve();\n    \n    // Output swaps\n    cout << swaps.size() << '\\n';\n    for (auto& swap : swaps) {\n        cout << swap.first.first << ' ' << swap.first.second << ' ' \n             << swap.second.first << ' ' << swap.second.second << '\\n';\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int D = 9;\nconst int di[] = {-1, 0, 1, 0};\nconst int dj[] = {0, 1, 0, -1};\n\nint N;\nbool obstacle[D][D];\nbool occupied[D][D];\nint container[D][D]; // container[i][j] = t_d if occupied, else -1\nint dist[D][D];\n\nvoid bfs_dist() {\n    queue<pair<int, int>> q;\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            dist[i][j] = -1;\n        }\n    }\n    int si = 0, sj = (D-1)/2;\n    dist[si][sj] = 0;\n    q.emplace(si, sj);\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) continue;\n            if (obstacle[ni][nj] || occupied[ni][nj]) continue;\n            if (dist[ni][nj] == -1) {\n                dist[ni][nj] = dist[i][j] + 1;\n                q.emplace(ni, nj);\n            }\n        }\n    }\n}\n\nbool is_reachable(int i, int j) {\n    if (obstacle[i][j] || occupied[i][j]) return false;\n    bfs_dist();\n    return dist[i][j] != -1;\n}\n\nvector<pair<int, int>> get_reachable() {\n    bfs_dist();\n    vector<pair<int, int>> res;\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            if (!obstacle[i][j] && !occupied[i][j] && dist[i][j] != -1) {\n                res.emplace_back(i, j);\n            }\n        }\n    }\n    return res;\n}\n\npair<int, int> choose_placement(int t) {\n    auto reachable = get_reachable();\n    if (reachable.empty()) {\n        cerr << \"No reachable cells!\" << endl;\n        exit(1);\n    }\n    // Choose the cell with maximum distance from entrance\n    pair<int, int> best = reachable[0];\n    int best_dist = dist[best.first][best.second];\n    for (auto [i, j] : reachable) {\n        if (dist[i][j] > best_dist) {\n            best_dist = dist[i][j];\n            best = {i, j};\n        }\n    }\n    return best;\n}\n\nvector<pair<int, int>> retrieval_order;\n\nvoid compute_retrieval() {\n    // Reset occupied to true where containers are placed\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            occupied[i][j] = (container[i][j] != -1);\n        }\n    }\n    priority_queue<pair<int, pair<int, int>>, vector<pair<int, pair<int, int>>>, greater<pair<int, pair<int, int>>>> pq;\n    // Initial reachable containers\n    bfs_dist();\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            if (container[i][j] != -1 && dist[i][j] != -1) {\n                pq.emplace(container[i][j], make_pair(i, j));\n            }\n        }\n    }\n    while (!pq.empty()) {\n        auto [t, pos] = pq.top(); pq.pop();\n        auto [i, j] = pos;\n        if (container[i][j] == -1) continue; // already removed\n        retrieval_order.emplace_back(i, j);\n        occupied[i][j] = false;\n        container[i][j] = -1;\n        // Update reachability\n        bfs_dist();\n        // Add newly reachable containers\n        for (int ni = 0; ni < D; ++ni) {\n            for (int nj = 0; nj < D; ++nj) {\n                if (container[ni][nj] != -1 && dist[ni][nj] != -1) {\n                    pq.emplace(container[ni][nj], make_pair(ni, nj));\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cout << fixed << setprecision(20);\n\n    cin >> D >> N;\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            obstacle[i][j] = false;\n            occupied[i][j] = false;\n            container[i][j] = -1;\n        }\n    }\n    for (int k = 0; k < N; ++k) {\n        int ri, rj;\n        cin >> ri >> rj;\n        obstacle[ri][rj] = true;\n    }\n\n    int total_containers = D*D - 1 - N;\n    for (int d = 0; d < total_containers; ++d) {\n        int t;\n        cin >> t;\n        auto [i, j] = choose_placement(t);\n        occupied[i][j] = true;\n        container[i][j] = t;\n        cout << i << \" \" << j << endl;\n    }\n\n    compute_retrieval();\n    for (auto [i, j] : retrieval_order) {\n        cout << i << \" \" << j << \"\\n\";\n    }\n    cout.flush();\n\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 50;\nconst int MAX_M = 100;\n\nint n, m;\nint input[MAX_N][MAX_N];\nbool adj[MAX_M + 1][MAX_M + 1];\nint output[MAX_N][MAX_N];\n\n// Directions for adjacency checking\nint dx[] = {-1, 1, 0, 0};\nint dy[] = {0, 0, -1, 1};\n\nvoid extract_adjacencies() {\n    memset(adj, false, sizeof(adj));\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int c1 = input[i][j];\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d];\n                int nj = j + dy[d];\n                int c2;\n                \n                if (ni < 0 || ni >= n || nj < 0 || nj >= n) {\n                    c2 = 0; // Outside\n                } else {\n                    c2 = input[ni][nj];\n                }\n                \n                if (c1 != c2) {\n                    int u = min(c1, c2);\n                    int v = max(c1, c2);\n                    adj[u][v] = true;\n                }\n            }\n        }\n    }\n}\n\nbool is_valid_placement() {\n    // Check connectivity for each color\n    for (int color = 0; color <= m; color++) {\n        vector<pair<int, int>> cells;\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (output[i][j] == color) {\n                    cells.push_back({i, j});\n                }\n            }\n        }\n        \n        if (cells.empty()) continue;\n        \n        // BFS to check connectivity\n        vector<vector<bool>> visited(n, vector<bool>(n, false));\n        queue<pair<int, int>> q;\n        q.push(cells[0]);\n        visited[cells[0].first][cells[0].second] = true;\n        int count = 1;\n        \n        while (!q.empty()) {\n            auto [i, j] = q.front(); q.pop();\n            \n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d];\n                int nj = j + dy[d];\n                \n                if (ni >= 0 && ni < n && nj >= 0 && nj < n && \n                    output[ni][nj] == color && !visited[ni][nj]) {\n                    visited[ni][nj] = true;\n                    q.push({ni, nj});\n                    count++;\n                }\n            }\n        }\n        \n        if (count != cells.size()) return false;\n    }\n    \n    // Check adjacency preservation\n    bool output_adj[MAX_M + 1][MAX_M + 1] = {false};\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int c1 = output[i][j];\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d];\n                int nj = j + dy[d];\n                int c2;\n                \n                if (ni < 0 || ni >= n || nj < 0 || nj >= n) {\n                    c2 = 0;\n                } else {\n                    c2 = output[ni][nj];\n                }\n                \n                if (c1 != c2) {\n                    int u = min(c1, c2);\n                    int v = max(c1, c2);\n                    output_adj[u][v] = true;\n                }\n            }\n        }\n    }\n    \n    for (int i = 0; i <= m; i++) {\n        for (int j = i + 1; j <= m; j++) {\n            if (adj[i][j] != output_adj[i][j]) {\n                return false;\n            }\n        }\n    }\n    \n    return true;\n}\n\nint count_zeros() {\n    int count = 0;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (output[i][j] == 0) count++;\n        }\n    }\n    return count;\n}\n\nvoid improve_solution() {\n    int best_zeros = count_zeros();\n    auto best_output = output;\n    \n    // Try some local improvements\n    for (int iter = 0; iter < 1000; iter++) {\n        int i = rand() % n;\n        int j = rand() % n;\n        \n        if (output[i][j] == 0) continue;\n        \n        int original_color = output[i][j];\n        \n        // Try setting to 0\n        output[i][j] = 0;\n        if (is_valid_placement()) {\n            int zeros = count_zeros();\n            if (zeros > best_zeros) {\n                best_zeros = zeros;\n                best_output = output;\n            }\n        } else {\n            output[i][j] = original_color;\n        }\n    }\n    \n    output = best_output;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> n >> m;\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> input[i][j];\n        }\n    }\n    \n    extract_adjacencies();\n    \n    // Initialize output with all zeros\n    memset(output, 0, sizeof(output));\n    \n    // Simple greedy approach: place each color in a compact region\n    vector<int> colors;\n    for (int c = 1; c <= m; c++) colors.push_back(c);\n    \n    // Sort colors by their frequency in input (descending)\n    vector<int> freq(m + 1, 0);\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            freq[input[i][j]]++;\n        }\n    }\n    \n    sort(colors.begin(), colors.end(), [&](int a, int b) {\n        return freq[a] > freq[b];\n    });\n    \n    // Place colors starting from corners/edges\n    int start_i = 0, start_j = 0;\n    \n    for (int color : colors) {\n        // Find all positions this color should be adjacent to\n        set<int> neighbors;\n        for (int other = 0; other <= m; other++) {\n            if (adj[min(color, other)][max(color, other)]) {\n                neighbors.insert(other);\n            }\n        }\n        \n        // Try to place near existing neighbors\n        bool placed = false;\n        \n        for (int i = 0; i < n && !placed; i++) {\n            for (int j = 0; j < n && !placed; j++) {\n                if (output[i][j] != 0) continue;\n                \n                // Check if adjacent to any neighbor\n                bool has_neighbor = false;\n                for (int d = 0; d < 4; d++) {\n                    int ni = i + dx[d];\n                    int nj = j + dy[d];\n                    \n                    if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                        if (neighbors.count(output[ni][nj])) {\n                            has_neighbor = true;\n                            break;\n                        }\n                    } else if (neighbors.count(0)) {\n                        has_neighbor = true;\n                        break;\n                    }\n                }\n                \n                if (has_neighbor) {\n                    output[i][j] = color;\n                    placed = true;\n                }\n            }\n        }\n        \n        // If no good position found, place anywhere\n        if (!placed) {\n            for (int i = 0; i < n && !placed; i++) {\n                for (int j = 0; j < n && !placed; j++) {\n                    if (output[i][j] == 0) {\n                        output[i][j] = color;\n                        placed = true;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Try to improve the solution\n    improve_solution();\n    \n    // Output the result\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << output[i][j];\n            if (j < n - 1) cout << \" \";\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, D, Q;\nvector<int> estimated_weight;\nvector<int> assignment;\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nstring query(const vector<int>& L, const vector<int>& R) {\n    cout << L.size() << \" \" << R.size();\n    for (int x : L) cout << \" \" << x;\n    for (int x : R) cout << \" \" << x;\n    cout << endl;\n    string res;\n    cin >> res;\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> D >> Q;\n    \n    estimated_weight.assign(N, 1);\n    assignment.assign(N, 0);\n    \n    // Phase 1: Quick pairwise comparisons to get rough ordering\n    int queries_used = 0;\n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n    \n    // Do some random pairwise comparisons\n    for (int i = 0; i < min(Q/4, N*2) && queries_used < Q; i++) {\n        int a = rng() % N;\n        int b = rng() % N;\n        if (a == b) continue;\n        \n        string res = query({a}, {b});\n        queries_used++;\n        \n        if (res == \">\") {\n            estimated_weight[a] += 2;\n        } else if (res == \"<\") {\n            estimated_weight[b] += 2;\n        } else {\n            estimated_weight[a] += 1;\n            estimated_weight[b] += 1;\n        }\n    }\n    \n    // Phase 2: Compare groups to refine estimates\n    for (int i = 0; i < min(Q/4, N) && queries_used < Q; i++) {\n        // Compare random subsets\n        vector<int> group1, group2;\n        for (int j = 0; j < N; j++) {\n            if (rng() % 2 == 0) group1.push_back(j);\n            else if (rng() % 2 == 0) group2.push_back(j);\n        }\n        \n        if (group1.empty() || group2.empty()) continue;\n        \n        string res = query(group1, group2);\n        queries_used++;\n        \n        // Adjust weights based on group comparison\n        if (res == \">\") {\n            for (int x : group1) estimated_weight[x] += 1;\n        } else if (res == \"<\") {\n            for (int x : group2) estimated_weight[x] += 1;\n        }\n    }\n    \n    // Phase 3: Sort by estimated weight and assign greedily\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        return estimated_weight[a] > estimated_weight[b];\n    });\n    \n    vector<long long> group_sum(D, 0);\n    \n    // Assign heaviest items first to balance groups\n    for (int i = 0; i < N; i++) {\n        int item = order[i];\n        // Find group with minimum current sum\n        int best_group = 0;\n        for (int g = 1; g < D; g++) {\n            if (group_sum[g] < group_sum[best_group]) {\n                best_group = g;\n            }\n        }\n        assignment[item] = best_group;\n        group_sum[best_group] += estimated_weight[item];\n    }\n    \n    // Phase 4: Try some local improvements with remaining queries\n    for (int q = queries_used; q < Q && q < queries_used + Q/8; q++) {\n        // Try swapping two items between groups\n        int a = rng() % N;\n        int b = rng() % N;\n        if (a == b || assignment[a] == assignment[b]) continue;\n        \n        // Compare these two items\n        string res = query({a}, {b});\n        \n        // If our assignment seems wrong, try to fix it\n        if ((res == \">\" && group_sum[assignment[a]] < group_sum[assignment[b]]) ||\n            (res == \"<\" && group_sum[assignment[a]] > group_sum[assignment[b]])) {\n            // Swap assignments\n            int old_a = assignment[a];\n            int old_b = assignment[b];\n            assignment[a] = old_b;\n            assignment[b] = old_a;\n            group_sum[old_b] += estimated_weight[a] - estimated_weight[b];\n            group_sum[old_a] += estimated_weight[b] - estimated_weight[a];\n        }\n    }\n    \n    // Output final assignment\n    for (int i = 0; i < N; i++) {\n        cout << assignment[i];\n        if (i < N-1) cout << \" \";\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 200;\nconst int MAXM = 10;\n\nint n, m;\nvector<int> st[MAXM];\npair<int,int> where[MAXN+1]; // {stack, index} for box v; stack=-1 if carried\n\nvector<pair<int,int>> ops;\n\n// Carry out box v from stack s\nvoid carry_out(int v, int s) {\n    ops.emplace_back(v, 0);\n    st[s].pop_back();\n    where[v] = {-1, -1};\n}\n\n// Move box v and all above it from stack s to stack t\nvoid move_block(int v, int s, int t) {\n    int idx = where[v].second;\n    int k = st[s].size() - idx; // number of boxes to move\n    ops.emplace_back(v, t+1); // output is 1-indexed\n\n    // Extract block\n    vector<int> block(st[s].begin() + idx, st[s].end());\n    st[s].resize(idx);\n\n    // Append to target\n    for(int x : block) {\n        st[t].push_back(x);\n        where[x] = {t, (int)st[t].size()-1};\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> n >> m;\n    for(int i = 0; i < m; i++) {\n        st[i].resize(n/m);\n        for(int j = 0; j < n/m; j++) {\n            cin >> st[i][j];\n            where[ st[i][j] ] = {i, j};\n        }\n    }\n\n    int next_out = 1;\n\n    while(next_out <= n) {\n        // Phase 1: carry out as many as possible\n        bool progress = true;\n        while(progress && next_out <= n) {\n            progress = false;\n            // Find if next_out is at top of any stack\n            for(int i = 0; i < m; i++) {\n                if(!st[i].empty() && st[i].back() == next_out) {\n                    carry_out(next_out, i);\n                    next_out++;\n                    progress = true;\n                    break;\n                }\n            }\n        }\n        if(next_out > n) break;\n\n        // Phase 2: next_out is buried somewhere\n        int s = -1;\n        for(int i = 0; i < m; i++) {\n            for(int j = 0; j < st[i].size(); j++) {\n                if(st[i][j] == next_out) {\n                    s = i;\n                    break;\n                }\n            }\n            if(s != -1) break;\n        }\n        // s is the stack containing next_out\n        int idx = where[next_out].second;\n        int k = st[s].size() - idx; // boxes from next_out to top\n\n        // Choose target stack t != s with maximum top box\n        int best_t = -1;\n        int best_top = -1;\n        for(int t = 0; t < m; t++) {\n            if(t == s) continue;\n            int top_val = st[t].empty() ? 0 : st[t].back();\n            if(top_val > best_top) {\n                best_top = top_val;\n                best_t = t;\n            }\n        }\n        // Move block to best_t\n        move_block(next_out, s, best_t);\n    }\n\n    // Output operations\n    for(auto [v, i] : ops) {\n        cout << v << \" \" << i << \"\\n\";\n    }\n\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nstatic const int DI[4] = {1,0,-1,0};\nstatic const int DJ[4] = {0,1,0,-1};\nstatic const char DC[4] = {'D','R','U','L'};\n\nint main(){\n  ios::sync_with_stdio(false);\n  cin.tie(nullptr);\n\n  int N; cin>>N;\n  vector<string> hwall(N-1), vwall(N);\n  for(int i=0;i<N-1;i++) cin>>hwall[i];\n  for(int i=0;i<N;  i++) cin>>vwall[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  // build adj\n  auto inside = [&](int i,int j){ return 0<=i&&i<N&&0<=j&&j<N; };\n  vector<vector<array<int,2>>> adj(N*N);\n  auto enc = [&](int i,int j){ return i*N+j; };\n  auto dec = [&](int v){ return array<int,2>{v/N, v%N}; };\n  for(int i=0;i<N;i++){\n    for(int j=0;j<N;j++){\n      int v = enc(i,j);\n      for(int dir=0;dir<4;dir++){\n        int ni=i+DI[dir], nj=j+DJ[dir];\n        if(!inside(ni,nj)) continue;\n        bool ok = true;\n        if(dir==0){ // D\n          if(hwall[i][j]=='1') ok=false;\n        }else if(dir==2){ // U\n          if(hwall[i-1][j]=='1') ok=false;\n        }else if(dir==1){ // R\n          if(vwall[i][j]=='1') ok=false;\n        }else{ // L\n          if(vwall[i][j-1]=='1') ok=false;\n        }\n        if(ok){\n          adj[v].push_back({enc(ni,nj), dir});\n        }\n      }\n    }\n  }\n\n  // 1. basic Euler tour by DFS (simple, ensures all visited)\n  vector<bool> vis(N*N,false);\n  string basic;\n  function<void(int)> dfs = [&](int v){\n    vis[v]=true;\n    auto [i,j]=dec(v);\n    for(auto [u,dir]: adj[v]){\n      if(!vis[u]){\n        basic += DC[dir];\n        dfs(u);\n        basic += DC[dir^2]; // back\n      }\n    }\n  };\n  dfs(0);\n  // basic is already closed at (0,0)\n\n  // 2. enumerate small cycles (length <= 10) for each node\n  const int MAXCYCLE=10;\n  vector<vector<array<int,2>>> cycles(N*N); // cycles[v] = list of {start_index_in_basic, cycle_length}\n  // but we need actual cycle sequences to insert\n  // instead, we precompute for each node v: list of cycles (as string) that start from v and return to v with length <= MAXCYCLE\n  vector<vector<string>> nodeCycles(N*N);\n  vector<int> dist(N*N), parent(N*N), parDir(N*N);\n  for(int sv=0; sv<N*N; sv++){\n    fill(dist.begin(), dist.end(), -1);\n    dist[sv]=0;\n    queue<int> q; q.push(sv);\n    while(!q.empty()){\n      int v=q.front(); q.pop();\n      if(dist[v]>=MAXCYCLE) continue;\n      for(auto [u,dir]: adj[v]){\n        if(dist[u]==-1){\n          dist[u]=dist[v]+1;\n          parent[u]=v;\n          parDir[u]=dir;\n          q.push(u);\n        }\n        // found back to sv\n        if(u==sv && dist[v]+1>=2 && dist[v]+1<=MAXCYCLE){\n          // reconstruct\n          string cyc;\n          int x=v;\n          int len=dist[v]+1;\n          while(x!=sv){\n            cyc += DC[parDir[x]];\n            x = parent[x];\n          }\n          // we are at sv, but we need to close the cycle\n          // last step from v to sv is by 'dir'\n          // but we already have full path\n          // actually we don't need to push last dir, because we are already at sv\n          // the cycle string is cyc (from sv to v) and then one more step dir\n          cyc += DC[dir];\n          // this cycle starts/ends at sv, length = len\n          nodeCycles[sv].push_back(cyc);\n        }\n      }\n    }\n  }\n\n  // 3. compute efficiency = (sum of d on cycle vertices) / (cycle length)\n  vector<tuple<double,int,int,string>> effCycles; // (eff, node, index_in_nodeCycles, cycle_string)\n  for(int v=0;v<N*N;v++){\n    auto [i0,j0]=dec(v);\n    for(auto& cyc: nodeCycles[v]){\n      set<int> verts;\n      int u=v;\n      verts.insert(u);\n      for(char ch: cyc){\n        int dir = string(\"DRUL\").find(ch);\n        auto [i,j]=dec(u);\n        int ni=i+DI[dir], nj=j+DJ[dir];\n        u = enc(ni,nj);\n        verts.insert(u);\n      }\n      long long sd=0;\n      for(int x: verts){\n        auto [i,j]=dec(x);\n        sd += d[i][j];\n      }\n      double eff = (double)sd / (double)cyc.size();\n      effCycles.emplace_back(eff, v, 0, cyc);\n    }\n  }\n  // sort by eff desc\n  sort(effCycles.rbegin(), effCycles.rend());\n\n  // 4. try to insert high-eff cycles into basic as many as possible\n  // we can do: for each occurrence of v in basic, we can insert cycle there\n  // but we do greedy: take highest eff, and insert as many as possible within budget\n  const int LMAX = 100000;\n  int budget = LMAX - (int)basic.size();\n  string route = basic;\n  // we need to know positions of each node in route\n  // but route will be extended dynamically -> we do offline: precompute positions in basic, and insertions\n  // instead, we do simple: for each cycle in effCycles, try to insert at first occurrence of node\n  vector<int> posInBasic(N*N, -1);\n  {\n    int u=0;\n    posInBasic[u]=0;\n    for(int i=0;i<(int)basic.size();i++){\n      char ch=basic[i];\n      int dir=string(\"DRUL\").find(ch);\n      auto [x,y]=dec(u);\n      int nx=x+DI[dir], ny=y+DJ[dir];\n      u = enc(nx,ny);\n      if(posInBasic[u]==-1) posInBasic[u]=i+1;\n    }\n  }\n  // now for each cycle, if node v appears in basic, we can insert at posInBasic[v]\n  // we do greedy: for each cycle, insert as many as possible at that position\n  for(auto& [eff, v, dummy, cyc]: effCycles){\n    if(budget <=0) break;\n    int p = posInBasic[v];\n    if(p==-1) continue;\n    int len = cyc.size();\n    int maxrep = budget / len;\n    if(maxrep<=0) continue;\n    string add;\n    for(int t=0;t<maxrep;t++) add += cyc;\n    // insert at p\n    route.insert(p, add);\n    budget -= maxrep * len;\n  }\n\n  // 5. ensure we are back at (0,0) and length <= 1e5\n  // our basic was closed, and inserted cycles are closed, so whole route is closed\n  if(route.size() > LMAX){\n    route.resize(LMAX);\n  }\n  cout << route << endl;\n\n  return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nconst int INF = 1e9;\nint N, M;\nint si, sj;\narray<array<char,15>,15> A;\nvector<string> t(200);\nvector<int> perm;          // order in which we will embed the keywords\n\n// for each letter c, store all positions that contain c\nvector<pair<int,int>> pos[26];\n\n// shortest path length on grid between any two letters\nint distLetter[26][26];\n\n// precompute shortest paths between any cell and any letter\nvoid buildDistLetter(){\n    for(int c=0;c<26;c++){\n        static int d[15][15];\n        for(int i=0;i<15;i++)for(int j=0;j<15;j++) d[i][j]=INF;\n        queue<pair<int,int>> q;\n        for(auto [i,j]: pos[c]){\n            d[i][j]=0;\n            q.emplace(i,j);\n        }\n        int dx[4]={1,-1,0,0}, dy[4]={0,0,1,-1};\n        while(!q.empty()){\n            auto [i,j]=q.front(); q.pop();\n            for(int dir=0;dir<4;dir++){\n                int ni=i+dx[dir], nj=j+dy[dir];\n                if(ni<0||ni>=N||nj<0||nj>=N) continue;\n                if(d[ni][nj]>d[i][j]+1){\n                    d[ni][nj]=d[i][j]+1;\n                    q.emplace(ni,nj);\n                }\n            }\n        }\n        for(int c2=0;c2<26;c2++){\n            int best=INF;\n            for(auto [i,j]: pos[c2]) best=min(best, d[i][j]);\n            distLetter[c][c2]=best;\n        }\n    }\n}\n\n// movement cost from letter a to letter b (Manhattan+1)\nint moveCost(int a,int b){\n    return distLetter[a][b]+1;\n}\n\n// overlap length between two strings (suffix of a == prefix of b)\nint overlap(const string& a, const string& b){\n    int maxo=0;\n    int al=a.size(), bl=b.size();\n    int lim=min(al,bl);\n    for(int o=1;o<=lim;o++){\n        bool ok=true;\n        for(int i=0;i<o;i++) if(a[al-o+i]!=b[i]){ ok=false; break; }\n        if(ok) maxo=o;\n    }\n    return maxo;\n}\n\n// greedy maximum overlap ordering, tie-break by actual movement cost\nvoid greedyOrder(){\n    perm.resize(M);\n    for(int i=0;i<M;i++) perm[i]=i;\n    vector<bool> used(M,false);\n    vector<int> ord;\n    ord.reserve(M);\n    // start with arbitrary keyword\n    ord.push_back(0);\n    used[0]=true;\n    while((int)ord.size()<M){\n        int best=-1, besto=-1, bestcost=INF;\n        int lasti=ord.back();\n        char lastc = t[lasti].back();\n        for(int i=0;i<M;i++) if(!used[i]){\n            int o=overlap(t[lasti], t[i]);\n            char fc = t[i][0];\n            int cst = moveCost(lastc-'A', fc-'A');\n            // prefer larger overlap, then smaller cost\n            if(o>besto || (o==besto && cst<bestcost)){\n                besto=o;\n                bestcost=cst;\n                best=i;\n            }\n        }\n        ord.push_back(best);\n        used[best]=true;\n    }\n    perm=ord;\n}\n\n// path reconstruction: we store for each letter c the predecessor grid\n// so we can reconstruct shortest path from any cell to some cell of c\narray<array<pair<int,int>,15>,15> pred[26];\nvoid buildPred(){\n    for(int c=0;c<26;c++){\n        static int d[15][15];\n        for(int i=0;i<15;i++)for(int j=0;j<15;j++) d[i][j]=INF;\n        queue<pair<int,int>> q;\n        for(auto [i,j]: pos[c]){\n            d[i][j]=0;\n            pred[c][i][j]={-1,-1};\n            q.emplace(i,j);\n        }\n        int dx[4]={1,-1,0,0}, dy[4]={0,0,1,-1};\n        while(!q.empty()){\n            auto [i,j]=q.front(); q.pop();\n            for(int dir=0;dir<4;dir++){\n                int ni=i+dx[dir], nj=j+dy[dir];\n                if(ni<0||ni>=N||nj<0||nj>=N) continue;\n                if(d[ni][nj]>d[i][j]+1){\n                    d[ni][nj]=d[i][j]+1;\n                    pred[c][ni][nj]={i,j};\n                    q.emplace(ni,nj);\n                }\n            }\n        }\n    }\n}\n\n// reconstruct shortest path from (i,j) to *some* cell of letter c\nvector<pair<int,int>> recoverPath(int c, int i, int j){\n    vector<pair<int,int>> rev;\n    auto cur=make_pair(i,j);\n    while(cur.first>=0){\n        rev.push_back(cur);\n        cur=pred[c][cur.first][cur.second];\n    }\n    reverse(rev.begin(), rev.end());\n    return rev;\n}\n\n// global path we are going to output\nvector<pair<int,int>> outPath;\nint curi, curj;\n\nvoid appendMove(int ti,int tj){\n    // BFS on grid to go from (curi,curj) to (ti,tj)\n    static int d[15][15];\n    static pair<int,int> p[15][15];\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++) d[i][j]=INF;\n    queue<pair<int,int>> q;\n    d[curi][curj]=0;\n    q.emplace(curi,curj);\n    int dx[4]={1,-1,0,0}, dy[4]={0,0,1,-1};\n    while(!q.empty()){\n        auto [i,j]=q.front(); q.pop();\n        if(i==ti&&j==tj) break;\n        for(int dir=0;dir<4;dir++){\n            int ni=i+dx[dir], nj=j+dy[dir];\n            if(ni<0||ni>=N||nj<0||nj>=N) continue;\n            if(d[ni][nj]>d[i][j]+1){\n                d[ni][nj]=d[i][j]+1;\n                p[ni][nj]={i,j};\n                q.emplace(ni,nj);\n            }\n        }\n    }\n    // reconstruct\n    vector<pair<int,int>> tmp;\n    auto cur=make_pair(ti,tj);\n    while(cur.first!=curi||cur.second!=curj){\n        tmp.push_back(cur);\n        cur=p[cur.first][cur.second];\n    }\n    reverse(tmp.begin(), tmp.end());\n    for(auto [i,j]: tmp){\n        outPath.emplace_back(i,j);\n    }\n    curi=ti; curj=tj;\n}\n\nvoid spell(const string& s){\n    for(char c: s){\n        int cc=c-'A';\n        // go to any cell of c\n        int best=INF;\n        pair<int,int> tgt;\n        for(auto [i,j]: pos[cc]){\n            int md=abs(i-curi)+abs(j-curj);\n            if(md<best){\n                best=md;\n                tgt={i,j};\n            }\n        }\n        appendMove(tgt.first, tgt.second);\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin>>N>>M;\n    cin>>si>>sj;\n    for(int i=0;i<N;i++){\n        string row;\n        cin>>row;\n        for(int j=0;j<N;j++){\n            A[i][j]=row[j];\n            pos[A[i][j]-'A'].emplace_back(i,j);\n        }\n    }\n    for(int k=0;k<M;k++){\n        cin>>t[k];\n    }\n    buildDistLetter();\n    buildPred();\n    greedyOrder();\n\n    curi=si; curj=sj;\n    outPath.clear();\n\n    for(int k=0;k<M;k++){\n        int id=perm[k];\n        const string& w=t[id];\n        if(k==0){\n            spell(w);\n        } else {\n            int previd=perm[k-1];\n            const string& prevw=t[previd];\n            int o=overlap(prevw, w);\n            if(o==0){\n                spell(w);\n            } else {\n                string suffix=w.substr(o);\n                spell(suffix);\n            }\n        }\n    }\n\n    // output\n    cout<<outPath.size()<<\"\\n\";\n    for(auto [i,j]: outPath){\n        cout<<i<<\" \"<<j<<\"\\n\";\n    }\n    return 0;\n}","ahc030":"#include <iostream>\n#include <vector>\n#include <random>\n#include <algorithm>\n#include <cmath>\n#include <set>\n#include <map>\n#include <queue>\n\nusing namespace std;\n\nstruct Point {\n    int i, j;\n    Point(int i = 0, int j = 0) : i(i), j(j) {}\n    bool operator<(const Point& other) const {\n        if (i != other.i) return i < other.i;\n        return j < other.j;\n    }\n    bool operator==(const Point& other) const {\n        return i == other.i && j == other.j;\n    }\n};\n\nint N, M;\ndouble eps;\nvector<vector<Point>> oil_fields;\nvector<vector<int>> true_grid;\nvector<vector<bool>> drilled;\nvector<vector<int>> drilled_values;\nvector<vector<double>> belief;\nset<Point> candidates;\nmt19937 rng(42);\n\n// Query functions\nint drill(int i, int j) {\n    cout << \"q 1 \" << i << \" \" << j << endl;\n    int response;\n    cin >> response;\n    return response;\n}\n\nint divine(const vector<Point>& points) {\n    cout << \"q \" << points.size();\n    for (const auto& p : points) {\n        cout << \" \" << p.i << \" \" << p.j;\n    }\n    cout << endl;\n    int response;\n    cin >> response;\n    return response;\n}\n\nbool answer(const set<Point>& answer_points) {\n    cout << \"a \" << answer_points.size();\n    for (const auto& p : answer_points) {\n        cout << \" \" << p.i << \" \" << p.j;\n    }\n    cout << endl;\n    int response;\n    cin >> response;\n    return response == 1;\n}\n\n// Initialize data structures\nvoid initialize() {\n    cin >> N >> M >> eps;\n    oil_fields.resize(M);\n    drilled.assign(N, vector<bool>(N, false));\n    drilled_values.assign(N, vector<int>(N, 0));\n    belief.assign(N, vector<double>(N, 0.5));\n    \n    for (int k = 0; k < M; k++) {\n        int d;\n        cin >> d;\n        oil_fields[k].resize(d);\n        for (int i = 0; i < d; i++) {\n            cin >> oil_fields[k][i].i >> oil_fields[k][i].j;\n        }\n    }\n    \n    // Initialize all squares as candidates\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            candidates.insert(Point(i, j));\n        }\n    }\n}\n\n// Get all possible positions for an oil field\nvector<Point> get_possible_positions(const vector<Point>& field) {\n    vector<Point> positions;\n    int max_i = 0, max_j = 0;\n    for (const auto& p : field) {\n        max_i = max(max_i, p.i);\n        max_j = max(max_j, p.j);\n    }\n    \n    for (int di = 0; di + max_i < N; di++) {\n        for (int dj = 0; dj + max_j < N; dj++) {\n            positions.push_back(Point(di, dj));\n        }\n    }\n    return positions;\n}\n\n// Check if an oil field at position covers square (i,j)\nbool covers(const vector<Point>& field, int pos_i, int pos_j, int i, int j) {\n    for (const auto& p : field) {\n        if (pos_i + p.i == i && pos_j + p.j == j) {\n            return true;\n        }\n    }\n    return false;\n}\n\n// Update beliefs based on drilling result\nvoid update_belief_drill(int i, int j, int value) {\n    drilled[i][j] = true;\n    drilled_values[i][j] = value;\n    \n    if (value > 0) {\n        belief[i][j] = 1.0;\n        // Increase belief for neighboring squares\n        for (int di = -1; di <= 1; di++) {\n            for (int dj = -1; dj <= 1; dj++) {\n                int ni = i + di, nj = j + dj;\n                if (ni >= 0 && ni < N && nj >= 0 && nj < N && !drilled[ni][nj]) {\n                    belief[ni][nj] = min(1.0, belief[ni][nj] + 0.1);\n                }\n            }\n        }\n    } else {\n        belief[i][j] = 0.0;\n    }\n}\n\n// Update beliefs based on divination result\nvoid update_belief_divine(const vector<Point>& points, int observed_sum) {\n    double expected_sum = 0;\n    for (const auto& p : points) {\n        expected_sum += belief[p.i][p.j];\n    }\n    \n    double ratio = observed_sum / max(expected_sum, 0.1);\n    for (const auto& p : points) {\n        if (!drilled[p.i][p.j]) {\n            belief[p.i][p.j] = min(1.0, max(0.0, belief[p.i][p.j] * ratio));\n        }\n    }\n}\n\n// Select squares for divination based on current beliefs\nvector<Point> select_divination_squares(int num_squares) {\n    vector<pair<double, Point>> scored_points;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (!drilled[i][j]) {\n                double score = belief[i][j] * (1 - belief[i][j]); // Uncertainty\n                scored_points.push_back({score, Point(i, j)});\n            }\n        }\n    }\n    \n    sort(scored_points.rbegin(), scored_points.rend());\n    \n    vector<Point> selected;\n    for (int i = 0; i < min(num_squares, (int)scored_points.size()); i++) {\n        selected.push_back(scored_points[i].second);\n    }\n    \n    return selected;\n}\n\n// Select best square to drill\nPoint select_drill_square() {\n    double best_score = -1;\n    Point best_square;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (!drilled[i][j]) {\n                double score = belief[i][j];\n                // Bonus for strategic positions\n                if (i > 0 && j > 0 && i < N-1 && j < N-1) {\n                    score *= 1.1; // Prefer interior squares\n                }\n                if (score > best_score) {\n                    best_score = score;\n                    best_square = Point(i, j);\n                }\n            }\n        }\n    }\n    \n    return best_square;\n}\n\n// Make final guess based on current information\nset<Point> make_guess() {\n    set<Point> guess;\n    \n    // Include all drilled squares with oil\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (drilled[i][j] && drilled_values[i][j] > 0) {\n                guess.insert(Point(i, j));\n            }\n        }\n    }\n    \n    // Add high-belief squares\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (!drilled[i][j] && belief[i][j] > 0.7) {\n                guess.insert(Point(i, j));\n            }\n        }\n    }\n    \n    return guess;\n}\n\nint main() {\n    initialize();\n    \n    int operations = 0;\n    const int max_operations = 2 * N * N;\n    \n    // Phase 1: Initial divination to get coarse estimates\n    int divination_size = min(25, N * N / 4);\n    for (int phase = 0; phase < 3 && operations < max_operations; phase++) {\n        auto squares = select_divination_squares(divination_size);\n        if (squares.size() < 2) break;\n        \n        int result = divine(squares);\n        operations++;\n        update_belief_divine(squares, result);\n    }\n    \n    // Phase 2: Strategic drilling\n    while (operations < max_operations - 10) {\n        Point drill_square = select_drill_square();\n        int value = drill(drill_square.i, drill_square.j);\n        operations++;\n        update_belief_drill(drill_square.i, drill_square.j, value);\n        \n        // Occasionally use divination to refine beliefs\n        if (operations % 10 == 0) {\n            auto squares = select_divination_squares(min(16, (int)candidates.size()));\n            if (squares.size() >= 2) {\n                int result = divine(squares);\n                operations++;\n                update_belief_divine(squares, result);\n            }\n        }\n    }\n    \n    // Final guess\n    auto final_guess = make_guess();\n    if (answer(final_guess)) {\n        return 0;\n    }\n    \n    // If wrong, drill remaining high-belief squares\n    for (int i = 0; i < N && operations < max_operations; i++) {\n        for (int j = 0; j < N && operations < max_operations; j++) {\n            if (!drilled[i][j] && belief[i][j] > 0.5) {\n                int value = drill(i, j);\n                operations++;\n                update_belief_drill(i, j, value);\n            }\n        }\n    }\n    \n    // Final attempt\n    final_guess = make_guess();\n    answer(final_guess);\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nstatic const int W = 1000;\nint D, N;\nvector<vector<int>> a;\n\n// partition bitsets: 1 = partition exists\n// Hseg[i][j] : horizontal segment at row i, columns j..j+1  (i in [1,W-1], j in [0,W-1])\n// Vseg[i][j] : vertical   segment at col j, rows i..i+1    (i in [0,W-1], j in [1,W-1])\nbitset<W> Hseg[W], Vseg[W];\n\nstruct Rect {\n    int i0, j0, i1, j1;\n    int area() const { return (i1 - i0) * (j1 - j0); }\n};\n\n// output rectangles per day\nvector<vector<Rect>> outRect;\n\n// compute partition-change cost versus previous day\nint computeLd(const vector<Rect>& rects) {\n    // new partition maps\n    bitset<W> nH[W], nV[W];\n    for (const auto& r : rects) {\n        int i0 = r.i0, j0 = r.j0, i1 = r.i1, j1 = r.j1;\n        // top edge\n        if (i0 > 0)      for (int j = j0; j < j1; ++j) nH[i0].set(j);\n        // bottom edge\n        if (i1 < W)      for (int j = j0; j < j1; ++j) nH[i1].set(j);\n        // left edge\n        if (j0 > 0)      for (int i = i0; i < i1; ++i) nV[i].set(j0);\n        // right edge\n        if (j1 < W)      for (int i = i0; i < i1; ++i) nV[i].set(j1);\n    }\n    int cost = 0;\n    for (int i = 1; i < W; ++i) {\n        auto diff = Hseg[i] ^ nH[i];\n        cost += diff.count();\n    }\n    for (int j = 1; j < W; ++j) {\n        bitset<W> diff;\n        for (int i = 0; i < W; ++i) diff[i] = Vseg[i][j] ^ nV[i][j];\n        cost += diff.count();\n    }\n    return cost;\n}\n\n// assign rectangles for one day\nvoid solveDay(int d) {\n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    // largest first\n    sort(ord.begin(), ord.end(), [&](int x, int y) {\n        return a[d][x] > a[d][y];\n    });\n\n    // free rectangles\n    vector<Rect> freeList = { {0, 0, W, W} };\n    vector<Rect> assigned(N);\n\n    auto bestSplit = [&](const Rect& hole, int need,\n                         int& bestCost, Rect& bestA, Rect& bestB, bool& bestIsHoriz) {\n        bestCost = INT_MAX;\n        int h = hole.i1 - hole.i0;\n        int w = hole.j1 - hole.j0;\n        // try horizontal split: i0..cut and cut..i1\n        if (h > 1) {\n            int cutLo = hole.i0 + 1;\n            int cutHi = hole.i1 - 1;\n            int step = max(1, (cutHi - cutLo + 1) / 20);\n            for (int cut = cutLo; cut <= cutHi; cut += step) {\n                Rect A = { hole.i0, hole.j0, cut,     hole.j1 };\n                Rect B = { cut,     hole.j0, hole.i1, hole.j1 };\n                if (A.area() < need) continue;\n                // compute extra partition cost\n                int c = 0;\n                // new horizontal segment at 'cut'\n                for (int j = hole.j0; j < hole.j1; ++j) {\n                    bool old = Hseg[cut][j];\n                    if (!old) c++;\n                }\n                if (c < bestCost) {\n                    bestCost = c;\n                    bestA = A;\n                    bestB = B;\n                    bestIsHoriz = true;\n                }\n            }\n        }\n        // try vertical split\n        if (w > 1) {\n            int cutLo = hole.j0 + 1;\n            int cutHi = hole.j1 - 1;\n            int step = max(1, (cutHi - cutLo + 1) / 20);\n            for (int cut = cutLo; cut <= cutHi; cut += step) {\n                Rect A = { hole.i0, hole.j0, hole.i1, cut };\n                Rect B = { hole.i0, cut,     hole.i1, hole.j1 };\n                if (A.area() < need) continue;\n                int c = 0;\n                for (int i = hole.i0; i < hole.i1; ++i) {\n                    bool old = Vseg[i][cut];\n                    if (!old) c++;\n                }\n                if (c < bestCost) {\n                    bestCost = c;\n                    bestA = A;\n                    bestB = B;\n                    bestIsHoriz = false;\n                }\n            }\n        }\n    };\n\n    for (int k : ord) {\n        int need = a[d][k];\n        int bestCost = INT_MAX;\n        Rect bestA, bestB;\n        bool bestIsHoriz = false;\n        int bestIdx = -1;\n        for (int idx = 0; idx < (int)freeList.size(); ++idx) {\n            const Rect& hole = freeList[idx];\n            if (hole.area() < need) continue;\n            int c; Rect A, B; bool ih;\n            bestSplit(hole, need, c, A, B, ih);\n            if (c < bestCost) {\n                bestCost = c;\n                bestA = A;\n                bestB = B;\n                bestIsHoriz = ih;\n                bestIdx = idx;\n            }\n        }\n        assert(bestIdx != -1);\n        assigned[k] = bestA;\n        freeList[bestIdx] = bestB;\n    }\n\n    // store output order\n    outRect[d] = assigned;\n\n    // update global partition maps for next day\n    for (int i = 0; i < W; ++i) Hseg[i].reset();\n    for (int j = 0; j < W; ++j) Vseg[j].reset();\n    for (const auto& r : assigned) {\n        int i0 = r.i0, j0 = r.j0, i1 = r.i1, j1 = r.j1;\n        if (i0 > 0)      for (int j = j0; j < j1; ++j) Hseg[i0].set(j);\n        if (i1 < W)      for (int j = j0; j < j1; ++j) Hseg[i1].set(j);\n        if (j0 > 0)      for (int i = i0; i < i1; ++i) Vseg[i].set(j0);\n        if (j1 < W)      for (int i = i0; i < i1; ++i) Vseg[i].set(j1);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> W >> D >> N;\n    a.assign(D, vector<int>(N));\n    for (int d = 0; d < D; ++d)\n        for (int k = 0; k < N; ++k)\n            cin >> a[d][k];\n\n    outRect.assign(D, vector<Rect>(N));\n\n    // initialize partitions: none\n    for (int i = 0; i < W; ++i) {\n        Hseg[i].reset();\n        Vseg[i].reset();\n    }\n\n    for (int d = 0; d < D; ++d) {\n        solveDay(d);\n    }\n\n    // output\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            const auto& r = outRect[d][k];\n            cout << r.i0 << ' ' << r.j0 << ' ' << r.i1 << ' ' << r.j1 << '\\n';\n        }\n    }\n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <tuple>\n\nusing namespace std;\n\nconst int MOD = 998244353;\nconst int N = 9;\nconst int M = 20;\nconst int K = 81;\n\nint board[N][N];\nint stamps[M][3][3];\nint temp_board[N][N];\n\nint compute_marginal(int m, int p, int q) {\n    int gain = 0;\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            int original = board[p + i][q + j] % MOD;\n            int new_val = (board[p + i][q + j] + stamps[m][i][j]) % MOD;\n            gain += new_val - original;\n        }\n    }\n    return gain;\n}\n\nvoid apply_stamp(int m, int p, int q) {\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            board[p + i][q + j] = (board[p + i][q + j] + stamps[m][i][j]) % MOD;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read input\n    int n, m, k;\n    cin >> n >> m >> k;\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cin >> board[i][j];\n        }\n    }\n    for (int mm = 0; mm < m; ++mm) {\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                cin >> stamps[mm][i][j];\n            }\n        }\n    }\n\n    vector<tuple<int, int, int>> operations;\n\n    for (int step = 0; step < k; ++step) {\n        int best_m = -1, best_p = -1, best_q = -1;\n        int best_gain = -1e9;\n\n        // Find the best stamp and position\n        for (int mm = 0; mm < m; ++mm) {\n            for (int p = 0; p <= n - 3; ++p) {\n                for (int q = 0; q <= n - 3; ++q) {\n                    int gain = compute_marginal(mm, p, q);\n                    if (gain > best_gain) {\n                        best_gain = gain;\n                        best_m = mm;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n\n        if (best_gain <= 0) break; // No positive gain possible\n\n        // Apply the best stamp\n        apply_stamp(best_m, best_p, best_q);\n        operations.emplace_back(best_m, best_p, best_q);\n    }\n\n    // Output the operations\n    cout << operations.size() << '\\n';\n    for (auto [mm, p, q] : operations) {\n        cout << mm << ' ' << p << ' ' << q << '\\n';\n    }\n\n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <string>\n#include <queue>\n#include <set>\n\nusing namespace std;\n\nconst int MAX_N = 5;\nconst int MAX_TURNS = 10000;\n\nint N;\nint A[MAX_N][MAX_N];\nvector<string> operations(MAX_N);\n\n// Current state\nint grid[MAX_N][MAX_N];  // -1 if empty, otherwise container number\nint crane_pos[MAX_N][2];  // crane positions: [crane_id][x,y]\nbool crane_carry[MAX_N];  // whether crane is carrying\nint crane_container[MAX_N];  // container being carried (-1 if none)\nbool crane_alive[MAX_N];\n\n// Target dispatch information\nint target_gate(int container) {\n    return container / N;\n}\n\nbool is_correct_container_for_gate(int gate, int container) {\n    return container >= gate * N && container < (gate + 1) * N;\n}\n\n// Check if move is valid for crane\nbool can_move(int crane_id, int dx, int dy) {\n    if (!crane_alive[crane_id]) return false;\n    \n    int new_x = crane_pos[crane_id][0] + dx;\n    int new_y = crane_pos[crane_id][1] + dy;\n    \n    if (new_x < 0 || new_x >= N || new_y < 0 || new_y >= N) return false;\n    \n    // Check crane collision\n    for (int i = 0; i < N; i++) {\n        if (i != crane_id && crane_alive[i] && \n            crane_pos[i][0] == new_x && crane_pos[i][1] == new_y) {\n            return false;\n        }\n    }\n    \n    // Small crane carrying cannot move to occupied square\n    if (crane_id > 0 && crane_carry[crane_id] && grid[new_x][new_y] != -1) {\n        return false;\n    }\n    \n    return true;\n}\n\n// Simple pathfinding for crane movement\nvector<char> find_path(int crane_id, int target_x, int target_y) {\n    vector<char> path;\n    int x = crane_pos[crane_id][0];\n    int y = crane_pos[crane_id][1];\n    \n    while (x != target_x || y != target_y) {\n        int dx = 0, dy = 0;\n        char move_char = '.';\n        \n        if (x < target_x) { dx = 1; move_char = 'D'; }\n        else if (x > target_x) { dx = -1; move_char = 'U'; }\n        else if (y < target_y) { dy = 1; move_char = 'R'; }\n        else if (y > target_y) { dy = -1; move_char = 'L'; }\n        \n        if (can_move(crane_id, dx, dy)) {\n            path.push_back(move_char);\n            x += dx;\n            y += dy;\n        } else {\n            // Try alternative moves\n            bool moved = false;\n            int alternatives[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}};\n            char alt_chars[4] = {'R', 'L', 'D', 'U'};\n            \n            for (int i = 0; i < 4 && !moved; i++) {\n                if (alternatives[i][0] != dx || alternatives[i][1] != dy) {\n                    if (can_move(crane_id, alternatives[i][0], alternatives[i][1])) {\n                        path.push_back(alt_chars[i]);\n                        x += alternatives[i][0];\n                        y += alternatives[i][1];\n                        moved = true;\n                    }\n                }\n            }\n            if (!moved) break;\n        }\n        \n        if (path.size() > 50) break; // Safety limit\n    }\n    \n    return path;\n}\n\nvoid simulate_turn(const vector<char>& moves) {\n    // Step 1: Receive containers\n    for (int i = 0; i < N; i++) {\n        if (grid[i][0] == -1 && !crane_carry[i]) {\n            // Find next container for this gate\n            static int received_count[MAX_N] = {0};\n            if (received_count[i] < N) {\n                grid[i][0] = A[i][received_count[i]];\n                received_count[i]++;\n            }\n        }\n    }\n    \n    // Step 2: Execute crane moves\n    for (int i = 0; i < N; i++) {\n        if (i < moves.size() && crane_alive[i]) {\n            char move = moves[i];\n            \n            if (move == 'P') {\n                if (!crane_carry[i] && grid[crane_pos[i][0]][crane_pos[i][1]] != -1) {\n                    crane_carry[i] = true;\n                    crane_container[i] = grid[crane_pos[i][0]][crane_pos[i][1]];\n                    grid[crane_pos[i][0]][crane_pos[i][1]] = -1;\n                }\n            } else if (move == 'Q') {\n                if (crane_carry[i] && grid[crane_pos[i][0]][crane_pos[i][1]] == -1) {\n                    crane_carry[i] = false;\n                    grid[crane_pos[i][0]][crane_pos[i][1]] = crane_container[i];\n                    crane_container[i] = -1;\n                }\n            } else if (move == 'U' && can_move(i, -1, 0)) {\n                crane_pos[i][0]--;\n            } else if (move == 'D' && can_move(i, 1, 0)) {\n                crane_pos[i][0]++;\n            } else if (move == 'L' && can_move(i, 0, -1)) {\n                crane_pos[i][1]--;\n            } else if (move == 'R' && can_move(i, 0, 1)) {\n                crane_pos[i][1]++;\n            } else if (move == 'B') {\n                if (!crane_carry[i]) {\n                    crane_alive[i] = false;\n                }\n            }\n        }\n    }\n    \n    // Step 3: Dispatch containers\n    for (int i = 0; i < N; i++) {\n        if (grid[i][N-1] != -1) {\n            grid[i][N-1] = -1; // Container dispatched\n        }\n    }\n}\n\nint main() {\n    cin >> N;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> A[i][j];\n        }\n    }\n    \n    // Initialize state\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = -1;\n        }\n        crane_pos[i][0] = i;\n        crane_pos[i][1] = 0;\n        crane_carry[i] = false;\n        crane_container[i] = -1;\n        crane_alive[i] = true;\n        operations[i] = \"\";\n    }\n    \n    // Simple strategy: Use large crane to collect and sort containers\n    // Small cranes help with local operations\n    \n    int turns = 0;\n    const int max_turns = 8000; // Leave some buffer\n    \n    while (turns < max_turns) {\n        vector<char> current_moves(N, '.');\n        \n        // Large crane (index 0) strategy: collect containers and move to sorting area\n        if (crane_alive[0]) {\n            int x = crane_pos[0][0];\n            int y = crane_pos[0][1];\n            \n            if (!crane_carry[0]) {\n                // Try to pick up container\n                if (grid[x][y] != -1) {\n                    current_moves[0] = 'P';\n                } else {\n                    // Move to find containers\n                    if (y < N-2) {\n                        current_moves[0] = 'R';\n                    } else if (x < N-1) {\n                        current_moves[0] = 'D';\n                    } else {\n                        current_moves[0] = 'U';\n                    }\n                }\n            } else {\n                // Carrying container - move to appropriate area\n                int container = crane_container[0];\n                int target_gate = target_gate(container);\n                \n                // Move toward target gate's column, but stay in middle rows for sorting\n                if (y < N-1) {\n                    current_moves[0] = 'R';\n                } else if (x != target_gate) {\n                    current_moves[0] = (x < target_gate) ? 'D' : 'U';\n                } else {\n                    // At target gate row, place container\n                    current_moves[0] = 'Q';\n                }\n            }\n        }\n        \n        // Small cranes: assist with local operations\n        for (int i = 1; i < N; i++) {\n            if (!crane_alive[i]) continue;\n            \n            int x = crane_pos[i][0];\n            int y = crane_pos[i][1];\n            \n            // Simple behavior: help move containers toward right\n            if (!crane_carry[i]) {\n                if (grid[x][y] != -1) {\n                    current_moves[i] = 'P';\n                } else if (y < N-1) {\n                    current_moves[i] = 'R';\n                }\n            } else {\n                if (y < N-1) {\n                    current_moves[i] = 'R';\n                } else {\n                    current_moves[i] = 'Q';\n                }\n            }\n        }\n        \n        // Execute turn\n        simulate_turn(current_moves);\n        \n        // Record operations\n        for (int i = 0; i < N; i++) {\n            if (turns < operations[i].size() || operations[i].empty()) {\n                operations[i] += current_moves[i];\n            }\n        }\n        \n        turns++;\n        \n        // Check if we should stop (simple heuristic)\n        if (turns > 1000) {\n            bool all_dispatched = true;\n            for (int i = 0; i < N && all_dispatched; i++) {\n                for (int j = 0; j < N && all_dispatched; j++) {\n                    if (grid[i][j] != -1) all_dispatched = false;\n                }\n            }\n            if (all_dispatched) break;\n        }\n    }\n    \n    // Ensure all strings have same length\n    int max_len = 0;\n    for (int i = 0; i < N; i++) {\n        max_len = max(max_len, (int)operations[i].size());\n    }\n    \n    for (int i = 0; i < N; i++) {\n        while (operations[i].size() < max_len) {\n            operations[i] += '.';\n        }\n    }\n    \n    // Output operations\n    for (int i = 0; i < N; i++) {\n        cout << operations[i] << endl;\n    }\n    \n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nint h[20][20];\nvector<string> out;\n\ninline void go(int di, int dj) {\n    if (di > 0) out.insert(out.end(), di, 'D');\n    if (di < 0) out.insert(out.end(), -di, 'U');\n    if (dj > 0) out.insert(out.end(), dj, 'R');\n    if (dj < 0) out.insert(out.end(), -dj, 'L');\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> h[i][j];\n\n    // collect sources and sinks\n    vector<tuple<int,int,int>> src, snk;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            if (h[i][j] > 0) src.emplace_back(i, j, h[i][j]);\n            else if (h[i][j] < 0) snk.emplace_back(i, j, -h[i][j]);\n        }\n\n    int ci = 0, cj = 0;          // current truck position\n    int load = 0;                // current load\n\n    // ---------- PHASE 1: pick up all sources while empty ----------\n    for (auto [si, sj, amt] : src) {\n        go(si - ci, sj - cj);\n        ci = si; cj = sj;\n        out.push_back(\"+\" + to_string(amt));\n        load += amt;\n    }\n\n    // ---------- PHASE 2: deliver to sinks, nearest first ----------\n    // sort sinks by Manhattan distance from last source position (ci,cj)\n    sort(snk.begin(), snk.end(), [&](auto &a, auto &b){\n        auto [ai,aj,aa]=a;\n        auto [bi,bj,ba]=b;\n        int da = abs(ai - ci) + abs(aj - cj);\n        int db = abs(bi - ci) + abs(bj - cj);\n        return da < db;\n    });\n\n    for (auto [si, sj, amt] : snk) {\n        go(si - ci, sj - cj);\n        ci = si; cj = sj;\n        out.push_back(\"-\" + to_string(amt));\n        load -= amt;\n    }\n    assert(load == 0);\n\n    // ---------- output ----------\n    for (auto &s : out) cout << s << '\\n';\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\nconst int N = 6;\nconst int M = 15;\nconst int SEED_COUNT = 2 * N * (N - 1);\nconst int GRID_SIZE = N * N;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int T;\n    cin >> T;\n\n    vector<vector<int>> seeds(SEED_COUNT, vector<int>(M));\n    vector<int> seed_values(SEED_COUNT);\n\n    // Read initial seeds\n    for (int i = 0; i < SEED_COUNT; i++) {\n        for (int j = 0; j < M; j++) {\n            cin >> seeds[i][j];\n        }\n    }\n\n    // Calculate initial seed values\n    for (int i = 0; i < SEED_COUNT; i++) {\n        seed_values[i] = 0;\n        for (int j = 0; j < M; j++) {\n            seed_values[i] += seeds[i][j];\n        }\n    }\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    for (int turn = 0; turn < T; turn++) {\n        vector<int> selected_indices(SEED_COUNT);\n        iota(selected_indices.begin(), selected_indices.end(), 0);\n        \n        // Sort by seed value in descending order\n        sort(selected_indices.begin(), selected_indices.end(), \n             [&](int a, int b) { return seed_values[a] > seed_values[b]; });\n\n        vector<vector<int>> grid(N, vector<int>(N));\n        vector<bool> used(SEED_COUNT, false);\n\n        // Strategy: Use top seeds but with some randomization for diversity\n        int pos = 0;\n        \n        // Fill grid with a mix of top seeds and some random choices\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int idx;\n                \n                if (turn < 3) {\n                    // Early turns: focus on best seeds\n                    idx = selected_indices[pos % (SEED_COUNT / 2)];\n                } else if (turn < 6) {\n                    // Middle turns: mix best with some diversity\n                    if (rng() % 3 == 0) {\n                        idx = selected_indices[rng() % SEED_COUNT];\n                    } else {\n                        idx = selected_indices[pos % (SEED_COUNT / 3)];\n                    }\n                } else {\n                    // Later turns: more aggressive selection of best\n                    idx = selected_indices[pos % max(10, SEED_COUNT / 4)];\n                }\n                \n                // Ensure we don't reuse seeds\n                while (used[idx]) {\n                    idx = (idx + 1) % SEED_COUNT;\n                }\n                used[idx] = true;\n                grid[i][j] = idx;\n                pos++;\n            }\n        }\n\n        // Output the grid\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << grid[i][j];\n                if (j < N - 1) cout << \" \";\n            }\n            cout << \"\\n\";\n        }\n        cout.flush();\n\n        // Read new seeds\n        for (int i = 0; i < SEED_COUNT; i++) {\n            for (int j = 0; j < M; j++) {\n                cin >> seeds[i][j];\n            }\n        }\n\n        // Recalculate seed values\n        for (int i = 0; i < SEED_COUNT; i++) {\n            seed_values[i] = 0;\n            for (int j = 0; j < M; j++) {\n                seed_values[i] += seeds[i][j];\n            }\n        }\n    }\n\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 30;\nconst int MAX_V = 15;\n\nint N, M, V;\nvector<string> s, t;\nvector<pair<int, int>> sources, targets;\nvector<int> parent;\nvector<int> length;\nint root_x, root_y;\n\n// Find positions of 1s in grid\nvector<pair<int, int>> find_positions(const vector<string>& grid) {\n    vector<pair<int, int>> positions;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] == '1') {\n                positions.push_back({i, j});\n            }\n        }\n    }\n    return positions;\n}\n\n// Design a star-shaped tree with multiple fingertips\nvoid design_arm() {\n    parent.resize(V);\n    length.resize(V);\n    \n    // Create a star shape: root at center, multiple arms\n    int fingertips = min(V - 1, 6); // Use up to 6 fingertips\n    int arm_length = max(1, (N - 1) / 3);\n    \n    for (int i = 1; i <= fingertips; i++) {\n        parent[i] = 0;\n        length[i] = arm_length;\n    }\n    \n    // Add intermediate joints if we have more vertices\n    int used = fingertips + 1;\n    for (int i = used; i < V; i++) {\n        // Attach to existing vertices to create more complex structure\n        parent[i] = (i - used) % fingertips + 1;\n        length[i] = max(1, arm_length / 2);\n    }\n    \n    // Place root near center\n    root_x = N / 2;\n    root_y = N / 2;\n}\n\n// Calculate Manhattan distance\nint manhattan_distance(pair<int, int> a, pair<int, int> b) {\n    return abs(a.first - b.first) + abs(a.second - b.second);\n}\n\n// Find closest available target for a source\npair<int, int> find_closest_target(pair<int, int> source, \n                                  const vector<pair<int, int>>& available_targets) {\n    int best_idx = -1;\n    int best_dist = INT_MAX;\n    \n    for (int i = 0; i < available_targets.size(); i++) {\n        int dist = manhattan_distance(source, available_targets[i]);\n        if (dist < best_dist) {\n            best_dist = dist;\n            best_idx = i;\n        }\n    }\n    \n    return {best_idx, best_dist};\n}\n\n// Simple pathfinding with basic collision avoidance\nvector<string> generate_path(pair<int, int> from, pair<int, int> to, \n                            vector<string>& current_state) {\n    vector<string> path;\n    int x = from.first, y = from.second;\n    int tx = to.first, ty = to.second;\n    \n    while (x != tx || y != ty) {\n        string move(2 * V, '.');\n        \n        // Move horizontally first\n        if (x < tx) {\n            move[0] = 'D';\n            x++;\n        } else if (x > tx) {\n            move[0] = 'U';\n            x--;\n        } else if (y < ty) {\n            move[0] = 'R';\n            y++;\n        } else if (y > ty) {\n            move[0] = 'L';\n            y--;\n        }\n        \n        path.push_back(move);\n    }\n    \n    return path;\n}\n\n// Main solving function\nvector<string> solve() {\n    vector<string> operations;\n    vector<string> current_s = s;\n    vector<pair<int, int>> remaining_sources = sources;\n    vector<pair<int, int>> remaining_targets = targets;\n    \n    // Sort by distance to prioritize closer pairs\n    vector<tuple<int, int, int>> source_target_pairs;\n    for (int i = 0; i < remaining_sources.size(); i++) {\n        auto [target_idx, dist] = find_closest_target(remaining_sources[i], remaining_targets);\n        if (target_idx != -1) {\n            source_target_pairs.push_back({dist, i, target_idx});\n        }\n    }\n    sort(source_target_pairs.begin(), source_target_pairs.end());\n    \n    int turns = 0;\n    const int MAX_TURNS = 100000;\n    \n    for (auto [dist, src_idx, tgt_idx] : source_target_pairs) {\n        if (turns >= MAX_TURNS - 1000) break;\n        \n        auto source = remaining_sources[src_idx];\n        auto target = remaining_targets[tgt_idx];\n        \n        // Move arm to source\n        auto path_to_source = generate_path({root_x, root_y}, source, current_s);\n        for (const auto& move : path_to_source) {\n            operations.push_back(move);\n            turns++;\n            if (turns >= MAX_TURNS) break;\n        }\n        if (turns >= MAX_TURNS) break;\n        \n        // Grab takoyaki\n        string grab_op(2 * V, '.');\n        grab_op[0] = '.'; // No movement\n        // Use first available fingertip\n        for (int i = 1; i < V; i++) {\n            if (parent[i] != -1 && i < V/2 + 1) { // Assume these are fingertips\n                grab_op[V + i] = 'P';\n                break;\n            }\n        }\n        operations.push_back(grab_op);\n        turns++;\n        \n        // Update current state\n        current_s[source.first][source.second] = '0';\n        \n        // Move to target\n        auto path_to_target = generate_path(source, target, current_s);\n        for (const auto& move : path_to_target) {\n            operations.push_back(move);\n            turns++;\n            if (turns >= MAX_TURNS) break;\n        }\n        if (turns >= MAX_TURNS) break;\n        \n        // Release takoyaki\n        string release_op(2 * V, '.');\n        release_op[0] = '.';\n        for (int i = 1; i < V; i++) {\n            if (parent[i] != -1 && i < V/2 + 1) {\n                release_op[V + i] = 'P';\n                break;\n            }\n        }\n        operations.push_back(release_op);\n        turns++;\n        \n        // Update current state\n        current_s[target.first][target.second] = '1';\n        \n        // Remove completed pair\n        remaining_sources.erase(remaining_sources.begin() + src_idx);\n        remaining_targets.erase(remaining_targets.begin() + tgt_idx);\n    }\n    \n    return operations;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> V;\n    \n    s.resize(N);\n    t.resize(N);\n    \n    for (int i = 0; i < N; i++) {\n        cin >> s[i];\n    }\n    for (int i = 0; i < N; i++) {\n        cin >> t[i];\n    }\n    \n    sources = find_positions(s);\n    targets = find_positions(t);\n    \n    // Design and output arm\n    design_arm();\n    \n    cout << V << \"\\n\";\n    for (int i = 1; i < V; i++) {\n        cout << parent[i] << \" \" << length[i] << \"\\n\";\n    }\n    cout << root_x << \" \" << root_y << \"\\n\";\n    \n    // Generate and output operations\n    auto operations = solve();\n    \n    for (const auto& op : operations) {\n        cout << op << \"\\n\";\n    }\n    \n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    Point(int x = 0, int y = 0) : x(x), y(y) {}\n};\n\nstruct Fish {\n    int x, y, type; // 0 = mackerel, 1 = sardine\n};\n\nint N;\nvector<Fish> fishes;\nvector<Point> polygon;\n\n// Count fish in rectangle [x1,x2] \u00d7 [y1,y2]\npair<int,int> countFish(int x1, int y1, int x2, int y2) {\n    int mackerels = 0, sardines = 0;\n    for (const auto& fish : fishes) {\n        if (fish.x >= x1 && fish.x <= x2 && fish.y >= y1 && fish.y <= y2) {\n            if (fish.type == 0) mackerels++;\n            else sardines++;\n        }\n    }\n    return {mackerels, sardines};\n}\n\n// Calculate score for a region\nint scoreRegion(int x1, int y1, int x2, int y2) {\n    auto [m, s] = countFish(x1, y1, x2, y2);\n    return max(0, m - s + 1);\n}\n\n// Create simple rectangle polygon\nvector<Point> createRectangle(int x1, int y1, int x2, int y2) {\n    return {\n        Point(x1, y1),\n        Point(x2, y1),\n        Point(x2, y2),\n        Point(x1, y2)\n    };\n}\n\n// Try to improve polygon by adding a rectangular notch\nvector<Point> tryAddNotch(const vector<Point>& poly, int x1, int y1, int x2, int y2) {\n    // Find which edge to modify\n    vector<Point> bestPoly = poly;\n    int bestScore = 0;\n    \n    // Count current fish in polygon (simplified - assumes rectangle)\n    auto [currM, currS] = countFish(0, 0, 100000, 100000);\n    int currScore = max(0, currM - currS + 1);\n    \n    // Try removing the rectangular region\n    auto [removeM, removeS] = countFish(x1, y1, x2, y2);\n    int newScore = max(0, (currM - removeM) - (currS - removeS) + 1);\n    \n    if (newScore > currScore) {\n        // Create notch by modifying polygon\n        vector<Point> newPoly;\n        \n        // Simple approach: if notch is at edge, extend polygon\n        if (x1 == 0) {\n            newPoly = {\n                Point(x2, y1),\n                Point(100000, y1),\n                Point(100000, 100000),\n                Point(0, 100000),\n                Point(0, y2),\n                Point(x2, y2)\n            };\n        } else if (x2 == 100000) {\n            newPoly = {\n                Point(0, 0),\n                Point(x1, 0),\n                Point(x1, y1),\n                Point(100000, y1),\n                Point(100000, y2),\n                Point(x1, y2),\n                Point(x1, 100000),\n                Point(0, 100000)\n            };\n        } else {\n            // For internal notches, create more complex polygon\n            newPoly = poly; // Keep original if can't handle\n        }\n        \n        return newPoly;\n    }\n    \n    return poly;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    \n    // Read mackerels\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        fishes.push_back({x, y, 0});\n    }\n    \n    // Read sardines\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        fishes.push_back({x, y, 1});\n    }\n    \n    // Start with full area\n    polygon = createRectangle(0, 0, 100000, 100000);\n    \n    // Try to improve by removing bad regions\n    const int STEP = 10000;\n    const int MIN_SIZE = 5000;\n    \n    // Greedy removal of sardine-heavy regions\n    for (int iter = 0; iter < 10; iter++) {\n        bool improved = false;\n        \n        // Try different rectangular regions to remove\n        for (int x = 0; x + MIN_SIZE <= 100000; x += STEP) {\n            for (int y = 0; y + MIN_SIZE <= 100000; y += STEP) {\n                vector<Point> newPoly = tryAddNotch(polygon, x, y, x + MIN_SIZE, y + MIN_SIZE);\n                \n                // Count fish in new polygon (simplified)\n                auto [newM, newS] = countFish(0, 0, 100000, 100000); // This is simplified\n                int newScore = max(0, newM - newS + 1);\n                \n                auto [currM, currS] = countFish(0, 0, 100000, 100000);\n                int currScore = max(0, currM - currS + 1);\n                \n                if (newScore > currScore) {\n                    polygon = newPoly;\n                    improved = true;\n                    break;\n                }\n            }\n            if (improved) break;\n        }\n        if (!improved) break;\n    }\n    \n    // Ensure polygon is valid and output\n    if (polygon.size() < 4) {\n        polygon = createRectangle(0, 0, 100000, 100000);\n    }\n    \n    // Remove consecutive duplicate points\n    vector<Point> cleaned;\n    for (int i = 0; i < polygon.size(); i++) {\n        int next = (i + 1) % polygon.size();\n        if (polygon[i].x != polygon[next].x || polygon[i].y != polygon[next].y) {\n            cleaned.push_back(polygon[i]);\n        }\n    }\n    polygon = cleaned;\n    \n    if (polygon.size() < 4) {\n        polygon = createRectangle(0, 0, 100000, 100000);\n    }\n    \n    // Output result\n    cout << polygon.size() << \"\\n\";\n    for (const auto& p : polygon) {\n        cout << p.x << \" \" << p.y << \"\\n\";\n    }\n    \n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\n#include <random>\n#include <chrono>\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint randint(int a, int b) {\n    return uniform_int_distribution<int>(a, b)(rng);\n}\n\nstruct Rect {\n    long long w, h;\n    int idx;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T, sigma;\n    cin >> N >> T >> sigma;\n    vector<Rect> rects(N);\n    for (int i = 0; i < N; i++) {\n        cin >> rects[i].w >> rects[i].h;\n        rects[i].idx = i;\n    }\n\n    // We'll track the best estimated score\n    long long best_est_score = LLONG_MAX;\n    int best_skip = 0;\n\n    for (int turn = 0; turn < T; turn++) {\n        // Decide how many to skip\n        int skip;\n        if (turn < T * 0.6) {\n            skip = randint(0, N/2);\n        } else {\n            skip = best_skip;\n        }\n\n        // Build skip mask: skip the 'skip' rectangles with largest (w+h)\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int i, int j) {\n            return (rects[i].w + rects[i].h) > (rects[j].w + rects[j].h);\n        });\n        vector<bool> skip_mask(N, false);\n        for (int i = 0; i < skip; i++) {\n            skip_mask[order[i]] = true;\n        }\n\n        // Build list of rectangles to place: in increasing index order\n        vector<int> to_place;\n        for (int i = 0; i < N; i++) {\n            if (!skip_mask[i]) to_place.push_back(i);\n        }\n        int n = to_place.size();\n\n        // We'll simulate placements using noisy sizes\n        vector<long long> xleft(n), ytop(n); // positions\n        vector<long long> width(n), height(n); // actual sizes used (rotated)\n        vector<int> orig_idx(n); // original index\n\n        // Output sequence\n        vector<tuple<int, int, char, int>> seq;\n\n        long long curW = 0, curH = 0;\n\n        for (int i = 0; i < n; i++) {\n            int idx = to_place[i];\n            long long w0 = rects[idx].w;\n            long long h0 = rects[idx].h;\n\n            int best_r = 0;\n            char best_d = 'U';\n            int best_b = -1;\n            long long best_WH = LLONG_MAX;\n\n            // Try several random combinations\n            int tries = 10;\n            for (int t = 0; t < tries; t++) {\n                int r = randint(0, 1);\n                long long wi = (r == 0 ? w0 : h0);\n                long long hi = (r == 0 ? h0 : w0);\n\n                char d = (randint(0,1) ? 'U' : 'L');\n                int b = -1;\n                if (d == 'U') {\n                    // b must be -1 or a previously placed rectangle (index < i)\n                    if (i > 0) {\n                        b = randint(-1, i-1);\n                    } else {\n                        b = -1;\n                    }\n                } else {\n                    if (i > 0) {\n                        b = randint(-1, i-1);\n                    } else {\n                        b = -1;\n                    }\n                }\n\n                // Compute position for this combo\n                long long xi, yi;\n\n                if (d == 'U') {\n                    // x: align left edge to right edge of b (or 0)\n                    if (b == -1) {\n                        xi = 0;\n                    } else {\n                        xi = xleft[b] + width[b];\n                    }\n                    // y: drop from top until hit bottom of someone or y=0\n                    yi = 0;\n                    for (int j = 0; j < i; j++) {\n                        // check overlap in x\n                        long long x1 = xi, x2 = xi + wi;\n                        long long ox1 = xleft[j], ox2 = xleft[j] + width[j];\n                        if (x2 > ox1 && x1 < ox2) {\n                            yi = max(yi, ytop[j] + height[j]);\n                        }\n                    }\n                } else {\n                    // y: align top edge to bottom edge of b (or 0)\n                    if (b == -1) {\n                        yi = 0;\n                    } else {\n                        yi = ytop[b] + height[b];\n                    }\n                    // x: move left until hit right edge of someone or x=0\n                    xi = 0;\n                    for (int j = 0; j < i; j++) {\n                        long long y1 = yi, y2 = yi + hi;\n                        long long oy1 = ytop[j], oy2 = ytop[j] + height[j];\n                        if (y2 > oy1 && y1 < oy2) {\n                            xi = max(xi, xleft[j] + width[j]);\n                        }\n                    }\n                }\n\n                long long newW = max(curW, xi + wi);\n                long long newH = max(curH, yi + hi);\n                long long WH = newW + newH;\n\n                if (WH < best_WH) {\n                    best_WH = WH;\n                    best_r = r;\n                    best_d = d;\n                    best_b = b;\n                }\n            }\n\n            // Now do the best one for real\n            long long wi = (best_r == 0 ? w0 : h0);\n            long long hi = (best_r == 0 ? h0 : w0);\n\n            long long xi, yi;\n            if (best_d == 'U') {\n                if (best_b == -1) {\n                    xi = 0;\n                } else {\n                    xi = xleft[best_b] + width[best_b];\n                }\n                yi = 0;\n                for (int j = 0; j < i; j++) {\n                    long long x1 = xi, x2 = xi + wi;\n                    long long ox1 = xleft[j], ox2 = xleft[j] + width[j];\n                    if (x2 > ox1 && x1 < ox2) {\n                        yi = max(yi, ytop[j] + height[j]);\n                    }\n                }\n            } else {\n                if (best_b == -1) {\n                    yi = 0;\n                } else {\n                    yi = ytop[best_b] + height[best_b];\n                }\n                xi = 0;\n                for (int j = 0; j < i; j++) {\n                    long long y1 = yi, y2 = yi + hi;\n                    long long oy1 = ytop[j], oy2 = ytop[j] + height[j];\n                    if (y2 > oy1 && y1 < oy2) {\n                        xi = max(xi, xleft[j] + width[j]);\n                    }\n                }\n            }\n\n            // Store\n            xleft[i] = xi;\n            ytop[i] = yi;\n            width[i] = wi;\n            height[i] = hi;\n            orig_idx[i] = idx;\n\n            curW = max(curW, xi + wi);\n            curH = max(curH, yi + hi);\n\n            seq.emplace_back(idx, best_r, best_d, best_b);\n        }\n\n        // Output\n        cout << n << \"\\n\";\n        for (auto [p, r, d, b] : seq) {\n            cout << p << \" \" << r << \" \" << d << \" \" << b << \"\\n\";\n        }\n        cout.flush();\n\n        // Read W', H'\n        long long Wp, Hp;\n        cin >> Wp >> Hp;\n\n        // Compute estimated total score\n        long long unused = 0;\n        for (int i = 0; i < N; i++) {\n            if (skip_mask[i]) {\n                unused += rects[i].w + rects[i].h;\n            }\n        }\n        long long est_total = Wp + Hp + unused;\n\n        if (est_total < best_est_score) {\n            best_est_score = est_total;\n            best_skip = skip;\n            // # cerr << \"# New best est: \" << est_total << \" (skip=\" << skip << \")\" << endl;\n            cout << \"# improved: \" << est_total << \" (skip=\" << skip << \")\" << endl;\n        }\n    }\n\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\n#include <atcoder/dsu>\nusing namespace std;\nusing namespace atcoder;\n\nstatic const int MAXN = 1005;\nstatic const int MAXH = 12;\n\nint N, M, H;\nint A[MAXN];\nvector<int> G[MAXN];\nint par[MAXN];          // parent array, -1 for root\nint depth[MAXN];        // depth[v] = number of edges from root\nint64_t contrib[MAXN];  // (depth[v]+1)*A[v]\nint64_t total_score;\n\n// ---------- utility ----------\ninline void update_contrib(int v) {\n    contrib[v] = int64_t(depth[v] + 1) * A[v];\n}\n\n// ---------- initial greedy ----------\nvoid greedy_build() {\n    vector<char> used(N, 0);\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    // shuffle for diversity\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    shuffle(order.begin(), order.end(), rng);\n\n    // sort by beauty descending\n    sort(order.begin(), order.end(), [&](int u, int v) {\n        return A[u] > A[v];\n    });\n\n    total_score = 0;\n    for (int v = 0; v < N; ++v) par[v] = -2;\n\n    for (int u : order) if (par[u] == -2) {\n        // BFS tree rooted at u, cap depth at H\n        queue<int> q;\n        par[u] = -1;\n        depth[u] = 0;\n        update_contrib(u);\n        q.push(u);\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            if (depth[v] == H) continue;\n            for (int w : G[v]) if (par[w] == -2) {\n                par[w] = v;\n                depth[w] = depth[v] + 1;\n                update_contrib(w);\n                q.push(w);\n            }\n        }\n    }\n    // compute total\n    total_score = 0;\n    for (int v = 0; v < N; ++v) total_score += contrib[v];\n}\n\n// ---------- local improvement ----------\nvoid local_search(int iterations) {\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    vector<int> verts(N);\n    iota(verts.begin(), verts.end(), 0);\n\n    for (int it = 0; it < iterations; ++it) {\n        shuffle(verts.begin(), verts.end(), rng);\n        bool improved = false;\n\n        for (int v : verts) {\n            int old_p = par[v];\n            int old_d = depth[v];\n            int64_t old_delta = -contrib[v];\n\n            // try making v a new root\n            int best_new_p = -1;\n            int best_new_d = 0;\n            int64_t best_delta = 0;\n\n            // delta if root\n            int64_t delta_root = int64_t(1) * A[v] + old_delta;\n\n            if (delta_root > 0) {\n                best_new_p = -1;\n                best_new_d = 0;\n                best_delta = delta_root;\n            }\n\n            // try all neighbors as new parent\n            for (int w : G[v]) {\n                if (w == old_p) continue;\n                int nd = depth[w] + 1;\n                if (nd > H) continue;\n                int64_t delta = int64_t(nd + 1) * A[v] - contrib[v];\n                if (delta > best_delta) {\n                    best_delta = delta;\n                    best_new_p = w;\n                    best_new_d = nd;\n                }\n            }\n\n            if (best_delta > 0) {\n                // apply move\n                par[v] = best_new_p;\n                depth[v] = best_new_d;\n                update_contrib(v);\n                total_score += best_delta;\n                improved = true;\n            }\n        }\n        if (!improved) break;\n    }\n}\n\n// ---------- output ----------\nvoid output_answer() {\n    for (int i = 0; i < N; ++i) {\n        cout << par[i] << (i + 1 < N ? ' ' : '\\n');\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> H;\n    for (int i = 0; i < N; ++i) cin >> A[i];\n    for (int i = 0; i < M; ++i) {\n        int u, v; cin >> u >> v;\n        G[u].push_back(v);\n        G[v].push_back(u);\n    }\n    // discard coordinates\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n    }\n\n    int64_t best_score = -1;\n    vector<int> best_par(N);\n\n    auto save_best = [&]() {\n        if (total_score > best_score) {\n            best_score = total_score;\n            copy(par, par + N, best_par.begin());\n        }\n    };\n\n    // multi-start greedy + local\n    const int tries = 25;\n    const int loc_its = 80;\n    for (int t = 0; t < tries; ++t) {\n        greedy_build();\n        local_search(loc_its);\n        save_best();\n    }\n\n    // final output\n    copy(best_par.begin(), best_par.end(), par);\n    output_answer();\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\nusing uint = unsigned int;\n\nconst int NONE = -1;\nconst int DR[4] = {0, 0, -1, 1};\nconst int DC[4] = {-1, 1, 0, 0};\nconst char DIRC[4] = {'L','R','U','D'};\nconst int BACK[4] = {1, 0, 3, 2};\n\nint N;\nvector<string> B;\nvector<pair<int,int>> oni, fuku;\nvector<int> safe_dir;          // safe direction for each oni\nvector<vector<char>> cur;      // current board state\nvector<pair<char,int>> ops;    // output sequence\n\n// apply one shift and record it\nvoid apply(int d, int p) {\n    ops.emplace_back(DIRC[d], p);\n    if (d == 0) { // L row p\n        for (int j = 0; j + 1 < N; ++j) cur[p][j] = cur[p][j+1];\n        cur[p][N-1] = '.';\n    } else if (d == 1) { // R row p\n        for (int j = N-1; j > 0; --j) cur[p][j] = cur[p][j-1];\n        cur[p][0] = '.';\n    } else if (d == 2) { // U col p\n        for (int i = 0; i + 1 < N; ++i) cur[i][p] = cur[i+1][p];\n        cur[N-1][p] = '.';\n    } else { // D col p\n        for (int i = N-1; i > 0; --i) cur[i][p] = cur[i-1][p];\n        cur[0][p] = '.';\n    }\n}\n\n// push+pull sequence along direction d for row/col p\nvoid push_pull(int d, int p) {\n    int len = (d < 2 ? N : N);\n    for (int t = 0; t < len; ++t) apply(d, p);\n    for (int t = 0; t < len; ++t) apply(BACK[d], p);\n}\n\n// count how many oni in row/col p can be removed by direction d without hitting fuku\nint count_removable(int d, int p) {\n    int cnt = 0;\n    if (d < 2) { // row p\n        int step = (d == 0 ? -1 : 1);\n        for (int j = 0; j < N; ++j) {\n            bool ok = true;\n            for (int k = j; k >= 0 && k < N; k += step) {\n                if (cur[p][k] == 'o') { ok = false; break; }\n                if (cur[p][k] == 'x') break;\n            }\n            if (ok && cur[p][j] == 'x') ++cnt;\n        }\n    } else { // col p\n        int step = (d == 2 ? -1 : 1);\n        for (int i = 0; i < N; ++i) {\n            bool ok = true;\n            for (int k = i; k >= 0 && k < N; k += step) {\n                if (cur[k][p] == 'o') { ok = false; break; }\n                if (cur[k][p] == 'x') break;\n            }\n            if (ok && cur[i][p] == 'x') ++cnt;\n        }\n    }\n    return cnt;\n}\n\n// greedy baseline: always pick the row/col+direction that removes most oni at once\nvoid greedy_pass() {\n    while (true) {\n        int best = 0, bd = NONE, bp = NONE;\n        for (int d = 0; d < 4; ++d) {\n            for (int p = 0; p < N; ++p) {\n                int c = count_removable(d, p);\n                if (c > best) { best = c; bd = d; bp = p; }\n            }\n        }\n        if (best == 0) break;\n        push_pull(bd, bp);\n    }\n}\n\n// evaluate total moves for current safe_dir assignment\nint evaluate() {\n    // rebuild cur\n    cur = vector<vector<char>>(N, vector<char>(N, '.'));\n    for (auto [i,j]: fuku) cur[i][j] = 'o';\n    for (int idx = 0; idx < (int)oni.size(); ++idx) {\n        auto [i,j] = oni[idx];\n        cur[i][j] = 'x';\n    }\n    ops.clear();\n    greedy_pass();\n    return ops.size();\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    B.resize(N);\n    for (int i = 0; i < N; ++i) cin >> B[i];\n\n    // collect initial positions\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            if (B[i][j] == 'x') oni.emplace_back(i,j);\n            if (B[i][j] == 'o') fuku.emplace_back(i,j);\n        }\n    const int M = oni.size();\n\n    // precompute safe directions for each oni\n    safe_dir.resize(M);\n    for (int idx = 0; idx < M; ++idx) {\n        auto [i,j] = oni[idx];\n        vector<bool> safe(4, true);\n        // left\n        for (int k = j-1; k >= 0; --k) if (B[i][k] == 'o') safe[0] = false;\n        // right\n        for (int k = j+1; k < N; ++k) if (B[i][k] == 'o') safe[1] = false;\n        // up\n        for (int k = i-1; k >= 0; --k) if (B[k][j] == 'o') safe[2] = false;\n        // down\n        for (int k = i+1; k < N; ++k) if (B[k][j] == 'o') safe[3] = false;\n        // pick first safe\n        int pick = 0;\n        for (; pick < 4; ++pick) if (safe[pick]) break;\n        safe_dir[idx] = pick;\n    }\n\n    // initial evaluation\n    int bestT = evaluate();\n    auto best_ops = ops;\n\n    // simple randomised local search\n    mt19937 rng(42);\n    uniform_int_distribution<int> uid_idx(0, M-1);\n    uniform_int_distribution<int> uid_dir(0, 3);\n    const double START_TEMP = 10.0, END_TEMP = 1.0;\n    const int MAX_ITER = 200000;\n    for (int iter = 0; iter < MAX_ITER; ++iter) {\n        double temp = START_TEMP + (END_TEMP - START_TEMP) * iter / MAX_ITER;\n        int idx = uid_idx(rng);\n        auto [i,j] = oni[idx];\n        int oldd = safe_dir[idx];\n        int newd = uid_dir(rng);\n        if (newd == oldd) continue;\n        // check newd is safe for this oni\n        bool ok = true;\n        if (newd == 0) { for (int k = j-1; k >= 0; --k) if (B[i][k]=='o') ok=false; }\n        else if (newd==1){ for(int k=j+1;k<N;++k) if(B[i][k]=='o') ok=false; }\n        else if (newd==2){ for(int k=i-1;k>=0;--k) if(B[k][j]=='o') ok=false; }\n        else { for(int k=i+1;k<N;++k) if(B[k][j]=='o') ok=false; }\n        if (!ok) continue;\n\n        safe_dir[idx] = newd;\n        int newT = evaluate();\n        int delta = newT - bestT;\n        bool accept = (delta < 0) || (uniform_real_distribution<double>(0,1)(rng) < exp(-delta/temp));\n        if (delta < 0) {\n            bestT = newT;\n            best_ops = ops;\n        }\n        if (!accept) {\n            safe_dir[idx] = oldd;\n        }\n    }\n\n    // output best found\n    cerr << \"T = \" << bestT << \"\\n\";\n    for (auto [d,p]: best_ops) cout << d << \" \" << p << \"\\n\";\n    return 0;\n}","ahc044":"#include <iostream>\n#include <vector>\n#include <random>\n#include <algorithm>\n#include <chrono>\n\nusing namespace std;\n\nconst int N = 100;\nconst int L = 500000;\n\nint T[N];\nint a[N], b[N];\nint t[N];\nint current_sequence[L];\n\nint simulate() {\n    fill(t, t + N, 0);\n    int current = 0;\n    t[current] = 1;\n    for (int week = 1; week < L; ++week) {\n        int count = t[current];\n        int next;\n        if (count % 2 == 1) {\n            next = a[current];\n        } else {\n            next = b[current];\n        }\n        t[next]++;\n        current = next;\n    }\n    int error = 0;\n    for (int i = 0; i < N; ++i) {\n        error += abs(t[i] - T[i]);\n    }\n    return error;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    for (int i = 0; i < N; ++i) {\n        cin >> T[i];\n    }\n\n    // Initial greedy assignment\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    for (int i = 0; i < N; ++i) {\n        a[i] = uniform_int_distribution<int>(0, N - 1)(rng);\n        b[i] = uniform_int_distribution<int>(0, N - 1)(rng);\n    }\n\n    int best_error = simulate();\n    auto start = chrono::steady_clock::now();\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start).count() > 1800) {\n            break; // Stop after 1.8 seconds to ensure we don't exceed 2 seconds\n        }\n\n        int i = uniform_int_distribution<int>(0, N - 1)(rng);\n        int old_a = a[i], old_b = b[i];\n\n        // Try changing a[i] or b[i]\n        if (uniform_int_distribution<int>(0, 1)(rng) == 0) {\n            a[i] = uniform_int_distribution<int>(0, N - 1)(rng);\n        } else {\n            b[i] = uniform_int_distribution<int>(0, N - 1)(rng);\n        }\n\n        int new_error = simulate();\n        if (new_error < best_error) {\n            best_error = new_error;\n        } else {\n            // Revert\n            a[i] = old_a;\n            b[i] = old_b;\n        }\n    }\n\n    // Output the best found\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 City {\n    int id, lx, rx, ly, ry;\n    int cx() const { return (lx + rx) / 2; }\n    int cy() const { return (ly + ry) / 2; }\n};\n\nint N, M, Q, L, W;\nvector<int> G;\nvector<City> cities;\nvector<vector<int>> groups;\nvector<vector<pair<int, int>>> group_edges;\n\nvector<pair<int, int>> query(const vector<int>& c) {\n    cout << \"? \" << c.size();\n    for (int x : c) cout << \" \" << x;\n    cout << endl;\n    vector<pair<int, int>> edges;\n    for (int i = 0; i < c.size() - 1; ++i) {\n        int a, b;\n        cin >> a >> b;\n        edges.emplace_back(a, b);\n    }\n    return edges;\n}\n\nvoid answer() {\n    cout << \"!\" << endl;\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < groups[i].size(); ++j) {\n            if (j > 0) cout << \" \";\n            cout << groups[i][j];\n        }\n        cout << endl;\n        for (auto [a, b] : group_edges[i]) {\n            cout << a << \" \" << b << endl;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    cities.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> cities[i].lx >> cities[i].rx >> cities[i].ly >> cities[i].ry;\n        cities[i].id = i;\n    }\n\n    // Sort cities by center coordinates\n    sort(cities.begin(), cities.end(), [](const City& a, const City& b) {\n        if (a.cx() != b.cx()) return a.cx() < b.cx();\n        return a.cy() < b.cy();\n    });\n\n    // Assign to groups\n    groups.resize(M);\n    group_edges.resize(M);\n    int ptr = 0;\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < G[i]; ++j) {\n            groups[i].push_back(cities[ptr++].id);\n        }\n    }\n\n    // Use queries to get edges for each group\n    int queries_used = 0;\n    for (int i = 0; i < M; ++i) {\n        int sz = groups[i].size();\n        if (sz <= 1) continue;\n        // Use triplets to cover the group\n        for (int j = 0; j < sz - 1; j += 2) {\n            if (queries_used >= Q) break;\n            vector<int> c;\n            if (j + 2 < sz) {\n                c = {groups[i][j], groups[i][j+1], groups[i][j+2]};\n            } else {\n                c = {groups[i][j], groups[i][j+1]};\n            }\n            auto edges = query(c);\n            for (auto [a, b] : edges) {\n                group_edges[i].emplace_back(a, b);\n            }\n            queries_used++;\n        }\n        // Ensure connectivity by adding edges if necessary\n        // This is a simple heuristic: connect in order\n        if (group_edges[i].size() < sz - 1) {\n            for (int j = 0; j < sz - 1; ++j) {\n                group_edges[i].emplace_back(groups[i][j], groups[i][j+1]);\n            }\n        }\n    }\n\n    answer();\n    return 0;\n}","ahc046":"#pragma GCC optimize(\"O3,unroll-loops\")\n#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nstatic const int N = 20;\nstatic const int M = 40;\nstatic const int LIMIT = 2*N*M;\n\nint target[M];\nint targetLeft;                      // how many still to visit\nbool blocked[N][N];                  // current wall state\nint  distSlide[N][N][4];             // dist to next block/border in 4 dirs\nint  di[] = {-1,1,0,0};\nint  dj[] = {0,0,-1,1};\nchar actionChar[] = {'M','S','A'};\nchar dirChar[]    = {'U','D','L','R'};\n\nstruct Step {\n    int i,j;\n    int g;\n    vector<pair<int,int>> pathActs; // (act,dir) pairs leading here\n    bool operator<(const Step& o) const { return g > o.g; }\n};\n\ninline bool inside(int i,int j){ return i>=0&&i<N&&j>=0&&j<N; }\n\nvoid rebuildDistSlide(){\n    for(int i=0;i<N;i++){\n        // up\n        for(int j=0;j<N;j++){\n            int d=0;\n            for(int ii=i-1;ii>=0;ii--){\n                if(blocked[ii][j]) break;\n                d++;\n            }\n            distSlide[i][j][0]=d;\n        }\n        // down\n        for(int j=0;j<N;j++){\n            int d=0;\n            for(int ii=i+1;ii<N;ii++){\n                if(blocked[ii][j]) break;\n                d++;\n            }\n            distSlide[i][j][1]=d;\n        }\n    }\n    for(int j=0;j<N;j++){\n        // left\n        for(int i=0;i<N;i++){\n            int d=0;\n            for(int jj=j-1;jj>=0;jj--){\n                if(blocked[i][jj]) break;\n                d++;\n            }\n            distSlide[i][j][2]=d;\n        }\n        // right\n        for(int i=0;i<N;i++){\n            int d=0;\n            for(int jj=j+1;jj<N;jj++){\n                if(blocked[i][jj]) break;\n                d++;\n            }\n            distSlide[i][j][3]=d;\n        }\n    }\n}\n\nint heuristic(int si,int sj,int ti,int tj){\n    return abs(si-ti)+abs(sj-tj);\n}\n\nvector<pair<int,int>> planSegment(int si,int sj,int ti,int tj){\n    priority_queue<Step> pq;\n    Step start{si,sj,0,{}};\n    pq.push(start);\n    static char vis[ N ][ N ];\n    memset(vis,0,sizeof(vis));\n    vis[si][sj]=1;\n    const int EXPAND = 20000;\n    int expanded = 0;\n    while(!pq.empty() && expanded < EXPAND){\n        Step cur = pq.top(); pq.pop();\n        expanded++;\n        if(cur.i==ti && cur.j==tj){\n            return cur.pathActs;\n        }\n        int g2 = cur.g+1;\n        for(int dir=0;dir<4;dir++){\n            int ni = cur.i + di[dir];\n            int nj = cur.j + dj[dir];\n            // 1) Move\n            if(inside(ni,nj) && !blocked[ni][nj] && !vis[ni][nj]){\n                vis[ni][nj]=1;\n                Step nxt = cur;\n                nxt.i=ni; nxt.j=nj; nxt.g=g2;\n                nxt.pathActs.emplace_back(0,dir);\n                pq.push(nxt);\n            }\n            // 2) Slide\n            int ds = distSlide[cur.i][cur.j][dir];\n            if(ds>0){\n                int ei = cur.i + di[dir]*ds;\n                int ej = cur.j + dj[dir]*ds;\n                if(!vis[ei][ej]){\n                    vis[ei][ej]=1;\n                    Step nxt = cur;\n                    nxt.i=ei; nxt.j=ej; nxt.g=g2;\n                    nxt.pathActs.emplace_back(1,dir);\n                    pq.push(nxt);\n                }\n            }\n            // 3) Alter\n            int bi = cur.i + di[dir];\n            int bj = cur.j + dj[dir];\n            if(inside(bi,bj)){\n                // toggle\n                blocked[bi][bj] ^= 1;\n                rebuildDistSlide();\n                Step nxt = cur;\n                nxt.g=g2;\n                nxt.pathActs.emplace_back(2,dir);\n                pq.push(nxt);\n                // undo\n                blocked[bi][bj] ^= 1;\n                rebuildDistSlide();\n            }\n        }\n    }\n    // fallback: plain Manhattan moves\n    vector<pair<int,int>> fallback;\n    int dx = ti - si;\n    int dy = tj - sj;\n    int px = si, py = sj;\n    while(px<ti){ px++; fallback.emplace_back(0,1); }\n    while(px>ti){ px--; fallback.emplace_back(0,0); }\n    while(py<tj){ py++; fallback.emplace_back(0,3); }\n    while(py>tj){ py--; fallback.emplace_back(0,2); }\n    return fallback;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int n,m;\n    cin >> n >> m;\n    assert(n==N && m==M);\n    int si,sj;\n    cin >> si >> sj;\n    vector<int> I(M),J(M);\n    for(int k=0;k<M;k++){\n        cin >> I[k] >> J[k];\n    }\n    // initialise\n    memset(blocked,0,sizeof(blocked));\n    rebuildDistSlide();\n    vector<pair<int,int>> fullPlan;\n    int ci=si, cj=sj;\n    for(int idx=0;idx<M;idx++){\n        int ti = I[idx];\n        int tj = J[idx];\n        auto seg = planSegment(ci,cj,ti,tj);\n        fullPlan.insert(fullPlan.end(), seg.begin(), seg.end());\n        // execute to update real state\n        for(auto [act,dir]: seg){\n            if(act==0){ // Move\n                ci += di[dir];\n                cj += dj[dir];\n            } else if(act==1){ // Slide\n                int ds = distSlide[ci][cj][dir];\n                ci += di[dir]*ds;\n                cj += dj[dir]*ds;\n            } else { // Alter\n                int bi = ci + di[dir];\n                int bj = cj + dj[dir];\n                blocked[bi][bj] ^= 1;\n                rebuildDistSlide();\n            }\n        }\n        assert(ci==ti && cj==tj);\n    }\n    // output\n    cout << fullPlan.size() << \"\\n\";\n    for(auto [act,dir]: fullPlan){\n        cout << actionChar[act] << \" \" << dirChar[dir] << \"\\n\";\n    }\n    return 0;\n}"},"2":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nstruct Rect {\n    int a, b, c, d;\n    ll area()  const { return (ll)(c - a) * (d - b); }\n    bool contains(double x, double y) const {\n        return a <= x && x <= c && b <= y && y <= d;\n    }\n};\n\nstruct Company {\n    int x, y, r;\n    Rect R;\n    double cx, cy;          // desired centre\n};\n\nint n;\nvector<Company> co;\n\nbool overlap(int i, int j) {\n    const Rect &p = co[i].R, &q = co[j].R;\n    return !(p.c <= q.a || q.c <= p.a || p.d <= q.b || q.d <= p.b);\n}\n\nvoid remove_all_overlaps() {\n    bool dirty;\n    do {\n        dirty = false;\n        for (int i = 0; i < n; ++i)\n            for (int j = i + 1; j < n; ++j)\n                if (overlap(i, j)) {\n                    dirty = true;\n                    Rect &u = co[i].R;\n                    Rect &v = co[j].R;\n                    // shrink the one that is larger than its request, or the larger area\n                    if (u.area() > co[i].r || (v.area() <= co[j].r && u.area() > v.area())) {\n                        // shrink u by one pixel\n                        int dx = u.c - u.a, dy = u.d - u.b;\n                        if (dx > dy) {\n                            if (u.c - 1 > u.a) u.c--;\n                            else if (u.a + 1 < u.c) u.a++;\n                            else if (u.d - 1 > u.b) u.d--;\n                            else u.b++;\n                        } else {\n                            if (u.d - 1 > u.b) u.d--;\n                            else if (u.b + 1 < u.d) u.b++;\n                            else if (u.c - 1 > u.a) u.c--;\n                            else u.a++;\n                        }\n                    } else {\n                        // shrink v by one pixel\n                        int dx = v.c - v.a, dy = v.d - v.b;\n                        if (dx > dy) {\n                            if (v.c - 1 > v.a) v.c--;\n                            else if (v.a + 1 < v.c) v.a++;\n                            else if (v.d - 1 > v.b) v.d--;\n                            else v.b++;\n                        } else {\n                            if (v.d - 1 > v.b) v.d--;\n                            else if (v.b + 1 < v.d) v.b++;\n                            else if (v.c - 1 > v.a) v.c--;\n                            else v.a++;\n                        }\n                    }\n                }\n    } while (dirty);\n}\n\nvoid grow_all() {\n    bool progress;\n    do {\n        progress = false;\n        for (int i = 0; i < n; ++i) {\n            Rect &R = co[i].R;\n            // try to expand by 1 pixel in each of the 4 directions\n            for (int dir = 0; dir < 4; ++dir) {\n                Rect tmp = R;\n                if (dir == 0) { tmp.a--; if (tmp.a < 0) continue; }\n                if (dir == 1) { tmp.b--; if (tmp.b < 0) continue; }\n                if (dir == 2) { tmp.c++; if (tmp.c > 10000) continue; }\n                if (dir == 3) { tmp.d++; if (tmp.d > 10000) continue; }\n                if (!tmp.contains(co[i].cx, co[i].cy)) continue;\n                bool ok = true;\n                for (int j = 0; j < n && ok; ++j)\n                    if (i != j && overlap(i, j)) ok = false;\n                if (ok) { R = tmp; progress = true; }\n            }\n        }\n    } while (progress);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> n;\n    co.resize(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> co[i].x >> co[i].y >> co[i].r;\n        co[i].cx = co[i].x + 0.5;\n        co[i].cy = co[i].y + 0.5;\n        // minimal rectangle containing the desired centre\n        co[i].R = {co[i].x, co[i].y, co[i].x + 1, co[i].y + 1};\n    }\n\n    remove_all_overlaps();   // guarantee no overlap\n    grow_all();              // improve score greedily\n    remove_all_overlaps();   // safety pass (grow_all is conservative, but be sure)\n\n    for (int i = 0; i < n; ++i)\n        cout << co[i].R.a << ' ' << co[i].R.b << ' '\n             << co[i].R.c << ' ' << co[i].R.d << '\\n';\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nint si, sj;\nint t[50][50];\nint p[50][50];\nint M;                       // number of distinct tiles\nvector<vector<pair<int,int>>> tileSquares; // tile id -> its squares\nint bestScore;\nstring bestPath;\n\n// 4 directions\nconst int dx[4] = {-1,1,0,0};\nconst int dy[4] = {0,0,-1,1};\nconst char dc[4] = {'U','D','L','R'};\n\n// order of directions, we will shuffle it sometimes\nint order[4] = {0,1,2,3};\n\nvoid dfs(int i, int j, vector<bool>& used, int score, string& path, int depth){\n    if(score > bestScore){\n        bestScore = score;\n        bestPath = path;\n    }\n    // try neighbours\n    for(int k = 0; k < 4; k++){\n        int d = order[k];\n        int ni = i + dx[d];\n        int nj = j + dy[d];\n        if(ni<0||ni>=50||nj<0||nj>=50) continue;\n        int nt = t[ni][nj];\n        if(used[nt]) continue;\n        // step on this tile\n        used[nt] = true;\n        path.push_back(dc[d]);\n        dfs(ni, nj, used, score + p[ni][nj], path, depth+1);\n        path.pop_back();\n        used[nt] = false;\n    }\n}\n\nstring solveOne(int starti, int startj){\n    bestScore = p[starti][startj];\n    bestPath.clear();\n    vector<bool> used(M, false);\n    used[t[starti][startj]] = true;\n    string path;\n    dfs(starti, startj, used, bestScore, path, 0);\n    return bestPath;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> si >> sj;\n    for(int i=0;i<50;i++)for(int j=0;j<50;j++) cin >> t[i][j];\n    for(int i=0;i<50;i++)for(int j=0;j<50;j++) cin >> p[i][j];\n\n    // build tileSquares and find M\n    int maxt = 0;\n    for(int i=0;i<50;i++)for(int j=0;j<50;j++) maxt = max(maxt, t[i][j]);\n    M = maxt + 1;\n    tileSquares.assign(M, {});\n    for(int i=0;i<50;i++)for(int j=0;j<50;j++) tileSquares[t[i][j]].emplace_back(i,j);\n\n    // try both squares of the initial tile (if 2 squares)\n    vector<pair<int,int>> starts;\n    int st = t[si][sj];\n    for(auto [i,j]: tileSquares[st]) starts.emplace_back(i,j);\n\n    string globalBest;\n    int globalScore = -1;\n\n    // several random restarts with shuffled direction order\n    for(int rep=0; rep<10; rep++){\n        // shuffle direction order\n        shuffle(order, order+4, mt19937(rep));\n        for(auto [i,j]: starts){\n            string cand = solveOne(i, j);\n            if(bestScore > globalScore){\n                globalScore = bestScore;\n                globalBest = cand;\n            }\n        }\n    }\n    cout << globalBest << '\\n';\n    return 0;\n}","ahc003":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <string>\n#include <algorithm>\n#include <cmath>\n#include <iomanip>\n#include <unordered_map>\n\nusing namespace std;\n\nconst int GRID_SIZE = 30;\nconst int NUM_QUERIES = 1000;\n\n// Directions: U, D, L, R\nconst int dr[] = {-1, 1, 0, 0};\nconst int dc[] = {0, 0, -1, 1};\nconst char dir_chars[] = {'U', 'D', 'L', 'R'};\n\nstruct Edge {\n    int r1, c1, r2, c2;\n    double length;\n    int count;\n    double sum_observed;\n\n    Edge(int r1, int c1, int r2, int c2) : r1(r1), c1(c1), r2(r2), c2(c2), length(5000.0), count(0), sum_observed(0.0) {}\n};\n\nvector<vector<Edge>> horizontal_edges; // horizontal_edges[i][j] is between (i,j) and (i,j+1)\nvector<vector<Edge>> vertical_edges;   // vertical_edges[i][j] is between (i,j) and (i+1,j)\n\nvoid initialize_edges() {\n    horizontal_edges.resize(GRID_SIZE, vector<Edge>(GRID_SIZE - 1));\n    vertical_edges.resize(GRID_SIZE - 1, vector<Edge>(GRID_SIZE));\n\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        for (int j = 0; j < GRID_SIZE - 1; ++j) {\n            horizontal_edges[i][j] = Edge(i, j, i, j + 1);\n        }\n    }\n    for (int i = 0; i < GRID_SIZE - 1; ++i) {\n        for (int j = 0; j < GRID_SIZE; ++j) {\n            vertical_edges[i][j] = Edge(i, j, i + 1, j);\n        }\n    }\n}\n\nstring generate_manhattan_path(int si, int sj, int ti, int tj) {\n    string path;\n    int dr = ti - si;\n    int dc = tj - sj;\n    if (dr > 0) {\n        path += string(dr, 'D');\n    } else {\n        path += string(-dr, 'U');\n    }\n    if (dc > 0) {\n        path += string(dc, 'R');\n    } else {\n        path += string(-dc, 'L');\n    }\n    return path;\n}\n\nvector<pair<int, int>> parse_path(int si, int sj, const string& path) {\n    vector<pair<int, int>> vertices;\n    int r = si, c = sj;\n    vertices.emplace_back(r, c);\n    for (char d : path) {\n        if (d == 'U') r--;\n        else if (d == 'D') r++;\n        else if (d == 'L') c--;\n        else if (d == 'R') c++;\n        vertices.emplace_back(r, c);\n    }\n    return vertices;\n}\n\ndouble compute_path_length(const vector<pair<int, int>>& vertices) {\n    double length = 0.0;\n    for (int i = 0; i + 1 < vertices.size(); ++i) {\n        int r1 = vertices[i].first, c1 = vertices[i].second;\n        int r2 = vertices[i + 1].first, c2 = vertices[i + 1].second;\n        if (r1 == r2 && abs(c1 - c2) == 1) {\n            int j = min(c1, c2);\n            length += horizontal_edges[r1][j].length;\n        } else if (c1 == c2 && abs(r1 - r2) == 1) {\n            int i = min(r1, r2);\n            length += vertical_edges[i][c1].length;\n        } else {\n            // invalid edge\n            length += 1e9;\n        }\n    }\n    return length;\n}\n\nvoid update_edges(const vector<pair<int, int>>& vertices, int observed) {\n    double observed_length = observed;\n    // De-noise: assume the true length is around observed / 1.0 (since noise is 0.9-1.1)\n    // But we can average over multiple observations\n    for (int i = 0; i + 1 < vertices.size(); ++i) {\n        int r1 = vertices[i].first, c1 = vertices[i].second;\n        int r2 = vertices[i + 1].first, c2 = vertices[i + 1].second;\n        Edge* edge = nullptr;\n        if (r1 == r2 && abs(c1 - c2) == 1) {\n            int j = min(c1, c2);\n            edge = &horizontal_edges[r1][j];\n        } else if (c1 == c2 && abs(r1 - r2) == 1) {\n            int i = min(r1, r2);\n            edge = &vertical_edges[i][c1];\n        }\n        if (edge) {\n            edge->count++;\n            edge->sum_observed += observed_length;\n            edge->length = edge->sum_observed / edge->count;\n        }\n    }\n}\n\nstring dijkstra(int si, int sj, int ti, int tj) {\n    // Dijkstra's algorithm to find the shortest path in the current estimates\n    vector<vector<double>> dist(GRID_SIZE, vector<double>(GRID_SIZE, 1e18));\n    vector<vector<pair<int, int>>> parent(GRID_SIZE, vector<pair<int, int>>(GRID_SIZE, {-1, -1}));\n    priority_queue<pair<double, pair<int, int>>, vector<pair<double, pair<int, int>>>, greater<pair<double, pair<int, int>>>> pq;\n    dist[si][sj] = 0.0;\n    pq.push({0.0, {si, sj}});\n\n    while (!pq.empty()) {\n        auto [d, pos] = pq.top(); pq.pop();\n        int r = pos.first, c = pos.second;\n        if (d > dist[r][c]) continue;\n        if (r == ti && c == tj) break;\n\n        for (int k = 0; k < 4; ++k) {\n            int nr = r + dr[k], nc = c + dc[k];\n            if (nr < 0 || nr >= GRID_SIZE || nc < 0 || nc >= GRID_SIZE) continue;\n            double edge_len = 0.0;\n            if (k == 0) { // U\n                edge_len = vertical_edges[nr][nc].length;\n            } else if (k == 1) { // D\n                edge_len = vertical_edges[r][c].length;\n            } else if (k == 2) { // L\n                edge_len = horizontal_edges[r][nc].length;\n            } else if (k == 3) { // R\n                edge_len = horizontal_edges[r][c].length;\n            }\n            if (dist[nr][nc] > d + edge_len) {\n                dist[nr][nc] = d + edge_len;\n                parent[nr][nc] = {r, c};\n                pq.push({dist[nr][nc], {nr, nc}});\n            }\n        }\n    }\n\n    // Reconstruct path\n    string path;\n    int r = ti, c = tj;\n    while (parent[r][c].first != -1) {\n        int pr = parent[r][c].first, pc = parent[r][c].second;\n        if (pr == r - 1) path += 'D';\n        else if (pr == r + 1) path += 'U';\n        else if (pc == c - 1) path += 'R';\n        else if (pc == c + 1) path += 'L';\n        r = pr; c = pc;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    initialize_edges();\n\n    for (int k = 0; k < NUM_QUERIES; ++k) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n\n        string path;\n        if (k < 100) {\n            // Early queries: use Manhattan path for exploration\n            path = generate_manhattan_path(si, sj, ti, tj);\n        } else {\n            // Later queries: use Dijkstra with current estimates\n            path = dijkstra(si, sj, ti, tj);\n            if (path.empty()) {\n                // Fallback to Manhattan if Dijkstra fails\n                path = generate_manhattan_path(si, sj, ti, tj);\n            }\n        }\n\n        cout << path << endl;\n        cout.flush();\n\n        int observed;\n        cin >> observed;\n        auto vertices = parse_path(si, sj, path);\n        update_edges(vertices, observed);\n    }\n\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\n#include \"atcoder/xoshiro256.h\"\nusing namespace std;\nusing ll = long long;\n\nstatic const int N = 20;\nstatic const int AL = 8;          // A..H\nstatic const char LET[] = \"ABCDEFGH\";\nstatic atcoder::xoshiro256 rng;\n\nint M;\nvector<string> S;\nint bestC;\nvector<string> bestGrid;\nint evalCalls = 0;\n\n// ---------- evaluation ----------\ninline int index(char c) { return c - 'A'; }\n\n// returns number of matched strings\nint evaluate(const vector<string>& g) {\n    ++evalCalls;\n    int cnt = 0;\n    for (const auto& s : S) {\n        int L = (int)s.size();\n        bool ok = false;\n        // horizontal\n        for (int i = 0; i < N && !ok; ++i) {\n            for (int st = 0; st < N; ++st) {\n                bool match = true;\n                for (int p = 0; p < L; ++p) {\n                    if (g[i][(st + p) % N] != s[p]) { match = false; break; }\n                }\n                if (match) { ok = true; break; }\n            }\n        }\n        if (ok) { ++cnt; continue; }\n        // vertical\n        for (int j = 0; j < N && !ok; ++j) {\n            for (int st = 0; st < N; ++st) {\n                bool match = true;\n                for (int p = 0; p < L; ++p) {\n                    if (g[(st + p) % N][j] != s[p]) { match = false; break; }\n                }\n                if (match) { ok = true; break; }\n            }\n        }\n        if (ok) ++cnt;\n    }\n    return cnt;\n}\n\n// ---------- utility ----------\nint fillCount(const vector<string>& g) {\n    int c = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (g[i][j] != '.') ++c;\n    return c;\n}\n\nvoid printGrid(const vector<string>& g) {\n    for (const auto& row : g) cout << row << '\\n';\n}\n\n// ---------- random grid ----------\nvector<string> randomGrid() {\n    vector<string> g(N, string(N, '.'));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            g[i][j] = LET[rng() % AL];\n    return g;\n}\n\n// ---------- mutation ----------\n// change one cell\nvoid mutate1(vector<string>& g) {\n    int i = rng() % N;\n    int j = rng() % N;\n    char old = g[i][j];\n    // with 10 % chance try '.' once c==M\n    char nu;\n    if (bestC == M && rng() % 10 == 0) {\n        nu = '.';\n    } else {\n        nu = LET[rng() % AL];\n    }\n    g[i][j] = nu;\n    int c = evaluate(g);\n    if (c > bestC || (c == bestC && rng() % 2)) {\n        bestC = c;\n        bestGrid = g;\n    } else {\n        g[i][j] = old;\n    }\n}\n\n// fix an entire row to a random string that needs it\nvoid mutateRow(vector<string>& g) {\n    int i = rng() % N;\n    string old = g[i];\n    // pick a random unsatisfied string\n    static vector<int> unsat;\n    unsat.clear();\n    for (int idx = 0; idx < M; ++idx) {\n        // quick check: does it fit in row i?\n        bool any = false;\n        const string& s = S[idx];\n        int L = s.size();\n        for (int st = 0; st < N; ++st) {\n            bool ok = true;\n            for (int p = 0; p < L; ++p)\n                if (g[i][(st + p) % N] != s[p]) { ok = false; break; }\n            if (ok) { any = true; break; }\n        }\n        if (!any) unsat.push_back(idx);\n    }\n    if (unsat.empty()) return;\n    int pick = unsat[rng() % unsat.size()];\n    const string& tgt = S[pick];\n    int L = tgt.size();\n    int st = rng() % N;\n    for (int p = 0; p < L; ++p)\n        g[i][(st + p) % N] = tgt[p];\n    int c = evaluate(g);\n    if (c > bestC || (c == bestC && rng() % 2)) {\n        bestC = c;\n        bestGrid = g;\n    } else {\n        g[i] = old;\n    }\n}\n\n// ---------- main ----------\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M;\n    S.resize(M);\n    for (int i = 0; i < M; ++i) cin >> S[i];\n\n    bestGrid = randomGrid();\n    bestC = evaluate(bestGrid);\n\n    // Hill-climb with random walks\n    const double TIME_LIMIT = 2.8;\n    auto start = chrono::steady_clock::now();\n    int iter = 0;\n    while (true) {\n        ++iter;\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > TIME_LIMIT) break;\n\n        // once we reach M, try to fill more\n        if (bestC < M) {\n            if (rng() % 4 == 0) mutateRow(bestGrid);\n            else                  mutate1(bestGrid);\n        } else {\n            // maximize fill\n            mutate1(bestGrid);\n        }\n    }\n\n    // final greedy fill pass\n    if (bestC == M) {\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                if (bestGrid[i][j] == '.') {\n                    for (char c : LET) {\n                        bestGrid[i][j] = c;\n                        if (evaluate(bestGrid) == M) break;\n                    }\n                    if (bestGrid[i][j] == '.') {\n                        // revert\n                        bestGrid[i][j] = '.';\n                    }\n                }\n    }\n\n    printGrid(bestGrid);\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 70;\nconst int INF  = 0x3f3f3f3f;\n\nint N, si, sj;\nchar grid[MAXN][MAXN];\nint  cost[MAXN][MAXN];\nbool isRoad[MAXN][MAXN];\n\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\nchar dirC[] = {'U', 'D', 'L', 'R'};\n\nbitset<MAXN*MAXN> visFrom[MAXN][MAXN];   // what becomes visible\nbitset<MAXN*MAXN> coverage;\nint totalRoads;\n\n/* ---------- visibility precomputation ---------- */\nvoid buildVisibility() {\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (!isRoad[i][j]) continue;\n            auto &bs = visFrom[i][j];\n            // row left\n            for (int jj = j; jj >= 0 && isRoad[i][jj]; --jj) bs.set(i*N + jj);\n            // row right\n            for (int jj = j; jj <  N && isRoad[i][jj]; ++jj) bs.set(i*N + jj);\n            // col up\n            for (int ii = i; ii >= 0 && isRoad[ii][j]; --ii) bs.set(ii*N + j);\n            // col down\n            for (int ii = i; ii <  N && isRoad[ii][j]; ++ii) bs.set(ii*N + j);\n        }\n    }\n}\n\n/* ---------- single Dijkstra ---------- */\nint dist[MAXN][MAXN];\npair<int,int> parent[MAXN][MAXN];\n\nvoid dijkstra(int sr, int sc) {\n    memset(dist, 0x3f, sizeof(dist));\n    using T = tuple<int,int,int>;\n    priority_queue<T, vector<T>, greater<T>> pq;\n    dist[sr][sc] = 0;\n    parent[sr][sc] = {-1,-1};\n    pq.emplace(0, sr, sc);\n    while (!pq.empty()) {\n        auto [d, r, c] = pq.top(); pq.pop();\n        if (d > dist[r][c]) continue;\n        for (int k = 0; k < 4; ++k) {\n            int nr = r + dr[k], nc = c + dc[k];\n            if (nr<0||nr>=N||nc<0||nc>=N || !isRoad[nr][nc]) continue;\n            int nd = d + cost[nr][nc];\n            if (nd < dist[nr][nc]) {\n                dist[nr][nc] = nd;\n                parent[nr][nc] = {r,c};\n                pq.emplace(nd, nr, nc);\n            }\n        }\n    }\n}\n\n/* ---------- path reconstruction ---------- */\nvector<pair<int,int>> reconstruct(int tr, int tc) {\n    vector<pair<int,int>> path;\n    for (int r=tr, c=tc; r!=-1; tie(r,c)=parent[r][c]) path.emplace_back(r,c);\n    reverse(path.begin(), path.end());\n    return path;\n}\nstring toMoves(const vector<pair<int,int>>& path) {\n    string s;\n    for (int i = 1; i < (int)path.size(); ++i) {\n        int dr = path[i].first  - path[i-1].first;\n        int dc = path[i].second - path[i-1].second;\n        if (dr==-1) s+='U'; else if (dr==1) s+='D';\n        else if (dc==-1) s+='L'; else s+='R';\n    }\n    return s;\n}\n\n/* ---------- greedy cover ---------- */\nstring greedyCover() {\n    coverage.reset();\n    int cr = si, cc = sj;\n    string route;\n    coverage |= visFrom[cr][cc];\n\n    while ((int)coverage.count() < totalRoads) {\n        dijkstra(cr, cc);          // single Dijkstra\n        int best_r=-1, best_c=-1, best_gain=0, best_cost=INF;\n        for (int i=0;i<N;++i) {\n            for (int j=0;j<N;++j) {\n                if (!isRoad[i][j] || dist[i][j]==INF) continue;\n                int g = (visFrom[i][j] & ~coverage).count();\n                if (g==0) continue;\n                int c = dist[i][j];\n                if (g>best_gain || (g==best_gain && c<best_cost)) {\n                    best_gain = g; best_cost = c;\n                    best_r = i; best_c = j;\n                }\n            }\n        }\n        if (best_r==-1) break;     // should not happen\n        auto path = reconstruct(best_r, best_c);\n        route += toMoves(path);\n        cr = best_r; cc = best_c;\n        coverage |= visFrom[cr][cc];\n    }\n    // return to start\n    dijkstra(cr, cc);\n    auto pathBack = reconstruct(si, sj);\n    route += toMoves(pathBack);\n    return route;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin>>N>>si>>sj;\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]=='#') isRoad[i][j]=false, cost[i][j]=0;\n            else isRoad[i][j]=true, cost[i][j]=grid[i][j]-'0';\n        }\n    }\n    buildVisibility();\n    totalRoads = 0;\n    for(int i=0;i<N;++i)for(int j=0;j<N;++j)if(isRoad[i][j])++totalRoads;\n\n    string ans = greedyCover();\n    cout<<ans<<'\\n';\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const int INF = 1e9;\nstatic const int MAX_DAY = 2000;\nstatic const int K_MAX   = 20;\n\nint N, M, K, R;\nvector<array<int, K_MAX>> d;\nvector<vector<int>> adj, radj;          // precedence graph\nvector<int> level;                      // longest path from sources\nvector<int> remPred;                    // #unfinished preds\nvector<char> done;\nvector<int> memberTask;                 // current task of member (-1 if idle)\nvector<int> taskMember;                 // member doing task (-1 if none)\nvector<vector<int>> finishedList;       // per member: list of task indices finished\nvector<vector<int>> finishedDur;        // corresponding durations\n\n// belief intervals [L,U] for every member and skill\narray<array<int, K_MAX>, 20> L, U;\n\n// exploration counters: member j , skill bucket b\narray<array<int, 101>, 20> expCount;\n\n// ready tasks\nvector<int> ready;\nchar readyDirty = false;\n\nvoid build_level(){\n    level.assign(N,0);\n    for(int i = 0; i < N; i++){\n        for(int v : adj[i]) level[v] = max(level[v], level[i]+1);\n    }\n}\n\nvoid mark_done(int task){\n    if(done[task]) return;\n    done[task] = 1;\n    for(int v : adj[task]){\n        remPred[v]--;\n        if(remPred[v]==0){\n            ready.push_back(v);\n            readyDirty = true;\n        }\n    }\n}\n\n// quick greedy update of belief intervals after (j,task,dur)\nvoid update_belief(int j, int task, int dur){\n    int low = max(0, dur - 3);\n    int high = dur + 3;\n    // current sum estimate\n    int sumLo = 0, sumHi = 0;\n    for(int k = 0; k < K; k++){\n        int dk = d[task][k];\n        // sjk in [Ljk, Ujk]\n        sumLo += max(0, dk - U[j][k]);\n        sumHi += max(0, dk - L[j][k]);\n    }\n    // we need sumLo <= high and sumHi >= low\n    // tighten only if violated\n    if(sumLo > high){\n        // must increase some U[j][k] -> decrease sumLo\n        int need = sumLo - high;\n        int cnt = 0;\n        for(int k = 0; k < K; k++){\n            int dk = d[task][k];\n            if(dk > L[j][k] && dk < U[j][k]) cnt++;\n        }\n        if(cnt==0) cnt=1;\n        int each = (need + cnt - 1)/cnt;\n        for(int k = 0; k < K; k++){\n            int dk = d[task][k];\n            if(dk > L[j][k] && dk < U[j][k]){\n                U[j][k] = min(U[j][k], dk);\n                need -= each;\n                if(need <= 0) break;\n            }\n        }\n    }\n    if(sumHi < low){\n        // must decrease some L[j][k] -> increase sumHi\n        int need = low - sumHi;\n        int cnt = 0;\n        for(int k = 0; k < K; k++){\n            int dk = d[task][k];\n            if(dk > L[j][k]) cnt++;\n        }\n        if(cnt==0) cnt=1;\n        int each = (need + cnt - 1)/cnt;\n        for(int k = 0; k < K; k++){\n            int dk = d[task][k];\n            if(dk > L[j][k]){\n                L[j][k] = max(L[j][k], dk - each);\n                need -= each;\n                if(need <= 0) break;\n            }\n        }\n    }\n}\n\n// optimistic and pessimistic durations\npair<int,int> est_duration(int task, int j){\n    int optGap = 0, pesGap = 0;\n    for(int k = 0; k < K; k++){\n        int dk = d[task][k];\n        optGap += max(0, dk - U[j][k]);\n        pesGap += max(0, dk - L[j][k]);\n    }\n    int opt = max(1, optGap - 3);\n    int pes = max(1, pesGap + 3);\n    return {opt, pes};\n}\n\n// exploration bonus: bucket = average d over skills\nint bucket(int task){\n    int s = 0;\n    for(int k = 0; k < K; k++) s += d[task][k];\n    return s / K;\n}\n\n// greedy matching: smallest weight\nvector<pair<int,int>> assign(){\n    if(readyDirty){\n        // remove already done tasks\n        vector<int> tmp;\n        for(int t : ready) if(!done[t]) tmp.push_back(t);\n        ready.swap(tmp);\n        readyDirty = false;\n    }\n    vector<int> avail;\n    for(int j = 0; j < M; j++) if(memberTask[j]<0) avail.push_back(j);\n    if(avail.empty() || ready.empty()) return {};\n\n    // build cost matrix\n    int A = avail.size(), T = ready.size();\n    vector<vector<int>> cost(A, vector<int>(T, INF));\n    for(int a = 0; a < A; a++){\n        int j = avail[a];\n        for(int t = 0; t < T; t++){\n            int i = ready[t];\n            auto [opt, pes] = est_duration(i, j);\n            int b = bucket(i);\n            int bonus = expCount[j][b];\n            // weight = 3*opt + 1*pes - 5*bonus + 2*level[i]\n            int w = 3*opt + pes - 5*bonus + 2*level[i];\n            cost[a][t] = w;\n        }\n    }\n    // greedy: smallest cost first\n    vector<tuple<int,int,int>> edges;\n    for(int a = 0; a < A; a++)\n        for(int t = 0; t < T; t++)\n            edges.emplace_back(cost[a][t], a, t);\n    sort(edges.begin(), edges.end());\n    vector<char> usedA(A,0), usedT(T,0);\n    vector<pair<int,int>> ans;\n    for(auto [w,a,t] : edges){\n        if(usedA[a] || usedT[t]) continue;\n        usedA[a] = usedT[t] = 1;\n        int j = avail[a];\n        int i = ready[t];\n        ans.emplace_back(j, i);\n    }\n    return ans;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> K >> R;\n    d.assign(N, array<int, K_MAX>{});\n    for(int i = 0; i < N; i++){\n        for(int k = 0; k < K; k++) cin >> d[i][k];\n    }\n    adj.assign(N, {});\n    radj.assign(N, {});\n    for(int i = 0; i < R; i++){\n        int u,v; cin >> u >> v; u--; v--;\n        adj[u].push_back(v);\n        radj[v].push_back(u);\n    }\n    // initial ready\n    remPred.assign(N,0);\n    for(int i = 0; i < N; i++){\n        remPred[i] = radj[i].size();\n        if(remPred[i]==0) ready.push_back(i);\n    }\n    done.assign(N,0);\n    memberTask.assign(M, -1);\n    taskMember.assign(N, -1);\n    finishedList.assign(M, {});\n    finishedDur.assign(M, {});\n\n    build_level();\n\n    // init belief: L=0, U=large\n    for(int j = 0; j < M; j++){\n        for(int k = 0; k < K; k++){\n            L[j][k] = 0;\n            U[j][k] = 200;\n        }\n    }\n    for(int j = 0; j < M; j++){\n        for(int b = 0; b <= 100; b++) expCount[j][b] = 0;\n    }\n\n    int day = 0;\n    while(day < MAX_DAY){\n        day++;\n        // 1. assign\n        auto match = assign();\n        // build output\n        cout << match.size();\n        for(auto [j,i] : match){\n            cout << ' ' << (j+1) << ' ' << (i+1);\n            // update state\n            memberTask[j] = i;\n            taskMember[i] = j;\n            // exploration count\n            int b = bucket(i);\n            expCount[j][b]++;\n            // remove from ready\n            auto it = find(ready.begin(), ready.end(), i);\n            if(it != ready.end()) ready.erase(it);\n        }\n        cout << '\\n';\n        cout.flush();\n\n        // 2. read finished\n        int nFin; \n        if(!(cin >> nFin)) break;\n        if(nFin == -1) break;\n        vector<int> fins(nFin);\n        for(int i = 0; i < nFin; i++){\n            cin >> fins[i]; fins[i]--;\n        }\n        // process finishes\n        for(int j : fins){\n            int task = memberTask[j];\n            if(task < 0) continue;\n            // read duration (hidden, but tester gives it in local mode)\n            // we simulate by recomputing w and adding noise, but here\n            // we assume the *real* duration is given via stdin in the\n            // same line after fins (local tester does that)\n            int dur; cin >> dur;\n            finishedList[j].push_back(task);\n            finishedDur[j].push_back(dur);\n            update_belief(j, task, dur);\n            mark_done(task);\n            memberTask[j] = -1;\n            taskMember[task] = -1;\n        }\n        // check global finish\n        bool allDone = true;\n        for(int i = 0; i < N; i++) if(!done[i]){ allDone=false; break; }\n        if(allDone) break;\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nstruct Point {\n    int x, y;\n    Point() = default;\n    Point(int x, int y) : x(x), y(y) {}\n};\ninline int man(const Point& a, const Point& b) {\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\nstruct Order {\n    Point p, d;          // pickup, delivery\n    int id;\n};\n\nint N = 1000;\nvector<Order> orders;\nvector<int> bestTourIdx;\nvector<Point> bestTour;\nll bestT = 1e18;\n\n// current working tour\nvector<Point> tour;\nvector<int>   taskId;   // 0..49  -> pickup, 50..99 -> delivery, -1 -> office\nvector<int>   posInTour; // for each task (0..99) its index in tour\n\n// feasibility checker: for every order i, pos[pickup_i] < pos[delivery_i]\nbool feasible() {\n    for (int i = 0; i < 50; ++i) {\n        if (posInTour[i] >= posInTour[i+50]) return false;\n    }\n    return true;\n}\n\nll tourLength() {\n    ll len = 0;\n    for (int i = 0; i + 1 < (int)tour.size(); ++i)\n        len += man(tour[i], tour[i+1]);\n    return len;\n}\n\n// insert task t (0..99) at position ins (0..tour.size())\nvoid insertTask(int t, int ins) {\n    Point pt = (t < 50 ? orders[t].p : orders[t-50].d);\n    tour.insert(tour.begin() + ins, pt);\n    taskId.insert(taskId.begin() + ins, t);\n    // update posInTour\n    for (int i = ins; i < (int)tour.size(); ++i) {\n        int tt = taskId[i];\n        if (tt >= 0) posInTour[tt] = i;\n    }\n}\n\n// remove task t from tour\nvoid removeTask(int t) {\n    int at = posInTour[t];\n    tour.erase(tour.begin() + at);\n    taskId.erase(taskId.begin() + at);\n    // update posInTour\n    for (int i = at; i < (int)tour.size(); ++i) {\n        int tt = taskId[i];\n        if (tt >= 0) posInTour[tt] = i;\n    }\n}\n\n// try to improve by relocating single task\nbool relocateImprove() {\n    bool improved = false;\n    for (int t = 0; t < 100; ++t) {\n        int oldpos = posInTour[t];\n        removeTask(t);\n        int bestpos = -1;\n        ll bestinc = 1e18;\n        // try all possible insert positions\n        for (int ins = 0; ins <= (int)tour.size(); ++ins) {\n            // check feasibility: if t is pickup, must stay before its delivery\n            if (t < 50) {\n                int delpos = posInTour[t+50];\n                if (ins > delpos) continue;\n            } else {\n                int pickpos = posInTour[t-50];\n                if (ins <= pickpos) continue;\n            }\n            // compute delta\n            Point pt = (t < 50 ? orders[t].p : orders[t-50].d);\n            ll delta = 0;\n            if (ins == 0) {\n                delta += man(pt, tour[0]) - man(Point(400,400), tour[0]);\n            } else if (ins == (int)tour.size()) {\n                delta += man(tour.back(), pt) - man(tour.back(), Point(400,400));\n            } else {\n                delta += man(tour[ins-1], pt) + man(pt, tour[ins])\n                       - man(tour[ins-1], tour[ins]);\n            }\n            if (delta < bestinc) {\n                bestinc = delta;\n                bestpos = ins;\n            }\n        }\n        if (bestpos >= 0 && bestinc < -1e-9) {\n            insertTask(t, bestpos);\n            improved = true;\n        } else {\n            // put it back where it was\n            insertTask(t, oldpos);\n        }\n    }\n    return improved;\n}\n\n// 2-opt segment reversal\nbool twoOptImprove() {\n    bool improved = false;\n    int n = tour.size();\n    for (int i = 0; i + 1 < n; ++i) {\n        for (int j = i + 2; j + 1 < n; ++j) {\n            // reverse segment [i+1 .. j]\n            ll old = man(tour[i], tour[i+1]) + man(tour[j], tour[j+1]);\n            ll nw  = man(tour[i], tour[j]) + man(tour[i+1], tour[j+1]);\n            if (nw >= old) continue;\n            // check feasibility after reversal\n            // build pos map quickly\n            vector<int> oldpos = posInTour;\n            // do reversal\n            reverse(tour.begin() + i + 1, tour.begin() + j + 1);\n            reverse(taskId.begin() + i + 1, taskId.begin() + j + 1);\n            // rebuild posInTour\n            for (int k = 0; k < n; ++k) {\n                int t = taskId[k];\n                if (t >= 0) posInTour[t] = k;\n            }\n            if (feasible()) {\n                improved = true;\n                goto out;\n            } else {\n                // rollback\n                reverse(tour.begin() + i + 1, tour.begin() + j + 1);\n                reverse(taskId.begin() + i + 1, taskId.begin() + j + 1);\n                posInTour = oldpos;\n            }\n        }\n    }\nout:\n    return improved;\n}\n\nvoid localSearch() {\n    bool improved;\n    do {\n        improved = false;\n        improved |= relocateImprove();\n        improved |= twoOptImprove();\n    } while (improved);\n}\n\nvoid buildGreedyTour(const vector<int>& sel) {\n    tour.clear();\n    taskId.clear();\n    tour.emplace_back(400, 400);\n    taskId.push_back(-1);\n    // task 0..49 pickup, 50..99 delivery\n    posInTour.assign(100, -1);\n\n    // random order of insertion\n    vector<int> ord = sel;\n    shuffle(ord.begin(), ord.end(), mt19937(random_device{}()));\n\n    for (int idx : ord) {\n        int pick = idx;\n        int del  = idx + 50;\n        Point pp = orders[pick].p;\n        Point pd = orders[del].d;\n        // find best pair of positions\n        ll bestinc = 1e18;\n        int bestpi = -1, bestdi = -1;\n        for (int pi = 0; pi <= (int)tour.size(); ++pi) {\n            for (int di = pi + 1; di <= (int)tour.size() + 1; ++di) {\n                // compute delta\n                ll inc = 0;\n                // insert pickup at pi\n                if (pi == 0) {\n                    inc += man(Point(400,400), pp) + man(pp, tour[0])\n                         - man(Point(400,400), tour[0]);\n                } else if (pi == (int)tour.size()) {\n                    inc += man(tour.back(), pp) + man(pp, Point(400,400))\n                         - man(tour.back(), Point(400,400));\n                } else {\n                    inc += man(tour[pi-1], pp) + man(pp, tour[pi])\n                         - man(tour[pi-1], tour[pi]);\n                }\n                // insert delivery at di (after pi)\n                Point afterpick = (di <= pi ? pp : (di-1 <= pi ? pp : tour[di-1]));\n                if (di == 0) {\n                    inc += man(Point(400,400), pd) + man(pd, tour[0])\n                         - man(Point(400,400), tour[0]);\n                } else if (di == (int)tour.size() + 1) {\n                    inc += man(tour.back(), pd) + man(pd, Point(400,400))\n                         - man(tour.back(), Point(400,400));\n                } else {\n                    int realdi = (di > pi ? di - 1 : di);\n                    inc += man(tour[realdi-1], pd) + man(pd, tour[realdi])\n                         - man(tour[realdi-1], tour[realdi]);\n                }\n                if (inc < bestinc) {\n                    bestinc = inc;\n                    bestpi = pi;\n                    bestdi = di;\n                }\n            }\n        }\n        // do insertion\n        insertTask(pick, bestpi);\n        int realdi = (bestdi > bestpi ? bestdi : bestdi);\n        insertTask(del, realdi);\n    }\n    // close tour\n    tour.emplace_back(400, 400);\n    taskId.push_back(-1);\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    orders.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> orders[i].p.x >> orders[i].p.y\n            >> orders[i].d.x >> orders[i].d.y;\n        orders[i].id = i;\n    }\n\n    auto start = chrono::steady_clock::now();\n    int iter = 0;\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > 1.95) break;\n\n        // random subset\n        vector<int> perm(N);\n        iota(perm.begin(), perm.end(), 0);\n        shuffle(perm.begin(), perm.end(), mt19937(iter++));\n        vector<int> sel(perm.begin(), perm.begin() + 50);\n\n        buildGreedyTour(sel);\n        localSearch();\n        ll curT = tourLength();\n        if (curT < bestT) {\n            bestT = curT;\n            bestTour = tour;\n            bestTourIdx = sel;\n        }\n    }\n\n    // output\n    cout << 50;\n    for (int i = 0; i < 50; ++i) cout << ' ' << bestTourIdx[i] + 1;\n    cout << '\\n';\n    cout << bestTour.size();\n    for (auto &p : bestTour) cout << ' ' << p.x << ' ' << p.y;\n    cout << '\\n';\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct UnionFind {\n    vector<int> parent, rank;\n    \n    UnionFind(int n) : parent(n), rank(n, 0) {\n        for (int i = 0; i < n; i++) {\n            parent[i] = i;\n        }\n    }\n    \n    int find(int x) {\n        if (parent[x] != x) {\n            parent[x] = find(parent[x]);\n        }\n        return parent[x];\n    }\n    \n    bool unite(int x, int y) {\n        int px = find(x), py = find(y);\n        if (px == py) return false;\n        \n        if (rank[px] < rank[py]) {\n            parent[px] = py;\n        } else {\n            parent[py] = px;\n            if (rank[px] == rank[py]) {\n                rank[px]++;\n            }\n        }\n        return true;\n    }\n    \n    bool connected() {\n        int root = find(0);\n        for (int i = 1; i < parent.size(); i++) {\n            if (find(i) != root) return false;\n        }\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 400, M = 1995;\n    \n    // Read coordinates\n    vector<pair<int, int>> coords(N);\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    // Read edges and calculate expected lengths\n    vector<int> u(M), v(M);\n    vector<double> expected(M);\n    \n    for (int i = 0; i < M; i++) {\n        cin >> u[i] >> v[i];\n        \n        // Calculate Euclidean distance\n        double dx = coords[u[i]].first - coords[v[i]].first;\n        double dy = coords[u[i]].second - coords[v[i]].second;\n        double dist = sqrt(dx*dx + dy*dy);\n        int d = round(dist);\n        \n        // Expected length for uniform [d, 3d]\n        expected[i] = 2.0 * d;\n    }\n    \n    UnionFind uf(N);\n    int accepted = 0;\n    \n    // Process each edge\n    for (int i = 0; i < M; i++) {\n        int l;\n        cin >> l;\n        \n        // Calculate threshold based on current state\n        double threshold = expected[i];\n        \n        // Adjust threshold based on connectivity needs\n        if (!uf.connected()) {\n            // Need more edges to ensure connectivity\n            threshold *= 1.2;\n        } else {\n            // Already connected, can be more selective\n            threshold *= 0.9;\n        }\n        \n        // Adjust based on how many edges we've accepted\n        if (accepted < N - 1) {\n            // Still need edges for spanning tree\n            threshold *= 1.1;\n        } else if (accepted > N - 1 + 50) {\n            // Already accepted many edges, be more selective\n            threshold *= 0.85;\n        }\n        \n        bool adopt = false;\n        \n        // Always accept if it connects different components\n        if (uf.find(u[i]) != uf.find(v[i])) {\n            adopt = true;\n        }\n        // Otherwise, accept if it's a good deal\n        else if (l <= threshold) {\n            adopt = true;\n        }\n        \n        if (adopt) {\n            uf.unite(u[i], v[i]);\n            accepted++;\n            cout << \"1\" << endl;\n        } else {\n            cout << \"0\" << endl;\n        }\n        \n        cout.flush();\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 30, W = 30, TURNS = 300;\nconst int dx[4] = {-1, 1, 0, 0}, dy[4] = {0, 0, -1, 1};\nconst char *dir = \"UDLR\", *Dir = \"UDLR\", *block = \"udlr\";\n\nint N, M;\nstruct Pet {\n    int x, y, t;\n} pets[20];\nstruct Human {\n    int x, y;\n} humans[10];\n\nbool wall[H][W]; // wall[x][y] = true if blocked\nint pet_x[20], pet_y[20];\n\n// BFS reachable squares from (sx,sy), return count and pet count\npair<int, int> bfs_reachable(int sx, int sy) {\n    static bool vis[H][W];\n    memset(vis, 0, sizeof(vis));\n    queue<pair<int, int>> q;\n    if (wall[sx][sy]) return {0, 0};\n    vis[sx][sy] = true;\n    q.push({sx, sy});\n    int cnt = 0, pcnt = 0;\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        cnt++;\n        for (int i = 0; i < N; i++) {\n            if (pet_x[i] == x && pet_y[i] == pcnt++) pcnt--;\n            if (pet_x[i] == x && pet_y[i] == y) pcnt++;\n        }\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n            if (wall[nx][ny] || vis[nx][ny]) continue;\n            vis[nx][ny] = true;\n            q.push({nx, ny});\n        }\n    }\n    return {cnt, pcnt};\n}\n\n// Heuristic score for a human at (x,y)\ndouble heuristic(int x, int y) {\n    auto [r, p] = bfs_reachable(x, y);\n    return r - 900.0 * p / 2.0;\n}\n\n// Check if can block (bx,by) from human at (x,y)\nbool can_block(int x, int y, int bx, int by) {\n    if (abs(bx - x) + abs(by - y) != 1) return false;\n    if (wall[bx][by]) return true; // already blocked\n    // Check if any pet or human is on (bx,by) at start\n    for (int i = 0; i < N; i++) {\n        if (pet_x[i] == bx && pet_y[i] == by) return false;\n    }\n    for (int i = 0; i < M; i++) {\n        if (humans[i].x == bx && humans[i].y == by) return false;\n    }\n    // Check if any pet is adjacent to (bx,by)\n    for (int d = 0; d < 4; d++) {\n        int nx = bx + dx[d], ny = by + dy[d];\n        if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n        for (int i = 0; i < N; i++) {\n            if (pet_x[i] == nx && pet_y[i] == ny) return false;\n        }\n    }\n    return true;\n}\n\n// Simulate pet moves (simplified: assume random for 1-3, greedy for 4-5)\nvoid simulate_pets() {\n    // For types 1-3: random basic moves (here we just do random)\n    // For types 4-5: target and move closer\n    // This is a placeholder: in real code, use BFS and rules\n    for (int i = 0; i < N; i++) {\n        int t = pets[i].t;\n        int &x = pet_x[i], &y = pet_y[i];\n        if (t <= 3) {\n            int steps = t;\n            while (steps--) {\n                vector<int> dirs;\n                for (int d = 0; d < 4; d++) {\n                    int nx = x + dx[d], ny = y + dy[d];\n                    if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n                    if (wall[nx][ny]) continue;\n                    dirs.push_back(d);\n                }\n                if (dirs.empty()) break;\n                int d = dirs[rand() % dirs.size()];\n                x += dx[d]; y += dy[d];\n            }\n        } else if (t == 4) {\n            // Dog: target human, move closer\n            // Simplified: pick random human and move one step closer\n            int ti = rand() % M;\n            int hx = humans[ti].x, hy = humans[ti].y;\n            // BFS to find direction\n            // For now, just move randomly\n            vector<int> dirs;\n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n                if (wall[nx][ny]) continue;\n                dirs.push_back(d);\n            }\n            if (!dirs.empty()) {\n                int d = dirs[rand() % dirs.size()];\n                x += dx[d]; y += dy[d];\n            }\n        } else {\n            // Cat: target square, move closer\n            // Simplified: move randomly\n            vector<int> dirs;\n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n                if (wall[nx][ny]) continue;\n                dirs.push_back(d);\n            }\n            if (!dirs.empty()) {\n                int d = dirs[rand() % dirs.size()];\n                x += dx[d]; y += dy[d];\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    for (int i = 0; i < N; i++) {\n        cin >> pets[i].x >> pets[i].y >> pets[i].t;\n        pets[i].x--; pets[i].y--;\n        pet_x[i] = pets[i].x;\n        pet_y[i] = pets[i].y;\n    }\n    cin >> M;\n    for (int i = 0; i < M; i++) {\n        cin >> humans[i].x >> humans[i].y;\n        humans[i].x--; humans[i].y--;\n    }\n\n    memset(wall, 0, sizeof(wall));\n\n    for (int turn = 0; turn < TURNS; turn++) {\n        string act;\n        for (int i = 0; i < M; i++) {\n            int x = humans[i].x, y = humans[i].y;\n            double best = -1e9;\n            char best_act = '.';\n            // Try stay\n            double sc = heuristic(x, y);\n            if (sc > best) { best = sc; best_act = '.'; }\n            // Try move\n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n                if (wall[nx][ny]) continue;\n                humans[i].x = nx; humans[i].y = ny;\n                sc = heuristic(nx, ny);\n                if (sc > best) { best = sc; best_act = Dir[d]; }\n                humans[i].x = x; humans[i].y = y;\n            }\n            // Try block\n            for (int d = 0; d < 4; d++) {\n                int bx = x + dx[d], by = y + dy[d];\n                if (!can_block(x, y, bx, by)) continue;\n                bool old = wall[bx][by];\n                wall[bx][by] = true;\n                sc = heuristic(x, y);\n                if (sc > best) { best = sc; best_act = block[d]; }\n                wall[bx][by] = old;\n            }\n            act += best_act;\n            // Apply best action\n            if (best_act == '.') {\n                // stay\n            } else if (best_act >= 'U' && best_act <= 'R') {\n                int d = best_act - 'U';\n                humans[i].x += dx[d];\n                humans[i].y += dy[d];\n            } else if (best_act >= 'u' && best_act <= 'r') {\n                int d = best_act - 'u';\n                int bx = x + dx[d], by = y + dy[d];\n                wall[bx][by] = true;\n            }\n        }\n        cout << act << endl;\n        cout.flush();\n\n        // Read pet moves\n        for (int i = 0; i < N; i++) {\n            string s;\n            cin >> s;\n            // Apply pet moves\n            int &x = pet_x[i], &y = pet_y[i];\n            for (char c : s) {\n                int d = -1;\n                if (c == 'U') d = 0;\n                else if (c == 'D') d = 1;\n                else if (c == 'L') d = 2;\n                else if (c == 'R') d = 3;\n                else continue;\n                int nx = x + dx[d], ny = y + dy[d];\n                if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n                if (wall[nx][ny]) continue;\n                x = nx; y = ny;\n            }\n        }\n    }\n\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic uint64_t rng_state = 123456789123456789ULL;\ninline uint64_t xorshift64() {\n    uint64_t x = rng_state;\n    x ^= x << 13;\n    x ^= x >> 7;\n    x ^= x << 17;\n    rng_state = x;\n    return x;\n}\ninline int randint(int l, int r) {   // [l, r]\n    return l + (xorshift64() % (r - l + 1));\n}\ninline double rand01() {\n    return (xorshift64() & ((1ULL<<32)-1)) / double(1ULL<<32);\n}\n\nint si, sj, ti, tj;\ndouble pforget;\nbool wallh[20][19]; // wallh[i][j] blocks (i,j)-(i,j+1)\nbool wallv[19][20]; // wallv[i][j] blocks (i,j)-(i+1,j)\nint dist[20][20];\nint best_len;\nstring best_str;\ndouble best_score;\n\nconst int INF = 1000000;\n\nvoid bfs_dist() {\n    for(int i=0;i<20;i++)for(int j=0;j<20;j++) dist[i][j]=INF;\n    deque<pair<int,int>> dq;\n    dist[ti][tj]=0;\n    dq.push_back({ti,tj});\n    static int di[4]={-1,1,0,0}, dj[4]={0,0,-1,1};\n    while(!dq.empty()){\n        auto [i,j]=dq.front(); dq.pop_front();\n        for(int d=0;d<4;d++){\n            int ni=i+di[d], nj=j+dj[d];\n            if(ni<0||nj<0||ni>=20||nj>=20) continue;\n            if(d==0 && wallv[ni][j]) continue; // up\n            if(d==1 && wallv[i][j]) continue;   // down\n            if(d==2 && wallh[i][nj]) continue;  // left\n            if(d==3 && wallh[i][j]) continue;   // right\n            if(dist[ni][nj]>dist[i][j]+1){\n                dist[ni][nj]=dist[i][j]+1;\n                dq.push_back({ni,nj});\n            }\n        }\n    }\n}\n\ninline bool can_move(int i, int j, int d) {\n    if(d==0){ // U\n        if(i==0) return false;\n        return !wallv[i-1][j];\n    } else if(d==1){ // D\n        if(i==19) return false;\n        return !wallv[i][j];\n    } else if(d==2){ // L\n        if(j==0) return false;\n        return !wallh[i][j-1];\n    } else { // R\n        if(j==19) return false;\n        return !wallh[i][j];\n    }\n}\n\ninline int move_i(int i, int d) {\n    if(d==0) return i-1;\n    if(d==1) return i+1;\n    return i;\n}\ninline int move_j(int j, int d) {\n    if(d==2) return j-1;\n    if(d==3) return j+1;\n    return j;\n}\n\ndouble eval(const string &s) {\n    const int L = s.size();\n    static double cur[400], nxt[400];\n    for(int v=0;v<400;v++) cur[v]=0.0;\n    int start = si*20 + sj;\n    cur[start] = 1.0;\n    int goal = ti*20 + tj;\n    double succ = 0.0;\n    double et = 0.0;\n    for(int t=0;t<L;t++){\n        for(int v=0;v<400;v++) nxt[v]=0.0;\n        for(int v=0;v<400;v++){\n            if(cur[v]<1e-14) continue;\n            int i=v/20, j=v%20;\n            if(i==ti&&j==tj) continue; // already absorbed\n            int nopen=0;\n            for(int d=0;d<4;d++) if(can_move(i,j,d)) nopen++;\n            double p_stay = pforget;\n            if(nopen==0){\n                p_stay += (1-pforget);\n            } else {\n                p_stay += (1-pforget)*0; // no extra stay from walls\n            }\n            // forget \u2192 stay\n            nxt[v] += cur[v] * pforget;\n            // try to move\n            if(nopen>0){\n                double p_dir = (1-pforget) / nopen;\n                for(int d=0;d<4;d++){\n                    if(!can_move(i,j,d)) continue;\n                    int ni=move_i(i,d), nj=move_j(j,d);\n                    int u=ni*20+nj;\n                    if(ni==ti&&nj==tj){\n                        // absorbed at t+1\n                        double prob = cur[v] * p_dir;\n                        succ += prob;\n                        et += prob * (t+1);\n                    } else {\n                        nxt[u] += cur[v] * p_dir;\n                    }\n                }\n            } else {\n                // all directions blocked \u2192 forced stay\n                nxt[v] += cur[v] * (1-pforget);\n            }\n        }\n        swap(cur, nxt);\n    }\n    double left=0.0;\n    for(int v=0;v<400;v++) left+=cur[v];\n    succ = 1.0 - left;\n    // et already contains sum t*prob(t)\n    if(succ<1e-14) return 0.0;\n    double mean_t = et / succ;\n    double es = succ * (401.0 - mean_t);\n    return es;\n}\n\nstring greedy_random_walk(int want_len) {\n    string path;\n    int i=si, j=sj;\n    static int dirs[4]={0,1,2,3};\n    while((int)path.size() < want_len) {\n        if(i==ti && j==tj) break;\n        // shuffle directions\n        for(int k=0;k<4;k++){\n            int r=randint(k,3);\n            swap(dirs[k],dirs[r]);\n        }\n        double best_val=-1e9;\n        int best_d=-1;\n        for(int k=0;k<4;k++){\n            int d=dirs[k];\n            if(!can_move(i,j,d)) continue;\n            int ni=move_i(i,d), nj=move_j(j,d);\n            double val = -(dist[ni][nj]) + rand01()*0.3;\n            if(val>best_val){\n                best_val=val;\n                best_d=d;\n            }\n        }\n        if(best_d>=0){\n            path += \"UDLR\"[best_d];\n            i=move_i(i,best_d);\n            j=move_j(j,best_d);\n        } else {\n            // trapped \u2192 stay, any char\n            path += 'U';\n        }\n    }\n    // if we reached goal early, pad with something safe\n    while((int)path.size() < want_len){\n        if(i==ti&&j==tj){\n            path+='R'; // safe arbitrary\n        } else {\n            // greedy again\n            int dbest=-1, dbestv=INF;\n            for(int d=0;d<4;d++){\n                if(!can_move(i,j,d)) continue;\n                int ni=move_i(i,d), nj=move_j(j,d);\n                if(dist[ni][nj]<dbestv){\n                    dbestv=dist[ni][nj];\n                    dbest=d;\n                }\n            }\n            if(dbest>=0){\n                path+=\"UDLR\"[dbest];\n                i=move_i(i,dbest);\n                j=move_j(j,dbest);\n            } else {\n                path+='U';\n            }\n        }\n    }\n    return path;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin>>si>>sj>>ti>>tj>>pforget;\n    for(int i=0;i<20;i++){\n        string row; cin>>row;\n        for(int j=0;j<19;j++) wallh[i][j]=(row[j]=='1');\n    }\n    for(int i=0;i<19;i++){\n        string row; cin>>row;\n        for(int j=0;j<20;j++) wallv[i][j]=(row[j]=='1');\n    }\n\n    bfs_dist();\n\n    best_score=-1e9;\n    best_len=-1;\n\n    // spend ~1.8 seconds iterating\n    const auto start_time = chrono::steady_clock::now();\n    int attempt=0;\n    while(1){\n        attempt++;\n        auto now=chrono::steady_clock::now();\n        double elapsed=chrono::duration<double>(now-start_time).count();\n        if(elapsed>1.85) break;\n\n        int want_len = randint(60,180);\n        string cand = greedy_random_walk(want_len);\n        double sc = eval(cand);\n        if(sc>best_score){\n            best_score=sc;\n            best_str=cand;\n            best_len=want_len;\n        }\n    }\n\n    cout<<best_str<<\"\\n\";\n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <random>\n#include <algorithm>\n#include <chrono>\n#include <set>\n\nusing namespace std;\n\nconst int SIZE = 30;\nconst int DIR[4][2] = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};\n\nconst int to[8][4] = {\n    {1, 0, -1, -1},  // type 0\n    {3, -1, -1, 0},  // type 1\n    {-1, -1, 3, 2},  // type 2\n    {-1, 2, 1, -1},  // type 3\n    {1, 0, 3, 2},    // type 4\n    {3, 2, 1, 0},    // type 5\n    {2, -1, 0, -1},  // type 6\n    {-1, 3, -1, 1}   // type 7\n};\n\nint grid[SIZE][SIZE];\nint rotation[SIZE][SIZE];\nint best_rotation[SIZE][SIZE];\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\ninline int get_tile_type(int i, int j) {\n    int base_type = grid[i][j];\n    int rot = rotation[i][j];\n    if (base_type <= 3) {\n        return (base_type + rot) % 4;\n    } else if (base_type <= 5) {\n        return 4 + (base_type - 4 + rot) % 2;\n    } else {\n        return 6 + (base_type - 6 + rot) % 2;\n    }\n}\n\nint trace_loop(int si, int sj, int sd) {\n    int i = si, j = sj, d = sd;\n    int length = 0;\n    \n    for (int step = 0; step < 1000; step++) {\n        int tile_type = get_tile_type(i, j);\n        int d2 = to[tile_type][d];\n        if (d2 == -1) return 0;\n        \n        i += DIR[d2][0];\n        j += DIR[d2][1];\n        if (i < 0 || i >= SIZE || j < 0 || j >= SIZE) return 0;\n        \n        d = (d2 + 2) % 4;\n        length++;\n        \n        if (i == si && j == sj && d == sd) return length;\n    }\n    return 0;\n}\n\npair<int, int> find_top_loops() {\n    vector<int> loop_lengths;\n    \n    // Sample key positions instead of checking all\n    for (int i = 1; i < SIZE-1; i += 3) {\n        for (int j = 1; j < SIZE-1; j += 3) {\n            for (int d = 0; d < 4; d++) {\n                int len = trace_loop(i, j, d);\n                if (len > 4) { // Only consider substantial loops\n                    loop_lengths.push_back(len);\n                }\n            }\n        }\n    }\n    \n    sort(loop_lengths.rbegin(), loop_lengths.rend());\n    if (loop_lengths.size() < 2) return {0, 0};\n    return {loop_lengths[0], loop_lengths[1]};\n}\n\nint calculate_score_fast() {\n    auto [l1, l2] = find_top_loops();\n    return l1 * l2;\n}\n\nvoid greedy_optimize() {\n    // Initialize with smart starting configuration\n    for (int i = 0; i < SIZE; i++) {\n        for (int j = 0; j < SIZE; j++) {\n            // Start with original configuration\n            rotation[i][j] = 0;\n            best_rotation[i][j] = 0;\n        }\n    }\n    \n    int best_score = calculate_score_fast();\n    int current_score = best_score;\n    \n    // Greedy local search with random sampling\n    const int max_iterations = 2000;\n    \n    for (int iter = 0; iter < max_iterations; iter++) {\n        bool improved = false;\n        \n        // Try random tiles\n        for (int k = 0; k < 50; k++) {\n            int i = rng() % SIZE;\n            int j = rng() % SIZE;\n            int old_rot = rotation[i][j];\n            \n            // Try all possible rotations\n            int best_local_rot = old_rot;\n            int best_local_score = current_score;\n            \n            for (int r = 1; r < 4; r++) {\n                rotation[i][j] = (old_rot + r) % 4;\n                int new_score = calculate_score_fast();\n                if (new_score > best_local_score) {\n                    best_local_score = new_score;\n                    best_local_rot = (old_rot + r) % 4;\n                }\n            }\n            \n            if (best_local_rot != old_rot) {\n                rotation[i][j] = best_local_rot;\n                current_score = best_local_score;\n                improved = true;\n                \n                if (current_score > best_score) {\n                    best_score = current_score;\n                    for (int x = 0; x < SIZE; x++) {\n                        for (int y = 0; y < SIZE; y++) {\n                            best_rotation[x][y] = rotation[x][y];\n                        }\n                    }\n                }\n            } else {\n                rotation[i][j] = old_rot; // Revert\n            }\n        }\n        \n        if (!improved && iter > max_iterations / 2) break;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    for (int i = 0; i < SIZE; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < SIZE; j++) {\n            grid[i][j] = line[j] - '0';\n        }\n    }\n    \n    // Run fast greedy optimization\n    greedy_optimize();\n    \n    // Output best solution\n    for (int i = 0; i < SIZE; i++) {\n        for (int j = 0; j < SIZE; j++) {\n            cout << best_rotation[i][j];\n        }\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc011":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <unordered_set>\n#include <chrono>\n\nusing namespace std;\n\nconst int dx[4] = {-1, 0, 1, 0};\nconst int dy[4] = {0, 1, 0, -1};\nconst char dir_char[4] = {'U', 'R', 'D', 'L'};\n\nint N, T;\nvector<vector<int>> board;\nint empty_row, empty_col;\nstring solution;\n\nbool has_line(int tile, int direction) {\n    return (tile >> direction) & 1;\n}\n\nbool can_connect(int tile1, int tile2, int direction) {\n    // direction: 0=up, 1=right, 2=down, 3=left\n    int opposite = (direction + 2) % 4;\n    return has_line(tile1, direction) && has_line(tile2, opposite);\n}\n\nint count_connections() {\n    int connections = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0) continue;\n            \n            // Check down connection\n            if (i < N-1 && board[i+1][j] != 0) {\n                if (can_connect(board[i][j], board[i+1][j], 2)) {\n                    connections++;\n                }\n            }\n            \n            // Check right connection\n            if (j < N-1 && board[i][j+1] != 0) {\n                if (can_connect(board[i][j], board[i][j+1], 1)) {\n                    connections++;\n                }\n            }\n        }\n    }\n    return connections;\n}\n\nint find_largest_tree() {\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    int max_size = 0;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0 || visited[i][j]) continue;\n            \n            queue<pair<int, int>> q;\n            q.push({i, j});\n            visited[i][j] = true;\n            int size = 0;\n            \n            while (!q.empty()) {\n                auto [r, c] = q.front();\n                q.pop();\n                size++;\n                \n                // Check all 4 directions\n                for (int d = 0; d < 4; d++) {\n                    int nr = r + dx[d];\n                    int nc = c + dy[d];\n                    \n                    if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n                    if (board[nr][nc] == 0 || visited[nr][nc]) continue;\n                    if (!can_connect(board[r][c], board[nr][nc], d)) continue;\n                    \n                    visited[nr][nc] = true;\n                    q.push({nr, nc});\n                }\n            }\n            \n            max_size = max(max_size, size);\n        }\n    }\n    \n    return max_size;\n}\n\nbool is_valid_move(int r, int c) {\n    return r >= 0 && r < N && c >= 0 && c < N && board[r][c] != 0;\n}\n\nvoid make_move(int direction) {\n    int nr = empty_row + dx[direction];\n    int nc = empty_col + dy[direction];\n    \n    if (!is_valid_move(nr, nc)) return;\n    \n    swap(board[empty_row][empty_col], board[nr][nc]);\n    empty_row = nr;\n    empty_col = nc;\n    solution += dir_char[direction];\n}\n\nvoid solve_greedy() {\n    auto start_time = chrono::high_resolution_clock::now();\n    int best_tree = find_largest_tree();\n    \n    while (solution.size() < T) {\n        int best_improvement = 0;\n        int best_direction = -1;\n        \n        for (int d = 0; d < 4; d++) {\n            int nr = empty_row + dx[d];\n            int nc = empty_col + dy[d];\n            \n            if (!is_valid_move(nr, nc)) continue;\n            \n            // Try the move\n            swap(board[empty_row][empty_col], board[nr][nc]);\n            int new_tree = find_largest_tree();\n            int improvement = new_tree - best_tree;\n            \n            // Undo the move\n            swap(board[empty_row][empty_col], board[nr][nc]);\n            \n            if (improvement > best_improvement) {\n                best_improvement = improvement;\n                best_direction = d;\n            }\n        }\n        \n        if (best_direction == -1) {\n            // No improving move, try random\n            best_direction = rand() % 4;\n        }\n        \n        make_move(best_direction);\n        best_tree = find_largest_tree();\n        \n        // Check time limit\n        auto current_time = chrono::high_resolution_clock::now();\n        auto elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count();\n        if (elapsed > 2800) break; // Leave some margin\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> T;\n    board.assign(N, vector<int>(N));\n    \n    for (int i = 0; i < N; i++) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < N; j++) {\n            char c = row[j];\n            if (c == '0') {\n                board[i][j] = 0;\n                empty_row = i;\n                empty_col = j;\n            } else if (c >= '1' && c <= '9') {\n                board[i][j] = c - '0';\n            } else {\n                board[i][j] = c - 'a' + 10;\n            }\n        }\n    }\n    \n    solve_greedy();\n    \n    cout << solution << endl;\n    \n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\nusing int64 = long long;\nusing f64 = long double;\n\n/* ---------- geometry primitives ---------- */\nconst f64 EPS = 1e-9L;\ninline int sign(f64 x) { return (x > EPS) - (x < -EPS); }\n\nstruct Line {\n    f64 A, B, C;          // A x + B y + C = 0,  A\u00b2+B\u00b2=1\n    Line() = default;\n    Line(f64 a, f64 b, f64 c) : A(a), B(b), C(c) { norm(); }\n    // through (x1,y1)->(x2,y2)\n    Line(f64 x1, f64 y1, f64 x2, f64 y2) {\n        A = y2 - y1;\n        B = x1 - x2;\n        C = x2*y1 - x1*y2;\n        norm();\n    }\n    void norm() {\n        f64 s = sqrtl(A*A + B*B);\n        if (s > EPS) { A /= s; B /= s; C /= s; }\n    }\n    int side(f64 x, f64 y) const {\n        f64 v = A*x + B*y + C;\n        return sign(v);\n    }\n};\n\n/* ---------- global input ---------- */\nint N, K;\nvector<int> a(11);            // 1..10\nvector<f64> X, Y;\n\n/* ---------- current state ---------- */\nint kUsed = 0;                // lines used so far\nvector<Line> lines;\nusing Bits = bitset<100>;\nvector<Bits> regionCode;      // regionCode[r] = sign vector\nvector<int> regionCount;      // regionCount[r] = #strawberries inside\nunordered_map<uint64_t, int> regMap; // hash of sign vector -> index\n\nint have[11] = {};            // have[d] = #regions with d strawberries\nint objective = 0;\n\n/* ---------- evaluation ---------- */\nint eval() {\n    int obj = 0;\n    for (int d = 1; d <= 10; ++d) obj += min(a[d], have[d]);\n    return obj;\n}\n\n/* ---------- incremental add line ---------- */\nvoid addLine(const Line &L) {\n    if (kUsed == K) return;\n    int id = kUsed++;\n    lines[id] = L;\n\n    // re-index regions\n    unordered_map<uint64_t, int> newMap;\n    vector<Bits> newCode;\n    vector<int> newCount;\n    int newR = 0;\n\n    // helper: hash of bitset\n    auto hashBits = [&](const Bits &b) -> uint64_t {\n        return b._Get_hash(); // libstdc++ extension, fast\n    };\n\n    // split every existing region\n    for (int r = 0; r < (int)regionCode.size(); ++r) {\n        int cnt = regionCount[r];\n        if (cnt == 0) continue;\n\n        Bits oldSig = regionCode[r];\n        // count strawberries on each side\n        int cntP = 0, cntM = 0, cnt0 = 0;\n        // we need to know which strawberries belong to region r\n        // but we don't store per-region lists -> re-scan all points\n        // This is O(N) per region, but total regions <= 5051 and N<=1000 -> acceptable\n        Bits sigP = oldSig, sigM = oldSig;\n        sigP.set(id);        // +1 side\n        sigM.reset(id);      // -1 side\n\n        for (int i = 0; i < N; ++i) {\n            int s = L.side(X[i], Y[i]);\n            if (s == 0) { cnt0++; continue; }\n            if (s > 0) cntP++; else cntM++;\n        }\n        // two children\n        if (cntP > 0) {\n            uint64_t h = hashBits(sigP);\n            auto it = newMap.find(h);\n            if (it == newMap.end()) {\n                newMap[h] = newR;\n                newCode.push_back(sigP);\n                newCount.push_back(cntP);\n                ++newR;\n            } else {\n                newCount[it->second] += cntP;\n            }\n        }\n        if (cntM > 0) {\n            uint64_t h = hashBits(sigM);\n            auto it = newMap.find(h);\n            if (it == newMap.end()) {\n                newMap[h] = newR;\n                newCode.push_back(sigM);\n                newCount.push_back(cntM);\n                ++newR;\n            } else {\n                newCount[it->second] += cntM;\n            }\n        }\n        // strawberries on the line (cnt0) are lost\n    }\n\n    // rebuild global arrays\n    regMap.swap(newMap);\n    regionCode.swap(newCode);\n    regionCount.swap(newCount);\n\n    // rebuild have[] and objective\n    fill(have, have+11, 0);\n    for (int c : regionCount) if (c <= 10) have[c]++;\n    objective = eval();\n}\n\n/* ---------- greedy candidate generation ---------- */\nLine bestGreedyLine() {\n    static mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> distN(0, N-1);\n    uniform_int_distribution<int> distC(-100000, 100000);\n    uniform_real_distribution<f64> distA(0, M_PIl);\n\n    int bestGain = 0;\n    Line bestL;\n\n    auto tryLine = [&](const Line &L) {\n        // simulate addLine without really modifying state\n        unordered_map<uint64_t, int> tmpMap;\n        vector<int> tmpCount;\n        vector<Bits> tmpCode;\n        int tmpHave[11] = {};\n        int tmpObj = 0;\n\n        // copy current state\n        for (int r = 0; r < (int)regionCode.size(); ++r) {\n            int cnt = regionCount[r];\n            if (cnt == 0) continue;\n            int cntP = 0, cntM = 0;\n            Bits sigP = regionCode[r], sigM = regionCode[r];\n            sigP.set(kUsed);\n            sigM.reset(kUsed);\n            for (int i = 0; i < N; ++i) {\n                int s = L.side(X[i], Y[i]);\n                if (s == 0) continue;\n                if (s > 0) cntP++; else cntM++;\n            }\n            if (cntP > 0) {\n                tmpCount.push_back(cntP);\n                tmpCode.push_back(sigP);\n            }\n            if (cntM > 0) {\n                tmpCount.push_back(cntM);\n                tmpCode.push_back(sigM);\n            }\n        }\n        for (int c : tmpCount) if (c <= 10) tmpHave[c]++;\n        for (int d = 1; d <= 10; ++d) tmpObj += min(a[d], tmpHave[d]);\n        int gain = tmpObj - objective;\n        if (gain > bestGain) {\n            bestGain = gain;\n            bestL = L;\n        }\n    };\n\n    // try random point-pairs\n    const int TRIES = 400;\n    for (int t = 0; t < TRIES; ++t) {\n        int i = distN(rng), j = distN(rng);\n        if (i == j) continue;\n        Line L(X[i], Y[i], X[j], Y[j]);\n        tryLine(L);\n    }\n    // try random directions through random points\n    for (int t = 0; t < TRIES; ++t) {\n        int i = distN(rng);\n        f64 ang = distA(rng);\n        f64 dx = cosl(ang), dy = sinl(ang);\n        Line L(X[i], Y[i], X[i] + dx, Y[i] + dy);\n        tryLine(L);\n    }\n    // try a few axis-aligned\n    for (int t = 0; t < 20; ++t) {\n        f64 x = distC(rng) * 1000;\n        Line L(1, 0, -x);\n        tryLine(L);\n        Line L2(0, 1, -x);\n        tryLine(L2);\n    }\n    return bestL;\n}\n\n/* ---------- main ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    auto clk_start = chrono::steady_clock::now();\n\n    cin >> N >> K;\n    for (int d = 1; d <= 10; ++d) cin >> a[d];\n    X.resize(N); Y.resize(N);\n    for (int i = 0; i < N; ++i) cin >> X[i] >> Y[i];\n\n    // initial state: 1 region\n    lines.assign(K, Line());\n    regionCode.clear();\n    regionCount.clear();\n    regMap.clear();\n    Bits initialSig;\n    initialSig.reset();\n    regionCode.push_back(initialSig);\n    regionCount.push_back(N);\n    regMap[initialSig._Get_hash()] = 0;\n    fill(have, have+11, 0);\n    have[min(N, 10)] = 1;\n    objective = eval();\n\n    // iterated greedy + local search\n    int bestEver = objective;\n    vector<Line> bestLines;\n    int bestK = 0;\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - clk_start).count();\n        if (elapsed > 2.85) break;\n\n        // greedy addition pass\n        while (kUsed < K) {\n            Line L = bestGreedyLine();\n            if (objective >= bestEver) {\n                bestEver = objective;\n                bestLines = vector<Line>(lines.begin(), lines.begin() + kUsed);\n                bestK = kUsed;\n            }\n            addLine(L);\n        }\n\n        // local perturbation: delete last 5 and re-add greedily\n        if (kUsed >= 5) {\n            for (int del = 0; del < 5; ++del) {\n                // remove last line\n                kUsed--;\n                // rebuild entire state from scratch (simplest)\n                regionCode.clear();\n                regionCount.clear();\n                regMap.clear();\n                Bits init;\n                init.reset();\n                regionCode.push_back(init);\n                regionCount.push_back(0);\n                regMap[init._Get_hash()] = 0;\n                // recount\n                fill(have, have+11, 0);\n                for (int i = 0; i < N; ++i) {\n                    Bits sig;\n                    sig.reset();\n                    for (int j = 0; j < kUsed; ++j) {\n                        int s = lines[j].side(X[i], Y[i]);\n                        if (s > 0) sig.set(j);\n                    }\n                    uint64_t h = sig._Get_hash();\n                    auto it = regMap.find(h);\n                    int r;\n                    if (it == regMap.end()) {\n                        r = regionCode.size();\n                        regMap[h] = r;\n                        regionCode.push_back(sig);\n                        regionCount.push_back(0);\n                    } else {\n                        r = it->second;\n                    }\n                    regionCount[r]++;\n                }\n                fill(have, have+11, 0);\n                for (int c : regionCount) if (c <= 10) have[c]++;\n                objective = eval();\n            }\n        }\n    }\n\n    // output best\n    cout << bestK << '\\n';\n    cout << fixed << setprecision(0);\n    for (int i = 0; i < bestK; ++i) {\n        // pick two integer points on the line\n        f64 A = bestLines[i].A, B = bestLines[i].B, C = bestLines[i].C;\n        // choose x1,y1,x2,y2 integers\n        int64_t x1, y1, x2, y2;\n        if (fabs(B) > EPS) {\n            x1 = 0;\n            y1 = llround(-C / B);\n            x2 = 1;\n            y2 = llround((-C - A) / B);\n        } else {\n            y1 = 0;\n            x1 = llround(-C / A);\n            y2 = 1;\n            x2 = llround((-C) / A);\n        }\n        cout << x1 << ' ' << y1 << ' ' << x2 << ' ' << y2 << '\\n';\n    }\n    return 0;\n}","ahc014":"#pragma GCC target(\"avx2\")\n#pragma GCC optimize(\"O3\")\n#pragma GCC optimize(\"unroll-loops\")\n#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing ll = long long;\n#define rep(i, n) for (int i = 0; i < (int)(n); i++)\n\n// ---------- \u8fba\u306e\u7b26\u53f7\u5316 ----------\ninline uint64_t ecode(int x1, int y1, int x2, int y2) {\n    if (x1 > x2 || (x1 == x2 && y1 > y2)) {\n        swap(x1, x2); swap(y1, y2);\n    }\n    return ((uint64_t)(uint16_t)x1 << 48) | ((uint64_t)(uint16_t)y1 << 32) |\n           ((uint64_t)(uint16_t)x2 << 16) | (uint64_t)(uint16_t)y2;\n}\n\n// ---------- \u30b0\u30ed\u30fc\u30d0\u30eb ----------\nint N, M;\nint c;\nvector<vector<int>> w;               // \u91cd\u307f\nvector<vector<bool>> dot;            // dot[x][y]\nstd::unordered_set<uint64_t> used_edge;   // \u4fee\u6b63\uff1astd \u3092\u4f7f\u3046\nvector<tuple<int,int,int,int,int,int,int,int>> ops;  // \u64cd\u4f5c\u5c65\u6b74\n\n// ---------- \u65b9\u5411 ----------\nconst int dx45[4] = {1, 1, -1, -1};\nconst int dy45[4] = {1, -1, -1, 1};\nconst int dxax[4] = {1, 0, -1, 0};\nconst int dyax[4] = {0, 1, 0, -1};\n\n// ---------- \u77e9\u5f62\u3092\u8a66\u3059 ----------\nbool try_rect(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    // 4\u9802\u70b9\u306e\u9806\u5e8f\u3092\u6b63\u3057\u304f\u56de\u3057\u3001p1=(x1,y1) \u304c\u7a7a\u3001\u4ed6\u304c dot \u3067\u3042\u308b\u3053\u3068\n    if (!dot[x2][y2] || !dot[x3][y3] || !dot[x4][y4]) return false;\n    if (dot[x1][y1]) return false;\n    // 4\u8fba\u306e\u7b26\u53f7\u5316\n    uint64_t e1 = ecode(x1,y1,x2,y2);\n    uint64_t e2 = ecode(x2,y2,x3,y3);\n    uint64_t e3 = ecode(x3,y3,x4,y4);\n    uint64_t e4 = ecode(x4,y4,x1,y1);\n    if (used_edge.count(e1) || used_edge.count(e2) ||\n        used_edge.count(e3) || used_edge.count(e4)) return false;\n    // \u8fba\u4e0a\u306b\u4ed6\u30c9\u30c3\u30c8\u304c\u306a\u3044\u304b\uff08\u7c21\u6613\uff1agcd \u3067\u7b49\u5206\u70b9\u30c1\u30a7\u30c3\u30af\uff09\n    auto check_edge = [&](int ax, int ay, int bx, int by) {\n        int dx = bx - ax, dy = by - ay;\n        int g = gcd(abs(dx), abs(dy));\n        int stepx = dx / g, stepy = dy / g;\n        for (int t = 1; t < g; t++) {\n            int xx = ax + t * stepx, yy = ay + t * stepy;\n            if (dot[xx][yy]) return false;\n        }\n        return true;\n    };\n    if (!check_edge(x1,y1,x2,y2)) return false;\n    if (!check_edge(x2,y2,x3,y3)) return false;\n    if (!check_edge(x3,y3,x4,y4)) return false;\n    if (!check_edge(x4,y4,x1,y1)) return false;\n    // \u5b9f\u884c\n    dot[x1][y1] = true;\n    used_edge.insert(e1);\n    used_edge.insert(e2);\n    used_edge.insert(e3);\n    used_edge.insert(e4);\n    ops.emplace_back(x1,y1,x2,y2,x3,y3,x4,y4);\n    return true;\n}\n\n// ---------- \u30e1\u30a4\u30f3 ----------\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    auto clk_st = chrono::steady_clock::now();\n\n    cin >> N >> M;\n    c = (N - 1) / 2;\n    w.assign(N, vector<int>(N));\n    dot.assign(N, vector<bool>(N, false));\n    ll S = 0;\n    rep(x,N) rep(y,N) {\n        int wx = (x - c) * (x - c) + (y - c) * (y - c) + 1;\n        w[x][y] = wx;\n        S += wx;\n    }\n    rep(i,M){\n        int x,y; cin >> x >> y;\n        dot[x][y] = true;\n    }\n\n    // \u9ad8\u91cd\u307f\u9806\u306b\u7a7a\u30de\u30b9\u3092\u62fe\u3046\u305f\u3081\u306e\u30ea\u30b9\u30c8\n    vector<pair<int,int>> cells;\n    rep(x,N) rep(y,N) if (!dot[x][y]) cells.emplace_back(x,y);\n    // \u91cd\u307f\u5927\u304d\u3044\u9806\u306b\u30bd\u30fc\u30c8\n    sort(cells.begin(), cells.end(), [&](auto &a, auto &b){\n        return w[a.first][a.second] > w[b.first][b.second];\n    });\n\n    // \u8caa\u6b32\u30e1\u30a4\u30f3\n    const double TIME_LIMIT = 4.8;\n    int iter = 0, total = cells.size();\n    while (1) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - clk_st).count();\n        if (elapsed > TIME_LIMIT) break;\n\n        // \u30e9\u30f3\u30c0\u30e0\u306b\u30d0\u30c3\u30c1\u3092\u62fe\u3046\uff08\u91cd\u3044\u9806\u306b\u3057\u3064\u3064\u30e9\u30f3\u30c0\u30e0\u30cd\u30b9\uff09\n        int batch = min(500, total);\n        vector<int> idx(batch);\n        rep(i,batch) idx[i] = (iter + i) % total;\n        shuffle(idx.begin(), idx.end(), mt19937(iter));\n\n        bool progress = false;\n        for (int i : idx) {\n            auto [x1,y1] = cells[i];\n            if (dot[x1][y1]) continue;\n            // \u8ef8\u5e73\u884c\u9577\u65b9\u5f62\u30924\u65b9\u5411\n            for (int d = 0; d < 4; d++) {\n                int len = 1;\n                while (1) {\n                    int x2 = x1 + len * dxax[d], y2 = y1 + len * dyax[d];\n                    int x3 = x2 + len * dxax[(d+1)&3], y3 = y2 + len * dyax[(d+1)&3];\n                    int x4 = x1 + len * dxax[(d+1)&3], y4 = y1 + len * dyax[(d+1)&3];\n                    if (x2<0||x2>=N||y2<0||y2>=N) break;\n                    if (x3<0||x3>=N||y3<0||y3>=N) break;\n                    if (x4<0||x4>=N||y4<0||y4>=N) break;\n                    if (try_rect(x1,y1,x2,y2,x3,y3,x4,y4)) { progress=true; goto NEXT; }\n                    len++;\n                }\n            }\n            // 45\u00b0\u9577\u65b9\u5f62\u30924\u65b9\u5411\n            for (int d = 0; d < 4; d++) {\n                int len = 1;\n                while (1) {\n                    int x2 = x1 + len * dx45[d], y2 = y1 + len * dy45[d];\n                    int x3 = x2 + len * dx45[(d+1)&3], y3 = y2 + len * dy45[(d+1)&3];\n                    int x4 = x1 + len * dx45[(d+1)&3], y4 = y1 + len * dy45[(d+1)&3];\n                    if (x2<0||x2>=N||y2<0||y2>=N) break;\n                    if (x3<0||x3>=N||y3<0||y3>=N) break;\n                    if (x4<0||x4>=N||y4<0||y4>=N) break;\n                    if (try_rect(x1,y1,x2,y2,x3,y3,x4,y4)) { progress=true; goto NEXT; }\n                    len++;\n                }\n            }\n        }\n        NEXT:\n        iter += batch;\n        if (!progress) break;\n    }\n\n    // \u51fa\u529b\n    cout << ops.size() << \"\\n\";\n    for (auto &[x1,y1,x2,y2,x3,y3,x4,y4] : ops) {\n        cout << x1 << \" \" << y1 << \" \"\n             << x2 << \" \" << y2 << \" \"\n             << x3 << \" \" << y3 << \" \"\n             << x4 << \" \" << y4 << \"\\n\";\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\nusing namespace std::chrono;\n\nstatic const int H = 10, W = 10, C = 3;\nint flavor[100];               // 0-indexed\nchar dirchar[4] = {'F','B','L','R'};\n\nmt19937 rng((uint64_t)(new char));\n\nint grid[H][W];\nint tmp [H][W];\n\nvoid gravity(int g[H][W], int d){\n    // d: 0=F(up),1=B(down),2=L(left),3=right\n    if(d==0){ // forward = up\n        for(int c=0;c<W;c++){\n            int write = 0;\n            for(int r=0;r<H;r++){\n                if(g[r][c]){\n                    if(write!=r) g[write][c] = g[r][c];\n                    write++;\n                }\n            }\n            for(int r=write;r<H;r++) g[r][c]=0;\n        }\n    }\n    else if(d==1){ // backward = down\n        for(int c=0;c<W;c++){\n            int write = H-1;\n            for(int r=H-1;r>=0;r--){\n                if(g[r][c]){\n                    if(write!=r) g[write][c] = g[r][c];\n                    write--;\n                }\n            }\n            for(int r=write;r>=0;r--) g[r][c]=0;\n        }\n    }\n    else if(d==2){ // left\n        for(int r=0;r<H;r++){\n            int write = 0;\n            for(int c=0;c<W;c++){\n                if(g[r][c]){\n                    if(write!=c) g[r][write] = g[r][c];\n                    write++;\n                }\n            }\n            for(int c=write;c<W;c++) g[r][c]=0;\n        }\n    }\n    else { // right\n        for(int r=0;r<H;r++){\n            int write = W-1;\n            for(int c=W-1;c>=0;c--){\n                if(g[r][c]){\n                    if(write!=c) g[r][write] = g[r][c];\n                    write--;\n                }\n            }\n            for(int c=write;c>=0;c--) g[r][c]=0;\n        }\n    }\n}\n\nint eval_once(int g[H][W]){\n    // return sum of squares of component sizes\n    static bool vis[H][W];\n    memset(vis,0,sizeof(vis));\n    int sum = 0;\n    for(int i=0;i<H;i++){\n        for(int j=0;j<W;j++){\n            if(!vis[i][j] && g[i][j]){\n                int col = g[i][j];\n                int sz  = 0;\n                // BFS\n                static deque<pair<int,int>> q;\n                q.emplace_back(i,j);\n                vis[i][j]=1;\n                while(!q.empty()){\n                    auto [r,c] = q.front(); q.pop_front();\n                    sz++;\n                    const int dr[4]={-1,1,0,0}, dc[4]={0,0,-1,1};\n                    for(int d=0;d<4;d++){\n                        int nr=r+dr[d], nc=c+dc[d];\n                        if(nr<0||nr>=H||nc<0||nc>=W) continue;\n                        if(!vis[nr][nc] && g[nr][nc]==col){\n                            vis[nr][nc]=1;\n                            q.emplace_back(nr,nc);\n                        }\n                    }\n                }\n                sum += sz*sz;\n            }\n        }\n    }\n    return sum;\n}\n\nint simulate_rollout(int g[H][W], int t){\n    // copy current state\n    memcpy(tmp, g, sizeof(tmp));\n    // random future\n    for(int k=t+1;k<100;k++){\n        // count empties\n        vector<int> empties;\n        empties.reserve(H*W);\n        for(int i=0;i<H*W;i++){\n            int r=i/W, c=i%W;\n            if(tmp[r][c]==0) empties.push_back(i);\n        }\n        if(empties.empty()) break;\n        uniform_int_distribution<int> uid(0,(int)empties.size()-1);\n        int pos = empties[uid(rng)];\n        int r=pos/W, c=pos%W;\n        tmp[r][c] = flavor[k];\n        // random tilt\n        uniform_int_distribution<int> did(0,3);\n        gravity(tmp, did(rng));\n    }\n    return eval_once(tmp);\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    for(int i=0;i<100;i++){\n        cin>>flavor[i];\n    }\n\n    memset(grid,0,sizeof(grid));\n\n    for(int t=0;t<100;t++){\n        int p; cin>>p; p--;\n        // place candy\n        int cnt=0,rr=-1,cc=-1;\n        for(int i=0;i<H*W;i++){\n            int r=i/W, c=i%W;\n            if(grid[r][c]==0){\n                if(cnt==p){ rr=r; cc=c; break; }\n                cnt++;\n            }\n        }\n        grid[rr][cc] = flavor[t];\n\n        int bestdir = 0, bestscore = -1;\n        const int K = 120; // roll-outs per candidate\n        for(int d=0;d<4;d++){\n            memcpy(tmp, grid, sizeof(tmp));\n            gravity(tmp, d);\n            int avg = 0;\n            for(int k=0;k<K;k++){\n                avg += simulate_rollout(tmp, t);\n            }\n            if(avg > bestscore){\n                bestscore = avg;\n                bestdir   = d;\n            }\n        }\n        // apply best to real grid\n        gravity(grid, bestdir);\n        cout << dirchar[bestdir] << '\\n';\n        cout.flush();\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\n// ---------------  \u57fa\u672c\u8a2d\u5b9a  ----------------\nint M; \ndouble eps;\nconst int MAX_N = 100;\nint N;                       // \u5b9f\u969b\u306b\u9078\u3076\u9802\u70b9\u6570\nint MAX_EDGES;               // N*(N-1)/2\n\n// \u5404 G_k \u306e\u8fba\u96c6\u5408\uff08bitmask \u3067\u3082 vector<bitset<>> \u3067\u3082\u53ef\uff09\n// \u3053\u3053\u3067\u306f\u96a3\u63a5\u884c\u5217\u3092 vector<bitset<MAX_N>> \u3067\u6301\u3064\nvector<bitset<MAX_N>> G[MAX_N*MAX_N]; // G[k][i][j] = 1 \u306a\u3089\u8fba (i,j) \u5b58\u5728\n\n// \u5404 G_k \u306e\u300c\u8fba\u6570\u300d\u304a\u3088\u3073\u300c\u6b21\u6570\u5217\uff08\u30bd\u30fc\u30c8\u6e08\u307f\uff09\u300d\nvector<int> target_edges;   // target_edges[k]\nvector<vector<int>> deg_seq; // deg_seq[k] : \u9577\u3055 N\u3001\u30bd\u30fc\u30c8\u6e08\u307f\n\n// --------------  \u4e8b\u524d\u8a08\u7b97\uff08Binomial \u5bfe\u6570\uff09 --------------\nconst int MAX_BINOM = MAX_N*MAX_N;\ndouble logfact[MAX_BINOM+1];\nvoid init_logfact(){\n    logfact[0] = 0.0;\n    for(int i=1;i<=MAX_BINOM;i++){\n        logfact[i] = logfact[i-1] + log(i);\n    }\n}\ninline double logbinom(int n, int k){\n    if(k<0||k>n) return -1e300;\n    return logfact[n] - logfact[k] - logfact[n-k];\n}\n\n// --------------  \u30b0\u30e9\u30d5\u51fa\u529b\u7528\u30a8\u30f3\u30b3\u30fc\u30c0 -----------------\nstring encode_graph(const vector<bitset<MAX_N>>& adj){\n    string s;\n    for(int i=0;i<N;i++){\n        for(int j=i+1;j<N;j++){\n            s += (adj[i][j] ? '1':'0');\n        }\n    }\n    return s;\n}\n\n// --------------  \u30e9\u30f3\u30c0\u30e0\u8fba\u751f\u6210 ------------------------\nvoid build_random_graph(vector<bitset<MAX_N>>& adj, int m){\n    adj.assign(N, bitset<MAX_N>());\n    int total = N*(N-1)/2;\n    vector<int> idx(total);\n    iota(idx.begin(), idx.end(), 0);\n    shuffle(idx.begin(), idx.end(), mt19937(12345));\n    for(int t=0;t<m;t++){\n        int e = idx[t];\n        int i = 0, j = 1;\n        // e \u756a\u76ee\u306e (i,j) (i<j) \u3092\u5fa9\u5143\n        int cnt = 0;\n        for(i=0;i<N;i++){\n            for(j=i+1;j<N;j++){\n                if(cnt==e) goto found;\n                cnt++;\n            }\n        }\n        found:\n        adj[i][j] = adj[j][i] = 1;\n    }\n}\n\n// --------------  \u6b21\u6570\u5217\u53d6\u5f97 --------------------------\nvector<int> get_degree_sequence(const vector<bitset<MAX_N>>& adj){\n    vector<int> deg(N);\n    for(int i=0;i<N;i++){\n        deg[i] = adj[i].count();\n    }\n    sort(deg.rbegin(), deg.rend());\n    return deg;\n}\n\n// --------------  \u5bfe\u6570\u5c24\u5ea6\u8fd1\u4f3c ------------------------\n// \u8fba\u6570 m \u306e\u307f\u3092\u898b\u308b\u7c21\u6613\u7248\ndouble loglikelihood_edge(int m, int k){\n    int total = N*(N-1)/2;\n    double p = (double)target_edges[k] / total;\n    // \u53cd\u8ee2\u5f8c\u306e\u671f\u5f85\u8fba\u6570\n    double mu = target_edges[k]*(1 - 2*eps) + eps*total;\n    double sigma2 = eps*(1 - eps)*total;\n    // \u6b63\u898f\u8fd1\u4f3c\n    double diff = m - mu;\n    return -0.5 * diff*diff / sigma2;\n}\n\n// --------------  \u30e1\u30a4\u30f3 --------------------------------\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // \u5165\u529b\n    cin >> M >> eps;\n\n    // N \u3092\u6c7a\u5b9a\uff08\u5c0f\u3055\u3044\u307b\u3046\u304c\u30b9\u30b3\u30a2\u500d\u7387\u304c\u9ad8\u3044\u304c\u3001\u8b58\u5225\u80fd\u529b\u304c\u843d\u3061\u308b\uff09\n    // \u3068\u308a\u3042\u3048\u305a N=20 \u3067\u56fa\u5b9a\n    N = 20;\n    MAX_EDGES = N*(N-1)/2;\n\n    // \u5bfe\u6570factorial \u521d\u671f\u5316\n    init_logfact();\n\n    // \u5404 G_k \u306e\u300c\u76ee\u6a19\u8fba\u6570\u300d\u3092\u7b49\u9593\u9694\u306b\n    target_edges.resize(M);\n    double step = (double)MAX_EDGES / (M-1);\n    for(int k=0;k<M;k++){\n        target_edges[k] = (int)round( k * step );\n    }\n\n    // \u5404 G_k \u3092\u751f\u6210 & \u6b21\u6570\u5217\u8a08\u7b97\n    for(int k=0;k<M;k++){\n        build_random_graph(G[k], target_edges[k]);\n        deg_seq.emplace_back( get_degree_sequence(G[k]) );\n    }\n\n    // \u51fa\u529b\n    cout << N << \"\\n\";\n    for(int k=0;k<M;k++){\n        cout << encode_graph(G[k]) << \"\\n\";\n    }\n    cout.flush();\n\n    // \u30af\u30a8\u30ea\u51e6\u7406\n    for(int q=0;q<100;q++){\n        string Hstr;\n        cin >> Hstr;\n        // H \u3092\u96a3\u63a5\u884c\u5217\u306b\n        vector<bitset<MAX_N>> H(N);\n        int ptr = 0;\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                if(Hstr[ptr++]=='1'){\n                    H[i][j] = H[j][i] = 1;\n                }\n            }\n        }\n        // \u8fba\u6570\n        int m = 0;\n        for(int i=0;i<N;i++) m += H[i].count();\n        m /= 2;\n\n        // \u5404 k \u306b\u3064\u3044\u3066\u5bfe\u6570\u5c24\u5ea6\uff08\u8fba\u6570\u306e\u307f\uff09\u3092\u8a08\u7b97\n        int best_k = 0;\n        double best_ll = -1e300;\n        for(int k=0;k<M;k++){\n            double ll = loglikelihood_edge(m, k);\n            if(ll > best_ll){\n                best_ll = ll;\n                best_k = k;\n            }\n        }\n        cout << best_k << \"\\n\";\n        cout.flush();\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\nconst int MAX_N = 1005;\nconst int MAX_M = 3005;\n\nint N, M, D, K;\nint u[MAX_M], v[MAX_M], w[MAX_M];\nint x[MAX_N], y[MAX_N];\nint assignment[MAX_M];\nint dist[MAX_N][MAX_N];\nint original_dist[MAX_N][MAX_N];\nvector<pair<int, int>> adj[MAX_N];\n\n// Calculate edge importance based on shortest path usage\nvector<int> calculate_edge_importance() {\n    vector<int> importance(M, 0);\n    \n    // Count how many shortest paths use each edge\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (i == j) continue;\n            int shortest_dist = original_dist[i][j];\n            \n            // Check if removing this edge would increase the distance\n            for (int e = 0; e < M; e++) {\n                // Simple heuristic: edges with low weight and high betweenness are important\n                if (original_dist[i][u[e]] + w[e] + original_dist[v[e]][j] == shortest_dist ||\n                    original_dist[i][v[e]] + w[e] + original_dist[u[e]][j] == shortest_dist) {\n                    importance[e]++;\n                }\n            }\n        }\n    }\n    \n    return importance;\n}\n\n// Calculate frustration for a given assignment\ndouble calculate_frustration() {\n    double total_frustration = 0.0;\n    \n    for (int day = 1; day <= D; day++) {\n        // Build graph for this day\n        vector<pair<int, int>> day_adj[MAX_N];\n        vector<bool> edge_removed(M, false);\n        \n        for (int e = 0; e < M; e++) {\n            if (assignment[e] == day) {\n                edge_removed[e] = true;\n            } else {\n                day_adj[u[e]].push_back({v[e], w[e]});\n                day_adj[v[e]].push_back({u[e], w[e]});\n            }\n        }\n        \n        // Calculate all-pairs shortest paths for this day\n        int day_dist[MAX_N][MAX_N];\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                day_dist[i][j] = (i == j) ? 0 : INF;\n            }\n        }\n        \n        // Use Dijkstra's algorithm for each vertex\n        for (int src = 0; src < N; src++) {\n            priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;\n            pq.push({0, src});\n            \n            while (!pq.empty()) {\n                auto [d, u_node] = pq.top();\n                pq.pop();\n                \n                if (d > day_dist[src][u_node]) continue;\n                \n                for (auto [v_node, weight] : day_adj[u_node]) {\n                    if (day_dist[src][v_node] > d + weight) {\n                        day_dist[src][v_node] = d + weight;\n                        pq.push({day_dist[src][v_node], v_node});\n                    }\n                }\n            }\n        }\n        \n        // Calculate frustration for this day\n        double day_frustration = 0.0;\n        int count = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (i != j) {\n                    int increase = day_dist[i][j] - original_dist[i][j];\n                    if (day_dist[i][j] == INF) increase = INF - original_dist[i][j];\n                    day_frustration += increase;\n                    count++;\n                }\n            }\n        }\n        \n        total_frustration += day_frustration / count;\n    }\n    \n    return total_frustration / D;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> D >> K;\n    \n    for (int i = 0; i < M; i++) {\n        cin >> u[i] >> v[i] >> w[i];\n        u[i]--; v[i]--;\n        adj[u[i]].push_back({v[i], w[i]});\n        adj[v[i]].push_back({u[i], w[i]});\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n    \n    // Calculate original shortest paths\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            original_dist[i][j] = (i == j) ? 0 : INF;\n        }\n    }\n    \n    for (int src = 0; src < N; src++) {\n        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;\n        pq.push({0, src});\n        \n        while (!pq.empty()) {\n            auto [d, u_node] = pq.top();\n            pq.pop();\n            \n            if (d > original_dist[src][u_node]) continue;\n            \n            for (auto [v_node, weight] : adj[u_node]) {\n                if (original_dist[src][v_node] > d + weight) {\n                    original_dist[src][v_node] = d + weight;\n                    pq.push({original_dist[src][v_node], v_node});\n                }\n            }\n        }\n    }\n    \n    // Calculate edge importance\n    vector<int> importance = calculate_edge_importance();\n    \n    // Sort edges by importance (descending)\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 importance[a] > importance[b];\n    });\n    \n    // Assign edges to days using a greedy approach\n    vector<int> day_load(D + 1, 0);\n    \n    // First, try to balance important edges across days\n    for (int e : edge_order) {\n        // Find the day with minimum load that can accommodate this edge\n        int best_day = 1;\n        int min_load = day_load[1];\n        \n        for (int day = 2; day <= D; day++) {\n            if (day_load[day] < min_load) {\n                min_load = day_load[day];\n                best_day = day;\n            }\n        }\n        \n        assignment[e] = best_day;\n        day_load[best_day]++;\n    }\n    \n    // Local search improvement\n    double best_frustration = calculate_frustration();\n    bool improved = true;\n    \n    while (improved) {\n        improved = false;\n        \n        // Try swapping edges between days\n        for (int e1 = 0; e1 < M; e1++) {\n            for (int e2 = e1 + 1; e2 < M; e2++) {\n                if (assignment[e1] != assignment[e2]) {\n                    // Try swapping\n                    int old_day1 = assignment[e1];\n                    int old_day2 = assignment[e2];\n                    \n                    assignment[e1] = old_day2;\n                    assignment[e2] = old_day1;\n                    \n                    double new_frustration = calculate_frustration();\n                    \n                    if (new_frustration < best_frustration) {\n                        best_frustration = new_frustration;\n                        improved = true;\n                    } else {\n                        // Revert\n                        assignment[e1] = old_day1;\n                        assignment[e2] = old_day2;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Output the assignment\n    for (int i = 0; i < M; i++) {\n        cout << assignment[i] << (i == M - 1 ? \"\\n\" : \" \");\n    }\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nusing ull = unsigned long long;\nusing int2 = __int128_t;\n\nstatic constexpr int MAXD = 14;\nstatic constexpr int MAXV = 16;               // max volume of generated blocks\nstatic constexpr int MAXB = 40000;            // max number of generated blocks\nstatic constexpr double TIME_LIMIT = 5.8;\n\nint D, DD, DDD;\nbitset<MAXD*MAXD*MAXD> mandatory[2], sharedMandatory;\nint mandatoryVol[2], sharedVol;\n\nstruct Block {\n    int vol;\n    vector<tuple<int,int,int>> cells;   // original coordinates\n    vector<vector<tuple<int,int,int>>> rot; // 24 rotations\n};\nint nBlocks = 0;\nBlock blocks[MAXB];\n\n// ---------- utilities ----------\ninline int idx(int x, int y, int z) { return x*D*D + y*D + z; }\ninline bool inside(int x, int y, int z) {\n    return 0 <= x && x < D && 0 <= y && y < D && 0 <= z && z < D;\n}\n\n// ---------- rotation ----------\nvector<vector<tuple<int,int,int>>> generateRotations(const vector<tuple<int,int,int>>& src) {\n    vector<vector<tuple<int,int,int>>> res;\n    set<vector<tuple<int,int,int>>> seen;\n    for (int rx = 0; rx < 4; ++rx)\n    for (int ry = 0; ry < 4; ++ry)\n    for (int rz = 0; rz < 4; ++rz) {\n        vector<tuple<int,int,int>> tmp;\n        for (auto [x,y,z] : src) {\n            int cx = x, cy = y, cz = z;\n            // rotate around X\n            for (int k = 0; k < rx; ++k) {\n                int ny = -cz, nz = cy;\n                cy = ny; cz = nz;\n            }\n            // rotate around Y\n            for (int k = 0; k < ry; ++k) {\n                int nx = cz, nz = -cx;\n                cx = nx; cz = nz;\n            }\n            // rotate around Z\n            for (int k = 0; k < rz; ++k) {\n                int nx = -cy, ny = cx;\n                cx = nx; cy = ny;\n            }\n            tmp.emplace_back(cx, cy, cz);\n        }\n        // normalize\n        int minx=INT_MAX, miny=INT_MAX, minz=INT_MAX;\n        for (auto [x,y,z] : tmp) {\n            minx = min(minx, x); miny = min(miny, y); minz = min(minz, z);\n        }\n        for (auto& [x,y,z] : tmp) {\n            x -= minx; y -= miny; z -= minz;\n        }\n        sort(tmp.begin(), tmp.end());\n        if (seen.insert(tmp).second) res.push_back(tmp);\n    }\n    return res;\n}\n\n// ---------- polycube generation ----------\nvoid generateBlocks() {\n    // BFS enumeration of all free polycubes up to volume MAXV\n    map<vector<tuple<int,int,int>>, int> canonicalId;\n    queue<pair<vector<tuple<int,int,int>>, int>> q;\n    q.push({{{0,0,0}}, 1});\n    canonicalId[{{{0,0,0}}}] = 1;\n    int dx[] = {1,-1,0,0,0,0}, dy[] = {0,0,1,-1,0,0}, dz[] = {0,0,0,0,1,-1};\n    while (!q.empty() && nBlocks < MAXB) {\n        auto [shape, vol] = q.front(); q.pop();\n        if (vol > MAXV) continue;\n        // store this shape\n        {\n            Block& B = blocks[nBlocks++];\n            B.vol = vol;\n            B.cells = shape;\n            B.rot = generateRotations(shape);\n        }\n        // expand\n        set<tuple<int,int,int>> frontier;\n        for (auto [x,y,z] : shape)\n        for (int d = 0; d < 6; ++d) {\n            int nx = x+dx[d], ny = y+dy[d], nz = z+dz[d];\n            if (!inside(nx,ny,nz)) continue;\n            if (find(shape.begin(), shape.end(), make_tuple(nx,ny,nz)) != shape.end()) continue;\n            frontier.emplace(nx,ny,nz);\n        }\n        for (auto [x,y,z] : frontier) {\n            auto ns = shape;\n            ns.emplace_back(x,y,z);\n            // normalize\n            int minx=INT_MAX,miny=INT_MAX,minz=INT_MAX;\n            for (auto [xx,yy,zz] : ns) {\n                minx=min(minx,xx); miny=min(miny,yy); minz=min(minz,zz);\n            }\n            for (auto& [xx,yy,zz] : ns) {\n                xx-=minx; yy-=miny; zz-=minz;\n            }\n            sort(ns.begin(), ns.end());\n            if (canonicalId.count(ns)) continue;\n            canonicalId[ns] = 1;\n            q.push({ns, vol+1});\n        }\n    }\n    cerr << \"generated \" << nBlocks << \" blocks up to volume \" << MAXV << \"\\n\";\n}\n\n// ---------- placement ----------\nstruct Placement {\n    bitset<MAXD*MAXD*MAXD> occ;\n    int usedVol;\n    vector<int> blockIds;\n    vector<vector<tuple<int,int,int>>> poses; // for each block, its rotated+translated cells\n};\nPlacement bestP[2];\ndouble bestScore = 1e18;\n\n// try to place block B with rotation r at (bx,by,bz) into grid g\nbool canPlace(const bitset<MAXD*MAXD*MAXD>& g, const Block& B, int r, int bx, int by, int bz) {\n    for (auto [x,y,z] : B.rot[r]) {\n        int xx = x+bx, yy = y+by, zz = z+bz;\n        if (!inside(xx,yy,zz)) return false;\n        if (g.test(idx(xx,yy,zz))) return false;\n    }\n    return true;\n}\nvoid place(bitset<MAXD*MAXD*MAXD>& g, const Block& B, int r, int bx, int by, int bz) {\n    for (auto [x,y,z] : B.rot[r]) {\n        int xx = x+bx, yy = y+by, zz = z+bz;\n        g.set(idx(xx,yy,zz));\n    }\n}\n\n// greedy cover for one silhouette\nPlacement greedyCover(const bitset<MAXD*MAXD*MAXD>& target, int which) {\n    Placement P;\n    P.occ.reset(); P.usedVol = 0;\n    vector<int> order(nBlocks);\n    iota(order.begin(), order.end(), 0);\n    // sort by 1/vol descending\n    sort(order.begin(), order.end(), [&](int a, int b){\n        return blocks[a].vol > blocks[b].vol;\n    });\n    bitset<MAXD*MAXD*MAXD> rem = target;\n    int remVol = target.count();\n    for (int id : order) {\n        if (remVol == 0) break;\n        const Block& B = blocks[id];\n        bool placed = false;\n        // try all rotations and positions\n        for (int r = 0; r < (int)B.rot.size() && !placed; ++r) {\n            int maxx=0,maxy=0,maxz=0;\n            for (auto [x,y,z] : B.rot[r]) {\n                maxx=max(maxx,x); maxy=max(maxy,y); maxz=max(maxz,z);\n            }\n            for (int bx = 0; bx + maxx < D && !placed; ++bx)\n            for (int by = 0; by + maxy < D && !placed; ++by)\n            for (int bz = 0; bz + maxz < D && !placed; ++bz) {\n                if (!canPlace(P.occ, B, r, bx,by,bz)) continue;\n                // check if it covers at least one remaining voxel\n                bool cov = false;\n                for (auto [x,y,z] : B.rot[r]) {\n                    int xx = x+bx, yy = y+by, zz = z+bz;\n                    if (rem.test(idx(xx,yy,zz))) { cov=true; break; }\n                }\n                if (!cov) continue;\n                // place it\n                place(P.occ, B, r, bx,by,bz);\n                P.blockIds.push_back(id);\n                vector<tuple<int,int,int>> pose;\n                for (auto [x,y,z] : B.rot[r]) pose.emplace_back(x+bx, y+by, z+bz);\n                P.poses.push_back(pose);\n                P.usedVol += B.vol;\n                // update rem\n                for (auto [x,y,z] : B.rot[r]) {\n                    int xx = x+bx, yy = y+by, zz = z+bz;\n                    rem.reset(idx(xx,yy,zz));\n                }\n                remVol = rem.count();\n                placed = true;\n            }\n        }\n    }\n    return P;\n}\n\n// ---------- scoring ----------\ndouble eval(const Placement& p1, const Placement& p2) {\n    // build set of used blocks\n    unordered_set<int> used1(p1.blockIds.begin(), p1.blockIds.end());\n    unordered_set<int> used2(p2.blockIds.begin(), p2.blockIds.end());\n    int r1 = 0, r2 = 0;\n    double sumInv = 0.0;\n    for (int i = 0; i < nBlocks; ++i) {\n        bool in1 = used1.count(i), in2 = used2.count(i);\n        if (!in1 && !in2) continue; // not allowed, but we prune earlier\n        if (!in1) r1 += blocks[i].vol;\n        if (!in2) r2 += blocks[i].vol;\n        if (in1 && in2) sumInv += 1.0 / blocks[i].vol;\n    }\n    double score = r1 + r2 + sumInv;\n    return score;\n}\n\n// ---------- output ----------\nvoid output(const Placement& p1, const Placement& p2) {\n    // build global block list\n    unordered_map<int,int> globalId;\n    int nOut = 0;\n    for (int id : p1.blockIds) if (!globalId.count(id)) globalId[id] = nOut++;\n    for (int id : p2.blockIds) if (!globalId.count(id)) globalId[id] = nOut++;\n    cout << nOut << \"\\n\";\n    // output b1\n    vector<int> flat1(D*D*D, 0);\n    for (int i = 0; i < (int)p1.blockIds.size(); ++i) {\n        int gid = globalId[p1.blockIds[i]];\n        for (auto [x,y,z] : p1.poses[i]) {\n            flat1[idx(x,y,z)] = gid+1;\n        }\n    }\n    for (int i = 0; i < DDD; ++i) {\n        if (i) cout << \" \";\n        cout << flat1[i];\n    }\n    cout << \"\\n\";\n    // output b2\n    vector<int> flat2(D*D*D, 0);\n    for (int i = 0; i < (int)p2.blockIds.size(); ++i) {\n        int gid = globalId[p2.blockIds[i]];\n        for (auto [x,y,z] : p2.poses[i]) {\n            flat2[idx(x,y,z)] = gid+1;\n        }\n    }\n    for (int i = 0; i < DDD; ++i) {\n        if (i) cout << \" \";\n        cout << flat2[i];\n    }\n    cout << \"\\n\";\n}\n\n// ---------- main ----------\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    auto clk = chrono::high_resolution_clock::now();\n\n    cin >> D;\n    DD = D*D; DDD = D*D*D;\n    // read silhouettes\n    vector<string> fstr[2], rstr[2];\n    for (int i = 0; i < 2; ++i) {\n        fstr[i].resize(D);\n        for (int z = 0; z < D; ++z) cin >> fstr[i][z];\n        rstr[i].resize(D);\n        for (int z = 0; z < D; ++z) cin >> rstr[i][z];\n    }\n    // build mandatory voxels\n    for (int i = 0; i < 2; ++i) {\n        mandatory[i].reset();\n        for (int x = 0; x < D; ++x)\n        for (int y = 0; y < D; ++y)\n        for (int z = 0; z < D; ++z) {\n            if (fstr[i][z][x]=='1' && rstr[i][z][y]=='1') {\n                mandatory[i].set(idx(x,y,z));\n            }\n        }\n        mandatoryVol[i] = mandatory[i].count();\n    }\n    sharedMandatory = mandatory[0] & mandatory[1];\n    sharedVol = sharedMandatory.count();\n\n    // generate block catalogue\n    generateBlocks();\n\n    // greedy cover for each silhouette\n    bestP[0] = greedyCover(mandatory[0], 0);\n    bestP[1] = greedyCover(mandatory[1], 1);\n    bestScore = eval(bestP[0], bestP[1]);\n\n    // simple iterative improvement: try to replace one block by a larger unused one\n    // (very fast, so we do many iterations)\n    int iter = 0;\n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - clk).count();\n        if (elapsed > TIME_LIMIT) break;\n        iter++;\n        // pick random placement\n        int w = rand()&1;\n        Placement& P = bestP[w];\n        if (P.blockIds.empty()) continue;\n        int k = rand() % P.blockIds.size();\n        int oldId = P.blockIds[k];\n        // try all bigger unused blocks\n        bool improved = false;\n        for (int cand = 0; cand < nBlocks && !improved; ++cand) {\n            if (blocks[cand].vol <= blocks[oldId].vol) continue;\n            // try to place cand instead of oldId\n            Placement tmp = P;\n            // remove oldId\n            tmp.occ.reset();\n            tmp.usedVol -= blocks[oldId].vol;\n            tmp.blockIds.erase(tmp.blockIds.begin()+k);\n            tmp.poses.erase(tmp.poses.begin()+k);\n            // rebuild occ\n            for (int i = 0; i < (int)tmp.blockIds.size(); ++i) {\n                const Block& B = blocks[tmp.blockIds[i]];\n                for (auto [x,y,z] : tmp.poses[i]) tmp.occ.set(idx(x,y,z));\n            }\n            // try to add cand somewhere\n            const Block& B = blocks[cand];\n            bool placed = false;\n            for (int r = 0; r < (int)B.rot.size() && !placed; ++r) {\n                int maxx=0,maxy=0,maxz=0;\n                for (auto [x,y,z] : B.rot[r]) {\n                    maxx=max(maxx,x); maxy=max(maxy,y); maxz=max(maxz,z);\n                }\n                for (int bx = 0; bx + maxx < D && !placed; ++bx)\n                for (int by = 0; by + maxy < D && !placed; ++by)\n                for (int bz = 0; bz + maxz < D && !placed; ++bz) {\n                    if (!canPlace(tmp.occ, B, r, bx,by,bz)) continue;\n                    // check it covers at least one missing voxel\n                    bitset<MAXD*MAXD*MAXD> need = mandatory[w];\n                    for (int i = 0; i < (int)tmp.blockIds.size(); ++i)\n                        for (auto [x,y,z] : tmp.poses[i]) need.reset(idx(x,y,z));\n                    bool cov = false;\n                    for (auto [x,y,z] : B.rot[r]) {\n                        int xx = x+bx, yy = y+by, zz = z+bz;\n                        if (need.test(idx(xx,yy,zz))) { cov=true; break; }\n                    }\n                    if (!cov) continue;\n                    // place it\n                    place(tmp.occ, B, r, bx,by,bz);\n                    tmp.blockIds.push_back(cand);\n                    vector<tuple<int,int,int>> pose;\n                    for (auto [x,y,z] : B.rot[r]) pose.emplace_back(x+bx, y+by, z+bz);\n                    tmp.poses.push_back(pose);\n                    tmp.usedVol += B.vol;\n                    placed = true;\n                }\n            }\n            if (!placed) continue;\n            // finish covering with greedy\n            bitset<MAXD*MAXD*MAXD> rem = mandatory[w];\n            for (int i = 0; i < (int)tmp.blockIds.size(); ++i)\n                for (auto [x,y,z] : tmp.poses[i]) rem.reset(idx(x,y,z));\n            if (rem.any()) {\n                Placement fill = greedyCover(rem, w);\n                for (int i = 0; i < (int)fill.blockIds.size(); ++i) {\n                    tmp.blockIds.push_back(fill.blockIds[i]);\n                    tmp.poses.push_back(fill.poses[i]);\n                    tmp.usedVol += blocks[fill.blockIds[i]].vol;\n                    for (auto [x,y,z] : fill.poses[i]) tmp.occ.set(idx(x,y,z));\n                }\n            }\n            // evaluate\n            double sc = eval(tmp, bestP[w^1]);\n            if (sc < bestScore) {\n                bestScore = sc;\n                bestP[w] = tmp;\n                improved = true;\n            }\n        }\n    }\n\n    cerr << \"iterations \" << iter << \" bestScore \" << bestScore << \"\\n\";\n    output(bestP[0], bestP[1]);\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing int64 = long long;\n\nstatic const int MAXN = 105;\nstatic const int MAXM = 305;\nstatic const int MAXK = 5005;\nstatic const int MAXP = 5000;\n\nint N, M, K;\ndouble x[MAXN], y[MAXN];\nint u_e[MAXM], v_e[MAXM], w_e[MAXM];\ndouble a[MAXK], b[MAXK];\n\n// DSU for Kruskal\nint parent[MAXN];\nint find_set(int v) {\n    if (v == parent[v]) return v;\n    return parent[v] = find_set(parent[v]);\n}\nbool union_set(int u, int v) {\n    u = find_set(u);\n    v = find_set(v);\n    if (u == v) return false;\n    parent[v] = u;\n    return true;\n}\n\n// graph\nvector<pair<int,int>> adj[MAXN]; // (neighbor, edge_index)\n\n// MST flags\nbool in_mst[MAXM];\nint64 total_edge_cost = 0;\n\n// resident -> distance to each vertex\ndouble dist_ik[MAXK][MAXN];\n\n// current solution\nint P[MAXN];\nbool edge_on[MAXM];\n\n// recompute vertex cost and detect uncovered residents\n// returns -1 if some resident has closest > MAXP\nint64 recompute_vertex_cost(const vector<char>& reachable,\n                            vector<int>& bestP)\n{\n    bestP.assign(N, 0);\n    for (int k = 0; k < K; k++) {\n        double best_d = 1e18;\n        int best_i = -1;\n        for (int i = 0; i < N; i++) {\n            if (reachable[i] && dist_ik[k][i] < best_d) {\n                best_d = dist_ik[k][i];\n                best_i = i;\n            }\n        }\n        if (best_d > MAXP) return -1;          // unreachable within limit\n        int need = (int)ceil(best_d);\n        need = min(need, MAXP);\n        bestP[best_i] = max(bestP[best_i], need);\n    }\n    int64 cost = 0;\n    for (int i = 0; i < N; i++) cost += (int64)bestP[i] * bestP[i];\n    return cost;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> K;\n    for(int i = 0; i < N; i++){\n        cin >> x[i] >> y[i];\n    }\n    for(int j = 0; j < M; j++){\n        cin >> u_e[j] >> v_e[j] >> w_e[j];\n        --u_e[j]; --v_e[j];\n    }\n    for(int k = 0; k < K; k++){\n        cin >> a[k] >> b[k];\n    }\n\n    // precompute resident->vertex distances\n    for(int k = 0; k < K; k++){\n        for(int i = 0; i < N; i++){\n            double dx = x[i] - a[k];\n            double dy = y[i] - b[k];\n            dist_ik[k][i] = sqrt(dx*dx + dy*dy);\n        }\n    }\n\n    // Kruskal MST\n    for(int i = 0; i < N; i++) parent[i] = i;\n    vector<int> edges_order(M);\n    iota(edges_order.begin(), edges_order.end(), 0);\n    sort(edges_order.begin(), edges_order.end(),\n         [&](int j1, int j2){ return w_e[j1] < w_e[j2]; });\n\n    fill(in_mst, in_mst + M, false);\n    for(int jj = 0; jj < M; jj++){\n        int j = edges_order[jj];\n        if (union_set(u_e[j], v_e[j])) {\n            in_mst[j] = true;\n            total_edge_cost += w_e[j];\n        }\n    }\n\n    // build adj for BFS\n    for(int j = 0; j < M; j++){\n        if (in_mst[j]){\n            adj[u_e[j]].emplace_back(v_e[j], j);\n            adj[v_e[j]].emplace_back(u_e[j], j);\n        }\n    }\n\n    // initial full reachable\n    vector<char> fullReach(N, true);\n    vector<int>  bestP(N);\n    int64 vertex_cost = recompute_vertex_cost(fullReach, bestP);\n    for(int i = 0; i < N; i++) P[i] = bestP[i];\n    for(int j = 0; j < M; j++) edge_on[j] = in_mst[j];\n\n    // greedy deletion pass: largest weight first\n    vector<int> tree_edges;\n    for(int j = 0; j < M; j++) if (in_mst[j]) tree_edges.push_back(j);\n    sort(tree_edges.begin(), tree_edges.end(),\n         [&](int j1, int j2){ return w_e[j1] > w_e[j2]; });\n\n    bool improved;\n    do {\n        improved = false;\n        for(int j_idx = 0; j_idx < (int)tree_edges.size(); j_idx++){\n            int j = tree_edges[j_idx];\n            if (!edge_on[j]) continue;\n\n            edge_on[j] = false;\n            // BFS reachable\n            vector<char> reach(N, false);\n            queue<int> q;\n            reach[0] = true; q.push(0);\n            while(!q.empty()){\n                int u = q.front(); q.pop();\n                for(auto& [v, eidx] : adj[u]){\n                    if (!edge_on[eidx]) continue;\n                    if (!reach[v]){\n                        reach[v] = true;\n                        q.push(v);\n                    }\n                }\n            }\n            vector<int> newP(N);\n            int64 new_vertex_cost = recompute_vertex_cost(reach, newP);\n            if (new_vertex_cost == -1){\n                // some resident uncovered -> reject\n                edge_on[j] = true;\n                continue;\n            }\n            int64 saved = w_e[j];\n            int64 extra = new_vertex_cost - vertex_cost;\n            if (extra < saved){\n                vertex_cost = new_vertex_cost;\n                for(int i = 0; i < N; i++) P[i] = newP[i];\n                improved = true;\n            } else {\n                edge_on[j] = true;\n            }\n        }\n    } while(improved);\n\n    // output\n    for(int i = 0; i < N; i++){\n        cout << P[i] << (i+1<N?' ':'\\n');\n    }\n    for(int j = 0; j < M; j++){\n        cout << (edge_on[j]?1:0) << (j+1<M?' ':'\\n');\n    }\n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\nstruct Ball {\n    int value;\n    int x, y;\n};\n\nconst int N = 30;\nconst int MAX_SWAPS = 10000;\n\nint pyramid[N][N];\nvector<pair<pair<int,int>, pair<int,int>>> swaps;\n\n// Check if two positions are adjacent in 6 directions\nbool isAdjacent(int x1, int y1, int x2, int y2) {\n    if (x1 == x2-1 && (y1 == y2-1 || y1 == y2)) return true;\n    if (x1 == x2 && (y1 == y2-1 || y1 == y2+1)) return true;\n    if (x1 == x2+1 && (y1 == y2 || y1 == y2+1)) return true;\n    return false;\n}\n\n// Swap two balls and record the operation\nvoid performSwap(int x1, int y1, int x2, int y2) {\n    swap(pyramid[x1][y1], pyramid[x2][y2]);\n    swaps.push_back({{x1, y1}, {x2, y2}});\n}\n\n// Check if position (x,y) violates the heap property\nbool violatesHeap(int x, int y) {\n    if (x == N-1) return false; // Bottom tier doesn't violate\n    \n    int val = pyramid[x][y];\n    int leftChild = pyramid[x+1][y];\n    int rightChild = pyramid[x+1][y+1];\n    \n    return val > leftChild || val > rightChild;\n}\n\n// Find path to bring a small value up\nvector<pair<int,int>> findBubblePath(int targetX, int targetY) {\n    vector<pair<int,int>> path;\n    int x = targetX, y = targetY;\n    \n    while (x > 0) {\n        // Try to move up-left first\n        if (y > 0 && x-1 >= 0 && y-1 >= 0) {\n            path.push_back({x-1, y-1});\n            x--; y--;\n        }\n        // Then try up-right\n        else if (y < x && x-1 >= 0 && y < x-1) {\n            path.push_back({x-1, y});\n            x--;\n        }\n        else {\n            break;\n        }\n    }\n    \n    return path;\n}\n\n// Bubble a value up to its correct position\nvoid bubbleUp(int startX, int startY) {\n    int x = startX, y = startY;\n    \n    while (x > 0) {\n        int parentX = -1, parentY = -1;\n        \n        // Find parent position\n        if (y > 0 && pyramid[x-1][y-1] > pyramid[x][y]) {\n            parentX = x-1; parentY = y-1;\n        }\n        else if (y < x && pyramid[x-1][y] > pyramid[x][y]) {\n            parentX = x-1; parentY = y;\n        }\n        \n        if (parentX == -1) break;\n        \n        performSwap(x, y, parentX, parentY);\n        x = parentX; y = parentY;\n        \n        if (swaps.size() >= MAX_SWAPS) return;\n    }\n}\n\n// Main algorithm: iterative improvement\nvoid solve() {\n    // Read input\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j <= i; j++) {\n            cin >> pyramid[i][j];\n        }\n    }\n    \n    // Multiple passes to fix violations\n    for (int pass = 0; pass < 5 && swaps.size() < MAX_SWAPS; pass++) {\n        bool improved = false;\n        \n        // Process from bottom to top\n        for (int x = N-2; x >= 0; x--) {\n            for (int y = 0; y <= x; y++) {\n                if (violatesHeap(x, y)) {\n                    bubbleUp(x, y);\n                    improved = true;\n                    \n                    if (swaps.size() >= MAX_SWAPS) return;\n                }\n            }\n        }\n        \n        if (!improved) break;\n    }\n    \n    // Local optimization: fix remaining violations\n    for (int iter = 0; iter < 100 && swaps.size() < MAX_SWAPS; iter++) {\n        bool fixed = false;\n        \n        for (int x = 0; x < N-1 && !fixed; x++) {\n            for (int y = 0; y <= x && !fixed; y++) {\n                if (violatesHeap(x, y)) {\n                    int val = pyramid[x][y];\n                    \n                    // Try swapping with children\n                    if (val > pyramid[x+1][y]) {\n                        performSwap(x, y, x+1, y);\n                        fixed = true;\n                    }\n                    else if (val > pyramid[x+1][y+1]) {\n                        performSwap(x, y, x+1, y+1);\n                        fixed = true;\n                    }\n                    \n                    if (swaps.size() >= MAX_SWAPS) return;\n                }\n            }\n        }\n        \n        if (!fixed) break;\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    solve();\n    \n    // Output swaps\n    cout << swaps.size() << '\\n';\n    for (auto& swap : swaps) {\n        cout << swap.first.first << ' ' << swap.first.second << ' ' \n             << swap.second.first << ' ' << swap.second.second << '\\n';\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int D = 9;\nconst int di[] = {-1, 0, 1, 0};\nconst int dj[] = {0, 1, 0, -1};\n\nint N;\nbool obstacle[D][D];\nbool occupied[D][D];\nint container[D][D]; // container[i][j] = t_d if occupied, else -1\nint dist[D][D];\n\nvoid bfs_dist() {\n    queue<pair<int, int>> q;\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            dist[i][j] = -1;\n        }\n    }\n    int si = 0, sj = (D-1)/2;\n    dist[si][sj] = 0;\n    q.emplace(si, sj);\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) continue;\n            if (obstacle[ni][nj] || occupied[ni][nj]) continue;\n            if (dist[ni][nj] == -1) {\n                dist[ni][nj] = dist[i][j] + 1;\n                q.emplace(ni, nj);\n            }\n        }\n    }\n}\n\nbool is_reachable(int i, int j) {\n    if (obstacle[i][j] || occupied[i][j]) return false;\n    bfs_dist();\n    return dist[i][j] != -1;\n}\n\nvector<pair<int, int>> get_reachable() {\n    bfs_dist();\n    vector<pair<int, int>> res;\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            if (!obstacle[i][j] && !occupied[i][j] && dist[i][j] != -1) {\n                res.emplace_back(i, j);\n            }\n        }\n    }\n    return res;\n}\n\npair<int, int> choose_placement(int t) {\n    auto reachable = get_reachable();\n    if (reachable.empty()) {\n        cerr << \"No reachable cells!\" << endl;\n        exit(1);\n    }\n    // Choose the cell with maximum distance from entrance\n    pair<int, int> best = reachable[0];\n    int best_dist = dist[best.first][best.second];\n    for (auto [i, j] : reachable) {\n        if (dist[i][j] > best_dist) {\n            best_dist = dist[i][j];\n            best = {i, j};\n        }\n    }\n    return best;\n}\n\nvector<pair<int, int>> retrieval_order;\n\nvoid compute_retrieval() {\n    // Reset occupied to true where containers are placed\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            occupied[i][j] = (container[i][j] != -1);\n        }\n    }\n    priority_queue<pair<int, pair<int, int>>, vector<pair<int, pair<int, int>>>, greater<pair<int, pair<int, int>>>> pq;\n    // Initial reachable containers\n    bfs_dist();\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            if (container[i][j] != -1 && dist[i][j] != -1) {\n                pq.emplace(container[i][j], make_pair(i, j));\n            }\n        }\n    }\n    while (!pq.empty()) {\n        auto [t, pos] = pq.top(); pq.pop();\n        auto [i, j] = pos;\n        if (container[i][j] == -1) continue; // already removed\n        retrieval_order.emplace_back(i, j);\n        occupied[i][j] = false;\n        container[i][j] = -1;\n        // Update reachability\n        bfs_dist();\n        // Add newly reachable containers\n        for (int ni = 0; ni < D; ++ni) {\n            for (int nj = 0; nj < D; ++nj) {\n                if (container[ni][nj] != -1 && dist[ni][nj] != -1) {\n                    pq.emplace(container[ni][nj], make_pair(ni, nj));\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cout << fixed << setprecision(20);\n\n    cin >> D >> N;\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            obstacle[i][j] = false;\n            occupied[i][j] = false;\n            container[i][j] = -1;\n        }\n    }\n    for (int k = 0; k < N; ++k) {\n        int ri, rj;\n        cin >> ri >> rj;\n        obstacle[ri][rj] = true;\n    }\n\n    int total_containers = D*D - 1 - N;\n    for (int d = 0; d < total_containers; ++d) {\n        int t;\n        cin >> t;\n        auto [i, j] = choose_placement(t);\n        occupied[i][j] = true;\n        container[i][j] = t;\n        cout << i << \" \" << j << endl;\n    }\n\n    compute_retrieval();\n    for (auto [i, j] : retrieval_order) {\n        cout << i << \" \" << j << \"\\n\";\n    }\n    cout.flush();\n\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 50;\nconst int MAX_M = 100;\n\nint n, m;\nint input[MAX_N][MAX_N];\nbool adj[MAX_M + 1][MAX_M + 1];\nint output[MAX_N][MAX_N];\n\n// Directions for adjacency checking\nint dx[] = {-1, 1, 0, 0};\nint dy[] = {0, 0, -1, 1};\n\nvoid extract_adjacencies() {\n    memset(adj, false, sizeof(adj));\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int c1 = input[i][j];\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d];\n                int nj = j + dy[d];\n                int c2;\n                \n                if (ni < 0 || ni >= n || nj < 0 || nj >= n) {\n                    c2 = 0; // Outside\n                } else {\n                    c2 = input[ni][nj];\n                }\n                \n                if (c1 != c2) {\n                    int u = min(c1, c2);\n                    int v = max(c1, c2);\n                    adj[u][v] = true;\n                }\n            }\n        }\n    }\n}\n\nbool is_valid_placement() {\n    // Check connectivity for each color\n    for (int color = 0; color <= m; color++) {\n        vector<pair<int, int>> cells;\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (output[i][j] == color) {\n                    cells.push_back({i, j});\n                }\n            }\n        }\n        \n        if (cells.empty()) continue;\n        \n        // BFS to check connectivity\n        vector<vector<bool>> visited(n, vector<bool>(n, false));\n        queue<pair<int, int>> q;\n        q.push(cells[0]);\n        visited[cells[0].first][cells[0].second] = true;\n        int count = 1;\n        \n        while (!q.empty()) {\n            auto [i, j] = q.front(); q.pop();\n            \n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d];\n                int nj = j + dy[d];\n                \n                if (ni >= 0 && ni < n && nj >= 0 && nj < n && \n                    output[ni][nj] == color && !visited[ni][nj]) {\n                    visited[ni][nj] = true;\n                    q.push({ni, nj});\n                    count++;\n                }\n            }\n        }\n        \n        if (count != (int)cells.size()) return false;\n    }\n    \n    // Check adjacency preservation\n    bool output_adj[MAX_M + 1][MAX_M + 1] = {false};\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int c1 = output[i][j];\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d];\n                int nj = j + dy[d];\n                int c2;\n                \n                if (ni < 0 || ni >= n || nj < 0 || nj >= n) {\n                    c2 = 0;\n                } else {\n                    c2 = output[ni][nj];\n                }\n                \n                if (c1 != c2) {\n                    int u = min(c1, c2);\n                    int v = max(c1, c2);\n                    output_adj[u][v] = true;\n                }\n            }\n        }\n    }\n    \n    for (int i = 0; i <= m; i++) {\n        for (int j = i + 1; j <= m; j++) {\n            if (adj[i][j] != output_adj[i][j]) {\n                return false;\n            }\n        }\n    }\n    \n    return true;\n}\n\nint count_zeros() {\n    int count = 0;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (output[i][j] == 0) count++;\n        }\n    }\n    return count;\n}\n\nvoid copy_output(int dest[MAX_N][MAX_N], const int src[MAX_N][MAX_N]) {\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            dest[i][j] = src[i][j];\n        }\n    }\n}\n\nvoid improve_solution() {\n    int best_zeros = count_zeros();\n    int best_output[MAX_N][MAX_N];\n    copy_output(best_output, output);\n    \n    // Try some local improvements with simulated annealing\n    double temperature = 1.0;\n    const double cooling_rate = 0.995;\n    \n    for (int iter = 0; iter < 5000 && temperature > 0.01; iter++) {\n        int i = rand() % n;\n        int j = rand() % n;\n        \n        if (output[i][j] == 0) continue;\n        \n        int original_color = output[i][j];\n        \n        // Try setting to 0\n        output[i][j] = 0;\n        if (is_valid_placement()) {\n            int zeros = count_zeros();\n            if (zeros > best_zeros) {\n                best_zeros = zeros;\n                copy_output(best_output, output);\n            } else if (zeros == best_zeros && (rand() / double(RAND_MAX)) < temperature) {\n                // Accept same score with some probability (simulated annealing)\n            } else {\n                // Revert if worse\n                output[i][j] = original_color;\n            }\n        } else {\n            output[i][j] = original_color;\n        }\n        \n        temperature *= cooling_rate;\n    }\n    \n    copy_output(output, best_output);\n}\n\nvoid find_compact_embedding() {\n    // Create a spanning tree of the adjacency graph\n    vector<vector<int>> graph(m + 1);\n    for (int i = 0; i <= m; i++) {\n        for (int j = i + 1; j <= m; j++) {\n            if (adj[i][j]) {\n                graph[i].push_back(j);\n                graph[j].push_back(i);\n            }\n        }\n    }\n    \n    // Use BFS to find a good ordering\n    vector<int> ordering;\n    vector<bool> visited(m + 1, false);\n    queue<int> q;\n    q.push(0); // Start with color 0 (outside)\n    visited[0] = true;\n    \n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        if (u != 0) ordering.push_back(u);\n        \n        for (int v : graph[u]) {\n            if (!visited[v]) {\n                visited[v] = true;\n                q.push(v);\n            }\n        }\n    }\n    \n    // Place colors in a spiral pattern starting from edges\n    int center_i = n / 2, center_j = n / 2;\n    int current_i = 0, current_j = 0;\n    int di = 0, dj = 1;\n    int steps = 1;\n    int step_count = 0;\n    int turn_count = 0;\n    \n    // First, ensure color 0 is on boundaries\n    for (int i = 0; i < n; i++) {\n        output[i][0] = 0;\n        output[i][n-1] = 0;\n        output[0][i] = 0;\n        output[n-1][i] = 0;\n    }\n    \n    // Place other colors\n    for (int color : ordering) {\n        bool placed = false;\n        \n        // Try to place near existing neighbors\n        for (int radius = 1; radius < n && !placed; radius++) {\n            for (int i = max(0, center_i - radius); i <= min(n-1, center_i + radius) && !placed; i++) {\n                for (int j = max(0, center_j - radius); j <= min(n-1, center_j + radius) && !placed; j++) {\n                    if (output[i][j] != 0) continue;\n                    \n                    // Check if adjacent to any required neighbor\n                    bool has_required_neighbor = false;\n                    for (int d = 0; d < 4; d++) {\n                        int ni = i + dx[d];\n                        int nj = j + dy[d];\n                        \n                        if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                            int neighbor_color = output[ni][nj];\n                            if (adj[min(color, neighbor_color)][max(color, neighbor_color)]) {\n                                has_required_neighbor = true;\n                                break;\n                            }\n                        } else if (adj[min(color, 0)][max(color, 0)]) {\n                            has_required_neighbor = true;\n                            break;\n                        }\n                    }\n                    \n                    if (has_required_neighbor || radius <= 2) {\n                        output[i][j] = color;\n                        placed = true;\n                    }\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> n >> m;\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> input[i][j];\n        }\n    }\n    \n    extract_adjacencies();\n    \n    // Initialize output with all zeros\n    memset(output, 0, sizeof(output));\n    \n    // Find a compact embedding\n    find_compact_embedding();\n    \n    // Verify and improve if needed\n    if (!is_valid_placement()) {\n        // Fallback: use input as output\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                output[i][j] = input[i][j];\n            }\n        }\n    } else {\n        // Try to improve the solution\n        improve_solution();\n    }\n    \n    // Output the result\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << output[i][j];\n            if (j < n - 1) cout << \" \";\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, D, Q;\nvector<int> estimated_weight;\nvector<int> assignment;\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nstring query(const vector<int>& L, const vector<int>& R) {\n    cout << L.size() << \" \" << R.size();\n    for (int x : L) cout << \" \" << x;\n    for (int x : R) cout << \" \" << x;\n    cout << endl;\n    string res;\n    cin >> res;\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> D >> Q;\n    \n    estimated_weight.assign(N, 1);\n    assignment.assign(N, 0);\n    \n    // Phase 1: Quick pairwise comparisons to get rough ordering\n    int queries_used = 0;\n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n    \n    // Do some random pairwise comparisons\n    for (int i = 0; i < min(Q/4, N*2) && queries_used < Q; i++) {\n        int a = rng() % N;\n        int b = rng() % N;\n        if (a == b) continue;\n        \n        string res = query({a}, {b});\n        queries_used++;\n        \n        if (res == \">\") {\n            estimated_weight[a] += 2;\n        } else if (res == \"<\") {\n            estimated_weight[b] += 2;\n        } else {\n            estimated_weight[a] += 1;\n            estimated_weight[b] += 1;\n        }\n    }\n    \n    // Phase 2: Compare groups to refine estimates\n    for (int i = 0; i < min(Q/4, N) && queries_used < Q; i++) {\n        // Compare random subsets\n        vector<int> group1, group2;\n        for (int j = 0; j < N; j++) {\n            if (rng() % 2 == 0) group1.push_back(j);\n            else if (rng() % 2 == 0) group2.push_back(j);\n        }\n        \n        if (group1.empty() || group2.empty()) continue;\n        \n        string res = query(group1, group2);\n        queries_used++;\n        \n        // Adjust weights based on group comparison\n        if (res == \">\") {\n            for (int x : group1) estimated_weight[x] += 1;\n        } else if (res == \"<\") {\n            for (int x : group2) estimated_weight[x] += 1;\n        }\n    }\n    \n    // Phase 3: Sort by estimated weight and assign greedily\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        return estimated_weight[a] > estimated_weight[b];\n    });\n    \n    vector<long long> group_sum(D, 0);\n    \n    // Assign heaviest items first to balance groups\n    for (int i = 0; i < N; i++) {\n        int item = order[i];\n        // Find group with minimum current sum\n        int best_group = 0;\n        for (int g = 1; g < D; g++) {\n            if (group_sum[g] < group_sum[best_group]) {\n                best_group = g;\n            }\n        }\n        assignment[item] = best_group;\n        group_sum[best_group] += estimated_weight[item];\n    }\n    \n    // Phase 4: Try some local improvements with remaining queries\n    for (int q = queries_used; q < Q && q < queries_used + Q/8; q++) {\n        // Try swapping two items between groups\n        int a = rng() % N;\n        int b = rng() % N;\n        if (a == b || assignment[a] == assignment[b]) continue;\n        \n        // Compare these two items\n        string res = query({a}, {b});\n        \n        // If our assignment seems wrong, try to fix it\n        if ((res == \">\" && group_sum[assignment[a]] < group_sum[assignment[b]]) ||\n            (res == \"<\" && group_sum[assignment[a]] > group_sum[assignment[b]])) {\n            // Swap assignments\n            int old_a = assignment[a];\n            int old_b = assignment[b];\n            assignment[a] = old_b;\n            assignment[b] = old_a;\n            group_sum[old_b] += estimated_weight[a] - estimated_weight[b];\n            group_sum[old_a] += estimated_weight[b] - estimated_weight[a];\n        }\n    }\n    \n    // Output final assignment\n    for (int i = 0; i < N; i++) {\n        cout << assignment[i];\n        if (i < N-1) cout << \" \";\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 200;\nconst int MAXM = 10;\n\nint n, m;\nvector<int> st[MAXM];\npair<int,int> where[MAXN+1]; // {stack, index} for box v; stack=-1 if carried\n\nvector<pair<int,int>> ops;\n\n// Carry out box v from stack s\nvoid carry_out(int v, int s) {\n    ops.emplace_back(v, 0);\n    st[s].pop_back();\n    where[v] = {-1, -1};\n}\n\n// Move box v and all above it from stack s to stack t\nvoid move_block(int v, int s, int t) {\n    int idx = where[v].second;\n    int k = st[s].size() - idx; // number of boxes to move\n    ops.emplace_back(v, t+1); // output is 1-indexed\n\n    // Extract block\n    vector<int> block(st[s].begin() + idx, st[s].end());\n    st[s].resize(idx);\n\n    // Append to target\n    for(int x : block) {\n        st[t].push_back(x);\n        where[x] = {t, (int)st[t].size()-1};\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> n >> m;\n    for(int i = 0; i < m; i++) {\n        st[i].resize(n/m);\n        for(int j = 0; j < n/m; j++) {\n            cin >> st[i][j];\n            where[ st[i][j] ] = {i, j};\n        }\n    }\n\n    int next_out = 1;\n\n    while(next_out <= n) {\n        // Phase 1: carry out as many as possible\n        bool progress = true;\n        while(progress && next_out <= n) {\n            progress = false;\n            // Find if next_out is at top of any stack\n            for(int i = 0; i < m; i++) {\n                if(!st[i].empty() && st[i].back() == next_out) {\n                    carry_out(next_out, i);\n                    next_out++;\n                    progress = true;\n                    break;\n                }\n            }\n        }\n        if(next_out > n) break;\n\n        // Phase 2: next_out is buried somewhere\n        int s = -1;\n        for(int i = 0; i < m; i++) {\n            for(int j = 0; j < st[i].size(); j++) {\n                if(st[i][j] == next_out) {\n                    s = i;\n                    break;\n                }\n            }\n            if(s != -1) break;\n        }\n        // s is the stack containing next_out\n        int idx = where[next_out].second;\n        int k = st[s].size() - idx; // boxes from next_out to top\n\n        // Choose target stack t != s with maximum top box\n        int best_t = -1;\n        int best_top = -1;\n        for(int t = 0; t < m; t++) {\n            if(t == s) continue;\n            int top_val = st[t].empty() ? 0 : st[t].back();\n            if(top_val > best_top) {\n                best_top = top_val;\n                best_t = t;\n            }\n        }\n        // Move block to best_t\n        move_block(next_out, s, best_t);\n    }\n\n    // Output operations\n    for(auto [v, i] : ops) {\n        cout << v << \" \" << i << \"\\n\";\n    }\n\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nstatic const int DI[4] = {1,0,-1,0};\nstatic const int DJ[4] = {0,1,0,-1};\nstatic const char DC[4] = {'D','R','U','L'};\n\nint main(){\n  ios::sync_with_stdio(false);\n  cin.tie(nullptr);\n\n  int N; cin>>N;\n  vector<string> hwall(N-1), vwall(N);\n  for(int i=0;i<N-1;i++) cin>>hwall[i];\n  for(int i=0;i<N;  i++) cin>>vwall[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  // build adj\n  auto inside = [&](int i,int j){ return 0<=i&&i<N&&0<=j&&j<N; };\n  vector<vector<array<int,2>>> adj(N*N);\n  auto enc = [&](int i,int j){ return i*N+j; };\n  auto dec = [&](int v){ return array<int,2>{v/N, v%N}; };\n  for(int i=0;i<N;i++){\n    for(int j=0;j<N;j++){\n      int v = enc(i,j);\n      for(int dir=0;dir<4;dir++){\n        int ni=i+DI[dir], nj=j+DJ[dir];\n        if(!inside(ni,nj)) continue;\n        bool ok = true;\n        if(dir==0){ // D\n          if(hwall[i][j]=='1') ok=false;\n        }else if(dir==2){ // U\n          if(hwall[i-1][j]=='1') ok=false;\n        }else if(dir==1){ // R\n          if(vwall[i][j]=='1') ok=false;\n        }else{ // L\n          if(vwall[i][j-1]=='1') ok=false;\n        }\n        if(ok){\n          adj[v].push_back({enc(ni,nj), dir});\n        }\n      }\n    }\n  }\n\n  // 1. basic Euler tour by DFS (simple, ensures all visited)\n  vector<bool> vis(N*N,false);\n  string basic;\n  function<void(int)> dfs = [&](int v){\n    vis[v]=true;\n    auto [i,j]=dec(v);\n    for(auto [u,dir]: adj[v]){\n      if(!vis[u]){\n        basic += DC[dir];\n        dfs(u);\n        basic += DC[dir^2]; // back\n      }\n    }\n  };\n  dfs(0);\n  // basic is already closed at (0,0)\n\n  // 2. enumerate small cycles (length <= 10) for each node\n  const int MAXCYCLE=10;\n  vector<vector<array<int,2>>> cycles(N*N); // cycles[v] = list of {start_index_in_basic, cycle_length}\n  // but we need actual cycle sequences to insert\n  // instead, we precompute for each node v: list of cycles (as string) that start from v and return to v with length <= MAXCYCLE\n  vector<vector<string>> nodeCycles(N*N);\n  vector<int> dist(N*N), parent(N*N), parDir(N*N);\n  for(int sv=0; sv<N*N; sv++){\n    fill(dist.begin(), dist.end(), -1);\n    dist[sv]=0;\n    queue<int> q; q.push(sv);\n    while(!q.empty()){\n      int v=q.front(); q.pop();\n      if(dist[v]>=MAXCYCLE) continue;\n      for(auto [u,dir]: adj[v]){\n        if(dist[u]==-1){\n          dist[u]=dist[v]+1;\n          parent[u]=v;\n          parDir[u]=dir;\n          q.push(u);\n        }\n        // found back to sv\n        if(u==sv && dist[v]+1>=2 && dist[v]+1<=MAXCYCLE){\n          // reconstruct\n          string cyc;\n          int x=v;\n          int len=dist[v]+1;\n          while(x!=sv){\n            cyc += DC[parDir[x]];\n            x = parent[x];\n          }\n          // we are at sv, but we need to close the cycle\n          // last step from v to sv is by 'dir'\n          // but we already have full path\n          // actually we don't need to push last dir, because we are already at sv\n          // the cycle string is cyc (from sv to v) and then one more step dir\n          cyc += DC[dir];\n          // this cycle starts/ends at sv, length = len\n          nodeCycles[sv].push_back(cyc);\n        }\n      }\n    }\n  }\n\n  // 3. compute efficiency = (sum of d on cycle vertices) / (cycle length)\n  vector<tuple<double,int,int,string>> effCycles; // (eff, node, index_in_nodeCycles, cycle_string)\n  for(int v=0;v<N*N;v++){\n    auto [i0,j0]=dec(v);\n    for(auto& cyc: nodeCycles[v]){\n      set<int> verts;\n      int u=v;\n      verts.insert(u);\n      for(char ch: cyc){\n        int dir = string(\"DRUL\").find(ch);\n        auto [i,j]=dec(u);\n        int ni=i+DI[dir], nj=j+DJ[dir];\n        u = enc(ni,nj);\n        verts.insert(u);\n      }\n      long long sd=0;\n      for(int x: verts){\n        auto [i,j]=dec(x);\n        sd += d[i][j];\n      }\n      double eff = (double)sd / (double)cyc.size();\n      effCycles.emplace_back(eff, v, 0, cyc);\n    }\n  }\n  // sort by eff desc\n  sort(effCycles.rbegin(), effCycles.rend());\n\n  // 4. try to insert high-eff cycles into basic as many as possible\n  // we can do: for each occurrence of v in basic, we can insert cycle there\n  // but we do greedy: take highest eff, and insert as many as possible within budget\n  const int LMAX = 100000;\n  int budget = LMAX - (int)basic.size();\n  string route = basic;\n  // we need to know positions of each node in route\n  // but route will be extended dynamically -> we do offline: precompute positions in basic, and insertions\n  // instead, we do simple: for each cycle in effCycles, try to insert at first occurrence of node\n  vector<int> posInBasic(N*N, -1);\n  {\n    int u=0;\n    posInBasic[u]=0;\n    for(int i=0;i<(int)basic.size();i++){\n      char ch=basic[i];\n      int dir=string(\"DRUL\").find(ch);\n      auto [x,y]=dec(u);\n      int nx=x+DI[dir], ny=y+DJ[dir];\n      u = enc(nx,ny);\n      if(posInBasic[u]==-1) posInBasic[u]=i+1;\n    }\n  }\n  // now for each cycle, if node v appears in basic, we can insert at posInBasic[v]\n  // we do greedy: for each cycle, insert as many as possible at that position\n  for(auto& [eff, v, dummy, cyc]: effCycles){\n    if(budget <=0) break;\n    int p = posInBasic[v];\n    if(p==-1) continue;\n    int len = cyc.size();\n    int maxrep = budget / len;\n    if(maxrep<=0) continue;\n    string add;\n    for(int t=0;t<maxrep;t++) add += cyc;\n    // insert at p\n    route.insert(p, add);\n    budget -= maxrep * len;\n  }\n\n  // 5. ensure we are back at (0,0) and length <= 1e5\n  // our basic was closed, and inserted cycles are closed, so whole route is closed\n  if(route.size() > LMAX){\n    route.resize(LMAX);\n  }\n  cout << route << endl;\n\n  return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\nint N, M;\nint si, sj;\narray<array<char, 15>, 15> A;\nvector<string> t(200);\nvector<int> perm;          // order in which we will embed the keywords\n\n// for each letter c, store all positions that contain c\nvector<pair<int, int>> pos[26];\n\n// shortest path length on grid between any two letters\nint distLetter[26][26];\n\n// precompute shortest paths between any cell and any letter\nvoid buildDistLetter() {\n    for (int c = 0; c < 26; c++) {\n        static int d[15][15];\n        for (int i = 0; i < 15; i++)\n            for (int j = 0; j < 15; j++) d[i][j] = INF;\n        queue<pair<int, int>> q;\n        for (auto [i, j] : pos[c]) {\n            d[i][j] = 0;\n            q.emplace(i, j);\n        }\n        int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1};\n        while (!q.empty()) {\n            auto [i, j] = q.front(); q.pop();\n            for (int dir = 0; dir < 4; dir++) {\n                int ni = i + dx[dir], nj = j + dy[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                if (d[ni][nj] > d[i][j] + 1) {\n                    d[ni][nj] = d[i][j] + 1;\n                    q.emplace(ni, nj);\n                }\n            }\n        }\n        for (int c2 = 0; c2 < 26; c2++) {\n            int best = INF;\n            for (auto [i, j] : pos[c2]) best = min(best, d[i][j]);\n            distLetter[c][c2] = best;\n        }\n    }\n}\n\n// overlap length between two strings (suffix of a == prefix of b)\nint overlap(const string& a, const string& b) {\n    int maxo = 0;\n    int al = a.size(), bl = b.size();\n    int lim = min(al, bl);\n    for (int o = 1; o <= lim; o++) {\n        bool ok = true;\n        for (int i = 0; i < o; i++)\n            if (a[al - o + i] != b[i]) { ok = false; break; }\n        if (ok) maxo = o;\n    }\n    return maxo;\n}\n\n// greedy maximum overlap ordering, tie-break by actual movement cost\nvoid greedyOrder() {\n    perm.resize(M);\n    for (int i = 0; i < M; i++) perm[i] = i;\n    vector<bool> used(M, false);\n    vector<int> ord;\n    ord.reserve(M);\n    ord.push_back(0);\n    used[0] = true;\n    while ((int)ord.size() < M) {\n        int best = -1, besto = -1, bestcost = INF;\n        int lasti = ord.back();\n        char lastc = t[lasti].back();\n        for (int i = 0; i < M; i++)\n            if (!used[i]) {\n                int o = overlap(t[lasti], t[i]);\n                char fc = t[i][0];\n                int cst = distLetter[lastc - 'A'][fc - 'A'] + 1;\n                if (o > besto || (o == besto && cst < bestcost)) {\n                    besto = o;\n                    bestcost = cst;\n                    best = i;\n                }\n            }\n        ord.push_back(best);\n        used[best] = true;\n    }\n    perm = ord;\n}\n\n// predecessor grid for each letter c\narray<array<pair<int, int>, 15>, 15> pred[26];\nvoid buildPred() {\n    for (int c = 0; c < 26; c++) {\n        static int d[15][15];\n        for (int i = 0; i < 15; i++)\n            for (int j = 0; j < 15; j++) d[i][j] = INF;\n        queue<pair<int, int>> q;\n        for (auto [i, j] : pos[c]) {\n            d[i][j] = 0;\n            pred[c][i][j] = {-1, -1};\n            q.emplace(i, j);\n        }\n        int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1};\n        while (!q.empty()) {\n            auto [i, j] = q.front(); q.pop();\n            for (int dir = 0; dir < 4; dir++) {\n                int ni = i + dx[dir], nj = j + dy[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                if (d[ni][nj] > d[i][j] + 1) {\n                    d[ni][nj] = d[i][j] + 1;\n                    pred[c][ni][nj] = {i, j};\n                    q.emplace(ni, nj);\n                }\n            }\n        }\n    }\n}\n\n// global path we are going to output\nvector<pair<int, int>> outPath;\nint curi, curj;\n\nvoid appendMove(int ti, int tj) {\n    static int d[15][15];\n    static pair<int, int> p[15][15];\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) d[i][j] = INF;\n    queue<pair<int, int>> q;\n    d[curi][curj] = 0;\n    q.emplace(curi, curj);\n    int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1};\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        if (i == ti && j == tj) break;\n        for (int dir = 0; dir < 4; dir++) {\n            int ni = i + dx[dir], nj = j + dy[dir];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            if (d[ni][nj] > d[i][j] + 1) {\n                d[ni][nj] = d[i][j] + 1;\n                p[ni][nj] = {i, j};\n                q.emplace(ni, nj);\n            }\n        }\n    }\n    vector<pair<int, int>> tmp;\n    auto cur = make_pair(ti, tj);\n    while (cur.first != curi || cur.second != curj) {\n        tmp.push_back(cur);\n        cur = p[cur.first][cur.second];\n    }\n    reverse(tmp.begin(), tmp.end());\n    for (auto [i, j] : tmp) outPath.emplace_back(i, j);\n    curi = ti;\n    curj = tj;\n}\n\nvoid spell(const string& s) {\n    for (char c : s) {\n        int cc = c - 'A';\n        int best = INF;\n        pair<int, int> tgt;\n        for (auto [i, j] : pos[cc]) {\n            int md = abs(i - curi) + abs(j - curj);\n            if (md < best) {\n                best = md;\n                tgt = {i, j};\n            }\n        }\n        appendMove(tgt.first, tgt.second);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M;\n    cin >> si >> sj;\n    for (int i = 0; i < N; i++) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < N; j++) {\n            A[i][j] = row[j];\n            pos[A[i][j] - 'A'].emplace_back(i, j);\n        }\n    }\n    for (int k = 0; k < M; k++) cin >> t[k];\n    buildDistLetter();\n    buildPred();\n    greedyOrder();\n\n    curi = si;\n    curj = sj;\n    outPath.clear();\n\n    for (int k = 0; k < M; k++) {\n        int id = perm[k];\n        const string& w = t[id];\n        if (k == 0) {\n            spell(w);\n        } else {\n            int previd = perm[k - 1];\n            const string& prevw = t[previd];\n            int o = overlap(prevw, w);\n            if (o == 0) {\n                spell(w);\n            } else {\n                string suffix = w.substr(o);\n                spell(suffix);\n            }\n        }\n    }\n\n    // -----  FIXED: do NOT print the size  -----\n    for (auto [i, j] : outPath) cout << i << ' ' << j << '\\n';\n    return 0;\n}","ahc030":"#include <iostream>\n#include <vector>\n#include <random>\n#include <algorithm>\n#include <cmath>\n#include <set>\n#include <map>\n#include <queue>\n\nusing namespace std;\n\nstruct Point {\n    int i, j;\n    Point(int i = 0, int j = 0) : i(i), j(j) {}\n    bool operator<(const Point& other) const {\n        if (i != other.i) return i < other.i;\n        return j < other.j;\n    }\n    bool operator==(const Point& other) const {\n        return i == other.i && j == other.j;\n    }\n};\n\nint N, M;\ndouble eps;\nvector<vector<Point>> oil_fields;\nvector<vector<int>> true_grid;\nvector<vector<bool>> drilled;\nvector<vector<int>> drilled_values;\nvector<vector<double>> belief;\nset<Point> candidates;\nmt19937 rng(42);\n\n// Query functions\nint drill(int i, int j) {\n    cout << \"q 1 \" << i << \" \" << j << endl;\n    int response;\n    cin >> response;\n    return response;\n}\n\nint divine(const vector<Point>& points) {\n    cout << \"q \" << points.size();\n    for (const auto& p : points) {\n        cout << \" \" << p.i << \" \" << p.j;\n    }\n    cout << endl;\n    int response;\n    cin >> response;\n    return response;\n}\n\nbool answer(const set<Point>& answer_points) {\n    cout << \"a \" << answer_points.size();\n    for (const auto& p : answer_points) {\n        cout << \" \" << p.i << \" \" << p.j;\n    }\n    cout << endl;\n    int response;\n    cin >> response;\n    return response == 1;\n}\n\n// Initialize data structures\nvoid initialize() {\n    cin >> N >> M >> eps;\n    oil_fields.resize(M);\n    drilled.assign(N, vector<bool>(N, false));\n    drilled_values.assign(N, vector<int>(N, 0));\n    belief.assign(N, vector<double>(N, 0.5));\n    \n    for (int k = 0; k < M; k++) {\n        int d;\n        cin >> d;\n        oil_fields[k].resize(d);\n        for (int i = 0; i < d; i++) {\n            cin >> oil_fields[k][i].i >> oil_fields[k][i].j;\n        }\n    }\n    \n    // Initialize all squares as candidates\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            candidates.insert(Point(i, j));\n        }\n    }\n}\n\n// Get all possible positions for an oil field\nvector<Point> get_possible_positions(const vector<Point>& field) {\n    vector<Point> positions;\n    int max_i = 0, max_j = 0;\n    for (const auto& p : field) {\n        max_i = max(max_i, p.i);\n        max_j = max(max_j, p.j);\n    }\n    \n    for (int di = 0; di + max_i < N; di++) {\n        for (int dj = 0; dj + max_j < N; dj++) {\n            positions.push_back(Point(di, dj));\n        }\n    }\n    return positions;\n}\n\n// Check if an oil field at position covers square (i,j)\nbool covers(const vector<Point>& field, int pos_i, int pos_j, int i, int j) {\n    for (const auto& p : field) {\n        if (pos_i + p.i == i && pos_j + p.j == j) {\n            return true;\n        }\n    }\n    return false;\n}\n\n// Update beliefs based on drilling result\nvoid update_belief_drill(int i, int j, int value) {\n    drilled[i][j] = true;\n    drilled_values[i][j] = value;\n    \n    if (value > 0) {\n        belief[i][j] = 1.0;\n        // Increase belief for neighboring squares\n        for (int di = -1; di <= 1; di++) {\n            for (int dj = -1; dj <= 1; dj++) {\n                int ni = i + di, nj = j + dj;\n                if (ni >= 0 && ni < N && nj >= 0 && nj < N && !drilled[ni][nj]) {\n                    belief[ni][nj] = min(1.0, belief[ni][nj] + 0.1);\n                }\n            }\n        }\n    } else {\n        belief[i][j] = 0.0;\n    }\n}\n\n// Update beliefs based on divination result\nvoid update_belief_divine(const vector<Point>& points, int observed_sum) {\n    double expected_sum = 0;\n    for (const auto& p : points) {\n        expected_sum += belief[p.i][p.j];\n    }\n    \n    double ratio = observed_sum / max(expected_sum, 0.1);\n    for (const auto& p : points) {\n        if (!drilled[p.i][p.j]) {\n            belief[p.i][p.j] = min(1.0, max(0.0, belief[p.i][p.j] * ratio));\n        }\n    }\n}\n\n// Select squares for divination based on current beliefs\nvector<Point> select_divination_squares(int num_squares) {\n    vector<pair<double, Point>> scored_points;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (!drilled[i][j]) {\n                double score = belief[i][j] * (1 - belief[i][j]); // Uncertainty\n                scored_points.push_back({score, Point(i, j)});\n            }\n        }\n    }\n    \n    sort(scored_points.rbegin(), scored_points.rend());\n    \n    vector<Point> selected;\n    for (int i = 0; i < min(num_squares, (int)scored_points.size()); i++) {\n        selected.push_back(scored_points[i].second);\n    }\n    \n    return selected;\n}\n\n// Select best square to drill\nPoint select_drill_square() {\n    double best_score = -1;\n    Point best_square;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (!drilled[i][j]) {\n                double score = belief[i][j];\n                // Bonus for strategic positions\n                if (i > 0 && j > 0 && i < N-1 && j < N-1) {\n                    score *= 1.1; // Prefer interior squares\n                }\n                if (score > best_score) {\n                    best_score = score;\n                    best_square = Point(i, j);\n                }\n            }\n        }\n    }\n    \n    return best_square;\n}\n\n// Make final guess based on current information\nset<Point> make_guess() {\n    set<Point> guess;\n    \n    // Include all drilled squares with oil\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (drilled[i][j] && drilled_values[i][j] > 0) {\n                guess.insert(Point(i, j));\n            }\n        }\n    }\n    \n    // Add high-belief squares\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (!drilled[i][j] && belief[i][j] > 0.7) {\n                guess.insert(Point(i, j));\n            }\n        }\n    }\n    \n    return guess;\n}\n\nint main() {\n    initialize();\n    \n    int operations = 0;\n    const int max_operations = 2 * N * N;\n    \n    // Phase 1: Initial divination to get coarse estimates\n    int divination_size = min(25, N * N / 4);\n    for (int phase = 0; phase < 3 && operations < max_operations; phase++) {\n        auto squares = select_divination_squares(divination_size);\n        if (squares.size() < 2) break;\n        \n        int result = divine(squares);\n        operations++;\n        update_belief_divine(squares, result);\n    }\n    \n    // Phase 2: Strategic drilling\n    while (operations < max_operations - 10) {\n        Point drill_square = select_drill_square();\n        int value = drill(drill_square.i, drill_square.j);\n        operations++;\n        update_belief_drill(drill_square.i, drill_square.j, value);\n        \n        // Occasionally use divination to refine beliefs\n        if (operations % 10 == 0) {\n            auto squares = select_divination_squares(min(16, (int)candidates.size()));\n            if (squares.size() >= 2) {\n                int result = divine(squares);\n                operations++;\n                update_belief_divine(squares, result);\n            }\n        }\n    }\n    \n    // Final guess\n    auto final_guess = make_guess();\n    if (answer(final_guess)) {\n        return 0;\n    }\n    \n    // If wrong, drill remaining high-belief squares\n    for (int i = 0; i < N && operations < max_operations; i++) {\n        for (int j = 0; j < N && operations < max_operations; j++) {\n            if (!drilled[i][j] && belief[i][j] > 0.5) {\n                int value = drill(i, j);\n                operations++;\n                update_belief_drill(i, j, value);\n            }\n        }\n    }\n    \n    // Final attempt\n    final_guess = make_guess();\n    answer(final_guess);\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nstatic const int W = 1000;\nint D, N;\nvector<vector<int>> a;\n\n// partition bitsets: 1 = partition exists\n// Hseg[i][j] : horizontal segment at row i, columns j..j+1  (i in [1,W-1], j in [0,W-1])\n// Vseg[i][j] : vertical   segment at col j, rows i..i+1    (i in [0,W-1], j in [1,W-1])\nbitset<W> Hseg[W], Vseg[W];\n\nstruct Rect {\n    int i0, j0, i1, j1;\n    int area() const { return (i1 - i0) * (j1 - j0); }\n};\n\n// output rectangles per day\nvector<vector<Rect>> outRect;\n\n// compute partition-change cost versus previous day\nint computeLd(const vector<Rect>& rects) {\n    // new partition maps\n    bitset<W> nH[W], nV[W];\n    for (const auto& r : rects) {\n        int i0 = r.i0, j0 = r.j0, i1 = r.i1, j1 = r.j1;\n        // top edge\n        if (i0 > 0)      for (int j = j0; j < j1; ++j) nH[i0].set(j);\n        // bottom edge\n        if (i1 < W)      for (int j = j0; j < j1; ++j) nH[i1].set(j);\n        // left edge\n        if (j0 > 0)      for (int i = i0; i < i1; ++i) nV[i].set(j0);\n        // right edge\n        if (j1 < W)      for (int i = i0; i < i1; ++i) nV[i].set(j1);\n    }\n    int cost = 0;\n    for (int i = 1; i < W; ++i) {\n        auto diff = Hseg[i] ^ nH[i];\n        cost += diff.count();\n    }\n    for (int j = 1; j < W; ++j) {\n        bitset<W> diff;\n        for (int i = 0; i < W; ++i) diff[i] = Vseg[i][j] ^ nV[i][j];\n        cost += diff.count();\n    }\n    return cost;\n}\n\n// assign rectangles for one day\nvoid solveDay(int d) {\n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    // largest first\n    sort(ord.begin(), ord.end(), [&](int x, int y) {\n        return a[d][x] > a[d][y];\n    });\n\n    // free rectangles\n    vector<Rect> freeList = { {0, 0, W, W} };\n    vector<Rect> assigned(N);\n\n    auto bestSplit = [&](const Rect& hole, int need,\n                         int& bestCost, Rect& bestA, Rect& bestB, bool& bestIsHoriz) {\n        bestCost = INT_MAX;\n        int h = hole.i1 - hole.i0;\n        int w = hole.j1 - hole.j0;\n        // try horizontal split: i0..cut and cut..i1\n        if (h > 1) {\n            int cutLo = hole.i0 + 1;\n            int cutHi = hole.i1 - 1;\n            int step = max(1, (cutHi - cutLo + 1) / 20);\n            for (int cut = cutLo; cut <= cutHi; cut += step) {\n                Rect A = { hole.i0, hole.j0, cut,     hole.j1 };\n                Rect B = { cut,     hole.j0, hole.i1, hole.j1 };\n                if (A.area() < need) continue;\n                // compute extra partition cost\n                int c = 0;\n                // new horizontal segment at 'cut'\n                for (int j = hole.j0; j < hole.j1; ++j) {\n                    bool old = Hseg[cut][j];\n                    if (!old) c++;\n                }\n                if (c < bestCost) {\n                    bestCost = c;\n                    bestA = A;\n                    bestB = B;\n                    bestIsHoriz = true;\n                }\n            }\n        }\n        // try vertical split\n        if (w > 1) {\n            int cutLo = hole.j0 + 1;\n            int cutHi = hole.j1 - 1;\n            int step = max(1, (cutHi - cutLo + 1) / 20);\n            for (int cut = cutLo; cut <= cutHi; cut += step) {\n                Rect A = { hole.i0, hole.j0, hole.i1, cut };\n                Rect B = { hole.i0, cut,     hole.i1, hole.j1 };\n                if (A.area() < need) continue;\n                int c = 0;\n                for (int i = hole.i0; i < hole.i1; ++i) {\n                    bool old = Vseg[i][cut];\n                    if (!old) c++;\n                }\n                if (c < bestCost) {\n                    bestCost = c;\n                    bestA = A;\n                    bestB = B;\n                    bestIsHoriz = false;\n                }\n            }\n        }\n    };\n\n    for (int k : ord) {\n        int need = a[d][k];\n        int bestCost = INT_MAX;\n        Rect bestA, bestB;\n        bool bestIsHoriz = false;\n        int bestIdx = -1;\n        for (int idx = 0; idx < (int)freeList.size(); ++idx) {\n            const Rect& hole = freeList[idx];\n            if (hole.area() < need) continue;\n            int c; Rect A, B; bool ih;\n            bestSplit(hole, need, c, A, B, ih);\n            if (c < bestCost) {\n                bestCost = c;\n                bestA = A;\n                bestB = B;\n                bestIsHoriz = ih;\n                bestIdx = idx;\n            }\n        }\n        assert(bestIdx != -1);\n        assigned[k] = bestA;\n        freeList[bestIdx] = bestB;\n    }\n\n    // store output order\n    outRect[d] = assigned;\n\n    // update global partition maps for next day\n    for (int i = 0; i < W; ++i) Hseg[i].reset();\n    for (int j = 0; j < W; ++j) Vseg[j].reset();\n    for (const auto& r : assigned) {\n        int i0 = r.i0, j0 = r.j0, i1 = r.i1, j1 = r.j1;\n        if (i0 > 0)      for (int j = j0; j < j1; ++j) Hseg[i0].set(j);\n        if (i1 < W)      for (int j = j0; j < j1; ++j) Hseg[i1].set(j);\n        if (j0 > 0)      for (int i = i0; i < i1; ++i) Vseg[i].set(j0);\n        if (j1 < W)      for (int i = i0; i < i1; ++i) Vseg[i].set(j1);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> W >> D >> N;\n    a.assign(D, vector<int>(N));\n    for (int d = 0; d < D; ++d)\n        for (int k = 0; k < N; ++k)\n            cin >> a[d][k];\n\n    outRect.assign(D, vector<Rect>(N));\n\n    // initialize partitions: none\n    for (int i = 0; i < W; ++i) {\n        Hseg[i].reset();\n        Vseg[i].reset();\n    }\n\n    for (int d = 0; d < D; ++d) {\n        solveDay(d);\n    }\n\n    // output\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            const auto& r = outRect[d][k];\n            cout << r.i0 << ' ' << r.j0 << ' ' << r.i1 << ' ' << r.j1 << '\\n';\n        }\n    }\n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <tuple>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\nconst int MOD = 998244353;\nconst int N = 9;\nconst int M = 20;\nconst int K = 81;\n\nint board[N][N];\nint stamps[M][3][3];\nint temp_board[N][N];\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint compute_marginal(int m, int p, int q) {\n    int gain = 0;\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            int original = board[p + i][q + j] % MOD;\n            int new_val = (board[p + i][q + j] + stamps[m][i][j]) % MOD;\n            gain += new_val - original;\n        }\n    }\n    return gain;\n}\n\nvoid apply_stamp(int m, int p, int q) {\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            board[p + i][q + j] = (board[p + i][q + j] + stamps[m][i][j]) % MOD;\n        }\n    }\n}\n\nvoid revert_stamp(int m, int p, int q) {\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            board[p + i][q + j] = (board[p + i][q + j] - stamps[m][i][j] % MOD + MOD) % MOD;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n, m, k;\n    cin >> n >> m >> k;\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cin >> board[i][j];\n        }\n    }\n    for (int mm = 0; mm < m; ++mm) {\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                cin >> stamps[mm][i][j];\n            }\n        }\n    }\n\n    vector<tuple<int, int, int>> operations;\n\n    for (int step = 0; step < k; ++step) {\n        vector<tuple<int, int, int, int>> candidates; // (gain, m, p, q)\n        for (int mm = 0; mm < m; ++mm) {\n            for (int p = 0; p <= n - 3; ++p) {\n                for (int q = 0; q <= n - 3; ++q) {\n                    int gain = compute_marginal(mm, p, q);\n                    candidates.emplace_back(gain, mm, p, q);\n                }\n            }\n        }\n\n        sort(candidates.rbegin(), candidates.rend());\n        bool found = false;\n\n        // Try top 10 candidates with lookahead 2\n        for (int attempt = 0; attempt < min(10, (int)candidates.size()); ++attempt) {\n            auto [gain1, m1, p1, q1] = candidates[attempt];\n            if (gain1 <= 0 && attempt > 0) break;\n\n            apply_stamp(m1, p1, q1);\n\n            // Lookahead: find best second step\n            int best_gain2 = -1e9;\n            int best_m2 = -1, best_p2 = -1, best_q2 = -1;\n            for (int mm = 0; mm < m; ++mm) {\n                for (int p = 0; p <= n - 3; ++p) {\n                    for (int q = 0; q <= n - 3; ++q) {\n                        int gain2 = compute_marginal(mm, p, q);\n                        if (gain2 > best_gain2) {\n                            best_gain2 = gain2;\n                            best_m2 = mm;\n                            best_p2 = p;\n                            best_q2 = q;\n                        }\n                    }\n                }\n            }\n\n            if (gain1 + best_gain2 > 0) {\n                operations.emplace_back(m1, p1, q1);\n                found = true;\n                break;\n            } else {\n                revert_stamp(m1, p1, q1);\n            }\n        }\n\n        if (!found) {\n            // Random exploration\n            uniform_int_distribution<int> dist_m(0, m - 1);\n            uniform_int_distribution<int> dist_p(0, n - 3);\n            uniform_int_distribution<int> dist_q(0, n - 3);\n            int m_rand = dist_m(rng);\n            int p_rand = dist_p(rng);\n            int q_rand = dist_q(rng);\n            operations.emplace_back(m_rand, p_rand, q_rand);\n            apply_stamp(m_rand, p_rand, q_rand);\n        }\n    }\n\n    cout << operations.size() << '\\n';\n    for (auto [mm, p, q] : operations) {\n        cout << mm << ' ' << p << ' ' << q << '\\n';\n    }\n\n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <string>\n#include <queue>\n#include <set>\n\nusing namespace std;\n\nconst int MAX_N = 5;\nconst int MAX_TURNS = 10000;\n\nint N;\nint A[MAX_N][MAX_N];\nvector<string> operations(MAX_N);\n\n// Current state\nint grid[MAX_N][MAX_N];  // -1 if empty, otherwise container number\nint crane_pos[MAX_N][2];  // crane positions: [crane_id][x,y]\nbool crane_carry[MAX_N];  // whether crane is carrying\nint crane_container[MAX_N];  // container being carried (-1 if none)\nbool crane_alive[MAX_N];\n\n// Target dispatch information\nint target_gate(int container) {\n    return container / N;\n}\n\nbool is_correct_container_for_gate(int gate, int container) {\n    return container >= gate * N && container < (gate + 1) * N;\n}\n\n// Check if move is valid for crane\nbool can_move(int crane_id, int dx, int dy) {\n    if (!crane_alive[crane_id]) return false;\n    \n    int new_x = crane_pos[crane_id][0] + dx;\n    int new_y = crane_pos[crane_id][1] + dy;\n    \n    if (new_x < 0 || new_x >= N || new_y < 0 || new_y >= N) return false;\n    \n    // Check crane collision\n    for (int i = 0; i < N; i++) {\n        if (i != crane_id && crane_alive[i] && \n            crane_pos[i][0] == new_x && crane_pos[i][1] == new_y) {\n            return false;\n        }\n    }\n    \n    // Small crane carrying cannot move to occupied square\n    if (crane_id > 0 && crane_carry[crane_id] && grid[new_x][new_y] != -1) {\n        return false;\n    }\n    \n    return true;\n}\n\n// Simple pathfinding for crane movement\nvector<char> find_path(int crane_id, int target_x, int target_y) {\n    vector<char> path;\n    int x = crane_pos[crane_id][0];\n    int y = crane_pos[crane_id][1];\n    \n    while (x != target_x || y != target_y) {\n        int dx = 0, dy = 0;\n        char move_char = '.';\n        \n        if (x < target_x) { dx = 1; move_char = 'D'; }\n        else if (x > target_x) { dx = -1; move_char = 'U'; }\n        else if (y < target_y) { dy = 1; move_char = 'R'; }\n        else if (y > target_y) { dy = -1; move_char = 'L'; }\n        \n        if (can_move(crane_id, dx, dy)) {\n            path.push_back(move_char);\n            x += dx;\n            y += dy;\n        } else {\n            // Try alternative moves\n            bool moved = false;\n            int alternatives[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}};\n            char alt_chars[4] = {'R', 'L', 'D', 'U'};\n            \n            for (int i = 0; i < 4 && !moved; i++) {\n                if (alternatives[i][0] != dx || alternatives[i][1] != dy) {\n                    if (can_move(crane_id, alternatives[i][0], alternatives[i][1])) {\n                        path.push_back(alt_chars[i]);\n                        x += alternatives[i][0];\n                        y += alternatives[i][1];\n                        moved = true;\n                    }\n                }\n            }\n            if (!moved) break;\n        }\n        \n        if (path.size() > 50) break; // Safety limit\n    }\n    \n    return path;\n}\n\nvoid simulate_turn(const vector<char>& moves) {\n    // Step 1: Receive containers\n    for (int i = 0; i < N; i++) {\n        if (grid[i][0] == -1 && !crane_carry[i]) {\n            // Find next container for this gate\n            static int received_count[MAX_N] = {0};\n            if (received_count[i] < N) {\n                grid[i][0] = A[i][received_count[i]];\n                received_count[i]++;\n            }\n        }\n    }\n    \n    // Step 2: Execute crane moves\n    for (int i = 0; i < N; i++) {\n        if (i < moves.size() && crane_alive[i]) {\n            char move = moves[i];\n            \n            if (move == 'P') {\n                if (!crane_carry[i] && grid[crane_pos[i][0]][crane_pos[i][1]] != -1) {\n                    crane_carry[i] = true;\n                    crane_container[i] = grid[crane_pos[i][0]][crane_pos[i][1]];\n                    grid[crane_pos[i][0]][crane_pos[i][1]] = -1;\n                }\n            } else if (move == 'Q') {\n                if (crane_carry[i] && grid[crane_pos[i][0]][crane_pos[i][1]] == -1) {\n                    crane_carry[i] = false;\n                    grid[crane_pos[i][0]][crane_pos[i][1]] = crane_container[i];\n                    crane_container[i] = -1;\n                }\n            } else if (move == 'U' && can_move(i, -1, 0)) {\n                crane_pos[i][0]--;\n            } else if (move == 'D' && can_move(i, 1, 0)) {\n                crane_pos[i][0]++;\n            } else if (move == 'L' && can_move(i, 0, -1)) {\n                crane_pos[i][1]--;\n            } else if (move == 'R' && can_move(i, 0, 1)) {\n                crane_pos[i][1]++;\n            } else if (move == 'B') {\n                if (!crane_carry[i]) {\n                    crane_alive[i] = false;\n                }\n            }\n        }\n    }\n    \n    // Step 3: Dispatch containers\n    for (int i = 0; i < N; i++) {\n        if (grid[i][N-1] != -1) {\n            grid[i][N-1] = -1; // Container dispatched\n        }\n    }\n}\n\nint main() {\n    cin >> N;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> A[i][j];\n        }\n    }\n    \n    // Initialize state\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = -1;\n        }\n        crane_pos[i][0] = i;\n        crane_pos[i][1] = 0;\n        crane_carry[i] = false;\n        crane_container[i] = -1;\n        crane_alive[i] = true;\n        operations[i] = \"\";\n    }\n    \n    // Simple strategy: Use large crane to collect and sort containers\n    // Small cranes help with local operations\n    \n    int turns = 0;\n    const int max_turns = 8000; // Leave some buffer\n    \n    while (turns < max_turns) {\n        vector<char> current_moves(N, '.');\n        \n        // Large crane (index 0) strategy: collect containers and move to sorting area\n        if (crane_alive[0]) {\n            int x = crane_pos[0][0];\n            int y = crane_pos[0][1];\n            \n            if (!crane_carry[0]) {\n                // Try to pick up container\n                if (grid[x][y] != -1) {\n                    current_moves[0] = 'P';\n                } else {\n                    // Move to find containers\n                    if (y < N-2) {\n                        current_moves[0] = 'R';\n                    } else if (x < N-1) {\n                        current_moves[0] = 'D';\n                    } else {\n                        current_moves[0] = 'U';\n                    }\n                }\n            } else {\n                // Carrying container - move to appropriate area\n                int container = crane_container[0];\n                int target_gate = target_gate(container);\n                \n                // Move toward target gate's column, but stay in middle rows for sorting\n                if (y < N-1) {\n                    current_moves[0] = 'R';\n                } else if (x != target_gate) {\n                    current_moves[0] = (x < target_gate) ? 'D' : 'U';\n                } else {\n                    // At target gate row, place container\n                    current_moves[0] = 'Q';\n                }\n            }\n        }\n        \n        // Small cranes: assist with local operations\n        for (int i = 1; i < N; i++) {\n            if (!crane_alive[i]) continue;\n            \n            int x = crane_pos[i][0];\n            int y = crane_pos[i][1];\n            \n            // Simple behavior: help move containers toward right\n            if (!crane_carry[i]) {\n                if (grid[x][y] != -1) {\n                    current_moves[i] = 'P';\n                } else if (y < N-1) {\n                    current_moves[i] = 'R';\n                }\n            } else {\n                if (y < N-1) {\n                    current_moves[i] = 'R';\n                } else {\n                    current_moves[i] = 'Q';\n                }\n            }\n        }\n        \n        // Execute turn\n        simulate_turn(current_moves);\n        \n        // Record operations\n        for (int i = 0; i < N; i++) {\n            if (turns < operations[i].size() || operations[i].empty()) {\n                operations[i] += current_moves[i];\n            }\n        }\n        \n        turns++;\n        \n        // Check if we should stop (simple heuristic)\n        if (turns > 1000) {\n            bool all_dispatched = true;\n            for (int i = 0; i < N && all_dispatched; i++) {\n                for (int j = 0; j < N && all_dispatched; j++) {\n                    if (grid[i][j] != -1) all_dispatched = false;\n                }\n            }\n            if (all_dispatched) break;\n        }\n    }\n    \n    // Ensure all strings have same length\n    int max_len = 0;\n    for (int i = 0; i < N; i++) {\n        max_len = max(max_len, (int)operations[i].size());\n    }\n    \n    for (int i = 0; i < N; i++) {\n        while (operations[i].size() < max_len) {\n            operations[i] += '.';\n        }\n    }\n    \n    // Output operations\n    for (int i = 0; i < N; i++) {\n        cout << operations[i] << endl;\n    }\n    \n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nint h[20][20];\nvector<string> out;\n\ninline void go(int di, int dj) {\n    if (di > 0) for (int k = 0; k < di; ++k) out.push_back(\"D\");\n    if (di < 0) for (int k = 0; k < -di; ++k) out.push_back(\"U\");\n    if (dj > 0) for (int k = 0; k < dj; ++k) out.push_back(\"R\");\n    if (dj < 0) for (int k = 0; k < -dj; ++k) out.push_back(\"L\");\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> h[i][j];\n\n    vector<tuple<int,int,int>> src, snk;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            if (h[i][j] > 0) src.emplace_back(i, j, h[i][j]);\n            else if (h[i][j] < 0) snk.emplace_back(i, j, -h[i][j]);\n        }\n\n    int ci = 0, cj = 0;\n    // pick-up tour (empty truck)\n    for (auto [si, sj, amt] : src) {\n        go(si - ci, sj - cj);\n        ci = si; cj = sj;\n        out.push_back(\"+\" + to_string(amt));\n    }\n    // delivery tour (nearest first)\n    sort(snk.begin(), snk.end(), [&](auto &a, auto &b) {\n        auto [ai,aj,aa]=a; auto [bi,bj,ba]=b;\n        int da = abs(ai - ci) + abs(aj - cj);\n        int db = abs(bi - ci) + abs(bj - cj);\n        return da < db;\n    });\n    for (auto [si, sj, amt] : snk) {\n        go(si - ci, sj - cj);\n        ci = si; cj = sj;\n        out.push_back(\"-\" + to_string(amt));\n    }\n\n    for (auto &s : out) cout << s << '\\n';\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n\nusing namespace std;\n\nint main() {\n    int N, M, T;\n    cin >> N >> M >> T;\n    \n    const int seed_count = 2 * N * (N - 1);\n    vector<vector<int>> seeds(seed_count, vector<int>(M));\n    \n    // Read initial seeds\n    for (int i = 0; i < seed_count; i++) {\n        for (int j = 0; j < M; j++) {\n            cin >> seeds[i][j];\n        }\n    }\n    \n    for (int turn = 0; turn < T; turn++) {\n        // Simple strategy: just use seeds 0 to N*N-1 in order\n        vector<vector<int>> grid(N, vector<int>(N));\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                grid[i][j] = i * N + j;\n            }\n        }\n        \n        // Output the grid\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << grid[i][j];\n                if (j < N - 1) cout << \" \";\n            }\n            cout << endl;\n        }\n        cout.flush();\n        \n        // Read new seeds\n        for (int i = 0; i < seed_count; i++) {\n            for (int j = 0; j < M; j++) {\n                cin >> seeds[i][j];\n            }\n        }\n    }\n    \n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 30;\nconst int MAX_V = 15;\n\nint N, M, V;\nvector<string> s, t;\nvector<pair<int, int>> sources, targets;\nvector<int> parent;\nvector<int> length;\nint root_x, root_y;\n\n// Find positions of 1s in grid\nvector<pair<int, int>> find_positions(const vector<string>& grid) {\n    vector<pair<int, int>> positions;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] == '1') {\n                positions.push_back({i, j});\n            }\n        }\n    }\n    return positions;\n}\n\n// Design a star-shaped tree with multiple fingertips\nvoid design_arm() {\n    parent.resize(V);\n    length.resize(V);\n    \n    // Create a star shape: root at center, multiple arms\n    int fingertips = min(V - 1, 6); // Use up to 6 fingertips\n    int arm_length = max(1, (N - 1) / 3);\n    \n    for (int i = 1; i <= fingertips; i++) {\n        parent[i] = 0;\n        length[i] = arm_length;\n    }\n    \n    // Add intermediate joints if we have more vertices\n    int used = fingertips + 1;\n    for (int i = used; i < V; i++) {\n        // Attach to existing vertices to create more complex structure\n        parent[i] = (i - used) % fingertips + 1;\n        length[i] = max(1, arm_length / 2);\n    }\n    \n    // Place root near center\n    root_x = N / 2;\n    root_y = N / 2;\n}\n\n// Calculate Manhattan distance\nint manhattan_distance(pair<int, int> a, pair<int, int> b) {\n    return abs(a.first - b.first) + abs(a.second - b.second);\n}\n\n// Find closest available target for a source\npair<int, int> find_closest_target(pair<int, int> source, \n                                  const vector<pair<int, int>>& available_targets) {\n    int best_idx = -1;\n    int best_dist = INT_MAX;\n    \n    for (int i = 0; i < available_targets.size(); i++) {\n        int dist = manhattan_distance(source, available_targets[i]);\n        if (dist < best_dist) {\n            best_dist = dist;\n            best_idx = i;\n        }\n    }\n    \n    return {best_idx, best_dist};\n}\n\n// Simple pathfinding with basic collision avoidance\nvector<string> generate_path(pair<int, int> from, pair<int, int> to, \n                            vector<string>& current_state) {\n    vector<string> path;\n    int x = from.first, y = from.second;\n    int tx = to.first, ty = to.second;\n    \n    while (x != tx || y != ty) {\n        string move(2 * V, '.');\n        \n        // Move horizontally first\n        if (x < tx) {\n            move[0] = 'D';\n            x++;\n        } else if (x > tx) {\n            move[0] = 'U';\n            x--;\n        } else if (y < ty) {\n            move[0] = 'R';\n            y++;\n        } else if (y > ty) {\n            move[0] = 'L';\n            y--;\n        }\n        \n        path.push_back(move);\n    }\n    \n    return path;\n}\n\n// Main solving function\nvector<string> solve() {\n    vector<string> operations;\n    vector<string> current_s = s;\n    vector<pair<int, int>> remaining_sources = sources;\n    vector<pair<int, int>> remaining_targets = targets;\n    \n    // Sort by distance to prioritize closer pairs\n    vector<tuple<int, int, int>> source_target_pairs;\n    for (int i = 0; i < remaining_sources.size(); i++) {\n        auto [target_idx, dist] = find_closest_target(remaining_sources[i], remaining_targets);\n        if (target_idx != -1) {\n            source_target_pairs.push_back({dist, i, target_idx});\n        }\n    }\n    sort(source_target_pairs.begin(), source_target_pairs.end());\n    \n    int turns = 0;\n    const int MAX_TURNS = 100000;\n    \n    for (auto [dist, src_idx, tgt_idx] : source_target_pairs) {\n        if (turns >= MAX_TURNS - 1000) break;\n        \n        auto source = remaining_sources[src_idx];\n        auto target = remaining_targets[tgt_idx];\n        \n        // Move arm to source\n        auto path_to_source = generate_path({root_x, root_y}, source, current_s);\n        for (const auto& move : path_to_source) {\n            operations.push_back(move);\n            turns++;\n            if (turns >= MAX_TURNS) break;\n        }\n        if (turns >= MAX_TURNS) break;\n        \n        // Grab takoyaki\n        string grab_op(2 * V, '.');\n        grab_op[0] = '.'; // No movement\n        // Use first available fingertip\n        for (int i = 1; i < V; i++) {\n            if (parent[i] != -1 && i < V/2 + 1) { // Assume these are fingertips\n                grab_op[V + i] = 'P';\n                break;\n            }\n        }\n        operations.push_back(grab_op);\n        turns++;\n        \n        // Update current state\n        current_s[source.first][source.second] = '0';\n        \n        // Move to target\n        auto path_to_target = generate_path(source, target, current_s);\n        for (const auto& move : path_to_target) {\n            operations.push_back(move);\n            turns++;\n            if (turns >= MAX_TURNS) break;\n        }\n        if (turns >= MAX_TURNS) break;\n        \n        // Release takoyaki\n        string release_op(2 * V, '.');\n        release_op[0] = '.';\n        for (int i = 1; i < V; i++) {\n            if (parent[i] != -1 && i < V/2 + 1) {\n                release_op[V + i] = 'P';\n                break;\n            }\n        }\n        operations.push_back(release_op);\n        turns++;\n        \n        // Update current state\n        current_s[target.first][target.second] = '1';\n        \n        // Remove completed pair\n        remaining_sources.erase(remaining_sources.begin() + src_idx);\n        remaining_targets.erase(remaining_targets.begin() + tgt_idx);\n    }\n    \n    return operations;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> V;\n    \n    s.resize(N);\n    t.resize(N);\n    \n    for (int i = 0; i < N; i++) {\n        cin >> s[i];\n    }\n    for (int i = 0; i < N; i++) {\n        cin >> t[i];\n    }\n    \n    sources = find_positions(s);\n    targets = find_positions(t);\n    \n    // Design and output arm\n    design_arm();\n    \n    cout << V << \"\\n\";\n    for (int i = 1; i < V; i++) {\n        cout << parent[i] << \" \" << length[i] << \"\\n\";\n    }\n    cout << root_x << \" \" << root_y << \"\\n\";\n    \n    // Generate and output operations\n    auto operations = solve();\n    \n    for (const auto& op : operations) {\n        cout << op << \"\\n\";\n    }\n    \n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    Point(int x = 0, int y = 0) : x(x), y(y) {}\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\nstruct Fish {\n    int x, y, type;\n    Fish(int x = 0, int y = 0, int type = 0) : x(x), y(y), type(type) {}\n};\n\nint N;\nvector<Fish> fishes;\nvector<Point> polygon;\n\n// Ray casting algorithm to check if point is inside polygon\nbool pointInPolygon(int x, int y, const vector<Point>& poly) {\n    int n = poly.size();\n    bool inside = false;\n    \n    for (int i = 0, j = n - 1; i < n; j = i++) {\n        if (((poly[i].y > y) != (poly[j].y > y)) &&\n            (x < (poly[j].x - poly[i].x) * (y - poly[i].y) / (poly[j].y - poly[i].y) + poly[i].x)) {\n            inside = !inside;\n        }\n    }\n    return inside;\n}\n\n// Count fish inside actual polygon\npair<int,int> countFishInPolygon(const vector<Point>& poly) {\n    int mackerels = 0, sardines = 0;\n    for (const auto& fish : fishes) {\n        if (pointInPolygon(fish.x, fish.y, poly)) {\n            if (fish.type == 0) mackerels++;\n            else sardines++;\n        }\n    }\n    return {mackerels, sardines};\n}\n\n// Calculate polygon perimeter\nint calculatePerimeter(const vector<Point>& poly) {\n    int perimeter = 0;\n    int n = poly.size();\n    for (int i = 0; i < n; i++) {\n        int j = (i + 1) % n;\n        perimeter += abs(poly[j].x - poly[i].x) + abs(poly[j].y - poly[i].y);\n    }\n    return perimeter;\n}\n\n// Create rectangle polygon\nvector<Point> createRectangle(int x1, int y1, int x2, int y2) {\n    return {Point(x1, y1), Point(x2, y1), Point(x2, y2), Point(x1, y2)};\n}\n\n// Find dense mackerel regions using grid-based approach\nvector<pair<int,int>> findMackerelClusters() {\n    const int GRID_SIZE = 10000;\n    const int GRIDS = 100000 / GRID_SIZE + 1;\n    \n    vector<vector<int>> grid(GRIDS, vector<int>(GRIDS, 0));\n    \n    // Count mackerels in each grid cell\n    for (const auto& fish : fishes) {\n        if (fish.type == 0) {\n            int gx = fish.x / GRID_SIZE;\n            int gy = fish.y / GRID_SIZE;\n            if (gx < GRIDS && gy < GRIDS) {\n                grid[gx][gy]++;\n            }\n        }\n    }\n    \n    // Find top clusters\n    vector<pair<int,int>> clusters;\n    for (int i = 0; i < GRIDS; i++) {\n        for (int j = 0; j < GRIDS; j++) {\n            if (grid[i][j] > 5) { // Threshold for good cluster\n                clusters.push_back({i * GRID_SIZE + GRID_SIZE/2, j * GRID_SIZE + GRID_SIZE/2});\n            }\n        }\n    }\n    \n    return clusters;\n}\n\n// Try to create polygon around cluster\nvector<Point> createClusterPolygon(int cx, int cy, int size) {\n    int half = size / 2;\n    int x1 = max(0, cx - half);\n    int y1 = max(0, cy - half);\n    int x2 = min(100000, cx + half);\n    int y2 = min(100000, cy + half);\n    \n    return createRectangle(x1, y1, x2, y2);\n}\n\n// Optimize polygon by trying different sizes\nvector<Point> optimizeClusterPolygon(const vector<Point>& initial) {\n    vector<Point> best = initial;\n    auto [bestM, bestS] = countFishInPolygon(best);\n    int bestScore = max(0, bestM - bestS + 1);\n    \n    // Try shrinking the polygon\n    for (int shrink = 1000; shrink >= 100; shrink -= 100) {\n        vector<Point> shrunk;\n        int cx = (initial[0].x + initial[2].x) / 2;\n        int cy = (initial[0].y + initial[2].y) / 2;\n        \n        int half = shrink / 2;\n        int x1 = max(0, cx - half);\n        int y1 = max(0, cy - half);\n        int x2 = min(100000, cx + half);\n        int y2 = min(100000, cy + half);\n        \n        auto candidate = createRectangle(x1, y1, x2, y2);\n        auto [m, s] = countFishInPolygon(candidate);\n        int score = max(0, m - s + 1);\n        \n        if (score > bestScore && calculatePerimeter(candidate) <= 400000) {\n            best = candidate;\n            bestScore = score;\n        }\n    }\n    \n    return best;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    \n    // Read fish data\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        fishes.push_back({x, y, 0});\n    }\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        fishes.push_back({x, y, 1});\n    }\n    \n    // Find mackerel clusters\n    auto clusters = findMackerelClusters();\n    \n    if (clusters.empty()) {\n        // Fallback: create large rectangle\n        polygon = createRectangle(0, 0, 100000, 100000);\n    } else {\n        // Start with the best cluster\n        polygon = createClusterPolygon(clusters[0].first, clusters[0].second, 20000);\n        polygon = optimizeClusterPolygon(polygon);\n        \n        // Try to improve by adding more clusters\n        for (int i = 1; i < min(5, (int)clusters.size()); i++) {\n            auto extra = createClusterPolygon(clusters[i].first, clusters[i].second, 15000);\n            auto [m1, s1] = countFishInPolygon(polygon);\n            auto [m2, s2] = countFishInPolygon(extra);\n            \n            // Simple union approach - take bounding box\n            int minx = min(polygon[0].x, extra[0].x);\n            int miny = min(polygon[0].y, extra[0].y);\n            int maxx = max(polygon[2].x, extra[2].x);\n            int maxy = max(polygon[2].y, extra[2].y);\n            \n            auto combined = createRectangle(minx, miny, maxx, maxy);\n            if (calculatePerimeter(combined) <= 400000) {\n                auto [mc, sc] = countFishInPolygon(combined);\n                if (max(0, mc - sc + 1) > max(0, m1 - s1 + 1)) {\n                    polygon = combined;\n                }\n            }\n        }\n    }\n    \n    // Final optimization - try to remove sardine-heavy regions\n    auto [finalM, finalS] = countFishInPolygon(polygon);\n    int finalScore = max(0, finalM - finalS + 1);\n    \n    // Ensure valid output\n    if (polygon.size() < 4) {\n        polygon = createRectangle(0, 0, 100000, 100000);\n    }\n    \n    // Remove consecutive duplicates\n    vector<Point> cleaned;\n    for (int i = 0; i < polygon.size(); i++) {\n        int next = (i + 1) % polygon.size();\n        if (!(polygon[i] == polygon[next])) {\n            cleaned.push_back(polygon[i]);\n        }\n    }\n    polygon = cleaned;\n    \n    if (polygon.size() < 4) {\n        polygon = createRectangle(0, 0, 100000, 100000);\n    }\n    \n    cout << polygon.size() << \"\\n\";\n    for (const auto& p : polygon) {\n        cout << p.x << \" \" << p.y << \"\\n\";\n    }\n    \n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\n#include <random>\n#include <chrono>\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint randint(int a, int b) {\n    return uniform_int_distribution<int>(a, b)(rng);\n}\n\nstruct Rect {\n    long long w, h;\n    int idx;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T, sigma;\n    cin >> N >> T >> sigma;\n    vector<Rect> rects(N);\n    for (int i = 0; i < N; i++) {\n        cin >> rects[i].w >> rects[i].h;\n        rects[i].idx = i;\n    }\n\n    // We'll track the best estimated score\n    long long best_est_score = LLONG_MAX;\n    int best_skip = 0;\n\n    for (int turn = 0; turn < T; turn++) {\n        // Decide how many to skip\n        int skip;\n        if (turn < T * 0.6) {\n            skip = randint(0, N/2);\n        } else {\n            skip = best_skip;\n        }\n\n        // Build skip mask: skip the 'skip' rectangles with largest (w+h)\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int i, int j) {\n            return (rects[i].w + rects[i].h) > (rects[j].w + rects[j].h);\n        });\n        vector<bool> skip_mask(N, false);\n        for (int i = 0; i < skip; i++) {\n            skip_mask[order[i]] = true;\n        }\n\n        // Build list of rectangles to place: in increasing index order\n        vector<int> to_place;\n        for (int i = 0; i < N; i++) {\n            if (!skip_mask[i]) to_place.push_back(i);\n        }\n        int n = to_place.size();\n\n        // We'll simulate placements using noisy sizes\n        vector<long long> xleft(n), ytop(n); // positions\n        vector<long long> width(n), height(n); // actual sizes used (rotated)\n        vector<int> orig_idx(n); // original index\n\n        // Output sequence\n        vector<tuple<int, int, char, int>> seq;\n\n        long long curW = 0, curH = 0;\n\n        for (int i = 0; i < n; i++) {\n            int idx = to_place[i];\n            long long w0 = rects[idx].w;\n            long long h0 = rects[idx].h;\n\n            int best_r = 0;\n            char best_d = 'U';\n            int best_b = -1;\n            long long best_WH = LLONG_MAX;\n\n            // Try several random combinations\n            int tries = 10;\n            for (int t = 0; t < tries; t++) {\n                int r = randint(0, 1);\n                long long wi = (r == 0 ? w0 : h0);\n                long long hi = (r == 0 ? h0 : w0);\n\n                char d = (randint(0,1) ? 'U' : 'L');\n                int b = -1;\n                if (d == 'U') {\n                    // b must be -1 or a previously placed rectangle (index < i)\n                    if (i > 0) {\n                        b = randint(-1, i-1);\n                    } else {\n                        b = -1;\n                    }\n                } else {\n                    if (i > 0) {\n                        b = randint(-1, i-1);\n                    } else {\n                        b = -1;\n                    }\n                }\n\n                // Compute position for this combo\n                long long xi, yi;\n\n                if (d == 'U') {\n                    // x: align left edge to right edge of b (or 0)\n                    if (b == -1) {\n                        xi = 0;\n                    } else {\n                        xi = xleft[b] + width[b];\n                    }\n                    // y: drop from top until hit bottom of someone or y=0\n                    yi = 0;\n                    for (int j = 0; j < i; j++) {\n                        // check overlap in x\n                        long long x1 = xi, x2 = xi + wi;\n                        long long ox1 = xleft[j], ox2 = xleft[j] + width[j];\n                        if (x2 > ox1 && x1 < ox2) {\n                            yi = max(yi, ytop[j] + height[j]);\n                        }\n                    }\n                } else {\n                    // y: align top edge to bottom edge of b (or 0)\n                    if (b == -1) {\n                        yi = 0;\n                    } else {\n                        yi = ytop[b] + height[b];\n                    }\n                    // x: move left until hit right edge of someone or x=0\n                    xi = 0;\n                    for (int j = 0; j < i; j++) {\n                        long long y1 = yi, y2 = yi + hi;\n                        long long oy1 = ytop[j], oy2 = ytop[j] + height[j];\n                        if (y2 > oy1 && y1 < oy2) {\n                            xi = max(xi, xleft[j] + width[j]);\n                        }\n                    }\n                }\n\n                long long newW = max(curW, xi + wi);\n                long long newH = max(curH, yi + hi);\n                long long WH = newW + newH;\n\n                if (WH < best_WH) {\n                    best_WH = WH;\n                    best_r = r;\n                    best_d = d;\n                    best_b = b;\n                }\n            }\n\n            // Now do the best one for real\n            long long wi = (best_r == 0 ? w0 : h0);\n            long long hi = (best_r == 0 ? h0 : w0);\n\n            long long xi, yi;\n            if (best_d == 'U') {\n                if (best_b == -1) {\n                    xi = 0;\n                } else {\n                    xi = xleft[best_b] + width[best_b];\n                }\n                yi = 0;\n                for (int j = 0; j < i; j++) {\n                    long long x1 = xi, x2 = xi + wi;\n                    long long ox1 = xleft[j], ox2 = xleft[j] + width[j];\n                    if (x2 > ox1 && x1 < ox2) {\n                        yi = max(yi, ytop[j] + height[j]);\n                    }\n                }\n            } else {\n                if (best_b == -1) {\n                    yi = 0;\n                } else {\n                    yi = ytop[best_b] + height[best_b];\n                }\n                xi = 0;\n                for (int j = 0; j < i; j++) {\n                    long long y1 = yi, y2 = yi + hi;\n                    long long oy1 = ytop[j], oy2 = ytop[j] + height[j];\n                    if (y2 > oy1 && y1 < oy2) {\n                        xi = max(xi, xleft[j] + width[j]);\n                    }\n                }\n            }\n\n            // Store\n            xleft[i] = xi;\n            ytop[i] = yi;\n            width[i] = wi;\n            height[i] = hi;\n            orig_idx[i] = idx;\n\n            curW = max(curW, xi + wi);\n            curH = max(curH, yi + hi);\n\n            seq.emplace_back(idx, best_r, best_d, best_b);\n        }\n\n        // Output\n        cout << n << \"\\n\";\n        for (auto [p, r, d, b] : seq) {\n            cout << p << \" \" << r << \" \" << d << \" \" << b << \"\\n\";\n        }\n        cout.flush();\n\n        // Read W', H'\n        long long Wp, Hp;\n        cin >> Wp >> Hp;\n\n        // Compute estimated total score\n        long long unused = 0;\n        for (int i = 0; i < N; i++) {\n            if (skip_mask[i]) {\n                unused += rects[i].w + rects[i].h;\n            }\n        }\n        long long est_total = Wp + Hp + unused;\n\n        if (est_total < best_est_score) {\n            best_est_score = est_total;\n            best_skip = skip;\n            // # cerr << \"# New best est: \" << est_total << \" (skip=\" << skip << \")\" << endl;\n            cout << \"# improved: \" << est_total << \" (skip=\" << skip << \")\" << endl;\n        }\n    }\n\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\n#include <atcoder/dsu>\nusing namespace std;\nusing namespace atcoder;\n\nstatic const int MAXN = 1005;\nstatic const int MAXH = 12;\n\nint N, M, H;\nint A[MAXN];\nvector<int> G[MAXN];\nint par[MAXN];          // parent array, -1 for root\nint depth[MAXN];        // depth[v] = number of edges from root\nint64_t contrib[MAXN];  // (depth[v]+1)*A[v]\nint64_t total_score;\n\n// DSU that mirrors the *undirected* forest edges\ndsu uf;\n\n// ---------- utility ----------\ninline void update_contrib(int v) {\n    contrib[v] = int64_t(depth[v] + 1) * A[v];\n}\n\n// ---------- initial greedy ----------\nvoid greedy_build() {\n    vector<char> used(N, 0);\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    shuffle(order.begin(), order.end(), rng);\n    sort(order.begin(), order.end(), [&](int u, int v) {\n        return A[u] > A[v];\n    });\n\n    uf = dsu(N);\n    total_score = 0;\n    for (int v = 0; v < N; ++v) par[v] = -2;\n\n    for (int u : order) if (par[u] == -2) {\n        queue<int> q;\n        par[u] = -1;\n        depth[u] = 0;\n        update_contrib(u);\n        q.push(u);\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            if (depth[v] == H) continue;\n            for (int w : G[v]) if (par[w] == -2) {\n                // safe because w is unused\n                par[w] = v;\n                depth[w] = depth[v] + 1;\n                update_contrib(w);\n                uf.merge(v, w);\n                q.push(w);\n            }\n        }\n    }\n    total_score = 0;\n    for (int v = 0; v < N; ++v) total_score += contrib[v];\n}\n\n// ---------- local improvement ----------\nvoid local_search(int iterations) {\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    vector<int> verts(N);\n    iota(verts.begin(), verts.end(), 0);\n\n    for (int it = 0; it < iterations; ++it) {\n        shuffle(verts.begin(), verts.end(), rng);\n        bool improved = false;\n\n        for (int v : verts) {\n            int old_p = par[v];\n            int old_d = depth[v];\n            int64_t old_delta = -contrib[v];\n\n            // try making v a new root\n            int best_new_p = -1;\n            int best_new_d = 0;\n            int64_t best_delta = 0;\n\n            int64_t delta_root = int64_t(1) * A[v] + old_delta;\n            if (delta_root > 0) {\n                best_new_p = -1;\n                best_new_d = 0;\n                best_delta = delta_root;\n            }\n\n            // try all neighbors as new parent\n            for (int w : G[v]) {\n                if (w == old_p) continue;\n                int nd = depth[w] + 1;\n                if (nd > H) continue;\n                // cycle check\n                if (uf.same(v, w)) continue;\n                int64_t delta = int64_t(nd + 1) * A[v] - contrib[v];\n                if (delta > best_delta) {\n                    best_delta = delta;\n                    best_new_p = w;\n                    best_new_d = nd;\n                }\n            }\n\n            if (best_delta > 0) {\n                // apply move\n                if (old_p != -1) {\n                    // remove old edge (old_p,v)\n                    // dsu does not support edge deletion; rebuild edge set\n                    // instead we rebuild uf from scratch each move (N is small)\n                    // rebuild uf after every successful move\n                }\n                par[v] = best_new_p;\n                depth[v] = best_new_d;\n                update_contrib(v);\n                total_score += best_delta;\n                improved = true;\n                // rebuild uf to reflect new edge\n                uf = dsu(N);\n                for (int u = 0; u < N; ++u) if (par[u] != -1)\n                    uf.merge(u, par[u]);\n            }\n        }\n        if (!improved) break;\n    }\n}\n\n// ---------- output ----------\nvoid output_answer() {\n    for (int i = 0; i < N; ++i) {\n        cout << par[i] << (i + 1 < N ? ' ' : '\\n');\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> H;\n    for (int i = 0; i < N; ++i) cin >> A[i];\n    for (int i = 0; i < M; ++i) {\n        int u, v; cin >> u >> v;\n        G[u].push_back(v);\n        G[v].push_back(u);\n    }\n    // discard coordinates\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n    }\n\n    int64_t best_score = -1;\n    vector<int> best_par(N);\n\n    auto save_best = [&]() {\n        if (total_score > best_score) {\n            best_score = total_score;\n            copy(par, par + N, best_par.begin());\n        }\n    };\n\n    const int tries = 25;\n    const int loc_its = 80;\n    for (int t = 0; t < tries; ++t) {\n        greedy_build();\n        local_search(loc_its);\n        save_best();\n    }\n\n    copy(best_par.begin(), best_par.end(), par);\n    output_answer();\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\nusing uint = unsigned int;\n\nconst int NONE = -1;\nconst int DR[4] = {0, 0, -1, 1};\nconst int DC[4] = {-1, 1, 0, 0};\nconst char DIRC[4] = {'L','R','U','D'};\nconst int BACK[4] = {1, 0, 3, 2};\n\nint N;\nvector<string> B;\nvector<pair<int,int>> oni, fuku;\nvector<int> safe_dir;          // safe direction for each oni\nvector<vector<char>> cur;      // current board state\nvector<pair<char,int>> ops;    // output sequence\n\n// apply one shift and record it\nvoid apply(int d, int p) {\n    ops.emplace_back(DIRC[d], p);\n    if (d == 0) { // L row p\n        for (int j = 0; j + 1 < N; ++j) cur[p][j] = cur[p][j+1];\n        cur[p][N-1] = '.';\n    } else if (d == 1) { // R row p\n        for (int j = N-1; j > 0; --j) cur[p][j] = cur[p][j-1];\n        cur[p][0] = '.';\n    } else if (d == 2) { // U col p\n        for (int i = 0; i + 1 < N; ++i) cur[i][p] = cur[i+1][p];\n        cur[N-1][p] = '.';\n    } else { // D col p\n        for (int i = N-1; i > 0; --i) cur[i][p] = cur[i-1][p];\n        cur[0][p] = '.';\n    }\n}\n\n// push+pull sequence along direction d for row/col p\nvoid push_pull(int d, int p) {\n    int len = (d < 2 ? N : N);\n    for (int t = 0; t < len; ++t) apply(d, p);\n    for (int t = 0; t < len; ++t) apply(BACK[d], p);\n}\n\n// count how many oni in row/col p can be removed by direction d without hitting fuku\nint count_removable(int d, int p) {\n    int cnt = 0;\n    if (d < 2) { // row p\n        int step = (d == 0 ? -1 : 1);\n        for (int j = 0; j < N; ++j) {\n            bool ok = true;\n            for (int k = j; k >= 0 && k < N; k += step) {\n                if (cur[p][k] == 'o') { ok = false; break; }\n                if (cur[p][k] == 'x') break;\n            }\n            if (ok && cur[p][j] == 'x') ++cnt;\n        }\n    } else { // col p\n        int step = (d == 2 ? -1 : 1);\n        for (int i = 0; i < N; ++i) {\n            bool ok = true;\n            for (int k = i; k >= 0 && k < N; k += step) {\n                if (cur[k][p] == 'o') { ok = false; break; }\n                if (cur[k][p] == 'x') break;\n            }\n            if (ok && cur[i][p] == 'x') ++cnt;\n        }\n    }\n    return cnt;\n}\n\n// greedy baseline: always pick the row/col+direction that removes most oni at once\nvoid greedy_pass() {\n    while (true) {\n        int best = 0, bd = NONE, bp = NONE;\n        for (int d = 0; d < 4; ++d) {\n            for (int p = 0; p < N; ++p) {\n                int c = count_removable(d, p);\n                if (c > best) { best = c; bd = d; bp = p; }\n            }\n        }\n        if (best == 0) break;\n        push_pull(bd, bp);\n    }\n}\n\n// evaluate total moves for current safe_dir assignment\nint evaluate() {\n    // rebuild cur\n    cur = vector<vector<char>>(N, vector<char>(N, '.'));\n    for (auto [i,j]: fuku) cur[i][j] = 'o';\n    for (int idx = 0; idx < (int)oni.size(); ++idx) {\n        auto [i,j] = oni[idx];\n        cur[i][j] = 'x';\n    }\n    ops.clear();\n    greedy_pass();\n    return ops.size();\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    B.resize(N);\n    for (int i = 0; i < N; ++i) cin >> B[i];\n\n    // collect initial positions\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            if (B[i][j] == 'x') oni.emplace_back(i,j);\n            if (B[i][j] == 'o') fuku.emplace_back(i,j);\n        }\n    const int M = oni.size();\n\n    // precompute safe directions for each oni\n    safe_dir.resize(M);\n    for (int idx = 0; idx < M; ++idx) {\n        auto [i,j] = oni[idx];\n        vector<bool> safe(4, true);\n        // left\n        for (int k = j-1; k >= 0; --k) if (B[i][k] == 'o') safe[0] = false;\n        // right\n        for (int k = j+1; k < N; ++k) if (B[i][k] == 'o') safe[1] = false;\n        // up\n        for (int k = i-1; k >= 0; --k) if (B[k][j] == 'o') safe[2] = false;\n        // down\n        for (int k = i+1; k < N; ++k) if (B[k][j] == 'o') safe[3] = false;\n        // pick first safe\n        int pick = 0;\n        for (; pick < 4; ++pick) if (safe[pick]) break;\n        safe_dir[idx] = pick;\n    }\n\n    // initial evaluation\n    int bestT = evaluate();\n    auto best_ops = ops;\n\n    // simple randomised local search\n    mt19937 rng(42);\n    uniform_int_distribution<int> uid_idx(0, M-1);\n    uniform_int_distribution<int> uid_dir(0, 3);\n    const double START_TEMP = 10.0, END_TEMP = 1.0;\n    const int MAX_ITER = 200000;\n    for (int iter = 0; iter < MAX_ITER; ++iter) {\n        double temp = START_TEMP + (END_TEMP - START_TEMP) * iter / MAX_ITER;\n        int idx = uid_idx(rng);\n        auto [i,j] = oni[idx];\n        int oldd = safe_dir[idx];\n        int newd = uid_dir(rng);\n        if (newd == oldd) continue;\n        // check newd is safe for this oni\n        bool ok = true;\n        if (newd == 0) { for (int k = j-1; k >= 0; --k) if (B[i][k]=='o') ok=false; }\n        else if (newd==1){ for(int k=j+1;k<N;++k) if(B[i][k]=='o') ok=false; }\n        else if (newd==2){ for(int k=i-1;k>=0;--k) if(B[k][j]=='o') ok=false; }\n        else { for(int k=i+1;k<N;++k) if(B[k][j]=='o') ok=false; }\n        if (!ok) continue;\n\n        safe_dir[idx] = newd;\n        int newT = evaluate();\n        int delta = newT - bestT;\n        bool accept = (delta < 0) || (uniform_real_distribution<double>(0,1)(rng) < exp(-delta/temp));\n        if (delta < 0) {\n            bestT = newT;\n            best_ops = ops;\n        }\n        if (!accept) {\n            safe_dir[idx] = oldd;\n        }\n    }\n\n    // output best found\n    cerr << \"T = \" << bestT << \"\\n\";\n    for (auto [d,p]: best_ops) cout << d << \" \" << p << \"\\n\";\n    return 0;\n}","ahc044":"#include <iostream>\n#include <vector>\n#include <random>\n#include <algorithm>\n#include <chrono>\n\nusing namespace std;\n\nconst int N = 100;\nconst int L = 500000;\n\nint T[N];\nint a[N], b[N];\nint t[N];\nint current_sequence[L];\n\nint simulate() {\n    fill(t, t + N, 0);\n    int current = 0;\n    t[current] = 1;\n    for (int week = 1; week < L; ++week) {\n        int count = t[current];\n        int next;\n        if (count % 2 == 1) {\n            next = a[current];\n        } else {\n            next = b[current];\n        }\n        t[next]++;\n        current = next;\n    }\n    int error = 0;\n    for (int i = 0; i < N; ++i) {\n        error += abs(t[i] - T[i]);\n    }\n    return error;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    for (int i = 0; i < N; ++i) {\n        cin >> T[i];\n    }\n\n    // Initial greedy assignment\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    for (int i = 0; i < N; ++i) {\n        a[i] = uniform_int_distribution<int>(0, N - 1)(rng);\n        b[i] = uniform_int_distribution<int>(0, N - 1)(rng);\n    }\n\n    int best_error = simulate();\n    auto start = chrono::steady_clock::now();\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start).count() > 1800) {\n            break; // Stop after 1.8 seconds to ensure we don't exceed 2 seconds\n        }\n\n        int i = uniform_int_distribution<int>(0, N - 1)(rng);\n        int old_a = a[i], old_b = b[i];\n\n        // Try changing a[i] or b[i]\n        if (uniform_int_distribution<int>(0, 1)(rng) == 0) {\n            a[i] = uniform_int_distribution<int>(0, N - 1)(rng);\n        } else {\n            b[i] = uniform_int_distribution<int>(0, N - 1)(rng);\n        }\n\n        int new_error = simulate();\n        if (new_error < best_error) {\n            best_error = new_error;\n        } else {\n            // Revert\n            a[i] = old_a;\n            b[i] = old_b;\n        }\n    }\n\n    // Output the best found\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 City {\n    int id, lx, rx, ly, ry;\n    int cx() const { return (lx + rx) / 2; }\n    int cy() const { return (ly + ry) / 2; }\n};\n\nint N, M, Q, L, W;\nvector<int> G;\nvector<City> cities;\nvector<vector<int>> groups;\nvector<vector<pair<int, int>>> group_edges;\n\nvector<pair<int, int>> query(const vector<int>& c) {\n    cout << \"? \" << c.size();\n    for (int x : c) cout << \" \" << x;\n    cout << endl;\n    vector<pair<int, int>> edges;\n    for (int i = 0; i < c.size() - 1; ++i) {\n        int a, b;\n        cin >> a >> b;\n        edges.emplace_back(a, b);\n    }\n    return edges;\n}\n\nvoid answer() {\n    cout << \"!\" << endl;\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < groups[i].size(); ++j) {\n            if (j > 0) cout << \" \";\n            cout << groups[i][j];\n        }\n        cout << endl;\n        for (auto [a, b] : group_edges[i]) {\n            cout << a << \" \" << b << endl;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    cities.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> cities[i].lx >> cities[i].rx >> cities[i].ly >> cities[i].ry;\n        cities[i].id = i;\n    }\n\n    // Sort cities by center coordinates\n    sort(cities.begin(), cities.end(), [](const City& a, const City& b) {\n        if (a.cx() != b.cx()) return a.cx() < b.cx();\n        return a.cy() < b.cy();\n    });\n\n    // Assign to groups\n    groups.resize(M);\n    group_edges.resize(M);\n    int ptr = 0;\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < G[i]; ++j) {\n            groups[i].push_back(cities[ptr++].id);\n        }\n    }\n\n    // Use queries to get edges for each group\n    int queries_used = 0;\n    for (int i = 0; i < M; ++i) {\n        int sz = groups[i].size();\n        if (sz <= 1) continue;\n        // Use triplets to cover the group\n        for (int j = 0; j < sz - 1; j += 2) {\n            if (queries_used >= Q) break;\n            vector<int> c;\n            if (j + 2 < sz) {\n                c = {groups[i][j], groups[i][j+1], groups[i][j+2]};\n            } else {\n                c = {groups[i][j], groups[i][j+1]};\n            }\n            auto edges = query(c);\n            for (auto [a, b] : edges) {\n                group_edges[i].emplace_back(a, b);\n            }\n            queries_used++;\n        }\n        // Ensure connectivity by adding edges if necessary\n        // This is a simple heuristic: connect in order\n        if (group_edges[i].size() < sz - 1) {\n            for (int j = 0; j < sz - 1; ++j) {\n                group_edges[i].emplace_back(groups[i][j], groups[i][j+1]);\n            }\n        }\n    }\n\n    answer();\n    return 0;\n}","ahc046":"#pragma GCC optimize(\"O3,unroll-loops\")\n#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nstatic const int N = 20;\nstatic const int M = 40;\nstatic const int LIMIT = 2*N*M;\n\nint target[M];\nint targetLeft;                      // how many still to visit\nbool blocked[N][N];                  // current wall state\nint  distSlide[N][N][4];             // dist to next block/border in 4 dirs\nint  di[] = {-1,1,0,0};\nint  dj[] = {0,0,-1,1};\nchar actionChar[] = {'M','S','A'};\nchar dirChar[]    = {'U','D','L','R'};\n\nstruct Step {\n    int i,j;\n    int g;\n    vector<pair<int,int>> pathActs; // (act,dir) pairs leading here\n    bool operator<(const Step& o) const { return g > o.g; }\n};\n\ninline bool inside(int i,int j){ return i>=0&&i<N&&j>=0&&j<N; }\n\nvoid rebuildDistSlide(){\n    for(int i=0;i<N;i++){\n        // up\n        for(int j=0;j<N;j++){\n            int d=0;\n            for(int ii=i-1;ii>=0;ii--){\n                if(blocked[ii][j]) break;\n                d++;\n            }\n            distSlide[i][j][0]=d;\n        }\n        // down\n        for(int j=0;j<N;j++){\n            int d=0;\n            for(int ii=i+1;ii<N;ii++){\n                if(blocked[ii][j]) break;\n                d++;\n            }\n            distSlide[i][j][1]=d;\n        }\n    }\n    for(int j=0;j<N;j++){\n        // left\n        for(int i=0;i<N;i++){\n            int d=0;\n            for(int jj=j-1;jj>=0;jj--){\n                if(blocked[i][jj]) break;\n                d++;\n            }\n            distSlide[i][j][2]=d;\n        }\n        // right\n        for(int i=0;i<N;i++){\n            int d=0;\n            for(int jj=j+1;jj<N;jj++){\n                if(blocked[i][jj]) break;\n                d++;\n            }\n            distSlide[i][j][3]=d;\n        }\n    }\n}\n\nint heuristic(int si,int sj,int ti,int tj){\n    return abs(si-ti)+abs(sj-tj);\n}\n\nvector<pair<int,int>> planSegment(int si,int sj,int ti,int tj){\n    priority_queue<Step> pq;\n    Step start{si,sj,0,{}};\n    pq.push(start);\n    static char vis[ N ][ N ];\n    memset(vis,0,sizeof(vis));\n    vis[si][sj]=1;\n    const int EXPAND = 20000;\n    int expanded = 0;\n    while(!pq.empty() && expanded < EXPAND){\n        Step cur = pq.top(); pq.pop();\n        expanded++;\n        if(cur.i==ti && cur.j==tj){\n            return cur.pathActs;\n        }\n        int g2 = cur.g+1;\n        for(int dir=0;dir<4;dir++){\n            int ni = cur.i + di[dir];\n            int nj = cur.j + dj[dir];\n            // 1) Move\n            if(inside(ni,nj) && !blocked[ni][nj] && !vis[ni][nj]){\n                vis[ni][nj]=1;\n                Step nxt = cur;\n                nxt.i=ni; nxt.j=nj; nxt.g=g2;\n                nxt.pathActs.emplace_back(0,dir);\n                pq.push(nxt);\n            }\n            // 2) Slide\n            int ds = distSlide[cur.i][cur.j][dir];\n            if(ds>0){\n                int ei = cur.i + di[dir]*ds;\n                int ej = cur.j + dj[dir]*ds;\n                if(!vis[ei][ej]){\n                    vis[ei][ej]=1;\n                    Step nxt = cur;\n                    nxt.i=ei; nxt.j=ej; nxt.g=g2;\n                    nxt.pathActs.emplace_back(1,dir);\n                    pq.push(nxt);\n                }\n            }\n            // 3) Alter\n            int bi = cur.i + di[dir];\n            int bj = cur.j + dj[dir];\n            if(inside(bi,bj)){\n                // toggle\n                blocked[bi][bj] ^= 1;\n                rebuildDistSlide();\n                Step nxt = cur;\n                nxt.g=g2;\n                nxt.pathActs.emplace_back(2,dir);\n                pq.push(nxt);\n                // undo\n                blocked[bi][bj] ^= 1;\n                rebuildDistSlide();\n            }\n        }\n    }\n    // fallback: plain Manhattan moves\n    vector<pair<int,int>> fallback;\n    int dx = ti - si;\n    int dy = tj - sj;\n    int px = si, py = sj;\n    while(px<ti){ px++; fallback.emplace_back(0,1); }\n    while(px>ti){ px--; fallback.emplace_back(0,0); }\n    while(py<tj){ py++; fallback.emplace_back(0,3); }\n    while(py>tj){ py--; fallback.emplace_back(0,2); }\n    return fallback;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int n,m;\n    cin >> n >> m;\n    assert(n==N && m==M);\n    int si,sj;\n    cin >> si >> sj;\n    vector<int> I(M),J(M);\n    for(int k=0;k<M;k++){\n        cin >> I[k] >> J[k];\n    }\n    // initialise\n    memset(blocked,0,sizeof(blocked));\n    rebuildDistSlide();\n    vector<pair<int,int>> fullPlan;\n    int ci=si, cj=sj;\n    for(int idx=0;idx<M;idx++){\n        int ti = I[idx];\n        int tj = J[idx];\n        auto seg = planSegment(ci,cj,ti,tj);\n        fullPlan.insert(fullPlan.end(), seg.begin(), seg.end());\n        // execute to update real state\n        for(auto [act,dir]: seg){\n            if(act==0){ // Move\n                ci += di[dir];\n                cj += dj[dir];\n            } else if(act==1){ // Slide\n                int ds = distSlide[ci][cj][dir];\n                ci += di[dir]*ds;\n                cj += dj[dir]*ds;\n            } else { // Alter\n                int bi = ci + di[dir];\n                int bj = cj + dj[dir];\n                blocked[bi][bj] ^= 1;\n                rebuildDistSlide();\n            }\n        }\n        assert(ci==ti && cj==tj);\n    }\n    // output\n    cout << fullPlan.size() << \"\\n\";\n    for(auto [act,dir]: fullPlan){\n        cout << actionChar[act] << \" \" << dirChar[dir] << \"\\n\";\n    }\n    return 0;\n}"},"4":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nusing uint = unsigned int;\nusing ull = unsigned long long;\n\n/* ---------- basic geometry ---------- */\nstruct Rect {\n    int a, b, c, d;\n    ll area() const { return (ll)(c - a) * (d - b); }\n    bool contains(double x, double y) const {\n        return a <= x && x <= c && b <= y && y <= d;\n    }\n    // intersection area (0 if disjoint)\n    ll intersect(const Rect &o) const {\n        int A = max(a, o.a), B = max(b, o.b);\n        int C = min(c, o.c), D = min(d, o.d);\n        if (A >= C || B >= D) return 0;\n        return (ll)(C - A) * (D - B);\n    }\n};\nstruct Company {\n    int x, y, r;\n    double cx, cy;   // desired centre\n    Rect  R;\n    double priority() const {      // how far from desired area\n        ll s = R.area();\n        double rat = min((double)s, (double)r) / max((double)s, (double)r);\n        return 1.0 - rat;          // larger \u2192 more urgent\n    }\n};\n\n/* ---------- global ---------- */\nint n;\nvector<Company> co;\nchrono::steady_clock::time_point start;\ndouble time_elapsed() {\n    return chrono::duration<double>(chrono::steady_clock::now() - start).count();\n}\nconst double TIME_LIMIT = 4.8;\n\n/* ---------- overlap utilities ---------- */\nbool overlap(int i, int j) {\n    const Rect &p = co[i].R, &q = co[j].R;\n    return !(p.c <= q.a || q.c <= p.a || p.d <= q.b || q.d <= p.b);\n}\nll total_overlap() {   // total pairwise overlap area\n    ll bad = 0;\n    for (int i = 0; i < n; ++i)\n        for (int j = i + 1; j < n; ++j)\n            bad += co[i].R.intersect(co[j].R);\n    return bad;\n}\n\n/* ---------- priority overlap removal ---------- */\nvoid remove_overlaps_pq() {\n    priority_queue<pair<double, int>> pq; // priority -> index\n    auto push = [&](int i) { pq.emplace(co[i].priority(), i); };\n    for (int i = 0; i < n; ++i) push(i);\n\n    bool progress;\n    do {\n        progress = false;\n        while (!pq.empty()) {\n            int i = pq.top().second; pq.pop();\n            for (int j = 0; j < n; ++j) {\n                if (i == j) continue;\n                if (!overlap(i, j)) continue;\n                progress = true;\n                Rect &u = co[i].R, &v = co[j].R;\n                // shrink the one whose area is further above its r\n                bool shrink_u = (u.area() > co[i].r) ||\n                                (v.area() <= co[j].r && u.area() > v.area());\n                Rect *t = shrink_u ? &u : &v;\n                int dx = t->c - t->a, dy = t->d - t->b;\n                if (dx > dy) {\n                    if (t->c - 1 > t->a) t->c--;\n                    else if (t->a + 1 < t->c) t->a++;\n                    else if (t->d - 1 > t->b) t->d--;\n                    else t->b++;\n                } else {\n                    if (t->d - 1 > t->b) t->d--;\n                    else if (t->b + 1 < t->d) t->b++;\n                    else if (t->c - 1 > t->a) t->c--;\n                    else t->a++;\n                }\n                push(i);\n                push(j);\n                goto next_loop;\n            }\n        }\n        next_loop:;\n    } while (progress && time_elapsed() < TIME_LIMIT);\n}\n\n/* ---------- maximal empty rectangle (MER) ---------- */\nvector<Rect> find_MERs() {\n    // event-based maximal empty rectangles in orthogonal plane\n    // we implement a simplified 1-D maximal gap finder twice (x, y)\n    // and return up to 4*n largest empty rectangles.\n    vector<Rect> merch;\n    { // sweep along x\n        vector<int> xs = {0, 10000};\n        for (int i = 0; i < n; ++i) {\n            xs.push_back(co[i].R.a);\n            xs.push_back(co[i].R.c);\n        }\n        sort(xs.begin(), xs.end());\n        xs.erase(unique(xs.begin(), xs.end()), xs.end());\n        for (size_t i = 0; i + 1 < xs.size(); ++i) {\n            int x1 = xs[i], x2 = xs[i + 1];\n            vector<pair<int, int>> segs;\n            for (int j = 0; j < n; ++j) {\n                if (co[j].R.a <= x1 && x2 <= co[j].R.c) {\n                    segs.emplace_back(co[j].R.b, co[j].R.d);\n                }\n            }\n            sort(segs.begin(), segs.end());\n            int last = 0;\n            for (auto &s : segs) {\n                if (s.first > last) merch.push_back({x1, last, x2, s.first});\n                last = max(last, s.second);\n            }\n            if (last < 10000) merch.push_back({x1, last, x2, 10000});\n        }\n    }\n    // sort by decreasing area\n    sort(merch.begin(), merch.end(),\n         [](const Rect &A, const Rect &B) { return A.area() > B.area(); });\n    if (merch.size() > 4 * n) merch.resize(4 * n);\n    return merch;\n}\n\n/* ---------- try to assign exact r_i into biggest MER containing centre ---------- */\nvoid expand_to_MER() {\n    auto mer = find_MERs();\n    vector<int> ord(n);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(),\n         [&](int i, int j) { return co[i].priority() > co[j].priority(); });\n\n    for (int idx : ord) {\n        Company &C = co[idx];\n        for (const Rect &E : mer) {\n            if (!E.contains(C.cx, C.cy)) continue;\n            ll avail = E.area();\n            if (avail < C.r) continue;\n            // try to build a rectangle inside E, area = C.r, containing centre\n            int want = C.r;\n            int w = E.c - E.a, h = E.d - E.b;\n            // choose integer dimensions (dx,dy) with dx*dy = want, dx<=w, dy<=h\n            int dx = (int)sqrt(want), dy;\n            while (dx > 0) {\n                if (want % dx == 0) {\n                    dy = want / dx;\n                    if (dx <= w && dy <= h) break;\n                }\n                dx--;\n            }\n            if (dx == 0) continue; // cannot fit\n            // centre must be inside new rectangle\n            int nx1 = max(E.a, (int)floor(C.cx - dx / 2.0));\n            int nx2 = nx1 + dx;\n            if (nx2 > E.c) { nx2 = E.c; nx1 = nx2 - dx; }\n            int ny1 = max(E.b, (int)floor(C.cy - dy / 2.0));\n            int ny2 = ny1 + dy;\n            if (ny2 > E.d) { ny2 = E.d; ny1 = ny2 - dy; }\n            Rect cand{nx1, ny1, nx2, ny2};\n            if (!cand.contains(C.cx, C.cy)) continue;\n            // check overlap with others\n            bool ok = true;\n            for (int i = 0; i < n && ok; ++i)\n                if (i != idx && cand.intersect(co[i].R)) ok = false;\n            if (!ok) continue;\n            C.R = cand;\n            break;\n        }\n    }\n}\n\n/* ---------- simulated annealing outer loop ---------- */\ndouble raw_score() {\n    double sum = 0;\n    for (int i = 0; i < n; ++i) {\n        ll s = co[i].R.area();\n        ll r = co[i].r;\n        if (s == r) sum += 1.0;\n        else {\n            double rat = min((double)s, (double)r) / max((double)s, (double)r);\n            sum += 1.0 - (1.0 - rat) * (1.0 - rat);\n        }\n    }\n    return sum;\n}\nvoid anneal() {\n    double T0 = 1e-3, T, cooling = 0.995;\n    double best = raw_score() - 1e6 * total_overlap();\n    double cur = best;\n    mt19937 rng(42);\n    uniform_real_distribution<double> uni(0, 1);\n\n    while (time_elapsed() < TIME_LIMIT) {\n        T = T0;\n        for (int step = 0; step < 300 && time_elapsed() < TIME_LIMIT; ++step, T *= cooling) {\n            // neighbour: random small move\n            int i = uniform_int_distribution<int>(0, n - 1)(rng);\n            Rect old = co[i].R;\n            Rect neo = old;\n            int d = uniform_int_distribution<int>(-2, 2)(rng);\n            int mode = uniform_int_distribution<int>(0, 3)(rng);\n            if (mode == 0) neo.a += d;\n            if (mode == 1) neo.b += d;\n            if (mode == 2) neo.c += d;\n            if (mode == 3) neo.d += d;\n            if (neo.a >= neo.c || neo.b >= neo.d) continue;\n            if (neo.a < 0 || neo.b < 0 || neo.c > 10000 || neo.d > 10000) continue;\n            if (!neo.contains(co[i].cx, co[i].cy)) continue;\n\n            co[i].R = neo;\n            double nxt = raw_score() - 1e6 * total_overlap();\n            double delta = nxt - cur;\n            if (delta > 0 || uni(rng) < exp(delta / T)) {\n                cur = nxt;\n                if (cur > best) best = cur;\n            } else {\n                co[i].R = old;\n            }\n        }\n    }\n}\n\n/* ---------- driver ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    start = chrono::steady_clock::now();\n\n    cin >> n;\n    co.resize(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> co[i].x >> co[i].y >> co[i].r;\n        co[i].cx = co[i].x + 0.5;\n        co[i].cy = co[i].y + 0.5;\n        co[i].R = {co[i].x, co[i].y, co[i].x + 1, co[i].y + 1};\n    }\n\n    remove_overlaps_pq();\n    expand_to_MER();\n    remove_overlaps_pq();\n    anneal();\n\n    for (int i = 0; i < n; ++i)\n        cout << co[i].R.a << ' ' << co[i].R.b << ' '\n             << co[i].R.c << ' ' << co[i].R.d << '\\n';\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nint si, sj;\nint t[50][50];\nint p[50][50];\nint M;                       // number of distinct tiles\nvector<vector<pair<int,int>>> tileSquares; // tile id -> its squares\nint bestScore;\nstring bestPath;\n\n// 4 directions\nconst int dx[4] = {-1,1,0,0};\nconst int dy[4] = {0,0,-1,1};\nconst char dc[4] = {'U','D','L','R'};\n\n// order of directions, we will shuffle it sometimes\nint order[4] = {0,1,2,3};\n\nvoid dfs(int i, int j, vector<bool>& used, int score, string& path, int depth){\n    if(score > bestScore){\n        bestScore = score;\n        bestPath = path;\n    }\n    // try neighbours\n    for(int k = 0; k < 4; k++){\n        int d = order[k];\n        int ni = i + dx[d];\n        int nj = j + dy[d];\n        if(ni<0||ni>=50||nj<0||nj>=50) continue;\n        int nt = t[ni][nj];\n        if(used[nt]) continue;\n        // step on this tile\n        used[nt] = true;\n        path.push_back(dc[d]);\n        dfs(ni, nj, used, score + p[ni][nj], path, depth+1);\n        path.pop_back();\n        used[nt] = false;\n    }\n}\n\nstring solveOne(int starti, int startj){\n    bestScore = p[starti][startj];\n    bestPath.clear();\n    vector<bool> used(M, false);\n    used[t[starti][startj]] = true;\n    string path;\n    dfs(starti, startj, used, bestScore, path, 0);\n    return bestPath;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> si >> sj;\n    for(int i=0;i<50;i++)for(int j=0;j<50;j++) cin >> t[i][j];\n    for(int i=0;i<50;i++)for(int j=0;j<50;j++) cin >> p[i][j];\n\n    // build tileSquares and find M\n    int maxt = 0;\n    for(int i=0;i<50;i++)for(int j=0;j<50;j++) maxt = max(maxt, t[i][j]);\n    M = maxt + 1;\n    tileSquares.assign(M, {});\n    for(int i=0;i<50;i++)for(int j=0;j<50;j++) tileSquares[t[i][j]].emplace_back(i,j);\n\n    // try both squares of the initial tile (if 2 squares)\n    vector<pair<int,int>> starts;\n    int st = t[si][sj];\n    for(auto [i,j]: tileSquares[st]) starts.emplace_back(i,j);\n\n    string globalBest;\n    int globalScore = -1;\n\n    // several random restarts with shuffled direction order\n    for(int rep=0; rep<10; rep++){\n        // shuffle direction order\n        shuffle(order, order+4, mt19937(rep));\n        for(auto [i,j]: starts){\n            string cand = solveOne(i, j);\n            if(bestScore > globalScore){\n                globalScore = bestScore;\n                globalBest = cand;\n            }\n        }\n    }\n    cout << globalBest << '\\n';\n    return 0;\n}","ahc003":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <string>\n#include <algorithm>\n#include <cmath>\n#include <iomanip>\n#include <unordered_map>\n\nusing namespace std;\n\nconst int GRID_SIZE = 30;\nconst int NUM_QUERIES = 1000;\n\n// Directions: U, D, L, R\nconst int dr[] = {-1, 1, 0, 0};\nconst int dc[] = {0, 0, -1, 1};\nconst char dir_chars[] = {'U', 'D', 'L', 'R'};\n\nstruct Edge {\n    int r1, c1, r2, c2;\n    double length;\n    int count;\n    double sum_observed;\n\n    Edge(int r1, int c1, int r2, int c2) : r1(r1), c1(c1), r2(r2), c2(c2), length(5000.0), count(0), sum_observed(0.0) {}\n};\n\nvector<vector<Edge>> horizontal_edges; // horizontal_edges[i][j] is between (i,j) and (i,j+1)\nvector<vector<Edge>> vertical_edges;   // vertical_edges[i][j] is between (i,j) and (i+1,j)\n\nvoid initialize_edges() {\n    horizontal_edges.resize(GRID_SIZE, vector<Edge>(GRID_SIZE - 1));\n    vertical_edges.resize(GRID_SIZE - 1, vector<Edge>(GRID_SIZE));\n\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        for (int j = 0; j < GRID_SIZE - 1; ++j) {\n            horizontal_edges[i][j] = Edge(i, j, i, j + 1);\n        }\n    }\n    for (int i = 0; i < GRID_SIZE - 1; ++i) {\n        for (int j = 0; j < GRID_SIZE; ++j) {\n            vertical_edges[i][j] = Edge(i, j, i + 1, j);\n        }\n    }\n}\n\nstring generate_manhattan_path(int si, int sj, int ti, int tj) {\n    string path;\n    int dr = ti - si;\n    int dc = tj - sj;\n    if (dr > 0) {\n        path += string(dr, 'D');\n    } else {\n        path += string(-dr, 'U');\n    }\n    if (dc > 0) {\n        path += string(dc, 'R');\n    } else {\n        path += string(-dc, 'L');\n    }\n    return path;\n}\n\nvector<pair<int, int>> parse_path(int si, int sj, const string& path) {\n    vector<pair<int, int>> vertices;\n    int r = si, c = sj;\n    vertices.emplace_back(r, c);\n    for (char d : path) {\n        if (d == 'U') r--;\n        else if (d == 'D') r++;\n        else if (d == 'L') c--;\n        else if (d == 'R') c++;\n        vertices.emplace_back(r, c);\n    }\n    return vertices;\n}\n\ndouble compute_path_length(const vector<pair<int, int>>& vertices) {\n    double length = 0.0;\n    for (int i = 0; i + 1 < vertices.size(); ++i) {\n        int r1 = vertices[i].first, c1 = vertices[i].second;\n        int r2 = vertices[i + 1].first, c2 = vertices[i + 1].second;\n        if (r1 == r2 && abs(c1 - c2) == 1) {\n            int j = min(c1, c2);\n            length += horizontal_edges[r1][j].length;\n        } else if (c1 == c2 && abs(r1 - r2) == 1) {\n            int i = min(r1, r2);\n            length += vertical_edges[i][c1].length;\n        } else {\n            // invalid edge\n            length += 1e9;\n        }\n    }\n    return length;\n}\n\nvoid update_edges(const vector<pair<int, int>>& vertices, int observed) {\n    double observed_length = observed;\n    // De-noise: assume the true length is around observed / 1.0 (since noise is 0.9-1.1)\n    // But we can average over multiple observations\n    for (int i = 0; i + 1 < vertices.size(); ++i) {\n        int r1 = vertices[i].first, c1 = vertices[i].second;\n        int r2 = vertices[i + 1].first, c2 = vertices[i + 1].second;\n        Edge* edge = nullptr;\n        if (r1 == r2 && abs(c1 - c2) == 1) {\n            int j = min(c1, c2);\n            edge = &horizontal_edges[r1][j];\n        } else if (c1 == c2 && abs(r1 - r2) == 1) {\n            int i = min(r1, r2);\n            edge = &vertical_edges[i][c1];\n        }\n        if (edge) {\n            edge->count++;\n            edge->sum_observed += observed_length;\n            edge->length = edge->sum_observed / edge->count;\n        }\n    }\n}\n\nstring dijkstra(int si, int sj, int ti, int tj) {\n    // Dijkstra's algorithm to find the shortest path in the current estimates\n    vector<vector<double>> dist(GRID_SIZE, vector<double>(GRID_SIZE, 1e18));\n    vector<vector<pair<int, int>>> parent(GRID_SIZE, vector<pair<int, int>>(GRID_SIZE, {-1, -1}));\n    priority_queue<pair<double, pair<int, int>>, vector<pair<double, pair<int, int>>>, greater<pair<double, pair<int, int>>>> pq;\n    dist[si][sj] = 0.0;\n    pq.push({0.0, {si, sj}});\n\n    while (!pq.empty()) {\n        auto [d, pos] = pq.top(); pq.pop();\n        int r = pos.first, c = pos.second;\n        if (d > dist[r][c]) continue;\n        if (r == ti && c == tj) break;\n\n        for (int k = 0; k < 4; ++k) {\n            int nr = r + dr[k], nc = c + dc[k];\n            if (nr < 0 || nr >= GRID_SIZE || nc < 0 || nc >= GRID_SIZE) continue;\n            double edge_len = 0.0;\n            if (k == 0) { // U\n                edge_len = vertical_edges[nr][nc].length;\n            } else if (k == 1) { // D\n                edge_len = vertical_edges[r][c].length;\n            } else if (k == 2) { // L\n                edge_len = horizontal_edges[r][nc].length;\n            } else if (k == 3) { // R\n                edge_len = horizontal_edges[r][c].length;\n            }\n            if (dist[nr][nc] > d + edge_len) {\n                dist[nr][nc] = d + edge_len;\n                parent[nr][nc] = {r, c};\n                pq.push({dist[nr][nc], {nr, nc}});\n            }\n        }\n    }\n\n    // Reconstruct path\n    string path;\n    int r = ti, c = tj;\n    while (parent[r][c].first != -1) {\n        int pr = parent[r][c].first, pc = parent[r][c].second;\n        if (pr == r - 1) path += 'D';\n        else if (pr == r + 1) path += 'U';\n        else if (pc == c - 1) path += 'R';\n        else if (pc == c + 1) path += 'L';\n        r = pr; c = pc;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    initialize_edges();\n\n    for (int k = 0; k < NUM_QUERIES; ++k) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n\n        string path;\n        if (k < 100) {\n            // Early queries: use Manhattan path for exploration\n            path = generate_manhattan_path(si, sj, ti, tj);\n        } else {\n            // Later queries: use Dijkstra with current estimates\n            path = dijkstra(si, sj, ti, tj);\n            if (path.empty()) {\n                // Fallback to Manhattan if Dijkstra fails\n                path = generate_manhattan_path(si, sj, ti, tj);\n            }\n        }\n\n        cout << path << endl;\n        cout.flush();\n\n        int observed;\n        cin >> observed;\n        auto vertices = parse_path(si, sj, path);\n        update_edges(vertices, observed);\n    }\n\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const int N = 20;\nstatic const int AL = 8;          // A..H\nstatic const char LET[] = \"ABCDEFGH\";\n\nint M;\nvector<string> S;\nint bestC;\nvector<string> bestGrid;\n\n// ---------- portable RNG ----------\nmt19937_64 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count() ^\n               (uint64_t)random_device{}());\n\ninline int randInt(int l, int r) {   // [l, r]\n    return uniform_int_distribution<int>(l, r)(rng);\n}\n\n// ---------- evaluation ----------\ninline int index(char c) { return c - 'A'; }\n\nint evaluate(const vector<string>& g) {\n    int cnt = 0;\n    for (const auto& s : S) {\n        int L = (int)s.size();\n        bool ok = false;\n        // horizontal\n        for (int i = 0; i < N && !ok; ++i) {\n            for (int st = 0; st < N; ++st) {\n                bool match = true;\n                for (int p = 0; p < L; ++p)\n                    if (g[i][(st + p) % N] != s[p]) { match = false; break; }\n                if (match) { ok = true; break; }\n            }\n        }\n        if (ok) { ++cnt; continue; }\n        // vertical\n        for (int j = 0; j < N && !ok; ++j) {\n            for (int st = 0; st < N; ++st) {\n                bool match = true;\n                for (int p = 0; p < L; ++p)\n                    if (g[(st + p) % N][j] != s[p]) { match = false; break; }\n                if (match) { ok = true; break; }\n            }\n        }\n        if (ok) ++cnt;\n    }\n    return cnt;\n}\n\nint fillCount(const vector<string>& g) {\n    int c = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (g[i][j] != '.') ++c;\n    return c;\n}\n\nvoid printGrid(const vector<string>& g) {\n    for (const auto& row : g) cout << row << '\\n';\n}\n\n// ---------- random grid ----------\nvector<string> randomGrid() {\n    vector<string> g(N, string(N, '.'));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            g[i][j] = LET[randInt(0, AL - 1)];\n    return g;\n}\n\n// ---------- mutation ----------\nvoid mutate1(vector<string>& g) {\n    int i = randInt(0, N - 1);\n    int j = randInt(0, N - 1);\n    char old = g[i][j];\n    char nu;\n    if (bestC == M && randInt(0, 9) == 0) nu = '.';\n    else nu = LET[randInt(0, AL - 1)];\n    g[i][j] = nu;\n    int c = evaluate(g);\n    if (c > bestC || (c == bestC && randInt(0, 1))) {\n        bestC = c;\n        bestGrid = g;\n    } else {\n        g[i][j] = old;\n    }\n}\n\nvoid mutateRow(vector<string>& g) {\n    int i = randInt(0, N - 1);\n    string old = g[i];\n    vector<int> unsat;\n    for (int idx = 0; idx < M; ++idx) {\n        const string& s = S[idx];\n        int L = s.size();\n        bool any = false;\n        for (int st = 0; st < N; ++st) {\n            bool ok = true;\n            for (int p = 0; p < L; ++p)\n                if (g[i][(st + p) % N] != s[p]) { ok = false; break; }\n            if (ok) { any = true; break; }\n        }\n        if (!any) unsat.push_back(idx);\n    }\n    if (unsat.empty()) return;\n    int pick = unsat[randInt(0, (int)unsat.size() - 1)];\n    const string& tgt = S[pick];\n    int L = tgt.size();\n    int st = randInt(0, N - 1);\n    for (int p = 0; p < L; ++p) g[i][(st + p) % N] = tgt[p];\n    int c = evaluate(g);\n    if (c > bestC || (c == bestC && randInt(0, 1))) {\n        bestC = c;\n        bestGrid = g;\n    } else {\n        g[i] = old;\n    }\n}\n\n// ---------- main ----------\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n, m;\n    cin >> n >> m;\n    M = m;\n    S.resize(M);\n    for (int i = 0; i < M; ++i) cin >> S[i];\n\n    bestGrid = randomGrid();\n    bestC = evaluate(bestGrid);\n\n    const double TIME_LIMIT = 2.8;\n    auto start = chrono::steady_clock::now();\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > TIME_LIMIT) break;\n\n        if (bestC < M) {\n            if (randInt(0, 3) == 0) mutateRow(bestGrid);\n            else                      mutate1(bestGrid);\n        } else {\n            mutate1(bestGrid);\n        }\n    }\n\n    // final safe fill pass\n    if (bestC == M) {\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                if (bestGrid[i][j] == '.') {\n                    char old = bestGrid[i][j];\n                    bool ok = false;\n                    for (char c : LET) {\n                        bestGrid[i][j] = c;\n                        if (evaluate(bestGrid) == M) { ok = true; break; }\n                    }\n                    if (!ok) bestGrid[i][j] = old;\n                }\n    }\n\n    printGrid(bestGrid);\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 70;\nconst int INF  = 0x3f3f3f3f;\n\nint N, si, sj;\nchar grid[MAXN][MAXN];\nint  cost[MAXN][MAXN];\nbool isRoad[MAXN][MAXN];\n\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\nchar dirC[] = {'U', 'D', 'L', 'R'};\n\nbitset<MAXN*MAXN> visFrom[MAXN][MAXN];   // what becomes visible\nbitset<MAXN*MAXN> coverage;\nint totalRoads;\n\n/* ---------- visibility precomputation ---------- */\nvoid buildVisibility() {\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (!isRoad[i][j]) continue;\n            auto &bs = visFrom[i][j];\n            // row left\n            for (int jj = j; jj >= 0 && isRoad[i][jj]; --jj) bs.set(i*N + jj);\n            // row right\n            for (int jj = j; jj <  N && isRoad[i][jj]; ++jj) bs.set(i*N + jj);\n            // col up\n            for (int ii = i; ii >= 0 && isRoad[ii][j]; --ii) bs.set(ii*N + j);\n            // col down\n            for (int ii = i; ii <  N && isRoad[ii][j]; ++ii) bs.set(ii*N + j);\n        }\n    }\n}\n\n/* ---------- single Dijkstra ---------- */\nint dist[MAXN][MAXN];\npair<int,int> parent[MAXN][MAXN];\n\nvoid dijkstra(int sr, int sc) {\n    memset(dist, 0x3f, sizeof(dist));\n    using T = tuple<int,int,int>;\n    priority_queue<T, vector<T>, greater<T>> pq;\n    dist[sr][sc] = 0;\n    parent[sr][sc] = {-1,-1};\n    pq.emplace(0, sr, sc);\n    while (!pq.empty()) {\n        auto [d, r, c] = pq.top(); pq.pop();\n        if (d > dist[r][c]) continue;\n        for (int k = 0; k < 4; ++k) {\n            int nr = r + dr[k], nc = c + dc[k];\n            if (nr<0||nr>=N||nc<0||nc>=N || !isRoad[nr][nc]) continue;\n            int nd = d + cost[nr][nc];\n            if (nd < dist[nr][nc]) {\n                dist[nr][nc] = nd;\n                parent[nr][nc] = {r,c};\n                pq.emplace(nd, nr, nc);\n            }\n        }\n    }\n}\n\n/* ---------- path reconstruction ---------- */\nvector<pair<int,int>> reconstruct(int tr, int tc) {\n    vector<pair<int,int>> path;\n    for (int r=tr, c=tc; r!=-1; tie(r,c)=parent[r][c]) path.emplace_back(r,c);\n    reverse(path.begin(), path.end());\n    return path;\n}\nstring toMoves(const vector<pair<int,int>>& path) {\n    string s;\n    for (int i = 1; i < (int)path.size(); ++i) {\n        int dr = path[i].first  - path[i-1].first;\n        int dc = path[i].second - path[i-1].second;\n        if (dr==-1) s+='U'; else if (dr==1) s+='D';\n        else if (dc==-1) s+='L'; else s+='R';\n    }\n    return s;\n}\n\n/* ---------- greedy cover ---------- */\nstring greedyCover() {\n    coverage.reset();\n    int cr = si, cc = sj;\n    string route;\n    coverage |= visFrom[cr][cc];\n\n    while ((int)coverage.count() < totalRoads) {\n        dijkstra(cr, cc);          // single Dijkstra\n        int best_r=-1, best_c=-1, best_gain=0, best_cost=INF;\n        for (int i=0;i<N;++i) {\n            for (int j=0;j<N;++j) {\n                if (!isRoad[i][j] || dist[i][j]==INF) continue;\n                int g = (visFrom[i][j] & ~coverage).count();\n                if (g==0) continue;\n                int c = dist[i][j];\n                if (g>best_gain || (g==best_gain && c<best_cost)) {\n                    best_gain = g; best_cost = c;\n                    best_r = i; best_c = j;\n                }\n            }\n        }\n        if (best_r==-1) break;     // should not happen\n        auto path = reconstruct(best_r, best_c);\n        route += toMoves(path);\n        cr = best_r; cc = best_c;\n        coverage |= visFrom[cr][cc];\n    }\n    // return to start\n    dijkstra(cr, cc);\n    auto pathBack = reconstruct(si, sj);\n    route += toMoves(pathBack);\n    return route;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin>>N>>si>>sj;\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]=='#') isRoad[i][j]=false, cost[i][j]=0;\n            else isRoad[i][j]=true, cost[i][j]=grid[i][j]-'0';\n        }\n    }\n    buildVisibility();\n    totalRoads = 0;\n    for(int i=0;i<N;++i)for(int j=0;j<N;++j)if(isRoad[i][j])++totalRoads;\n\n    string ans = greedyCover();\n    cout<<ans<<'\\n';\n    return 0;\n}","future-contest-2022-qual":"#pragma GCC target(\"avx2,popcnt,lzcnt,abm,bmi,bmi2\")\n#pragma GCC optimize(\"O3,unroll-loops,inline\")\n#include <bits/stdc++.h>\nusing namespace std;\n\nstatic constexpr int MAXK = 20;\nstatic constexpr int MAXM = 20;\nstatic constexpr int MAXN = 1000;\nstatic constexpr int MAXDAY = 2000;\n\nint N, M, K, R;\nalignas(64) int d[MAXN][MAXK];\nint bucketId[MAXN];\nvector<int> adj[MAXN], radj[MAXN];\nint level[MAXN];\nint remPred[MAXN];\nbool done[MAXN];\nint memberTask[MAXM];\nint taskStart[MAXM];\nint taskMember[MAXN];\n\nint Lb[MAXM][MAXK], Ub[MAXM][MAXK];\n\n// ready list: [0..readyTail) are ready; readyTail..readySz are waiting\nint readyBuf[MAXN];\nint readyTail = 0, readySz = 0;\n\ninline void push_ready(int t){ readyBuf[readySz++] = t; }\n\nint globalBucket(int task){\n    int s = 0;\n    for(int k = 0; k < K; k++) s += d[task][k];\n    return s / K;\n}\n\nvoid build_level(){\n    for(int i = 0; i < N; i++){\n        for(int v : adj[i]) level[v] = max(level[v], level[i]+1);\n    }\n}\n\ninline void mark_done(int task){\n    if(done[task]) return;\n    done[task] = true;\n    for(int v : adj[task]){\n        remPred[v]--;\n        if(remPred[v] == 0) push_ready(v);\n    }\n}\n\ninline void belief_update(int j, int task, int dur){\n    const int low  = max(0, dur - 3);\n    const int high = dur + 3;\n    int sumLo = 0, sumHi = 0;\n    #pragma GCC unroll 8\n    for(int k = 0; k < K; k++){\n        const int dk = d[task][k];\n        sumLo += max(0, dk - Ub[j][k]);\n        sumHi += max(0, dk - Lb[j][k]);\n    }\n    if(sumLo > high){\n        int need = sumLo - high;\n        int cnt  = 0;\n        for(int k = 0; k < K; k++){\n            const int dk = d[task][k];\n            if(dk > Lb[j][k] && dk < Ub[j][k]) cnt++;\n        }\n        if(cnt == 0) cnt = 1;\n        int each = (need + cnt - 1) / cnt;\n        for(int k = 0; k < K; k++){\n            const int dk = d[task][k];\n            if(dk > Lb[j][k] && dk < Ub[j][k]){\n                Ub[j][k] = min(Ub[j][k], dk);\n                need -= each;\n                if(need <= 0) break;\n            }\n        }\n    }\n    if(sumHi < low){\n        int need = low - sumHi;\n        int cnt  = 0;\n        for(int k = 0; k < K; k++){\n            const int dk = d[task][k];\n            if(dk > Lb[j][k]) cnt++;\n        }\n        if(cnt == 0) cnt = 1;\n        int each = (need + cnt - 1) / cnt;\n        for(int k = 0; k < K; k++){\n            const int dk = d[task][k];\n            if(dk > Lb[j][k]){\n                Lb[j][k] = max(Lb[j][k], dk - each);\n                need -= each;\n                if(need <= 0) break;\n            }\n        }\n    }\n}\n\ninline pair<int,int> est(int task, int j){\n    int optGap = 0, pesGap = 0;\n    #pragma GCC unroll 8\n    for(int k = 0; k < K; k++){\n        const int dk = d[task][k];\n        optGap += max(0, dk - Ub[j][k]);\n        pesGap += max(0, dk - Lb[j][k]);\n    }\n    const int opt = max(1, optGap - 3);\n    const int pes = max(1, pesGap + 3);\n    return {opt, pes};\n}\n\nvector<pair<int,int>> assign(){\n    if(readyTail == readySz) return {};\n    static int avail[MAXM], nAvail;\n    nAvail = 0;\n    for(int j = 0; j < M; j++) if(memberTask[j] < 0) avail[nAvail++] = j;\n    if(nAvail == 0) return {};\n\n    static tuple<int,int,int> es[MAXM * MAXN];\n    int esz = 0;\n    for(int a = 0; a < nAvail; a++){\n        int j = avail[a];\n        for(int t = readyTail; t < readySz; t++){\n            int i = readyBuf[t];\n            auto [opt, pes] = est(i, j);\n            int w = 3*opt + pes + 2*level[i];\n            es[esz++] = {w, a, t};\n        }\n    }\n    sort(es, es + esz);\n    static char ua[MAXM], ut[MAXN];\n    memset(ua, 0, nAvail);\n    memset(ut, 0, readySz - readyTail);\n    vector<pair<int,int>> ans;\n    ans.reserve(min(nAvail, readySz - readyTail));\n    for(int e = 0; e < esz; e++){\n        auto [w, a, t] = es[e];\n        if(ua[a] || ut[t - readyTail]) continue;\n        ua[a] = ut[t - readyTail] = 1;\n        int j = avail[a];\n        int i = readyBuf[t];\n        ans.emplace_back(j, i);\n    }\n    return ans;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> K >> R;\n    for(int i = 0; i < N; i++){\n        for(int k = 0; k < K; k++) cin >> d[i][k];\n        bucketId[i] = globalBucket(i);\n    }\n    for(int i = 0; i < R; i++){\n        int u,v; cin >> u >> v; u--; v--;\n        adj[u].push_back(v);\n        radj[v].push_back(u);\n    }\n    for(int i = 0; i < N; i++){\n        remPred[i] = radj[i].size();\n        if(remPred[i] == 0) push_ready(i);\n    }\n    build_level();\n\n    for(int j = 0; j < M; j++)\n        for(int k = 0; k < K; k++){\n            Lb[j][k] = 0;\n            Ub[j][k] = 200;\n        }\n    memset(memberTask, -1, sizeof memberTask);\n    memset(taskMember, -1, sizeof taskMember);\n\n    int day = 0;\n    while(day < MAXDAY){\n        day++;\n        auto match = assign();\n        const int m = match.size();\n        cout << m;\n        for(int i = 0; i < m; i++){\n            auto [j, t] = match[i];\n            cout << ' ' << (j+1) << ' ' << (t+1);\n            memberTask[j] = t;\n            taskMember[t] = j;\n            taskStart[j] = day;\n            // mark task as taken (swap with tail and pop)\n            int pos = find(readyBuf + readyTail, readyBuf + readySz, t) - readyBuf;\n            swap(readyBuf[pos], readyBuf[readyTail]);\n            readyTail++;\n        }\n        cout << '\\n';\n        cout.flush();\n\n        int n; \n        if(!(cin >> n)) break;\n        if(n == -1) break;\n        for(int i = 0; i < n; i++){\n            int j; cin >> j; j--;\n            int task = memberTask[j];\n            if(task < 0) continue;\n            int dur = day - taskStart[j] + 1;\n            belief_update(j, task, dur);\n            mark_done(task);\n            memberTask[j] = -1;\n            taskMember[task] = -1;\n        }\n        bool alld = true;\n        for(int i = 0; i < N; i++) if(!done[i]){ alld=false; break; }\n        if(alld) break;\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nstruct P { int x, y; };\nint man(const P& a, const P& b){\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\nstruct Order { P pu, de; int id; };\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<Order> all(1000);\n    for (int i = 0; i < 1000; ++i){\n        cin >> all[i].pu.x >> all[i].pu.y >> all[i].de.x >> all[i].de.y;\n        all[i].id = i;\n    }\n\n    const auto t0 = chrono::steady_clock::now();\n    ll bestT = LLONG_MAX;\n    vector<int> bestSel;\n    vector<P>   bestRoute;\n\n    mt19937 rng(123456);\n\n    const P office{400, 400};\n\n    while (true){\n        auto now = chrono::steady_clock::now();\n        if (chrono::duration<double>(now - t0).count() > 1.96) break;\n\n        /* 1. choose 50 random orders */\n        vector<int> sel(1000);\n        iota(sel.begin(), sel.end(), 0);\n        shuffle(sel.begin(), sel.end(), rng);\n        sel.resize(50);\n        sort(sel.begin(), sel.end());\n\n        /* 2. build initial route: office -> ... -> office */\n        vector<P> route = { office };\n        vector<int> puOf(50, -1), deOf(50, -1); // positions in route\n\n        auto costIns = [&](const P& pt, int at){\n            if (at == 0)\n                return man(office, pt) + man(pt, route[0]) - man(office, route[0]);\n            if (at == (int)route.size())\n                return man(route.back(), pt) + man(pt, office) - man(route.back(), office);\n            return man(route[at-1], pt) + man(pt, route[at]) - man(route[at-1], route[at]);\n        };\n\n        for (int oid = 0; oid < 50; ++oid){\n            const Order& o = all[sel[oid]];\n            ll bestInc = LLONG_MAX;\n            int bestPu = -1, bestDe = -1;\n            for (int pu = 1; pu <= (int)route.size(); ++pu){ // pu after office\n                ll incPu = costIns(o.pu, pu);\n                for (int de = pu + 1; de <= (int)route.size() + 1; ++de){\n                    ll incDe = 0;\n                    int realDe = (de > pu ? de - 1 : de);\n                    incDe = costIns(o.de, realDe);\n                    if (incPu + incDe < bestInc){\n                        bestInc = incPu + incDe;\n                        bestPu  = pu;\n                        bestDe  = de;\n                    }\n                }\n            }\n            route.insert(route.begin() + bestPu, o.pu);\n            int realDe = (bestDe > bestPu ? bestDe : bestDe);\n            route.insert(route.begin() + realDe, o.de);\n            /* rebuild puOf/deOf */\n            for (int i = 0; i < (int)route.size(); ++i){\n                if (route[i].x == o.pu.x && route[i].y == o.pu.y) puOf[oid] = i;\n                if (route[i].x == o.de.x && route[i].y == o.de.y) deOf[oid] = i;\n            }\n        }\n        route.push_back(office);\n\n        /* 3. fast random 2-opt, keeping 0 and n-1 fixed */\n        auto length = [&](const vector<P>& r){\n            ll len = 0;\n            for (int i = 0; i + 1 < (int)r.size(); ++i) len += man(r[i], r[i+1]);\n            return len;\n        };\n\n        uniform_int_distribution<int> uid(1, (int)route.size() - 3);\n        const int MAX_TRIES = 20000;\n        for (int tries = 0; tries < MAX_TRIES; ++tries){\n            int i = uid(rng);\n            int j = uid(rng);\n            if (j <= i) continue;\n            ll old = man(route[i], route[i+1]) + man(route[j], route[j+1]);\n            ll neo = man(route[i], route[j]) + man(route[i+1], route[j+1]);\n            if (neo >= old) continue;\n            /* reverse segment i+1 .. j */\n            reverse(route.begin() + i + 1, route.begin() + j + 1);\n            /* rebuild puOf/deOf and check feasibility */\n            bool ok = true;\n            for (int oid = 0; oid < 50 && ok; ++oid){\n                puOf[oid] = deOf[oid] = -1;\n                for (int p = 0; p < (int)route.size(); ++p){\n                    if (route[p].x == all[sel[oid]].pu.x && route[p].y == all[sel[oid]].pu.y) puOf[oid] = p;\n                    if (route[p].x == all[sel[oid]].de.x && route[p].y == all[sel[oid]].de.y) deOf[oid] = p;\n                }\n                ok &= (puOf[oid] < deOf[oid]);\n            }\n            if (ok) continue; // accept\n            /* rollback */\n            reverse(route.begin() + i + 1, route.begin() + j + 1);\n            for (int oid = 0; oid < 50; ++oid){\n                puOf[oid] = deOf[oid] = -1;\n                for (int p = 0; p < (int)route.size(); ++p){\n                    if (route[p].x == all[sel[oid]].pu.x && route[p].y == all[sel[oid]].pu.y) puOf[oid] = p;\n                    if (route[p].x == all[sel[oid]].de.x && route[p].y == all[sel[oid]].de.y) deOf[oid] = p;\n                }\n            }\n        }\n\n        ll T = length(route);\n        if (T < bestT){\n            bestT = T;\n            bestSel = sel;\n            bestRoute = route;\n        }\n    }\n\n    /* 4. output */\n    cout << 50;\n    for (int x : bestSel) cout << ' ' << x + 1;\n    cout << '\\n';\n    cout << bestRoute.size();\n    for (auto &p : bestRoute) cout << ' ' << p.x << ' ' << p.y;\n    cout << '\\n';\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct UnionFind {\n    vector<int> parent, rank;\n    int components;\n    \n    UnionFind(int n) : parent(n), rank(n, 0), components(n) {\n        for (int i = 0; i < n; i++) {\n            parent[i] = i;\n        }\n    }\n    \n    int find(int x) {\n        if (parent[x] != x) {\n            parent[x] = find(parent[x]);\n        }\n        return parent[x];\n    }\n    \n    bool unite(int x, int y) {\n        int px = find(x), py = find(y);\n        if (px == py) return false;\n        \n        if (rank[px] < rank[py]) {\n            parent[px] = py;\n        } else {\n            parent[py] = px;\n            if (rank[px] == rank[py]) {\n                rank[px]++;\n            }\n        }\n        components--;\n        return true;\n    }\n    \n    bool connected() {\n        return components == 1;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 400, M = 1995;\n    \n    // Read coordinates\n    vector<pair<int, int>> coords(N);\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    // Read edges and calculate expected lengths\n    vector<int> u(M), v(M);\n    vector<int> d(M);\n    \n    for (int i = 0; i < M; i++) {\n        cin >> u[i] >> v[i];\n        \n        // Calculate Euclidean distance\n        double dx = coords[u[i]].first - coords[v[i]].first;\n        double dy = coords[u[i]].second - coords[v[i]].second;\n        double dist = sqrt(dx*dx + dy*dy);\n        d[i] = round(dist);\n    }\n    \n    UnionFind uf(N);\n    int accepted = 0;\n    \n    // Process each edge\n    for (int i = 0; i < M; i++) {\n        int l;\n        cin >> l;\n        \n        bool adopt = false;\n        \n        // CRITICAL: Always accept if it connects different components\n        if (uf.find(u[i]) != uf.find(v[i])) {\n            adopt = true;\n            \n            // In late rounds, be even more aggressive about connectivity\n            if (i > M - 50 && !uf.connected()) {\n                // Always accept connecting edges in late rounds\n                adopt = true;\n            }\n        }\n        // Only accept non-connecting edges if they're really good deals\n        else if (accepted <= N + 20) {  // Allow some extra edges\n            // Calculate how good a deal this is\n            double ratio = (double)l / d[i];\n            // Accept if not too expensive (closer to minimum than maximum)\n            if (ratio <= 1.8) {\n                adopt = true;\n            }\n        }\n        // Emergency mode: if we're very late and still need connectivity\n        else if (i > M - 20 && !uf.connected() && (double)l / d[i] <= 2.2) {\n            adopt = true;\n        }\n        \n        if (adopt) {\n            uf.unite(u[i], v[i]);\n            accepted++;\n            cout << \"1\" << endl;\n        } else {\n            cout << \"0\" << endl;\n        }\n        \n        cout.flush();\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 30, W = 30, TURNS = 300;\nconst int dx[4] = {-1, 1, 0, 0}, dy[4] = {0, 0, -1, 1};\nconst char *dir = \"UDLR\", *Dir = \"UDLR\", *block = \"udlr\";\n\nint N, M;\nstruct Pet {\n    int x, y, t;\n} pets[20];\nstruct Human {\n    int x, y;\n} humans[10];\n\nbool wall[H][W]; // wall[x][y] = true if blocked\nint pet_x[20], pet_y[20];\n\n// BFS reachable squares from (sx,sy), return count and pet count\npair<int, int> bfs_reachable(int sx, int sy) {\n    static bool vis[H][W];\n    memset(vis, 0, sizeof(vis));\n    queue<pair<int, int>> q;\n    if (wall[sx][sy]) return {0, 0};\n    vis[sx][sy] = true;\n    q.push({sx, sy});\n    int cnt = 0, pcnt = 0;\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        cnt++;\n        for (int i = 0; i < N; i++) {\n            if (pet_x[i] == x && pet_y[i] == pcnt++) pcnt--;\n            if (pet_x[i] == x && pet_y[i] == y) pcnt++;\n        }\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n            if (wall[nx][ny] || vis[nx][ny]) continue;\n            vis[nx][ny] = true;\n            q.push({nx, ny});\n        }\n    }\n    return {cnt, pcnt};\n}\n\n// Heuristic score for a human at (x,y)\ndouble heuristic(int x, int y) {\n    auto [r, p] = bfs_reachable(x, y);\n    return r - 900.0 * p / 2.0;\n}\n\n// Check if can block (bx,by) from human at (x,y)\nbool can_block(int x, int y, int bx, int by) {\n    if (abs(bx - x) + abs(by - y) != 1) return false;\n    if (wall[bx][by]) return true; // already blocked\n    // Check if any pet or human is on (bx,by) at start\n    for (int i = 0; i < N; i++) {\n        if (pet_x[i] == bx && pet_y[i] == by) return false;\n    }\n    for (int i = 0; i < M; i++) {\n        if (humans[i].x == bx && humans[i].y == by) return false;\n    }\n    // Check if any pet is adjacent to (bx,by)\n    for (int d = 0; d < 4; d++) {\n        int nx = bx + dx[d], ny = by + dy[d];\n        if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n        for (int i = 0; i < N; i++) {\n            if (pet_x[i] == nx && pet_y[i] == ny) return false;\n        }\n    }\n    return true;\n}\n\n// Simulate pet moves (simplified: assume random for 1-3, greedy for 4-5)\nvoid simulate_pets() {\n    // For types 1-3: random basic moves (here we just do random)\n    // For types 4-5: target and move closer\n    // This is a placeholder: in real code, use BFS and rules\n    for (int i = 0; i < N; i++) {\n        int t = pets[i].t;\n        int &x = pet_x[i], &y = pet_y[i];\n        if (t <= 3) {\n            int steps = t;\n            while (steps--) {\n                vector<int> dirs;\n                for (int d = 0; d < 4; d++) {\n                    int nx = x + dx[d], ny = y + dy[d];\n                    if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n                    if (wall[nx][ny]) continue;\n                    dirs.push_back(d);\n                }\n                if (dirs.empty()) break;\n                int d = dirs[rand() % dirs.size()];\n                x += dx[d]; y += dy[d];\n            }\n        } else if (t == 4) {\n            // Dog: target human, move closer\n            // Simplified: pick random human and move one step closer\n            int ti = rand() % M;\n            int hx = humans[ti].x, hy = humans[ti].y;\n            // BFS to find direction\n            // For now, just move randomly\n            vector<int> dirs;\n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n                if (wall[nx][ny]) continue;\n                dirs.push_back(d);\n            }\n            if (!dirs.empty()) {\n                int d = dirs[rand() % dirs.size()];\n                x += dx[d]; y += dy[d];\n            }\n        } else {\n            // Cat: target square, move closer\n            // Simplified: move randomly\n            vector<int> dirs;\n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n                if (wall[nx][ny]) continue;\n                dirs.push_back(d);\n            }\n            if (!dirs.empty()) {\n                int d = dirs[rand() % dirs.size()];\n                x += dx[d]; y += dy[d];\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    for (int i = 0; i < N; i++) {\n        cin >> pets[i].x >> pets[i].y >> pets[i].t;\n        pets[i].x--; pets[i].y--;\n        pet_x[i] = pets[i].x;\n        pet_y[i] = pets[i].y;\n    }\n    cin >> M;\n    for (int i = 0; i < M; i++) {\n        cin >> humans[i].x >> humans[i].y;\n        humans[i].x--; humans[i].y--;\n    }\n\n    memset(wall, 0, sizeof(wall));\n\n    for (int turn = 0; turn < TURNS; turn++) {\n        string act;\n        for (int i = 0; i < M; i++) {\n            int x = humans[i].x, y = humans[i].y;\n            double best = -1e9;\n            char best_act = '.';\n            // Try stay\n            double sc = heuristic(x, y);\n            if (sc > best) { best = sc; best_act = '.'; }\n            // Try move\n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n                if (wall[nx][ny]) continue;\n                humans[i].x = nx; humans[i].y = ny;\n                sc = heuristic(nx, ny);\n                if (sc > best) { best = sc; best_act = Dir[d]; }\n                humans[i].x = x; humans[i].y = y;\n            }\n            // Try block\n            for (int d = 0; d < 4; d++) {\n                int bx = x + dx[d], by = y + dy[d];\n                if (!can_block(x, y, bx, by)) continue;\n                bool old = wall[bx][by];\n                wall[bx][by] = true;\n                sc = heuristic(x, y);\n                if (sc > best) { best = sc; best_act = block[d]; }\n                wall[bx][by] = old;\n            }\n            act += best_act;\n            // Apply best action\n            if (best_act == '.') {\n                // stay\n            } else if (best_act >= 'U' && best_act <= 'R') {\n                int d = best_act - 'U';\n                humans[i].x += dx[d];\n                humans[i].y += dy[d];\n            } else if (best_act >= 'u' && best_act <= 'r') {\n                int d = best_act - 'u';\n                int bx = x + dx[d], by = y + dy[d];\n                wall[bx][by] = true;\n            }\n        }\n        cout << act << endl;\n        cout.flush();\n\n        // Read pet moves\n        for (int i = 0; i < N; i++) {\n            string s;\n            cin >> s;\n            // Apply pet moves\n            int &x = pet_x[i], &y = pet_y[i];\n            for (char c : s) {\n                int d = -1;\n                if (c == 'U') d = 0;\n                else if (c == 'D') d = 1;\n                else if (c == 'L') d = 2;\n                else if (c == 'R') d = 3;\n                else continue;\n                int nx = x + dx[d], ny = y + dy[d];\n                if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n                if (wall[nx][ny]) continue;\n                x = nx; y = ny;\n            }\n        }\n    }\n\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic uint64_t rng_state = 123456789123456789ULL;\ninline uint64_t xorshift64() {\n    uint64_t x = rng_state;\n    x ^= x << 13;\n    x ^= x >> 7;\n    x ^= x << 17;\n    rng_state = x;\n    return x;\n}\ninline int randint(int l, int r) {   // [l, r]\n    return l + (xorshift64() % (r - l + 1));\n}\ninline double rand01() {\n    return (xorshift64() & ((1ULL<<32)-1)) / double(1ULL<<32);\n}\n\nint si, sj, ti, tj;\ndouble pforget;\nbool wallh[20][19]; // wallh[i][j] blocks (i,j)-(i,j+1)\nbool wallv[19][20]; // wallv[i][j] blocks (i,j)-(i+1,j)\nint dist[20][20];\nint best_len;\nstring best_str;\ndouble best_score;\n\nconst int INF = 1000000;\n\nvoid bfs_dist() {\n    for(int i=0;i<20;i++)for(int j=0;j<20;j++) dist[i][j]=INF;\n    deque<pair<int,int>> dq;\n    dist[ti][tj]=0;\n    dq.push_back({ti,tj});\n    static int di[4]={-1,1,0,0}, dj[4]={0,0,-1,1};\n    while(!dq.empty()){\n        auto [i,j]=dq.front(); dq.pop_front();\n        for(int d=0;d<4;d++){\n            int ni=i+di[d], nj=j+dj[d];\n            if(ni<0||nj<0||ni>=20||nj>=20) continue;\n            if(d==0 && wallv[ni][j]) continue; // up\n            if(d==1 && wallv[i][j]) continue;   // down\n            if(d==2 && wallh[i][nj]) continue;  // left\n            if(d==3 && wallh[i][j]) continue;   // right\n            if(dist[ni][nj]>dist[i][j]+1){\n                dist[ni][nj]=dist[i][j]+1;\n                dq.push_back({ni,nj});\n            }\n        }\n    }\n}\n\ninline bool can_move(int i, int j, int d) {\n    if(d==0){ // U\n        if(i==0) return false;\n        return !wallv[i-1][j];\n    } else if(d==1){ // D\n        if(i==19) return false;\n        return !wallv[i][j];\n    } else if(d==2){ // L\n        if(j==0) return false;\n        return !wallh[i][j-1];\n    } else { // R\n        if(j==19) return false;\n        return !wallh[i][j];\n    }\n}\n\ninline int move_i(int i, int d) {\n    if(d==0) return i-1;\n    if(d==1) return i+1;\n    return i;\n}\ninline int move_j(int j, int d) {\n    if(d==2) return j-1;\n    if(d==3) return j+1;\n    return j;\n}\n\ndouble eval(const string &s) {\n    const int L = s.size();\n    static double cur[400], nxt[400];\n    for(int v=0;v<400;v++) cur[v]=0.0;\n    int start = si*20 + sj;\n    cur[start] = 1.0;\n    int goal = ti*20 + tj;\n    double succ = 0.0;\n    double et = 0.0;\n    for(int t=0;t<L;t++){\n        for(int v=0;v<400;v++) nxt[v]=0.0;\n        for(int v=0;v<400;v++){\n            if(cur[v]<1e-14) continue;\n            int i=v/20, j=v%20;\n            if(i==ti&&j==tj) continue; // already absorbed\n            int nopen=0;\n            for(int d=0;d<4;d++) if(can_move(i,j,d)) nopen++;\n            double p_stay = pforget;\n            if(nopen==0){\n                p_stay += (1-pforget);\n            } else {\n                p_stay += (1-pforget)*0; // no extra stay from walls\n            }\n            // forget \u2192 stay\n            nxt[v] += cur[v] * pforget;\n            // try to move\n            if(nopen>0){\n                double p_dir = (1-pforget) / nopen;\n                for(int d=0;d<4;d++){\n                    if(!can_move(i,j,d)) continue;\n                    int ni=move_i(i,d), nj=move_j(j,d);\n                    int u=ni*20+nj;\n                    if(ni==ti&&nj==tj){\n                        // absorbed at t+1\n                        double prob = cur[v] * p_dir;\n                        succ += prob;\n                        et += prob * (t+1);\n                    } else {\n                        nxt[u] += cur[v] * p_dir;\n                    }\n                }\n            } else {\n                // all directions blocked \u2192 forced stay\n                nxt[v] += cur[v] * (1-pforget);\n            }\n        }\n        swap(cur, nxt);\n    }\n    double left=0.0;\n    for(int v=0;v<400;v++) left+=cur[v];\n    succ = 1.0 - left;\n    // et already contains sum t*prob(t)\n    if(succ<1e-14) return 0.0;\n    double mean_t = et / succ;\n    double es = succ * (401.0 - mean_t);\n    return es;\n}\n\nstring greedy_random_walk(int want_len) {\n    string path;\n    int i=si, j=sj;\n    static int dirs[4]={0,1,2,3};\n    while((int)path.size() < want_len) {\n        if(i==ti && j==tj) break;\n        // shuffle directions\n        for(int k=0;k<4;k++){\n            int r=randint(k,3);\n            swap(dirs[k],dirs[r]);\n        }\n        double best_val=-1e9;\n        int best_d=-1;\n        for(int k=0;k<4;k++){\n            int d=dirs[k];\n            if(!can_move(i,j,d)) continue;\n            int ni=move_i(i,d), nj=move_j(j,d);\n            double val = -(dist[ni][nj]) + rand01()*0.3;\n            if(val>best_val){\n                best_val=val;\n                best_d=d;\n            }\n        }\n        if(best_d>=0){\n            path += \"UDLR\"[best_d];\n            i=move_i(i,best_d);\n            j=move_j(j,best_d);\n        } else {\n            // trapped \u2192 stay, any char\n            path += 'U';\n        }\n    }\n    // if we reached goal early, pad with something safe\n    while((int)path.size() < want_len){\n        if(i==ti&&j==tj){\n            path+='R'; // safe arbitrary\n        } else {\n            // greedy again\n            int dbest=-1, dbestv=INF;\n            for(int d=0;d<4;d++){\n                if(!can_move(i,j,d)) continue;\n                int ni=move_i(i,d), nj=move_j(j,d);\n                if(dist[ni][nj]<dbestv){\n                    dbestv=dist[ni][nj];\n                    dbest=d;\n                }\n            }\n            if(dbest>=0){\n                path+=\"UDLR\"[dbest];\n                i=move_i(i,dbest);\n                j=move_j(j,dbest);\n            } else {\n                path+='U';\n            }\n        }\n    }\n    return path;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin>>si>>sj>>ti>>tj>>pforget;\n    for(int i=0;i<20;i++){\n        string row; cin>>row;\n        for(int j=0;j<19;j++) wallh[i][j]=(row[j]=='1');\n    }\n    for(int i=0;i<19;i++){\n        string row; cin>>row;\n        for(int j=0;j<20;j++) wallv[i][j]=(row[j]=='1');\n    }\n\n    bfs_dist();\n\n    best_score=-1e9;\n    best_len=-1;\n\n    // spend ~1.8 seconds iterating\n    const auto start_time = chrono::steady_clock::now();\n    int attempt=0;\n    while(1){\n        attempt++;\n        auto now=chrono::steady_clock::now();\n        double elapsed=chrono::duration<double>(now-start_time).count();\n        if(elapsed>1.85) break;\n\n        int want_len = randint(60,180);\n        string cand = greedy_random_walk(want_len);\n        double sc = eval(cand);\n        if(sc>best_score){\n            best_score=sc;\n            best_str=cand;\n            best_len=want_len;\n        }\n    }\n\n    cout<<best_str<<\"\\n\";\n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <random>\n#include <algorithm>\n#include <chrono>\n#include <queue>\n#include <unordered_set>\n\nusing namespace std;\n\nconst int SIZE = 30;\nconst int DIR[4][2] = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};\n\nconst int to[8][4] = {\n    {1, 0, -1, -1},  // type 0\n    {3, -1, -1, 0},  // type 1\n    {-1, -1, 3, 2},  // type 2\n    {-1, 2, 1, -1},  // type 3\n    {1, 0, 3, 2},    // type 4\n    {3, 2, 1, 0},    // type 5\n    {2, -1, 0, -1},  // type 6\n    {-1, 3, -1, 1}   // type 7\n};\n\nint grid[SIZE][SIZE];\nint rotation[SIZE][SIZE];\nint best_rotation[SIZE][SIZE];\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\ninline int get_tile_type(int i, int j) {\n    int base_type = grid[i][j];\n    int rot = rotation[i][j];\n    if (base_type <= 3) {\n        return (base_type + rot) % 4;\n    } else if (base_type <= 5) {\n        return 4 + (base_type - 4 + rot) % 2;\n    } else {\n        return 6 + (base_type - 6 + rot) % 2;\n    }\n}\n\nint trace_loop(int si, int sj, int sd) {\n    int i = si, j = sj, d = sd;\n    int length = 0;\n    \n    for (int step = 0; step < 2000; step++) {\n        int tile_type = get_tile_type(i, j);\n        int d2 = to[tile_type][d];\n        if (d2 == -1) return 0;\n        \n        i += DIR[d2][0];\n        j += DIR[d2][1];\n        if (i < 0 || i >= SIZE || j < 0 || j >= SIZE) return 0;\n        \n        d = (d2 + 2) % 4;\n        length++;\n        \n        if (i == si && j == sj && d == sd) return length;\n    }\n    return 0;\n}\n\npair<int, int> find_loops_adaptive() {\n    vector<int> loop_lengths;\n    static vector<pair<int, int>> hotspots;\n    \n    // Initial hotspots\n    if (hotspots.empty()) {\n        // Center and edge areas\n        for (int i = 3; i < SIZE-3; i += 2) {\n            for (int j = 3; j < SIZE-3; j += 2) {\n                hotspots.push_back({i, j});\n            }\n        }\n    }\n    \n    // Check hotspots first\n    for (auto [i, j] : hotspots) {\n        if (i >= 0 && i < SIZE && j >= 0 && j < SIZE) {\n            for (int d = 0; d < 4; d++) {\n                int len = trace_loop(i, j, d);\n                if (len > 8) {\n                    loop_lengths.push_back(len);\n                    // Add neighbors of successful loops as new hotspots\n                    for (int di = -1; di <= 1; di++) {\n                        for (int dj = -1; dj <= 1; dj++) {\n                            if (di != 0 || dj != 0) {\n                                int ni = i + di, nj = j + dj;\n                                if (ni >= 0 && ni < SIZE && nj >= 0 && nj < SIZE) {\n                                    hotspots.push_back({ni, nj});\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Remove duplicates and limit hotspots\n    sort(hotspots.begin(), hotspots.end());\n    hotspots.erase(unique(hotspots.begin(), hotspots.end()), hotspots.end());\n    if (hotspots.size() > 200) {\n        hotspots.resize(200);\n    }\n    \n    // Fill with some random positions if needed\n    while (loop_lengths.size() < 10 && !hotspots.empty()) {\n        int idx = rng() % hotspots.size();\n        int i = hotspots[idx].first;\n        int j = hotspots[idx].second;\n        int d = rng() % 4;\n        int len = trace_loop(i, j, d);\n        if (len > 6) {\n            loop_lengths.push_back(len);\n        }\n        hotspots.erase(hotspots.begin() + idx);\n    }\n    \n    sort(loop_lengths.rbegin(), loop_lengths.rend());\n    if (loop_lengths.size() < 2) return {0, 0};\n    return {loop_lengths[0], loop_lengths[1]};\n}\n\nint calculate_score() {\n    auto [l1, l2] = find_loops_adaptive();\n    return l1 * l2;\n}\n\nvoid pattern_based_search() {\n    int best_score = 0;\n    \n    // Try different initialization patterns\n    vector<void(*)()> init_patterns = {\n        []() { // Smart pattern 1\n            for (int i = 0; i < SIZE; i++) {\n                for (int j = 0; j < SIZE; j++) {\n                    rotation[i][j] = ((i ^ j) + (i + j) / 3) % 4;\n                }\n            }\n        },\n        []() { // Smart pattern 2\n            for (int i = 0; i < SIZE; i++) {\n                for (int j = 0; j < SIZE; j++) {\n                    rotation[i][j] = (i * 2 + j * 3 + (i * j) / 10) % 4;\n                }\n            }\n        },\n        []() { // Random\n            for (int i = 0; i < SIZE; i++) {\n                for (int j = 0; j < SIZE; j++) {\n                    rotation[i][j] = rng() % 4;\n                }\n            }\n        }\n    };\n    \n    for (int pattern_idx = 0; pattern_idx < init_patterns.size(); pattern_idx++) {\n        init_patterns[pattern_idx]();\n        \n        int current_score = calculate_score();\n        int local_best = current_score;\n        \n        // Beam search with multiple candidates\n        const int beam_width = 5;\n        vector<vector<vector<int>>> candidates(beam_width, vector<vector<int>>(SIZE, vector<int>(SIZE)));\n        vector<int> candidate_scores(beam_width, current_score);\n        \n        // Fill initial candidates\n        for (int b = 0; b < beam_width; b++) {\n            for (int i = 0; i < SIZE; i++) {\n                for (int j = 0; j < SIZE; j++) {\n                    candidates[b][i][j] = rotation[i][j];\n                }\n            }\n        }\n        \n        // Iterative improvement\n        for (int iter = 0; iter < 1000; iter++) {\n            vector<pair<int, vector<vector<int>>>> all_candidates;\n            \n            // Generate neighbors for each beam candidate\n            for (int b = 0; b < beam_width; b++) {\n                // Copy current candidate to rotation\n                for (int i = 0; i < SIZE; i++) {\n                    for (int j = 0; j < SIZE; j++) {\n                        rotation[i][j] = candidates[b][i][j];\n                    }\n                }\n                \n                // Try pattern moves\n                for (int pattern = 0; pattern < 3; pattern++) {\n                    int center_i = rng() % (SIZE - 4) + 2;\n                    int center_j = rng() % (SIZE - 4) + 2;\n                    \n                    // Apply 2x2 pattern rotation\n                    for (int di = 0; di < 2; di++) {\n                        for (int dj = 0; dj < 2; dj++) {\n                            int ni = center_i + di;\n                            int nj = center_j + dj;\n                            rotation[ni][nj] = (rotation[ni][nj] + 1 + pattern) % 4;\n                        }\n                    }\n                    \n                    int score = calculate_score();\n                    all_candidates.push_back({score, vector<vector<int>>(SIZE, vector<int>(SIZE))});\n                    \n                    for (int i = 0; i < SIZE; i++) {\n                        for (int j = 0; j < SIZE; j++) {\n                            all_candidates.back().second[i][j] = rotation[i][j];\n                        }\n                    }\n                    \n                    // Revert for next try\n                    for (int di = 0; di < 2; di++) {\n                        for (int dj = 0; dj < 2; dj++) {\n                            int ni = center_i + di;\n                            int nj = center_j + dj;\n                            rotation[ni][nj] = candidates[b][ni][nj];\n                        }\n                    }\n                }\n            }\n            \n            // Keep best candidates\n            sort(all_candidates.rbegin(), all_candidates.rend());\n            int new_beam_size = min(beam_width, (int)all_candidates.size());\n            \n            for (int b = 0; b < new_beam_size; b++) {\n                candidate_scores[b] = all_candidates[b].first;\n                candidates[b] = all_candidates[b].second;\n                \n                if (all_candidates[b].first > local_best) {\n                    local_best = all_candidates[b].first;\n                    for (int i = 0; i < SIZE; i++) {\n                        for (int j = 0; j < SIZE; j++) {\n                            rotation[i][j] = all_candidates[b].second[i][j];\n                        }\n                    }\n                }\n            }\n            \n            if (iter > 200 && local_best == current_score) break;\n            current_score = local_best;\n        }\n        \n        if (current_score > best_score) {\n            best_score = current_score;\n            for (int i = 0; i < SIZE; i++) {\n                for (int j = 0; j < SIZE; j++) {\n                    best_rotation[i][j] = rotation[i][j];\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    for (int i = 0; i < SIZE; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < SIZE; j++) {\n            grid[i][j] = line[j] - '0';\n        }\n    }\n    \n    // Run pattern-based search\n    pattern_based_search();\n    \n    // Output best solution\n    for (int i = 0; i < SIZE; i++) {\n        for (int j = 0; j < SIZE; j++) {\n            cout << best_rotation[i][j];\n        }\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc011":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <unordered_set>\n#include <chrono>\n\nusing namespace std;\n\nconst int dx[4] = {-1, 0, 1, 0};\nconst int dy[4] = {0, 1, 0, -1};\nconst char dir_char[4] = {'U', 'R', 'D', 'L'};\n\nint N, T;\nvector<vector<int>> board;\nint empty_row, empty_col;\nstring solution;\n\nbool has_line(int tile, int direction) {\n    return (tile >> direction) & 1;\n}\n\nbool can_connect(int tile1, int tile2, int direction) {\n    // direction: 0=up, 1=right, 2=down, 3=left\n    int opposite = (direction + 2) % 4;\n    return has_line(tile1, direction) && has_line(tile2, opposite);\n}\n\nint count_connections() {\n    int connections = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0) continue;\n            \n            // Check down connection\n            if (i < N-1 && board[i+1][j] != 0) {\n                if (can_connect(board[i][j], board[i+1][j], 2)) {\n                    connections++;\n                }\n            }\n            \n            // Check right connection\n            if (j < N-1 && board[i][j+1] != 0) {\n                if (can_connect(board[i][j], board[i][j+1], 1)) {\n                    connections++;\n                }\n            }\n        }\n    }\n    return connections;\n}\n\nint find_largest_tree() {\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    int max_size = 0;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0 || visited[i][j]) continue;\n            \n            queue<pair<int, int>> q;\n            q.push({i, j});\n            visited[i][j] = true;\n            int size = 0;\n            \n            while (!q.empty()) {\n                auto [r, c] = q.front();\n                q.pop();\n                size++;\n                \n                // Check all 4 directions\n                for (int d = 0; d < 4; d++) {\n                    int nr = r + dx[d];\n                    int nc = c + dy[d];\n                    \n                    if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n                    if (board[nr][nc] == 0 || visited[nr][nc]) continue;\n                    if (!can_connect(board[r][c], board[nr][nc], d)) continue;\n                    \n                    visited[nr][nc] = true;\n                    q.push({nr, nc});\n                }\n            }\n            \n            max_size = max(max_size, size);\n        }\n    }\n    \n    return max_size;\n}\n\nbool is_valid_move(int r, int c) {\n    return r >= 0 && r < N && c >= 0 && c < N && board[r][c] != 0;\n}\n\nvoid make_move(int direction) {\n    int nr = empty_row + dx[direction];\n    int nc = empty_col + dy[direction];\n    \n    if (!is_valid_move(nr, nc)) return;\n    \n    swap(board[empty_row][empty_col], board[nr][nc]);\n    empty_row = nr;\n    empty_col = nc;\n    solution += dir_char[direction];\n}\n\nvoid solve_greedy() {\n    auto start_time = chrono::high_resolution_clock::now();\n    int best_tree = find_largest_tree();\n    \n    while (solution.size() < T) {\n        int best_improvement = 0;\n        int best_direction = -1;\n        \n        for (int d = 0; d < 4; d++) {\n            int nr = empty_row + dx[d];\n            int nc = empty_col + dy[d];\n            \n            if (!is_valid_move(nr, nc)) continue;\n            \n            // Try the move\n            swap(board[empty_row][empty_col], board[nr][nc]);\n            int new_tree = find_largest_tree();\n            int improvement = new_tree - best_tree;\n            \n            // Undo the move\n            swap(board[empty_row][empty_col], board[nr][nc]);\n            \n            if (improvement > best_improvement) {\n                best_improvement = improvement;\n                best_direction = d;\n            }\n        }\n        \n        if (best_direction == -1) {\n            // No improving move, try random\n            best_direction = rand() % 4;\n        }\n        \n        make_move(best_direction);\n        best_tree = find_largest_tree();\n        \n        // Check time limit\n        auto current_time = chrono::high_resolution_clock::now();\n        auto elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count();\n        if (elapsed > 2800) break; // Leave some margin\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> T;\n    board.assign(N, vector<int>(N));\n    \n    for (int i = 0; i < N; i++) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < N; j++) {\n            char c = row[j];\n            if (c == '0') {\n                board[i][j] = 0;\n                empty_row = i;\n                empty_col = j;\n            } else if (c >= '1' && c <= '9') {\n                board[i][j] = c - '0';\n            } else {\n                board[i][j] = c - 'a' + 10;\n            }\n        }\n    }\n    \n    solve_greedy();\n    \n    cout << solution << endl;\n    \n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\nusing int64 = long long;\nusing f64 = long double;\n\n/* ---------- geometry primitives ---------- */\nconst f64 EPS = 1e-9L;\ninline int sign(f64 x) { return (x > EPS) - (x < -EPS); }\n\nstruct Line {\n    f64 A, B, C;          // A x + B y + C = 0,  A\u00b2+B\u00b2=1\n    Line() = default;\n    Line(f64 a, f64 b, f64 c) : A(a), B(b), C(c) { norm(); }\n    // through (x1,y1)->(x2,y2)\n    Line(f64 x1, f64 y1, f64 x2, f64 y2) {\n        A = y2 - y1;\n        B = x1 - x2;\n        C = x2*y1 - x1*y2;\n        norm();\n    }\n    void norm() {\n        f64 s = sqrtl(A*A + B*B);\n        if (s > EPS) { A /= s; B /= s; C /= s; }\n    }\n    int side(f64 x, f64 y) const {\n        f64 v = A*x + B*y + C;\n        return sign(v);\n    }\n};\n\n/* ---------- global input ---------- */\nint N, K;\nvector<int> a(11);            // 1..10\nvector<f64> X, Y;\n\n/* ---------- current state ---------- */\nint kUsed = 0;                // lines used so far\nvector<Line> lines;\nusing Bits = bitset<100>;\nvector<Bits> regionCode;      // regionCode[r] = sign vector\nvector<int> regionCount;      // regionCount[r] = #strawberries inside\nunordered_map<uint64_t, int> regMap; // hash of sign vector -> index\n\nint have[11] = {};            // have[d] = #regions with d strawberries\nint objective = 0;\n\n/* ---------- evaluation ---------- */\nint eval() {\n    int obj = 0;\n    for (int d = 1; d <= 10; ++d) obj += min(a[d], have[d]);\n    return obj;\n}\n\n/* ---------- incremental add line ---------- */\nvoid addLine(const Line &L) {\n    if (kUsed == K) return;\n    int id = kUsed++;\n    lines[id] = L;\n\n    // re-index regions\n    unordered_map<uint64_t, int> newMap;\n    vector<Bits> newCode;\n    vector<int> newCount;\n    int newR = 0;\n\n    // helper: hash of bitset\n    auto hashBits = [&](const Bits &b) -> uint64_t {\n        return b._Get_hash(); // libstdc++ extension, fast\n    };\n\n    // split every existing region\n    for (int r = 0; r < (int)regionCode.size(); ++r) {\n        int cnt = regionCount[r];\n        if (cnt == 0) continue;\n\n        Bits oldSig = regionCode[r];\n        // count strawberries on each side\n        int cntP = 0, cntM = 0, cnt0 = 0;\n        // we need to know which strawberries belong to region r\n        // but we don't store per-region lists -> re-scan all points\n        // This is O(N) per region, but total regions <= 5051 and N<=1000 -> acceptable\n        Bits sigP = oldSig, sigM = oldSig;\n        sigP.set(id);        // +1 side\n        sigM.reset(id);      // -1 side\n\n        for (int i = 0; i < N; ++i) {\n            int s = L.side(X[i], Y[i]);\n            if (s == 0) { cnt0++; continue; }\n            if (s > 0) cntP++; else cntM++;\n        }\n        // two children\n        if (cntP > 0) {\n            uint64_t h = hashBits(sigP);\n            auto it = newMap.find(h);\n            if (it == newMap.end()) {\n                newMap[h] = newR;\n                newCode.push_back(sigP);\n                newCount.push_back(cntP);\n                ++newR;\n            } else {\n                newCount[it->second] += cntP;\n            }\n        }\n        if (cntM > 0) {\n            uint64_t h = hashBits(sigM);\n            auto it = newMap.find(h);\n            if (it == newMap.end()) {\n                newMap[h] = newR;\n                newCode.push_back(sigM);\n                newCount.push_back(cntM);\n                ++newR;\n            } else {\n                newCount[it->second] += cntM;\n            }\n        }\n        // strawberries on the line (cnt0) are lost\n    }\n\n    // rebuild global arrays\n    regMap.swap(newMap);\n    regionCode.swap(newCode);\n    regionCount.swap(newCount);\n\n    // rebuild have[] and objective\n    fill(have, have+11, 0);\n    for (int c : regionCount) if (c <= 10) have[c]++;\n    objective = eval();\n}\n\n/* ---------- greedy candidate generation ---------- */\nLine bestGreedyLine() {\n    static mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> distN(0, N-1);\n    uniform_int_distribution<int> distC(-100000, 100000);\n    uniform_real_distribution<f64> distA(0, M_PIl);\n\n    int bestGain = 0;\n    Line bestL;\n\n    auto tryLine = [&](const Line &L) {\n        // simulate addLine without really modifying state\n        unordered_map<uint64_t, int> tmpMap;\n        vector<int> tmpCount;\n        vector<Bits> tmpCode;\n        int tmpHave[11] = {};\n        int tmpObj = 0;\n\n        // copy current state\n        for (int r = 0; r < (int)regionCode.size(); ++r) {\n            int cnt = regionCount[r];\n            if (cnt == 0) continue;\n            int cntP = 0, cntM = 0;\n            Bits sigP = regionCode[r], sigM = regionCode[r];\n            sigP.set(kUsed);\n            sigM.reset(kUsed);\n            for (int i = 0; i < N; ++i) {\n                int s = L.side(X[i], Y[i]);\n                if (s == 0) continue;\n                if (s > 0) cntP++; else cntM++;\n            }\n            if (cntP > 0) {\n                tmpCount.push_back(cntP);\n                tmpCode.push_back(sigP);\n            }\n            if (cntM > 0) {\n                tmpCount.push_back(cntM);\n                tmpCode.push_back(sigM);\n            }\n        }\n        for (int c : tmpCount) if (c <= 10) tmpHave[c]++;\n        for (int d = 1; d <= 10; ++d) tmpObj += min(a[d], tmpHave[d]);\n        int gain = tmpObj - objective;\n        if (gain > bestGain) {\n            bestGain = gain;\n            bestL = L;\n        }\n    };\n\n    // try random point-pairs\n    const int TRIES = 400;\n    for (int t = 0; t < TRIES; ++t) {\n        int i = distN(rng), j = distN(rng);\n        if (i == j) continue;\n        Line L(X[i], Y[i], X[j], Y[j]);\n        tryLine(L);\n    }\n    // try random directions through random points\n    for (int t = 0; t < TRIES; ++t) {\n        int i = distN(rng);\n        f64 ang = distA(rng);\n        f64 dx = cosl(ang), dy = sinl(ang);\n        Line L(X[i], Y[i], X[i] + dx, Y[i] + dy);\n        tryLine(L);\n    }\n    // try a few axis-aligned\n    for (int t = 0; t < 20; ++t) {\n        f64 x = distC(rng) * 1000;\n        Line L(1, 0, -x);\n        tryLine(L);\n        Line L2(0, 1, -x);\n        tryLine(L2);\n    }\n    return bestL;\n}\n\n/* ---------- main ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    auto clk_start = chrono::steady_clock::now();\n\n    cin >> N >> K;\n    for (int d = 1; d <= 10; ++d) cin >> a[d];\n    X.resize(N); Y.resize(N);\n    for (int i = 0; i < N; ++i) cin >> X[i] >> Y[i];\n\n    // initial state: 1 region\n    lines.assign(K, Line());\n    regionCode.clear();\n    regionCount.clear();\n    regMap.clear();\n    Bits initialSig;\n    initialSig.reset();\n    regionCode.push_back(initialSig);\n    regionCount.push_back(N);\n    regMap[initialSig._Get_hash()] = 0;\n    fill(have, have+11, 0);\n    have[min(N, 10)] = 1;\n    objective = eval();\n\n    // iterated greedy + local search\n    int bestEver = objective;\n    vector<Line> bestLines;\n    int bestK = 0;\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - clk_start).count();\n        if (elapsed > 2.85) break;\n\n        // greedy addition pass\n        while (kUsed < K) {\n            Line L = bestGreedyLine();\n            if (objective >= bestEver) {\n                bestEver = objective;\n                bestLines = vector<Line>(lines.begin(), lines.begin() + kUsed);\n                bestK = kUsed;\n            }\n            addLine(L);\n        }\n\n        // local perturbation: delete last 5 and re-add greedily\n        if (kUsed >= 5) {\n            for (int del = 0; del < 5; ++del) {\n                // remove last line\n                kUsed--;\n                // rebuild entire state from scratch (simplest)\n                regionCode.clear();\n                regionCount.clear();\n                regMap.clear();\n                Bits init;\n                init.reset();\n                regionCode.push_back(init);\n                regionCount.push_back(0);\n                regMap[init._Get_hash()] = 0;\n                // recount\n                fill(have, have+11, 0);\n                for (int i = 0; i < N; ++i) {\n                    Bits sig;\n                    sig.reset();\n                    for (int j = 0; j < kUsed; ++j) {\n                        int s = lines[j].side(X[i], Y[i]);\n                        if (s > 0) sig.set(j);\n                    }\n                    uint64_t h = sig._Get_hash();\n                    auto it = regMap.find(h);\n                    int r;\n                    if (it == regMap.end()) {\n                        r = regionCode.size();\n                        regMap[h] = r;\n                        regionCode.push_back(sig);\n                        regionCount.push_back(0);\n                    } else {\n                        r = it->second;\n                    }\n                    regionCount[r]++;\n                }\n                fill(have, have+11, 0);\n                for (int c : regionCount) if (c <= 10) have[c]++;\n                objective = eval();\n            }\n        }\n    }\n\n    // output best\n    cout << bestK << '\\n';\n    cout << fixed << setprecision(0);\n    for (int i = 0; i < bestK; ++i) {\n        // pick two integer points on the line\n        f64 A = bestLines[i].A, B = bestLines[i].B, C = bestLines[i].C;\n        // choose x1,y1,x2,y2 integers\n        int64_t x1, y1, x2, y2;\n        if (fabs(B) > EPS) {\n            x1 = 0;\n            y1 = llround(-C / B);\n            x2 = 1;\n            y2 = llround((-C - A) / B);\n        } else {\n            y1 = 0;\n            x1 = llround(-C / A);\n            y2 = 1;\n            x2 = llround((-C) / A);\n        }\n        cout << x1 << ' ' << y1 << ' ' << x2 << ' ' << y2 << '\\n';\n    }\n    return 0;\n}","ahc014":"#pragma GCC target(\"avx2\")\n#pragma GCC optimize(\"O3\")\n#pragma GCC optimize(\"unroll-loops\")\n#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing ll = long long;\n#define rep(i, n) for (int i = 0; i < (int)(n); i++)\n\n// ---------- \u8fba\u306e\u7b26\u53f7\u5316 ----------\ninline uint64_t ecode(int x1, int y1, int x2, int y2) {\n    if (x1 > x2 || (x1 == x2 && y1 > y2)) {\n        swap(x1, x2); swap(y1, y2);\n    }\n    return ((uint64_t)(uint16_t)x1 << 48) | ((uint64_t)(uint16_t)y1 << 32) |\n           ((uint64_t)(uint16_t)x2 << 16) | (uint64_t)(uint16_t)y2;\n}\n\n// ---------- \u30b0\u30ed\u30fc\u30d0\u30eb ----------\nint N, M;\nint c;\nvector<vector<int>> w;               // \u91cd\u307f\nvector<vector<bool>> dot;            // dot[x][y]\nstd::unordered_set<uint64_t> used_edge;   // \u4fee\u6b63\uff1astd \u3092\u4f7f\u3046\nvector<tuple<int,int,int,int,int,int,int,int>> ops;  // \u64cd\u4f5c\u5c65\u6b74\n\n// ---------- \u65b9\u5411 ----------\nconst int dx45[4] = {1, 1, -1, -1};\nconst int dy45[4] = {1, -1, -1, 1};\nconst int dxax[4] = {1, 0, -1, 0};\nconst int dyax[4] = {0, 1, 0, -1};\n\n// ---------- \u77e9\u5f62\u3092\u8a66\u3059 ----------\nbool try_rect(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    // 4\u9802\u70b9\u306e\u9806\u5e8f\u3092\u6b63\u3057\u304f\u56de\u3057\u3001p1=(x1,y1) \u304c\u7a7a\u3001\u4ed6\u304c dot \u3067\u3042\u308b\u3053\u3068\n    if (!dot[x2][y2] || !dot[x3][y3] || !dot[x4][y4]) return false;\n    if (dot[x1][y1]) return false;\n    // 4\u8fba\u306e\u7b26\u53f7\u5316\n    uint64_t e1 = ecode(x1,y1,x2,y2);\n    uint64_t e2 = ecode(x2,y2,x3,y3);\n    uint64_t e3 = ecode(x3,y3,x4,y4);\n    uint64_t e4 = ecode(x4,y4,x1,y1);\n    if (used_edge.count(e1) || used_edge.count(e2) ||\n        used_edge.count(e3) || used_edge.count(e4)) return false;\n    // \u8fba\u4e0a\u306b\u4ed6\u30c9\u30c3\u30c8\u304c\u306a\u3044\u304b\uff08\u7c21\u6613\uff1agcd \u3067\u7b49\u5206\u70b9\u30c1\u30a7\u30c3\u30af\uff09\n    auto check_edge = [&](int ax, int ay, int bx, int by) {\n        int dx = bx - ax, dy = by - ay;\n        int g = gcd(abs(dx), abs(dy));\n        int stepx = dx / g, stepy = dy / g;\n        for (int t = 1; t < g; t++) {\n            int xx = ax + t * stepx, yy = ay + t * stepy;\n            if (dot[xx][yy]) return false;\n        }\n        return true;\n    };\n    if (!check_edge(x1,y1,x2,y2)) return false;\n    if (!check_edge(x2,y2,x3,y3)) return false;\n    if (!check_edge(x3,y3,x4,y4)) return false;\n    if (!check_edge(x4,y4,x1,y1)) return false;\n    // \u5b9f\u884c\n    dot[x1][y1] = true;\n    used_edge.insert(e1);\n    used_edge.insert(e2);\n    used_edge.insert(e3);\n    used_edge.insert(e4);\n    ops.emplace_back(x1,y1,x2,y2,x3,y3,x4,y4);\n    return true;\n}\n\n// ---------- \u30e1\u30a4\u30f3 ----------\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    auto clk_st = chrono::steady_clock::now();\n\n    cin >> N >> M;\n    c = (N - 1) / 2;\n    w.assign(N, vector<int>(N));\n    dot.assign(N, vector<bool>(N, false));\n    ll S = 0;\n    rep(x,N) rep(y,N) {\n        int wx = (x - c) * (x - c) + (y - c) * (y - c) + 1;\n        w[x][y] = wx;\n        S += wx;\n    }\n    rep(i,M){\n        int x,y; cin >> x >> y;\n        dot[x][y] = true;\n    }\n\n    // \u9ad8\u91cd\u307f\u9806\u306b\u7a7a\u30de\u30b9\u3092\u62fe\u3046\u305f\u3081\u306e\u30ea\u30b9\u30c8\n    vector<pair<int,int>> cells;\n    rep(x,N) rep(y,N) if (!dot[x][y]) cells.emplace_back(x,y);\n    // \u91cd\u307f\u5927\u304d\u3044\u9806\u306b\u30bd\u30fc\u30c8\n    sort(cells.begin(), cells.end(), [&](auto &a, auto &b){\n        return w[a.first][a.second] > w[b.first][b.second];\n    });\n\n    // \u8caa\u6b32\u30e1\u30a4\u30f3\n    const double TIME_LIMIT = 4.8;\n    int iter = 0, total = cells.size();\n    while (1) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - clk_st).count();\n        if (elapsed > TIME_LIMIT) break;\n\n        // \u30e9\u30f3\u30c0\u30e0\u306b\u30d0\u30c3\u30c1\u3092\u62fe\u3046\uff08\u91cd\u3044\u9806\u306b\u3057\u3064\u3064\u30e9\u30f3\u30c0\u30e0\u30cd\u30b9\uff09\n        int batch = min(500, total);\n        vector<int> idx(batch);\n        rep(i,batch) idx[i] = (iter + i) % total;\n        shuffle(idx.begin(), idx.end(), mt19937(iter));\n\n        bool progress = false;\n        for (int i : idx) {\n            auto [x1,y1] = cells[i];\n            if (dot[x1][y1]) continue;\n            // \u8ef8\u5e73\u884c\u9577\u65b9\u5f62\u30924\u65b9\u5411\n            for (int d = 0; d < 4; d++) {\n                int len = 1;\n                while (1) {\n                    int x2 = x1 + len * dxax[d], y2 = y1 + len * dyax[d];\n                    int x3 = x2 + len * dxax[(d+1)&3], y3 = y2 + len * dyax[(d+1)&3];\n                    int x4 = x1 + len * dxax[(d+1)&3], y4 = y1 + len * dyax[(d+1)&3];\n                    if (x2<0||x2>=N||y2<0||y2>=N) break;\n                    if (x3<0||x3>=N||y3<0||y3>=N) break;\n                    if (x4<0||x4>=N||y4<0||y4>=N) break;\n                    if (try_rect(x1,y1,x2,y2,x3,y3,x4,y4)) { progress=true; goto NEXT; }\n                    len++;\n                }\n            }\n            // 45\u00b0\u9577\u65b9\u5f62\u30924\u65b9\u5411\n            for (int d = 0; d < 4; d++) {\n                int len = 1;\n                while (1) {\n                    int x2 = x1 + len * dx45[d], y2 = y1 + len * dy45[d];\n                    int x3 = x2 + len * dx45[(d+1)&3], y3 = y2 + len * dy45[(d+1)&3];\n                    int x4 = x1 + len * dx45[(d+1)&3], y4 = y1 + len * dy45[(d+1)&3];\n                    if (x2<0||x2>=N||y2<0||y2>=N) break;\n                    if (x3<0||x3>=N||y3<0||y3>=N) break;\n                    if (x4<0||x4>=N||y4<0||y4>=N) break;\n                    if (try_rect(x1,y1,x2,y2,x3,y3,x4,y4)) { progress=true; goto NEXT; }\n                    len++;\n                }\n            }\n        }\n        NEXT:\n        iter += batch;\n        if (!progress) break;\n    }\n\n    // \u51fa\u529b\n    cout << ops.size() << \"\\n\";\n    for (auto &[x1,y1,x2,y2,x3,y3,x4,y4] : ops) {\n        cout << x1 << \" \" << y1 << \" \"\n             << x2 << \" \" << y2 << \" \"\n             << x3 << \" \" << y3 << \" \"\n             << x4 << \" \" << y4 << \"\\n\";\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\nusing namespace std::chrono;\n\nstatic const int H = 10, W = 10, C = 3;\nint flavor[100];               // 0-indexed\nchar dirchar[4] = {'F','B','L','R'};\n\nmt19937 rng((uint64_t)(new char));\n\nint grid[H][W];\nint tmp [H][W];\n\nvoid gravity(int g[H][W], int d){\n    // d: 0=F(up),1=B(down),2=L(left),3=right\n    if(d==0){ // forward = up\n        for(int c=0;c<W;c++){\n            int write = 0;\n            for(int r=0;r<H;r++){\n                if(g[r][c]){\n                    if(write!=r) g[write][c] = g[r][c];\n                    write++;\n                }\n            }\n            for(int r=write;r<H;r++) g[r][c]=0;\n        }\n    }\n    else if(d==1){ // backward = down\n        for(int c=0;c<W;c++){\n            int write = H-1;\n            for(int r=H-1;r>=0;r--){\n                if(g[r][c]){\n                    if(write!=r) g[write][c] = g[r][c];\n                    write--;\n                }\n            }\n            for(int r=write;r>=0;r--) g[r][c]=0;\n        }\n    }\n    else if(d==2){ // left\n        for(int r=0;r<H;r++){\n            int write = 0;\n            for(int c=0;c<W;c++){\n                if(g[r][c]){\n                    if(write!=c) g[r][write] = g[r][c];\n                    write++;\n                }\n            }\n            for(int c=write;c<W;c++) g[r][c]=0;\n        }\n    }\n    else { // right\n        for(int r=0;r<H;r++){\n            int write = W-1;\n            for(int c=W-1;c>=0;c--){\n                if(g[r][c]){\n                    if(write!=c) g[r][write] = g[r][c];\n                    write--;\n                }\n            }\n            for(int c=write;c>=0;c--) g[r][c]=0;\n        }\n    }\n}\n\nint eval_once(int g[H][W]){\n    // return sum of squares of component sizes\n    static bool vis[H][W];\n    memset(vis,0,sizeof(vis));\n    int sum = 0;\n    for(int i=0;i<H;i++){\n        for(int j=0;j<W;j++){\n            if(!vis[i][j] && g[i][j]){\n                int col = g[i][j];\n                int sz  = 0;\n                // BFS\n                static deque<pair<int,int>> q;\n                q.emplace_back(i,j);\n                vis[i][j]=1;\n                while(!q.empty()){\n                    auto [r,c] = q.front(); q.pop_front();\n                    sz++;\n                    const int dr[4]={-1,1,0,0}, dc[4]={0,0,-1,1};\n                    for(int d=0;d<4;d++){\n                        int nr=r+dr[d], nc=c+dc[d];\n                        if(nr<0||nr>=H||nc<0||nc>=W) continue;\n                        if(!vis[nr][nc] && g[nr][nc]==col){\n                            vis[nr][nc]=1;\n                            q.emplace_back(nr,nc);\n                        }\n                    }\n                }\n                sum += sz*sz;\n            }\n        }\n    }\n    return sum;\n}\n\nint simulate_rollout(int g[H][W], int t){\n    // copy current state\n    memcpy(tmp, g, sizeof(tmp));\n    // random future\n    for(int k=t+1;k<100;k++){\n        // count empties\n        vector<int> empties;\n        empties.reserve(H*W);\n        for(int i=0;i<H*W;i++){\n            int r=i/W, c=i%W;\n            if(tmp[r][c]==0) empties.push_back(i);\n        }\n        if(empties.empty()) break;\n        uniform_int_distribution<int> uid(0,(int)empties.size()-1);\n        int pos = empties[uid(rng)];\n        int r=pos/W, c=pos%W;\n        tmp[r][c] = flavor[k];\n        // random tilt\n        uniform_int_distribution<int> did(0,3);\n        gravity(tmp, did(rng));\n    }\n    return eval_once(tmp);\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    for(int i=0;i<100;i++){\n        cin>>flavor[i];\n    }\n\n    memset(grid,0,sizeof(grid));\n\n    for(int t=0;t<100;t++){\n        int p; cin>>p; p--;\n        // place candy\n        int cnt=0,rr=-1,cc=-1;\n        for(int i=0;i<H*W;i++){\n            int r=i/W, c=i%W;\n            if(grid[r][c]==0){\n                if(cnt==p){ rr=r; cc=c; break; }\n                cnt++;\n            }\n        }\n        grid[rr][cc] = flavor[t];\n\n        int bestdir = 0, bestscore = -1;\n        const int K = 120; // roll-outs per candidate\n        for(int d=0;d<4;d++){\n            memcpy(tmp, grid, sizeof(tmp));\n            gravity(tmp, d);\n            int avg = 0;\n            for(int k=0;k<K;k++){\n                avg += simulate_rollout(tmp, t);\n            }\n            if(avg > bestscore){\n                bestscore = avg;\n                bestdir   = d;\n            }\n        }\n        // apply best to real grid\n        gravity(grid, bestdir);\n        cout << dirchar[bestdir] << '\\n';\n        cout.flush();\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\n// ---------------  \u57fa\u672c\u8a2d\u5b9a  ----------------\nint M; \ndouble eps;\nconst int MAX_N = 100;\nint N;                       // \u5b9f\u969b\u306b\u9078\u3076\u9802\u70b9\u6570\nint MAX_EDGES;               // N*(N-1)/2\n\n// \u5404 G_k \u306e\u8fba\u96c6\u5408\uff08bitmask \u3067\u3082 vector<bitset<>> \u3067\u3082\u53ef\uff09\n// \u3053\u3053\u3067\u306f\u96a3\u63a5\u884c\u5217\u3092 vector<bitset<MAX_N>> \u3067\u6301\u3064\nvector<bitset<MAX_N>> G[MAX_N*MAX_N]; // G[k][i][j] = 1 \u306a\u3089\u8fba (i,j) \u5b58\u5728\n\n// \u5404 G_k \u306e\u300c\u8fba\u6570\u300d\u304a\u3088\u3073\u300c\u6b21\u6570\u5217\uff08\u30bd\u30fc\u30c8\u6e08\u307f\uff09\u300d\nvector<int> target_edges;   // target_edges[k]\nvector<vector<int>> deg_seq; // deg_seq[k] : \u9577\u3055 N\u3001\u30bd\u30fc\u30c8\u6e08\u307f\n\n// --------------  \u4e8b\u524d\u8a08\u7b97\uff08Binomial \u5bfe\u6570\uff09 --------------\nconst int MAX_BINOM = MAX_N*MAX_N;\ndouble logfact[MAX_BINOM+1];\nvoid init_logfact(){\n    logfact[0] = 0.0;\n    for(int i=1;i<=MAX_BINOM;i++){\n        logfact[i] = logfact[i-1] + log(i);\n    }\n}\ninline double logbinom(int n, int k){\n    if(k<0||k>n) return -1e300;\n    return logfact[n] - logfact[k] - logfact[n-k];\n}\n\n// --------------  \u30b0\u30e9\u30d5\u51fa\u529b\u7528\u30a8\u30f3\u30b3\u30fc\u30c0 -----------------\nstring encode_graph(const vector<bitset<MAX_N>>& adj){\n    string s;\n    for(int i=0;i<N;i++){\n        for(int j=i+1;j<N;j++){\n            s += (adj[i][j] ? '1':'0');\n        }\n    }\n    return s;\n}\n\n// --------------  \u30e9\u30f3\u30c0\u30e0\u8fba\u751f\u6210 ------------------------\nvoid build_random_graph(vector<bitset<MAX_N>>& adj, int m){\n    adj.assign(N, bitset<MAX_N>());\n    int total = N*(N-1)/2;\n    vector<int> idx(total);\n    iota(idx.begin(), idx.end(), 0);\n    shuffle(idx.begin(), idx.end(), mt19937(12345));\n    for(int t=0;t<m;t++){\n        int e = idx[t];\n        int i = 0, j = 1;\n        // e \u756a\u76ee\u306e (i,j) (i<j) \u3092\u5fa9\u5143\n        int cnt = 0;\n        for(i=0;i<N;i++){\n            for(j=i+1;j<N;j++){\n                if(cnt==e) goto found;\n                cnt++;\n            }\n        }\n        found:\n        adj[i][j] = adj[j][i] = 1;\n    }\n}\n\n// --------------  \u6b21\u6570\u5217\u53d6\u5f97 --------------------------\nvector<int> get_degree_sequence(const vector<bitset<MAX_N>>& adj){\n    vector<int> deg(N);\n    for(int i=0;i<N;i++){\n        deg[i] = adj[i].count();\n    }\n    sort(deg.rbegin(), deg.rend());\n    return deg;\n}\n\n// --------------  \u5bfe\u6570\u5c24\u5ea6\u8fd1\u4f3c ------------------------\n// \u8fba\u6570 m \u306e\u307f\u3092\u898b\u308b\u7c21\u6613\u7248\ndouble loglikelihood_edge(int m, int k){\n    int total = N*(N-1)/2;\n    double p = (double)target_edges[k] / total;\n    // \u53cd\u8ee2\u5f8c\u306e\u671f\u5f85\u8fba\u6570\n    double mu = target_edges[k]*(1 - 2*eps) + eps*total;\n    double sigma2 = eps*(1 - eps)*total;\n    // \u6b63\u898f\u8fd1\u4f3c\n    double diff = m - mu;\n    return -0.5 * diff*diff / sigma2;\n}\n\n// --------------  \u30e1\u30a4\u30f3 --------------------------------\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // \u5165\u529b\n    cin >> M >> eps;\n\n    // N \u3092\u6c7a\u5b9a\uff08\u5c0f\u3055\u3044\u307b\u3046\u304c\u30b9\u30b3\u30a2\u500d\u7387\u304c\u9ad8\u3044\u304c\u3001\u8b58\u5225\u80fd\u529b\u304c\u843d\u3061\u308b\uff09\n    // \u3068\u308a\u3042\u3048\u305a N=20 \u3067\u56fa\u5b9a\n    N = 20;\n    MAX_EDGES = N*(N-1)/2;\n\n    // \u5bfe\u6570factorial \u521d\u671f\u5316\n    init_logfact();\n\n    // \u5404 G_k \u306e\u300c\u76ee\u6a19\u8fba\u6570\u300d\u3092\u7b49\u9593\u9694\u306b\n    target_edges.resize(M);\n    double step = (double)MAX_EDGES / (M-1);\n    for(int k=0;k<M;k++){\n        target_edges[k] = (int)round( k * step );\n    }\n\n    // \u5404 G_k \u3092\u751f\u6210 & \u6b21\u6570\u5217\u8a08\u7b97\n    for(int k=0;k<M;k++){\n        build_random_graph(G[k], target_edges[k]);\n        deg_seq.emplace_back( get_degree_sequence(G[k]) );\n    }\n\n    // \u51fa\u529b\n    cout << N << \"\\n\";\n    for(int k=0;k<M;k++){\n        cout << encode_graph(G[k]) << \"\\n\";\n    }\n    cout.flush();\n\n    // \u30af\u30a8\u30ea\u51e6\u7406\n    for(int q=0;q<100;q++){\n        string Hstr;\n        cin >> Hstr;\n        // H \u3092\u96a3\u63a5\u884c\u5217\u306b\n        vector<bitset<MAX_N>> H(N);\n        int ptr = 0;\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                if(Hstr[ptr++]=='1'){\n                    H[i][j] = H[j][i] = 1;\n                }\n            }\n        }\n        // \u8fba\u6570\n        int m = 0;\n        for(int i=0;i<N;i++) m += H[i].count();\n        m /= 2;\n\n        // \u5404 k \u306b\u3064\u3044\u3066\u5bfe\u6570\u5c24\u5ea6\uff08\u8fba\u6570\u306e\u307f\uff09\u3092\u8a08\u7b97\n        int best_k = 0;\n        double best_ll = -1e300;\n        for(int k=0;k<M;k++){\n            double ll = loglikelihood_edge(m, k);\n            if(ll > best_ll){\n                best_ll = ll;\n                best_k = k;\n            }\n        }\n        cout << best_k << \"\\n\";\n        cout.flush();\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 1005;\nconst int MAX_M = 3005;\n\nint N, M, D, K;\nint u[MAX_M], v[MAX_M], w[MAX_M];\nint x[MAX_N], y[MAX_N];\nint assignment[MAX_M];\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> D >> K;\n    \n    for (int i = 0; i < M; i++) {\n        cin >> u[i] >> v[i] >> w[i];\n        u[i]--; v[i]--;\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n    \n    // Calculate maximum edges per day\n    int max_per_day = K;\n    \n    // Strategy: Use spatial partitioning to minimize local impact\n    // Group edges by spatial regions and distribute across days\n    \n    // Create spatial groups\n    vector<pair<int, int>> edge_regions(M);\n    for (int i = 0; i < M; i++) {\n        // Use midpoint to determine region\n        int mid_x = (x[u[i]] + x[v[i]]) / 2;\n        int mid_y = (y[u[i]] + y[v[i]]) / 2;\n        \n        // Create region index (simple grid-based)\n        int region_x = mid_x / 200;  // Divide 1000x1000 into ~5x5 regions\n        int region_y = mid_y / 200;\n        int region = region_x * 5 + region_y;\n        \n        edge_regions[i] = {region, i};\n    }\n    \n    // Sort by region for spatial grouping\n    sort(edge_regions.begin(), edge_regions.end());\n    \n    // Assign edges to days with strict K constraint\n    vector<int> day_count(D + 1, 0);\n    \n    // Process regions in order, but distribute within each region\n    int current_region = -1;\n    int region_start = 0;\n    \n    for (int i = 0; i < M; i++) {\n        int region = edge_regions[i].first;\n        int e = edge_regions[i].second;\n        \n        if (region != current_region) {\n            current_region = region;\n            region_start = i;\n        }\n        \n        // Within each region, distribute across days to spread impact\n        int region_offset = i - region_start;\n        int base_day = (region_offset % D) + 1;\n        \n        // Find the best day with available capacity\n        int best_day = -1;\n        int min_load = max_per_day + 1;\n        \n        // Check days in order, starting from base_day\n        for (int offset = 0; offset < D; offset++) {\n            int try_day = ((base_day + offset - 1) % D) + 1;\n            if (day_count[try_day] < max_per_day && day_count[try_day] < min_load) {\n                min_load = day_count[try_day];\n                best_day = try_day;\n            }\n        }\n        \n        // Fallback: find any day with capacity\n        if (best_day == -1) {\n            for (int day = 1; day <= D; day++) {\n                if (day_count[day] < max_per_day) {\n                    best_day = day;\n                    break;\n                }\n            }\n        }\n        \n        assignment[e] = best_day;\n        day_count[best_day]++;\n    }\n    \n    // Verify constraint satisfaction\n    bool valid = true;\n    for (int day = 1; day <= D; day++) {\n        if (day_count[day] > max_per_day) {\n            valid = false;\n            break;\n        }\n    }\n    \n    // If spatial approach failed, use simple round-robin with constraint\n    if (!valid) {\n        fill(assignment, assignment + M, 0);\n        fill(day_count.begin(), day_count.end(), 0);\n        \n        for (int i = 0; i < M; i++) {\n            // Find day with minimum load that has capacity\n            int best_day = 1;\n            for (int day = 2; day <= D; day++) {\n                if (day_count[day] < day_count[best_day] && day_count[day] < max_per_day) {\n                    best_day = day;\n                }\n            }\n            \n            assignment[i] = best_day;\n            day_count[best_day]++;\n        }\n    }\n    \n    // Output the assignment\n    for (int i = 0; i < M; i++) {\n        cout << assignment[i] << (i == M - 1 ? \"\\n\" : \" \");\n    }\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nusing ull = unsigned long long;\nusing int2 = __int128_t;\n\nstatic constexpr int MAXD = 14;\nstatic constexpr int MAXV = 16;               // max volume of generated blocks\nstatic constexpr int MAXB = 40000;            // max number of generated blocks\nstatic constexpr double TIME_LIMIT = 5.8;\n\nint D, DD, DDD;\nbitset<MAXD*MAXD*MAXD> mandatory[2], sharedMandatory;\nint mandatoryVol[2], sharedVol;\n\nstruct Block {\n    int vol;\n    vector<tuple<int,int,int>> cells;   // original coordinates\n    vector<vector<tuple<int,int,int>>> rot; // 24 rotations\n};\nint nBlocks = 0;\nBlock blocks[MAXB];\n\n// ---------- utilities ----------\ninline int idx(int x, int y, int z) { return x*D*D + y*D + z; }\ninline bool inside(int x, int y, int z) {\n    return 0 <= x && x < D && 0 <= y && y < D && 0 <= z && z < D;\n}\n\n// ---------- rotation ----------\nvector<vector<tuple<int,int,int>>> generateRotations(const vector<tuple<int,int,int>>& src) {\n    vector<vector<tuple<int,int,int>>> res;\n    set<vector<tuple<int,int,int>>> seen;\n    for (int rx = 0; rx < 4; ++rx)\n    for (int ry = 0; ry < 4; ++ry)\n    for (int rz = 0; rz < 4; ++rz) {\n        vector<tuple<int,int,int>> tmp;\n        for (auto [x,y,z] : src) {\n            int cx = x, cy = y, cz = z;\n            // rotate around X\n            for (int k = 0; k < rx; ++k) {\n                int ny = -cz, nz = cy;\n                cy = ny; cz = nz;\n            }\n            // rotate around Y\n            for (int k = 0; k < ry; ++k) {\n                int nx = cz, nz = -cx;\n                cx = nx; cz = nz;\n            }\n            // rotate around Z\n            for (int k = 0; k < rz; ++k) {\n                int nx = -cy, ny = cx;\n                cx = nx; cy = ny;\n            }\n            tmp.emplace_back(cx, cy, cz);\n        }\n        // normalize\n        int minx=INT_MAX, miny=INT_MAX, minz=INT_MAX;\n        for (auto [x,y,z] : tmp) {\n            minx = min(minx, x); miny = min(miny, y); minz = min(minz, z);\n        }\n        for (auto& [x,y,z] : tmp) {\n            x -= minx; y -= miny; z -= minz;\n        }\n        sort(tmp.begin(), tmp.end());\n        if (seen.insert(tmp).second) res.push_back(tmp);\n    }\n    return res;\n}\n\n// ---------- polycube generation ----------\nvoid generateBlocks() {\n    // BFS enumeration of all free polycubes up to volume MAXV\n    map<vector<tuple<int,int,int>>, int> canonicalId;\n    queue<pair<vector<tuple<int,int,int>>, int>> q;\n    q.push({{{0,0,0}}, 1});\n    canonicalId[{{{0,0,0}}}] = 1;\n    int dx[] = {1,-1,0,0,0,0}, dy[] = {0,0,1,-1,0,0}, dz[] = {0,0,0,0,1,-1};\n    while (!q.empty() && nBlocks < MAXB) {\n        auto [shape, vol] = q.front(); q.pop();\n        if (vol > MAXV) continue;\n        // store this shape\n        {\n            Block& B = blocks[nBlocks++];\n            B.vol = vol;\n            B.cells = shape;\n            B.rot = generateRotations(shape);\n        }\n        // expand\n        set<tuple<int,int,int>> frontier;\n        for (auto [x,y,z] : shape)\n        for (int d = 0; d < 6; ++d) {\n            int nx = x+dx[d], ny = y+dy[d], nz = z+dz[d];\n            if (!inside(nx,ny,nz)) continue;\n            if (find(shape.begin(), shape.end(), make_tuple(nx,ny,nz)) != shape.end()) continue;\n            frontier.emplace(nx,ny,nz);\n        }\n        for (auto [x,y,z] : frontier) {\n            auto ns = shape;\n            ns.emplace_back(x,y,z);\n            // normalize\n            int minx=INT_MAX,miny=INT_MAX,minz=INT_MAX;\n            for (auto [xx,yy,zz] : ns) {\n                minx=min(minx,xx); miny=min(miny,yy); minz=min(minz,zz);\n            }\n            for (auto& [xx,yy,zz] : ns) {\n                xx-=minx; yy-=miny; zz-=minz;\n            }\n            sort(ns.begin(), ns.end());\n            if (canonicalId.count(ns)) continue;\n            canonicalId[ns] = 1;\n            q.push({ns, vol+1});\n        }\n    }\n    cerr << \"generated \" << nBlocks << \" blocks up to volume \" << MAXV << \"\\n\";\n}\n\n// ---------- placement ----------\nstruct Placement {\n    bitset<MAXD*MAXD*MAXD> occ;\n    int usedVol;\n    vector<int> blockIds;\n    vector<vector<tuple<int,int,int>>> poses; // for each block, its rotated+translated cells\n};\nPlacement bestP[2];\ndouble bestScore = 1e18;\n\n// try to place block B with rotation r at (bx,by,bz) into grid g\nbool canPlace(const bitset<MAXD*MAXD*MAXD>& g, const Block& B, int r, int bx, int by, int bz) {\n    for (auto [x,y,z] : B.rot[r]) {\n        int xx = x+bx, yy = y+by, zz = z+bz;\n        if (!inside(xx,yy,zz)) return false;\n        if (g.test(idx(xx,yy,zz))) return false;\n    }\n    return true;\n}\nvoid place(bitset<MAXD*MAXD*MAXD>& g, const Block& B, int r, int bx, int by, int bz) {\n    for (auto [x,y,z] : B.rot[r]) {\n        int xx = x+bx, yy = y+by, zz = z+bz;\n        g.set(idx(xx,yy,zz));\n    }\n}\n\n// greedy cover for one silhouette\nPlacement greedyCover(const bitset<MAXD*MAXD*MAXD>& target, int which) {\n    Placement P;\n    P.occ.reset(); P.usedVol = 0;\n    vector<int> order(nBlocks);\n    iota(order.begin(), order.end(), 0);\n    // sort by 1/vol descending\n    sort(order.begin(), order.end(), [&](int a, int b){\n        return blocks[a].vol > blocks[b].vol;\n    });\n    bitset<MAXD*MAXD*MAXD> rem = target;\n    int remVol = target.count();\n    for (int id : order) {\n        if (remVol == 0) break;\n        const Block& B = blocks[id];\n        bool placed = false;\n        // try all rotations and positions\n        for (int r = 0; r < (int)B.rot.size() && !placed; ++r) {\n            int maxx=0,maxy=0,maxz=0;\n            for (auto [x,y,z] : B.rot[r]) {\n                maxx=max(maxx,x); maxy=max(maxy,y); maxz=max(maxz,z);\n            }\n            for (int bx = 0; bx + maxx < D && !placed; ++bx)\n            for (int by = 0; by + maxy < D && !placed; ++by)\n            for (int bz = 0; bz + maxz < D && !placed; ++bz) {\n                if (!canPlace(P.occ, B, r, bx,by,bz)) continue;\n                // check if it covers at least one remaining voxel\n                bool cov = false;\n                for (auto [x,y,z] : B.rot[r]) {\n                    int xx = x+bx, yy = y+by, zz = z+bz;\n                    if (rem.test(idx(xx,yy,zz))) { cov=true; break; }\n                }\n                if (!cov) continue;\n                // place it\n                place(P.occ, B, r, bx,by,bz);\n                P.blockIds.push_back(id);\n                vector<tuple<int,int,int>> pose;\n                for (auto [x,y,z] : B.rot[r]) pose.emplace_back(x+bx, y+by, z+bz);\n                P.poses.push_back(pose);\n                P.usedVol += B.vol;\n                // update rem\n                for (auto [x,y,z] : B.rot[r]) {\n                    int xx = x+bx, yy = y+by, zz = z+bz;\n                    rem.reset(idx(xx,yy,zz));\n                }\n                remVol = rem.count();\n                placed = true;\n            }\n        }\n    }\n    return P;\n}\n\n// ---------- scoring ----------\ndouble eval(const Placement& p1, const Placement& p2) {\n    // build set of used blocks\n    unordered_set<int> used1(p1.blockIds.begin(), p1.blockIds.end());\n    unordered_set<int> used2(p2.blockIds.begin(), p2.blockIds.end());\n    int r1 = 0, r2 = 0;\n    double sumInv = 0.0;\n    for (int i = 0; i < nBlocks; ++i) {\n        bool in1 = used1.count(i), in2 = used2.count(i);\n        if (!in1 && !in2) continue; // not allowed, but we prune earlier\n        if (!in1) r1 += blocks[i].vol;\n        if (!in2) r2 += blocks[i].vol;\n        if (in1 && in2) sumInv += 1.0 / blocks[i].vol;\n    }\n    double score = r1 + r2 + sumInv;\n    return score;\n}\n\n// ---------- output ----------\nvoid output(const Placement& p1, const Placement& p2) {\n    // build global block list\n    unordered_map<int,int> globalId;\n    int nOut = 0;\n    for (int id : p1.blockIds) if (!globalId.count(id)) globalId[id] = nOut++;\n    for (int id : p2.blockIds) if (!globalId.count(id)) globalId[id] = nOut++;\n    cout << nOut << \"\\n\";\n    // output b1\n    vector<int> flat1(D*D*D, 0);\n    for (int i = 0; i < (int)p1.blockIds.size(); ++i) {\n        int gid = globalId[p1.blockIds[i]];\n        for (auto [x,y,z] : p1.poses[i]) {\n            flat1[idx(x,y,z)] = gid+1;\n        }\n    }\n    for (int i = 0; i < DDD; ++i) {\n        if (i) cout << \" \";\n        cout << flat1[i];\n    }\n    cout << \"\\n\";\n    // output b2\n    vector<int> flat2(D*D*D, 0);\n    for (int i = 0; i < (int)p2.blockIds.size(); ++i) {\n        int gid = globalId[p2.blockIds[i]];\n        for (auto [x,y,z] : p2.poses[i]) {\n            flat2[idx(x,y,z)] = gid+1;\n        }\n    }\n    for (int i = 0; i < DDD; ++i) {\n        if (i) cout << \" \";\n        cout << flat2[i];\n    }\n    cout << \"\\n\";\n}\n\n// ---------- main ----------\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    auto clk = chrono::high_resolution_clock::now();\n\n    cin >> D;\n    DD = D*D; DDD = D*D*D;\n    // read silhouettes\n    vector<string> fstr[2], rstr[2];\n    for (int i = 0; i < 2; ++i) {\n        fstr[i].resize(D);\n        for (int z = 0; z < D; ++z) cin >> fstr[i][z];\n        rstr[i].resize(D);\n        for (int z = 0; z < D; ++z) cin >> rstr[i][z];\n    }\n    // build mandatory voxels\n    for (int i = 0; i < 2; ++i) {\n        mandatory[i].reset();\n        for (int x = 0; x < D; ++x)\n        for (int y = 0; y < D; ++y)\n        for (int z = 0; z < D; ++z) {\n            if (fstr[i][z][x]=='1' && rstr[i][z][y]=='1') {\n                mandatory[i].set(idx(x,y,z));\n            }\n        }\n        mandatoryVol[i] = mandatory[i].count();\n    }\n    sharedMandatory = mandatory[0] & mandatory[1];\n    sharedVol = sharedMandatory.count();\n\n    // generate block catalogue\n    generateBlocks();\n\n    // greedy cover for each silhouette\n    bestP[0] = greedyCover(mandatory[0], 0);\n    bestP[1] = greedyCover(mandatory[1], 1);\n    bestScore = eval(bestP[0], bestP[1]);\n\n    // simple iterative improvement: try to replace one block by a larger unused one\n    // (very fast, so we do many iterations)\n    int iter = 0;\n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - clk).count();\n        if (elapsed > TIME_LIMIT) break;\n        iter++;\n        // pick random placement\n        int w = rand()&1;\n        Placement& P = bestP[w];\n        if (P.blockIds.empty()) continue;\n        int k = rand() % P.blockIds.size();\n        int oldId = P.blockIds[k];\n        // try all bigger unused blocks\n        bool improved = false;\n        for (int cand = 0; cand < nBlocks && !improved; ++cand) {\n            if (blocks[cand].vol <= blocks[oldId].vol) continue;\n            // try to place cand instead of oldId\n            Placement tmp = P;\n            // remove oldId\n            tmp.occ.reset();\n            tmp.usedVol -= blocks[oldId].vol;\n            tmp.blockIds.erase(tmp.blockIds.begin()+k);\n            tmp.poses.erase(tmp.poses.begin()+k);\n            // rebuild occ\n            for (int i = 0; i < (int)tmp.blockIds.size(); ++i) {\n                const Block& B = blocks[tmp.blockIds[i]];\n                for (auto [x,y,z] : tmp.poses[i]) tmp.occ.set(idx(x,y,z));\n            }\n            // try to add cand somewhere\n            const Block& B = blocks[cand];\n            bool placed = false;\n            for (int r = 0; r < (int)B.rot.size() && !placed; ++r) {\n                int maxx=0,maxy=0,maxz=0;\n                for (auto [x,y,z] : B.rot[r]) {\n                    maxx=max(maxx,x); maxy=max(maxy,y); maxz=max(maxz,z);\n                }\n                for (int bx = 0; bx + maxx < D && !placed; ++bx)\n                for (int by = 0; by + maxy < D && !placed; ++by)\n                for (int bz = 0; bz + maxz < D && !placed; ++bz) {\n                    if (!canPlace(tmp.occ, B, r, bx,by,bz)) continue;\n                    // check it covers at least one missing voxel\n                    bitset<MAXD*MAXD*MAXD> need = mandatory[w];\n                    for (int i = 0; i < (int)tmp.blockIds.size(); ++i)\n                        for (auto [x,y,z] : tmp.poses[i]) need.reset(idx(x,y,z));\n                    bool cov = false;\n                    for (auto [x,y,z] : B.rot[r]) {\n                        int xx = x+bx, yy = y+by, zz = z+bz;\n                        if (need.test(idx(xx,yy,zz))) { cov=true; break; }\n                    }\n                    if (!cov) continue;\n                    // place it\n                    place(tmp.occ, B, r, bx,by,bz);\n                    tmp.blockIds.push_back(cand);\n                    vector<tuple<int,int,int>> pose;\n                    for (auto [x,y,z] : B.rot[r]) pose.emplace_back(x+bx, y+by, z+bz);\n                    tmp.poses.push_back(pose);\n                    tmp.usedVol += B.vol;\n                    placed = true;\n                }\n            }\n            if (!placed) continue;\n            // finish covering with greedy\n            bitset<MAXD*MAXD*MAXD> rem = mandatory[w];\n            for (int i = 0; i < (int)tmp.blockIds.size(); ++i)\n                for (auto [x,y,z] : tmp.poses[i]) rem.reset(idx(x,y,z));\n            if (rem.any()) {\n                Placement fill = greedyCover(rem, w);\n                for (int i = 0; i < (int)fill.blockIds.size(); ++i) {\n                    tmp.blockIds.push_back(fill.blockIds[i]);\n                    tmp.poses.push_back(fill.poses[i]);\n                    tmp.usedVol += blocks[fill.blockIds[i]].vol;\n                    for (auto [x,y,z] : fill.poses[i]) tmp.occ.set(idx(x,y,z));\n                }\n            }\n            // evaluate\n            double sc = eval(tmp, bestP[w^1]);\n            if (sc < bestScore) {\n                bestScore = sc;\n                bestP[w] = tmp;\n                improved = true;\n            }\n        }\n    }\n\n    cerr << \"iterations \" << iter << \" bestScore \" << bestScore << \"\\n\";\n    output(bestP[0], bestP[1]);\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing int64 = long long;\n\nstatic const int MAXN = 105;\nstatic const int MAXM = 305;\nstatic const int MAXK = 5005;\nstatic const int MAXP = 5000;\n\nint N, M, K;\ndouble x[MAXN], y[MAXN];\nint u_e[MAXM], v_e[MAXM], w_e[MAXM];\ndouble a[MAXK], b[MAXK];\n\n// DSU for Kruskal\nint parent[MAXN];\nint find_set(int v) {\n    if (v == parent[v]) return v;\n    return parent[v] = find_set(parent[v]);\n}\nbool union_set(int u, int v) {\n    u = find_set(u);\n    v = find_set(v);\n    if (u == v) return false;\n    parent[v] = u;\n    return true;\n}\n\n// graph\nvector<pair<int,int>> adj[MAXN]; // (neighbor, edge_index)\n\n// MST flags\nbool in_mst[MAXM];\nint64 total_edge_cost = 0;\n\n// resident -> distance to each vertex\ndouble dist_ik[MAXK][MAXN];\n\n// current solution\nint P[MAXN];\nbool edge_on[MAXM];\n\n// recompute vertex cost and detect uncovered residents\n// returns -1 if some resident has closest > MAXP\nint64 recompute_vertex_cost(const vector<char>& reachable,\n                            vector<int>& bestP)\n{\n    bestP.assign(N, 0);\n    for (int k = 0; k < K; k++) {\n        double best_d = 1e18;\n        int best_i = -1;\n        for (int i = 0; i < N; i++) {\n            if (reachable[i] && dist_ik[k][i] < best_d) {\n                best_d = dist_ik[k][i];\n                best_i = i;\n            }\n        }\n        if (best_d > MAXP) return -1;          // unreachable within limit\n        int need = (int)ceil(best_d);\n        need = min(need, MAXP);\n        bestP[best_i] = max(bestP[best_i], need);\n    }\n    int64 cost = 0;\n    for (int i = 0; i < N; i++) cost += (int64)bestP[i] * bestP[i];\n    return cost;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> K;\n    for(int i = 0; i < N; i++){\n        cin >> x[i] >> y[i];\n    }\n    for(int j = 0; j < M; j++){\n        cin >> u_e[j] >> v_e[j] >> w_e[j];\n        --u_e[j]; --v_e[j];\n    }\n    for(int k = 0; k < K; k++){\n        cin >> a[k] >> b[k];\n    }\n\n    // precompute resident->vertex distances\n    for(int k = 0; k < K; k++){\n        for(int i = 0; i < N; i++){\n            double dx = x[i] - a[k];\n            double dy = y[i] - b[k];\n            dist_ik[k][i] = sqrt(dx*dx + dy*dy);\n        }\n    }\n\n    // Kruskal MST\n    for(int i = 0; i < N; i++) parent[i] = i;\n    vector<int> edges_order(M);\n    iota(edges_order.begin(), edges_order.end(), 0);\n    sort(edges_order.begin(), edges_order.end(),\n         [&](int j1, int j2){ return w_e[j1] < w_e[j2]; });\n\n    fill(in_mst, in_mst + M, false);\n    for(int jj = 0; jj < M; jj++){\n        int j = edges_order[jj];\n        if (union_set(u_e[j], v_e[j])) {\n            in_mst[j] = true;\n            total_edge_cost += w_e[j];\n        }\n    }\n\n    // build adj for BFS\n    for(int j = 0; j < M; j++){\n        if (in_mst[j]){\n            adj[u_e[j]].emplace_back(v_e[j], j);\n            adj[v_e[j]].emplace_back(u_e[j], j);\n        }\n    }\n\n    // initial full reachable\n    vector<char> fullReach(N, true);\n    vector<int>  bestP(N);\n    int64 vertex_cost = recompute_vertex_cost(fullReach, bestP);\n    for(int i = 0; i < N; i++) P[i] = bestP[i];\n    for(int j = 0; j < M; j++) edge_on[j] = in_mst[j];\n\n    // greedy deletion pass: largest weight first\n    vector<int> tree_edges;\n    for(int j = 0; j < M; j++) if (in_mst[j]) tree_edges.push_back(j);\n    sort(tree_edges.begin(), tree_edges.end(),\n         [&](int j1, int j2){ return w_e[j1] > w_e[j2]; });\n\n    bool improved;\n    do {\n        improved = false;\n        for(int j_idx = 0; j_idx < (int)tree_edges.size(); j_idx++){\n            int j = tree_edges[j_idx];\n            if (!edge_on[j]) continue;\n\n            edge_on[j] = false;\n            // BFS reachable\n            vector<char> reach(N, false);\n            queue<int> q;\n            reach[0] = true; q.push(0);\n            while(!q.empty()){\n                int u = q.front(); q.pop();\n                for(auto& [v, eidx] : adj[u]){\n                    if (!edge_on[eidx]) continue;\n                    if (!reach[v]){\n                        reach[v] = true;\n                        q.push(v);\n                    }\n                }\n            }\n            vector<int> newP(N);\n            int64 new_vertex_cost = recompute_vertex_cost(reach, newP);\n            if (new_vertex_cost == -1){\n                // some resident uncovered -> reject\n                edge_on[j] = true;\n                continue;\n            }\n            int64 saved = w_e[j];\n            int64 extra = new_vertex_cost - vertex_cost;\n            if (extra < saved){\n                vertex_cost = new_vertex_cost;\n                for(int i = 0; i < N; i++) P[i] = newP[i];\n                improved = true;\n            } else {\n                edge_on[j] = true;\n            }\n        }\n    } while(improved);\n\n    // output\n    for(int i = 0; i < N; i++){\n        cout << P[i] << (i+1<N?' ':'\\n');\n    }\n    for(int j = 0; j < M; j++){\n        cout << (edge_on[j]?1:0) << (j+1<M?' ':'\\n');\n    }\n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\nstruct Ball {\n    int value;\n    int x, y;\n};\n\nconst int N = 30;\nconst int MAX_SWAPS = 10000;\n\nint pyramid[N][N];\nvector<pair<pair<int,int>, pair<int,int>>> swaps;\n\n// Check if two positions are adjacent in 6 directions\nbool isAdjacent(int x1, int y1, int x2, int y2) {\n    if (x1 == x2-1 && (y1 == y2-1 || y1 == y2)) return true;\n    if (x1 == x2 && (y1 == y2-1 || y1 == y2+1)) return true;\n    if (x1 == x2+1 && (y1 == y2 || y1 == y2+1)) return true;\n    return false;\n}\n\n// Swap two balls and record the operation\nvoid performSwap(int x1, int y1, int x2, int y2) {\n    swap(pyramid[x1][y1], pyramid[x2][y2]);\n    swaps.push_back({{x1, y1}, {x2, y2}});\n}\n\n// Check if position (x,y) violates the heap property\nbool violatesHeap(int x, int y) {\n    if (x == N-1) return false; // Bottom tier doesn't violate\n    \n    int val = pyramid[x][y];\n    int leftChild = pyramid[x+1][y];\n    int rightChild = pyramid[x+1][y+1];\n    \n    return val > leftChild || val > rightChild;\n}\n\n// Find path to bring a small value up\nvector<pair<int,int>> findBubblePath(int targetX, int targetY) {\n    vector<pair<int,int>> path;\n    int x = targetX, y = targetY;\n    \n    while (x > 0) {\n        // Try to move up-left first\n        if (y > 0 && x-1 >= 0 && y-1 >= 0) {\n            path.push_back({x-1, y-1});\n            x--; y--;\n        }\n        // Then try up-right\n        else if (y < x && x-1 >= 0 && y < x-1) {\n            path.push_back({x-1, y});\n            x--;\n        }\n        else {\n            break;\n        }\n    }\n    \n    return path;\n}\n\n// Bubble a value up to its correct position\nvoid bubbleUp(int startX, int startY) {\n    int x = startX, y = startY;\n    \n    while (x > 0) {\n        int parentX = -1, parentY = -1;\n        \n        // Find parent position\n        if (y > 0 && pyramid[x-1][y-1] > pyramid[x][y]) {\n            parentX = x-1; parentY = y-1;\n        }\n        else if (y < x && pyramid[x-1][y] > pyramid[x][y]) {\n            parentX = x-1; parentY = y;\n        }\n        \n        if (parentX == -1) break;\n        \n        performSwap(x, y, parentX, parentY);\n        x = parentX; y = parentY;\n        \n        if (swaps.size() >= MAX_SWAPS) return;\n    }\n}\n\n// Main algorithm: iterative improvement\nvoid solve() {\n    // Read input\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j <= i; j++) {\n            cin >> pyramid[i][j];\n        }\n    }\n    \n    // Multiple passes to fix violations\n    for (int pass = 0; pass < 5 && swaps.size() < MAX_SWAPS; pass++) {\n        bool improved = false;\n        \n        // Process from bottom to top\n        for (int x = N-2; x >= 0; x--) {\n            for (int y = 0; y <= x; y++) {\n                if (violatesHeap(x, y)) {\n                    bubbleUp(x, y);\n                    improved = true;\n                    \n                    if (swaps.size() >= MAX_SWAPS) return;\n                }\n            }\n        }\n        \n        if (!improved) break;\n    }\n    \n    // Local optimization: fix remaining violations\n    for (int iter = 0; iter < 100 && swaps.size() < MAX_SWAPS; iter++) {\n        bool fixed = false;\n        \n        for (int x = 0; x < N-1 && !fixed; x++) {\n            for (int y = 0; y <= x && !fixed; y++) {\n                if (violatesHeap(x, y)) {\n                    int val = pyramid[x][y];\n                    \n                    // Try swapping with children\n                    if (val > pyramid[x+1][y]) {\n                        performSwap(x, y, x+1, y);\n                        fixed = true;\n                    }\n                    else if (val > pyramid[x+1][y+1]) {\n                        performSwap(x, y, x+1, y+1);\n                        fixed = true;\n                    }\n                    \n                    if (swaps.size() >= MAX_SWAPS) return;\n                }\n            }\n        }\n        \n        if (!fixed) break;\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    solve();\n    \n    // Output swaps\n    cout << swaps.size() << '\\n';\n    for (auto& swap : swaps) {\n        cout << swap.first.first << ' ' << swap.first.second << ' ' \n             << swap.second.first << ' ' << swap.second.second << '\\n';\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int D = 9;\nconst int di[] = {-1, 0, 1, 0};\nconst int dj[] = {0, 1, 0, -1};\n\nint N;\nbool obstacle[D][D];\nbool occupied[D][D];\nint container[D][D]; // container[i][j] = t_d if occupied, else -1\nint dist[D][D];\n\nvoid bfs_dist() {\n    queue<pair<int, int>> q;\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            dist[i][j] = -1;\n        }\n    }\n    int si = 0, sj = (D-1)/2;\n    dist[si][sj] = 0;\n    q.emplace(si, sj);\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) continue;\n            if (obstacle[ni][nj] || occupied[ni][nj]) continue;\n            if (dist[ni][nj] == -1) {\n                dist[ni][nj] = dist[i][j] + 1;\n                q.emplace(ni, nj);\n            }\n        }\n    }\n}\n\nbool is_reachable(int i, int j) {\n    if (obstacle[i][j] || occupied[i][j]) return false;\n    bfs_dist();\n    return dist[i][j] != -1;\n}\n\nvector<pair<int, int>> get_reachable() {\n    bfs_dist();\n    vector<pair<int, int>> res;\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            if (!obstacle[i][j] && !occupied[i][j] && dist[i][j] != -1) {\n                res.emplace_back(i, j);\n            }\n        }\n    }\n    return res;\n}\n\npair<int, int> choose_placement(int t) {\n    auto reachable = get_reachable();\n    if (reachable.empty()) {\n        cerr << \"No reachable cells!\" << endl;\n        exit(1);\n    }\n    // Choose the cell with maximum distance from entrance\n    pair<int, int> best = reachable[0];\n    int best_dist = dist[best.first][best.second];\n    for (auto [i, j] : reachable) {\n        if (dist[i][j] > best_dist) {\n            best_dist = dist[i][j];\n            best = {i, j};\n        }\n    }\n    return best;\n}\n\nvector<pair<int, int>> retrieval_order;\n\nvoid compute_retrieval() {\n    // Reset occupied to true where containers are placed\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            occupied[i][j] = (container[i][j] != -1);\n        }\n    }\n    priority_queue<pair<int, pair<int, int>>, vector<pair<int, pair<int, int>>>, greater<pair<int, pair<int, int>>>> pq;\n    // Initial reachable containers\n    bfs_dist();\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            if (container[i][j] != -1 && dist[i][j] != -1) {\n                pq.emplace(container[i][j], make_pair(i, j));\n            }\n        }\n    }\n    while (!pq.empty()) {\n        auto [t, pos] = pq.top(); pq.pop();\n        auto [i, j] = pos;\n        if (container[i][j] == -1) continue; // already removed\n        retrieval_order.emplace_back(i, j);\n        occupied[i][j] = false;\n        container[i][j] = -1;\n        // Update reachability\n        bfs_dist();\n        // Add newly reachable containers\n        for (int ni = 0; ni < D; ++ni) {\n            for (int nj = 0; nj < D; ++nj) {\n                if (container[ni][nj] != -1 && dist[ni][nj] != -1) {\n                    pq.emplace(container[ni][nj], make_pair(ni, nj));\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cout << fixed << setprecision(20);\n\n    cin >> D >> N;\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            obstacle[i][j] = false;\n            occupied[i][j] = false;\n            container[i][j] = -1;\n        }\n    }\n    for (int k = 0; k < N; ++k) {\n        int ri, rj;\n        cin >> ri >> rj;\n        obstacle[ri][rj] = true;\n    }\n\n    int total_containers = D*D - 1 - N;\n    for (int d = 0; d < total_containers; ++d) {\n        int t;\n        cin >> t;\n        auto [i, j] = choose_placement(t);\n        occupied[i][j] = true;\n        container[i][j] = t;\n        cout << i << \" \" << j << endl;\n    }\n\n    compute_retrieval();\n    for (auto [i, j] : retrieval_order) {\n        cout << i << \" \" << j << \"\\n\";\n    }\n    cout.flush();\n\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 50;\nconst int MAX_M = 100;\n\nint n, m;\nint input[MAX_N][MAX_N];\nbool adj[MAX_M + 1][MAX_M + 1];\nint output[MAX_N][MAX_N];\n\n// Directions for adjacency checking\nint dx[] = {-1, 1, 0, 0};\nint dy[] = {0, 0, -1, 1};\n\nvoid extract_adjacencies() {\n    memset(adj, false, sizeof(adj));\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int c1 = input[i][j];\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d];\n                int nj = j + dy[d];\n                int c2;\n                \n                if (ni < 0 || ni >= n || nj < 0 || nj >= n) {\n                    c2 = 0; // Outside\n                } else {\n                    c2 = input[ni][nj];\n                }\n                \n                if (c1 != c2) {\n                    int u = min(c1, c2);\n                    int v = max(c1, c2);\n                    adj[u][v] = true;\n                }\n            }\n        }\n    }\n}\n\nbool is_valid_placement() {\n    // Check connectivity for each color\n    for (int color = 0; color <= m; color++) {\n        vector<pair<int, int>> cells;\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (output[i][j] == color) {\n                    cells.push_back({i, j});\n                }\n            }\n        }\n        \n        if (cells.empty()) continue;\n        \n        // BFS to check connectivity\n        vector<vector<bool>> visited(n, vector<bool>(n, false));\n        queue<pair<int, int>> q;\n        q.push(cells[0]);\n        visited[cells[0].first][cells[0].second] = true;\n        int count = 1;\n        \n        while (!q.empty()) {\n            auto [i, j] = q.front(); q.pop();\n            \n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d];\n                int nj = j + dy[d];\n                \n                if (ni >= 0 && ni < n && nj >= 0 && nj < n && \n                    output[ni][nj] == color && !visited[ni][nj]) {\n                    visited[ni][nj] = true;\n                    q.push({ni, nj});\n                    count++;\n                }\n            }\n        }\n        \n        if (count != (int)cells.size()) return false;\n    }\n    \n    // Check adjacency preservation\n    bool output_adj[MAX_M + 1][MAX_M + 1] = {false};\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int c1 = output[i][j];\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d];\n                int nj = j + dy[d];\n                int c2;\n                \n                if (ni < 0 || ni >= n || nj < 0 || nj >= n) {\n                    c2 = 0;\n                } else {\n                    c2 = output[ni][nj];\n                }\n                \n                if (c1 != c2) {\n                    int u = min(c1, c2);\n                    int v = max(c1, c2);\n                    output_adj[u][v] = true;\n                }\n            }\n        }\n    }\n    \n    for (int i = 0; i <= m; i++) {\n        for (int j = i + 1; j <= m; j++) {\n            if (adj[i][j] != output_adj[i][j]) {\n                return false;\n            }\n        }\n    }\n    \n    return true;\n}\n\nint count_zeros() {\n    int count = 0;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (output[i][j] == 0) count++;\n        }\n    }\n    return count;\n}\n\nvoid copy_output(int dest[MAX_N][MAX_N], const int src[MAX_N][MAX_N]) {\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            dest[i][j] = src[i][j];\n        }\n    }\n}\n\nvoid improve_solution() {\n    int best_zeros = count_zeros();\n    int best_output[MAX_N][MAX_N];\n    copy_output(best_output, output);\n    \n    // Try some local improvements with simulated annealing\n    double temperature = 1.0;\n    const double cooling_rate = 0.995;\n    \n    for (int iter = 0; iter < 5000 && temperature > 0.01; iter++) {\n        int i = rand() % n;\n        int j = rand() % n;\n        \n        if (output[i][j] == 0) continue;\n        \n        int original_color = output[i][j];\n        \n        // Try setting to 0\n        output[i][j] = 0;\n        if (is_valid_placement()) {\n            int zeros = count_zeros();\n            if (zeros > best_zeros) {\n                best_zeros = zeros;\n                copy_output(best_output, output);\n            } else if (zeros == best_zeros && (rand() / double(RAND_MAX)) < temperature) {\n                // Accept same score with some probability (simulated annealing)\n            } else {\n                // Revert if worse\n                output[i][j] = original_color;\n            }\n        } else {\n            output[i][j] = original_color;\n        }\n        \n        temperature *= cooling_rate;\n    }\n    \n    copy_output(output, best_output);\n}\n\nvoid find_compact_embedding() {\n    // Create a spanning tree of the adjacency graph\n    vector<vector<int>> graph(m + 1);\n    for (int i = 0; i <= m; i++) {\n        for (int j = i + 1; j <= m; j++) {\n            if (adj[i][j]) {\n                graph[i].push_back(j);\n                graph[j].push_back(i);\n            }\n        }\n    }\n    \n    // Use BFS to find a good ordering\n    vector<int> ordering;\n    vector<bool> visited(m + 1, false);\n    queue<int> q;\n    q.push(0); // Start with color 0 (outside)\n    visited[0] = true;\n    \n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        if (u != 0) ordering.push_back(u);\n        \n        for (int v : graph[u]) {\n            if (!visited[v]) {\n                visited[v] = true;\n                q.push(v);\n            }\n        }\n    }\n    \n    // Place colors in a spiral pattern starting from edges\n    int center_i = n / 2, center_j = n / 2;\n    int current_i = 0, current_j = 0;\n    int di = 0, dj = 1;\n    int steps = 1;\n    int step_count = 0;\n    int turn_count = 0;\n    \n    // First, ensure color 0 is on boundaries\n    for (int i = 0; i < n; i++) {\n        output[i][0] = 0;\n        output[i][n-1] = 0;\n        output[0][i] = 0;\n        output[n-1][i] = 0;\n    }\n    \n    // Place other colors\n    for (int color : ordering) {\n        bool placed = false;\n        \n        // Try to place near existing neighbors\n        for (int radius = 1; radius < n && !placed; radius++) {\n            for (int i = max(0, center_i - radius); i <= min(n-1, center_i + radius) && !placed; i++) {\n                for (int j = max(0, center_j - radius); j <= min(n-1, center_j + radius) && !placed; j++) {\n                    if (output[i][j] != 0) continue;\n                    \n                    // Check if adjacent to any required neighbor\n                    bool has_required_neighbor = false;\n                    for (int d = 0; d < 4; d++) {\n                        int ni = i + dx[d];\n                        int nj = j + dy[d];\n                        \n                        if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                            int neighbor_color = output[ni][nj];\n                            if (adj[min(color, neighbor_color)][max(color, neighbor_color)]) {\n                                has_required_neighbor = true;\n                                break;\n                            }\n                        } else if (adj[min(color, 0)][max(color, 0)]) {\n                            has_required_neighbor = true;\n                            break;\n                        }\n                    }\n                    \n                    if (has_required_neighbor || radius <= 2) {\n                        output[i][j] = color;\n                        placed = true;\n                    }\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> n >> m;\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> input[i][j];\n        }\n    }\n    \n    extract_adjacencies();\n    \n    // Initialize output with all zeros\n    memset(output, 0, sizeof(output));\n    \n    // Find a compact embedding\n    find_compact_embedding();\n    \n    // Verify and improve if needed\n    if (!is_valid_placement()) {\n        // Fallback: use input as output\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                output[i][j] = input[i][j];\n            }\n        }\n    } else {\n        // Try to improve the solution\n        improve_solution();\n    }\n    \n    // Output the result\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << output[i][j];\n            if (j < n - 1) cout << \" \";\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, D, Q;\nvector<int> estimated_weight;\nvector<int> assignment;\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nstring query(const vector<int>& L, const vector<int>& R) {\n    cout << L.size() << \" \" << R.size();\n    for (int x : L) cout << \" \" << x;\n    for (int x : R) cout << \" \" << x;\n    cout << endl;\n    string res;\n    cin >> res;\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> D >> Q;\n    \n    estimated_weight.assign(N, 1);\n    assignment.assign(N, 0);\n    \n    // Phase 1: Quick pairwise comparisons to get rough ordering\n    int queries_used = 0;\n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n    \n    // Do some random pairwise comparisons\n    for (int i = 0; i < min(Q/4, N*2) && queries_used < Q; i++) {\n        int a = rng() % N;\n        int b = rng() % N;\n        if (a == b) continue;\n        \n        string res = query({a}, {b});\n        queries_used++;\n        \n        if (res == \">\") {\n            estimated_weight[a] += 2;\n        } else if (res == \"<\") {\n            estimated_weight[b] += 2;\n        } else {\n            estimated_weight[a] += 1;\n            estimated_weight[b] += 1;\n        }\n    }\n    \n    // Phase 2: Compare groups to refine estimates\n    for (int i = 0; i < min(Q/4, N) && queries_used < Q; i++) {\n        // Compare random subsets\n        vector<int> group1, group2;\n        for (int j = 0; j < N; j++) {\n            if (rng() % 2 == 0) group1.push_back(j);\n            else if (rng() % 2 == 0) group2.push_back(j);\n        }\n        \n        if (group1.empty() || group2.empty()) continue;\n        \n        string res = query(group1, group2);\n        queries_used++;\n        \n        // Adjust weights based on group comparison\n        if (res == \">\") {\n            for (int x : group1) estimated_weight[x] += 1;\n        } else if (res == \"<\") {\n            for (int x : group2) estimated_weight[x] += 1;\n        }\n    }\n    \n    // Phase 3: Sort by estimated weight and assign greedily\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        return estimated_weight[a] > estimated_weight[b];\n    });\n    \n    vector<long long> group_sum(D, 0);\n    \n    // Assign heaviest items first to balance groups\n    for (int i = 0; i < N; i++) {\n        int item = order[i];\n        // Find group with minimum current sum\n        int best_group = 0;\n        for (int g = 1; g < D; g++) {\n            if (group_sum[g] < group_sum[best_group]) {\n                best_group = g;\n            }\n        }\n        assignment[item] = best_group;\n        group_sum[best_group] += estimated_weight[item];\n    }\n    \n    // Phase 4: Try some local improvements with remaining queries\n    for (int q = queries_used; q < Q && q < queries_used + Q/8; q++) {\n        // Try swapping two items between groups\n        int a = rng() % N;\n        int b = rng() % N;\n        if (a == b || assignment[a] == assignment[b]) continue;\n        \n        // Compare these two items\n        string res = query({a}, {b});\n        \n        // If our assignment seems wrong, try to fix it\n        if ((res == \">\" && group_sum[assignment[a]] < group_sum[assignment[b]]) ||\n            (res == \"<\" && group_sum[assignment[a]] > group_sum[assignment[b]])) {\n            // Swap assignments\n            int old_a = assignment[a];\n            int old_b = assignment[b];\n            assignment[a] = old_b;\n            assignment[b] = old_a;\n            group_sum[old_b] += estimated_weight[a] - estimated_weight[b];\n            group_sum[old_a] += estimated_weight[b] - estimated_weight[a];\n        }\n    }\n    \n    // Output final assignment\n    for (int i = 0; i < N; i++) {\n        cout << assignment[i];\n        if (i < N-1) cout << \" \";\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 200;\nconst int MAXM = 10;\n\nint n, m;\nvector<int> st[MAXM];\npair<int,int> where[MAXN+1]; // {stack, index} for box v; stack=-1 if carried\n\nvector<pair<int,int>> ops;\n\n// Carry out box v from stack s\nvoid carry_out(int v, int s) {\n    ops.emplace_back(v, 0);\n    st[s].pop_back();\n    where[v] = {-1, -1};\n}\n\n// Move box v and all above it from stack s to stack t\nvoid move_block(int v, int s, int t) {\n    int idx = where[v].second;\n    int k = st[s].size() - idx; // number of boxes to move\n    ops.emplace_back(v, t+1); // output is 1-indexed\n\n    // Extract block\n    vector<int> block(st[s].begin() + idx, st[s].end());\n    st[s].resize(idx);\n\n    // Append to target\n    for(int x : block) {\n        st[t].push_back(x);\n        where[x] = {t, (int)st[t].size()-1};\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> n >> m;\n    for(int i = 0; i < m; i++) {\n        st[i].resize(n/m);\n        for(int j = 0; j < n/m; j++) {\n            cin >> st[i][j];\n            where[ st[i][j] ] = {i, j};\n        }\n    }\n\n    int next_out = 1;\n\n    while(next_out <= n) {\n        // Phase 1: carry out as many as possible\n        bool progress = true;\n        while(progress && next_out <= n) {\n            progress = false;\n            // Find if next_out is at top of any stack\n            for(int i = 0; i < m; i++) {\n                if(!st[i].empty() && st[i].back() == next_out) {\n                    carry_out(next_out, i);\n                    next_out++;\n                    progress = true;\n                    break;\n                }\n            }\n        }\n        if(next_out > n) break;\n\n        // Phase 2: next_out is buried somewhere\n        int s = -1;\n        for(int i = 0; i < m; i++) {\n            for(int j = 0; j < st[i].size(); j++) {\n                if(st[i][j] == next_out) {\n                    s = i;\n                    break;\n                }\n            }\n            if(s != -1) break;\n        }\n        // s is the stack containing next_out\n        int idx = where[next_out].second;\n        int k = st[s].size() - idx; // boxes from next_out to top\n\n        // Choose target stack t != s with maximum top box\n        int best_t = -1;\n        int best_top = -1;\n        for(int t = 0; t < m; t++) {\n            if(t == s) continue;\n            int top_val = st[t].empty() ? 0 : st[t].back();\n            if(top_val > best_top) {\n                best_top = top_val;\n                best_t = t;\n            }\n        }\n        // Move block to best_t\n        move_block(next_out, s, best_t);\n    }\n\n    // Output operations\n    for(auto [v, i] : ops) {\n        cout << v << \" \" << i << \"\\n\";\n    }\n\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nstatic const int DI[4] = {1,0,-1,0};\nstatic const int DJ[4] = {0,1,0,-1};\nstatic const char DC[4] = {'D','R','U','L'};\n\nint main(){\n  ios::sync_with_stdio(false);\n  cin.tie(nullptr);\n\n  int N; cin>>N;\n  vector<string> hwall(N-1), vwall(N);\n  for(int i=0;i<N-1;i++) cin>>hwall[i];\n  for(int i=0;i<N;  i++) cin>>vwall[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  // build adj\n  auto inside = [&](int i,int j){ return 0<=i&&i<N&&0<=j&&j<N; };\n  vector<vector<array<int,2>>> adj(N*N);\n  auto enc = [&](int i,int j){ return i*N+j; };\n  auto dec = [&](int v){ return array<int,2>{v/N, v%N}; };\n  for(int i=0;i<N;i++){\n    for(int j=0;j<N;j++){\n      int v = enc(i,j);\n      for(int dir=0;dir<4;dir++){\n        int ni=i+DI[dir], nj=j+DJ[dir];\n        if(!inside(ni,nj)) continue;\n        bool ok = true;\n        if(dir==0){ // D\n          if(hwall[i][j]=='1') ok=false;\n        }else if(dir==2){ // U\n          if(hwall[i-1][j]=='1') ok=false;\n        }else if(dir==1){ // R\n          if(vwall[i][j]=='1') ok=false;\n        }else{ // L\n          if(vwall[i][j-1]=='1') ok=false;\n        }\n        if(ok){\n          adj[v].push_back({enc(ni,nj), dir});\n        }\n      }\n    }\n  }\n\n  // 1. basic Euler tour by DFS (simple, ensures all visited)\n  vector<bool> vis(N*N,false);\n  string basic;\n  function<void(int)> dfs = [&](int v){\n    vis[v]=true;\n    auto [i,j]=dec(v);\n    for(auto [u,dir]: adj[v]){\n      if(!vis[u]){\n        basic += DC[dir];\n        dfs(u);\n        basic += DC[dir^2]; // back\n      }\n    }\n  };\n  dfs(0);\n  // basic is already closed at (0,0)\n\n  // 2. enumerate small cycles (length <= 10) for each node\n  const int MAXCYCLE=10;\n  vector<vector<array<int,2>>> cycles(N*N); // cycles[v] = list of {start_index_in_basic, cycle_length}\n  // but we need actual cycle sequences to insert\n  // instead, we precompute for each node v: list of cycles (as string) that start from v and return to v with length <= MAXCYCLE\n  vector<vector<string>> nodeCycles(N*N);\n  vector<int> dist(N*N), parent(N*N), parDir(N*N);\n  for(int sv=0; sv<N*N; sv++){\n    fill(dist.begin(), dist.end(), -1);\n    dist[sv]=0;\n    queue<int> q; q.push(sv);\n    while(!q.empty()){\n      int v=q.front(); q.pop();\n      if(dist[v]>=MAXCYCLE) continue;\n      for(auto [u,dir]: adj[v]){\n        if(dist[u]==-1){\n          dist[u]=dist[v]+1;\n          parent[u]=v;\n          parDir[u]=dir;\n          q.push(u);\n        }\n        // found back to sv\n        if(u==sv && dist[v]+1>=2 && dist[v]+1<=MAXCYCLE){\n          // reconstruct\n          string cyc;\n          int x=v;\n          int len=dist[v]+1;\n          while(x!=sv){\n            cyc += DC[parDir[x]];\n            x = parent[x];\n          }\n          // we are at sv, but we need to close the cycle\n          // last step from v to sv is by 'dir'\n          // but we already have full path\n          // actually we don't need to push last dir, because we are already at sv\n          // the cycle string is cyc (from sv to v) and then one more step dir\n          cyc += DC[dir];\n          // this cycle starts/ends at sv, length = len\n          nodeCycles[sv].push_back(cyc);\n        }\n      }\n    }\n  }\n\n  // 3. compute efficiency = (sum of d on cycle vertices) / (cycle length)\n  vector<tuple<double,int,int,string>> effCycles; // (eff, node, index_in_nodeCycles, cycle_string)\n  for(int v=0;v<N*N;v++){\n    auto [i0,j0]=dec(v);\n    for(auto& cyc: nodeCycles[v]){\n      set<int> verts;\n      int u=v;\n      verts.insert(u);\n      for(char ch: cyc){\n        int dir = string(\"DRUL\").find(ch);\n        auto [i,j]=dec(u);\n        int ni=i+DI[dir], nj=j+DJ[dir];\n        u = enc(ni,nj);\n        verts.insert(u);\n      }\n      long long sd=0;\n      for(int x: verts){\n        auto [i,j]=dec(x);\n        sd += d[i][j];\n      }\n      double eff = (double)sd / (double)cyc.size();\n      effCycles.emplace_back(eff, v, 0, cyc);\n    }\n  }\n  // sort by eff desc\n  sort(effCycles.rbegin(), effCycles.rend());\n\n  // 4. try to insert high-eff cycles into basic as many as possible\n  // we can do: for each occurrence of v in basic, we can insert cycle there\n  // but we do greedy: take highest eff, and insert as many as possible within budget\n  const int LMAX = 100000;\n  int budget = LMAX - (int)basic.size();\n  string route = basic;\n  // we need to know positions of each node in route\n  // but route will be extended dynamically -> we do offline: precompute positions in basic, and insertions\n  // instead, we do simple: for each cycle in effCycles, try to insert at first occurrence of node\n  vector<int> posInBasic(N*N, -1);\n  {\n    int u=0;\n    posInBasic[u]=0;\n    for(int i=0;i<(int)basic.size();i++){\n      char ch=basic[i];\n      int dir=string(\"DRUL\").find(ch);\n      auto [x,y]=dec(u);\n      int nx=x+DI[dir], ny=y+DJ[dir];\n      u = enc(nx,ny);\n      if(posInBasic[u]==-1) posInBasic[u]=i+1;\n    }\n  }\n  // now for each cycle, if node v appears in basic, we can insert at posInBasic[v]\n  // we do greedy: for each cycle, insert as many as possible at that position\n  for(auto& [eff, v, dummy, cyc]: effCycles){\n    if(budget <=0) break;\n    int p = posInBasic[v];\n    if(p==-1) continue;\n    int len = cyc.size();\n    int maxrep = budget / len;\n    if(maxrep<=0) continue;\n    string add;\n    for(int t=0;t<maxrep;t++) add += cyc;\n    // insert at p\n    route.insert(p, add);\n    budget -= maxrep * len;\n  }\n\n  // 5. ensure we are back at (0,0) and length <= 1e5\n  // our basic was closed, and inserted cycles are closed, so whole route is closed\n  if(route.size() > LMAX){\n    route.resize(LMAX);\n  }\n  cout << route << endl;\n\n  return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nconst int INF = 1e9;\nint N, M;\nint si, sj;\narray<array<char, 15>, 15> A;\nvector<string> t(200);\n\n/* ========== basic grid tooling ========== */\nvector<pair<int, int>> pos[26];          // letter -> cells\nint distLetter[26][26];                  // letter -> letter (min steps)\n\nvoid buildDistLetter() {\n    for (int c = 0; c < 26; ++c) {\n        static int d[15][15];\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j) d[i][j] = INF;\n        queue<pair<int, int>> q;\n        for (auto [i, j] : pos[c]) {\n            d[i][j] = 0;\n            q.emplace(i, j);\n        }\n        int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1};\n        while (!q.empty()) {\n            auto [i, j] = q.front(); q.pop();\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + dx[dir], nj = j + dy[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                if (d[ni][nj] > d[i][j] + 1) {\n                    d[ni][nj] = d[i][j] + 1;\n                    q.emplace(ni, nj);\n                }\n            }\n        }\n        for (int c2 = 0; c2 < 26; ++c2) {\n            int best = INF;\n            for (auto [i, j] : pos[c2]) best = min(best, d[i][j]);\n            distLetter[c][c2] = best;\n        }\n    }\n}\n\n/* ========== path reconstruction ========== */\narray<array<pair<int, int>, 15>, 15> pred[26];\nvoid buildPred() {\n    for (int c = 0; c < 26; ++c) {\n        static int d[15][15];\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j) d[i][j] = INF;\n        queue<pair<int, int>> q;\n        for (auto [i, j] : pos[c]) {\n            d[i][j] = 0;\n            pred[c][i][j] = {-1, -1};\n            q.emplace(i, j);\n        }\n        int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1};\n        while (!q.empty()) {\n            auto [i, j] = q.front(); q.pop();\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + dx[dir], nj = j + dy[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                if (d[ni][nj] > d[i][j] + 1) {\n                    d[ni][nj] = d[i][j] + 1;\n                    pred[c][ni][nj] = {i, j};\n                    q.emplace(ni, nj);\n                }\n            }\n        }\n    }\n}\n\n/* ========== overlap ========== */\nint overlap(const string& a, const string& b) {\n    int maxo = 0;\n    int al = a.size(), bl = b.size();\n    int lim = min(al, bl);\n    for (int o = 1; o <= lim; ++o) {\n        bool ok = true;\n        for (int i = 0; i < o; ++i)\n            if (a[al - o + i] != b[i]) { ok = false; break; }\n        if (ok) maxo = o;\n    }\n    return maxo;\n}\n\n/* ========== Aho\u2013Corasick for full check ========== */\nnamespace AC {\n    const int A = 26, N = 200 * 5 + 10;\n    int trie[N][A], fail[N], cnt[N], nodes = 1;\n    int insert(const string& s) {\n        int v = 0;\n        for (char ch : s) {\n            int c = ch - 'A';\n            if (!trie[v][c]) trie[v][c] = nodes++;\n            v = trie[v][c];\n        }\n        cnt[v]++;\n        return v;\n    }\n    void build() {\n        queue<int> q;\n        for (int c = 0; c < A; ++c) if (trie[0][c]) q.push(trie[0][c]);\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            for (int c = 0; c < A; ++c) {\n                int u = trie[v][c];\n                if (!u) { trie[v][c] = trie[fail[v]][c]; continue; }\n                fail[u] = v ? trie[fail[v]][c] : 0;\n                q.push(u);\n            }\n        }\n    }\n    int countMatches(const string& s) {\n        int v = 0, matches = 0;\n        for (char ch : s) {\n            int c = ch - 'A';\n            v = trie[v][c];\n            int tmp = v;\n            while (tmp) { matches += cnt[tmp]; cnt[tmp] = 0; tmp = fail[tmp]; }\n        }\n        return matches;\n    }\n}\n\n/* ========== real path & string ========== */\nvector<pair<int, int>> outPath;\nint curi, curj;\n\nvoid appendMove(int ti, int tj) {\n    if (curi == ti && curj == tj) return;\n    static int d[15][15];\n    static pair<int, int> p[15][15];\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) d[i][j] = INF;\n    queue<pair<int, int>> q;\n    d[curi][curj] = 0;\n    q.emplace(curi, curj);\n    int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1};\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        if (i == ti && j == tj) break;\n        for (int dir = 0; dir < 4; ++dir) {\n            int ni = i + dx[dir], nj = j + dy[dir];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            if (d[ni][nj] > d[i][j] + 1) {\n                d[ni][nj] = d[i][j] + 1;\n                p[ni][nj] = {i, j};\n                q.emplace(ni, nj);\n            }\n        }\n    }\n    vector<pair<int, int>> rev;\n    auto xy = make_pair(ti, tj);\n    while (xy.first != curi || xy.second != curj) {\n        rev.push_back(xy);\n        xy = p[xy.first][xy.second];\n    }\n    reverse(rev.begin(), rev.end());\n    for (auto [i, j] : rev) outPath.emplace_back(i, j);\n    curi = ti; curj = tj;\n}\n\n/* choose concrete cells for a suffix */\nvector<pair<int, int>> chooseCells(const string& s, char nextFirst) {\n    vector<pair<int, int>> res;\n    int nc = nextFirst == 0 ? -1 : nextFirst - 'A';\n    for (char c : s) {\n        int cc = c - 'A';\n        int best = INF;\n        pair<int, int> pick;\n        for (auto [i, j] : pos[cc]) {\n            int dd = abs(i - curi) + abs(j - curj);\n            int centr = abs(i - N / 2) + abs(j - N / 2);\n            int score = dd + centr / 3;\n            if (score < best) { best = score; pick = {i, j}; }\n        }\n        res.push_back(pick);\n        curi = pick.first; curj = pick.second;\n    }\n    return res;\n}\n\n/* build path & extract string S */\nstring buildString(const vector<int>& ord) {\n    outPath.clear();\n    curi = si; curj = sj;\n    string S;\n    S.reserve(6000);\n    auto pushCell = [&](int i, int j) {\n        appendMove(i, j);\n        S.push_back(A[i][j]);\n    };\n    for (int k = 0; k < M; ++k) {\n        int id = ord[k];\n        const string& w = t[id];\n        if (k == 0) {\n            auto cells = chooseCells(w, M > 1 ? t[ord[1]][0] : 0);\n            for (auto [i, j] : cells) pushCell(i, j);\n        } else {\n            int o = overlap(t[ord[k - 1]], w);\n            string suf = w.substr(o);\n            char nf = 0;\n            if (k + 1 < M) nf = t[ord[k + 1]][0];\n            auto cells = chooseCells(suf, nf);\n            for (auto [i, j] : cells) pushCell(i, j);\n        }\n        if (S.size() > 5000) return \"\";          // early give-up\n    }\n    return S;\n}\n\n/* ========== 2-opt on word order ========== */\nvoid twoOpt(vector<int>& ord) {\n    auto costEdge = [&](int l, int r) {\n        char lc = t[ord[l]].back();\n        char fc = t[ord[r]][0];\n        return distLetter[lc - 'A'][fc - 'A'] + 1;\n    };\n    bool improved = true;\n    int iter = 0;\n    while (improved && ++iter < 1000) {\n        improved = false;\n        for (int i = 0; i + 1 < M; ++i)\n            for (int j = i + 1; j < M; ++j) {\n                ll old = costEdge(i - 1, i) + costEdge(i, i + 1)\n                       + costEdge(j - 1, j) + costEdge(j, (j + 1) % M);\n                ll nw = costEdge(i - 1, j) + costEdge(j, i + 1)\n                      + costEdge(j - 1, i) + costEdge(i, (j + 1) % M);\n                if (nw < old) {\n                    swap(ord[i], ord[j]);\n                    improved = true;\n                }\n            }\n    }\n}\n\n/* ========== driver ========== */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M;\n    cin >> si >> sj;\n    for (int i = 0; i < N; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < N; ++j) {\n            A[i][j] = row[j];\n            pos[A[i][j] - 'A'].emplace_back(i, j);\n        }\n    }\n    for (int k = 0; k < M; ++k) cin >> t[k];\n\n    buildDistLetter();\n    buildPred();\n    /* Aho-Corasick */\n    for (const string& s : t) AC::insert(s);\n    AC::build();\n\n    /* greedy initial order */\n    vector<int> ord(M);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int a, int b) {\n        return t[a] < t[b];\n    });\n    twoOpt(ord);\n\n    /* ensure validity */\n    string S = buildString(ord);\n    if ((int)S.size() > 5000 || AC::countMatches(S) < M) {\n        /* fallback: original greedy overlap order */\n        ord.assign(M, 0);\n        iota(ord.begin(), ord.end(), 0);\n        sort(ord.begin(), ord.end(), [&](int a, int b) {\n            int oa = overlap(t[ord[0]], t[a]);\n            int ob = overlap(t[ord[0]], t[b]);\n            if (oa != ob) return oa > ob;\n            return distLetter[t[ord[0]].back() - 'A'][t[a][0] - 'A']\n                 < distLetter[t[ord[0]].back() - 'A'][t[b][0] - 'A'];\n        });\n        S = buildString(ord);\n    }\n\n    /* output path */\n    for (auto [i, j] : outPath) cout << i << ' ' << j << '\\n';\n    return 0;\n}","ahc030":"#include <iostream>\n#include <vector>\n#include <set>\n#include <algorithm>\n\nusing namespace std;\n\nint N, M;\ndouble eps;\nvector<vector<bool>> drilled;\nvector<vector<int>> values;\n\n// Simple query functions\nint drill(int i, int j) {\n    cout << \"q 1 \" << i << \" \" << j << endl;\n    int response;\n    cin >> response;\n    return response;\n}\n\nint divine(const vector<pair<int, int>>& points) {\n    if (points.size() < 2) return 0;\n    \n    cout << \"q \" << points.size();\n    for (auto [i, j] : points) {\n        cout << \" \" << i << \" \" << j;\n    }\n    cout << endl;\n    \n    int response;\n    cin >> response;\n    return max(0, response);  // Ensure non-negative\n}\n\nbool answer(const vector<pair<int, int>>& answer_points) {\n    cout << \"a \" << answer_points.size();\n    for (auto [i, j] : answer_points) {\n        cout << \" \" << i << \" \" << j;\n    }\n    cout << endl;\n    \n    int response;\n    cin >> response;\n    return response == 1;\n}\n\nint main() {\n    // Read input\n    cin >> N >> M >> eps;\n    \n    // Read oil field shapes (we'll use these for intelligent guessing)\n    vector<vector<pair<int, int>>> oil_fields(M);\n    for (int k = 0; k < M; k++) {\n        int d;\n        cin >> d;\n        oil_fields[k].resize(d);\n        for (int i = 0; i < d; i++) {\n            cin >> oil_fields[k][i].first >> oil_fields[k][i].second;\n        }\n    }\n    \n    // Initialize tracking\n    drilled.assign(N, vector<bool>(N, false));\n    values.assign(N, vector<int>(N, -1));\n    \n    vector<pair<int, int>> oil_squares;\n    int operations = 0;\n    const int max_ops = 2 * N * N;\n    \n    // Strategy 1: Use divination to find regions with oil\n    // Divide grid into blocks and divine each block\n    \n    int block_size = 4;  // 4x4 blocks\n    if (N <= 12) block_size = 3;\n    if (N <= 8) block_size = 2;\n    \n    for (int bi = 0; bi < N && operations < max_ops - 50; bi += block_size) {\n        for (int bj = 0; bj < N && operations < max_ops - 50; bj += block_size) {\n            vector<pair<int, int>> block;\n            \n            for (int i = bi; i < min(bi + block_size, N); i++) {\n                for (int j = bj; j < min(bj + block_size, N); j++) {\n                    block.emplace_back(i, j);\n                }\n            }\n            \n            if (block.size() >= 2) {\n                int sum = divine(block);\n                operations++;\n                \n                // If sum is significant, this block likely contains oil\n                if (sum > 0) {\n                    // Drill a few squares in this block to confirm\n                    int to_drill = min(sum, (int)block.size() / 2);\n                    for (int k = 0; k < to_drill && operations < max_ops - 20; k++) {\n                        auto [i, j] = block[k];\n                        if (!drilled[i][j]) {\n                            int val = drill(i, j);\n                            operations++;\n                            drilled[i][j] = true;\n                            values[i][j] = val;\n                            if (val > 0) {\n                                oil_squares.emplace_back(i, j);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Strategy 2: If we found oil, explore around it using shape information\n    if (!oil_squares.empty() && operations < max_ops - 20) {\n        // For each oil square we found, check neighbors that could be part of oil fields\n        set<pair<int, int>> candidates;\n        \n        for (auto [oi, oj] : oil_squares) {\n            // Add all neighbors within reasonable distance\n            for (int di = -3; di <= 3; di++) {\n                for (int dj = -3; dj <= 3; dj++) {\n                    int ni = oi + di, nj = oj + dj;\n                    if (ni >= 0 && ni < N && nj >= 0 && nj < N && !drilled[ni][nj]) {\n                        candidates.insert({ni, nj});\n                    }\n                }\n            }\n        }\n        \n        // Divine groups of candidates\n        vector<pair<int, int>> candidate_list(candidates.begin(), candidates.end());\n        for (int i = 0; i < (int)candidate_list.size() && operations < max_ops - 10; i += 9) {\n            vector<pair<int, int>> group;\n            for (int j = i; j < min(i + 9, (int)candidate_list.size()); j++) {\n                group.push_back(candidate_list[j]);\n            }\n            if (group.size() >= 2) {\n                int sum = divine(group);\n                operations++;\n                \n                // Drill high-probability squares\n                if (sum > 0) {\n                    int to_drill = min(sum, (int)group.size());\n                    for (int k = 0; k < to_drill && operations < max_ops - 5; k++) {\n                        auto [x, y] = group[k];\n                        if (!drilled[x][y]) {\n                            int val = drill(x, y);\n                            operations++;\n                            drilled[x][y] = true;\n                            values[x][y] = val;\n                            if (val > 0) {\n                                oil_squares.emplace_back(x, y);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Strategy 3: Final cleanup - check remaining high-probability areas\n    // Focus on center areas first as oil fields are more likely there\n    vector<pair<int, int>> remaining;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (!drilled[i][j]) {\n                // Priority based on distance to center and existing oil\n                int dist_to_center = abs(i - N/2) + abs(j - N/2);\n                int dist_to_oil = N * 2;\n                for (auto [oi, oj] : oil_squares) {\n                    dist_to_oil = min(dist_to_oil, abs(i - oi) + abs(j - oj));\n                }\n                \n                int priority = dist_to_oil * 2 + dist_to_center;\n                remaining.push_back({i, j});\n            }\n        }\n    }\n    \n    // Drill remaining squares strategically\n    for (int i = 0; i < (int)remaining.size() && operations < max_ops - 1; i++) {\n        auto [x, y] = remaining[i];\n        int val = drill(x, y);\n        operations++;\n        drilled[x][y] = true;\n        values[x][y] = val;\n        if (val > 0) {\n            oil_squares.emplace_back(x, y);\n        }\n    }\n    \n    // Final answer\n    answer(oil_squares);\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nstatic const int W = 1000;\nint D, N;\nvector<vector<int>> a;\n\n// partition bitsets: 1 = partition exists\n// Hseg[i][j] : horizontal segment at row i, columns j..j+1  (i in [1,W-1], j in [0,W-1])\n// Vseg[i][j] : vertical   segment at col j, rows i..i+1    (i in [0,W-1], j in [1,W-1])\nbitset<W> Hseg[W], Vseg[W];\n\nstruct Rect {\n    int i0, j0, i1, j1;\n    int area() const { return (i1 - i0) * (j1 - j0); }\n};\n\n// output rectangles per day\nvector<vector<Rect>> outRect;\n\n// compute partition-change cost versus previous day\nint computeLd(const vector<Rect>& rects) {\n    // new partition maps\n    bitset<W> nH[W], nV[W];\n    for (const auto& r : rects) {\n        int i0 = r.i0, j0 = r.j0, i1 = r.i1, j1 = r.j1;\n        // top edge\n        if (i0 > 0)      for (int j = j0; j < j1; ++j) nH[i0].set(j);\n        // bottom edge\n        if (i1 < W)      for (int j = j0; j < j1; ++j) nH[i1].set(j);\n        // left edge\n        if (j0 > 0)      for (int i = i0; i < i1; ++i) nV[i].set(j0);\n        // right edge\n        if (j1 < W)      for (int i = i0; i < i1; ++i) nV[i].set(j1);\n    }\n    int cost = 0;\n    for (int i = 1; i < W; ++i) {\n        auto diff = Hseg[i] ^ nH[i];\n        cost += diff.count();\n    }\n    for (int j = 1; j < W; ++j) {\n        bitset<W> diff;\n        for (int i = 0; i < W; ++i) diff[i] = Vseg[i][j] ^ nV[i][j];\n        cost += diff.count();\n    }\n    return cost;\n}\n\n// assign rectangles for one day\nvoid solveDay(int d) {\n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    // largest first\n    sort(ord.begin(), ord.end(), [&](int x, int y) {\n        return a[d][x] > a[d][y];\n    });\n\n    // free rectangles\n    vector<Rect> freeList = { {0, 0, W, W} };\n    vector<Rect> assigned(N);\n\n    auto bestSplit = [&](const Rect& hole, int need,\n                         int& bestCost, Rect& bestA, Rect& bestB, bool& bestIsHoriz) {\n        bestCost = INT_MAX;\n        int h = hole.i1 - hole.i0;\n        int w = hole.j1 - hole.j0;\n        // try horizontal split: i0..cut and cut..i1\n        if (h > 1) {\n            int cutLo = hole.i0 + 1;\n            int cutHi = hole.i1 - 1;\n            int step = max(1, (cutHi - cutLo + 1) / 20);\n            for (int cut = cutLo; cut <= cutHi; cut += step) {\n                Rect A = { hole.i0, hole.j0, cut,     hole.j1 };\n                Rect B = { cut,     hole.j0, hole.i1, hole.j1 };\n                if (A.area() < need) continue;\n                // compute extra partition cost\n                int c = 0;\n                // new horizontal segment at 'cut'\n                for (int j = hole.j0; j < hole.j1; ++j) {\n                    bool old = Hseg[cut][j];\n                    if (!old) c++;\n                }\n                if (c < bestCost) {\n                    bestCost = c;\n                    bestA = A;\n                    bestB = B;\n                    bestIsHoriz = true;\n                }\n            }\n        }\n        // try vertical split\n        if (w > 1) {\n            int cutLo = hole.j0 + 1;\n            int cutHi = hole.j1 - 1;\n            int step = max(1, (cutHi - cutLo + 1) / 20);\n            for (int cut = cutLo; cut <= cutHi; cut += step) {\n                Rect A = { hole.i0, hole.j0, hole.i1, cut };\n                Rect B = { hole.i0, cut,     hole.i1, hole.j1 };\n                if (A.area() < need) continue;\n                int c = 0;\n                for (int i = hole.i0; i < hole.i1; ++i) {\n                    bool old = Vseg[i][cut];\n                    if (!old) c++;\n                }\n                if (c < bestCost) {\n                    bestCost = c;\n                    bestA = A;\n                    bestB = B;\n                    bestIsHoriz = false;\n                }\n            }\n        }\n    };\n\n    for (int k : ord) {\n        int need = a[d][k];\n        int bestCost = INT_MAX;\n        Rect bestA, bestB;\n        bool bestIsHoriz = false;\n        int bestIdx = -1;\n        for (int idx = 0; idx < (int)freeList.size(); ++idx) {\n            const Rect& hole = freeList[idx];\n            if (hole.area() < need) continue;\n            int c; Rect A, B; bool ih;\n            bestSplit(hole, need, c, A, B, ih);\n            if (c < bestCost) {\n                bestCost = c;\n                bestA = A;\n                bestB = B;\n                bestIsHoriz = ih;\n                bestIdx = idx;\n            }\n        }\n        assert(bestIdx != -1);\n        assigned[k] = bestA;\n        freeList[bestIdx] = bestB;\n    }\n\n    // store output order\n    outRect[d] = assigned;\n\n    // update global partition maps for next day\n    for (int i = 0; i < W; ++i) Hseg[i].reset();\n    for (int j = 0; j < W; ++j) Vseg[j].reset();\n    for (const auto& r : assigned) {\n        int i0 = r.i0, j0 = r.j0, i1 = r.i1, j1 = r.j1;\n        if (i0 > 0)      for (int j = j0; j < j1; ++j) Hseg[i0].set(j);\n        if (i1 < W)      for (int j = j0; j < j1; ++j) Hseg[i1].set(j);\n        if (j0 > 0)      for (int i = i0; i < i1; ++i) Vseg[i].set(j0);\n        if (j1 < W)      for (int i = i0; i < i1; ++i) Vseg[i].set(j1);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> W >> D >> N;\n    a.assign(D, vector<int>(N));\n    for (int d = 0; d < D; ++d)\n        for (int k = 0; k < N; ++k)\n            cin >> a[d][k];\n\n    outRect.assign(D, vector<Rect>(N));\n\n    // initialize partitions: none\n    for (int i = 0; i < W; ++i) {\n        Hseg[i].reset();\n        Vseg[i].reset();\n    }\n\n    for (int d = 0; d < D; ++d) {\n        solveDay(d);\n    }\n\n    // output\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            const auto& r = outRect[d][k];\n            cout << r.i0 << ' ' << r.j0 << ' ' << r.i1 << ' ' << r.j1 << '\\n';\n        }\n    }\n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <tuple>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\nconst int MOD = 998244353;\nconst int N = 9;\nconst int M = 20;\nconst int K = 81;\n\nint board[N][N];\nint stamps[M][3][3];\nint temp_board[N][N];\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint compute_marginal(int m, int p, int q) {\n    int gain = 0;\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            int original = board[p + i][q + j] % MOD;\n            int new_val = (board[p + i][q + j] + stamps[m][i][j]) % MOD;\n            gain += new_val - original;\n        }\n    }\n    return gain;\n}\n\nvoid apply_stamp(int m, int p, int q) {\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            board[p + i][q + j] = (board[p + i][q + j] + stamps[m][i][j]) % MOD;\n        }\n    }\n}\n\nvoid revert_stamp(int m, int p, int q) {\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            board[p + i][q + j] = (board[p + i][q + j] - stamps[m][i][j] % MOD + MOD) % MOD;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n, m, k;\n    cin >> n >> m >> k;\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cin >> board[i][j];\n        }\n    }\n    for (int mm = 0; mm < m; ++mm) {\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                cin >> stamps[mm][i][j];\n            }\n        }\n    }\n\n    vector<tuple<int, int, int>> operations;\n\n    for (int step = 0; step < k; ++step) {\n        vector<tuple<int, int, int, int>> candidates; // (gain, m, p, q)\n        for (int mm = 0; mm < m; ++mm) {\n            for (int p = 0; p <= n - 3; ++p) {\n                for (int q = 0; q <= n - 3; ++q) {\n                    int gain = compute_marginal(mm, p, q);\n                    candidates.emplace_back(gain, mm, p, q);\n                }\n            }\n        }\n\n        sort(candidates.rbegin(), candidates.rend());\n        bool found = false;\n\n        // Try top 10 candidates with lookahead 2\n        for (int attempt = 0; attempt < min(10, (int)candidates.size()); ++attempt) {\n            auto [gain1, m1, p1, q1] = candidates[attempt];\n            if (gain1 <= 0 && attempt > 0) break;\n\n            apply_stamp(m1, p1, q1);\n\n            // Lookahead: find best second step\n            int best_gain2 = -1e9;\n            int best_m2 = -1, best_p2 = -1, best_q2 = -1;\n            for (int mm = 0; mm < m; ++mm) {\n                for (int p = 0; p <= n - 3; ++p) {\n                    for (int q = 0; q <= n - 3; ++q) {\n                        int gain2 = compute_marginal(mm, p, q);\n                        if (gain2 > best_gain2) {\n                            best_gain2 = gain2;\n                            best_m2 = mm;\n                            best_p2 = p;\n                            best_q2 = q;\n                        }\n                    }\n                }\n            }\n\n            if (gain1 + best_gain2 > 0) {\n                operations.emplace_back(m1, p1, q1);\n                found = true;\n                break;\n            } else {\n                revert_stamp(m1, p1, q1);\n            }\n        }\n\n        if (!found) {\n            // Random exploration\n            uniform_int_distribution<int> dist_m(0, m - 1);\n            uniform_int_distribution<int> dist_p(0, n - 3);\n            uniform_int_distribution<int> dist_q(0, n - 3);\n            int m_rand = dist_m(rng);\n            int p_rand = dist_p(rng);\n            int q_rand = dist_q(rng);\n            operations.emplace_back(m_rand, p_rand, q_rand);\n            apply_stamp(m_rand, p_rand, q_rand);\n        }\n    }\n\n    cout << operations.size() << '\\n';\n    for (auto [mm, p, q] : operations) {\n        cout << mm << ' ' << p << ' ' << q << '\\n';\n    }\n\n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <string>\n\nusing namespace std;\n\nconst int MAX_N = 5;\n\nint N;\nint A[MAX_N][MAX_N];\nvector<string> operations(MAX_N);\n\n// Current state\nint grid[MAX_N][MAX_N];  // -1 if empty, otherwise container number\nint crane_pos[MAX_N][2];  // crane positions: [crane_id][x,y]\nbool crane_carry[MAX_N];  // whether crane is holding\nint crane_container[MAX_N];  // container being carried (-1 if none)\nbool crane_alive[MAX_N];\n\n// Helper functions\nint get_target_gate(int container) {\n    if (container < 0 || container >= N*N) return 0;\n    return container / N;\n}\n\nbool is_valid_position(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N;\n}\n\nbool can_crane_move(int crane_id, int dx, int dy) {\n    if (!crane_alive[crane_id]) return false;\n    \n    int new_x = crane_pos[crane_id][0] + dx;\n    int new_y = crane_pos[crane_id][1] + dy;\n    \n    if (!is_valid_position(new_x, new_y)) return false;\n    \n    // Check crane collision\n    for (int i = 0; i < N; i++) {\n        if (i != crane_id && crane_alive[i] && \n            crane_pos[i][0] == new_x && crane_pos[i][1] == new_y) {\n            return false;\n        }\n    }\n    \n    // Small crane carrying cannot move to occupied square\n    if (crane_id > 0 && crane_carry[crane_id] && grid[new_x][new_y] != -1) {\n        return false;\n    }\n    \n    return true;\n}\n\nvoid simulate_turn(const vector<char>& moves) {\n    // Step 1: Receive containers\n    static int received_count[MAX_N] = {0};\n    for (int i = 0; i < N; i++) {\n        if (grid[i][0] == -1 && !crane_carry[i] && received_count[i] < N) {\n            bool occupied = false;\n            for (int j = 0; j < N; j++) {\n                if (crane_pos[j][0] == i && crane_pos[j][1] == 0 && crane_alive[j]) {\n                    occupied = true;\n                    break;\n                }\n            }\n            if (!occupied) {\n                grid[i][0] = A[i][received_count[i]];\n                received_count[i]++;\n            }\n        }\n    }\n    \n    // Step 2: Execute crane moves\n    for (int i = 0; i < N && i < (int)moves.size(); i++) {\n        if (!crane_alive[i]) continue;\n        \n        char move = moves[i];\n        \n        if (move == 'P') {\n            if (!crane_carry[i] && grid[crane_pos[i][0]][crane_pos[i][1]] != -1) {\n                crane_carry[i] = true;\n                crane_container[i] = grid[crane_pos[i][0]][crane_pos[i][1]];\n                grid[crane_pos[i][0]][crane_pos[i][1]] = -1;\n            }\n        } else if (move == 'Q') {\n            if (crane_carry[i] && grid[crane_pos[i][0]][crane_pos[i][1]] == -1) {\n                crane_carry[i] = false;\n                grid[crane_pos[i][0]][crane_pos[i][1]] = crane_container[i];\n                crane_container[i] = -1;\n            }\n        } else if (move == 'U' && can_crane_move(i, -1, 0)) {\n            crane_pos[i][0]--;\n        } else if (move == 'D' && can_crane_move(i, 1, 0)) {\n            crane_pos[i][0]++;\n        } else if (move == 'L' && can_crane_move(i, 0, -1)) {\n            crane_pos[i][1]--;\n        } else if (move == 'R' && can_crane_move(i, 0, 1)) {\n            crane_pos[i][1]++;\n        } else if (move == 'B') {\n            if (!crane_carry[i]) {\n                crane_alive[i] = false;\n            }\n        }\n    }\n    \n    // Step 3: Dispatch containers\n    for (int i = 0; i < N; i++) {\n        if (grid[i][N-1] != -1) {\n            grid[i][N-1] = -1;\n        }\n    }\n}\n\nint main() {\n    cin >> N;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> A[i][j];\n        }\n    }\n    \n    // Initialize state\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = -1;\n        }\n        crane_pos[i][0] = i;\n        crane_pos[i][1] = 0;\n        crane_carry[i] = false;\n        crane_container[i] = -1;\n        crane_alive[i] = true;\n        operations[i] = \"\";\n    }\n    \n    // Conservative strategy: Safe movement with strong boundary checks\n    int turns = 0;\n    const int max_turns = 5000; // Reduced to ensure safety\n    \n    while (turns < max_turns) {\n        vector<char> current_moves(N, '.');\n        \n        // Large crane (index 0): Very conservative approach\n        if (crane_alive[0]) {\n            int x = crane_pos[0][0];\n            int y = crane_pos[0][1];\n            \n            if (!crane_carry[0]) {\n                // Pick up if container available\n                if (grid[x][y] != -1) {\n                    current_moves[0] = 'P';\n                } else {\n                    // Safe exploration: prefer right, then down/up, avoid left edge\n                    if (y < N-1 && can_crane_move(0, 0, 1)) {\n                        current_moves[0] = 'R';\n                    } else if (x < N-1 && can_crane_move(0, 1, 0)) {\n                        current_moves[0] = 'D';\n                    } else if (x > 0 && can_crane_move(0, -1, 0)) {\n                        current_moves[0] = 'U';\n                    }\n                }\n            } else {\n                // Move toward right edge carefully\n                int container = crane_container[0];\n                int target_gate = get_target_gate(container);\n                \n                // First get to correct row\n                if (x < target_gate && can_crane_move(0, 1, 0)) {\n                    current_moves[0] = 'D';\n                } else if (x > target_gate && can_crane_move(0, -1, 0)) {\n                    current_moves[0] = 'U';\n                } else if (y < N-1 && can_crane_move(0, 0, 1)) {\n                    current_moves[0] = 'R';\n                } else if (y == N-1) {\n                    current_moves[0] = 'Q';\n                } else {\n                    // Stuck, try alternative moves\n                    if (can_crane_move(0, 1, 0)) {\n                        current_moves[0] = 'D';\n                    } else if (can_crane_move(0, -1, 0)) {\n                        current_moves[0] = 'U';\n                    } else if (can_crane_move(0, 0, -1)) {\n                        current_moves[0] = 'L';\n                    }\n                }\n            }\n        }\n        \n        // Small cranes: Very conservative transport\n        for (int i = 1; i < N; i++) {\n            if (!crane_alive[i]) continue;\n            \n            int x = crane_pos[i][0];\n            int y = crane_pos[i][1];\n            \n            if (!crane_carry[i]) {\n                if (grid[x][y] != -1) {\n                    current_moves[i] = 'P';\n                } else {\n                    // Safe rightward movement\n                    if (y < N-1 && can_crane_move(i, 0, 1)) {\n                        current_moves[i] = 'R';\n                    } else if (x < N-1 && can_crane_move(i, 1, 0) && y > 0) {\n                        current_moves[i] = 'D';\n                    } else if (x > 0 && can_crane_move(i, -1, 0) && y > 0) {\n                        current_moves[i] = 'U';\n                    }\n                }\n            } else {\n                // Move right if possible, otherwise find safe direction\n                if (y < N-1 && can_crane_move(i, 0, 1)) {\n                    current_moves[i] = 'R';\n                } else if (y == N-1) {\n                    current_moves[i] = 'Q';\n                } else {\n                    // Find any safe move\n                    if (can_crane_move(i, 1, 0)) {\n                        current_moves[i] = 'D';\n                    } else if (can_crane_move(i, -1, 0)) {\n                        current_moves[i] = 'U';\n                    } else if (can_crane_move(i, 0, -1)) {\n                        current_moves[i] = 'L';\n                    }\n                }\n            }\n        }\n        \n        // Validate all moves before executing\n        for (int i = 0; i < N; i++) {\n            if (current_moves[i] == 'U' && !can_crane_move(i, -1, 0)) current_moves[i] = '.';\n            if (current_moves[i] == 'D' && !can_crane_move(i, 1, 0)) current_moves[i] = '.';\n            if (current_moves[i] == 'L' && !can_crane_move(i, 0, -1)) current_moves[i] = '.';\n            if (current_moves[i] == 'R' && !can_crane_move(i, 0, 1)) current_moves[i] = '.';\n        }\n        \n        simulate_turn(current_moves);\n        \n        // Record operations\n        for (int i = 0; i < N; i++) {\n            operations[i] += current_moves[i];\n        }\n        \n        turns++;\n        \n        // Early termination check\n        if (turns > 1000) {\n            bool grid_empty = true;\n            for (int i = 0; i < N && grid_empty; i++) {\n                for (int j = 0; j < N && grid_empty; j++) {\n                    if (grid[i][j] != -1) grid_empty = false;\n                }\n            }\n            if (grid_empty) break;\n        }\n    }\n    \n    // Ensure all strings have same length\n    size_t max_len = 0;\n    for (int i = 0; i < N; i++) {\n        max_len = max(max_len, operations[i].size());\n    }\n    \n    for (int i = 0; i < N; i++) {\n        while (operations[i].size() < max_len) {\n            operations[i] += '.';\n        }\n    }\n    \n    // Output operations\n    for (int i = 0; i < N; i++) {\n        cout << operations[i] << endl;\n    }\n    \n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nint h[20][20];\nvector<string> out;\n\nvoid go(int di, int dj) {\n    if (di > 0) for (int k = 0; k < di; ++k) out.push_back(\"D\");\n    if (di < 0) for (int k = 0; k < -di; ++k) out.push_back(\"U\");\n    if (dj > 0) for (int k = 0; k < dj; ++k) out.push_back(\"R\");\n    if (dj < 0) for (int k = 0; k < -dj; ++k) out.push_back(\"L\");\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    vector<tuple<int,int,int>> src, snk;\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) src.emplace_back(i, j, h[i][j]);\n            else if (h[i][j] < 0) snk.emplace_back(i, j, -h[i][j]);\n        }\n\n    int ci = 0, cj = 0;\n    // \u5269\u4f59\u9700\u6c42\u6570\u7ec4\n    vector<int> need(snk.size());\n    for (size_t i = 0; i < snk.size(); ++i) need[i] = get<2>(snk[i]);\n\n    // \u5355\u6e90\u5373\u65f6\u6295\u9012\n    for (auto [si, sj, amt] : src) {\n        // \u7a7a\u8f66\u53bb\u6e90\u70b9\n        go(si - ci, sj - cj);\n        ci = si; cj = sj;\n        out.push_back(\"+\" + to_string(amt));\n        int load = amt;\n\n        // \u6700\u8fd1\u90bb\u5378\u5b8c\n        while (load > 0) {\n            int best = INT_MAX, bi = -1, bj = -1, bidx = -1, bgive = 0;\n            for (size_t i = 0; i < snk.size(); ++i) {\n                if (need[i] == 0) continue;\n                auto [ti, tj, ta] = snk[i];\n                int d = abs(ci - ti) + abs(cj - tj);\n                if (d < best) {\n                    best = d; bi = ti; bj = tj; bidx = (int)i; bgive = min(load, need[i]);\n                }\n            }\n            go(bi - ci, bj - cj);\n            ci = bi; cj = bj;\n            out.push_back(\"-\" + to_string(bgive));\n            load -= bgive;\n            need[bidx] -= bgive;\n        }\n    }\n\n    // \u82e5\u8fd8\u6709\u6c47\u70b9\u672a\u6e05\u96f6\uff08\u6781\u5c11\uff09\uff0c\u7a7a\u8f66\u8865\u9f50\n    for (size_t i = 0; i < snk.size(); ++i) {\n        if (need[i] == 0) continue;\n        auto [ti, tj, ta] = snk[i];\n        go(ti - ci, tj - cj);\n        ci = ti; cj = tj;\n        out.push_back(\"-\" + to_string(need[i]));\n    }\n\n    for (auto &s : out) cout << s << '\\n';\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n\nusing namespace std;\n\nint main() {\n    int N, M, T;\n    cin >> N >> M >> T;\n    \n    const int seed_count = 2 * N * (N - 1);\n    vector<vector<int>> seeds(seed_count, vector<int>(M));\n    vector<int> seed_values(seed_count);\n    \n    // Read initial seeds\n    for (int i = 0; i < seed_count; i++) {\n        for (int j = 0; j < M; j++) {\n            cin >> seeds[i][j];\n        }\n    }\n    \n    for (int turn = 0; turn < T; turn++) {\n        // Calculate current seed values\n        for (int i = 0; i < seed_count; i++) {\n            seed_values[i] = 0;\n            for (int j = 0; j < M; j++) {\n                seed_values[i] += seeds[i][j];\n            }\n        }\n        \n        // Simple strategy: select top 36 seeds by value\n        vector<int> indices(seed_count);\n        for (int i = 0; i < seed_count; i++) {\n            indices[i] = i;\n        }\n        \n        // Sort by value (stable sort)\n        sort(indices.begin(), indices.end(), [&](int a, int b) {\n            return seed_values[a] > seed_values[b];\n        });\n        \n        // Create grid using top seeds\n        vector<vector<int>> grid(N, vector<int>(N));\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int pos = i * N + j;\n                if (pos < 36) {  // Ensure we don't go out of bounds\n                    grid[i][j] = indices[pos];\n                } else {\n                    grid[i][j] = indices[pos % 36];\n                }\n            }\n        }\n        \n        // Output grid\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << grid[i][j];\n                if (j < N - 1) cout << \" \";\n            }\n            cout << endl;\n        }\n        cout.flush();\n        \n        // Read new seeds\n        for (int i = 0; i < seed_count; i++) {\n            for (int j = 0; j < M; j++) {\n                cin >> seeds[i][j];\n            }\n        }\n    }\n    \n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, V;\nvector<string> initial_s, target_t;\nvector<string> current_grid; // Track current state\nvector<vector<int>> children;\nvector<int> parent;\nvector<int> edge_length;\nint root_x, root_y;\n\n// Track current positions of all vertices\nvector<pair<int, int>> vertex_positions;\nvector<int> edge_directions;\n\n// Track held takoyaki\nvector<bool> holding_takoyaki;\n\n// Find positions of 1s in grid\nvector<pair<int, int>> find_positions(const vector<string>& grid) {\n    vector<pair<int, int>> positions;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] == '1') {\n                positions.push_back({i, j});\n            }\n        }\n    }\n    return positions;\n}\n\n// Calculate position of vertex based on parent and edge configuration\npair<int, int> calculate_position(int v) {\n    if (v == 0) return {root_x, root_y};\n    \n    int p = parent[v];\n    auto parent_pos = vertex_positions[p];\n    int dir = edge_directions[v];\n    int len = edge_length[v];\n    \n    int dx[] = {0, 1, 0, -1};\n    int dy[] = {1, 0, -1, 0};\n    \n    return {parent_pos.first + dx[dir] * len, parent_pos.second + dy[dir] * len};\n}\n\n// Update all positions after movement/rotation\nvoid update_positions() {\n    for (int i = 0; i < V; i++) {\n        vertex_positions[i] = calculate_position(i);\n    }\n}\n\n// Build a compact tree with shorter edges\nvoid design_arm() {\n    children.resize(V);\n    parent.resize(V, -1);\n    edge_length.resize(V, 1);\n    vertex_positions.resize(V);\n    edge_directions.resize(V, 0);\n    holding_takoyaki.resize(V, false);\n    \n    // Create a simple structure with clear fingertips\n    if (V >= 3) {\n        // Root -> intermediate -> fingertip structure\n        for (int i = 1; i < V; i++) {\n            parent[i] = i - 1;\n            edge_length[i] = min(2, N / 3);\n            children[i-1].push_back(i);\n        }\n    } else {\n        // Simple chain for small V\n        for (int i = 1; i < V; i++) {\n            parent[i] = 0;\n            edge_length[i] = min(2, N / 3);\n            children[0].push_back(i);\n        }\n    }\n    \n    // Place root in center\n    root_x = N / 2;\n    root_y = N / 2;\n    \n    update_positions();\n}\n\n// Get all leaf nodes (fingertips)\nvector<int> get_fingertips() {\n    vector<int> fingertips;\n    for (int i = 0; i < V; i++) {\n        if (children[i].empty()) {\n            fingertips.push_back(i);\n        }\n    }\n    return fingertips;\n}\n\n// Check if position is valid and contains takoyaki\nbool can_grab_at(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N && current_grid[x][y] == '1';\n}\n\n// Check if position is valid and empty for placement\nbool can_release_at(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N && current_grid[x][y] == '0' && target_t[x][y] == '1';\n}\n\n// Generate intelligent operations\nvector<string> generate_operations() {\n    vector<string> ops;\n    vector<int> fingertips = get_fingertips();\n    vector<pair<int, int>> sources = find_positions(initial_s);\n    vector<pair<int, int>> targets = find_positions(target_t);\n    \n    // Create mapping from positions to track progress\n    set<pair<int, int>> remaining_sources;\n    for (auto& pos : sources) remaining_sources.insert(pos);\n    \n    int turn_count = 0;\n    const int max_turns = 50000;\n    \n    // Systematic coverage with intelligent grab/release\n    for (int sweep = 0; sweep < 4 && turn_count < max_turns; sweep++) {\n        // Spiral inward from corners\n        for (int step = 0; step < N && turn_count < max_turns; step++) {\n            for (int inner = 0; inner < 4 && turn_count < max_turns; inner++) {\n                string op(2 * V, '.');\n                \n                // Move in systematic pattern\n                int target_x = (sweep == 0) ? step : (sweep == 1) ? N-1-step : (sweep == 2) ? step : N-1-step;\n                int target_y = (inner * N/4) % N;\n                \n                // Move root toward target\n                if (root_x < target_x && root_x + 1 < N) {\n                    root_x++;\n                    op[0] = 'D';\n                } else if (root_x > target_x && root_x - 1 >= 0) {\n                    root_x--;\n                    op[0] = 'U';\n                } else if (root_y < target_y && root_y + 1 < N) {\n                    root_y++;\n                    op[0] = 'R';\n                } else if (root_y > target_y && root_y - 1 >= 0) {\n                    root_y--;\n                    op[0] = 'L';\n                }\n                \n                update_positions();\n                \n                // Check each fingertip for possible actions\n                for (int fingertip : fingertips) {\n                    auto pos = vertex_positions[fingertip];\n                    int x = pos.first, y = pos.second;\n                    \n                    if (!holding_takoyaki[fingertip] && can_grab_at(x, y)) {\n                        // Grab takoyaki\n                        op[V + fingertip] = 'P';\n                        holding_takoyaki[fingertip] = true;\n                        current_grid[x][y] = '0';\n                        remaining_sources.erase({x, y});\n                        break; // Only one action per turn\n                    } else if (holding_takoyaki[fingertip] && can_release_at(x, y)) {\n                        // Release takoyaki\n                        op[V + fingertip] = 'P';\n                        holding_takoyaki[fingertip] = false;\n                        current_grid[x][y] = '1';\n                        break; // Only one action per turn\n                    }\n                }\n                \n                ops.push_back(op);\n                turn_count++;\n            }\n        }\n    }\n    \n    return ops;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> V;\n    \n    initial_s.resize(N);\n    target_t.resize(N);\n    \n    for (int i = 0; i < N; i++) {\n        cin >> initial_s[i];\n    }\n    for (int i = 0; i < N; i++) {\n        cin >> target_t[i];\n    }\n    \n    // Initialize current grid\n    current_grid = initial_s;\n    \n    // Design and output arm\n    design_arm();\n    \n    cout << V << \"\\n\";\n    for (int i = 1; i < V; i++) {\n        cout << parent[i] << \" \" << edge_length[i] << \"\\n\";\n    }\n    cout << root_x << \" \" << root_y << \"\\n\";\n    \n    // Generate and output operations\n    auto operations = generate_operations();\n    \n    for (const auto& op : operations) {\n        cout << op << \"\\n\";\n    }\n    \n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    Point(int x = 0, int y = 0) : x(x), y(y) {}\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\nstruct Fish {\n    int x, y, type;\n    Fish(int x = 0, int y = 0, int type = 0) : x(x), y(y), type(type) {}\n};\n\nint N;\nvector<Fish> fishes;\nvector<Point> polygon;\n\n// Ray casting algorithm to check if point is inside polygon\nbool pointInPolygon(int x, int y, const vector<Point>& poly) {\n    int n = poly.size();\n    bool inside = false;\n    \n    for (int i = 0, j = n - 1; i < n; j = i++) {\n        if (((poly[i].y > y) != (poly[j].y > y)) &&\n            (x < (poly[j].x - poly[i].x) * (y - poly[i].y) / (poly[j].y - poly[i].y) + poly[i].x)) {\n            inside = !inside;\n        }\n    }\n    return inside;\n}\n\n// Count fish inside actual polygon\npair<int,int> countFishInPolygon(const vector<Point>& poly) {\n    int mackerels = 0, sardines = 0;\n    for (const auto& fish : fishes) {\n        if (pointInPolygon(fish.x, fish.y, poly)) {\n            if (fish.type == 0) mackerels++;\n            else sardines++;\n        }\n    }\n    return {mackerels, sardines};\n}\n\n// Calculate polygon perimeter\nint calculatePerimeter(const vector<Point>& poly) {\n    int perimeter = 0;\n    int n = poly.size();\n    for (int i = 0; i < n; i++) {\n        int j = (i + 1) % n;\n        perimeter += abs(poly[j].x - poly[i].x) + abs(poly[j].y - poly[i].y);\n    }\n    return perimeter;\n}\n\n// Create rectangle polygon\nvector<Point> createRectangle(int x1, int y1, int x2, int y2) {\n    return {Point(x1, y1), Point(x2, y1), Point(x2, y2), Point(x1, y2)};\n}\n\n// Find dense mackerel regions using grid-based approach\nvector<pair<int,int>> findMackerelClusters() {\n    const int GRID_SIZE = 10000;\n    const int GRIDS = 100000 / GRID_SIZE + 1;\n    \n    vector<vector<int>> grid(GRIDS, vector<int>(GRIDS, 0));\n    \n    // Count mackerels in each grid cell\n    for (const auto& fish : fishes) {\n        if (fish.type == 0) {\n            int gx = fish.x / GRID_SIZE;\n            int gy = fish.y / GRID_SIZE;\n            if (gx < GRIDS && gy < GRIDS) {\n                grid[gx][gy]++;\n            }\n        }\n    }\n    \n    // Find top clusters\n    vector<pair<int,int>> clusters;\n    for (int i = 0; i < GRIDS; i++) {\n        for (int j = 0; j < GRIDS; j++) {\n            if (grid[i][j] > 5) { // Threshold for good cluster\n                clusters.push_back({i * GRID_SIZE + GRID_SIZE/2, j * GRID_SIZE + GRID_SIZE/2});\n            }\n        }\n    }\n    \n    return clusters;\n}\n\n// Try to create polygon around cluster\nvector<Point> createClusterPolygon(int cx, int cy, int size) {\n    int half = size / 2;\n    int x1 = max(0, cx - half);\n    int y1 = max(0, cy - half);\n    int x2 = min(100000, cx + half);\n    int y2 = min(100000, cy + half);\n    \n    return createRectangle(x1, y1, x2, y2);\n}\n\n// Optimize polygon by trying different sizes\nvector<Point> optimizeClusterPolygon(const vector<Point>& initial) {\n    vector<Point> best = initial;\n    auto [bestM, bestS] = countFishInPolygon(best);\n    int bestScore = max(0, bestM - bestS + 1);\n    \n    // Try shrinking the polygon\n    for (int shrink = 1000; shrink >= 100; shrink -= 100) {\n        vector<Point> shrunk;\n        int cx = (initial[0].x + initial[2].x) / 2;\n        int cy = (initial[0].y + initial[2].y) / 2;\n        \n        int half = shrink / 2;\n        int x1 = max(0, cx - half);\n        int y1 = max(0, cy - half);\n        int x2 = min(100000, cx + half);\n        int y2 = min(100000, cy + half);\n        \n        auto candidate = createRectangle(x1, y1, x2, y2);\n        auto [m, s] = countFishInPolygon(candidate);\n        int score = max(0, m - s + 1);\n        \n        if (score > bestScore && calculatePerimeter(candidate) <= 400000) {\n            best = candidate;\n            bestScore = score;\n        }\n    }\n    \n    return best;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    \n    // Read fish data\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        fishes.push_back({x, y, 0});\n    }\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        fishes.push_back({x, y, 1});\n    }\n    \n    // Find mackerel clusters\n    auto clusters = findMackerelClusters();\n    \n    if (clusters.empty()) {\n        // Fallback: create large rectangle\n        polygon = createRectangle(0, 0, 100000, 100000);\n    } else {\n        // Start with the best cluster\n        polygon = createClusterPolygon(clusters[0].first, clusters[0].second, 20000);\n        polygon = optimizeClusterPolygon(polygon);\n        \n        // Try to improve by adding more clusters\n        for (int i = 1; i < min(5, (int)clusters.size()); i++) {\n            auto extra = createClusterPolygon(clusters[i].first, clusters[i].second, 15000);\n            auto [m1, s1] = countFishInPolygon(polygon);\n            auto [m2, s2] = countFishInPolygon(extra);\n            \n            // Simple union approach - take bounding box\n            int minx = min(polygon[0].x, extra[0].x);\n            int miny = min(polygon[0].y, extra[0].y);\n            int maxx = max(polygon[2].x, extra[2].x);\n            int maxy = max(polygon[2].y, extra[2].y);\n            \n            auto combined = createRectangle(minx, miny, maxx, maxy);\n            if (calculatePerimeter(combined) <= 400000) {\n                auto [mc, sc] = countFishInPolygon(combined);\n                if (max(0, mc - sc + 1) > max(0, m1 - s1 + 1)) {\n                    polygon = combined;\n                }\n            }\n        }\n    }\n    \n    // Final optimization - try to remove sardine-heavy regions\n    auto [finalM, finalS] = countFishInPolygon(polygon);\n    int finalScore = max(0, finalM - finalS + 1);\n    \n    // Ensure valid output\n    if (polygon.size() < 4) {\n        polygon = createRectangle(0, 0, 100000, 100000);\n    }\n    \n    // Remove consecutive duplicates\n    vector<Point> cleaned;\n    for (int i = 0; i < polygon.size(); i++) {\n        int next = (i + 1) % polygon.size();\n        if (!(polygon[i] == polygon[next])) {\n            cleaned.push_back(polygon[i]);\n        }\n    }\n    polygon = cleaned;\n    \n    if (polygon.size() < 4) {\n        polygon = createRectangle(0, 0, 100000, 100000);\n    }\n    \n    cout << polygon.size() << \"\\n\";\n    for (const auto& p : polygon) {\n        cout << p.x << \" \" << p.y << \"\\n\";\n    }\n    \n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\n#include <random>\n#include <chrono>\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint randint(int a, int b) {\n    return uniform_int_distribution<int>(a, b)(rng);\n}\n\nstruct Rect {\n    long long w, h;\n    int idx;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T, sigma;\n    cin >> N >> T >> sigma;\n    vector<Rect> rects(N);\n    for (int i = 0; i < N; i++) {\n        cin >> rects[i].w >> rects[i].h;\n        rects[i].idx = i;\n    }\n\n    for (int turn = 0; turn < T; turn++) {\n        const int n = N;\n        vector<long long> xleft(n), ytop(n), width(n), height(n);\n\n        long long curW = 0, curH = 0;\n        vector<tuple<int, int, char, int>> seq;\n\n        for (int i = 0; i < n; i++) {\n            long long w0 = rects[i].w;\n            long long h0 = rects[i].h;\n\n            int best_r = 0;\n            char best_d = 'U';\n            int best_b = -1;\n            long long best_WH = LLONG_MAX;\n\n            int tries = 10;\n            for (int t = 0; t < tries; t++) {\n                int r = randint(0, 1);\n                long long wi = (r ? h0 : w0);\n                long long hi = (r ? w0 : h0);\n\n                char d = (randint(0,1) ? 'U' : 'L');\n                int b = (i==0 ? -1 : randint(-1, i-1));\n\n                long long xi, yi;\n                if (d == 'U') {\n                    xi = (b==-1? 0 : xleft[b] + width[b]);\n                    yi = 0;\n                    for (int j = 0; j < i; j++) {\n                        long long x1 = xi, x2 = xi + wi;\n                        long long ox1 = xleft[j], ox2 = xleft[j] + width[j];\n                        if (x2 > ox1 && x1 < ox2) yi = max(yi, ytop[j] + height[j]);\n                    }\n                } else {\n                    yi = (b==-1? 0 : ytop[b] + height[b]);\n                    xi = 0;\n                    for (int j = 0; j < i; j++) {\n                        long long y1 = yi, y2 = yi + hi;\n                        long long oy1 = ytop[j], oy2 = ytop[j] + height[j];\n                        if (y2 > oy1 && y1 < oy2) xi = max(xi, xleft[j] + width[j]);\n                    }\n                }\n                long long newW = max(curW, xi + wi);\n                long long newH = max(curH, yi + hi);\n                long long WH = newW + newH;\n                if (WH < best_WH) {\n                    best_WH = WH;\n                    best_r = r;\n                    best_d = d;\n                    best_b = b;\n                }\n            }\n\n            long long wi = (best_r ? h0 : w0);\n            long long hi = (best_r ? w0 : h0);\n            long long xi, yi;\n            if (best_d == 'U') {\n                xi = (best_b==-1? 0 : xleft[best_b] + width[best_b]);\n                yi = 0;\n                for (int j = 0; j < i; j++) {\n                    long long x1 = xi, x2 = xi + wi;\n                    long long ox1 = xleft[j], ox2 = xleft[j] + width[j];\n                    if (x2 > ox1 && x1 < ox2) yi = max(yi, ytop[j] + height[j]);\n                }\n            } else {\n                yi = (best_b==-1? 0 : ytop[best_b] + height[best_b]);\n                xi = 0;\n                for (int j = 0; j < i; j++) {\n                    long long y1 = yi, y2 = yi + hi;\n                    long long oy1 = ytop[j], oy2 = ytop[j] + height[j];\n                    if (y2 > oy1 && y1 < oy2) xi = max(xi, xleft[j] + width[j]);\n                }\n            }\n            xleft[i] = xi;\n            ytop[i] = yi;\n            width[i] = wi;\n            height[i] = hi;\n            curW = max(curW, xi + wi);\n            curH = max(curH, yi + hi);\n            seq.emplace_back(i, best_r, best_d, best_b);\n        }\n\n        cout << n << '\\n';\n        for (auto [p,r,d,b] : seq) cout << p << ' ' << r << ' ' << d << ' ' << b << '\\n';\n        cout.flush();\n\n        long long Wp, Hp;\n        cin >> Wp >> Hp;\n    }\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\n#include <atcoder/dsu>\nusing namespace std;\nusing namespace atcoder;\n\nstatic const int MAXN = 1005;\nstatic const int MAXH = 12;\n\nint N, M, H;\nint A[MAXN];\nvector<int> G[MAXN];\nint par[MAXN];          // parent array, -1 for root\nint depth[MAXN];        // depth[v] = number of edges from root\nint64_t contrib[MAXN];  // (depth[v]+1)*A[v]\nint64_t total_score;\n\n// DSU that mirrors the *undirected* forest edges\ndsu uf;\n\n// ---------- utility ----------\ninline void update_contrib(int v) {\n    contrib[v] = int64_t(depth[v] + 1) * A[v];\n}\n\n// ---------- initial greedy ----------\nvoid greedy_build() {\n    vector<char> used(N, 0);\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    shuffle(order.begin(), order.end(), rng);\n    sort(order.begin(), order.end(), [&](int u, int v) {\n        return A[u] > A[v];\n    });\n\n    uf = dsu(N);\n    total_score = 0;\n    for (int v = 0; v < N; ++v) par[v] = -2;\n\n    for (int u : order) if (par[u] == -2) {\n        queue<int> q;\n        par[u] = -1;\n        depth[u] = 0;\n        update_contrib(u);\n        q.push(u);\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            if (depth[v] == H) continue;\n            for (int w : G[v]) if (par[w] == -2) {\n                // safe because w is unused\n                par[w] = v;\n                depth[w] = depth[v] + 1;\n                update_contrib(w);\n                uf.merge(v, w);\n                q.push(w);\n            }\n        }\n    }\n    total_score = 0;\n    for (int v = 0; v < N; ++v) total_score += contrib[v];\n}\n\n// ---------- local improvement ----------\nvoid local_search(int iterations) {\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    vector<int> verts(N);\n    iota(verts.begin(), verts.end(), 0);\n\n    for (int it = 0; it < iterations; ++it) {\n        shuffle(verts.begin(), verts.end(), rng);\n        bool improved = false;\n\n        for (int v : verts) {\n            int old_p = par[v];\n            int old_d = depth[v];\n            int64_t old_delta = -contrib[v];\n\n            // try making v a new root\n            int best_new_p = -1;\n            int best_new_d = 0;\n            int64_t best_delta = 0;\n\n            int64_t delta_root = int64_t(1) * A[v] + old_delta;\n            if (delta_root > 0) {\n                best_new_p = -1;\n                best_new_d = 0;\n                best_delta = delta_root;\n            }\n\n            // try all neighbors as new parent\n            for (int w : G[v]) {\n                if (w == old_p) continue;\n                int nd = depth[w] + 1;\n                if (nd > H) continue;\n                // cycle check\n                if (uf.same(v, w)) continue;\n                int64_t delta = int64_t(nd + 1) * A[v] - contrib[v];\n                if (delta > best_delta) {\n                    best_delta = delta;\n                    best_new_p = w;\n                    best_new_d = nd;\n                }\n            }\n\n            if (best_delta > 0) {\n                // apply move\n                if (old_p != -1) {\n                    // remove old edge (old_p,v)\n                    // dsu does not support edge deletion; rebuild edge set\n                    // instead we rebuild uf from scratch each move (N is small)\n                    // rebuild uf after every successful move\n                }\n                par[v] = best_new_p;\n                depth[v] = best_new_d;\n                update_contrib(v);\n                total_score += best_delta;\n                improved = true;\n                // rebuild uf to reflect new edge\n                uf = dsu(N);\n                for (int u = 0; u < N; ++u) if (par[u] != -1)\n                    uf.merge(u, par[u]);\n            }\n        }\n        if (!improved) break;\n    }\n}\n\n// ---------- output ----------\nvoid output_answer() {\n    for (int i = 0; i < N; ++i) {\n        cout << par[i] << (i + 1 < N ? ' ' : '\\n');\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> H;\n    for (int i = 0; i < N; ++i) cin >> A[i];\n    for (int i = 0; i < M; ++i) {\n        int u, v; cin >> u >> v;\n        G[u].push_back(v);\n        G[v].push_back(u);\n    }\n    // discard coordinates\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n    }\n\n    int64_t best_score = -1;\n    vector<int> best_par(N);\n\n    auto save_best = [&]() {\n        if (total_score > best_score) {\n            best_score = total_score;\n            copy(par, par + N, best_par.begin());\n        }\n    };\n\n    const int tries = 25;\n    const int loc_its = 80;\n    for (int t = 0; t < tries; ++t) {\n        greedy_build();\n        local_search(loc_its);\n        save_best();\n    }\n\n    copy(best_par.begin(), best_par.end(), par);\n    output_answer();\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const int FIXED_N = 20;\nstatic const int NONE = -1;          // <\u2014 added\nchar board[FIXED_N][FIXED_N + 1];\nint  N;\n\n// ---------- direction constants ----------\nstatic const int L = 0, R = 1, U = 2, D = 3;\nstatic const int BACK[4] = {1, 0, 3, 2};\nstatic const char DIRC[4] = {'L','R','U','D'};\n\n// ---------- data ----------\nint oni_r[40], oni_c[40], oni_cnt;\nint fuku_r[40], fuku_c[40], fuku_cnt;\nint safe_dir[40];\nint cnt[4][FIXED_N];\nint total_moves;\n\n// ---------- fast SA ----------\nmt19937 rng(123456);\n\ninline int non_zero() {\n    int nz = 0;\n    for (int d = 0; d < 4; ++d)\n        for (int p = 0; p < FIXED_N; ++p)\n            if (cnt[d][p]) ++nz;\n    return nz;\n}\n\nvoid build_sequence(vector<pair<char,int>>& out) {\n    out.clear();\n    static char cur[FIXED_N][FIXED_N + 1];\n    for (int i = 0; i < FIXED_N; ++i) fill(cur[i], cur[i] + FIXED_N, '.');\n    for (int k = 0; k < fuku_cnt; ++k) cur[fuku_r[k]][fuku_c[k]] = 'o';\n    for (int k = 0; k < oni_cnt; ++k)  cur[oni_r[k]][oni_c[k]]  = 'x';\n\n    auto apply = [&](int d, int p) {\n        out.emplace_back(DIRC[d], p);\n        if (d == L) {\n            for (int j = 0; j + 1 < FIXED_N; ++j) cur[p][j] = cur[p][j + 1];\n            cur[p][FIXED_N - 1] = '.';\n        } else if (d == R) {\n            for (int j = FIXED_N - 1; j > 0; --j) cur[p][j] = cur[p][j - 1];\n            cur[p][0] = '.';\n        } else if (d == U) {\n            for (int i = 0; i + 1 < FIXED_N; ++i) cur[i][p] = cur[i + 1][p];\n            cur[FIXED_N - 1][p] = '.';\n        } else { // D\n            for (int i = FIXED_N - 1; i > 0; --i) cur[i][p] = cur[i - 1][p];\n            cur[0][p] = '.';\n        }\n    };\n\n    while (true) {\n        int best = 0, bd = NONE, bp = NONE;\n        for (int d = 0; d < 4; ++d)\n            for (int p = 0; p < FIXED_N; ++p)\n                if (cnt[d][p] > best) { best = cnt[d][p]; bd = d; bp = p; }\n        if (best == 0) break;\n        int len = (bd < 2 ? FIXED_N : FIXED_N);\n        for (int t = 0; t < len; ++t) apply(bd, bp);\n        for (int t = 0; t < len; ++t) apply(BACK[bd], bp);\n        cnt[bd][bp] = 0;\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    assert(N == FIXED_N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n\n    oni_cnt = fuku_cnt = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 'x') {\n                oni_r[oni_cnt] = i;\n                oni_c[oni_cnt] = j;\n                ++oni_cnt;\n            } else if (board[i][j] == 'o') {\n                fuku_r[fuku_cnt] = i;\n                fuku_c[fuku_cnt] = j;\n                ++fuku_cnt;\n            }\n        }\n\n    for (int k = 0; k < oni_cnt; ++k) {\n        int i = oni_r[k], j = oni_c[k];\n        bool safe[4] = {true,true,true,true};\n        for (int t = j - 1; t >= 0; --t) if (board[i][t] == 'o') safe[L] = false;\n        for (int t = j + 1; t < N; ++t) if (board[i][t] == 'o') safe[R] = false;\n        for (int t = i - 1; t >= 0; --t) if (board[t][j] == 'o') safe[U] = false;\n        for (int t = i + 1; t < N; ++t) if (board[t][j] == 'o') safe[D] = false;\n        int pick = 0; while (pick < 4 && !safe[pick]) ++pick;\n        safe_dir[k] = pick;\n    }\n\n    memset(cnt, 0, sizeof(cnt));\n    for (int k = 0; k < oni_cnt; ++k) {\n        int d = safe_dir[k];\n        int rc = (d < 2 ? oni_r[k] : oni_c[k]);\n        ++cnt[d][rc];\n    }\n    total_moves = 2 * non_zero();\n\n    uniform_int_distribution<int> uid_k(0, oni_cnt - 1);\n    uniform_int_distribution<int> uid_d(0, 3);\n\n    const int ITER = 200000;\n    for (int it = 0; it < ITER; ++it) {\n        int k  = uid_k(rng);\n        int i  = oni_r[k], j = oni_c[k];\n        int old_d = safe_dir[k];\n        int new_d = uid_d(rng);\n        if (new_d == old_d) continue;\n\n        bool ok = true;\n        if (new_d == L){ for(int t=j-1;t>=0;--t)if(board[i][t]=='o')ok=false; }\n        else if(new_d==R){ for(int t=j+1;t<N;++t)if(board[i][t]=='o')ok=false; }\n        else if(new_d==U){ for(int t=i-1;t>=0;--t)if(board[t][j]=='o')ok=false; }\n        else { for(int t=i+1;t<N;++t)if(board[t][j]=='o')ok=false; }\n        if (!ok) continue;\n\n        int rc_old = (old_d < 2 ? i : j);\n        int rc_new = (new_d < 2 ? i : j);\n\n        int delta = 0;\n        if (cnt[old_d][rc_old] == 1) delta -= 2;\n        --cnt[old_d][rc_old];\n        if (cnt[old_d][rc_old] == 0) delta += 2;\n\n        if (cnt[new_d][rc_new] == 0) delta -= 2;\n        ++cnt[new_d][rc_new];\n        if (cnt[new_d][rc_new] == 1) delta += 2;\n\n        int new_total = total_moves + delta;\n        if (new_total <= total_moves) {\n            total_moves = new_total;\n            safe_dir[k] = new_d;\n        } else {\n            --cnt[new_d][rc_new];\n            ++cnt[old_d][rc_old];\n        }\n    }\n\n    vector<pair<char,int>> out;\n    build_sequence(out);\n    for (auto [d, p] : out) cout << d << ' ' << p << '\\n';\n    return 0;\n}","ahc044":"#include <iostream>\n#include <vector>\n#include <random>\n#include <algorithm>\n#include <chrono>\n\nusing namespace std;\n\nconst int N = 100;\nconst int L = 500000;\n\nint T[N];\nint a[N], b[N];\nint t[N];\nint current_sequence[L];\n\nint simulate() {\n    fill(t, t + N, 0);\n    int current = 0;\n    t[current] = 1;\n    for (int week = 1; week < L; ++week) {\n        int count = t[current];\n        int next;\n        if (count % 2 == 1) {\n            next = a[current];\n        } else {\n            next = b[current];\n        }\n        t[next]++;\n        current = next;\n    }\n    int error = 0;\n    for (int i = 0; i < N; ++i) {\n        error += abs(t[i] - T[i]);\n    }\n    return error;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    for (int i = 0; i < N; ++i) {\n        cin >> T[i];\n    }\n\n    // Initial greedy assignment\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    for (int i = 0; i < N; ++i) {\n        a[i] = uniform_int_distribution<int>(0, N - 1)(rng);\n        b[i] = uniform_int_distribution<int>(0, N - 1)(rng);\n    }\n\n    int best_error = simulate();\n    auto start = chrono::steady_clock::now();\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start).count() > 1800) {\n            break; // Stop after 1.8 seconds to ensure we don't exceed 2 seconds\n        }\n\n        int i = uniform_int_distribution<int>(0, N - 1)(rng);\n        int old_a = a[i], old_b = b[i];\n\n        // Try changing a[i] or b[i]\n        if (uniform_int_distribution<int>(0, 1)(rng) == 0) {\n            a[i] = uniform_int_distribution<int>(0, N - 1)(rng);\n        } else {\n            b[i] = uniform_int_distribution<int>(0, N - 1)(rng);\n        }\n\n        int new_error = simulate();\n        if (new_error < best_error) {\n            best_error = new_error;\n        } else {\n            // Revert\n            a[i] = old_a;\n            b[i] = old_b;\n        }\n    }\n\n    // Output the best found\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 City {\n    int id, lx, rx, ly, ry;\n    int cx() const { return (lx + rx) / 2; }\n    int cy() const { return (ly + ry) / 2; }\n};\n\nint N, M, Q, L, W;\nvector<int> G;\nvector<City> cities;\nvector<vector<int>> groups;\nvector<vector<pair<int, int>>> group_edges;\n\nvector<pair<int, int>> query(const vector<int>& c) {\n    cout << \"? \" << c.size();\n    for (int x : c) cout << \" \" << x;\n    cout << endl;\n    vector<pair<int, int>> edges;\n    for (int i = 0; i < c.size() - 1; ++i) {\n        int a, b;\n        cin >> a >> b;\n        edges.emplace_back(a, b);\n    }\n    return edges;\n}\n\nvoid answer() {\n    cout << \"!\" << endl;\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < groups[i].size(); ++j) {\n            if (j > 0) cout << \" \";\n            cout << groups[i][j];\n        }\n        cout << endl;\n        for (auto [a, b] : group_edges[i]) {\n            cout << a << \" \" << b << endl;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    cities.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> cities[i].lx >> cities[i].rx >> cities[i].ly >> cities[i].ry;\n        cities[i].id = i;\n    }\n\n    // Sort cities by center coordinates\n    sort(cities.begin(), cities.end(), [](const City& a, const City& b) {\n        if (a.cx() != b.cx()) return a.cx() < b.cx();\n        return a.cy() < b.cy();\n    });\n\n    // Assign to groups\n    groups.resize(M);\n    group_edges.resize(M);\n    int ptr = 0;\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < G[i]; ++j) {\n            groups[i].push_back(cities[ptr++].id);\n        }\n    }\n\n    // Use queries to get edges for each group\n    int queries_used = 0;\n    for (int i = 0; i < M; ++i) {\n        int sz = groups[i].size();\n        if (sz <= 1) continue;\n        // Use triplets to cover the group\n        for (int j = 0; j < sz - 1; j += 2) {\n            if (queries_used >= Q) break;\n            vector<int> c;\n            if (j + 2 < sz) {\n                c = {groups[i][j], groups[i][j+1], groups[i][j+2]};\n            } else {\n                c = {groups[i][j], groups[i][j+1]};\n            }\n            auto edges = query(c);\n            for (auto [a, b] : edges) {\n                group_edges[i].emplace_back(a, b);\n            }\n            queries_used++;\n        }\n        // Ensure connectivity by adding edges if necessary\n        // This is a simple heuristic: connect in order\n        if (group_edges[i].size() < sz - 1) {\n            for (int j = 0; j < sz - 1; ++j) {\n                group_edges[i].emplace_back(groups[i][j], groups[i][j+1]);\n            }\n        }\n    }\n\n    answer();\n    return 0;\n}","ahc046":"#pragma GCC optimize(\"O3,unroll-loops\")\n#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nstatic const int N = 20;\nstatic const int M = 40;\nstatic const int LIMIT = 2*N*M;\n\nint target[M];\nint targetLeft;                      // how many still to visit\nbool blocked[N][N];                  // current wall state\nint  distSlide[N][N][4];             // dist to next block/border in 4 dirs\nint  di[] = {-1,1,0,0};\nint  dj[] = {0,0,-1,1};\nchar actionChar[] = {'M','S','A'};\nchar dirChar[]    = {'U','D','L','R'};\n\nstruct Step {\n    int i,j;\n    int g;\n    vector<pair<int,int>> pathActs; // (act,dir) pairs leading here\n    bool operator<(const Step& o) const { return g > o.g; }\n};\n\ninline bool inside(int i,int j){ return i>=0&&i<N&&j>=0&&j<N; }\n\nvoid rebuildDistSlide(){\n    for(int i=0;i<N;i++){\n        // up\n        for(int j=0;j<N;j++){\n            int d=0;\n            for(int ii=i-1;ii>=0;ii--){\n                if(blocked[ii][j]) break;\n                d++;\n            }\n            distSlide[i][j][0]=d;\n        }\n        // down\n        for(int j=0;j<N;j++){\n            int d=0;\n            for(int ii=i+1;ii<N;ii++){\n                if(blocked[ii][j]) break;\n                d++;\n            }\n            distSlide[i][j][1]=d;\n        }\n    }\n    for(int j=0;j<N;j++){\n        // left\n        for(int i=0;i<N;i++){\n            int d=0;\n            for(int jj=j-1;jj>=0;jj--){\n                if(blocked[i][jj]) break;\n                d++;\n            }\n            distSlide[i][j][2]=d;\n        }\n        // right\n        for(int i=0;i<N;i++){\n            int d=0;\n            for(int jj=j+1;jj<N;jj++){\n                if(blocked[i][jj]) break;\n                d++;\n            }\n            distSlide[i][j][3]=d;\n        }\n    }\n}\n\nint heuristic(int si,int sj,int ti,int tj){\n    return abs(si-ti)+abs(sj-tj);\n}\n\nvector<pair<int,int>> planSegment(int si,int sj,int ti,int tj){\n    priority_queue<Step> pq;\n    Step start{si,sj,0,{}};\n    pq.push(start);\n    static char vis[ N ][ N ];\n    memset(vis,0,sizeof(vis));\n    vis[si][sj]=1;\n    const int EXPAND = 20000;\n    int expanded = 0;\n    while(!pq.empty() && expanded < EXPAND){\n        Step cur = pq.top(); pq.pop();\n        expanded++;\n        if(cur.i==ti && cur.j==tj){\n            return cur.pathActs;\n        }\n        int g2 = cur.g+1;\n        for(int dir=0;dir<4;dir++){\n            int ni = cur.i + di[dir];\n            int nj = cur.j + dj[dir];\n            // 1) Move\n            if(inside(ni,nj) && !blocked[ni][nj] && !vis[ni][nj]){\n                vis[ni][nj]=1;\n                Step nxt = cur;\n                nxt.i=ni; nxt.j=nj; nxt.g=g2;\n                nxt.pathActs.emplace_back(0,dir);\n                pq.push(nxt);\n            }\n            // 2) Slide\n            int ds = distSlide[cur.i][cur.j][dir];\n            if(ds>0){\n                int ei = cur.i + di[dir]*ds;\n                int ej = cur.j + dj[dir]*ds;\n                if(!vis[ei][ej]){\n                    vis[ei][ej]=1;\n                    Step nxt = cur;\n                    nxt.i=ei; nxt.j=ej; nxt.g=g2;\n                    nxt.pathActs.emplace_back(1,dir);\n                    pq.push(nxt);\n                }\n            }\n            // 3) Alter\n            int bi = cur.i + di[dir];\n            int bj = cur.j + dj[dir];\n            if(inside(bi,bj)){\n                // toggle\n                blocked[bi][bj] ^= 1;\n                rebuildDistSlide();\n                Step nxt = cur;\n                nxt.g=g2;\n                nxt.pathActs.emplace_back(2,dir);\n                pq.push(nxt);\n                // undo\n                blocked[bi][bj] ^= 1;\n                rebuildDistSlide();\n            }\n        }\n    }\n    // fallback: plain Manhattan moves\n    vector<pair<int,int>> fallback;\n    int dx = ti - si;\n    int dy = tj - sj;\n    int px = si, py = sj;\n    while(px<ti){ px++; fallback.emplace_back(0,1); }\n    while(px>ti){ px--; fallback.emplace_back(0,0); }\n    while(py<tj){ py++; fallback.emplace_back(0,3); }\n    while(py>tj){ py--; fallback.emplace_back(0,2); }\n    return fallback;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int n,m;\n    cin >> n >> m;\n    assert(n==N && m==M);\n    int si,sj;\n    cin >> si >> sj;\n    vector<int> I(M),J(M);\n    for(int k=0;k<M;k++){\n        cin >> I[k] >> J[k];\n    }\n    // initialise\n    memset(blocked,0,sizeof(blocked));\n    rebuildDistSlide();\n    vector<pair<int,int>> fullPlan;\n    int ci=si, cj=sj;\n    for(int idx=0;idx<M;idx++){\n        int ti = I[idx];\n        int tj = J[idx];\n        auto seg = planSegment(ci,cj,ti,tj);\n        fullPlan.insert(fullPlan.end(), seg.begin(), seg.end());\n        // execute to update real state\n        for(auto [act,dir]: seg){\n            if(act==0){ // Move\n                ci += di[dir];\n                cj += dj[dir];\n            } else if(act==1){ // Slide\n                int ds = distSlide[ci][cj][dir];\n                ci += di[dir]*ds;\n                cj += dj[dir]*ds;\n            } else { // Alter\n                int bi = ci + di[dir];\n                int bj = cj + dj[dir];\n                blocked[bi][bj] ^= 1;\n                rebuildDistSlide();\n            }\n        }\n        assert(ci==ti && cj==tj);\n    }\n    // output\n    cout << fullPlan.size() << \"\\n\";\n    for(auto [act,dir]: fullPlan){\n        cout << actionChar[act] << \" \" << dirChar[dir] << \"\\n\";\n    }\n    return 0;\n}"},"8":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nusing uint = unsigned int;\nusing ull = unsigned long long;\n\n/* ---------- basic geometry ---------- */\nstruct Rect {\n    int a, b, c, d;\n    ll area() const { return (ll)(c - a) * (d - b); }\n    bool contains(double x, double y) const {\n        return a <= x && x <= c && b <= y && y <= d;\n    }\n    // intersection area (0 if disjoint)\n    ll intersect(const Rect &o) const {\n        int A = max(a, o.a), B = max(b, o.b);\n        int C = min(c, o.c), D = min(d, o.d);\n        if (A >= C || B >= D) return 0;\n        return (ll)(C - A) * (D - B);\n    }\n};\nstruct Company {\n    int x, y, r;\n    double cx, cy;   // desired centre\n    Rect  R;\n    double priority() const {      // how far from desired area\n        ll s = R.area();\n        double rat = min((double)s, (double)r) / max((double)s, (double)r);\n        return 1.0 - rat;          // larger \u2192 more urgent\n    }\n};\n\n/* ---------- global ---------- */\nint n;\nvector<Company> co;\nchrono::steady_clock::time_point start;\ndouble time_elapsed() {\n    return chrono::duration<double>(chrono::steady_clock::now() - start).count();\n}\nconst double TIME_LIMIT = 4.8;\n\n/* ---------- overlap utilities ---------- */\nbool overlap(int i, int j) {\n    const Rect &p = co[i].R, &q = co[j].R;\n    return !(p.c <= q.a || q.c <= p.a || p.d <= q.b || q.d <= p.b);\n}\nll total_overlap() {   // total pairwise overlap area\n    ll bad = 0;\n    for (int i = 0; i < n; ++i)\n        for (int j = i + 1; j < n; ++j)\n            bad += co[i].R.intersect(co[j].R);\n    return bad;\n}\n\n/* ---------- priority overlap removal ---------- */\nvoid remove_overlaps_pq() {\n    priority_queue<pair<double, int>> pq; // priority -> index\n    auto push = [&](int i) { pq.emplace(co[i].priority(), i); };\n    for (int i = 0; i < n; ++i) push(i);\n\n    bool progress;\n    do {\n        progress = false;\n        while (!pq.empty()) {\n            int i = pq.top().second; pq.pop();\n            for (int j = 0; j < n; ++j) {\n                if (i == j) continue;\n                if (!overlap(i, j)) continue;\n                progress = true;\n                Rect &u = co[i].R, &v = co[j].R;\n                // shrink the one whose area is further above its r\n                bool shrink_u = (u.area() > co[i].r) ||\n                                (v.area() <= co[j].r && u.area() > v.area());\n                Rect *t = shrink_u ? &u : &v;\n                int dx = t->c - t->a, dy = t->d - t->b;\n                if (dx > dy) {\n                    if (t->c - 1 > t->a) t->c--;\n                    else if (t->a + 1 < t->c) t->a++;\n                    else if (t->d - 1 > t->b) t->d--;\n                    else t->b++;\n                } else {\n                    if (t->d - 1 > t->b) t->d--;\n                    else if (t->b + 1 < t->d) t->b++;\n                    else if (t->c - 1 > t->a) t->c--;\n                    else t->a++;\n                }\n                push(i);\n                push(j);\n                goto next_loop;\n            }\n        }\n        next_loop:;\n    } while (progress && time_elapsed() < TIME_LIMIT);\n}\n\n/* ---------- maximal empty rectangle (MER) ---------- */\nvector<Rect> find_MERs() {\n    // event-based maximal empty rectangles in orthogonal plane\n    // we implement a simplified 1-D maximal gap finder twice (x, y)\n    // and return up to 4*n largest empty rectangles.\n    vector<Rect> merch;\n    { // sweep along x\n        vector<int> xs = {0, 10000};\n        for (int i = 0; i < n; ++i) {\n            xs.push_back(co[i].R.a);\n            xs.push_back(co[i].R.c);\n        }\n        sort(xs.begin(), xs.end());\n        xs.erase(unique(xs.begin(), xs.end()), xs.end());\n        for (size_t i = 0; i + 1 < xs.size(); ++i) {\n            int x1 = xs[i], x2 = xs[i + 1];\n            vector<pair<int, int>> segs;\n            for (int j = 0; j < n; ++j) {\n                if (co[j].R.a <= x1 && x2 <= co[j].R.c) {\n                    segs.emplace_back(co[j].R.b, co[j].R.d);\n                }\n            }\n            sort(segs.begin(), segs.end());\n            int last = 0;\n            for (auto &s : segs) {\n                if (s.first > last) merch.push_back({x1, last, x2, s.first});\n                last = max(last, s.second);\n            }\n            if (last < 10000) merch.push_back({x1, last, x2, 10000});\n        }\n    }\n    // sort by decreasing area\n    sort(merch.begin(), merch.end(),\n         [](const Rect &A, const Rect &B) { return A.area() > B.area(); });\n    if (merch.size() > 4 * n) merch.resize(4 * n);\n    return merch;\n}\n\n/* ---------- try to assign exact r_i into biggest MER containing centre ---------- */\nvoid expand_to_MER() {\n    auto mer = find_MERs();\n    vector<int> ord(n);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(),\n         [&](int i, int j) { return co[i].priority() > co[j].priority(); });\n\n    for (int idx : ord) {\n        Company &C = co[idx];\n        for (const Rect &E : mer) {\n            if (!E.contains(C.cx, C.cy)) continue;\n            ll avail = E.area();\n            if (avail < C.r) continue;\n            // try to build a rectangle inside E, area = C.r, containing centre\n            int want = C.r;\n            int w = E.c - E.a, h = E.d - E.b;\n            // choose integer dimensions (dx,dy) with dx*dy = want, dx<=w, dy<=h\n            int dx = (int)sqrt(want), dy;\n            while (dx > 0) {\n                if (want % dx == 0) {\n                    dy = want / dx;\n                    if (dx <= w && dy <= h) break;\n                }\n                dx--;\n            }\n            if (dx == 0) continue; // cannot fit\n            // centre must be inside new rectangle\n            int nx1 = max(E.a, (int)floor(C.cx - dx / 2.0));\n            int nx2 = nx1 + dx;\n            if (nx2 > E.c) { nx2 = E.c; nx1 = nx2 - dx; }\n            int ny1 = max(E.b, (int)floor(C.cy - dy / 2.0));\n            int ny2 = ny1 + dy;\n            if (ny2 > E.d) { ny2 = E.d; ny1 = ny2 - dy; }\n            Rect cand{nx1, ny1, nx2, ny2};\n            if (!cand.contains(C.cx, C.cy)) continue;\n            // check overlap with others\n            bool ok = true;\n            for (int i = 0; i < n && ok; ++i)\n                if (i != idx && cand.intersect(co[i].R)) ok = false;\n            if (!ok) continue;\n            C.R = cand;\n            break;\n        }\n    }\n}\n\n/* ---------- simulated annealing outer loop ---------- */\ndouble raw_score() {\n    double sum = 0;\n    for (int i = 0; i < n; ++i) {\n        ll s = co[i].R.area();\n        ll r = co[i].r;\n        if (s == r) sum += 1.0;\n        else {\n            double rat = min((double)s, (double)r) / max((double)s, (double)r);\n            sum += 1.0 - (1.0 - rat) * (1.0 - rat);\n        }\n    }\n    return sum;\n}\nvoid anneal() {\n    double T0 = 1e-3, T, cooling = 0.995;\n    double best = raw_score() - 1e6 * total_overlap();\n    double cur = best;\n    mt19937 rng(42);\n    uniform_real_distribution<double> uni(0, 1);\n\n    while (time_elapsed() < TIME_LIMIT) {\n        T = T0;\n        for (int step = 0; step < 300 && time_elapsed() < TIME_LIMIT; ++step, T *= cooling) {\n            // neighbour: random small move\n            int i = uniform_int_distribution<int>(0, n - 1)(rng);\n            Rect old = co[i].R;\n            Rect neo = old;\n            int d = uniform_int_distribution<int>(-2, 2)(rng);\n            int mode = uniform_int_distribution<int>(0, 3)(rng);\n            if (mode == 0) neo.a += d;\n            if (mode == 1) neo.b += d;\n            if (mode == 2) neo.c += d;\n            if (mode == 3) neo.d += d;\n            if (neo.a >= neo.c || neo.b >= neo.d) continue;\n            if (neo.a < 0 || neo.b < 0 || neo.c > 10000 || neo.d > 10000) continue;\n            if (!neo.contains(co[i].cx, co[i].cy)) continue;\n\n            co[i].R = neo;\n            double nxt = raw_score() - 1e6 * total_overlap();\n            double delta = nxt - cur;\n            if (delta > 0 || uni(rng) < exp(delta / T)) {\n                cur = nxt;\n                if (cur > best) best = cur;\n            } else {\n                co[i].R = old;\n            }\n        }\n    }\n}\n\n/* ---------- driver ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    start = chrono::steady_clock::now();\n\n    cin >> n;\n    co.resize(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> co[i].x >> co[i].y >> co[i].r;\n        co[i].cx = co[i].x + 0.5;\n        co[i].cy = co[i].y + 0.5;\n        co[i].R = {co[i].x, co[i].y, co[i].x + 1, co[i].y + 1};\n    }\n\n    remove_overlaps_pq();\n    expand_to_MER();\n    remove_overlaps_pq();\n    anneal();\n\n    for (int i = 0; i < n; ++i)\n        cout << co[i].R.a << ' ' << co[i].R.b << ' '\n             << co[i].R.c << ' ' << co[i].R.d << '\\n';\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nint si, sj;\nint t[50][50];\nint p[50][50];\nint M;\nint bestScore;\nstring bestPath;\n\nconst int dx[4] = {-1,1,0,0};\nconst int dy[4] = {0,0,-1,1};\nconst char dc[4] = {'U','D','L','R'};\n\nchrono::steady_clock::time_point start;\n\ninline bool timeout(double lim = 1.80) {\n    return chrono::duration<double>(chrono::steady_clock::now() - start).count() > lim;\n}\n\ninline vector<int> orderNeigh(int i, int j) {\n    array<pair<int,int>,4> tmp;\n    for(int d=0;d<4;d++){\n        int ni=i+dx[d], nj=j+dy[d];\n        int val = (ni<0||ni>=50||nj<0||nj>=50) ? -1 : p[ni][nj];\n        tmp[d] = {val, d};\n    }\n    sort(tmp.begin(), tmp.end(), greater<pair<int,int>>());\n    vector<int> ord(4);\n    for(int k=0;k<4;k++) ord[k] = tmp[k].second;\n    return ord;\n}\n\nvoid dfs(int i, int j, bitset<2500> used, int score, string path, int depth, int limit) {\n    if (timeout()) return;\n    if (score > bestScore) {\n        bestScore = score;\n        bestPath  = path;\n    }\n    if (depth == limit) return;\n    auto ord = orderNeigh(i, j);\n    for (int d : ord) {\n        int ni = i + dx[d], nj = j + dy[d];\n        if (ni<0||ni>=50||nj<0||nj>=50) continue;\n        int nt = t[ni][nj];\n        if (used[nt]) continue;\n        used[nt] = 1;\n        path.push_back(dc[d]);\n        dfs(ni, nj, used, score + p[ni][nj], path, depth + 1, limit);\n        path.pop_back();\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    start = chrono::steady_clock::now();\n\n    cin >> si >> sj;\n    for(int i=0;i<50;i++)for(int j=0;j<50;j++) cin >> t[i][j];\n    for(int i=0;i<50;i++)for(int j=0;j<50;j++) cin >> p[i][j];\n\n    int maxt = 0;\n    for(int i=0;i<50;i++)for(int j=0;j<50;j++) maxt = max(maxt, t[i][j]);\n    M = maxt + 1;\n\n    bestScore = p[si][sj];   // starting square score\n    bestPath  = \"\";          // empty path = stay once\n\n    for (int limit = 0; limit <= 2000; limit += 50) {  // limit 0 allows snapshotting the start\n        if (timeout()) break;\n        bitset<2500> used;\n        used[t[si][sj]] = 1;          // mark **inside** the first layer\n        dfs(si, sj, used, bestScore, string(), 0, limit);\n        if (timeout()) break;\n    }\n    cout << bestPath << endl;\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int Q = 1000;\n\nstruct Edge {\n    double len = 5000.0, sumObs = 0.0;\n    int cnt = 0;\n    Edge() = default;\n};\n\nint dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1};\n\nvector<vector<Edge>> hEdge(N, vector<Edge>(N - 1));\nvector<vector<Edge>> vEdge(N - 1, vector<Edge>(N));\n\n/* ---------- basic helpers ---------- */\nstring manhattan(int sr, int sc, int tr, int tc) {\n    string s;\n    int d = tr - sr, c = tc - sc;\n    if (d > 0) s.append(d, 'D'); else s.append(-d, 'U');\n    if (c > 0) s.append(c, 'R'); else s.append(-c, 'L');\n    return s;\n}\n\nvector<pair<int, int>> vertices_on_path(int sr, int sc, const string &p) {\n    vector<pair<int, int>> v = {{sr, sc}};\n    int r = sr, c = sc;\n    for (char ch : p) {\n        if (ch == 'U') { --r; }\n        if (ch == 'D') { ++r; }\n        if (ch == 'L') { --c; }\n        if (ch == 'R') { ++c; }\n        v.emplace_back(r, c);\n    }\n    return v;\n}\n\ndouble path_length(const vector<pair<int, int>> &v) {\n    double len = 0;\n    for (size_t i = 0; i + 1 < v.size(); ++i) {\n        int r1 = v[i].first, c1 = v[i].second;\n        int r2 = v[i + 1].first, c2 = v[i + 1].second;\n        if (r1 == r2 && abs(c1 - c2) == 1) {\n            len += hEdge[r1][min(c1, c2)].len;\n        } else if (c1 == c2 && abs(r1 - r2) == 1) {\n            len += vEdge[min(r1, r2)][c1].len;\n        } else {\n            len += 1e18; // invalid edge\n        }\n    }\n    return len;\n}\n\nvoid update_edges(const vector<pair<int, int>> &v, int noisy) {\n    double obs = noisy;\n    for (size_t i = 0; i + 1 < v.size(); ++i) {\n        int r1 = v[i].first, c1 = v[i].second;\n        int r2 = v[i + 1].first, c2 = v[i + 1].second;\n        Edge *e = nullptr;\n        if (r1 == r2 && abs(c1 - c2) == 1) e = &hEdge[r1][min(c1, c2)];\n        if (c1 == c2 && abs(r1 - r2) == 1) e = &vEdge[min(r1, r2)][c1];\n        if (e) {\n            e->sumObs += obs;\n            e->cnt += 1;\n            e->len = e->sumObs / e->cnt;\n        }\n    }\n}\n\n/* ---------- Dijkstra with current estimates ---------- */\nstring dijkstra(int sr, int sc, int tr, int tc) {\n    using P = pair<double, pair<int, int>>;\n    using Cmp = greater<P>;                       // alias avoids >> trouble\n    priority_queue<P, vector<P>, Cmp> pq;         // single > only\n    vector<vector<double>> dist(N, vector<double>(N, 1e18));\n    vector<vector<pair<int, int>>> par(N, vector<pair<int, int>>(N, {-1, -1}));\n    dist[sr][sc] = 0;\n    pq.push({0, {sr, sc}});\n\n    while (!pq.empty()) {\n        auto top = pq.top();\n        pq.pop();\n        double d = top.first;\n        int r = top.second.first, c = top.second.second;\n        if (d > dist[r][c]) continue;\n        if (r == tr && c == tc) break;\n        for (int k = 0; k < 4; ++k) {\n            int nr = r + dr[k], nc = c + dc[k];\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n            double w = 0;\n            if (k == 0) w = vEdge[nr][nc].len;\n            if (k == 1) w = vEdge[r][c].len;\n            if (k == 2) w = hEdge[r][nc].len;\n            if (k == 3) w = hEdge[r][c].len;\n            if (dist[nr][nc] > d + w) {\n                dist[nr][nc] = d + w;\n                par[nr][nc] = {r, c};\n                pq.push({dist[nr][nc], {nr, nc}});\n            }\n        }\n    }\n\n    string path;\n    int r = tr, c = tc;\n    while (par[r][c].first != -1) {\n        int pr = par[r][c].first, pc = par[r][c].second;\n        if (pr == r - 1) path += 'D';\n        else if (pr == r + 1) path += 'U';\n        else if (pc == c - 1) path += 'R';\n        else if (pc == c + 1) path += 'L';\n        r = pr;\n        c = pc;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n/* ---------- main ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    for (int q = 0; q < Q; ++q) {\n        int sr, sc, tr, tc;\n        cin >> sr >> sc >> tr >> tc;\n        string path;\n        if (q < 100) path = manhattan(sr, sc, tr, tc);\n        else path = dijkstra(sr, sc, tr, tc);\n        cout << path << '\\n';\n        cout.flush();\n\n        int noisy;\n        cin >> noisy;\n        auto v = vertices_on_path(sr, sc, path);\n        update_edges(v, noisy);\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const int N = 20;\nstatic const int AL = 8;          // A..H\nstatic const char LET[] = \"ABCDEFGH\";\n\nint M;\nvector<string> S;\nint bestC;\nvector<string> bestGrid;\n\n// ---------- portable RNG ----------\nmt19937_64 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count() ^\n               (uint64_t)random_device{}());\n\ninline int randInt(int l, int r) {   // [l, r]\n    return uniform_int_distribution<int>(l, r)(rng);\n}\n\n// ---------- evaluation ----------\ninline int index(char c) { return c - 'A'; }\n\nint evaluate(const vector<string>& g) {\n    int cnt = 0;\n    for (const auto& s : S) {\n        int L = (int)s.size();\n        bool ok = false;\n        // horizontal\n        for (int i = 0; i < N && !ok; ++i) {\n            for (int st = 0; st < N; ++st) {\n                bool match = true;\n                for (int p = 0; p < L; ++p)\n                    if (g[i][(st + p) % N] != s[p]) { match = false; break; }\n                if (match) { ok = true; break; }\n            }\n        }\n        if (ok) { ++cnt; continue; }\n        // vertical\n        for (int j = 0; j < N && !ok; ++j) {\n            for (int st = 0; st < N; ++st) {\n                bool match = true;\n                for (int p = 0; p < L; ++p)\n                    if (g[(st + p) % N][j] != s[p]) { match = false; break; }\n                if (match) { ok = true; break; }\n            }\n        }\n        if (ok) ++cnt;\n    }\n    return cnt;\n}\n\nint fillCount(const vector<string>& g) {\n    int c = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (g[i][j] != '.') ++c;\n    return c;\n}\n\nvoid printGrid(const vector<string>& g) {\n    for (const auto& row : g) cout << row << '\\n';\n}\n\n// ---------- random grid ----------\nvector<string> randomGrid() {\n    vector<string> g(N, string(N, '.'));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            g[i][j] = LET[randInt(0, AL - 1)];\n    return g;\n}\n\n// ---------- mutation ----------\nvoid mutate1(vector<string>& g) {\n    int i = randInt(0, N - 1);\n    int j = randInt(0, N - 1);\n    char old = g[i][j];\n    char nu;\n    if (bestC == M && randInt(0, 9) == 0) nu = '.';\n    else nu = LET[randInt(0, AL - 1)];\n    g[i][j] = nu;\n    int c = evaluate(g);\n    if (c > bestC || (c == bestC && randInt(0, 1))) {\n        bestC = c;\n        bestGrid = g;\n    } else {\n        g[i][j] = old;\n    }\n}\n\nvoid mutateRow(vector<string>& g) {\n    int i = randInt(0, N - 1);\n    string old = g[i];\n    vector<int> unsat;\n    for (int idx = 0; idx < M; ++idx) {\n        const string& s = S[idx];\n        int L = s.size();\n        bool any = false;\n        for (int st = 0; st < N; ++st) {\n            bool ok = true;\n            for (int p = 0; p < L; ++p)\n                if (g[i][(st + p) % N] != s[p]) { ok = false; break; }\n            if (ok) { any = true; break; }\n        }\n        if (!any) unsat.push_back(idx);\n    }\n    if (unsat.empty()) return;\n    int pick = unsat[randInt(0, (int)unsat.size() - 1)];\n    const string& tgt = S[pick];\n    int L = tgt.size();\n    int st = randInt(0, N - 1);\n    for (int p = 0; p < L; ++p) g[i][(st + p) % N] = tgt[p];\n    int c = evaluate(g);\n    if (c > bestC || (c == bestC && randInt(0, 1))) {\n        bestC = c;\n        bestGrid = g;\n    } else {\n        g[i] = old;\n    }\n}\n\n// ---------- main ----------\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n, m;\n    cin >> n >> m;\n    M = m;\n    S.resize(M);\n    for (int i = 0; i < M; ++i) cin >> S[i];\n\n    bestGrid = randomGrid();\n    bestC = evaluate(bestGrid);\n\n    const double TIME_LIMIT = 2.8;\n    auto start = chrono::steady_clock::now();\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > TIME_LIMIT) break;\n\n        if (bestC < M) {\n            if (randInt(0, 3) == 0) mutateRow(bestGrid);\n            else                      mutate1(bestGrid);\n        } else {\n            mutate1(bestGrid);\n        }\n    }\n\n    // final safe fill pass\n    if (bestC == M) {\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                if (bestGrid[i][j] == '.') {\n                    char old = bestGrid[i][j];\n                    bool ok = false;\n                    for (char c : LET) {\n                        bestGrid[i][j] = c;\n                        if (evaluate(bestGrid) == M) { ok = true; break; }\n                    }\n                    if (!ok) bestGrid[i][j] = old;\n                }\n    }\n\n    printGrid(bestGrid);\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 70;\nconst int INF  = 0x3f3f3f3f;\n\nint N, si, sj;\nchar grid[MAXN][MAXN];\nint  cost[MAXN][MAXN];\nbool isRoad[MAXN][MAXN];\n\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\nchar dirC[] = {'U', 'D', 'L', 'R'};\n\nbitset<MAXN*MAXN> visFrom[MAXN][MAXN];   // what becomes visible\nbitset<MAXN*MAXN> coverage;\nint totalRoads;\n\n/* ---------- visibility precomputation ---------- */\nvoid buildVisibility() {\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (!isRoad[i][j]) continue;\n            auto &bs = visFrom[i][j];\n            // row left\n            for (int jj = j; jj >= 0 && isRoad[i][jj]; --jj) bs.set(i*N + jj);\n            // row right\n            for (int jj = j; jj <  N && isRoad[i][jj]; ++jj) bs.set(i*N + jj);\n            // col up\n            for (int ii = i; ii >= 0 && isRoad[ii][j]; --ii) bs.set(ii*N + j);\n            // col down\n            for (int ii = i; ii <  N && isRoad[ii][j]; ++ii) bs.set(ii*N + j);\n        }\n    }\n}\n\n/* ---------- single Dijkstra ---------- */\nint dist[MAXN][MAXN];\npair<int,int> parent[MAXN][MAXN];\n\nvoid dijkstra(int sr, int sc) {\n    memset(dist, 0x3f, sizeof(dist));\n    using T = tuple<int,int,int>;\n    priority_queue<T, vector<T>, greater<T>> pq;\n    dist[sr][sc] = 0;\n    parent[sr][sc] = {-1,-1};\n    pq.emplace(0, sr, sc);\n    while (!pq.empty()) {\n        auto [d, r, c] = pq.top(); pq.pop();\n        if (d > dist[r][c]) continue;\n        for (int k = 0; k < 4; ++k) {\n            int nr = r + dr[k], nc = c + dc[k];\n            if (nr<0||nr>=N||nc<0||nc>=N || !isRoad[nr][nc]) continue;\n            int nd = d + cost[nr][nc];\n            if (nd < dist[nr][nc]) {\n                dist[nr][nc] = nd;\n                parent[nr][nc] = {r,c};\n                pq.emplace(nd, nr, nc);\n            }\n        }\n    }\n}\n\n/* ---------- path reconstruction ---------- */\nvector<pair<int,int>> reconstruct(int tr, int tc) {\n    vector<pair<int,int>> path;\n    for (int r=tr, c=tc; r!=-1; tie(r,c)=parent[r][c]) path.emplace_back(r,c);\n    reverse(path.begin(), path.end());\n    return path;\n}\nstring toMoves(const vector<pair<int,int>>& path) {\n    string s;\n    for (int i = 1; i < (int)path.size(); ++i) {\n        int dr = path[i].first  - path[i-1].first;\n        int dc = path[i].second - path[i-1].second;\n        if (dr==-1) s+='U'; else if (dr==1) s+='D';\n        else if (dc==-1) s+='L'; else s+='R';\n    }\n    return s;\n}\n\n/* ---------- greedy cover ---------- */\nstring greedyCover() {\n    coverage.reset();\n    int cr = si, cc = sj;\n    string route;\n    coverage |= visFrom[cr][cc];\n\n    while ((int)coverage.count() < totalRoads) {\n        dijkstra(cr, cc);          // single Dijkstra\n        int best_r=-1, best_c=-1, best_gain=0, best_cost=INF;\n        for (int i=0;i<N;++i) {\n            for (int j=0;j<N;++j) {\n                if (!isRoad[i][j] || dist[i][j]==INF) continue;\n                int g = (visFrom[i][j] & ~coverage).count();\n                if (g==0) continue;\n                int c = dist[i][j];\n                if (g>best_gain || (g==best_gain && c<best_cost)) {\n                    best_gain = g; best_cost = c;\n                    best_r = i; best_c = j;\n                }\n            }\n        }\n        if (best_r==-1) break;     // should not happen\n        auto path = reconstruct(best_r, best_c);\n        route += toMoves(path);\n        cr = best_r; cc = best_c;\n        coverage |= visFrom[cr][cc];\n    }\n    // return to start\n    dijkstra(cr, cc);\n    auto pathBack = reconstruct(si, sj);\n    route += toMoves(pathBack);\n    return route;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin>>N>>si>>sj;\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]=='#') isRoad[i][j]=false, cost[i][j]=0;\n            else isRoad[i][j]=true, cost[i][j]=grid[i][j]-'0';\n        }\n    }\n    buildVisibility();\n    totalRoads = 0;\n    for(int i=0;i<N;++i)for(int j=0;j<N;++j)if(isRoad[i][j])++totalRoads;\n\n    string ans = greedyCover();\n    cout<<ans<<'\\n';\n    return 0;\n}","future-contest-2022-qual":"#pragma GCC target(\"avx2,popcnt,lzcnt,abm,bmi,bmi2\")\n#pragma GCC optimize(\"O3,unroll-loops,inline\")\n#include <bits/stdc++.h>\nusing namespace std;\n\nstatic constexpr int MAXK = 20;\nstatic constexpr int MAXM = 20;\nstatic constexpr int MAXN = 1000;\nstatic constexpr int MAXDAY = 2000;\n\nint N, M, K, R;\nalignas(64) int d[MAXN][MAXK];\nint bucketId[MAXN];\nvector<int> adj[MAXN], radj[MAXN];\nint level[MAXN];\nint remPred[MAXN];\nbool done[MAXN];\nint memberTask[MAXM];\nint taskStart[MAXM];\nint taskMember[MAXN];\n\nint Lb[MAXM][MAXK], Ub[MAXM][MAXK];\n\n// ready list: [0..readyTail) are ready; readyTail..readySz are waiting\nint readyBuf[MAXN];\nint readyTail = 0, readySz = 0;\n\ninline void push_ready(int t){ readyBuf[readySz++] = t; }\n\nint globalBucket(int task){\n    int s = 0;\n    for(int k = 0; k < K; k++) s += d[task][k];\n    return s / K;\n}\n\nvoid build_level(){\n    for(int i = 0; i < N; i++){\n        for(int v : adj[i]) level[v] = max(level[v], level[i]+1);\n    }\n}\n\ninline void mark_done(int task){\n    if(done[task]) return;\n    done[task] = true;\n    for(int v : adj[task]){\n        remPred[v]--;\n        if(remPred[v] == 0) push_ready(v);\n    }\n}\n\ninline void belief_update(int j, int task, int dur){\n    const int low  = max(0, dur - 3);\n    const int high = dur + 3;\n    int sumLo = 0, sumHi = 0;\n    #pragma GCC unroll 8\n    for(int k = 0; k < K; k++){\n        const int dk = d[task][k];\n        sumLo += max(0, dk - Ub[j][k]);\n        sumHi += max(0, dk - Lb[j][k]);\n    }\n    if(sumLo > high){\n        int need = sumLo - high;\n        int cnt  = 0;\n        for(int k = 0; k < K; k++){\n            const int dk = d[task][k];\n            if(dk > Lb[j][k] && dk < Ub[j][k]) cnt++;\n        }\n        if(cnt == 0) cnt = 1;\n        int each = (need + cnt - 1) / cnt;\n        for(int k = 0; k < K; k++){\n            const int dk = d[task][k];\n            if(dk > Lb[j][k] && dk < Ub[j][k]){\n                Ub[j][k] = min(Ub[j][k], dk);\n                need -= each;\n                if(need <= 0) break;\n            }\n        }\n    }\n    if(sumHi < low){\n        int need = low - sumHi;\n        int cnt  = 0;\n        for(int k = 0; k < K; k++){\n            const int dk = d[task][k];\n            if(dk > Lb[j][k]) cnt++;\n        }\n        if(cnt == 0) cnt = 1;\n        int each = (need + cnt - 1) / cnt;\n        for(int k = 0; k < K; k++){\n            const int dk = d[task][k];\n            if(dk > Lb[j][k]){\n                Lb[j][k] = max(Lb[j][k], dk - each);\n                need -= each;\n                if(need <= 0) break;\n            }\n        }\n    }\n}\n\ninline pair<int,int> est(int task, int j){\n    int optGap = 0, pesGap = 0;\n    #pragma GCC unroll 8\n    for(int k = 0; k < K; k++){\n        const int dk = d[task][k];\n        optGap += max(0, dk - Ub[j][k]);\n        pesGap += max(0, dk - Lb[j][k]);\n    }\n    const int opt = max(1, optGap - 3);\n    const int pes = max(1, pesGap + 3);\n    return {opt, pes};\n}\n\nvector<pair<int,int>> assign(){\n    if(readyTail == readySz) return {};\n    static int avail[MAXM], nAvail;\n    nAvail = 0;\n    for(int j = 0; j < M; j++) if(memberTask[j] < 0) avail[nAvail++] = j;\n    if(nAvail == 0) return {};\n\n    static tuple<int,int,int> es[MAXM * MAXN];\n    int esz = 0;\n    for(int a = 0; a < nAvail; a++){\n        int j = avail[a];\n        for(int t = readyTail; t < readySz; t++){\n            int i = readyBuf[t];\n            auto [opt, pes] = est(i, j);\n            int w = 3*opt + pes + 2*level[i];\n            es[esz++] = {w, a, t};\n        }\n    }\n    sort(es, es + esz);\n    static char ua[MAXM], ut[MAXN];\n    memset(ua, 0, nAvail);\n    memset(ut, 0, readySz - readyTail);\n    vector<pair<int,int>> ans;\n    ans.reserve(min(nAvail, readySz - readyTail));\n    for(int e = 0; e < esz; e++){\n        auto [w, a, t] = es[e];\n        if(ua[a] || ut[t - readyTail]) continue;\n        ua[a] = ut[t - readyTail] = 1;\n        int j = avail[a];\n        int i = readyBuf[t];\n        ans.emplace_back(j, i);\n    }\n    return ans;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> K >> R;\n    for(int i = 0; i < N; i++){\n        for(int k = 0; k < K; k++) cin >> d[i][k];\n        bucketId[i] = globalBucket(i);\n    }\n    for(int i = 0; i < R; i++){\n        int u,v; cin >> u >> v; u--; v--;\n        adj[u].push_back(v);\n        radj[v].push_back(u);\n    }\n    for(int i = 0; i < N; i++){\n        remPred[i] = radj[i].size();\n        if(remPred[i] == 0) push_ready(i);\n    }\n    build_level();\n\n    for(int j = 0; j < M; j++)\n        for(int k = 0; k < K; k++){\n            Lb[j][k] = 0;\n            Ub[j][k] = 200;\n        }\n    memset(memberTask, -1, sizeof memberTask);\n    memset(taskMember, -1, sizeof taskMember);\n\n    int day = 0;\n    while(day < MAXDAY){\n        day++;\n        auto match = assign();\n        const int m = match.size();\n        cout << m;\n        for(int i = 0; i < m; i++){\n            auto [j, t] = match[i];\n            cout << ' ' << (j+1) << ' ' << (t+1);\n            memberTask[j] = t;\n            taskMember[t] = j;\n            taskStart[j] = day;\n            // mark task as taken (swap with tail and pop)\n            int pos = find(readyBuf + readyTail, readyBuf + readySz, t) - readyBuf;\n            swap(readyBuf[pos], readyBuf[readyTail]);\n            readyTail++;\n        }\n        cout << '\\n';\n        cout.flush();\n\n        int n; \n        if(!(cin >> n)) break;\n        if(n == -1) break;\n        for(int i = 0; i < n; i++){\n            int j; cin >> j; j--;\n            int task = memberTask[j];\n            if(task < 0) continue;\n            int dur = day - taskStart[j] + 1;\n            belief_update(j, task, dur);\n            mark_done(task);\n            memberTask[j] = -1;\n            taskMember[task] = -1;\n        }\n        bool alld = true;\n        for(int i = 0; i < N; i++) if(!done[i]){ alld=false; break; }\n        if(alld) break;\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nstruct P { int x, y; };\nint man(const P& a, const P& b){\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\nstruct Order { P pu, de; int id; };\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<Order> all(1000);\n    for (int i = 0; i < 1000; ++i){\n        cin >> all[i].pu.x >> all[i].pu.y >> all[i].de.x >> all[i].de.y;\n        all[i].id = i;\n    }\n\n    const auto t0 = chrono::steady_clock::now();\n    ll bestT = LLONG_MAX;\n    vector<int> bestSel;\n    vector<P>   bestRoute;\n\n    mt19937 rng(123456);\n\n    const P office{400, 400};\n\n    while (true){\n        auto now = chrono::steady_clock::now();\n        if (chrono::duration<double>(now - t0).count() > 1.96) break;\n\n        /* 1. choose 50 random orders */\n        vector<int> sel(1000);\n        iota(sel.begin(), sel.end(), 0);\n        shuffle(sel.begin(), sel.end(), rng);\n        sel.resize(50);\n        sort(sel.begin(), sel.end());\n\n        /* 2. build initial route: office -> ... -> office */\n        vector<P> route = { office };\n        vector<int> puOf(50, -1), deOf(50, -1); // positions in route\n\n        auto costIns = [&](const P& pt, int at){\n            if (at == 0)\n                return man(office, pt) + man(pt, route[0]) - man(office, route[0]);\n            if (at == (int)route.size())\n                return man(route.back(), pt) + man(pt, office) - man(route.back(), office);\n            return man(route[at-1], pt) + man(pt, route[at]) - man(route[at-1], route[at]);\n        };\n\n        for (int oid = 0; oid < 50; ++oid){\n            const Order& o = all[sel[oid]];\n            ll bestInc = LLONG_MAX;\n            int bestPu = -1, bestDe = -1;\n            for (int pu = 1; pu <= (int)route.size(); ++pu){ // pu after office\n                ll incPu = costIns(o.pu, pu);\n                for (int de = pu + 1; de <= (int)route.size() + 1; ++de){\n                    ll incDe = 0;\n                    int realDe = (de > pu ? de - 1 : de);\n                    incDe = costIns(o.de, realDe);\n                    if (incPu + incDe < bestInc){\n                        bestInc = incPu + incDe;\n                        bestPu  = pu;\n                        bestDe  = de;\n                    }\n                }\n            }\n            route.insert(route.begin() + bestPu, o.pu);\n            int realDe = (bestDe > bestPu ? bestDe : bestDe);\n            route.insert(route.begin() + realDe, o.de);\n            /* rebuild puOf/deOf */\n            for (int i = 0; i < (int)route.size(); ++i){\n                if (route[i].x == o.pu.x && route[i].y == o.pu.y) puOf[oid] = i;\n                if (route[i].x == o.de.x && route[i].y == o.de.y) deOf[oid] = i;\n            }\n        }\n        route.push_back(office);\n\n        /* 3. fast random 2-opt, keeping 0 and n-1 fixed */\n        auto length = [&](const vector<P>& r){\n            ll len = 0;\n            for (int i = 0; i + 1 < (int)r.size(); ++i) len += man(r[i], r[i+1]);\n            return len;\n        };\n\n        uniform_int_distribution<int> uid(1, (int)route.size() - 3);\n        const int MAX_TRIES = 20000;\n        for (int tries = 0; tries < MAX_TRIES; ++tries){\n            int i = uid(rng);\n            int j = uid(rng);\n            if (j <= i) continue;\n            ll old = man(route[i], route[i+1]) + man(route[j], route[j+1]);\n            ll neo = man(route[i], route[j]) + man(route[i+1], route[j+1]);\n            if (neo >= old) continue;\n            /* reverse segment i+1 .. j */\n            reverse(route.begin() + i + 1, route.begin() + j + 1);\n            /* rebuild puOf/deOf and check feasibility */\n            bool ok = true;\n            for (int oid = 0; oid < 50 && ok; ++oid){\n                puOf[oid] = deOf[oid] = -1;\n                for (int p = 0; p < (int)route.size(); ++p){\n                    if (route[p].x == all[sel[oid]].pu.x && route[p].y == all[sel[oid]].pu.y) puOf[oid] = p;\n                    if (route[p].x == all[sel[oid]].de.x && route[p].y == all[sel[oid]].de.y) deOf[oid] = p;\n                }\n                ok &= (puOf[oid] < deOf[oid]);\n            }\n            if (ok) continue; // accept\n            /* rollback */\n            reverse(route.begin() + i + 1, route.begin() + j + 1);\n            for (int oid = 0; oid < 50; ++oid){\n                puOf[oid] = deOf[oid] = -1;\n                for (int p = 0; p < (int)route.size(); ++p){\n                    if (route[p].x == all[sel[oid]].pu.x && route[p].y == all[sel[oid]].pu.y) puOf[oid] = p;\n                    if (route[p].x == all[sel[oid]].de.x && route[p].y == all[sel[oid]].de.y) deOf[oid] = p;\n                }\n            }\n        }\n\n        ll T = length(route);\n        if (T < bestT){\n            bestT = T;\n            bestSel = sel;\n            bestRoute = route;\n        }\n    }\n\n    /* 4. output */\n    cout << 50;\n    for (int x : bestSel) cout << ' ' << x + 1;\n    cout << '\\n';\n    cout << bestRoute.size();\n    for (auto &p : bestRoute) cout << ' ' << p.x << ' ' << p.y;\n    cout << '\\n';\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct UnionFind {\n    vector<int> parent, rank;\n    int components;\n    \n    UnionFind(int n) : parent(n), rank(n, 0), components(n) {\n        for (int i = 0; i < n; i++) {\n            parent[i] = i;\n        }\n    }\n    \n    int find(int x) {\n        if (parent[x] != x) {\n            parent[x] = find(parent[x]);\n        }\n        return parent[x];\n    }\n    \n    bool unite(int x, int y) {\n        int px = find(x), py = find(y);\n        if (px == py) return false;\n        \n        if (rank[px] < rank[py]) {\n            parent[px] = py;\n        } else {\n            parent[py] = px;\n            if (rank[px] == rank[py]) {\n                rank[px]++;\n            }\n        }\n        components--;\n        return true;\n    }\n    \n    bool connected() {\n        return components == 1;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 400, M = 1995;\n    \n    // Read coordinates\n    vector<pair<int, int>> coords(N);\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    // Read edges and calculate expected lengths\n    vector<int> u(M), v(M);\n    vector<int> d(M);\n    \n    for (int i = 0; i < M; i++) {\n        cin >> u[i] >> v[i];\n        \n        // Calculate Euclidean distance\n        double dx = coords[u[i]].first - coords[v[i]].first;\n        double dy = coords[u[i]].second - coords[v[i]].second;\n        double dist = sqrt(dx*dx + dy*dy);\n        d[i] = round(dist);\n    }\n    \n    UnionFind uf(N);\n    int accepted = 0;\n    bool has_spanning_tree = false;\n    int good_edges_seen = 0;\n    int total_connecting_edges = 0;\n    \n    // Process each edge\n    for (int i = 0; i < M; i++) {\n        int l;\n        cin >> l;\n        \n        bool adopt = false;\n        double ratio = (double)l / d[i];\n        \n        // ALWAYS accept connecting edges - connectivity is non-negotiable\n        if (uf.find(u[i]) != uf.find(v[i])) {\n            adopt = true;\n            total_connecting_edges++;\n            \n            // Track quality of connecting edges for future reference\n            if (ratio <= 1.3) good_edges_seen++;\n        }\n        // For non-connecting edges, use dynamic selectivity\n        else if (!has_spanning_tree && accepted < N + 5) {\n            // Pre-connectivity: be very selective, but adapt based on what we've seen\n            double threshold = 1.25;\n            \n            // If we've seen many good connecting edges, we can be more selective\n            if (total_connecting_edges > 50 && good_edges_seen > 20) {\n                threshold = 1.2;  // Be more selective if connectivity looks good\n            }\n            \n            if (ratio <= threshold) {\n                adopt = true;\n            }\n        }\n        // Post-connectivity: be extremely selective\n        else if (has_spanning_tree && ratio <= 1.08) {\n            adopt = true;\n        }\n        // Emergency: very late rounds with many components remaining\n        else if (i > M - 20 && uf.components > 2 && ratio <= 1.3) {\n            adopt = true;\n        }\n        \n        if (adopt) {\n            bool was_connected = uf.connected();\n            uf.unite(u[i], v[i]);\n            accepted++;\n            \n            if (!was_connected && uf.connected()) {\n                has_spanning_tree = true;\n            }\n            \n            cout << \"1\" << endl;\n        } else {\n            cout << \"0\" << endl;\n        }\n        \n        cout.flush();\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 30, W = 30, TURNS = 300;\nconst int dx[4] = {-1, 1, 0, 0}, dy[4] = {0, 0, -1, 1};\nconst char *dir = \"UDLR\", *Dir = \"UDLR\", *block = \"udlr\";\n\nint N, M;\nstruct Pet {\n    int x, y, t;\n} pets[20];\nstruct Human {\n    int x, y;\n} humans[10];\n\nbool wall[H][W]; // wall[x][y] = true if blocked\nint pet_x[20], pet_y[20];\n\n// BFS reachable squares from (sx,sy), return count and pet count\npair<int, int> bfs_reachable(int sx, int sy) {\n    static bool vis[H][W];\n    memset(vis, 0, sizeof(vis));\n    queue<pair<int, int>> q;\n    if (wall[sx][sy]) return {0, 0};\n    vis[sx][sy] = true;\n    q.push({sx, sy});\n    int cnt = 0, pcnt = 0;\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        cnt++;\n        for (int i = 0; i < N; i++) {\n            if (pet_x[i] == x && pet_y[i] == pcnt++) pcnt--;\n            if (pet_x[i] == x && pet_y[i] == y) pcnt++;\n        }\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n            if (wall[nx][ny] || vis[nx][ny]) continue;\n            vis[nx][ny] = true;\n            q.push({nx, ny});\n        }\n    }\n    return {cnt, pcnt};\n}\n\n// Heuristic score for a human at (x,y)\ndouble heuristic(int x, int y) {\n    auto [r, p] = bfs_reachable(x, y);\n    return r - 900.0 * p / 2.0;\n}\n\n// Check if can block (bx,by) from human at (x,y)\nbool can_block(int x, int y, int bx, int by) {\n    if (abs(bx - x) + abs(by - y) != 1) return false;\n    if (wall[bx][by]) return true; // already blocked\n    // Check if any pet or human is on (bx,by) at start\n    for (int i = 0; i < N; i++) {\n        if (pet_x[i] == bx && pet_y[i] == by) return false;\n    }\n    for (int i = 0; i < M; i++) {\n        if (humans[i].x == bx && humans[i].y == by) return false;\n    }\n    // Check if any pet is adjacent to (bx,by)\n    for (int d = 0; d < 4; d++) {\n        int nx = bx + dx[d], ny = by + dy[d];\n        if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n        for (int i = 0; i < N; i++) {\n            if (pet_x[i] == nx && pet_y[i] == ny) return false;\n        }\n    }\n    return true;\n}\n\n// Simulate pet moves (simplified: assume random for 1-3, greedy for 4-5)\nvoid simulate_pets() {\n    // For types 1-3: random basic moves (here we just do random)\n    // For types 4-5: target and move closer\n    // This is a placeholder: in real code, use BFS and rules\n    for (int i = 0; i < N; i++) {\n        int t = pets[i].t;\n        int &x = pet_x[i], &y = pet_y[i];\n        if (t <= 3) {\n            int steps = t;\n            while (steps--) {\n                vector<int> dirs;\n                for (int d = 0; d < 4; d++) {\n                    int nx = x + dx[d], ny = y + dy[d];\n                    if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n                    if (wall[nx][ny]) continue;\n                    dirs.push_back(d);\n                }\n                if (dirs.empty()) break;\n                int d = dirs[rand() % dirs.size()];\n                x += dx[d]; y += dy[d];\n            }\n        } else if (t == 4) {\n            // Dog: target human, move closer\n            // Simplified: pick random human and move one step closer\n            int ti = rand() % M;\n            int hx = humans[ti].x, hy = humans[ti].y;\n            // BFS to find direction\n            // For now, just move randomly\n            vector<int> dirs;\n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n                if (wall[nx][ny]) continue;\n                dirs.push_back(d);\n            }\n            if (!dirs.empty()) {\n                int d = dirs[rand() % dirs.size()];\n                x += dx[d]; y += dy[d];\n            }\n        } else {\n            // Cat: target square, move closer\n            // Simplified: move randomly\n            vector<int> dirs;\n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n                if (wall[nx][ny]) continue;\n                dirs.push_back(d);\n            }\n            if (!dirs.empty()) {\n                int d = dirs[rand() % dirs.size()];\n                x += dx[d]; y += dy[d];\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    for (int i = 0; i < N; i++) {\n        cin >> pets[i].x >> pets[i].y >> pets[i].t;\n        pets[i].x--; pets[i].y--;\n        pet_x[i] = pets[i].x;\n        pet_y[i] = pets[i].y;\n    }\n    cin >> M;\n    for (int i = 0; i < M; i++) {\n        cin >> humans[i].x >> humans[i].y;\n        humans[i].x--; humans[i].y--;\n    }\n\n    memset(wall, 0, sizeof(wall));\n\n    for (int turn = 0; turn < TURNS; turn++) {\n        string act;\n        for (int i = 0; i < M; i++) {\n            int x = humans[i].x, y = humans[i].y;\n            double best = -1e9;\n            char best_act = '.';\n            // Try stay\n            double sc = heuristic(x, y);\n            if (sc > best) { best = sc; best_act = '.'; }\n            // Try move\n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n                if (wall[nx][ny]) continue;\n                humans[i].x = nx; humans[i].y = ny;\n                sc = heuristic(nx, ny);\n                if (sc > best) { best = sc; best_act = Dir[d]; }\n                humans[i].x = x; humans[i].y = y;\n            }\n            // Try block\n            for (int d = 0; d < 4; d++) {\n                int bx = x + dx[d], by = y + dy[d];\n                if (!can_block(x, y, bx, by)) continue;\n                bool old = wall[bx][by];\n                wall[bx][by] = true;\n                sc = heuristic(x, y);\n                if (sc > best) { best = sc; best_act = block[d]; }\n                wall[bx][by] = old;\n            }\n            act += best_act;\n            // Apply best action\n            if (best_act == '.') {\n                // stay\n            } else if (best_act >= 'U' && best_act <= 'R') {\n                int d = best_act - 'U';\n                humans[i].x += dx[d];\n                humans[i].y += dy[d];\n            } else if (best_act >= 'u' && best_act <= 'r') {\n                int d = best_act - 'u';\n                int bx = x + dx[d], by = y + dy[d];\n                wall[bx][by] = true;\n            }\n        }\n        cout << act << endl;\n        cout.flush();\n\n        // Read pet moves\n        for (int i = 0; i < N; i++) {\n            string s;\n            cin >> s;\n            // Apply pet moves\n            int &x = pet_x[i], &y = pet_y[i];\n            for (char c : s) {\n                int d = -1;\n                if (c == 'U') d = 0;\n                else if (c == 'D') d = 1;\n                else if (c == 'L') d = 2;\n                else if (c == 'R') d = 3;\n                else continue;\n                int nx = x + dx[d], ny = y + dy[d];\n                if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n                if (wall[nx][ny]) continue;\n                x = nx; y = ny;\n            }\n        }\n    }\n\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic uint64_t rng_state = 123456789123456789ULL;\ninline uint64_t xorshift64() {\n    uint64_t x = rng_state;\n    x ^= x << 13; x ^= x >> 7; x ^= x << 17;\n    rng_state = x; return x;\n}\ninline int  randint(int l, int r)   { return l + (xorshift64() % (r - l + 1)); }\ninline double rand01()              { return (xorshift64() & ((1ULL<<32)-1)) / double(1ULL<<32); }\n\nint si,sj,ti,tj;\ndouble pforget;\nbool wallh[20][19], wallv[19][20];\nint  dist[20][20];\nstring best_str;\ndouble best_score;\nchrono::steady_clock::time_point start_time;\n\nconst int INF = 1000000;\n\n/* ---------- grid utilities ---------- */\nvoid bfs_dist(){\n    for(int i=0;i<20;i++)for(int j=0;j<20;j++) dist[i][j]=INF;\n    deque<pair<int,int>> dq;\n    dist[ti][tj]=0; dq.push_back({ti,tj});\n    static int di[4]={-1,1,0,0}, dj[4]={0,0,-1,1};\n    while(!dq.empty()){\n        auto [i,j]=dq.front(); dq.pop_front();\n        for(int d=0;d<4;d++){\n            int ni=i+di[d], nj=j+dj[d];\n            if(ni<0||nj<0||ni>=20||nj>=20) continue;\n            if(d==0&&wallv[ni][j]) continue;\n            if(d==1&&wallv[i][j]) continue;\n            if(d==2&&wallh[i][nj]) continue;\n            if(d==3&&wallh[i][j]) continue;\n            if(dist[ni][nj]>dist[i][j]+1){\n                dist[ni][nj]=dist[i][j]+1;\n                dq.push_back({ni,nj});\n            }\n        }\n    }\n}\ninline bool canmove(int i,int j,int d){\n    if(d==0){ if(i==0) return 0; return !wallv[i-1][j]; }\n    if(d==1){ if(i==19)return 0; return !wallv[i][j]; }\n    if(d==2){ if(j==0) return 0; return !wallh[i][j-1]; }\n    if(d==3){ if(j==19)return 0; return !wallh[i][j]; }\n    return 0;\n}\ninline int mi(int i,int d){ return d==0?i-1:(d==1?i+1:i); }\ninline int mj(int j,int d){ return d==2?j-1:(d==3?j+1:j); }\n\n/* ---------- exact evaluator ---------- */\ndouble eval(const string &s){\n    const int L=s.size();\n    static double cur[400], nxt[400];\n    for(int v=0;v<400;v++) cur[v]=0.;\n    int start=si*20+sj;\n    cur[start]=1.0;\n    double succ=0., et=0.;\n    for(int t=0;t<L;t++){\n        for(int v=0;v<400;v++) nxt[v]=0.;\n        for(int v=0;v<400;v++){\n            if(cur[v]<1e-14) continue;\n            int i=v/20, j=v%20;\n            if(i==ti&&j==tj) continue;\n            int nopen=0;\n            for(int d=0;d<4;d++) if(canmove(i,j,d)) nopen++;\n            double pstay = pforget;\n            nxt[v] += cur[v]*pstay;\n            if(nopen>0){\n                double pdir = (1.-pforget)/nopen;\n                for(int d=0;d<4;d++){\n                    if(!canmove(i,j,d)) continue;\n                    int ni=mi(i,d), nj=mj(j,d), u=ni*20+nj;\n                    if(ni==ti&&nj==tj){\n                        double prob=cur[v]*pdir;\n                        succ+=prob; et+=prob*(t+1);\n                    }else nxt[u]+=cur[v]*pdir;\n                }\n            }else nxt[v]+=cur[v]*(1.-pforget);\n        }\n        swap(cur,nxt);\n    }\n    double left=0.; for(int v=0;v<400;v++) left+=cur[v];\n    succ=1.-left;\n    if(succ<1e-14) return 0.;\n    double mean_t=et/succ;\n    double raw=succ*(401.-mean_t);\n    return raw - 0.05*max(0,(int)s.size()-90);\n}\n\n/* ---------- greedy random walk ---------- */\nstring greedy_random_walk(int want_len){\n    string path;\n    int i=si, j=sj;\n    while((int)path.size()<want_len){\n        if(i==ti&&j==tj) break;\n        int dirs[4]={0,1,2,3};\n        for(int k=0;k<4;k++){ int r=randint(k,3); swap(dirs[k],dirs[r]); }\n        double best=-1e9; int bestd=-1;\n        for(int k=0;k<4;k++){\n            int d=dirs[k]; if(!canmove(i,j,d)) continue;\n            int ni=mi(i,d), nj=mj(j,d);\n            double val=-dist[ni][nj]+rand01()*0.3;\n            if(val>best){ best=val; bestd=d; }\n        }\n        if(bestd>=0){ path+=\"UDLR\"[bestd]; i=mi(i,bestd); j=mj(j,bestd); }\n        else path+='U';\n    }\n    while((int)path.size()<want_len){\n        if(i==ti&&j==tj){ path+='R'; continue; }\n        int bestd=-1, bestv=INF;\n        for(int d=0;d<4;d++){\n            if(!canmove(i,j,d)) continue;\n            int ni=mi(i,d), nj=mj(j,d);\n            if(dist[ni][nj]<bestv){ bestv=dist[ni][nj]; bestd=d; }\n        }\n        if(bestd>=0){ path+=\"UDLR\"[bestd]; i=mi(i,bestd); j=mj(j,bestd); }\n        else path+='U';\n    }\n    return path;\n}\n\n/* ---------- segment re-route ---------- */\nstring greedy_segment(int len, int &ri, int &rj){\n    string path;\n    int i=ri, j=rj;\n    while((int)path.size()<len){\n        if(i==ti&&j==tj) break;\n        int dirs[4]={0,1,2,3};\n        for(int k=0;k<4;k++){ int r=randint(k,3); swap(dirs[k],dirs[r]); }\n        double best=-1e9; int bestd=-1;\n        for(int k=0;k<4;k++){\n            int d=dirs[k]; if(!canmove(i,j,d)) continue;\n            int ni=mi(i,d), nj=mj(j,d);\n            double val=-dist[ni][nj]+rand01()*0.3;\n            if(val>best){ best=val; bestd=d; }\n        }\n        if(bestd>=0){ path+=\"UDLR\"[bestd]; i=mi(i,bestd); j=mj(j,bestd); }\n        else path+='U';\n    }\n    while((int)path.size()<len){\n        if(i==ti&&j==tj){ path+='R'; continue; }\n        int bestd=-1, bestv=INF;\n        for(int d=0;d<4;d++){\n            if(!canmove(i,j,d)) continue;\n            int ni=mi(i,d), nj=mj(j,d);\n            if(dist[ni][nj]<bestv){ bestv=dist[ni][nj]; bestd=d; }\n        }\n        if(bestd>=0){ path+=\"UDLR\"[bestd]; i=mi(i,bestd); j=mj(j,bestd); }\n        else path+='U';\n    }\n    ri=i; rj=j;\n    return path;\n}\n\ninline int char2d(char c){\n    return c=='U'?0:(c=='D'?1:(c=='L'?2:3));\n}\n\nstring segment_reroute(const string &s){\n    int L=s.size();\n    if(L<10) return s;\n    int seg_len=randint(5,min(20,L));\n    int pos=randint(0,L-seg_len);\n    int i=si, j=sj;\n    // simulate up to pos\n    for(int k=0;k<pos;k++){\n        int d=char2d(s[k]);\n        if(canmove(i,j,d)){ i=mi(i,d); j=mj(j,d); }\n    }\n    int si_seg=i, sj_seg=j;\n    // simulate the segment to know where we must arrive\n    for(int k=pos;k<pos+seg_len;k++){\n        int d=char2d(s[k]);\n        if(canmove(i,j,d)){ i=mi(i,d); j=mj(j,d); }\n    }\n    // build new segment that starts at (si_seg,sj_seg) and has same length\n    string replacement=greedy_segment(seg_len, si_seg, sj_seg);\n    // patch\n    string nxt=s;\n    nxt.replace(pos,seg_len,replacement);\n    return nxt;\n}\n\n/* ---------- simulated annealing ---------- */\nvoid anneal(){\n    const double T0=0.5, alpha=0.995;\n    string cur=best_str;\n    double cursc=best_score;\n    double T=T0;\n    while(1){\n        auto now=chrono::steady_clock::now();\n        double elapsed=chrono::duration<double>(now - start_time).count();\n        if(elapsed>1.75) break;\n\n        string nxt=cur;\n        int op=randint(0,11);   // 0-7 flip, 8 del, 9 ins, 10-11 reroute\n        if(op<=7){\n            int pos=randint(0,(int)nxt.size()-1);\n            int nd=randint(0,3);\n            nxt[pos]=\"UDLR\"[nd];\n        }else if(op==8){\n            if(nxt.size()<=60) continue;\n            int pos=randint(0,(int)nxt.size()-1);\n            nxt.erase(pos,1);\n        }else if(op==9){\n            if(nxt.size()>=200) continue;\n            int pos=randint(0,(int)nxt.size());\n            int nd=randint(0,3);\n            nxt.insert(pos,1,\"UDLR\"[nd]);\n        }else{\n            nxt=segment_reroute(cur);\n        }\n\n        double nxtsc=eval(nxt);\n        double delta=nxtsc-cursc;\n        if(delta>0 || rand01()<exp(delta/T)){\n            cur=nxt; cursc=nxtsc;\n            if(nxtsc>best_score){\n                best_score=nxtsc;\n                best_str=nxt;\n            }\n        }\n        T*=alpha;\n        if(T<1e-4) T=1e-4;\n    }\n}\n\n/* ---------- final robustness repair ---------- */\nvoid repair_zeros(){\n    for(int attempt=0;attempt<13;attempt++){\n        auto now=chrono::steady_clock::now();\n        double elapsed=chrono::duration<double>(now - start_time).count();\n        if(elapsed>1.98) break;\n        int want=min(200, (int)best_str.size()+30);\n        string cand=greedy_random_walk(want);\n        double sc=eval(cand);\n        if(sc>best_score){ best_score=sc; best_str=cand; }\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    start_time=chrono::steady_clock::now();\n\n    cin>>si>>sj>>ti>>tj>>pforget;\n    for(int i=0;i<20;i++){\n        string row; cin>>row;\n        for(int j=0;j<19;j++) wallh[i][j]=(row[j]=='1');\n    }\n    for(int i=0;i<19;i++){\n        string row; cin>>row;\n        for(int j=0;j<20;j++) wallv[i][j]=(row[j]=='1');\n    }\n    bfs_dist();\n\n    best_score=-1e9;\n    for(int attempt=0;attempt<200;attempt++){\n        int want=randint(60,180);\n        string cand=greedy_random_walk(want);\n        double sc=eval(cand);\n        if(sc>best_score){ best_score=sc; best_str=cand; }\n    }\n    anneal();\n    repair_zeros();\n    cout<<best_str<<\"\\n\";\n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <random>\n#include <algorithm>\n#include <chrono>\n#include <queue>\n#include <unordered_set>\n\nusing namespace std;\n\nconst int SIZE = 30;\nconst int DIR[4][2] = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};\n\nconst int to[8][4] = {\n    {1, 0, -1, -1},  // type 0\n    {3, -1, -1, 0},  // type 1\n    {-1, -1, 3, 2},  // type 2\n    {-1, 2, 1, -1},  // type 3\n    {1, 0, 3, 2},    // type 4\n    {3, 2, 1, 0},    // type 5\n    {2, -1, 0, -1},  // type 6\n    {-1, 3, -1, 1}   // type 7\n};\n\nint grid[SIZE][SIZE];\nint rotation[SIZE][SIZE];\nint best_rotation[SIZE][SIZE];\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\ninline int get_tile_type(int i, int j) {\n    int base_type = grid[i][j];\n    int rot = rotation[i][j];\n    if (base_type <= 3) {\n        return (base_type + rot) % 4;\n    } else if (base_type <= 5) {\n        return 4 + (base_type - 4 + rot) % 2;\n    } else {\n        return 6 + (base_type - 6 + rot) % 2;\n    }\n}\n\nint trace_loop(int si, int sj, int sd) {\n    int i = si, j = sj, d = sd;\n    int length = 0;\n    \n    for (int step = 0; step < 2000; step++) {\n        int tile_type = get_tile_type(i, j);\n        int d2 = to[tile_type][d];\n        if (d2 == -1) return 0;\n        \n        i += DIR[d2][0];\n        j += DIR[d2][1];\n        if (i < 0 || i >= SIZE || j < 0 || j >= SIZE) return 0;\n        \n        d = (d2 + 2) % 4;\n        length++;\n        \n        if (i == si && j == sj && d == sd) return length;\n    }\n    return 0;\n}\n\npair<int, int> find_loops_adaptive() {\n    vector<int> loop_lengths;\n    static vector<pair<int, int>> hotspots;\n    \n    // Initial hotspots\n    if (hotspots.empty()) {\n        // Center and edge areas\n        for (int i = 3; i < SIZE-3; i += 2) {\n            for (int j = 3; j < SIZE-3; j += 2) {\n                hotspots.push_back({i, j});\n            }\n        }\n    }\n    \n    // Check hotspots first\n    for (auto [i, j] : hotspots) {\n        if (i >= 0 && i < SIZE && j >= 0 && j < SIZE) {\n            for (int d = 0; d < 4; d++) {\n                int len = trace_loop(i, j, d);\n                if (len > 8) {\n                    loop_lengths.push_back(len);\n                    // Add neighbors of successful loops as new hotspots\n                    for (int di = -1; di <= 1; di++) {\n                        for (int dj = -1; dj <= 1; dj++) {\n                            if (di != 0 || dj != 0) {\n                                int ni = i + di, nj = j + dj;\n                                if (ni >= 0 && ni < SIZE && nj >= 0 && nj < SIZE) {\n                                    hotspots.push_back({ni, nj});\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Remove duplicates and limit hotspots\n    sort(hotspots.begin(), hotspots.end());\n    hotspots.erase(unique(hotspots.begin(), hotspots.end()), hotspots.end());\n    if (hotspots.size() > 200) {\n        hotspots.resize(200);\n    }\n    \n    // Fill with some random positions if needed\n    while (loop_lengths.size() < 10 && !hotspots.empty()) {\n        int idx = rng() % hotspots.size();\n        int i = hotspots[idx].first;\n        int j = hotspots[idx].second;\n        int d = rng() % 4;\n        int len = trace_loop(i, j, d);\n        if (len > 6) {\n            loop_lengths.push_back(len);\n        }\n        hotspots.erase(hotspots.begin() + idx);\n    }\n    \n    sort(loop_lengths.rbegin(), loop_lengths.rend());\n    if (loop_lengths.size() < 2) return {0, 0};\n    return {loop_lengths[0], loop_lengths[1]};\n}\n\nint calculate_score() {\n    auto [l1, l2] = find_loops_adaptive();\n    return l1 * l2;\n}\n\nvoid pattern_based_search() {\n    int best_score = 0;\n    \n    // Try different initialization patterns\n    vector<void(*)()> init_patterns = {\n        []() { // Smart pattern 1\n            for (int i = 0; i < SIZE; i++) {\n                for (int j = 0; j < SIZE; j++) {\n                    rotation[i][j] = ((i ^ j) + (i + j) / 3) % 4;\n                }\n            }\n        },\n        []() { // Smart pattern 2\n            for (int i = 0; i < SIZE; i++) {\n                for (int j = 0; j < SIZE; j++) {\n                    rotation[i][j] = (i * 2 + j * 3 + (i * j) / 10) % 4;\n                }\n            }\n        },\n        []() { // Random\n            for (int i = 0; i < SIZE; i++) {\n                for (int j = 0; j < SIZE; j++) {\n                    rotation[i][j] = rng() % 4;\n                }\n            }\n        }\n    };\n    \n    for (int pattern_idx = 0; pattern_idx < init_patterns.size(); pattern_idx++) {\n        init_patterns[pattern_idx]();\n        \n        int current_score = calculate_score();\n        int local_best = current_score;\n        \n        // Beam search with multiple candidates\n        const int beam_width = 5;\n        vector<vector<vector<int>>> candidates(beam_width, vector<vector<int>>(SIZE, vector<int>(SIZE)));\n        vector<int> candidate_scores(beam_width, current_score);\n        \n        // Fill initial candidates\n        for (int b = 0; b < beam_width; b++) {\n            for (int i = 0; i < SIZE; i++) {\n                for (int j = 0; j < SIZE; j++) {\n                    candidates[b][i][j] = rotation[i][j];\n                }\n            }\n        }\n        \n        // Iterative improvement\n        for (int iter = 0; iter < 1000; iter++) {\n            vector<pair<int, vector<vector<int>>>> all_candidates;\n            \n            // Generate neighbors for each beam candidate\n            for (int b = 0; b < beam_width; b++) {\n                // Copy current candidate to rotation\n                for (int i = 0; i < SIZE; i++) {\n                    for (int j = 0; j < SIZE; j++) {\n                        rotation[i][j] = candidates[b][i][j];\n                    }\n                }\n                \n                // Try pattern moves\n                for (int pattern = 0; pattern < 3; pattern++) {\n                    int center_i = rng() % (SIZE - 4) + 2;\n                    int center_j = rng() % (SIZE - 4) + 2;\n                    \n                    // Apply 2x2 pattern rotation\n                    for (int di = 0; di < 2; di++) {\n                        for (int dj = 0; dj < 2; dj++) {\n                            int ni = center_i + di;\n                            int nj = center_j + dj;\n                            rotation[ni][nj] = (rotation[ni][nj] + 1 + pattern) % 4;\n                        }\n                    }\n                    \n                    int score = calculate_score();\n                    all_candidates.push_back({score, vector<vector<int>>(SIZE, vector<int>(SIZE))});\n                    \n                    for (int i = 0; i < SIZE; i++) {\n                        for (int j = 0; j < SIZE; j++) {\n                            all_candidates.back().second[i][j] = rotation[i][j];\n                        }\n                    }\n                    \n                    // Revert for next try\n                    for (int di = 0; di < 2; di++) {\n                        for (int dj = 0; dj < 2; dj++) {\n                            int ni = center_i + di;\n                            int nj = center_j + dj;\n                            rotation[ni][nj] = candidates[b][ni][nj];\n                        }\n                    }\n                }\n            }\n            \n            // Keep best candidates\n            sort(all_candidates.rbegin(), all_candidates.rend());\n            int new_beam_size = min(beam_width, (int)all_candidates.size());\n            \n            for (int b = 0; b < new_beam_size; b++) {\n                candidate_scores[b] = all_candidates[b].first;\n                candidates[b] = all_candidates[b].second;\n                \n                if (all_candidates[b].first > local_best) {\n                    local_best = all_candidates[b].first;\n                    for (int i = 0; i < SIZE; i++) {\n                        for (int j = 0; j < SIZE; j++) {\n                            rotation[i][j] = all_candidates[b].second[i][j];\n                        }\n                    }\n                }\n            }\n            \n            if (iter > 200 && local_best == current_score) break;\n            current_score = local_best;\n        }\n        \n        if (current_score > best_score) {\n            best_score = current_score;\n            for (int i = 0; i < SIZE; i++) {\n                for (int j = 0; j < SIZE; j++) {\n                    best_rotation[i][j] = rotation[i][j];\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    for (int i = 0; i < SIZE; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < SIZE; j++) {\n            grid[i][j] = line[j] - '0';\n        }\n    }\n    \n    // Run pattern-based search\n    pattern_based_search();\n    \n    // Output best solution\n    for (int i = 0; i < SIZE; i++) {\n        for (int j = 0; j < SIZE; j++) {\n            cout << best_rotation[i][j];\n        }\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc011":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <chrono>\n#include <algorithm>\n#include <unordered_set>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\nconst int dx[4] = {-1, 0, 1, 0};\nconst int dy[4] = {0, 1, 0, -1};\nconst char dir_char[4] = {'U', 'R', 'D', 'L'};\n\nint N, T;\nvector<vector<int>> board;\nint empty_row, empty_col;\nstring solution;\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nbool has_line(int tile, int direction) {\n    return (tile >> direction) & 1;\n}\n\nbool can_connect(int tile1, int tile2, int direction) {\n    int opposite = (direction + 2) % 4;\n    return has_line(tile1, direction) && has_line(tile2, opposite);\n}\n\nbool is_valid_move(int r, int c) {\n    return r >= 0 && r < N && c >= 0 && c < N && board[r][c] != 0;\n}\n\nvoid make_move(int direction) {\n    int nr = empty_row + dx[direction];\n    int nc = empty_col + dy[direction];\n    \n    if (!is_valid_move(nr, nc)) return;\n    \n    swap(board[empty_row][empty_col], board[nr][nc]);\n    empty_row = nr;\n    empty_col = nc;\n    solution += dir_char[direction];\n}\n\nint count_tree_size(int start_r, int start_c, vector<vector<bool>>& visited) {\n    if (board[start_r][start_c] == 0 || visited[start_r][start_c]) return 0;\n    \n    vector<pair<int, int>> stack;\n    stack.push_back({start_r, start_c});\n    visited[start_r][start_c] = true;\n    int size = 0;\n    \n    while (!stack.empty()) {\n        auto [r, c] = stack.back();\n        stack.pop_back();\n        size++;\n        \n        for (int d = 0; d < 4; d++) {\n            int nr = r + dx[d];\n            int nc = c + dy[d];\n            \n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n            if (board[nr][nc] == 0 || visited[nr][nc]) continue;\n            if (!can_connect(board[r][c], board[nr][nc], d)) continue;\n            \n            visited[nr][nc] = true;\n            stack.push_back({nr, nc});\n        }\n    }\n    \n    return size;\n}\n\nint find_largest_tree() {\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    int max_size = 0;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0 || visited[i][j]) continue;\n            max_size = max(max_size, count_tree_size(i, j, visited));\n        }\n    }\n    \n    return max_size;\n}\n\nvector<vector<int>> find_components() {\n    vector<vector<int>> components(N, vector<int>(N, -1));\n    int component_id = 0;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0 || components[i][j] != -1) continue;\n            \n            vector<pair<int, int>> stack;\n            stack.push_back({i, j});\n            components[i][j] = component_id;\n            \n            while (!stack.empty()) {\n                auto [r, c] = stack.back();\n                stack.pop_back();\n                \n                for (int d = 0; d < 4; d++) {\n                    int nr = r + dx[d];\n                    int nc = c + dy[d];\n                    \n                    if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n                    if (board[nr][nc] == 0 || components[nr][nc] != -1) continue;\n                    if (!can_connect(board[r][c], board[nr][nc], d)) continue;\n                    \n                    components[nr][nc] = component_id;\n                    stack.push_back({nr, nc});\n                }\n            }\n            component_id++;\n        }\n    }\n    \n    return components;\n}\n\nint calculate_bridge_potential(int r, int c, int tile) {\n    int potential = 0;\n    \n    // Find current components\n    vector<vector<int>> components = find_components();\n    \n    // Check if this position can bridge components\n    unordered_set<int> adjacent_components;\n    \n    for (int d = 0; d < 4; d++) {\n        int nr = r + dx[d];\n        int nc = c + dy[d];\n        \n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n        if (board[nr][nc] == 0) continue;\n        \n        int comp = components[nr][nc];\n        if (comp != -1) {\n            if (has_line(tile, d) && has_line(board[nr][nc], (d + 2) % 4)) {\n                adjacent_components.insert(comp);\n            }\n        }\n    }\n    \n    // High reward for bridging multiple components\n    if (adjacent_components.size() >= 2) {\n        potential += adjacent_components.size() * 50;\n    }\n    \n    return potential;\n}\n\nint evaluate_strategic_move(int direction) {\n    int nr = empty_row + dx[direction];\n    int nc = empty_col + dy[direction];\n    \n    if (!is_valid_move(nr, nc)) return -1000000;\n    \n    int tile = board[nr][nc];\n    \n    // Multi-factor evaluation\n    int score = 0;\n    \n    // 1. Direct tree size impact\n    swap(board[empty_row][empty_col], board[nr][nc]);\n    int new_tree = find_largest_tree();\n    swap(board[empty_row][empty_col], board[nr][nc]);\n    score += new_tree * 1000;\n    \n    // 2. Bridge potential\n    int bridge_potential = calculate_bridge_potential(empty_row, empty_col, tile);\n    score += bridge_potential;\n    \n    // 3. Connection potential at new position\n    int connection_potential = 0;\n    for (int d = 0; d < 4; d++) {\n        int nr2 = nr + dx[d];\n        int nc2 = nc + dy[d];\n        \n        if (nr2 < 0 || nr2 >= N || nc2 < 0 || nc2 >= N) continue;\n        if (board[nr2][nc2] == 0) continue;\n        \n        if (can_connect(tile, board[nr2][nc2], d)) {\n            connection_potential += 20;\n        } else if (has_line(tile, d) || has_line(board[nr2][nc2], (d + 2) % 4)) {\n            connection_potential += 5; // Partial connection\n        }\n    }\n    score += connection_potential;\n    \n    // 4. Strategic position bonus (center preferred for connectivity)\n    int center_distance = abs(nr - (N-1)/2) + abs(nc - (N-1)/2);\n    score += max(0, (N - center_distance) * 2);\n    \n    return score;\n}\n\nvoid iterative_deepening_search() {\n    auto start_time = chrono::high_resolution_clock::now();\n    \n    int best_tree = find_largest_tree();\n    int iterations_without_improvement = 0;\n    int phase = 0; // 0=exploration, 1=exploitation, 2=fine-tuning\n    \n    while (solution.size() < T) {\n        auto current_time = chrono::high_resolution_clock::now();\n        auto elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count();\n        if (elapsed > 2800) break;\n        \n        // Adaptive phase switching\n        if (iterations_without_improvement > 100) {\n            phase = (phase + 1) % 3;\n            iterations_without_improvement = 0;\n        }\n        \n        int best_score = -1000000;\n        vector<int> candidate_moves;\n        \n        // Evaluate all possible moves\n        for (int d = 0; d < 4; d++) {\n            int score;\n            \n            if (phase == 0) { // Exploration phase\n                score = evaluate_strategic_move(d) + (rng() % 100); // Add randomness\n            } else if (phase == 1) { // Exploitation phase\n                score = evaluate_strategic_move(d);\n            } else { // Fine-tuning phase\n                score = evaluate_strategic_move(d) + (rng() % 20); // Small randomness\n            }\n            \n            if (score > best_score) {\n                best_score = score;\n                candidate_moves.clear();\n                candidate_moves.push_back(d);\n            } else if (score == best_score) {\n                candidate_moves.push_back(d);\n            }\n        }\n        \n        if (!candidate_moves.empty()) {\n            // Random selection among best moves\n            int direction = candidate_moves[rng() % candidate_moves.size()];\n            make_move(direction);\n            \n            int new_tree = find_largest_tree();\n            if (new_tree > best_tree) {\n                best_tree = new_tree;\n                iterations_without_improvement = 0;\n            } else {\n                iterations_without_improvement++;\n            }\n            \n            if (best_tree == N * N - 1) break;\n        } else {\n            break;\n        }\n        \n        // Periodic random restart\n        if (iterations_without_improvement > 200 && solution.size() + 20 < T) {\n            for (int i = 0; i < 20; i++) {\n                int d = rng() % 4;\n                int nr = empty_row + dx[d];\n                int nc = empty_col + dy[d];\n                if (is_valid_move(nr, nc)) {\n                    make_move(d);\n                }\n            }\n            iterations_without_improvement = 0;\n        }\n    }\n}\n\nvoid advanced_multi_phase() {\n    auto start_time = chrono::high_resolution_clock::now();\n    \n    // Phase 1: Strategic component bridging\n    for (int i = 0; i < N && solution.size() < T * 0.3; i++) {\n        for (int j = 0; j < N && solution.size() < T * 0.3; j++) {\n            if (board[i][j] == 0) continue;\n            \n            // Prioritize positions that can bridge components\n            int bridge_potential = calculate_bridge_potential(i, j, board[i][j]);\n            if (bridge_potential > 50) {\n                // Try to move this tile to a strategic position\n                // This is simplified - in practice we'd plan a path\n            }\n        }\n    }\n    \n    // Phase 2: Iterative deepening optimization\n    iterative_deepening_search();\n    \n    // Phase 3: Final optimization with remaining moves\n    int final_tree = find_largest_tree();\n    while (solution.size() < T) {\n        auto current_time = chrono::high_resolution_clock::now();\n        auto elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count();\n        if (elapsed > 2950) break;\n        \n        bool improved = false;\n        for (int d = 0; d < 4; d++) {\n            int nr = empty_row + dx[d];\n            int nc = empty_col + dy[d];\n            \n            if (!is_valid_move(nr, nc)) continue;\n            \n            make_move(d);\n            int new_tree = find_largest_tree();\n            \n            if (new_tree >= final_tree) {\n                final_tree = new_tree;\n                improved = true;\n                break;\n            } else {\n                // Undo move\n                int opposite = (d + 2) % 4;\n                make_move(opposite);\n                solution.pop_back();\n                solution.pop_back();\n            }\n        }\n        \n        if (!improved) break;\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> T;\n    board.assign(N, vector<int>(N));\n    \n    for (int i = 0; i < N; i++) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < N; j++) {\n            char c = row[j];\n            if (c == '0') {\n                board[i][j] = 0;\n                empty_row = i;\n                empty_col = j;\n            } else if (c >= '1' && c <= '9') {\n                board[i][j] = c - '0';\n            } else {\n                board[i][j] = c - 'a' + 10;\n            }\n        }\n    }\n    \n    advanced_multi_phase();\n    \n    if (solution.size() > (size_t)T) {\n        solution = solution.substr(0, T);\n    }\n    \n    cout << solution << endl;\n    \n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\nusing int64 = long long;\nusing f64 = long double;\n\n/* ---------- geometry primitives ---------- */\nconst f64 EPS = 1e-9L;\ninline int sign(f64 x) { return (x > EPS) - (x < -EPS); }\n\nstruct Line {\n    f64 A, B, C;          // A x + B y + C = 0,  A\u00b2+B\u00b2=1\n    Line() = default;\n    Line(f64 a, f64 b, f64 c) : A(a), B(b), C(c) { norm(); }\n    // through (x1,y1)->(x2,y2)\n    Line(f64 x1, f64 y1, f64 x2, f64 y2) {\n        A = y2 - y1;\n        B = x1 - x2;\n        C = x2*y1 - x1*y2;\n        norm();\n    }\n    void norm() {\n        f64 s = sqrtl(A*A + B*B);\n        if (s > EPS) { A /= s; B /= s; C /= s; }\n    }\n    int side(f64 x, f64 y) const {\n        f64 v = A*x + B*y + C;\n        return sign(v);\n    }\n};\n\n/* ---------- global input ---------- */\nint N, K;\nvector<int> a(11);            // 1..10\nvector<f64> X, Y;\n\n/* ---------- current state ---------- */\nint kUsed = 0;                // lines used so far\nvector<Line> lines;\nusing Bits = bitset<100>;\nvector<Bits> regionCode;      // regionCode[r] = sign vector\nvector<int> regionCount;      // regionCount[r] = #strawberries inside\nunordered_map<uint64_t, int> regMap; // hash of sign vector -> index\n\nint have[11] = {};            // have[d] = #regions with d strawberries\nint objective = 0;\n\n/* ---------- evaluation ---------- */\nint eval() {\n    int obj = 0;\n    for (int d = 1; d <= 10; ++d) obj += min(a[d], have[d]);\n    return obj;\n}\n\n/* ---------- incremental add line ---------- */\nvoid addLine(const Line &L) {\n    if (kUsed == K) return;\n    int id = kUsed++;\n    lines[id] = L;\n\n    // re-index regions\n    unordered_map<uint64_t, int> newMap;\n    vector<Bits> newCode;\n    vector<int> newCount;\n    int newR = 0;\n\n    // helper: hash of bitset\n    auto hashBits = [&](const Bits &b) -> uint64_t {\n        return b._Get_hash(); // libstdc++ extension, fast\n    };\n\n    // split every existing region\n    for (int r = 0; r < (int)regionCode.size(); ++r) {\n        int cnt = regionCount[r];\n        if (cnt == 0) continue;\n\n        Bits oldSig = regionCode[r];\n        // count strawberries on each side\n        int cntP = 0, cntM = 0, cnt0 = 0;\n        // we need to know which strawberries belong to region r\n        // but we don't store per-region lists -> re-scan all points\n        // This is O(N) per region, but total regions <= 5051 and N<=1000 -> acceptable\n        Bits sigP = oldSig, sigM = oldSig;\n        sigP.set(id);        // +1 side\n        sigM.reset(id);      // -1 side\n\n        for (int i = 0; i < N; ++i) {\n            int s = L.side(X[i], Y[i]);\n            if (s == 0) { cnt0++; continue; }\n            if (s > 0) cntP++; else cntM++;\n        }\n        // two children\n        if (cntP > 0) {\n            uint64_t h = hashBits(sigP);\n            auto it = newMap.find(h);\n            if (it == newMap.end()) {\n                newMap[h] = newR;\n                newCode.push_back(sigP);\n                newCount.push_back(cntP);\n                ++newR;\n            } else {\n                newCount[it->second] += cntP;\n            }\n        }\n        if (cntM > 0) {\n            uint64_t h = hashBits(sigM);\n            auto it = newMap.find(h);\n            if (it == newMap.end()) {\n                newMap[h] = newR;\n                newCode.push_back(sigM);\n                newCount.push_back(cntM);\n                ++newR;\n            } else {\n                newCount[it->second] += cntM;\n            }\n        }\n        // strawberries on the line (cnt0) are lost\n    }\n\n    // rebuild global arrays\n    regMap.swap(newMap);\n    regionCode.swap(newCode);\n    regionCount.swap(newCount);\n\n    // rebuild have[] and objective\n    fill(have, have+11, 0);\n    for (int c : regionCount) if (c <= 10) have[c]++;\n    objective = eval();\n}\n\n/* ---------- greedy candidate generation ---------- */\nLine bestGreedyLine() {\n    static mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> distN(0, N-1);\n    uniform_int_distribution<int> distC(-100000, 100000);\n    uniform_real_distribution<f64> distA(0, M_PIl);\n\n    int bestGain = 0;\n    Line bestL;\n\n    auto tryLine = [&](const Line &L) {\n        // simulate addLine without really modifying state\n        unordered_map<uint64_t, int> tmpMap;\n        vector<int> tmpCount;\n        vector<Bits> tmpCode;\n        int tmpHave[11] = {};\n        int tmpObj = 0;\n\n        // copy current state\n        for (int r = 0; r < (int)regionCode.size(); ++r) {\n            int cnt = regionCount[r];\n            if (cnt == 0) continue;\n            int cntP = 0, cntM = 0;\n            Bits sigP = regionCode[r], sigM = regionCode[r];\n            sigP.set(kUsed);\n            sigM.reset(kUsed);\n            for (int i = 0; i < N; ++i) {\n                int s = L.side(X[i], Y[i]);\n                if (s == 0) continue;\n                if (s > 0) cntP++; else cntM++;\n            }\n            if (cntP > 0) {\n                tmpCount.push_back(cntP);\n                tmpCode.push_back(sigP);\n            }\n            if (cntM > 0) {\n                tmpCount.push_back(cntM);\n                tmpCode.push_back(sigM);\n            }\n        }\n        for (int c : tmpCount) if (c <= 10) tmpHave[c]++;\n        for (int d = 1; d <= 10; ++d) tmpObj += min(a[d], tmpHave[d]);\n        int gain = tmpObj - objective;\n        if (gain > bestGain) {\n            bestGain = gain;\n            bestL = L;\n        }\n    };\n\n    // try random point-pairs\n    const int TRIES = 400;\n    for (int t = 0; t < TRIES; ++t) {\n        int i = distN(rng), j = distN(rng);\n        if (i == j) continue;\n        Line L(X[i], Y[i], X[j], Y[j]);\n        tryLine(L);\n    }\n    // try random directions through random points\n    for (int t = 0; t < TRIES; ++t) {\n        int i = distN(rng);\n        f64 ang = distA(rng);\n        f64 dx = cosl(ang), dy = sinl(ang);\n        Line L(X[i], Y[i], X[i] + dx, Y[i] + dy);\n        tryLine(L);\n    }\n    // try a few axis-aligned\n    for (int t = 0; t < 20; ++t) {\n        f64 x = distC(rng) * 1000;\n        Line L(1, 0, -x);\n        tryLine(L);\n        Line L2(0, 1, -x);\n        tryLine(L2);\n    }\n    return bestL;\n}\n\n/* ---------- main ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    auto clk_start = chrono::steady_clock::now();\n\n    cin >> N >> K;\n    for (int d = 1; d <= 10; ++d) cin >> a[d];\n    X.resize(N); Y.resize(N);\n    for (int i = 0; i < N; ++i) cin >> X[i] >> Y[i];\n\n    // initial state: 1 region\n    lines.assign(K, Line());\n    regionCode.clear();\n    regionCount.clear();\n    regMap.clear();\n    Bits initialSig;\n    initialSig.reset();\n    regionCode.push_back(initialSig);\n    regionCount.push_back(N);\n    regMap[initialSig._Get_hash()] = 0;\n    fill(have, have+11, 0);\n    have[min(N, 10)] = 1;\n    objective = eval();\n\n    // iterated greedy + local search\n    int bestEver = objective;\n    vector<Line> bestLines;\n    int bestK = 0;\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - clk_start).count();\n        if (elapsed > 2.85) break;\n\n        // greedy addition pass\n        while (kUsed < K) {\n            Line L = bestGreedyLine();\n            if (objective >= bestEver) {\n                bestEver = objective;\n                bestLines = vector<Line>(lines.begin(), lines.begin() + kUsed);\n                bestK = kUsed;\n            }\n            addLine(L);\n        }\n\n        // local perturbation: delete last 5 and re-add greedily\n        if (kUsed >= 5) {\n            for (int del = 0; del < 5; ++del) {\n                // remove last line\n                kUsed--;\n                // rebuild entire state from scratch (simplest)\n                regionCode.clear();\n                regionCount.clear();\n                regMap.clear();\n                Bits init;\n                init.reset();\n                regionCode.push_back(init);\n                regionCount.push_back(0);\n                regMap[init._Get_hash()] = 0;\n                // recount\n                fill(have, have+11, 0);\n                for (int i = 0; i < N; ++i) {\n                    Bits sig;\n                    sig.reset();\n                    for (int j = 0; j < kUsed; ++j) {\n                        int s = lines[j].side(X[i], Y[i]);\n                        if (s > 0) sig.set(j);\n                    }\n                    uint64_t h = sig._Get_hash();\n                    auto it = regMap.find(h);\n                    int r;\n                    if (it == regMap.end()) {\n                        r = regionCode.size();\n                        regMap[h] = r;\n                        regionCode.push_back(sig);\n                        regionCount.push_back(0);\n                    } else {\n                        r = it->second;\n                    }\n                    regionCount[r]++;\n                }\n                fill(have, have+11, 0);\n                for (int c : regionCount) if (c <= 10) have[c]++;\n                objective = eval();\n            }\n        }\n    }\n\n    // output best\n    cout << bestK << '\\n';\n    cout << fixed << setprecision(0);\n    for (int i = 0; i < bestK; ++i) {\n        // pick two integer points on the line\n        f64 A = bestLines[i].A, B = bestLines[i].B, C = bestLines[i].C;\n        // choose x1,y1,x2,y2 integers\n        int64_t x1, y1, x2, y2;\n        if (fabs(B) > EPS) {\n            x1 = 0;\n            y1 = llround(-C / B);\n            x2 = 1;\n            y2 = llround((-C - A) / B);\n        } else {\n            y1 = 0;\n            x1 = llround(-C / A);\n            y2 = 1;\n            x2 = llround((-C) / A);\n        }\n        cout << x1 << ' ' << y1 << ' ' << x2 << ' ' << y2 << '\\n';\n    }\n    return 0;\n}","ahc014":"#pragma GCC target(\"avx2\")\n#pragma GCC optimize(\"O3\")\n#pragma GCC optimize(\"unroll-loops\")\n#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing ll = long long;\n#define rep(i, n) for (int i = 0; i < (int)(n); i++)\n\n// ---------- \u8fba\u306e\u7b26\u53f7\u5316 ----------\ninline uint64_t ecode(int x1, int y1, int x2, int y2) {\n    if (x1 > x2 || (x1 == x2 && y1 > y2)) {\n        swap(x1, x2); swap(y1, y2);\n    }\n    return ((uint64_t)(uint16_t)x1 << 48) | ((uint64_t)(uint16_t)y1 << 32) |\n           ((uint64_t)(uint16_t)x2 << 16) | (uint64_t)(uint16_t)y2;\n}\n\n// ---------- \u30b0\u30ed\u30fc\u30d0\u30eb ----------\nint N, M;\nint c;\nvector<vector<int>> w;               // \u91cd\u307f\nvector<vector<bool>> dot;            // dot[x][y]\nstd::unordered_set<uint64_t> used_edge;   // \u4fee\u6b63\uff1astd \u3092\u4f7f\u3046\nvector<tuple<int,int,int,int,int,int,int,int>> ops;  // \u64cd\u4f5c\u5c65\u6b74\n\n// ---------- \u65b9\u5411 ----------\nconst int dx45[4] = {1, 1, -1, -1};\nconst int dy45[4] = {1, -1, -1, 1};\nconst int dxax[4] = {1, 0, -1, 0};\nconst int dyax[4] = {0, 1, 0, -1};\n\n// ---------- \u77e9\u5f62\u3092\u8a66\u3059 ----------\nbool try_rect(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    // 4\u9802\u70b9\u306e\u9806\u5e8f\u3092\u6b63\u3057\u304f\u56de\u3057\u3001p1=(x1,y1) \u304c\u7a7a\u3001\u4ed6\u304c dot \u3067\u3042\u308b\u3053\u3068\n    if (!dot[x2][y2] || !dot[x3][y3] || !dot[x4][y4]) return false;\n    if (dot[x1][y1]) return false;\n    // 4\u8fba\u306e\u7b26\u53f7\u5316\n    uint64_t e1 = ecode(x1,y1,x2,y2);\n    uint64_t e2 = ecode(x2,y2,x3,y3);\n    uint64_t e3 = ecode(x3,y3,x4,y4);\n    uint64_t e4 = ecode(x4,y4,x1,y1);\n    if (used_edge.count(e1) || used_edge.count(e2) ||\n        used_edge.count(e3) || used_edge.count(e4)) return false;\n    // \u8fba\u4e0a\u306b\u4ed6\u30c9\u30c3\u30c8\u304c\u306a\u3044\u304b\uff08\u7c21\u6613\uff1agcd \u3067\u7b49\u5206\u70b9\u30c1\u30a7\u30c3\u30af\uff09\n    auto check_edge = [&](int ax, int ay, int bx, int by) {\n        int dx = bx - ax, dy = by - ay;\n        int g = gcd(abs(dx), abs(dy));\n        int stepx = dx / g, stepy = dy / g;\n        for (int t = 1; t < g; t++) {\n            int xx = ax + t * stepx, yy = ay + t * stepy;\n            if (dot[xx][yy]) return false;\n        }\n        return true;\n    };\n    if (!check_edge(x1,y1,x2,y2)) return false;\n    if (!check_edge(x2,y2,x3,y3)) return false;\n    if (!check_edge(x3,y3,x4,y4)) return false;\n    if (!check_edge(x4,y4,x1,y1)) return false;\n    // \u5b9f\u884c\n    dot[x1][y1] = true;\n    used_edge.insert(e1);\n    used_edge.insert(e2);\n    used_edge.insert(e3);\n    used_edge.insert(e4);\n    ops.emplace_back(x1,y1,x2,y2,x3,y3,x4,y4);\n    return true;\n}\n\n// ---------- \u30e1\u30a4\u30f3 ----------\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    auto clk_st = chrono::steady_clock::now();\n\n    cin >> N >> M;\n    c = (N - 1) / 2;\n    w.assign(N, vector<int>(N));\n    dot.assign(N, vector<bool>(N, false));\n    ll S = 0;\n    rep(x,N) rep(y,N) {\n        int wx = (x - c) * (x - c) + (y - c) * (y - c) + 1;\n        w[x][y] = wx;\n        S += wx;\n    }\n    rep(i,M){\n        int x,y; cin >> x >> y;\n        dot[x][y] = true;\n    }\n\n    // \u9ad8\u91cd\u307f\u9806\u306b\u7a7a\u30de\u30b9\u3092\u62fe\u3046\u305f\u3081\u306e\u30ea\u30b9\u30c8\n    vector<pair<int,int>> cells;\n    rep(x,N) rep(y,N) if (!dot[x][y]) cells.emplace_back(x,y);\n    // \u91cd\u307f\u5927\u304d\u3044\u9806\u306b\u30bd\u30fc\u30c8\n    sort(cells.begin(), cells.end(), [&](auto &a, auto &b){\n        return w[a.first][a.second] > w[b.first][b.second];\n    });\n\n    // \u8caa\u6b32\u30e1\u30a4\u30f3\n    const double TIME_LIMIT = 4.8;\n    int iter = 0, total = cells.size();\n    while (1) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - clk_st).count();\n        if (elapsed > TIME_LIMIT) break;\n\n        // \u30e9\u30f3\u30c0\u30e0\u306b\u30d0\u30c3\u30c1\u3092\u62fe\u3046\uff08\u91cd\u3044\u9806\u306b\u3057\u3064\u3064\u30e9\u30f3\u30c0\u30e0\u30cd\u30b9\uff09\n        int batch = min(500, total);\n        vector<int> idx(batch);\n        rep(i,batch) idx[i] = (iter + i) % total;\n        shuffle(idx.begin(), idx.end(), mt19937(iter));\n\n        bool progress = false;\n        for (int i : idx) {\n            auto [x1,y1] = cells[i];\n            if (dot[x1][y1]) continue;\n            // \u8ef8\u5e73\u884c\u9577\u65b9\u5f62\u30924\u65b9\u5411\n            for (int d = 0; d < 4; d++) {\n                int len = 1;\n                while (1) {\n                    int x2 = x1 + len * dxax[d], y2 = y1 + len * dyax[d];\n                    int x3 = x2 + len * dxax[(d+1)&3], y3 = y2 + len * dyax[(d+1)&3];\n                    int x4 = x1 + len * dxax[(d+1)&3], y4 = y1 + len * dyax[(d+1)&3];\n                    if (x2<0||x2>=N||y2<0||y2>=N) break;\n                    if (x3<0||x3>=N||y3<0||y3>=N) break;\n                    if (x4<0||x4>=N||y4<0||y4>=N) break;\n                    if (try_rect(x1,y1,x2,y2,x3,y3,x4,y4)) { progress=true; goto NEXT; }\n                    len++;\n                }\n            }\n            // 45\u00b0\u9577\u65b9\u5f62\u30924\u65b9\u5411\n            for (int d = 0; d < 4; d++) {\n                int len = 1;\n                while (1) {\n                    int x2 = x1 + len * dx45[d], y2 = y1 + len * dy45[d];\n                    int x3 = x2 + len * dx45[(d+1)&3], y3 = y2 + len * dy45[(d+1)&3];\n                    int x4 = x1 + len * dx45[(d+1)&3], y4 = y1 + len * dy45[(d+1)&3];\n                    if (x2<0||x2>=N||y2<0||y2>=N) break;\n                    if (x3<0||x3>=N||y3<0||y3>=N) break;\n                    if (x4<0||x4>=N||y4<0||y4>=N) break;\n                    if (try_rect(x1,y1,x2,y2,x3,y3,x4,y4)) { progress=true; goto NEXT; }\n                    len++;\n                }\n            }\n        }\n        NEXT:\n        iter += batch;\n        if (!progress) break;\n    }\n\n    // \u51fa\u529b\n    cout << ops.size() << \"\\n\";\n    for (auto &[x1,y1,x2,y2,x3,y3,x4,y4] : ops) {\n        cout << x1 << \" \" << y1 << \" \"\n             << x2 << \" \" << y2 << \" \"\n             << x3 << \" \" << y3 << \" \"\n             << x4 << \" \" << y4 << \"\\n\";\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\nusing namespace std::chrono;\n\nconstexpr int H = 10, W = 10, N = 100, C = 3;\nint flavour[N];\nchar dc[4] = {'F','B','L','R'};\n\nmt19937_64 rng(123456789);\n\n/* ---------- bit-packed column-wise board ---------- */\nstruct Grid {\n    uint64_t col[W];\n    Grid(){ memset(col,0,sizeof(col)); }\n    int get(int r,int c) const { return (col[c]>>(r*2))&3ULL; }\n    void set(int r,int c,int v){\n        col[c] &= ~(3ULL<<(r*2));\n        col[c] |= uint64_t(v)<<(r*2);\n    }\n    bool empty(int r,int c) const { return get(r,c)==0; }\n};\n\ninline void gravity(Grid& g,int d){\n    if(d==0){\n        for(int c=0;c<W;c++){\n            uint64_t m = g.col[c];\n            uint64_t occ = 0;\n            for(int r=0;r<H;r++) occ |= (m>>(r*2)&3) ? (1ULL<<r) : 0;\n            int ones = __builtin_popcountll(occ);\n            uint64_t newm = 0;\n            int wr = H-ones;\n            for(int r=0;r<H;r++){\n                int v = (m>>(r*2))&3;\n                if(v){ newm |= uint64_t(v)<<((wr++)*2); }\n            }\n            g.col[c] = newm;\n        }\n    }else if(d==1){\n        for(int c=0;c<W;c++){\n            uint64_t m = g.col[c];\n            uint64_t occ = 0;\n            for(int r=0;r<H;r++) occ |= (m>>(r*2)&3) ? (1ULL<<r) : 0;\n            int ones = __builtin_popcountll(occ);\n            uint64_t newm = 0;\n            int wr = 0;\n            for(int r=0;r<H;r++){\n                int v = (m>>(r*2))&3;\n                if(v){ newm |= uint64_t(v)<<((wr++)*2); }\n            }\n            g.col[c] = newm;\n        }\n    }else if(d==2){\n        Grid ng;\n        for(int r=0;r<H;r++){\n            int w=0;\n            for(int c=0;c<W;c++){\n                int v = g.get(r,c);\n                if(v){ ng.set(r,w,v); w++; }\n            }\n        }\n        g = ng;\n    }else{\n        Grid ng;\n        for(int r=0;r<H;r++){\n            int w=W-1;\n            for(int c=W-1;c>=0;c--){\n                int v = g.get(r,c);\n                if(v){ ng.set(r,w,v); w--; }\n            }\n        }\n        g = ng;\n    }\n}\n\nint evalScore(const Grid& g){\n    static int id[H][W], sz[N], p[N];\n    iota(p,p+N,0);\n    function<int(int)> root=[&](int x){ return p[x]==x?x:p[x]=root(p[x]); };\n    auto unite=[&](int x,int y){ x=root(x); y=root(y); if(x!=y){ if(sz[x]<sz[y]) swap(x,y); p[y]=x; sz[x]+=sz[y]; }};\n\n    memset(id,-1,sizeof(id));\n    int comp = 0;\n    for(int r=0;r<H;r++)for(int c=0;c<W;c++){\n        int v = g.get(r,c);\n        if(v){ id[r][c]=comp; sz[comp]=1; comp++; }\n    }\n    const int dr[4]={-1,1,0,0}, dc[4]={0,0,-1,1};\n    for(int r=0;r<H;r++)for(int c=0;c<W;c++){\n        int v = g.get(r,c);\n        if(!v) continue;\n        for(int d=0;d<4;d++){\n            int nr=r+dr[d], nc=c+dc[d];\n            if(nr<0||nr>=H||nc<0||nc>=W) continue;\n            if(g.get(nr,nc)==v) unite(id[r][c], id[nr][nc]);\n        }\n    }\n    int sum = 0;\n    for(int i=0;i<comp;i++) if(root(i)==i) sum += sz[i]*sz[i];\n    return sum;\n}\n\n/* ---------- importance-sampled roll-out ---------- */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    for(int i=0;i<N;i++){ cin>>flavour[i]; flavour[i]--; }\n\n    Grid base;\n    for(int t=0;t<N;t++){\n        int p; cin>>p; p--;\n        int cnt=0, rr=-1,cc=-1;\n        for(int i=0;i<H*W;i++){\n            int r=i/W, c=i%W;\n            if(base.empty(r,c)){\n                if(cnt==p){ rr=r; cc=c; break; }\n                cnt++;\n            }\n        }\n        base.set(rr,cc,flavour[t]+1);\n\n        int bestDir = 0, bestSum = -1;\n        auto deadline = steady_clock::now() + milliseconds(15);\n        int scores[4]={0,0,0,0}, tries[4]={0,0,0,0};\n\n        while(steady_clock::now() < deadline){\n            for(int cand=0;cand<4;cand++){\n                if(tries[cand]<0) continue;  // dead\n                Grid g = base;\n                gravity(g, cand);\n                /* build importance vector for this cand */\n                int targetCol = flavour[t]+1;\n                vector<int> prefPos;\n                /* largest same-col wall */\n                int bestC = -1, bestH = 0;\n                for(int c=0;c<W;c++){\n                    int h = 0;\n                    for(int r=H-1;r>=0;r--){\n                        if(g.get(r,c)==targetCol) h++;\n                        else break;\n                    }\n                    if(h>bestH){ bestH=h; bestC=c; }\n                }\n                if(bestC>=0){\n                    for(int r=0;r<H;r++) if(g.empty(r,bestC)) prefPos.push_back(r*W+bestC);\n                }\n                /* roll the future */\n                for(int u=t+1;u<N;u++){\n                    int pp;\n                    if(!prefPos.empty() && bernoulli_distribution(0.5)(rng)){\n                        uniform_int_distribution<int> U(0,(int)prefPos.size()-1);\n                        pp = prefPos[U(rng)];\n                    }else{\n                        vector<int> all;\n                        for(int i=0;i<H*W;i++) if(g.empty(i/W,i%W)) all.push_back(i);\n                        if(all.empty()) break;\n                        uniform_int_distribution<int> U(0,(int)all.size()-1);\n                        pp = all[U(rng)];\n                    }\n                    int r=pp/W, c=pp%W;\n                    g.set(r,c,flavour[u]+1);\n                    gravity(g, uniform_int_distribution<int>(0,3)(rng));\n                    /* rebuild prefPos for next step */\n                    prefPos.clear();\n                    bestC=-1; bestH=0;\n                    for(int cc=0;cc<W;cc++){\n                        int h=0;\n                        for(int rr=H-1;rr>=0;rr--){\n                            if(g.get(rr,cc)==targetCol) h++;\n                            else break;\n                        }\n                        if(h>bestH){ bestH=h; bestC=cc; }\n                    }\n                    if(bestC>=0){\n                        prefPos.clear();\n                        for(int rr=0;rr<H;rr++) if(g.empty(rr,bestC)) prefPos.push_back(rr*W+bestC);\n                    }\n                }\n                int sc = evalScore(g);\n                scores[cand] += sc;\n                tries[cand]++;\n                /* early kill */\n                if(tries[cand]>=50){\n                    double avg = double(scores[cand])/tries[cand];\n                    bool hopeless = false;\n                    for(int o=0;o<4;o++) if(o!=cand && tries[o]>=50){\n                        double avgo = double(scores[o])/tries[o];\n                        if(avgo - avg > 300){ hopeless=true; break; }\n                    }\n                    if(hopeless) tries[cand] = -1;\n                }\n            }\n        }\n        for(int cand=0;cand<4;cand++){\n            if(tries[cand]<=0) continue;\n            double avg = double(scores[cand])/tries[cand];\n            if(int(avg) > bestSum){ bestSum=int(avg); bestDir=cand; }\n        }\n        gravity(base, bestDir);\n        cout << dc[bestDir] << '\\n';\n        cout.flush();\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\n// ---------------  \u57fa\u672c\u8a2d\u5b9a  ----------------\nint M; \ndouble eps;\nconst int MAX_N = 100;\nint N;                       // \u5b9f\u969b\u306b\u9078\u3076\u9802\u70b9\u6570\nint MAX_EDGES;               // N*(N-1)/2\n\n// \u5404 G_k \u306e\u8fba\u96c6\u5408\uff08bitmask \u3067\u3082 vector<bitset<>> \u3067\u3082\u53ef\uff09\n// \u3053\u3053\u3067\u306f\u96a3\u63a5\u884c\u5217\u3092 vector<bitset<MAX_N>> \u3067\u6301\u3064\nvector<bitset<MAX_N>> G[MAX_N*MAX_N]; // G[k][i][j] = 1 \u306a\u3089\u8fba (i,j) \u5b58\u5728\n\n// \u5404 G_k \u306e\u300c\u8fba\u6570\u300d\u304a\u3088\u3073\u300c\u6b21\u6570\u5217\uff08\u30bd\u30fc\u30c8\u6e08\u307f\uff09\u300d\nvector<int> target_edges;   // target_edges[k]\nvector<vector<int>> deg_seq; // deg_seq[k] : \u9577\u3055 N\u3001\u30bd\u30fc\u30c8\u6e08\u307f\n\n// --------------  \u4e8b\u524d\u8a08\u7b97\uff08Binomial \u5bfe\u6570\uff09 --------------\nconst int MAX_BINOM = MAX_N*MAX_N;\ndouble logfact[MAX_BINOM+1];\nvoid init_logfact(){\n    logfact[0] = 0.0;\n    for(int i=1;i<=MAX_BINOM;i++){\n        logfact[i] = logfact[i-1] + log(i);\n    }\n}\ninline double logbinom(int n, int k){\n    if(k<0||k>n) return -1e300;\n    return logfact[n] - logfact[k] - logfact[n-k];\n}\n\n// --------------  \u30b0\u30e9\u30d5\u51fa\u529b\u7528\u30a8\u30f3\u30b3\u30fc\u30c0 -----------------\nstring encode_graph(const vector<bitset<MAX_N>>& adj){\n    string s;\n    for(int i=0;i<N;i++){\n        for(int j=i+1;j<N;j++){\n            s += (adj[i][j] ? '1':'0');\n        }\n    }\n    return s;\n}\n\n// --------------  \u30e9\u30f3\u30c0\u30e0\u8fba\u751f\u6210 ------------------------\nvoid build_random_graph(vector<bitset<MAX_N>>& adj, int m){\n    adj.assign(N, bitset<MAX_N>());\n    int total = N*(N-1)/2;\n    vector<int> idx(total);\n    iota(idx.begin(), idx.end(), 0);\n    shuffle(idx.begin(), idx.end(), mt19937(12345));\n    for(int t=0;t<m;t++){\n        int e = idx[t];\n        int i = 0, j = 1;\n        // e \u756a\u76ee\u306e (i,j) (i<j) \u3092\u5fa9\u5143\n        int cnt = 0;\n        for(i=0;i<N;i++){\n            for(j=i+1;j<N;j++){\n                if(cnt==e) goto found;\n                cnt++;\n            }\n        }\n        found:\n        adj[i][j] = adj[j][i] = 1;\n    }\n}\n\n// --------------  \u6b21\u6570\u5217\u53d6\u5f97 --------------------------\nvector<int> get_degree_sequence(const vector<bitset<MAX_N>>& adj){\n    vector<int> deg(N);\n    for(int i=0;i<N;i++){\n        deg[i] = adj[i].count();\n    }\n    sort(deg.rbegin(), deg.rend());\n    return deg;\n}\n\n// --------------  \u5bfe\u6570\u5c24\u5ea6\u8fd1\u4f3c ------------------------\n// \u8fba\u6570 m \u306e\u307f\u3092\u898b\u308b\u7c21\u6613\u7248\ndouble loglikelihood_edge(int m, int k){\n    int total = N*(N-1)/2;\n    double p = (double)target_edges[k] / total;\n    // \u53cd\u8ee2\u5f8c\u306e\u671f\u5f85\u8fba\u6570\n    double mu = target_edges[k]*(1 - 2*eps) + eps*total;\n    double sigma2 = eps*(1 - eps)*total;\n    // \u6b63\u898f\u8fd1\u4f3c\n    double diff = m - mu;\n    return -0.5 * diff*diff / sigma2;\n}\n\n// --------------  \u30e1\u30a4\u30f3 --------------------------------\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // \u5165\u529b\n    cin >> M >> eps;\n\n    // N \u3092\u6c7a\u5b9a\uff08\u5c0f\u3055\u3044\u307b\u3046\u304c\u30b9\u30b3\u30a2\u500d\u7387\u304c\u9ad8\u3044\u304c\u3001\u8b58\u5225\u80fd\u529b\u304c\u843d\u3061\u308b\uff09\n    // \u3068\u308a\u3042\u3048\u305a N=20 \u3067\u56fa\u5b9a\n    N = 20;\n    MAX_EDGES = N*(N-1)/2;\n\n    // \u5bfe\u6570factorial \u521d\u671f\u5316\n    init_logfact();\n\n    // \u5404 G_k \u306e\u300c\u76ee\u6a19\u8fba\u6570\u300d\u3092\u7b49\u9593\u9694\u306b\n    target_edges.resize(M);\n    double step = (double)MAX_EDGES / (M-1);\n    for(int k=0;k<M;k++){\n        target_edges[k] = (int)round( k * step );\n    }\n\n    // \u5404 G_k \u3092\u751f\u6210 & \u6b21\u6570\u5217\u8a08\u7b97\n    for(int k=0;k<M;k++){\n        build_random_graph(G[k], target_edges[k]);\n        deg_seq.emplace_back( get_degree_sequence(G[k]) );\n    }\n\n    // \u51fa\u529b\n    cout << N << \"\\n\";\n    for(int k=0;k<M;k++){\n        cout << encode_graph(G[k]) << \"\\n\";\n    }\n    cout.flush();\n\n    // \u30af\u30a8\u30ea\u51e6\u7406\n    for(int q=0;q<100;q++){\n        string Hstr;\n        cin >> Hstr;\n        // H \u3092\u96a3\u63a5\u884c\u5217\u306b\n        vector<bitset<MAX_N>> H(N);\n        int ptr = 0;\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                if(Hstr[ptr++]=='1'){\n                    H[i][j] = H[j][i] = 1;\n                }\n            }\n        }\n        // \u8fba\u6570\n        int m = 0;\n        for(int i=0;i<N;i++) m += H[i].count();\n        m /= 2;\n\n        // \u5404 k \u306b\u3064\u3044\u3066\u5bfe\u6570\u5c24\u5ea6\uff08\u8fba\u6570\u306e\u307f\uff09\u3092\u8a08\u7b97\n        int best_k = 0;\n        double best_ll = -1e300;\n        for(int k=0;k<M;k++){\n            double ll = loglikelihood_edge(m, k);\n            if(ll > best_ll){\n                best_ll = ll;\n                best_k = k;\n            }\n        }\n        cout << best_k << \"\\n\";\n        cout.flush();\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 1005;\nconst int MAX_M = 3005;\n\nint N, M, D, K;\nint u[MAX_M], v[MAX_M], w[MAX_M];\nint x[MAX_N], y[MAX_N];\nint assignment[MAX_M];\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> D >> K;\n    \n    for (int i = 0; i < M; i++) {\n        cin >> u[i] >> v[i] >> w[i];\n        u[i]--; v[i]--;\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n    \n    // Calculate maximum edges per day\n    int max_per_day = K;\n    \n    // Strategy: Use spatial partitioning to minimize local impact\n    // Group edges by spatial regions and distribute across days\n    \n    // Create spatial groups\n    vector<pair<int, int>> edge_regions(M);\n    for (int i = 0; i < M; i++) {\n        // Use midpoint to determine region\n        int mid_x = (x[u[i]] + x[v[i]]) / 2;\n        int mid_y = (y[u[i]] + y[v[i]]) / 2;\n        \n        // Create region index (simple grid-based)\n        int region_x = mid_x / 200;  // Divide 1000x1000 into ~5x5 regions\n        int region_y = mid_y / 200;\n        int region = region_x * 5 + region_y;\n        \n        edge_regions[i] = {region, i};\n    }\n    \n    // Sort by region for spatial grouping\n    sort(edge_regions.begin(), edge_regions.end());\n    \n    // Assign edges to days with strict K constraint\n    vector<int> day_count(D + 1, 0);\n    \n    // Process regions in order, but distribute within each region\n    int current_region = -1;\n    int region_start = 0;\n    \n    for (int i = 0; i < M; i++) {\n        int region = edge_regions[i].first;\n        int e = edge_regions[i].second;\n        \n        if (region != current_region) {\n            current_region = region;\n            region_start = i;\n        }\n        \n        // Within each region, distribute across days to spread impact\n        int region_offset = i - region_start;\n        int base_day = (region_offset % D) + 1;\n        \n        // Find the best day with available capacity\n        int best_day = -1;\n        int min_load = max_per_day + 1;\n        \n        // Check days in order, starting from base_day\n        for (int offset = 0; offset < D; offset++) {\n            int try_day = ((base_day + offset - 1) % D) + 1;\n            if (day_count[try_day] < max_per_day && day_count[try_day] < min_load) {\n                min_load = day_count[try_day];\n                best_day = try_day;\n            }\n        }\n        \n        // Fallback: find any day with capacity\n        if (best_day == -1) {\n            for (int day = 1; day <= D; day++) {\n                if (day_count[day] < max_per_day) {\n                    best_day = day;\n                    break;\n                }\n            }\n        }\n        \n        assignment[e] = best_day;\n        day_count[best_day]++;\n    }\n    \n    // Verify constraint satisfaction\n    bool valid = true;\n    for (int day = 1; day <= D; day++) {\n        if (day_count[day] > max_per_day) {\n            valid = false;\n            break;\n        }\n    }\n    \n    // If spatial approach failed, use simple round-robin with constraint\n    if (!valid) {\n        fill(assignment, assignment + M, 0);\n        fill(day_count.begin(), day_count.end(), 0);\n        \n        for (int i = 0; i < M; i++) {\n            // Find day with minimum load that has capacity\n            int best_day = 1;\n            for (int day = 2; day <= D; day++) {\n                if (day_count[day] < day_count[best_day] && day_count[day] < max_per_day) {\n                    best_day = day;\n                }\n            }\n            \n            assignment[i] = best_day;\n            day_count[best_day]++;\n        }\n    }\n    \n    // Output the assignment\n    for (int i = 0; i < M; i++) {\n        cout << assignment[i] << (i == M - 1 ? \"\\n\" : \" \");\n    }\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nusing ull = unsigned long long;\nusing int2 = __int128_t;\n\nstatic constexpr int MAXD = 14;\nstatic constexpr int MAXV = 16;               // max volume of generated blocks\nstatic constexpr int MAXB = 40000;            // max number of generated blocks\nstatic constexpr double TIME_LIMIT = 5.8;\n\nint D, DD, DDD;\nbitset<MAXD*MAXD*MAXD> mandatory[2], sharedMandatory;\nint mandatoryVol[2], sharedVol;\n\nstruct Block {\n    int vol;\n    vector<tuple<int,int,int>> cells;   // original coordinates\n    vector<vector<tuple<int,int,int>>> rot; // 24 rotations\n};\nint nBlocks = 0;\nBlock blocks[MAXB];\n\n// ---------- utilities ----------\ninline int idx(int x, int y, int z) { return x*D*D + y*D + z; }\ninline bool inside(int x, int y, int z) {\n    return 0 <= x && x < D && 0 <= y && y < D && 0 <= z && z < D;\n}\n\n// ---------- rotation ----------\nvector<vector<tuple<int,int,int>>> generateRotations(const vector<tuple<int,int,int>>& src) {\n    vector<vector<tuple<int,int,int>>> res;\n    set<vector<tuple<int,int,int>>> seen;\n    for (int rx = 0; rx < 4; ++rx)\n    for (int ry = 0; ry < 4; ++ry)\n    for (int rz = 0; rz < 4; ++rz) {\n        vector<tuple<int,int,int>> tmp;\n        for (auto [x,y,z] : src) {\n            int cx = x, cy = y, cz = z;\n            // rotate around X\n            for (int k = 0; k < rx; ++k) {\n                int ny = -cz, nz = cy;\n                cy = ny; cz = nz;\n            }\n            // rotate around Y\n            for (int k = 0; k < ry; ++k) {\n                int nx = cz, nz = -cx;\n                cx = nx; cz = nz;\n            }\n            // rotate around Z\n            for (int k = 0; k < rz; ++k) {\n                int nx = -cy, ny = cx;\n                cx = nx; cy = ny;\n            }\n            tmp.emplace_back(cx, cy, cz);\n        }\n        // normalize\n        int minx=INT_MAX, miny=INT_MAX, minz=INT_MAX;\n        for (auto [x,y,z] : tmp) {\n            minx = min(minx, x); miny = min(miny, y); minz = min(minz, z);\n        }\n        for (auto& [x,y,z] : tmp) {\n            x -= minx; y -= miny; z -= minz;\n        }\n        sort(tmp.begin(), tmp.end());\n        if (seen.insert(tmp).second) res.push_back(tmp);\n    }\n    return res;\n}\n\n// ---------- polycube generation ----------\nvoid generateBlocks() {\n    // BFS enumeration of all free polycubes up to volume MAXV\n    map<vector<tuple<int,int,int>>, int> canonicalId;\n    queue<pair<vector<tuple<int,int,int>>, int>> q;\n    q.push({{{0,0,0}}, 1});\n    canonicalId[{{{0,0,0}}}] = 1;\n    int dx[] = {1,-1,0,0,0,0}, dy[] = {0,0,1,-1,0,0}, dz[] = {0,0,0,0,1,-1};\n    while (!q.empty() && nBlocks < MAXB) {\n        auto [shape, vol] = q.front(); q.pop();\n        if (vol > MAXV) continue;\n        // store this shape\n        {\n            Block& B = blocks[nBlocks++];\n            B.vol = vol;\n            B.cells = shape;\n            B.rot = generateRotations(shape);\n        }\n        // expand\n        set<tuple<int,int,int>> frontier;\n        for (auto [x,y,z] : shape)\n        for (int d = 0; d < 6; ++d) {\n            int nx = x+dx[d], ny = y+dy[d], nz = z+dz[d];\n            if (!inside(nx,ny,nz)) continue;\n            if (find(shape.begin(), shape.end(), make_tuple(nx,ny,nz)) != shape.end()) continue;\n            frontier.emplace(nx,ny,nz);\n        }\n        for (auto [x,y,z] : frontier) {\n            auto ns = shape;\n            ns.emplace_back(x,y,z);\n            // normalize\n            int minx=INT_MAX,miny=INT_MAX,minz=INT_MAX;\n            for (auto [xx,yy,zz] : ns) {\n                minx=min(minx,xx); miny=min(miny,yy); minz=min(minz,zz);\n            }\n            for (auto& [xx,yy,zz] : ns) {\n                xx-=minx; yy-=miny; zz-=minz;\n            }\n            sort(ns.begin(), ns.end());\n            if (canonicalId.count(ns)) continue;\n            canonicalId[ns] = 1;\n            q.push({ns, vol+1});\n        }\n    }\n    cerr << \"generated \" << nBlocks << \" blocks up to volume \" << MAXV << \"\\n\";\n}\n\n// ---------- placement ----------\nstruct Placement {\n    bitset<MAXD*MAXD*MAXD> occ;\n    int usedVol;\n    vector<int> blockIds;\n    vector<vector<tuple<int,int,int>>> poses; // for each block, its rotated+translated cells\n};\nPlacement bestP[2];\ndouble bestScore = 1e18;\n\n// try to place block B with rotation r at (bx,by,bz) into grid g\nbool canPlace(const bitset<MAXD*MAXD*MAXD>& g, const Block& B, int r, int bx, int by, int bz) {\n    for (auto [x,y,z] : B.rot[r]) {\n        int xx = x+bx, yy = y+by, zz = z+bz;\n        if (!inside(xx,yy,zz)) return false;\n        if (g.test(idx(xx,yy,zz))) return false;\n    }\n    return true;\n}\nvoid place(bitset<MAXD*MAXD*MAXD>& g, const Block& B, int r, int bx, int by, int bz) {\n    for (auto [x,y,z] : B.rot[r]) {\n        int xx = x+bx, yy = y+by, zz = z+bz;\n        g.set(idx(xx,yy,zz));\n    }\n}\n\n// greedy cover for one silhouette\nPlacement greedyCover(const bitset<MAXD*MAXD*MAXD>& target, int which) {\n    Placement P;\n    P.occ.reset(); P.usedVol = 0;\n    vector<int> order(nBlocks);\n    iota(order.begin(), order.end(), 0);\n    // sort by 1/vol descending\n    sort(order.begin(), order.end(), [&](int a, int b){\n        return blocks[a].vol > blocks[b].vol;\n    });\n    bitset<MAXD*MAXD*MAXD> rem = target;\n    int remVol = target.count();\n    for (int id : order) {\n        if (remVol == 0) break;\n        const Block& B = blocks[id];\n        bool placed = false;\n        // try all rotations and positions\n        for (int r = 0; r < (int)B.rot.size() && !placed; ++r) {\n            int maxx=0,maxy=0,maxz=0;\n            for (auto [x,y,z] : B.rot[r]) {\n                maxx=max(maxx,x); maxy=max(maxy,y); maxz=max(maxz,z);\n            }\n            for (int bx = 0; bx + maxx < D && !placed; ++bx)\n            for (int by = 0; by + maxy < D && !placed; ++by)\n            for (int bz = 0; bz + maxz < D && !placed; ++bz) {\n                if (!canPlace(P.occ, B, r, bx,by,bz)) continue;\n                // check if it covers at least one remaining voxel\n                bool cov = false;\n                for (auto [x,y,z] : B.rot[r]) {\n                    int xx = x+bx, yy = y+by, zz = z+bz;\n                    if (rem.test(idx(xx,yy,zz))) { cov=true; break; }\n                }\n                if (!cov) continue;\n                // place it\n                place(P.occ, B, r, bx,by,bz);\n                P.blockIds.push_back(id);\n                vector<tuple<int,int,int>> pose;\n                for (auto [x,y,z] : B.rot[r]) pose.emplace_back(x+bx, y+by, z+bz);\n                P.poses.push_back(pose);\n                P.usedVol += B.vol;\n                // update rem\n                for (auto [x,y,z] : B.rot[r]) {\n                    int xx = x+bx, yy = y+by, zz = z+bz;\n                    rem.reset(idx(xx,yy,zz));\n                }\n                remVol = rem.count();\n                placed = true;\n            }\n        }\n    }\n    return P;\n}\n\n// ---------- scoring ----------\ndouble eval(const Placement& p1, const Placement& p2) {\n    // build set of used blocks\n    unordered_set<int> used1(p1.blockIds.begin(), p1.blockIds.end());\n    unordered_set<int> used2(p2.blockIds.begin(), p2.blockIds.end());\n    int r1 = 0, r2 = 0;\n    double sumInv = 0.0;\n    for (int i = 0; i < nBlocks; ++i) {\n        bool in1 = used1.count(i), in2 = used2.count(i);\n        if (!in1 && !in2) continue; // not allowed, but we prune earlier\n        if (!in1) r1 += blocks[i].vol;\n        if (!in2) r2 += blocks[i].vol;\n        if (in1 && in2) sumInv += 1.0 / blocks[i].vol;\n    }\n    double score = r1 + r2 + sumInv;\n    return score;\n}\n\n// ---------- output ----------\nvoid output(const Placement& p1, const Placement& p2) {\n    // build global block list\n    unordered_map<int,int> globalId;\n    int nOut = 0;\n    for (int id : p1.blockIds) if (!globalId.count(id)) globalId[id] = nOut++;\n    for (int id : p2.blockIds) if (!globalId.count(id)) globalId[id] = nOut++;\n    cout << nOut << \"\\n\";\n    // output b1\n    vector<int> flat1(D*D*D, 0);\n    for (int i = 0; i < (int)p1.blockIds.size(); ++i) {\n        int gid = globalId[p1.blockIds[i]];\n        for (auto [x,y,z] : p1.poses[i]) {\n            flat1[idx(x,y,z)] = gid+1;\n        }\n    }\n    for (int i = 0; i < DDD; ++i) {\n        if (i) cout << \" \";\n        cout << flat1[i];\n    }\n    cout << \"\\n\";\n    // output b2\n    vector<int> flat2(D*D*D, 0);\n    for (int i = 0; i < (int)p2.blockIds.size(); ++i) {\n        int gid = globalId[p2.blockIds[i]];\n        for (auto [x,y,z] : p2.poses[i]) {\n            flat2[idx(x,y,z)] = gid+1;\n        }\n    }\n    for (int i = 0; i < DDD; ++i) {\n        if (i) cout << \" \";\n        cout << flat2[i];\n    }\n    cout << \"\\n\";\n}\n\n// ---------- main ----------\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    auto clk = chrono::high_resolution_clock::now();\n\n    cin >> D;\n    DD = D*D; DDD = D*D*D;\n    // read silhouettes\n    vector<string> fstr[2], rstr[2];\n    for (int i = 0; i < 2; ++i) {\n        fstr[i].resize(D);\n        for (int z = 0; z < D; ++z) cin >> fstr[i][z];\n        rstr[i].resize(D);\n        for (int z = 0; z < D; ++z) cin >> rstr[i][z];\n    }\n    // build mandatory voxels\n    for (int i = 0; i < 2; ++i) {\n        mandatory[i].reset();\n        for (int x = 0; x < D; ++x)\n        for (int y = 0; y < D; ++y)\n        for (int z = 0; z < D; ++z) {\n            if (fstr[i][z][x]=='1' && rstr[i][z][y]=='1') {\n                mandatory[i].set(idx(x,y,z));\n            }\n        }\n        mandatoryVol[i] = mandatory[i].count();\n    }\n    sharedMandatory = mandatory[0] & mandatory[1];\n    sharedVol = sharedMandatory.count();\n\n    // generate block catalogue\n    generateBlocks();\n\n    // greedy cover for each silhouette\n    bestP[0] = greedyCover(mandatory[0], 0);\n    bestP[1] = greedyCover(mandatory[1], 1);\n    bestScore = eval(bestP[0], bestP[1]);\n\n    // simple iterative improvement: try to replace one block by a larger unused one\n    // (very fast, so we do many iterations)\n    int iter = 0;\n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - clk).count();\n        if (elapsed > TIME_LIMIT) break;\n        iter++;\n        // pick random placement\n        int w = rand()&1;\n        Placement& P = bestP[w];\n        if (P.blockIds.empty()) continue;\n        int k = rand() % P.blockIds.size();\n        int oldId = P.blockIds[k];\n        // try all bigger unused blocks\n        bool improved = false;\n        for (int cand = 0; cand < nBlocks && !improved; ++cand) {\n            if (blocks[cand].vol <= blocks[oldId].vol) continue;\n            // try to place cand instead of oldId\n            Placement tmp = P;\n            // remove oldId\n            tmp.occ.reset();\n            tmp.usedVol -= blocks[oldId].vol;\n            tmp.blockIds.erase(tmp.blockIds.begin()+k);\n            tmp.poses.erase(tmp.poses.begin()+k);\n            // rebuild occ\n            for (int i = 0; i < (int)tmp.blockIds.size(); ++i) {\n                const Block& B = blocks[tmp.blockIds[i]];\n                for (auto [x,y,z] : tmp.poses[i]) tmp.occ.set(idx(x,y,z));\n            }\n            // try to add cand somewhere\n            const Block& B = blocks[cand];\n            bool placed = false;\n            for (int r = 0; r < (int)B.rot.size() && !placed; ++r) {\n                int maxx=0,maxy=0,maxz=0;\n                for (auto [x,y,z] : B.rot[r]) {\n                    maxx=max(maxx,x); maxy=max(maxy,y); maxz=max(maxz,z);\n                }\n                for (int bx = 0; bx + maxx < D && !placed; ++bx)\n                for (int by = 0; by + maxy < D && !placed; ++by)\n                for (int bz = 0; bz + maxz < D && !placed; ++bz) {\n                    if (!canPlace(tmp.occ, B, r, bx,by,bz)) continue;\n                    // check it covers at least one missing voxel\n                    bitset<MAXD*MAXD*MAXD> need = mandatory[w];\n                    for (int i = 0; i < (int)tmp.blockIds.size(); ++i)\n                        for (auto [x,y,z] : tmp.poses[i]) need.reset(idx(x,y,z));\n                    bool cov = false;\n                    for (auto [x,y,z] : B.rot[r]) {\n                        int xx = x+bx, yy = y+by, zz = z+bz;\n                        if (need.test(idx(xx,yy,zz))) { cov=true; break; }\n                    }\n                    if (!cov) continue;\n                    // place it\n                    place(tmp.occ, B, r, bx,by,bz);\n                    tmp.blockIds.push_back(cand);\n                    vector<tuple<int,int,int>> pose;\n                    for (auto [x,y,z] : B.rot[r]) pose.emplace_back(x+bx, y+by, z+bz);\n                    tmp.poses.push_back(pose);\n                    tmp.usedVol += B.vol;\n                    placed = true;\n                }\n            }\n            if (!placed) continue;\n            // finish covering with greedy\n            bitset<MAXD*MAXD*MAXD> rem = mandatory[w];\n            for (int i = 0; i < (int)tmp.blockIds.size(); ++i)\n                for (auto [x,y,z] : tmp.poses[i]) rem.reset(idx(x,y,z));\n            if (rem.any()) {\n                Placement fill = greedyCover(rem, w);\n                for (int i = 0; i < (int)fill.blockIds.size(); ++i) {\n                    tmp.blockIds.push_back(fill.blockIds[i]);\n                    tmp.poses.push_back(fill.poses[i]);\n                    tmp.usedVol += blocks[fill.blockIds[i]].vol;\n                    for (auto [x,y,z] : fill.poses[i]) tmp.occ.set(idx(x,y,z));\n                }\n            }\n            // evaluate\n            double sc = eval(tmp, bestP[w^1]);\n            if (sc < bestScore) {\n                bestScore = sc;\n                bestP[w] = tmp;\n                improved = true;\n            }\n        }\n    }\n\n    cerr << \"iterations \" << iter << \" bestScore \" << bestScore << \"\\n\";\n    output(bestP[0], bestP[1]);\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing int64 = long long;\n\nstatic const int MAXN = 105;\nstatic const int MAXM = 305;\nstatic const int MAXK = 5005;\nstatic const int MAXP = 5000;\n\nint N, M, K;\ndouble x[MAXN], y[MAXN];\nint u_e[MAXM], v_e[MAXM], w_e[MAXM];\ndouble a[MAXK], b[MAXK];\n\n// DSU for Kruskal\nint parent[MAXN];\nint find_set(int v) {\n    if (v == parent[v]) return v;\n    return parent[v] = find_set(parent[v]);\n}\nbool union_set(int u, int v) {\n    u = find_set(u);\n    v = find_set(v);\n    if (u == v) return false;\n    parent[v] = u;\n    return true;\n}\n\n// graph\nvector<pair<int,int>> adj[MAXN]; // (neighbor, edge_index)\n\n// MST flags\nbool in_mst[MAXM];\nint64 total_edge_cost = 0;\n\n// resident -> distance to each vertex\ndouble dist_ik[MAXK][MAXN];\n\n// current solution\nint P[MAXN];\nbool edge_on[MAXM];\n\n// recompute vertex cost and detect uncovered residents\n// returns -1 if some resident has closest > MAXP\nint64 recompute_vertex_cost(const vector<char>& reachable,\n                            vector<int>& bestP)\n{\n    bestP.assign(N, 0);\n    for (int k = 0; k < K; k++) {\n        double best_d = 1e18;\n        int best_i = -1;\n        for (int i = 0; i < N; i++) {\n            if (reachable[i] && dist_ik[k][i] < best_d) {\n                best_d = dist_ik[k][i];\n                best_i = i;\n            }\n        }\n        if (best_d > MAXP) return -1;          // unreachable within limit\n        int need = (int)ceil(best_d);\n        need = min(need, MAXP);\n        bestP[best_i] = max(bestP[best_i], need);\n    }\n    int64 cost = 0;\n    for (int i = 0; i < N; i++) cost += (int64)bestP[i] * bestP[i];\n    return cost;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> K;\n    for(int i = 0; i < N; i++){\n        cin >> x[i] >> y[i];\n    }\n    for(int j = 0; j < M; j++){\n        cin >> u_e[j] >> v_e[j] >> w_e[j];\n        --u_e[j]; --v_e[j];\n    }\n    for(int k = 0; k < K; k++){\n        cin >> a[k] >> b[k];\n    }\n\n    // precompute resident->vertex distances\n    for(int k = 0; k < K; k++){\n        for(int i = 0; i < N; i++){\n            double dx = x[i] - a[k];\n            double dy = y[i] - b[k];\n            dist_ik[k][i] = sqrt(dx*dx + dy*dy);\n        }\n    }\n\n    // Kruskal MST\n    for(int i = 0; i < N; i++) parent[i] = i;\n    vector<int> edges_order(M);\n    iota(edges_order.begin(), edges_order.end(), 0);\n    sort(edges_order.begin(), edges_order.end(),\n         [&](int j1, int j2){ return w_e[j1] < w_e[j2]; });\n\n    fill(in_mst, in_mst + M, false);\n    for(int jj = 0; jj < M; jj++){\n        int j = edges_order[jj];\n        if (union_set(u_e[j], v_e[j])) {\n            in_mst[j] = true;\n            total_edge_cost += w_e[j];\n        }\n    }\n\n    // build adj for BFS\n    for(int j = 0; j < M; j++){\n        if (in_mst[j]){\n            adj[u_e[j]].emplace_back(v_e[j], j);\n            adj[v_e[j]].emplace_back(u_e[j], j);\n        }\n    }\n\n    // initial full reachable\n    vector<char> fullReach(N, true);\n    vector<int>  bestP(N);\n    int64 vertex_cost = recompute_vertex_cost(fullReach, bestP);\n    for(int i = 0; i < N; i++) P[i] = bestP[i];\n    for(int j = 0; j < M; j++) edge_on[j] = in_mst[j];\n\n    // greedy deletion pass: largest weight first\n    vector<int> tree_edges;\n    for(int j = 0; j < M; j++) if (in_mst[j]) tree_edges.push_back(j);\n    sort(tree_edges.begin(), tree_edges.end(),\n         [&](int j1, int j2){ return w_e[j1] > w_e[j2]; });\n\n    bool improved;\n    do {\n        improved = false;\n        for(int j_idx = 0; j_idx < (int)tree_edges.size(); j_idx++){\n            int j = tree_edges[j_idx];\n            if (!edge_on[j]) continue;\n\n            edge_on[j] = false;\n            // BFS reachable\n            vector<char> reach(N, false);\n            queue<int> q;\n            reach[0] = true; q.push(0);\n            while(!q.empty()){\n                int u = q.front(); q.pop();\n                for(auto& [v, eidx] : adj[u]){\n                    if (!edge_on[eidx]) continue;\n                    if (!reach[v]){\n                        reach[v] = true;\n                        q.push(v);\n                    }\n                }\n            }\n            vector<int> newP(N);\n            int64 new_vertex_cost = recompute_vertex_cost(reach, newP);\n            if (new_vertex_cost == -1){\n                // some resident uncovered -> reject\n                edge_on[j] = true;\n                continue;\n            }\n            int64 saved = w_e[j];\n            int64 extra = new_vertex_cost - vertex_cost;\n            if (extra < saved){\n                vertex_cost = new_vertex_cost;\n                for(int i = 0; i < N; i++) P[i] = newP[i];\n                improved = true;\n            } else {\n                edge_on[j] = true;\n            }\n        }\n    } while(improved);\n\n    // output\n    for(int i = 0; i < N; i++){\n        cout << P[i] << (i+1<N?' ':'\\n');\n    }\n    for(int j = 0; j < M; j++){\n        cout << (edge_on[j]?1:0) << (j+1<M?' ':'\\n');\n    }\n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\nstruct Ball {\n    int value;\n    int x, y;\n};\n\nconst int N = 30;\nconst int MAX_SWAPS = 10000;\n\nint pyramid[N][N];\nvector<pair<pair<int,int>, pair<int,int>>> swaps;\n\n// Check if two positions are adjacent in 6 directions\nbool isAdjacent(int x1, int y1, int x2, int y2) {\n    if (x1 == x2-1 && (y1 == y2-1 || y1 == y2)) return true;\n    if (x1 == x2 && (y1 == y2-1 || y1 == y2+1)) return true;\n    if (x1 == x2+1 && (y1 == y2 || y1 == y2+1)) return true;\n    return false;\n}\n\n// Swap two balls and record the operation\nvoid performSwap(int x1, int y1, int x2, int y2) {\n    swap(pyramid[x1][y1], pyramid[x2][y2]);\n    swaps.push_back({{x1, y1}, {x2, y2}});\n}\n\n// Check if position (x,y) violates the heap property\nbool violatesHeap(int x, int y) {\n    if (x == N-1) return false; // Bottom tier doesn't violate\n    \n    int val = pyramid[x][y];\n    int leftChild = pyramid[x+1][y];\n    int rightChild = pyramid[x+1][y+1];\n    \n    return val > leftChild || val > rightChild;\n}\n\n// Find path to bring a small value up\nvector<pair<int,int>> findBubblePath(int targetX, int targetY) {\n    vector<pair<int,int>> path;\n    int x = targetX, y = targetY;\n    \n    while (x > 0) {\n        // Try to move up-left first\n        if (y > 0 && x-1 >= 0 && y-1 >= 0) {\n            path.push_back({x-1, y-1});\n            x--; y--;\n        }\n        // Then try up-right\n        else if (y < x && x-1 >= 0 && y < x-1) {\n            path.push_back({x-1, y});\n            x--;\n        }\n        else {\n            break;\n        }\n    }\n    \n    return path;\n}\n\n// Bubble a value up to its correct position\nvoid bubbleUp(int startX, int startY) {\n    int x = startX, y = startY;\n    \n    while (x > 0) {\n        int parentX = -1, parentY = -1;\n        \n        // Find parent position\n        if (y > 0 && pyramid[x-1][y-1] > pyramid[x][y]) {\n            parentX = x-1; parentY = y-1;\n        }\n        else if (y < x && pyramid[x-1][y] > pyramid[x][y]) {\n            parentX = x-1; parentY = y;\n        }\n        \n        if (parentX == -1) break;\n        \n        performSwap(x, y, parentX, parentY);\n        x = parentX; y = parentY;\n        \n        if (swaps.size() >= MAX_SWAPS) return;\n    }\n}\n\n// Main algorithm: iterative improvement\nvoid solve() {\n    // Read input\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j <= i; j++) {\n            cin >> pyramid[i][j];\n        }\n    }\n    \n    // Multiple passes to fix violations\n    for (int pass = 0; pass < 5 && swaps.size() < MAX_SWAPS; pass++) {\n        bool improved = false;\n        \n        // Process from bottom to top\n        for (int x = N-2; x >= 0; x--) {\n            for (int y = 0; y <= x; y++) {\n                if (violatesHeap(x, y)) {\n                    bubbleUp(x, y);\n                    improved = true;\n                    \n                    if (swaps.size() >= MAX_SWAPS) return;\n                }\n            }\n        }\n        \n        if (!improved) break;\n    }\n    \n    // Local optimization: fix remaining violations\n    for (int iter = 0; iter < 100 && swaps.size() < MAX_SWAPS; iter++) {\n        bool fixed = false;\n        \n        for (int x = 0; x < N-1 && !fixed; x++) {\n            for (int y = 0; y <= x && !fixed; y++) {\n                if (violatesHeap(x, y)) {\n                    int val = pyramid[x][y];\n                    \n                    // Try swapping with children\n                    if (val > pyramid[x+1][y]) {\n                        performSwap(x, y, x+1, y);\n                        fixed = true;\n                    }\n                    else if (val > pyramid[x+1][y+1]) {\n                        performSwap(x, y, x+1, y+1);\n                        fixed = true;\n                    }\n                    \n                    if (swaps.size() >= MAX_SWAPS) return;\n                }\n            }\n        }\n        \n        if (!fixed) break;\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    solve();\n    \n    // Output swaps\n    cout << swaps.size() << '\\n';\n    for (auto& swap : swaps) {\n        cout << swap.first.first << ' ' << swap.first.second << ' ' \n             << swap.second.first << ' ' << swap.second.second << '\\n';\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int D = 9;\nconst int di[] = {-1, 0, 1, 0};\nconst int dj[] = {0, 1, 0, -1};\n\nint N;\nbool obstacle[D][D];\nbool occupied[D][D];\nint container[D][D]; // container[i][j] = t_d if occupied, else -1\nint dist[D][D];\n\nvoid bfs_dist() {\n    queue<pair<int, int>> q;\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            dist[i][j] = -1;\n        }\n    }\n    int si = 0, sj = (D-1)/2;\n    dist[si][sj] = 0;\n    q.emplace(si, sj);\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) continue;\n            if (obstacle[ni][nj] || occupied[ni][nj]) continue;\n            if (dist[ni][nj] == -1) {\n                dist[ni][nj] = dist[i][j] + 1;\n                q.emplace(ni, nj);\n            }\n        }\n    }\n}\n\nbool is_reachable(int i, int j) {\n    if (obstacle[i][j] || occupied[i][j]) return false;\n    bfs_dist();\n    return dist[i][j] != -1;\n}\n\nvector<pair<int, int>> get_reachable() {\n    bfs_dist();\n    vector<pair<int, int>> res;\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            if (!obstacle[i][j] && !occupied[i][j] && dist[i][j] != -1) {\n                res.emplace_back(i, j);\n            }\n        }\n    }\n    return res;\n}\n\npair<int, int> choose_placement(int t) {\n    auto reachable = get_reachable();\n    if (reachable.empty()) {\n        cerr << \"No reachable cells!\" << endl;\n        exit(1);\n    }\n    // Choose the cell with maximum distance from entrance\n    pair<int, int> best = reachable[0];\n    int best_dist = dist[best.first][best.second];\n    for (auto [i, j] : reachable) {\n        if (dist[i][j] > best_dist) {\n            best_dist = dist[i][j];\n            best = {i, j};\n        }\n    }\n    return best;\n}\n\nvector<pair<int, int>> retrieval_order;\n\nvoid compute_retrieval() {\n    // Reset occupied to true where containers are placed\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            occupied[i][j] = (container[i][j] != -1);\n        }\n    }\n    priority_queue<pair<int, pair<int, int>>, vector<pair<int, pair<int, int>>>, greater<pair<int, pair<int, int>>>> pq;\n    // Initial reachable containers\n    bfs_dist();\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            if (container[i][j] != -1 && dist[i][j] != -1) {\n                pq.emplace(container[i][j], make_pair(i, j));\n            }\n        }\n    }\n    while (!pq.empty()) {\n        auto [t, pos] = pq.top(); pq.pop();\n        auto [i, j] = pos;\n        if (container[i][j] == -1) continue; // already removed\n        retrieval_order.emplace_back(i, j);\n        occupied[i][j] = false;\n        container[i][j] = -1;\n        // Update reachability\n        bfs_dist();\n        // Add newly reachable containers\n        for (int ni = 0; ni < D; ++ni) {\n            for (int nj = 0; nj < D; ++nj) {\n                if (container[ni][nj] != -1 && dist[ni][nj] != -1) {\n                    pq.emplace(container[ni][nj], make_pair(ni, nj));\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cout << fixed << setprecision(20);\n\n    cin >> D >> N;\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            obstacle[i][j] = false;\n            occupied[i][j] = false;\n            container[i][j] = -1;\n        }\n    }\n    for (int k = 0; k < N; ++k) {\n        int ri, rj;\n        cin >> ri >> rj;\n        obstacle[ri][rj] = true;\n    }\n\n    int total_containers = D*D - 1 - N;\n    for (int d = 0; d < total_containers; ++d) {\n        int t;\n        cin >> t;\n        auto [i, j] = choose_placement(t);\n        occupied[i][j] = true;\n        container[i][j] = t;\n        cout << i << \" \" << j << endl;\n    }\n\n    compute_retrieval();\n    for (auto [i, j] : retrieval_order) {\n        cout << i << \" \" << j << \"\\n\";\n    }\n    cout.flush();\n\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 50;\nconst int MAX_M = 100;\n\nint n, m;\nint input[MAX_N][MAX_N];\nbool adj[MAX_M + 1][MAX_M + 1];\nbool forbidden_adj[MAX_M + 1][MAX_M + 1];\nint output[MAX_N][MAX_N];\n\n// Directions for adjacency checking\nint dx[] = {-1, 1, 0, 0};\nint dy[] = {0, 0, -1, 1};\n\nvoid extract_adjacencies() {\n    memset(adj, false, sizeof(adj));\n    memset(forbidden_adj, true, sizeof(forbidden_adj));\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int c1 = input[i][j];\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d];\n                int nj = j + dy[d];\n                int c2 = (ni < 0 || ni >= n || nj < 0 || nj >= n) ? 0 : input[ni][nj];\n                \n                if (c1 != c2) {\n                    int u = min(c1, c2);\n                    int v = max(c1, c2);\n                    adj[u][v] = true;\n                    forbidden_adj[u][v] = false;\n                }\n            }\n        }\n    }\n}\n\nbool check_adjacencies() {\n    static bool output_adj[MAX_M + 1][MAX_M + 1];\n    memset(output_adj, false, sizeof(output_adj));\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int c1 = output[i][j];\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d];\n                int nj = j + dy[d];\n                int c2 = (ni < 0 || ni >= n || nj < 0 || nj >= n) ? 0 : output[ni][nj];\n                \n                if (c1 != c2) {\n                    int u = min(c1, c2);\n                    int v = max(c1, c2);\n                    output_adj[u][v] = true;\n                }\n            }\n        }\n    }\n    \n    for (int i = 0; i <= m; i++) {\n        for (int j = i + 1; j <= m; j++) {\n            if (adj[i][j] && !output_adj[i][j]) return false;\n            if (forbidden_adj[i][j] && output_adj[i][j]) return false;\n        }\n    }\n    \n    return true;\n}\n\nbool is_connected(int color) {\n    vector<pair<int, int>> cells;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (output[i][j] == color) {\n                cells.push_back({i, j});\n            }\n        }\n    }\n    \n    if (cells.empty()) return true;\n    \n    vector<vector<bool>> visited(n, vector<bool>(n, false));\n    queue<pair<int, int>> q;\n    q.push(cells[0]);\n    visited[cells[0].first][cells[0].second] = true;\n    int count = 1;\n    \n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        \n        for (int d = 0; d < 4; d++) {\n            int ni = i + dx[d];\n            int nj = j + dy[d];\n            \n            if (ni >= 0 && ni < n && nj >= 0 && nj < n && \n                output[ni][nj] == color && !visited[ni][nj]) {\n                visited[ni][nj] = true;\n                q.push({ni, nj});\n                count++;\n            }\n        }\n    }\n    \n    return count == cells.size();\n}\n\nbool is_zero_connected() {\n    vector<vector<bool>> visited(n, vector<bool>(n, false));\n    queue<pair<int, int>> q;\n    \n    // Start from boundary zeros\n    for (int i = 0; i < n; i++) {\n        if (output[i][0] == 0) { q.push({i, 0}); visited[i][0] = true; }\n        if (output[i][n-1] == 0) { q.push({i, n-1}); visited[i][n-1] = true; }\n        if (output[0][i] == 0) { q.push({0, i}); visited[0][i] = true; }\n        if (output[n-1][i] == 0) { q.push({n-1, i}); visited[n-1][i] = true; }\n    }\n    \n    int count = q.size();\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        \n        for (int d = 0; d < 4; d++) {\n            int ni = i + dx[d];\n            int nj = j + dy[d];\n            \n            if (ni >= 0 && ni < n && nj >= 0 && nj < n && \n                output[ni][nj] == 0 && !visited[ni][nj]) {\n                visited[ni][nj] = true;\n                q.push({ni, nj});\n                count++;\n            }\n        }\n    }\n    \n    int total_zeros = 0;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (output[i][j] == 0) total_zeros++;\n        }\n    }\n    \n    return count == total_zeros;\n}\n\nbool is_valid_placement() {\n    if (!check_adjacencies()) return false;\n    if (!is_zero_connected()) return false;\n    \n    for (int color = 1; color <= m; color++) {\n        if (!is_connected(color)) return false;\n    }\n    \n    return true;\n}\n\nint count_zeros() {\n    int count = 0;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (output[i][j] == 0) count++;\n        }\n    }\n    return count;\n}\n\nvoid copy_output(int dest[MAX_N][MAX_N], const int src[MAX_N][MAX_N]) {\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            dest[i][j] = src[i][j];\n        }\n    }\n}\n\nvoid create_connected_initial_solution() {\n    // Start with input map and carefully remove only safe tiles\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            output[i][j] = input[i][j];\n        }\n    }\n    \n    // Only remove tiles that are \"surrounded\" by same color or zeros\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < j; j++) {\n            if (output[i][j] == 0) continue;\n            \n            int color = output[i][j];\n            int same_color_neighbors = 0;\n            int zero_neighbors = 0;\n            int total_valid_neighbors = 0;\n            \n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d];\n                int nj = j + dy[d];\n                if (ni < 0 || ni >= n || nj < 0 || nj >= n) continue;\n                \n                total_valid_neighbors++;\n                if (output[ni][nj] == color) same_color_neighbors++;\n                else if (output[ni][nj] == 0) zero_neighbors++;\n            }\n            \n            // Only remove if mostly surrounded by same color or zeros\n            if (same_color_neighbors + zero_neighbors >= total_valid_neighbors - 1) {\n                int original = output[i][j];\n                output[i][j] = 0;\n                \n                if (is_valid_placement()) {\n                    // Successfully removed\n                } else {\n                    output[i][j] = original;\n                }\n            }\n        }\n    }\n}\n\nvoid connectivity_preserving_removal() {\n    // More careful removal that preserves connectivity\n    vector<pair<int, int>> candidates;\n    \n    // Find candidates: tiles with multiple same-color neighbors\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (output[i][j] == 0) continue;\n            \n            int color = output[i][j];\n            int same_neighbors = 0;\n            \n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d];\n                int nj = j + dy[d];\n                if (ni >= 0 && ni < n && nj >= 0 && nj < n && output[ni][nj] == color) {\n                    same_neighbors++;\n                }\n            }\n            \n            if (same_neighbors >= 2) {\n                candidates.push_back({i, j});\n            }\n        }\n    }\n    \n    // Try to remove candidates\n    for (auto [i, j] : candidates) {\n        int original = output[i][j];\n        output[i][j] = 0;\n        \n        if (is_valid_placement()) {\n            // Good removal\n        } else {\n            output[i][j] = original;\n        }\n    }\n}\n\nvoid bridge_detection_removal() {\n    // Remove tiles that are not \"bridges\" in the connectivity graph\n    for (int color = 1; color <= m; color++) {\n        vector<pair<int, int>> color_tiles;\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (output[i][j] == color) {\n                    color_tiles.push_back({i, j});\n                }\n            }\n        }\n        \n        if (color_tiles.size() <= 2) continue;\n        \n        // Try removing each tile and check if color stays connected\n        for (auto [i, j] : color_tiles) {\n            int original = output[i][j];\n            output[i][j] = 0;\n            \n            if (is_connected(color) && is_valid_placement()) {\n                // Successfully removed without breaking connectivity\n            } else {\n                output[i][j] = original;\n            }\n        }\n    }\n}\n\nvoid fill_empty_regions() {\n    // Try to create larger empty regions by removing tiles strategically\n    for (int size = 3; size <= 8; size++) {\n        for (int i = 0; i <= n - size; i++) {\n            for (int j = 0; j <= n - size; j++) {\n                // Check if we can create an empty region here\n                bool can_create_empty = true;\n                vector<pair<int, int>> tiles_to_remove;\n                \n                for (int di = 0; di < size && can_create_empty; di++) {\n                    for (int dj = 0; dj < size && can_create_empty; dj++) {\n                        if (output[i + di][j + dj] != 0) {\n                            tiles_to_remove.push_back({i + di, j + dj});\n                        }\n                    }\n                }\n                \n                if (tiles_to_remove.size() > size * size / 2) continue;\n                \n                // Try to remove all tiles in this region\n                vector<int> original_values;\n                for (auto [ti, tj] : tiles_to_remove) {\n                    original_values.push_back(output[ti][tj]);\n                    output[ti][tj] = 0;\n                }\n                \n                if (is_valid_placement()) {\n                    // Successfully created empty region\n                } else {\n                    // Restore\n                    for (int k = 0; k < tiles_to_remove.size(); k++) {\n                        auto [ti, tj] = tiles_to_remove[k];\n                        output[ti][tj] = original_values[k];\n                    }\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> n >> m;\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> input[i][j];\n        }\n    }\n    \n    extract_adjacencies();\n    \n    // Create initial connected solution\n    create_connected_initial_solution();\n    \n    if (!is_valid_placement()) {\n        // Fallback to input\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                output[i][j] = input[i][j];\n            }\n        }\n    }\n    \n    // Apply connectivity-preserving optimizations\n    connectivity_preserving_removal();\n    bridge_detection_removal();\n    fill_empty_regions();\n    \n    // Final careful optimization\n    connectivity_preserving_removal();\n    \n    // Output the result\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << output[i][j];\n            if (j < n - 1) cout << \" \";\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int N, D, Q;\n    cin >> N >> D >> Q;\n    \n    // Use static arrays only\n    static int assignment[100];\n    static int weight_est[100];\n    \n    // Initialize\n    for (int i = 0; i < N; i++) {\n        assignment[i] = 0;\n        weight_est[i] = 1;\n    }\n    \n    // Phase 1: Quick weight estimation with safe comparisons\n    int queries_done = 0;\n    \n    for (int round = 0; round < 2 && queries_done < Q; round++) {\n        for (int i = 0; i < N && queries_done < Q; i++) {\n            int a = i;\n            int b = (i + 1 + round) % N;\n            \n            cout << \"1 1 \" << a << \" \" << b << endl;\n            \n            string res;\n            cin >> res;\n            queries_done++;\n            \n            if (res == \">\") {\n                weight_est[a] += 2;\n            } else if (res == \"<\") {\n                weight_est[b] += 2;\n            } else {\n                weight_est[a]++;\n                weight_est[b]++;\n            }\n        }\n    }\n    \n    // Phase 2: Group assignment based on estimated weights\n    static int group_weights[25] = {0};  // Max D is 25\n    \n    // Create simple ordering based on weights\n    for (int i = 0; i < N; i++) {\n        // Find which group to assign to (lightest group)\n        int best_group = 0;\n        for (int g = 1; g < D; g++) {\n            if (group_weights[g] < group_weights[best_group]) {\n                best_group = g;\n            }\n        }\n        \n        assignment[i] = best_group;\n        group_weights[best_group] += weight_est[i];\n    }\n    \n    // Use remaining queries for minor adjustments\n    while (queries_done < Q) {\n        int a = queries_done % N;\n        int b = (queries_done + N/2) % N;\n        \n        cout << \"1 1 \" << a << \" \" << b << endl;\n        \n        string res;\n        cin >> res;\n        queries_done++;\n        \n        // Just consume the response, don't over-adjust\n    }\n    \n    // Final output\n    for (int i = 0; i < N; i++) {\n        cout << assignment[i];\n        if (i < N-1) cout << \" \";\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 200;\nconst int MAXM = 10;\n\nint n, m;\nvector<int> st[MAXM];\npair<int,int> where[MAXN+1]; // {stack, index} for box v; stack=-1 if carried\n\nvector<pair<int,int>> ops;\n\n// Carry out box v from stack s\nvoid carry_out(int v, int s) {\n    ops.emplace_back(v, 0);\n    st[s].pop_back();\n    where[v] = {-1, -1};\n}\n\n// Move box v and all above it from stack s to stack t\nvoid move_block(int v, int s, int t) {\n    int idx = where[v].second;\n    int k = st[s].size() - idx; // number of boxes to move\n    ops.emplace_back(v, t+1); // output is 1-indexed\n\n    // Extract block\n    vector<int> block(st[s].begin() + idx, st[s].end());\n    st[s].resize(idx);\n\n    // Append to target\n    for(int x : block) {\n        st[t].push_back(x);\n        where[x] = {t, (int)st[t].size()-1};\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> n >> m;\n    for(int i = 0; i < m; i++) {\n        st[i].resize(n/m);\n        for(int j = 0; j < n/m; j++) {\n            cin >> st[i][j];\n            where[ st[i][j] ] = {i, j};\n        }\n    }\n\n    int next_out = 1;\n\n    while(next_out <= n) {\n        // Phase 1: carry out as many as possible\n        bool progress = true;\n        while(progress && next_out <= n) {\n            progress = false;\n            // Find if next_out is at top of any stack\n            for(int i = 0; i < m; i++) {\n                if(!st[i].empty() && st[i].back() == next_out) {\n                    carry_out(next_out, i);\n                    next_out++;\n                    progress = true;\n                    break;\n                }\n            }\n        }\n        if(next_out > n) break;\n\n        // Phase 2: next_out is buried somewhere\n        int s = -1;\n        for(int i = 0; i < m; i++) {\n            for(int j = 0; j < st[i].size(); j++) {\n                if(st[i][j] == next_out) {\n                    s = i;\n                    break;\n                }\n            }\n            if(s != -1) break;\n        }\n        // s is the stack containing next_out\n        int idx = where[next_out].second;\n        int k = st[s].size() - idx; // boxes from next_out to top\n\n        // Choose target stack t != s with maximum top box\n        int best_t = -1;\n        int best_top = -1;\n        for(int t = 0; t < m; t++) {\n            if(t == s) continue;\n            int top_val = st[t].empty() ? 0 : st[t].back();\n            if(top_val > best_top) {\n                best_top = top_val;\n                best_t = t;\n            }\n        }\n        // Move block to best_t\n        move_block(next_out, s, best_t);\n    }\n\n    // Output operations\n    for(auto [v, i] : ops) {\n        cout << v << \" \" << i << \"\\n\";\n    }\n\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nstatic const int DI[4] = {1,0,-1,0};\nstatic const int DJ[4] = {0,1,0,-1};\nstatic const char DC[4] = {'D','R','U','L'};\n\nint main(){\n  ios::sync_with_stdio(false);\n  cin.tie(nullptr);\n\n  int N; cin>>N;\n  vector<string> hwall(N-1), vwall(N);\n  for(int i=0;i<N-1;i++) cin>>hwall[i];\n  for(int i=0;i<N;  i++) cin>>vwall[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  // build adj\n  auto inside = [&](int i,int j){ return 0<=i&&i<N&&0<=j&&j<N; };\n  vector<vector<array<int,2>>> adj(N*N);\n  auto enc = [&](int i,int j){ return i*N+j; };\n  auto dec = [&](int v){ return array<int,2>{v/N, v%N}; };\n  for(int i=0;i<N;i++){\n    for(int j=0;j<N;j++){\n      int v = enc(i,j);\n      for(int dir=0;dir<4;dir++){\n        int ni=i+DI[dir], nj=j+DJ[dir];\n        if(!inside(ni,nj)) continue;\n        bool ok = true;\n        if(dir==0){ // D\n          if(hwall[i][j]=='1') ok=false;\n        }else if(dir==2){ // U\n          if(hwall[i-1][j]=='1') ok=false;\n        }else if(dir==1){ // R\n          if(vwall[i][j]=='1') ok=false;\n        }else{ // L\n          if(vwall[i][j-1]=='1') ok=false;\n        }\n        if(ok){\n          adj[v].push_back({enc(ni,nj), dir});\n        }\n      }\n    }\n  }\n\n  // 1. basic Euler tour by DFS (simple, ensures all visited)\n  vector<bool> vis(N*N,false);\n  string basic;\n  function<void(int)> dfs = [&](int v){\n    vis[v]=true;\n    auto [i,j]=dec(v);\n    for(auto [u,dir]: adj[v]){\n      if(!vis[u]){\n        basic += DC[dir];\n        dfs(u);\n        basic += DC[dir^2]; // back\n      }\n    }\n  };\n  dfs(0);\n  // basic is already closed at (0,0)\n\n  // 2. enumerate small cycles (length <= 10) for each node\n  const int MAXCYCLE=10;\n  vector<vector<array<int,2>>> cycles(N*N); // cycles[v] = list of {start_index_in_basic, cycle_length}\n  // but we need actual cycle sequences to insert\n  // instead, we precompute for each node v: list of cycles (as string) that start from v and return to v with length <= MAXCYCLE\n  vector<vector<string>> nodeCycles(N*N);\n  vector<int> dist(N*N), parent(N*N), parDir(N*N);\n  for(int sv=0; sv<N*N; sv++){\n    fill(dist.begin(), dist.end(), -1);\n    dist[sv]=0;\n    queue<int> q; q.push(sv);\n    while(!q.empty()){\n      int v=q.front(); q.pop();\n      if(dist[v]>=MAXCYCLE) continue;\n      for(auto [u,dir]: adj[v]){\n        if(dist[u]==-1){\n          dist[u]=dist[v]+1;\n          parent[u]=v;\n          parDir[u]=dir;\n          q.push(u);\n        }\n        // found back to sv\n        if(u==sv && dist[v]+1>=2 && dist[v]+1<=MAXCYCLE){\n          // reconstruct\n          string cyc;\n          int x=v;\n          int len=dist[v]+1;\n          while(x!=sv){\n            cyc += DC[parDir[x]];\n            x = parent[x];\n          }\n          // we are at sv, but we need to close the cycle\n          // last step from v to sv is by 'dir'\n          // but we already have full path\n          // actually we don't need to push last dir, because we are already at sv\n          // the cycle string is cyc (from sv to v) and then one more step dir\n          cyc += DC[dir];\n          // this cycle starts/ends at sv, length = len\n          nodeCycles[sv].push_back(cyc);\n        }\n      }\n    }\n  }\n\n  // 3. compute efficiency = (sum of d on cycle vertices) / (cycle length)\n  vector<tuple<double,int,int,string>> effCycles; // (eff, node, index_in_nodeCycles, cycle_string)\n  for(int v=0;v<N*N;v++){\n    auto [i0,j0]=dec(v);\n    for(auto& cyc: nodeCycles[v]){\n      set<int> verts;\n      int u=v;\n      verts.insert(u);\n      for(char ch: cyc){\n        int dir = string(\"DRUL\").find(ch);\n        auto [i,j]=dec(u);\n        int ni=i+DI[dir], nj=j+DJ[dir];\n        u = enc(ni,nj);\n        verts.insert(u);\n      }\n      long long sd=0;\n      for(int x: verts){\n        auto [i,j]=dec(x);\n        sd += d[i][j];\n      }\n      double eff = (double)sd / (double)cyc.size();\n      effCycles.emplace_back(eff, v, 0, cyc);\n    }\n  }\n  // sort by eff desc\n  sort(effCycles.rbegin(), effCycles.rend());\n\n  // 4. try to insert high-eff cycles into basic as many as possible\n  // we can do: for each occurrence of v in basic, we can insert cycle there\n  // but we do greedy: take highest eff, and insert as many as possible within budget\n  const int LMAX = 100000;\n  int budget = LMAX - (int)basic.size();\n  string route = basic;\n  // we need to know positions of each node in route\n  // but route will be extended dynamically -> we do offline: precompute positions in basic, and insertions\n  // instead, we do simple: for each cycle in effCycles, try to insert at first occurrence of node\n  vector<int> posInBasic(N*N, -1);\n  {\n    int u=0;\n    posInBasic[u]=0;\n    for(int i=0;i<(int)basic.size();i++){\n      char ch=basic[i];\n      int dir=string(\"DRUL\").find(ch);\n      auto [x,y]=dec(u);\n      int nx=x+DI[dir], ny=y+DJ[dir];\n      u = enc(nx,ny);\n      if(posInBasic[u]==-1) posInBasic[u]=i+1;\n    }\n  }\n  // now for each cycle, if node v appears in basic, we can insert at posInBasic[v]\n  // we do greedy: for each cycle, insert as many as possible at that position\n  for(auto& [eff, v, dummy, cyc]: effCycles){\n    if(budget <=0) break;\n    int p = posInBasic[v];\n    if(p==-1) continue;\n    int len = cyc.size();\n    int maxrep = budget / len;\n    if(maxrep<=0) continue;\n    string add;\n    for(int t=0;t<maxrep;t++) add += cyc;\n    // insert at p\n    route.insert(p, add);\n    budget -= maxrep * len;\n  }\n\n  // 5. ensure we are back at (0,0) and length <= 1e5\n  // our basic was closed, and inserted cycles are closed, so whole route is closed\n  if(route.size() > LMAX){\n    route.resize(LMAX);\n  }\n  cout << route << endl;\n\n  return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nconst int INF = 1e9;\nint N, M;\nint si, sj;\narray<array<char, 15>, 15> A;\nvector<string> t(200);\n\n/* ========== basic grid tooling ========== */\nvector<pair<int, int>> pos[26];          // letter -> cells\nint distLetter[26][26];                  // letter -> letter (min steps)\n\nvoid buildDistLetter() {\n    for (int c = 0; c < 26; ++c) {\n        static int d[15][15];\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j) d[i][j] = INF;\n        queue<pair<int, int>> q;\n        for (auto [i, j] : pos[c]) {\n            d[i][j] = 0;\n            q.emplace(i, j);\n        }\n        int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1};\n        while (!q.empty()) {\n            auto [i, j] = q.front(); q.pop();\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + dx[dir], nj = j + dy[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                if (d[ni][nj] > d[i][j] + 1) {\n                    d[ni][nj] = d[i][j] + 1;\n                    q.emplace(ni, nj);\n                }\n            }\n        }\n        for (int c2 = 0; c2 < 26; ++c2) {\n            int best = INF;\n            for (auto [i, j] : pos[c2]) best = min(best, d[i][j]);\n            distLetter[c][c2] = best;\n        }\n    }\n}\n\n/* ========== path reconstruction ========== */\narray<array<pair<int, int>, 15>, 15> pred[26];\nvoid buildPred() {\n    for (int c = 0; c < 26; ++c) {\n        static int d[15][15];\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j) d[i][j] = INF;\n        queue<pair<int, int>> q;\n        for (auto [i, j] : pos[c]) {\n            d[i][j] = 0;\n            pred[c][i][j] = {-1, -1};\n            q.emplace(i, j);\n        }\n        int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1};\n        while (!q.empty()) {\n            auto [i, j] = q.front(); q.pop();\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + dx[dir], nj = j + dy[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                if (d[ni][nj] > d[i][j] + 1) {\n                    d[ni][nj] = d[i][j] + 1;\n                    pred[c][ni][nj] = {i, j};\n                    q.emplace(ni, nj);\n                }\n            }\n        }\n    }\n}\n\n/* ========== overlap ========== */\nint overlap(const string& a, const string& b) {\n    int maxo = 0;\n    int al = a.size(), bl = b.size();\n    int lim = min(al, bl);\n    for (int o = 1; o <= lim; ++o) {\n        bool ok = true;\n        for (int i = 0; i < o; ++i)\n            if (a[al - o + i] != b[i]) { ok = false; break; }\n        if (ok) maxo = o;\n    }\n    return maxo;\n}\n\n/* ========== Aho\u2013Corasick for full check ========== */\nnamespace AC {\n    const int A = 26, N = 200 * 5 + 10;\n    int trie[N][A], fail[N], cnt[N], nodes = 1;\n    int insert(const string& s) {\n        int v = 0;\n        for (char ch : s) {\n            int c = ch - 'A';\n            if (!trie[v][c]) trie[v][c] = nodes++;\n            v = trie[v][c];\n        }\n        cnt[v]++;\n        return v;\n    }\n    void build() {\n        queue<int> q;\n        for (int c = 0; c < A; ++c) if (trie[0][c]) q.push(trie[0][c]);\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            for (int c = 0; c < A; ++c) {\n                int u = trie[v][c];\n                if (!u) { trie[v][c] = trie[fail[v]][c]; continue; }\n                fail[u] = v ? trie[fail[v]][c] : 0;\n                q.push(u);\n            }\n        }\n    }\n    int countMatches(const string& s) {\n        int v = 0, matches = 0;\n        for (char ch : s) {\n            int c = ch - 'A';\n            v = trie[v][c];\n            int tmp = v;\n            while (tmp) { matches += cnt[tmp]; cnt[tmp] = 0; tmp = fail[tmp]; }\n        }\n        return matches;\n    }\n}\n\n/* ========== real path & string ========== */\nvector<pair<int, int>> outPath;\nint curi, curj;\n\nvoid appendMove(int ti, int tj) {\n    if (curi == ti && curj == tj) return;\n    static int d[15][15];\n    static pair<int, int> p[15][15];\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) d[i][j] = INF;\n    queue<pair<int, int>> q;\n    d[curi][curj] = 0;\n    q.emplace(curi, curj);\n    int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1};\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        if (i == ti && j == tj) break;\n        for (int dir = 0; dir < 4; ++dir) {\n            int ni = i + dx[dir], nj = j + dy[dir];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            if (d[ni][nj] > d[i][j] + 1) {\n                d[ni][nj] = d[i][j] + 1;\n                p[ni][nj] = {i, j};\n                q.emplace(ni, nj);\n            }\n        }\n    }\n    vector<pair<int, int>> rev;\n    auto xy = make_pair(ti, tj);\n    while (xy.first != curi || xy.second != curj) {\n        rev.push_back(xy);\n        xy = p[xy.first][xy.second];\n    }\n    reverse(rev.begin(), rev.end());\n    for (auto [i, j] : rev) outPath.emplace_back(i, j);\n    curi = ti; curj = tj;\n}\n\n/* choose concrete cells for a suffix */\nvector<pair<int, int>> chooseCells(const string& s, char nextFirst) {\n    vector<pair<int, int>> res;\n    int nc = nextFirst == 0 ? -1 : nextFirst - 'A';\n    for (char c : s) {\n        int cc = c - 'A';\n        int best = INF;\n        pair<int, int> pick;\n        for (auto [i, j] : pos[cc]) {\n            int dd = abs(i - curi) + abs(j - curj);\n            int centr = abs(i - N / 2) + abs(j - N / 2);\n            int score = dd + centr / 3;\n            if (score < best) { best = score; pick = {i, j}; }\n        }\n        res.push_back(pick);\n        curi = pick.first; curj = pick.second;\n    }\n    return res;\n}\n\n/* build path & extract string S */\nstring buildString(const vector<int>& ord) {\n    outPath.clear();\n    curi = si; curj = sj;\n    string S;\n    S.reserve(6000);\n    auto pushCell = [&](int i, int j) {\n        appendMove(i, j);\n        S.push_back(A[i][j]);\n    };\n    for (int k = 0; k < M; ++k) {\n        int id = ord[k];\n        const string& w = t[id];\n        if (k == 0) {\n            auto cells = chooseCells(w, M > 1 ? t[ord[1]][0] : 0);\n            for (auto [i, j] : cells) pushCell(i, j);\n        } else {\n            int o = overlap(t[ord[k - 1]], w);\n            string suf = w.substr(o);\n            char nf = 0;\n            if (k + 1 < M) nf = t[ord[k + 1]][0];\n            auto cells = chooseCells(suf, nf);\n            for (auto [i, j] : cells) pushCell(i, j);\n        }\n        if (S.size() > 5000) return \"\";          // early give-up\n    }\n    return S;\n}\n\n/* ========== 2-opt on word order ========== */\nvoid twoOpt(vector<int>& ord) {\n    auto costEdge = [&](int l, int r) {\n        char lc = t[ord[l]].back();\n        char fc = t[ord[r]][0];\n        return distLetter[lc - 'A'][fc - 'A'] + 1;\n    };\n    bool improved = true;\n    int iter = 0;\n    while (improved && ++iter < 1000) {\n        improved = false;\n        for (int i = 0; i + 1 < M; ++i)\n            for (int j = i + 1; j < M; ++j) {\n                ll old = costEdge(i - 1, i) + costEdge(i, i + 1)\n                       + costEdge(j - 1, j) + costEdge(j, (j + 1) % M);\n                ll nw = costEdge(i - 1, j) + costEdge(j, i + 1)\n                      + costEdge(j - 1, i) + costEdge(i, (j + 1) % M);\n                if (nw < old) {\n                    swap(ord[i], ord[j]);\n                    improved = true;\n                }\n            }\n    }\n}\n\n/* ========== driver ========== */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M;\n    cin >> si >> sj;\n    for (int i = 0; i < N; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < N; ++j) {\n            A[i][j] = row[j];\n            pos[A[i][j] - 'A'].emplace_back(i, j);\n        }\n    }\n    for (int k = 0; k < M; ++k) cin >> t[k];\n\n    buildDistLetter();\n    buildPred();\n    /* Aho-Corasick */\n    for (const string& s : t) AC::insert(s);\n    AC::build();\n\n    /* greedy initial order */\n    vector<int> ord(M);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int a, int b) {\n        return t[a] < t[b];\n    });\n    twoOpt(ord);\n\n    /* ensure validity */\n    string S = buildString(ord);\n    if ((int)S.size() > 5000 || AC::countMatches(S) < M) {\n        /* fallback: original greedy overlap order */\n        ord.assign(M, 0);\n        iota(ord.begin(), ord.end(), 0);\n        sort(ord.begin(), ord.end(), [&](int a, int b) {\n            int oa = overlap(t[ord[0]], t[a]);\n            int ob = overlap(t[ord[0]], t[b]);\n            if (oa != ob) return oa > ob;\n            return distLetter[t[ord[0]].back() - 'A'][t[a][0] - 'A']\n                 < distLetter[t[ord[0]].back() - 'A'][t[b][0] - 'A'];\n        });\n        S = buildString(ord);\n    }\n\n    /* output path */\n    for (auto [i, j] : outPath) cout << i << ' ' << j << '\\n';\n    return 0;\n}","ahc030":"#include <iostream>\n#include <vector>\n#include <set>\n#include <algorithm>\n\nusing namespace std;\n\nint N, M;\ndouble eps;\nvector<vector<bool>> drilled;\nvector<vector<int>> values;\n\n// Simple query functions\nint drill(int i, int j) {\n    cout << \"q 1 \" << i << \" \" << j << endl;\n    int response;\n    cin >> response;\n    return response;\n}\n\nint divine(const vector<pair<int, int>>& points) {\n    if (points.size() < 2) return 0;\n    \n    cout << \"q \" << points.size();\n    for (auto [i, j] : points) {\n        cout << \" \" << i << \" \" << j;\n    }\n    cout << endl;\n    \n    int response;\n    cin >> response;\n    return max(0, response);  // Ensure non-negative\n}\n\nbool answer(const vector<pair<int, int>>& answer_points) {\n    cout << \"a \" << answer_points.size();\n    for (auto [i, j] : answer_points) {\n        cout << \" \" << i << \" \" << j;\n    }\n    cout << endl;\n    \n    int response;\n    cin >> response;\n    return response == 1;\n}\n\nint main() {\n    // Read input\n    cin >> N >> M >> eps;\n    \n    // Read oil field shapes (we'll use these for intelligent guessing)\n    vector<vector<pair<int, int>>> oil_fields(M);\n    for (int k = 0; k < M; k++) {\n        int d;\n        cin >> d;\n        oil_fields[k].resize(d);\n        for (int i = 0; i < d; i++) {\n            cin >> oil_fields[k][i].first >> oil_fields[k][i].second;\n        }\n    }\n    \n    // Initialize tracking\n    drilled.assign(N, vector<bool>(N, false));\n    values.assign(N, vector<int>(N, -1));\n    \n    vector<pair<int, int>> oil_squares;\n    int operations = 0;\n    const int max_ops = 2 * N * N;\n    \n    // Strategy 1: Use divination to find regions with oil\n    // Divide grid into blocks and divine each block\n    \n    int block_size = 4;  // 4x4 blocks\n    if (N <= 12) block_size = 3;\n    if (N <= 8) block_size = 2;\n    \n    for (int bi = 0; bi < N && operations < max_ops - 50; bi += block_size) {\n        for (int bj = 0; bj < N && operations < max_ops - 50; bj += block_size) {\n            vector<pair<int, int>> block;\n            \n            for (int i = bi; i < min(bi + block_size, N); i++) {\n                for (int j = bj; j < min(bj + block_size, N); j++) {\n                    block.emplace_back(i, j);\n                }\n            }\n            \n            if (block.size() >= 2) {\n                int sum = divine(block);\n                operations++;\n                \n                // If sum is significant, this block likely contains oil\n                if (sum > 0) {\n                    // Drill a few squares in this block to confirm\n                    int to_drill = min(sum, (int)block.size() / 2);\n                    for (int k = 0; k < to_drill && operations < max_ops - 20; k++) {\n                        auto [i, j] = block[k];\n                        if (!drilled[i][j]) {\n                            int val = drill(i, j);\n                            operations++;\n                            drilled[i][j] = true;\n                            values[i][j] = val;\n                            if (val > 0) {\n                                oil_squares.emplace_back(i, j);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Strategy 2: If we found oil, explore around it using shape information\n    if (!oil_squares.empty() && operations < max_ops - 20) {\n        // For each oil square we found, check neighbors that could be part of oil fields\n        set<pair<int, int>> candidates;\n        \n        for (auto [oi, oj] : oil_squares) {\n            // Add all neighbors within reasonable distance\n            for (int di = -3; di <= 3; di++) {\n                for (int dj = -3; dj <= 3; dj++) {\n                    int ni = oi + di, nj = oj + dj;\n                    if (ni >= 0 && ni < N && nj >= 0 && nj < N && !drilled[ni][nj]) {\n                        candidates.insert({ni, nj});\n                    }\n                }\n            }\n        }\n        \n        // Divine groups of candidates\n        vector<pair<int, int>> candidate_list(candidates.begin(), candidates.end());\n        for (int i = 0; i < (int)candidate_list.size() && operations < max_ops - 10; i += 9) {\n            vector<pair<int, int>> group;\n            for (int j = i; j < min(i + 9, (int)candidate_list.size()); j++) {\n                group.push_back(candidate_list[j]);\n            }\n            if (group.size() >= 2) {\n                int sum = divine(group);\n                operations++;\n                \n                // Drill high-probability squares\n                if (sum > 0) {\n                    int to_drill = min(sum, (int)group.size());\n                    for (int k = 0; k < to_drill && operations < max_ops - 5; k++) {\n                        auto [x, y] = group[k];\n                        if (!drilled[x][y]) {\n                            int val = drill(x, y);\n                            operations++;\n                            drilled[x][y] = true;\n                            values[x][y] = val;\n                            if (val > 0) {\n                                oil_squares.emplace_back(x, y);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Strategy 3: Final cleanup - check remaining high-probability areas\n    // Focus on center areas first as oil fields are more likely there\n    vector<pair<int, int>> remaining;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (!drilled[i][j]) {\n                // Priority based on distance to center and existing oil\n                int dist_to_center = abs(i - N/2) + abs(j - N/2);\n                int dist_to_oil = N * 2;\n                for (auto [oi, oj] : oil_squares) {\n                    dist_to_oil = min(dist_to_oil, abs(i - oi) + abs(j - oj));\n                }\n                \n                int priority = dist_to_oil * 2 + dist_to_center;\n                remaining.push_back({i, j});\n            }\n        }\n    }\n    \n    // Drill remaining squares strategically\n    for (int i = 0; i < (int)remaining.size() && operations < max_ops - 1; i++) {\n        auto [x, y] = remaining[i];\n        int val = drill(x, y);\n        operations++;\n        drilled[x][y] = true;\n        values[x][y] = val;\n        if (val > 0) {\n            oil_squares.emplace_back(x, y);\n        }\n    }\n    \n    // Final answer\n    answer(oil_squares);\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nstatic const int W = 1000;\nint D, N;\nvector<vector<int>> a;\n\n// partition bitsets: 1 = partition exists\n// Hseg[i][j] : horizontal segment at row i, columns j..j+1  (i in [1,W-1], j in [0,W-1])\n// Vseg[i][j] : vertical   segment at col j, rows i..i+1    (i in [0,W-1], j in [1,W-1])\nbitset<W> Hseg[W], Vseg[W];\n\nstruct Rect {\n    int i0, j0, i1, j1;\n    int area() const { return (i1 - i0) * (j1 - j0); }\n};\n\n// output rectangles per day\nvector<vector<Rect>> outRect;\n\n// compute partition-change cost versus previous day\nint computeLd(const vector<Rect>& rects) {\n    // new partition maps\n    bitset<W> nH[W], nV[W];\n    for (const auto& r : rects) {\n        int i0 = r.i0, j0 = r.j0, i1 = r.i1, j1 = r.j1;\n        // top edge\n        if (i0 > 0)      for (int j = j0; j < j1; ++j) nH[i0].set(j);\n        // bottom edge\n        if (i1 < W)      for (int j = j0; j < j1; ++j) nH[i1].set(j);\n        // left edge\n        if (j0 > 0)      for (int i = i0; i < i1; ++i) nV[i].set(j0);\n        // right edge\n        if (j1 < W)      for (int i = i0; i < i1; ++i) nV[i].set(j1);\n    }\n    int cost = 0;\n    for (int i = 1; i < W; ++i) {\n        auto diff = Hseg[i] ^ nH[i];\n        cost += diff.count();\n    }\n    for (int j = 1; j < W; ++j) {\n        bitset<W> diff;\n        for (int i = 0; i < W; ++i) diff[i] = Vseg[i][j] ^ nV[i][j];\n        cost += diff.count();\n    }\n    return cost;\n}\n\n// assign rectangles for one day\nvoid solveDay(int d) {\n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    // largest first\n    sort(ord.begin(), ord.end(), [&](int x, int y) {\n        return a[d][x] > a[d][y];\n    });\n\n    // free rectangles\n    vector<Rect> freeList = { {0, 0, W, W} };\n    vector<Rect> assigned(N);\n\n    auto bestSplit = [&](const Rect& hole, int need,\n                         int& bestCost, Rect& bestA, Rect& bestB, bool& bestIsHoriz) {\n        bestCost = INT_MAX;\n        int h = hole.i1 - hole.i0;\n        int w = hole.j1 - hole.j0;\n        // try horizontal split: i0..cut and cut..i1\n        if (h > 1) {\n            int cutLo = hole.i0 + 1;\n            int cutHi = hole.i1 - 1;\n            int step = max(1, (cutHi - cutLo + 1) / 20);\n            for (int cut = cutLo; cut <= cutHi; cut += step) {\n                Rect A = { hole.i0, hole.j0, cut,     hole.j1 };\n                Rect B = { cut,     hole.j0, hole.i1, hole.j1 };\n                if (A.area() < need) continue;\n                // compute extra partition cost\n                int c = 0;\n                // new horizontal segment at 'cut'\n                for (int j = hole.j0; j < hole.j1; ++j) {\n                    bool old = Hseg[cut][j];\n                    if (!old) c++;\n                }\n                if (c < bestCost) {\n                    bestCost = c;\n                    bestA = A;\n                    bestB = B;\n                    bestIsHoriz = true;\n                }\n            }\n        }\n        // try vertical split\n        if (w > 1) {\n            int cutLo = hole.j0 + 1;\n            int cutHi = hole.j1 - 1;\n            int step = max(1, (cutHi - cutLo + 1) / 20);\n            for (int cut = cutLo; cut <= cutHi; cut += step) {\n                Rect A = { hole.i0, hole.j0, hole.i1, cut };\n                Rect B = { hole.i0, cut,     hole.i1, hole.j1 };\n                if (A.area() < need) continue;\n                int c = 0;\n                for (int i = hole.i0; i < hole.i1; ++i) {\n                    bool old = Vseg[i][cut];\n                    if (!old) c++;\n                }\n                if (c < bestCost) {\n                    bestCost = c;\n                    bestA = A;\n                    bestB = B;\n                    bestIsHoriz = false;\n                }\n            }\n        }\n    };\n\n    for (int k : ord) {\n        int need = a[d][k];\n        int bestCost = INT_MAX;\n        Rect bestA, bestB;\n        bool bestIsHoriz = false;\n        int bestIdx = -1;\n        for (int idx = 0; idx < (int)freeList.size(); ++idx) {\n            const Rect& hole = freeList[idx];\n            if (hole.area() < need) continue;\n            int c; Rect A, B; bool ih;\n            bestSplit(hole, need, c, A, B, ih);\n            if (c < bestCost) {\n                bestCost = c;\n                bestA = A;\n                bestB = B;\n                bestIsHoriz = ih;\n                bestIdx = idx;\n            }\n        }\n        assert(bestIdx != -1);\n        assigned[k] = bestA;\n        freeList[bestIdx] = bestB;\n    }\n\n    // store output order\n    outRect[d] = assigned;\n\n    // update global partition maps for next day\n    for (int i = 0; i < W; ++i) Hseg[i].reset();\n    for (int j = 0; j < W; ++j) Vseg[j].reset();\n    for (const auto& r : assigned) {\n        int i0 = r.i0, j0 = r.j0, i1 = r.i1, j1 = r.j1;\n        if (i0 > 0)      for (int j = j0; j < j1; ++j) Hseg[i0].set(j);\n        if (i1 < W)      for (int j = j0; j < j1; ++j) Hseg[i1].set(j);\n        if (j0 > 0)      for (int i = i0; i < i1; ++i) Vseg[i].set(j0);\n        if (j1 < W)      for (int i = i0; i < i1; ++i) Vseg[i].set(j1);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> W >> D >> N;\n    a.assign(D, vector<int>(N));\n    for (int d = 0; d < D; ++d)\n        for (int k = 0; k < N; ++k)\n            cin >> a[d][k];\n\n    outRect.assign(D, vector<Rect>(N));\n\n    // initialize partitions: none\n    for (int i = 0; i < W; ++i) {\n        Hseg[i].reset();\n        Vseg[i].reset();\n    }\n\n    for (int d = 0; d < D; ++d) {\n        solveDay(d);\n    }\n\n    // output\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            const auto& r = outRect[d][k];\n            cout << r.i0 << ' ' << r.j0 << ' ' << r.i1 << ' ' << r.j1 << '\\n';\n        }\n    }\n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <tuple>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\nconst int MOD = 998244353;\nconst int N = 9;\nconst int M = 20;\nconst int K = 81;\n\nint board[N][N];\nint stamps[M][3][3];\nint temp_board[N][N];\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint compute_marginal(int m, int p, int q) {\n    int gain = 0;\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            int original = board[p + i][q + j] % MOD;\n            int new_val = (board[p + i][q + j] + stamps[m][i][j]) % MOD;\n            gain += new_val - original;\n        }\n    }\n    return gain;\n}\n\nvoid apply_stamp(int m, int p, int q) {\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            board[p + i][q + j] = (board[p + i][q + j] + stamps[m][i][j]) % MOD;\n        }\n    }\n}\n\nvoid revert_stamp(int m, int p, int q) {\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            board[p + i][q + j] = (board[p + i][q + j] - stamps[m][i][j] % MOD + MOD) % MOD;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n, m, k;\n    cin >> n >> m >> k;\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cin >> board[i][j];\n        }\n    }\n    for (int mm = 0; mm < m; ++mm) {\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                cin >> stamps[mm][i][j];\n            }\n        }\n    }\n\n    vector<tuple<int, int, int>> operations;\n\n    for (int step = 0; step < k; ++step) {\n        vector<tuple<int, int, int, int>> candidates; // (gain, m, p, q)\n        for (int mm = 0; mm < m; ++mm) {\n            for (int p = 0; p <= n - 3; ++p) {\n                for (int q = 0; q <= n - 3; ++q) {\n                    int gain = compute_marginal(mm, p, q);\n                    candidates.emplace_back(gain, mm, p, q);\n                }\n            }\n        }\n\n        sort(candidates.rbegin(), candidates.rend());\n        bool found = false;\n\n        // Try top 10 candidates with lookahead 2\n        for (int attempt = 0; attempt < min(10, (int)candidates.size()); ++attempt) {\n            auto [gain1, m1, p1, q1] = candidates[attempt];\n            if (gain1 <= 0 && attempt > 0) break;\n\n            apply_stamp(m1, p1, q1);\n\n            // Lookahead: find best second step\n            int best_gain2 = -1e9;\n            int best_m2 = -1, best_p2 = -1, best_q2 = -1;\n            for (int mm = 0; mm < m; ++mm) {\n                for (int p = 0; p <= n - 3; ++p) {\n                    for (int q = 0; q <= n - 3; ++q) {\n                        int gain2 = compute_marginal(mm, p, q);\n                        if (gain2 > best_gain2) {\n                            best_gain2 = gain2;\n                            best_m2 = mm;\n                            best_p2 = p;\n                            best_q2 = q;\n                        }\n                    }\n                }\n            }\n\n            if (gain1 + best_gain2 > 0) {\n                operations.emplace_back(m1, p1, q1);\n                found = true;\n                break;\n            } else {\n                revert_stamp(m1, p1, q1);\n            }\n        }\n\n        if (!found) {\n            // Random exploration\n            uniform_int_distribution<int> dist_m(0, m - 1);\n            uniform_int_distribution<int> dist_p(0, n - 3);\n            uniform_int_distribution<int> dist_q(0, n - 3);\n            int m_rand = dist_m(rng);\n            int p_rand = dist_p(rng);\n            int q_rand = dist_q(rng);\n            operations.emplace_back(m_rand, p_rand, q_rand);\n            apply_stamp(m_rand, p_rand, q_rand);\n        }\n    }\n\n    cout << operations.size() << '\\n';\n    for (auto [mm, p, q] : operations) {\n        cout << mm << ' ' << p << ' ' << q << '\\n';\n    }\n\n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <string>\n\nusing namespace std;\n\nconst int MAX_N = 5;\n\nint N;\nint A[MAX_N][MAX_N];\nvector<string> operations(MAX_N);\n\n// Current state\nint grid[MAX_N][MAX_N];\nint crane_pos[MAX_N][2];\nbool crane_carry[MAX_N];\nint crane_container[MAX_N];\nbool crane_alive[MAX_N];\n\n// Movement planning\nint planned_pos[MAX_N][2];  // Planned positions for next turn\nchar planned_move[MAX_N];\n\nint get_target_gate(int container) {\n    return container / N;\n}\n\nbool is_valid_position(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N;\n}\n\nbool can_crane_move_to(int crane_id, int target_x, int target_y) {\n    if (!is_valid_position(target_x, target_y)) return false;\n    \n    // Check if position is occupied by another crane (current positions)\n    for (int i = 0; i < N; i++) {\n        if (i != crane_id && crane_alive[i] && crane_pos[i][0] == target_x && crane_pos[i][1] == target_y) {\n            return false;\n        }\n    }\n    \n    // Small crane carrying cannot move to occupied square\n    if (crane_id > 0 && crane_carry[crane_id] && grid[target_x][target_y] != -1) {\n        return false;\n    }\n    \n    return true;\n}\n\nbool would_cause_collision(int crane_id, int target_x, int target_y) {\n    // Check against all other planned positions\n    for (int i = 0; i < N; i++) {\n        if (i != crane_id && crane_alive[i]) {\n            if (planned_pos[i][0] == target_x && planned_pos[i][1] == target_y) {\n                return true;\n            }\n            // Check for swap collisions\n            if (planned_pos[i][0] == crane_pos[crane_id][0] && planned_pos[i][1] == crane_pos[crane_id][1] &&\n                planned_pos[crane_id][0] == crane_pos[i][0] && planned_pos[crane_id][1] == crane_pos[i][1]) {\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\nvoid simulate_turn(const vector<char>& moves) {\n    // Step 1: Receive containers\n    static int received_count[MAX_N] = {0};\n    for (int i = 0; i < N; i++) {\n        if (grid[i][0] == -1 && !crane_carry[i] && received_count[i] < N) {\n            bool occupied = false;\n            for (int j = 0; j < N; j++) {\n                if (crane_pos[j][0] == i && crane_pos[j][1] == 0 && crane_alive[j]) {\n                    occupied = true;\n                    break;\n                }\n            }\n            if (!occupied) {\n                grid[i][0] = A[i][received_count[i]];\n                received_count[i]++;\n            }\n        }\n    }\n    \n    // Step 2: Execute crane moves\n    for (int i = 0; i < N && i < (int)moves.size(); i++) {\n        if (!crane_alive[i]) continue;\n        \n        char move = moves[i];\n        \n        if (move == 'P') {\n            if (!crane_carry[i] && grid[crane_pos[i][0]][crane_pos[i][1]] != -1) {\n                crane_carry[i] = true;\n                crane_container[i] = grid[crane_pos[i][0]][crane_pos[i][1]];\n                grid[crane_pos[i][0]][crane_pos[i][1]] = -1;\n            }\n        } else if (move == 'Q') {\n            if (crane_carry[i] && grid[crane_pos[i][0]][crane_pos[i][1]] == -1) {\n                crane_carry[i] = false;\n                grid[crane_pos[i][0]][crane_pos[i][1]] = crane_container[i];\n                crane_container[i] = -1;\n            }\n        } else if (move == 'U' && can_crane_move_to(i, crane_pos[i][0] - 1, crane_pos[i][1])) {\n            crane_pos[i][0]--;\n        } else if (move == 'D' && can_crane_move_to(i, crane_pos[i][0] + 1, crane_pos[i][1])) {\n            crane_pos[i][0]++;\n        } else if (move == 'L' && can_crane_move_to(i, crane_pos[i][0], crane_pos[i][1] - 1)) {\n            crane_pos[i][1]--;\n        } else if (move == 'R' && can_crane_move_to(i, crane_pos[i][0], crane_pos[i][1] + 1)) {\n            crane_pos[i][1]++;\n        } else if (move == 'B') {\n            if (!crane_carry[i]) {\n                crane_alive[i] = false;\n            }\n        }\n    }\n    \n    // Step 3: Dispatch containers\n    for (int i = 0; i < N; i++) {\n        if (grid[i][N-1] != -1) {\n            grid[i][N-1] = -1;\n        }\n    }\n}\n\nint main() {\n    cin >> N;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> A[i][j];\n        }\n    }\n    \n    // Initialize state\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = -1;\n        }\n        crane_pos[i][0] = i;\n        crane_pos[i][1] = 0;\n        crane_carry[i] = false;\n        crane_container[i] = -1;\n        crane_alive[i] = true;\n        operations[i] = \"\";\n        planned_pos[i][0] = i;\n        planned_pos[i][1] = 0;\n        planned_move[i] = '.';\n    }\n    \n    // Ultra-conservative strategy: Priority-based movement with collision avoidance\n    int turns = 0;\n    const int max_turns = 4000;\n    \n    while (turns < max_turns) {\n        vector<char> current_moves(N, '.');\n        \n        // Reset planned positions\n        for (int i = 0; i < N; i++) {\n            planned_pos[i][0] = crane_pos[i][0];\n            planned_pos[i][1] = crane_pos[i][1];\n            planned_move[i] = '.';\n        }\n        \n        // Plan moves in priority order (large crane first, then by position)\n        for (int priority = 0; priority < N; priority++) {\n            int i = (priority == 0) ? 0 : priority; // Large crane has highest priority\n            \n            if (!crane_alive[i]) continue;\n            \n            int x = crane_pos[i][0];\n            int y = crane_pos[i][1];\n            \n            if (!crane_carry[i]) {\n                // Try to pick up container if available\n                if (grid[x][y] != -1) {\n                    int new_x = x, new_y = y;\n                    if (!would_cause_collision(i, new_x, new_y)) {\n                        current_moves[i] = 'P';\n                        planned_pos[i][0] = new_x;\n                        planned_pos[i][1] = new_y;\n                        planned_move[i] = 'P';\n                        continue;\n                    }\n                }\n                \n                // Safe movement: prefer right, then down/up\n                bool moved = false;\n                \n                // Try right\n                if (!moved && y < N-1 && can_crane_move_to(i, x, y+1)) {\n                    int new_x = x, new_y = y+1;\n                    if (!would_cause_collision(i, new_x, new_y)) {\n                        current_moves[i] = 'R';\n                        planned_pos[i][0] = new_x;\n                        planned_pos[i][1] = new_y;\n                        planned_move[i] = 'R';\n                        moved = true;\n                    }\n                }\n                \n                // Try down (if not at bottom)\n                if (!moved && x < N-1 && can_crane_move_to(i, x+1, y)) {\n                    int new_x = x+1, new_y = y;\n                    if (!would_cause_collision(i, new_x, new_y)) {\n                        current_moves[i] = 'D';\n                        planned_pos[i][0] = new_x;\n                        planned_pos[i][1] = new_y;\n                        planned_move[i] = 'D';\n                        moved = true;\n                    }\n                }\n                \n                // Try up (if not at top)\n                if (!moved && x > 0 && can_crane_move_to(i, x-1, y)) {\n                    int new_x = x-1, new_y = y;\n                    if (!would_cause_collision(i, new_x, new_y)) {\n                        current_moves[i] = 'U';\n                        planned_pos[i][0] = new_x;\n                        planned_pos[i][1] = new_y;\n                        planned_move[i] = 'U';\n                        moved = true;\n                    }\n                }\n                \n                // Try left (last resort)\n                if (!moved && y > 0 && can_crane_move_to(i, x, y-1)) {\n                    int new_x = x, new_y = y-1;\n                    if (!would_cause_collision(i, new_x, new_y)) {\n                        current_moves[i] = 'L';\n                        planned_pos[i][0] = new_x;\n                        planned_pos[i][1] = new_y;\n                        planned_move[i] = 'L';\n                        moved = true;\n                    }\n                }\n            } else {\n                // Carrying container - move to dispatch area\n                bool moved = false;\n                \n                // Try to move right (toward dispatch)\n                if (y < N-1 && can_crane_move_to(i, x, y+1)) {\n                    int new_x = x, new_y = y+1;\n                    if (!would_cause_collision(i, new_x, new_y)) {\n                        current_moves[i] = 'R';\n                        planned_pos[i][0] = new_x;\n                        planned_pos[i][1] = new_y;\n                        planned_move[i] = 'R';\n                        moved = true;\n                    }\n                }\n                \n                // If at dispatch gate, drop container\n                if (!moved && y == N-1) {\n                    current_moves[i] = 'Q';\n                    planned_pos[i][0] = x;\n                    planned_pos[i][1] = y;\n                    planned_move[i] = 'Q';\n                    moved = true;\n                }\n                \n                // Try alternative directions if stuck\n                if (!moved) {\n                    if (x < N-1 && can_crane_move_to(i, x+1, y)) {\n                        int new_x = x+1, new_y = y;\n                        if (!would_cause_collision(i, new_x, new_y)) {\n                            current_moves[i] = 'D';\n                            planned_pos[i][0] = new_x;\n                            planned_pos[i][1] = new_y;\n                            planned_move[i] = 'D';\n                            moved = true;\n                        }\n                    }\n                    if (!moved && x > 0 && can_crane_move_to(i, x-1, y)) {\n                        int new_x = x-1, new_y = y;\n                        if (!would_cause_collision(i, new_x, new_y)) {\n                            current_moves[i] = 'U';\n                            planned_pos[i][0] = new_x;\n                            planned_pos[i][1] = new_y;\n                            planned_move[i] = 'U';\n                            moved = true;\n                        }\n                    }\n                }\n            }\n        }\n        \n        simulate_turn(current_moves);\n        \n        // Record operations\n        for (int i = 0; i < N; i++) {\n            operations[i] += current_moves[i];\n        }\n        \n        turns++;\n    }\n    \n    // Ensure all strings have same length\n    size_t max_len = 0;\n    for (int i = 0; i < N; i++) {\n        max_len = max(max_len, operations[i].size());\n    }\n    \n    for (int i = 0; i < N; i++) {\n        while (operations[i].size() < max_len) {\n            operations[i] += '.';\n        }\n    }\n    \n    // Output operations\n    for (int i = 0; i < N; i++) {\n        cout << operations[i] << endl;\n    }\n    \n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nint h[20][20];\nvector<string> out;\n\nstruct Pt { int i, j, a; };\nvector<Pt> src, snk;\n\nint md(const Pt &x, const Pt &y) {\n    return abs(x.i - y.i) + abs(x.j - y.j);\n}\n\nvoid go(int di, int dj) {\n    if (di > 0) for (int k = 0; k < di; ++k) out.push_back(\"D\");\n    if (di < 0) for (int k = 0; k < -di; ++k) out.push_back(\"U\");\n    if (dj > 0) for (int k = 0; k < dj; ++k) out.push_back(\"R\");\n    if (dj < 0) for (int k = 0; k < -dj; ++k) out.push_back(\"L\");\n}\n\n// 2-opt \u6539\u5584\u56de\u8def\ntemplate<typename T>\nvoid twoOpt(vector<T> &route, int rounds = 50) {\n    int n = route.size();\n    if (n < 4) return;\n    while (rounds--) {\n        bool improved = false;\n        for (int i = 0; i < n - 1; ++i) {\n            for (int j = i + 2; j < n; ++j) {\n                int old = md(route[i], route[i + 1]) + md(route[j], route[(j + 1) % n]);\n                int neq = md(route[i], route[j]) + md(route[i + 1], route[(j + 1) % n]);\n                if (neq < old) {\n                    reverse(route.begin() + i + 1, route.begin() + j + 1);\n                    improved = true;\n                }\n            }\n        }\n        if (!improved) break;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            cin >> h[i][j];\n            if (h[i][j] > 0) src.push_back({i, j, h[i][j]});\n            else if (h[i][j] < 0) snk.push_back({i, j, -h[i][j]});\n        }\n\n    // 1. \u6e90\u70b9\uff1aNN \u2192 2-opt\n    auto buildNN = [](vector<Pt> &v) {\n        if (v.empty()) return;\n        vector<char> used(v.size(), 0);\n        for (size_t rem = 0; rem < v.size(); ++rem) {\n            if (rem == 0) { used[0] = 1; continue; }\n            int best = INT_MAX, nxt = -1;\n            for (size_t i = 0; i < v.size(); ++i) if (!used[i]) {\n                int d = md(v[rem - 1], v[i]);\n                if (d < best) { best = d; nxt = (int)i; }\n            }\n            used[nxt] = 1;\n            swap(v[rem], v[nxt]);\n        }\n    };\n    buildNN(src);\n    twoOpt(src, 50);\n\n    // 2. \u6c47\u70b9\uff1a\u5b8c\u5168\u52a8\u6001 NN\uff0c\u6876\u54c8\u5e0c\u52a0\u901f\n    const int B = 5;\n    vector<vector<int>> bucket(B * B);\n    vector<int> need(snk.size());\n    for (size_t i = 0; i < snk.size(); ++i) {\n        need[i] = snk[i].a;\n        int bi = snk[i].i / B, bj = snk[i].j / B;\n        bucket[bi * B + bj].push_back(i);\n    }\n\n    int ci = 0, cj = 0;\n\n    // 3. \u6309 2-opt \u6e90\u5e8f\u6536\u96c6\n    for (auto &s : src) {\n        go(s.i - ci, s.j - cj);\n        ci = s.i; cj = s.j;\n        out.push_back(\"+\" + to_string(s.a));\n        int load = s.a;\n\n        // 4. \u52a8\u6001\u6700\u8fd1\u90bb\u5378\u8d27\uff0c\u6876\u54c8\u5e0c\u52a0\u901f\n        while (load > 0) {\n            int bi = clamp(ci / B, 0, B - 1), bj = clamp(cj / B, 0, B - 1);\n            int best = INT_MAX, bidx = -1, bgive = 0;\n            // 3x3 \u7a97\u53e3\n            for (int db = -1; db <= 1; ++db) {\n                for (int da = -1; da <= 1; ++da) {\n                    int nb = bi + db, na = bj + da;\n                    if (nb < 0 || nb >= B || na < 0 || na >= B) continue;\n                    auto &vec = bucket[nb * B + na];\n                    for (int idx : vec) if (need[idx]) {\n                        int d = md({ci, cj, 0}, snk[idx]);\n                        if (d < best) {\n                            best = d; bidx = idx; bgive = min(load, need[idx]);\n                        }\n                    }\n                }\n            }\n            if (bidx == -1) {\n                // 5x5 \u7a97\u53e3\n                for (int db = -2; db <= 2; ++db) {\n                    for (int da = -2; da <= 2; ++da) {\n                        int nb = bi + db, na = bj + da;\n                        if (nb < 0 || nb >= B || na < 0 || na >= B) continue;\n                        if (abs(db) <= 1 && abs(da) <= 1) continue;\n                        auto &vec = bucket[nb * B + na];\n                        for (int idx : vec) if (need[idx]) {\n                            int d = md({ci, cj, 0}, snk[idx]);\n                            if (d < best) {\n                                best = d; bidx = idx; bgive = min(load, need[idx]);\n                            }\n                        }\n                    }\n                }\n            }\n            if (bidx == -1) {\n                // \u5168\u5c40 fallback\n                for (size_t i = 0; i < snk.size(); ++i) if (need[i]) {\n                    int d = md({ci, cj, 0}, snk[i]);\n                    if (d < best) {\n                        best = d; bidx = (int)i; bgive = min(load, need[i]);\n                    }\n                }\n            }\n            if (bidx == -1) break; // \u5b89\u5168\n            auto &t = snk[bidx];\n            go(t.i - ci, t.j - cj);\n            ci = t.i; cj = t.j;\n            out.push_back(\"-\" + to_string(bgive));\n            load -= bgive;\n            need[bidx] -= bgive;\n        }\n    }\n\n    // 5. \u8865\u6f0f\n    for (size_t i = 0; i < snk.size(); ++i) if (need[i]) {\n        auto &t = snk[i];\n        go(t.i - ci, t.j - cj);\n        ci = t.i; cj = t.j;\n        out.push_back(\"-\" + to_string(need[i]));\n    }\n\n    for (auto &s : out) cout << s << '\\n';\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n\nusing namespace std;\n\nint main() {\n    int N, M, T;\n    cin >> N >> M >> T;\n    \n    const int seed_count = 2 * N * (N - 1);\n    vector<vector<int>> seeds(seed_count, vector<int>(M));\n    vector<int> seed_values(seed_count);\n    \n    // Read initial seeds\n    for (int i = 0; i < seed_count; i++) {\n        for (int j = 0; j < M; j++) {\n            cin >> seeds[i][j];\n        }\n    }\n    \n    for (int turn = 0; turn < T; turn++) {\n        // Calculate current seed values\n        for (int i = 0; i < seed_count; i++) {\n            seed_values[i] = 0;\n            for (int j = 0; j < M; j++) {\n                seed_values[i] += seeds[i][j];\n            }\n        }\n        \n        // Simple strategy: select top 36 seeds by value\n        vector<int> indices(seed_count);\n        for (int i = 0; i < seed_count; i++) {\n            indices[i] = i;\n        }\n        \n        // Sort by value (stable sort)\n        sort(indices.begin(), indices.end(), [&](int a, int b) {\n            return seed_values[a] > seed_values[b];\n        });\n        \n        // Create grid using top seeds\n        vector<vector<int>> grid(N, vector<int>(N));\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int pos = i * N + j;\n                if (pos < 36) {  // Ensure we don't go out of bounds\n                    grid[i][j] = indices[pos];\n                } else {\n                    grid[i][j] = indices[pos % 36];\n                }\n            }\n        }\n        \n        // Output grid\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << grid[i][j];\n                if (j < N - 1) cout << \" \";\n            }\n            cout << endl;\n        }\n        cout.flush();\n        \n        // Read new seeds\n        for (int i = 0; i < seed_count; i++) {\n            for (int j = 0; j < M; j++) {\n                cin >> seeds[i][j];\n            }\n        }\n    }\n    \n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, V;\nvector<string> initial_s, target_t;\nvector<string> current_grid; // Track current state\nvector<vector<int>> children;\nvector<int> parent;\nvector<int> edge_length;\nint root_x, root_y;\n\n// Track current positions of all vertices\nvector<pair<int, int>> vertex_positions;\nvector<int> edge_directions;\n\n// Track held takoyaki\nvector<bool> holding_takoyaki;\n\n// Find positions of 1s in grid\nvector<pair<int, int>> find_positions(const vector<string>& grid) {\n    vector<pair<int, int>> positions;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] == '1') {\n                positions.push_back({i, j});\n            }\n        }\n    }\n    return positions;\n}\n\n// Calculate position of vertex based on parent and edge configuration\npair<int, int> calculate_position(int v) {\n    if (v == 0) return {root_x, root_y};\n    \n    int p = parent[v];\n    auto parent_pos = vertex_positions[p];\n    int dir = edge_directions[v];\n    int len = edge_length[v];\n    \n    int dx[] = {0, 1, 0, -1};\n    int dy[] = {1, 0, -1, 0};\n    \n    return {parent_pos.first + dx[dir] * len, parent_pos.second + dy[dir] * len};\n}\n\n// Update all positions after movement/rotation\nvoid update_positions() {\n    for (int i = 0; i < V; i++) {\n        vertex_positions[i] = calculate_position(i);\n    }\n}\n\n// Build a compact tree with shorter edges\nvoid design_arm() {\n    children.resize(V);\n    parent.resize(V, -1);\n    edge_length.resize(V, 1);\n    vertex_positions.resize(V);\n    edge_directions.resize(V, 0);\n    holding_takoyaki.resize(V, false);\n    \n    // Create a simple structure with clear fingertips\n    if (V >= 3) {\n        // Root -> intermediate -> fingertip structure\n        for (int i = 1; i < V; i++) {\n            parent[i] = i - 1;\n            edge_length[i] = min(2, N / 3);\n            children[i-1].push_back(i);\n        }\n    } else {\n        // Simple chain for small V\n        for (int i = 1; i < V; i++) {\n            parent[i] = 0;\n            edge_length[i] = min(2, N / 3);\n            children[0].push_back(i);\n        }\n    }\n    \n    // Place root in center\n    root_x = N / 2;\n    root_y = N / 2;\n    \n    update_positions();\n}\n\n// Get all leaf nodes (fingertips)\nvector<int> get_fingertips() {\n    vector<int> fingertips;\n    for (int i = 0; i < V; i++) {\n        if (children[i].empty()) {\n            fingertips.push_back(i);\n        }\n    }\n    return fingertips;\n}\n\n// Check if position is valid and contains takoyaki\nbool can_grab_at(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N && current_grid[x][y] == '1';\n}\n\n// Check if position is valid and empty for placement\nbool can_release_at(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N && current_grid[x][y] == '0' && target_t[x][y] == '1';\n}\n\n// Generate intelligent operations\nvector<string> generate_operations() {\n    vector<string> ops;\n    vector<int> fingertips = get_fingertips();\n    vector<pair<int, int>> sources = find_positions(initial_s);\n    vector<pair<int, int>> targets = find_positions(target_t);\n    \n    // Create mapping from positions to track progress\n    set<pair<int, int>> remaining_sources;\n    for (auto& pos : sources) remaining_sources.insert(pos);\n    \n    int turn_count = 0;\n    const int max_turns = 50000;\n    \n    // Systematic coverage with intelligent grab/release\n    for (int sweep = 0; sweep < 4 && turn_count < max_turns; sweep++) {\n        // Spiral inward from corners\n        for (int step = 0; step < N && turn_count < max_turns; step++) {\n            for (int inner = 0; inner < 4 && turn_count < max_turns; inner++) {\n                string op(2 * V, '.');\n                \n                // Move in systematic pattern\n                int target_x = (sweep == 0) ? step : (sweep == 1) ? N-1-step : (sweep == 2) ? step : N-1-step;\n                int target_y = (inner * N/4) % N;\n                \n                // Move root toward target\n                if (root_x < target_x && root_x + 1 < N) {\n                    root_x++;\n                    op[0] = 'D';\n                } else if (root_x > target_x && root_x - 1 >= 0) {\n                    root_x--;\n                    op[0] = 'U';\n                } else if (root_y < target_y && root_y + 1 < N) {\n                    root_y++;\n                    op[0] = 'R';\n                } else if (root_y > target_y && root_y - 1 >= 0) {\n                    root_y--;\n                    op[0] = 'L';\n                }\n                \n                update_positions();\n                \n                // Check each fingertip for possible actions\n                for (int fingertip : fingertips) {\n                    auto pos = vertex_positions[fingertip];\n                    int x = pos.first, y = pos.second;\n                    \n                    if (!holding_takoyaki[fingertip] && can_grab_at(x, y)) {\n                        // Grab takoyaki\n                        op[V + fingertip] = 'P';\n                        holding_takoyaki[fingertip] = true;\n                        current_grid[x][y] = '0';\n                        remaining_sources.erase({x, y});\n                        break; // Only one action per turn\n                    } else if (holding_takoyaki[fingertip] && can_release_at(x, y)) {\n                        // Release takoyaki\n                        op[V + fingertip] = 'P';\n                        holding_takoyaki[fingertip] = false;\n                        current_grid[x][y] = '1';\n                        break; // Only one action per turn\n                    }\n                }\n                \n                ops.push_back(op);\n                turn_count++;\n            }\n        }\n    }\n    \n    return ops;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> V;\n    \n    initial_s.resize(N);\n    target_t.resize(N);\n    \n    for (int i = 0; i < N; i++) {\n        cin >> initial_s[i];\n    }\n    for (int i = 0; i < N; i++) {\n        cin >> target_t[i];\n    }\n    \n    // Initialize current grid\n    current_grid = initial_s;\n    \n    // Design and output arm\n    design_arm();\n    \n    cout << V << \"\\n\";\n    for (int i = 1; i < V; i++) {\n        cout << parent[i] << \" \" << edge_length[i] << \"\\n\";\n    }\n    cout << root_x << \" \" << root_y << \"\\n\";\n    \n    // Generate and output operations\n    auto operations = generate_operations();\n    \n    for (const auto& op : operations) {\n        cout << op << \"\\n\";\n    }\n    \n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    Point(int x = 0, int y = 0) : x(x), y(y) {}\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\nstruct Fish {\n    int x, y, type;\n    Fish(int x = 0, int y = 0, int type = 0) : x(x), y(y), type(type) {}\n};\n\nint N;\nvector<Fish> fishes;\nvector<Point> polygon;\n\n// Ray casting algorithm for point-in-polygon\nbool pointInPolygon(int x, int y, const vector<Point>& poly) {\n    int n = poly.size();\n    bool inside = false;\n    \n    for (int i = 0, j = n - 1; i < n; j = i++) {\n        if (((poly[i].y > y) != (poly[j].y > y)) &&\n            (x < (poly[j].x - poly[i].x) * (y - poly[i].y) / (poly[j].y - poly[i].y) + poly[i].x)) {\n            inside = !inside;\n        }\n    }\n    return inside;\n}\n\n// Count fish inside polygon\npair<int,int> countFishInPolygon(const vector<Point>& poly) {\n    int mackerels = 0, sardines = 0;\n    for (const auto& fish : fishes) {\n        if (pointInPolygon(fish.x, fish.y, poly)) {\n            if (fish.type == 0) mackerels++;\n            else sardines++;\n        }\n    }\n    return {mackerels, sardines};\n}\n\n// Calculate polygon perimeter\nint calculatePerimeter(const vector<Point>& poly) {\n    int perimeter = 0;\n    int n = poly.size();\n    for (int i = 0; i < n; i++) {\n        int j = (i + 1) % n;\n        perimeter += abs(poly[j].x - poly[i].x) + abs(poly[j].y - poly[i].y);\n    }\n    return perimeter;\n}\n\n// Create rectangle polygon\nvector<Point> createRectangle(int x1, int y1, int x2, int y2) {\n    return {Point(x1, y1), Point(x2, y1), Point(x2, y2), Point(x1, y2)};\n}\n\n// Find high-quality rectangular regions\nvector<tuple<int,int,int,int,int,int>> findQualityRectangles() {\n    vector<tuple<int,int,int,int,int,int>> rectangles; // x1,y1,x2,y2,score,perimeter\n    \n    // Use multiple scales and aspect ratios\n    const int WIDTHS[] = {6000, 8000, 12000, 16000, 20000, 25000};\n    const int HEIGHTS[] = {6000, 8000, 12000, 16000, 20000, 25000};\n    \n    for (int width : WIDTHS) {\n        for (int height : HEIGHTS) {\n            int x_step = width / 3;\n            int y_step = height / 3;\n            \n            for (int x = 0; x + width <= 100000; x += x_step) {\n                for (int y = 0; y + height <= 100000; y += y_step) {\n                    int x2 = x + width;\n                    int y2 = y + height;\n                    \n                    // Quick count of fish in region\n                    int mackerels = 0, sardines = 0;\n                    for (const auto& fish : fishes) {\n                        if (fish.x >= x && fish.x <= x2 && fish.y >= y && fish.y <= y2) {\n                            if (fish.type == 0) mackerels++;\n                            else sardines++;\n                        }\n                    }\n                    \n                    if (mackerels > 15) { // Minimum threshold\n                        int score = max(0, mackerels - sardines + 1);\n                        int perimeter = (width + height) * 2;\n                        double efficiency = (double)score / perimeter;\n                        \n                        if (efficiency > 0.01 || score > 1000) { // Good efficiency or high absolute score\n                            rectangles.push_back({x, y, x2, y2, score, perimeter});\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Sort by efficiency (score per perimeter) then by absolute score\n    sort(rectangles.begin(), rectangles.end(), \n         [](const auto& a, const auto& b) {\n             double eff_a = (double)get<4>(a) / get<5>(a);\n             double eff_b = (double)get<4>(b) / get<5>(b);\n             if (abs(eff_a - eff_b) > 0.001) return eff_a > eff_b;\n             return get<4>(a) > get<4>(b);\n         });\n    \n    return rectangles;\n}\n\n// Find non-overlapping high-quality rectangles\nvector<vector<Point>> findNonOverlappingRectangles() {\n    auto rectangles = findQualityRectangles();\n    vector<vector<Point>> selected;\n    vector<tuple<int,int,int,int>> selected_coords;\n    \n    int total_perimeter = 0;\n    const int MAX_PERIMETER = 350000; // Leave some margin\n    \n    for (const auto& rect : rectangles) {\n        int x1 = get<0>(rect), y1 = get<1>(rect);\n        int x2 = get<2>(rect), y2 = get<3>(rect);\n        int score = get<4>(rect), perimeter = get<5>(rect);\n        \n        // Check if this rectangle overlaps too much with already selected ones\n        bool too_much_overlap = false;\n        for (const auto& existing : selected_coords) {\n            int ex1 = get<0>(existing), ey1 = get<1>(existing);\n            int ex2 = get<2>(existing), ey2 = get<3>(existing);\n            \n            // Calculate overlap area\n            int ox1 = max(x1, ex1), oy1 = max(y1, ey1);\n            int ox2 = min(x2, ex2), oy2 = min(y2, ey2);\n            \n            if (ox2 > ox1 && oy2 > oy1) {\n                int overlap_area = (ox2 - ox1) * (oy2 - oy1);\n                int rect_area = (x2 - x1) * (y2 - y1);\n                \n                if (overlap_area > rect_area * 0.4) { // More than 40% overlap\n                    too_much_overlap = true;\n                    break;\n                }\n            }\n        }\n        \n        if (!too_much_overlap && total_perimeter + perimeter <= MAX_PERIMETER) {\n            selected.push_back(createRectangle(x1, y1, x2, y2));\n            selected_coords.push_back({x1, y1, x2, y2});\n            total_perimeter += perimeter;\n            \n            if (selected.size() >= 3) break; // Limit to 3 rectangles max\n        }\n    }\n    \n    return selected;\n}\n\n// Create combined polygon from multiple rectangles (simple union approach)\nvector<Point> createCombinedPolygon(const vector<vector<Point>>& rectangles) {\n    if (rectangles.empty()) {\n        return createRectangle(15000, 15000, 75000, 75000);\n    }\n    \n    if (rectangles.size() == 1) {\n        return rectangles[0];\n    }\n    \n    // For now, just return the best single rectangle\n    // Multi-rectangle union would require complex polygon operations\n    int best_score = -1;\n    vector<Point> best_rect;\n    \n    for (const auto& rect : rectangles) {\n        auto [m, s] = countFishInPolygon(rect);\n        int score = max(0, m - s + 1);\n        if (score > best_score) {\n            best_score = score;\n            best_rect = rect;\n        }\n    }\n    \n    return best_rect;\n}\n\n// Advanced rectangle optimization with sardine avoidance\nvector<Point> optimizeRectangleWithHoles(int x1, int y1, int x2, int y2) {\n    auto base_rect = createRectangle(x1, y1, x2, y2);\n    auto [base_m, base_s] = countFishInPolygon(base_rect);\n    int base_score = max(0, base_m - base_s + 1);\n    \n    // Find dense sardine clusters within this rectangle\n    map<pair<int,int>, vector<Point>> sardine_clusters;\n    \n    for (const auto& fish : fishes) {\n        if (fish.type == 1 && fish.x >= x1 && fish.x <= x2 && fish.y >= y1 && fish.y <= y2) {\n            int gx = (fish.x / 3000) * 3000;\n            int gy = (fish.y / 3000) * 3000;\n            sardine_clusters[{gx, gy}].push_back(Point(fish.x, fish.y));\n        }\n    }\n    \n    // If we found major sardine clusters, try to shrink the rectangle\n    vector<pair<int,int>> dense_sardines;\n    for (const auto& [center, sardines] : sardine_clusters) {\n        if (sardines.size() > 5) {\n            dense_sardines.push_back(center);\n        }\n    }\n    \n    if (!dense_sardines.empty()) {\n        // Try shrinking from edges that have dense sardines\n        int shrink_x1 = 0, shrink_y1 = 0, shrink_x2 = 0, shrink_y2 = 0;\n        \n        for (const auto& center : dense_sardines) {\n            if (center.first < x1 + (x2-x1)/3) shrink_x1 = max(shrink_x1, 2000);\n            if (center.first > x2 - (x2-x1)/3) shrink_x2 = max(shrink_x2, 2000);\n            if (center.second < y1 + (y2-y1)/3) shrink_y1 = max(shrink_y1, 2000);\n            if (center.second > y2 - (y2-y1)/3) shrink_y2 = max(shrink_y2, 2000);\n        }\n        \n        int new_x1 = min(x2 - 5000, x1 + shrink_x1);\n        int new_y1 = min(y2 - 5000, y1 + shrink_y1);\n        int new_x2 = max(x1 + 5000, x2 - shrink_x2);\n        int new_y2 = max(y1 + 5000, y2 - shrink_y2);\n        \n        auto shrunk_rect = createRectangle(new_x1, new_y1, new_x2, new_y2);\n        auto [new_m, new_s] = countFishInPolygon(shrunk_rect);\n        int new_score = max(0, new_m - new_s + 1);\n        \n        if (new_score > base_score) {\n            return shrunk_rect;\n        }\n    }\n    \n    return base_rect;\n}\n\n// Find the optimal rectangle using advanced techniques\nvector<Point> findOptimalAdvanced() {\n    // First try multi-rectangle approach\n    auto rectangles = findNonOverlappingRectangles();\n    if (rectangles.size() > 1) {\n        return createCombinedPolygon(rectangles);\n    }\n    \n    // Fall back to single optimized rectangle\n    auto clusters = findQualityRectangles();\n    if (!clusters.empty()) {\n        auto [x1, y1, x2, y2, score, perimeter] = clusters[0];\n        return optimizeRectangleWithHoles(x1, y1, x2, y2);\n    }\n    \n    // Ultimate fallback\n    return createRectangle(15000, 15000, 80000, 80000);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    \n    // Read fish data\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        fishes.push_back({x, y, 0});\n    }\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        fishes.push_back({x, y, 1});\n    }\n    \n    // Find optimal polygon using advanced algorithm\n    polygon = findOptimalAdvanced();\n    \n    // Final validation\n    if (polygon.size() != 4) {\n        polygon = createRectangle(20000, 20000, 80000, 80000);\n    }\n    \n    // Remove any duplicate points\n    vector<Point> cleaned;\n    for (size_t i = 0; i < polygon.size(); i++) {\n        size_t next = (i + 1) % polygon.size();\n        if (!(polygon[i] == polygon[next])) {\n            cleaned.push_back(polygon[i]);\n        }\n    }\n    polygon = cleaned;\n    \n    if (polygon.size() != 4) {\n        polygon = createRectangle(20000, 20000, 80000, 80000);\n    }\n    \n    cout << polygon.size() << \"\\n\";\n    for (const auto& p : polygon) {\n        cout << p.x << \" \" << p.y << \"\\n\";\n    }\n    \n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\n#include <random>\n#include <chrono>\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint randint(int a, int b) {\n    return uniform_int_distribution<int>(a, b)(rng);\n}\n\nstruct Rect {\n    long long w, h;\n    int idx;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T, sigma;\n    cin >> N >> T >> sigma;\n    vector<Rect> rects(N);\n    for (int i = 0; i < N; i++) {\n        cin >> rects[i].w >> rects[i].h;\n        rects[i].idx = i;\n    }\n\n    const int tries = 120;\n    long long best_obs = LLONG_MAX;\n    vector<tuple<int, int, char, int>> best_seq;\n\n    for (int turn = 0; turn < T; turn++) {\n        const int n = N;\n        vector<long long> xleft(n), ytop(n), width(n), height(n);\n        long long curW = 0, curH = 0;\n        vector<tuple<int, int, char, int>> seq;\n\n        for (int i = 0; i < n; i++) {\n            long long w0 = rects[i].w;\n            long long h0 = rects[i].h;\n\n            int best_r = 0;\n            char best_d = 'U';\n            int best_b = -1;\n            long long best_WH = LLONG_MAX;\n\n            for (int t = 0; t < tries; t++) {\n                int r = randint(0,1);\n                long long wi = (r ? h0 : w0);\n                long long hi = (r ? w0 : h0);\n\n                char d = (randint(0,1) ? 'U' : 'L');\n                int b = -1;\n                if (i > 0) {\n                    if (d == 'U') {\n                        // try rightmost candidate as well\n                        if (t < 30) {\n                            // random\n                            b = randint(-1, i-1);\n                        } else {\n                            // rightmost\n                            long long mx = -1;\n                            int idx = -1;\n                            for (int j = 0; j < i; j++) {\n                                long long rx = xleft[j] + width[j];\n                                if (rx > mx) { mx = rx; idx = j; }\n                            }\n                            b = idx;\n                        }\n                    } else {\n                        // bottommost\n                        if (t < 30) {\n                            b = randint(-1, i-1);\n                        } else {\n                            long long my = -1;\n                            int idx = -1;\n                            for (int j = 0; j < i; j++) {\n                                long long by = ytop[j] + height[j];\n                                if (by > my) { my = by; idx = j; }\n                            }\n                            b = idx;\n                        }\n                    }\n                }\n\n                long long xi, yi;\n                if (d == 'U') {\n                    xi = (b==-1? 0 : xleft[b] + width[b]);\n                    yi = 0;\n                    for (int j = 0; j < i; j++) {\n                        long long x1 = xi, x2 = xi + wi;\n                        long long ox1 = xleft[j], ox2 = xleft[j] + width[j];\n                        if (x2 > ox1 && x1 < ox2) yi = max(yi, ytop[j] + height[j]);\n                    }\n                } else {\n                    yi = (b==-1? 0 : ytop[b] + height[b]);\n                    xi = 0;\n                    for (int j = 0; j < i; j++) {\n                        long long y1 = yi, y2 = yi + hi;\n                        long long oy1 = ytop[j], oy2 = ytop[j] + height[j];\n                        if (y2 > oy1 && y1 < oy2) xi = max(xi, xleft[j] + width[j]);\n                    }\n                }\n                long long newW = max(curW, xi + wi);\n                long long newH = max(curH, yi + hi);\n                long long WH = newW + newH;\n                if (WH < best_WH) {\n                    best_WH = WH;\n                    best_r = r;\n                    best_d = d;\n                    best_b = b;\n                }\n            }\n\n            long long wi = (best_r ? h0 : w0);\n            long long hi = (best_r ? w0 : h0);\n            long long xi, yi;\n            if (best_d == 'U') {\n                xi = (best_b==-1? 0 : xleft[best_b] + width[best_b]);\n                yi = 0;\n                for (int j = 0; j < i; j++) {\n                    long long x1 = xi, x2 = xi + wi;\n                    long long ox1 = xleft[j], ox2 = xleft[j] + width[j];\n                    if (x2 > ox1 && x1 < ox2) yi = max(yi, ytop[j] + height[j]);\n                }\n            } else {\n                yi = (best_b==-1? 0 : ytop[best_b] + height[best_b]);\n                xi = 0;\n                for (int j = 0; j < i; j++) {\n                    long long y1 = yi, y2 = yi + hi;\n                    long long oy1 = ytop[j], oy2 = ytop[j] + height[j];\n                    if (y2 > oy1 && y1 < oy2) xi = max(xi, xleft[j] + width[j]);\n                }\n            }\n            xleft[i] = xi;\n            ytop[i] = yi;\n            width[i] = wi;\n            height[i] = hi;\n            curW = max(curW, xi + wi);\n            curH = max(curH, yi + hi);\n            seq.emplace_back(i, best_r, best_d, best_b);\n        }\n\n        // Exploration / exploitation schedule\n        if (turn >= T * 60 / 100 && !best_seq.empty() && randint(0,1) == 0) {\n            // small perturbation of best sequence\n            auto tmp = best_seq;\n            int k = randint(0, N-1);\n            auto &[p, r, d, b] = tmp[k];\n            r ^= 1;               // flip rotation\n            if (k > 0) b = randint(-1, k-1); // new random ref\n            cout << N << '\\n';\n            for (auto [pp,rr,dd,bb] : tmp) cout << pp << ' ' << rr << ' ' << dd << ' ' << bb << '\\n';\n            cout.flush();\n        } else if (turn >= T * 60 / 100 && !best_seq.empty() && randint(0,3) == 0) {\n            // emit best sequence as-is\n            cout << N << '\\n';\n            for (auto [p,r,d,b] : best_seq) cout << p << ' ' << r << ' ' << d << ' ' << b << '\\n';\n            cout.flush();\n        } else {\n            // fresh greedy\n            cout << N << '\\n';\n            for (auto [p,r,d,b] : seq) cout << p << ' ' << r << ' ' << d << ' ' << b << '\\n';\n            cout.flush();\n        }\n\n        long long Wp, Hp;\n        cin >> Wp >> Hp;\n        long long obs = Wp + Hp;\n        if (obs < best_obs) {\n            best_obs = obs;\n            best_seq = seq;\n        }\n    }\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\n#include <atcoder/dsu>\nusing namespace std;\nusing namespace atcoder;\n\nstatic const int MAXN = 1005;\nstatic const int MAXH = 12;\n\nint N, M, H;\nint A[MAXN];\nvector<int> G[MAXN];\nint par[MAXN];          // parent array, -1 for root\nint depth[MAXN];        // depth[v] = number of edges from root\nint64_t contrib[MAXN];  // (depth[v]+1)*A[v]\nint64_t total_score;\n\n// DSU that mirrors the *undirected* forest edges\ndsu uf;\n\n// ---------- utility ----------\ninline void update_contrib(int v) {\n    contrib[v] = int64_t(depth[v] + 1) * A[v];\n}\n\n// ---------- initial greedy ----------\nvoid greedy_build() {\n    vector<char> used(N, 0);\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    shuffle(order.begin(), order.end(), rng);\n    sort(order.begin(), order.end(), [&](int u, int v) {\n        return A[u] > A[v];\n    });\n\n    uf = dsu(N);\n    total_score = 0;\n    for (int v = 0; v < N; ++v) par[v] = -2;\n\n    for (int u : order) if (par[u] == -2) {\n        queue<int> q;\n        par[u] = -1;\n        depth[u] = 0;\n        update_contrib(u);\n        q.push(u);\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            if (depth[v] == H) continue;\n            for (int w : G[v]) if (par[w] == -2) {\n                // safe because w is unused\n                par[w] = v;\n                depth[w] = depth[v] + 1;\n                update_contrib(w);\n                uf.merge(v, w);\n                q.push(w);\n            }\n        }\n    }\n    total_score = 0;\n    for (int v = 0; v < N; ++v) total_score += contrib[v];\n}\n\n// ---------- local improvement ----------\nvoid local_search(int iterations) {\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    vector<int> verts(N);\n    iota(verts.begin(), verts.end(), 0);\n\n    for (int it = 0; it < iterations; ++it) {\n        shuffle(verts.begin(), verts.end(), rng);\n        bool improved = false;\n\n        for (int v : verts) {\n            int old_p = par[v];\n            int old_d = depth[v];\n            int64_t old_delta = -contrib[v];\n\n            // try making v a new root\n            int best_new_p = -1;\n            int best_new_d = 0;\n            int64_t best_delta = 0;\n\n            int64_t delta_root = int64_t(1) * A[v] + old_delta;\n            if (delta_root > 0) {\n                best_new_p = -1;\n                best_new_d = 0;\n                best_delta = delta_root;\n            }\n\n            // try all neighbors as new parent\n            for (int w : G[v]) {\n                if (w == old_p) continue;\n                int nd = depth[w] + 1;\n                if (nd > H) continue;\n                // cycle check\n                if (uf.same(v, w)) continue;\n                int64_t delta = int64_t(nd + 1) * A[v] - contrib[v];\n                if (delta > best_delta) {\n                    best_delta = delta;\n                    best_new_p = w;\n                    best_new_d = nd;\n                }\n            }\n\n            if (best_delta > 0) {\n                // apply move\n                if (old_p != -1) {\n                    // remove old edge (old_p,v)\n                    // dsu does not support edge deletion; rebuild edge set\n                    // instead we rebuild uf from scratch each move (N is small)\n                    // rebuild uf after every successful move\n                }\n                par[v] = best_new_p;\n                depth[v] = best_new_d;\n                update_contrib(v);\n                total_score += best_delta;\n                improved = true;\n                // rebuild uf to reflect new edge\n                uf = dsu(N);\n                for (int u = 0; u < N; ++u) if (par[u] != -1)\n                    uf.merge(u, par[u]);\n            }\n        }\n        if (!improved) break;\n    }\n}\n\n// ---------- output ----------\nvoid output_answer() {\n    for (int i = 0; i < N; ++i) {\n        cout << par[i] << (i + 1 < N ? ' ' : '\\n');\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> H;\n    for (int i = 0; i < N; ++i) cin >> A[i];\n    for (int i = 0; i < M; ++i) {\n        int u, v; cin >> u >> v;\n        G[u].push_back(v);\n        G[v].push_back(u);\n    }\n    // discard coordinates\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n    }\n\n    int64_t best_score = -1;\n    vector<int> best_par(N);\n\n    auto save_best = [&]() {\n        if (total_score > best_score) {\n            best_score = total_score;\n            copy(par, par + N, best_par.begin());\n        }\n    };\n\n    const int tries = 25;\n    const int loc_its = 80;\n    for (int t = 0; t < tries; ++t) {\n        greedy_build();\n        local_search(loc_its);\n        save_best();\n    }\n\n    copy(best_par.begin(), best_par.end(), par);\n    output_answer();\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const int FIXED_N = 20;\nstatic const int NONE = -1;\nchar board[FIXED_N][FIXED_N + 1];\nint  N;\n\nstatic const int L = 0, R = 1, U = 2, D = 3;\nstatic const int BACK[4] = {1, 0, 3, 2};\nstatic const char DIRC[4] = {'L','R','U','D'};\n\nint oni_r[40], oni_c[40], oni_cnt;\nint fuku_r[40], fuku_c[40], fuku_cnt;\nint safe_dir[40];               // current best direction\nint cnt[4][FIXED_N];            // counters\nint total_moves;                // 2 * non_zero\n\nmt19937 rng(12345678);\n\ninline int non_zero() {\n    int nz = 0;\n    for (int d = 0; d < 4; ++d)\n        for (int p = 0; p < FIXED_N; ++p)\n            if (cnt[d][p]) ++nz;\n    return nz;\n}\n\n// ---------- rebuild sequence ----------\nvoid build_sequence(vector<pair<char,int>>& out) {\n    out.clear();\n    static char cur[FIXED_N][FIXED_N + 1];\n    for (int i = 0; i < FIXED_N; ++i) fill(cur[i], cur[i] + FIXED_N, '.');\n    for (int k = 0; k < fuku_cnt; ++k) cur[fuku_r[k]][fuku_c[k]] = 'o';\n    for (int k = 0; k < oni_cnt; ++k)  cur[oni_r[k]][oni_c[k]]  = 'x';\n\n    auto apply = [&](int d, int p) {\n        out.emplace_back(DIRC[d], p);\n        if (d == L) {\n            for (int j = 0; j + 1 < FIXED_N; ++j) cur[p][j] = cur[p][j + 1];\n            cur[p][FIXED_N - 1] = '.';\n        } else if (d == R) {\n            for (int j = FIXED_N - 1; j > 0; --j) cur[p][j] = cur[p][j - 1];\n            cur[p][0] = '.';\n        } else if (d == U) {\n            for (int i = 0; i + 1 < FIXED_N; ++i) cur[i][p] = cur[i + 1][p];\n            cur[FIXED_N - 1][p] = '.';\n        } else { // D\n            for (int i = FIXED_N - 1; i > 0; --i) cur[i][p] = cur[i - 1][p];\n            cur[0][p] = '.';\n        }\n    };\n\n    while (true) {\n        int best = 0, bd = NONE, bp = NONE;\n        for (int d = 0; d < 4; ++d)\n            for (int p = 0; p < FIXED_N; ++p)\n                if (cnt[d][p] > best) { best = cnt[d][p]; bd = d; bp = p; }\n        if (best == 0) break;\n        int len = (bd < 2 ? FIXED_N : FIXED_N);\n        for (int t = 0; t < len; ++t) apply(bd, bp);\n        for (int t = 0; t < len; ++t) apply(BACK[bd], bp);\n        cnt[bd][bp] = 0;\n    }\n}\n\n// ---------- 1 000 randomised greedy starters ----------\nvector<pair<char,int>> best_starter;\nint best_T;\n\nvoid randomised_greedy_starters() {\n    best_T = INT_MAX;\n    uniform_int_distribution<int> uid_d(0, 3);\n    for (int run = 0; run < 1000; ++run) {\n        // randomise safe-dir tie-breaking\n        for (int k = 0; k < oni_cnt; ++k) {\n            int i = oni_r[k], j = oni_c[k];\n            vector<int> safe;\n            for (int d = 0; d < 4; ++d) {\n                bool ok = true;\n                if (d == L){ for(int t=j-1;t>=0;--t)if(board[i][t]=='o')ok=false; }\n                else if(d==R){ for(int t=j+1;t<N;++t)if(board[i][t]=='o')ok=false; }\n                else if(d==U){ for(int t=i-1;t>=0;--t)if(board[t][j]=='o')ok=false; }\n                else { for(int t=i+1;t<N;++t)if(board[t][j]=='o')ok=false; }\n                if (ok) safe.push_back(d);\n            }\n            safe_dir[k] = safe[uid_d(rng) % safe.size()];\n        }\n        memset(cnt, 0, sizeof(cnt));\n        for (int k = 0; k < oni_cnt; ++k) {\n            int d = safe_dir[k];\n            int rc = (d < 2 ? oni_r[k] : oni_c[k]);\n            ++cnt[d][rc];\n        }\n        int T = 2 * non_zero();\n        if (T < best_T) {\n            best_T = T;\n            build_sequence(best_starter);\n        }\n    }\n}\n\n// ---------- main ----------\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    assert(N == FIXED_N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n\n    oni_cnt = fuku_cnt = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 'x') {\n                oni_r[oni_cnt] = i;\n                oni_c[oni_cnt] = j;\n                ++oni_cnt;\n            } else if (board[i][j] == 'o') {\n                fuku_r[fuku_cnt] = i;\n                fuku_c[fuku_cnt] = j;\n                ++fuku_cnt;\n            }\n        }\n\n    // 1. fast randomised starter\n    randomised_greedy_starters();\n    // load best into counters\n    memset(cnt, 0, sizeof(cnt));\n    for (int k = 0; k < oni_cnt; ++k) {\n        int d = safe_dir[k];\n        int rc = (d < 2 ? oni_r[k] : oni_c[k]);\n        ++cnt[d][rc];\n    }\n    total_moves = best_T;\n\n    // 2. SA with single-flip + order-swap\n    uniform_int_distribution<int> uid_k(0, oni_cnt - 1);\n    uniform_int_distribution<int> uid_d(0, 3);\n    uniform_int_distribution<int> uid_op(0, 1); // 0=flip, 1=swap\n\n    const int ITER = 200000;\n    for (int it = 0; it < ITER; ++it) {\n        int op = uid_op(rng);\n        if (op == 0) {\n            // single direction flip\n            int k = uid_k(rng);\n            int i = oni_r[k], j = oni_c[k];\n            int old_d = safe_dir[k];\n            int new_d = uid_d(rng);\n            if (new_d == old_d) continue;\n            bool ok = true;\n            if (new_d == L){ for(int t=j-1;t>=0;--t)if(board[i][t]=='o')ok=false; }\n            else if(new_d==R){ for(int t=j+1;t<N;++t)if(board[i][t]=='o')ok=false; }\n            else if(new_d==U){ for(int t=i-1;t>=0;--t)if(board[t][j]=='o')ok=false; }\n            else { for(int t=i+1;t<N;++t)if(board[t][j]=='o')ok=false; }\n            if (!ok) continue;\n\n            int rc_old = (old_d < 2 ? i : j);\n            int rc_new = (new_d < 2 ? i : j);\n\n            int delta = 0;\n            if (cnt[old_d][rc_old] == 1) delta -= 2;\n            --cnt[old_d][rc_old];\n            if (cnt[old_d][rc_old] == 0) delta += 2;\n\n            if (cnt[new_d][rc_new] == 0) delta -= 2;\n            ++cnt[new_d][rc_new];\n            if (cnt[new_d][rc_new] == 1) delta += 2;\n\n            int new_total = total_moves + delta;\n            if (new_total <= total_moves) {\n                total_moves = new_total;\n                safe_dir[k] = new_d;\n            } else {\n                --cnt[new_d][rc_new];\n                ++cnt[old_d][rc_old];\n            }\n        } else {\n            // swap deletion order of two demons\n            int k1 = uid_k(rng), k2 = uid_k(rng);\n            if (k1 == k2) continue;\n            int d1 = safe_dir[k1], d2 = safe_dir[k2];\n            int rc1 = (d1 < 2 ? oni_r[k1] : oni_c[k1]);\n            int rc2 = (d2 < 2 ? oni_r[k2] : oni_c[k2]);\n            if (rc1 == rc2 && d1 == d2) continue; // same line, same dir \u2013 no change\n\n            // flip them\n            safe_dir[k1] = d2; safe_dir[k2] = d1;\n            memset(cnt, 0, sizeof(cnt));\n            for (int k = 0; k < oni_cnt; ++k) {\n                int d = safe_dir[k];\n                int rc = (d < 2 ? oni_r[k] : oni_c[k]);\n                ++cnt[d][rc];\n            }\n            int new_total = 2 * non_zero();\n            if (new_total <= total_moves) {\n                total_moves = new_total;\n            } else {\n                // rollback\n                safe_dir[k1] = d1; safe_dir[k2] = d2;\n                memset(cnt, 0, sizeof(cnt));\n                for (int k = 0; k < oni_cnt; ++k) {\n                    int d = safe_dir[k];\n                    int rc = (d < 2 ? oni_r[k] : oni_c[k]);\n                    ++cnt[d][rc];\n                }\n            }\n        }\n    }\n\n    // final rebuild\n    memset(cnt, 0, sizeof(cnt));\n    for (int k = 0; k < oni_cnt; ++k) {\n        int d = safe_dir[k];\n        int rc = (d < 2 ? oni_r[k] : oni_c[k]);\n        ++cnt[d][rc];\n    }\n    build_sequence(best_starter);\n    for (auto [d, p] : best_starter) cout << d << ' ' << p << '\\n';\n    return 0;\n}","ahc044":"#include <iostream>\n#include <vector>\n#include <random>\n#include <algorithm>\n#include <chrono>\n\nusing namespace std;\n\nconst int N = 100;\nconst int L = 500000;\n\nint T[N];\nint a[N], b[N];\nint t[N];\nint current_sequence[L];\n\nint simulate() {\n    fill(t, t + N, 0);\n    int current = 0;\n    t[current] = 1;\n    for (int week = 1; week < L; ++week) {\n        int count = t[current];\n        int next;\n        if (count % 2 == 1) {\n            next = a[current];\n        } else {\n            next = b[current];\n        }\n        t[next]++;\n        current = next;\n    }\n    int error = 0;\n    for (int i = 0; i < N; ++i) {\n        error += abs(t[i] - T[i]);\n    }\n    return error;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    for (int i = 0; i < N; ++i) {\n        cin >> T[i];\n    }\n\n    // Initial greedy assignment\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    for (int i = 0; i < N; ++i) {\n        a[i] = uniform_int_distribution<int>(0, N - 1)(rng);\n        b[i] = uniform_int_distribution<int>(0, N - 1)(rng);\n    }\n\n    int best_error = simulate();\n    auto start = chrono::steady_clock::now();\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start).count() > 1800) {\n            break; // Stop after 1.8 seconds to ensure we don't exceed 2 seconds\n        }\n\n        int i = uniform_int_distribution<int>(0, N - 1)(rng);\n        int old_a = a[i], old_b = b[i];\n\n        // Try changing a[i] or b[i]\n        if (uniform_int_distribution<int>(0, 1)(rng) == 0) {\n            a[i] = uniform_int_distribution<int>(0, N - 1)(rng);\n        } else {\n            b[i] = uniform_int_distribution<int>(0, N - 1)(rng);\n        }\n\n        int new_error = simulate();\n        if (new_error < best_error) {\n            best_error = new_error;\n        } else {\n            // Revert\n            a[i] = old_a;\n            b[i] = old_b;\n        }\n    }\n\n    // Output the best found\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 City {\n    int id, lx, rx, ly, ry;\n    int cx() const { return (lx + rx) / 2; }\n    int cy() const { return (ly + ry) / 2; }\n};\n\nint N, M, Q, L, W;\nvector<int> G;\nvector<City> cities;\nvector<vector<int>> groups;\nvector<vector<pair<int, int>>> group_edges;\n\nvector<pair<int, int>> query(const vector<int>& c) {\n    cout << \"? \" << c.size();\n    for (int x : c) cout << \" \" << x;\n    cout << endl;\n    vector<pair<int, int>> edges;\n    for (int i = 0; i < c.size() - 1; ++i) {\n        int a, b;\n        cin >> a >> b;\n        edges.emplace_back(a, b);\n    }\n    return edges;\n}\n\nvoid answer() {\n    cout << \"!\" << endl;\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < groups[i].size(); ++j) {\n            if (j > 0) cout << \" \";\n            cout << groups[i][j];\n        }\n        cout << endl;\n        for (auto [a, b] : group_edges[i]) {\n            cout << a << \" \" << b << endl;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    cities.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> cities[i].lx >> cities[i].rx >> cities[i].ly >> cities[i].ry;\n        cities[i].id = i;\n    }\n\n    // Sort cities by center coordinates\n    sort(cities.begin(), cities.end(), [](const City& a, const City& b) {\n        if (a.cx() != b.cx()) return a.cx() < b.cx();\n        return a.cy() < b.cy();\n    });\n\n    // Assign to groups\n    groups.resize(M);\n    group_edges.resize(M);\n    int ptr = 0;\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < G[i]; ++j) {\n            groups[i].push_back(cities[ptr++].id);\n        }\n    }\n\n    // Use queries to get edges for each group\n    int queries_used = 0;\n    for (int i = 0; i < M; ++i) {\n        int sz = groups[i].size();\n        if (sz <= 1) continue;\n        // Use triplets to cover the group\n        for (int j = 0; j < sz - 1; j += 2) {\n            if (queries_used >= Q) break;\n            vector<int> c;\n            if (j + 2 < sz) {\n                c = {groups[i][j], groups[i][j+1], groups[i][j+2]};\n            } else {\n                c = {groups[i][j], groups[i][j+1]};\n            }\n            auto edges = query(c);\n            for (auto [a, b] : edges) {\n                group_edges[i].emplace_back(a, b);\n            }\n            queries_used++;\n        }\n        // Ensure connectivity by adding edges if necessary\n        // This is a simple heuristic: connect in order\n        if (group_edges[i].size() < sz - 1) {\n            for (int j = 0; j < sz - 1; ++j) {\n                group_edges[i].emplace_back(groups[i][j], groups[i][j+1]);\n            }\n        }\n    }\n\n    answer();\n    return 0;\n}","ahc046":"#pragma GCC optimize(\"O3,unroll-loops\")\n#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nstatic const int N = 20;\nstatic const int M = 40;\nstatic const int LIMIT = 2*N*M;\n\nint target[M];\nint targetLeft;                      // how many still to visit\nbool blocked[N][N];                  // current wall state\nint  distSlide[N][N][4];             // dist to next block/border in 4 dirs\nint  di[] = {-1,1,0,0};\nint  dj[] = {0,0,-1,1};\nchar actionChar[] = {'M','S','A'};\nchar dirChar[]    = {'U','D','L','R'};\n\nstruct Step {\n    int i,j;\n    int g;\n    vector<pair<int,int>> pathActs; // (act,dir) pairs leading here\n    bool operator<(const Step& o) const { return g > o.g; }\n};\n\ninline bool inside(int i,int j){ return i>=0&&i<N&&j>=0&&j<N; }\n\nvoid rebuildDistSlide(){\n    for(int i=0;i<N;i++){\n        // up\n        for(int j=0;j<N;j++){\n            int d=0;\n            for(int ii=i-1;ii>=0;ii--){\n                if(blocked[ii][j]) break;\n                d++;\n            }\n            distSlide[i][j][0]=d;\n        }\n        // down\n        for(int j=0;j<N;j++){\n            int d=0;\n            for(int ii=i+1;ii<N;ii++){\n                if(blocked[ii][j]) break;\n                d++;\n            }\n            distSlide[i][j][1]=d;\n        }\n    }\n    for(int j=0;j<N;j++){\n        // left\n        for(int i=0;i<N;i++){\n            int d=0;\n            for(int jj=j-1;jj>=0;jj--){\n                if(blocked[i][jj]) break;\n                d++;\n            }\n            distSlide[i][j][2]=d;\n        }\n        // right\n        for(int i=0;i<N;i++){\n            int d=0;\n            for(int jj=j+1;jj<N;jj++){\n                if(blocked[i][jj]) break;\n                d++;\n            }\n            distSlide[i][j][3]=d;\n        }\n    }\n}\n\nint heuristic(int si,int sj,int ti,int tj){\n    return abs(si-ti)+abs(sj-tj);\n}\n\nvector<pair<int,int>> planSegment(int si,int sj,int ti,int tj){\n    priority_queue<Step> pq;\n    Step start{si,sj,0,{}};\n    pq.push(start);\n    static char vis[ N ][ N ];\n    memset(vis,0,sizeof(vis));\n    vis[si][sj]=1;\n    const int EXPAND = 20000;\n    int expanded = 0;\n    while(!pq.empty() && expanded < EXPAND){\n        Step cur = pq.top(); pq.pop();\n        expanded++;\n        if(cur.i==ti && cur.j==tj){\n            return cur.pathActs;\n        }\n        int g2 = cur.g+1;\n        for(int dir=0;dir<4;dir++){\n            int ni = cur.i + di[dir];\n            int nj = cur.j + dj[dir];\n            // 1) Move\n            if(inside(ni,nj) && !blocked[ni][nj] && !vis[ni][nj]){\n                vis[ni][nj]=1;\n                Step nxt = cur;\n                nxt.i=ni; nxt.j=nj; nxt.g=g2;\n                nxt.pathActs.emplace_back(0,dir);\n                pq.push(nxt);\n            }\n            // 2) Slide\n            int ds = distSlide[cur.i][cur.j][dir];\n            if(ds>0){\n                int ei = cur.i + di[dir]*ds;\n                int ej = cur.j + dj[dir]*ds;\n                if(!vis[ei][ej]){\n                    vis[ei][ej]=1;\n                    Step nxt = cur;\n                    nxt.i=ei; nxt.j=ej; nxt.g=g2;\n                    nxt.pathActs.emplace_back(1,dir);\n                    pq.push(nxt);\n                }\n            }\n            // 3) Alter\n            int bi = cur.i + di[dir];\n            int bj = cur.j + dj[dir];\n            if(inside(bi,bj)){\n                // toggle\n                blocked[bi][bj] ^= 1;\n                rebuildDistSlide();\n                Step nxt = cur;\n                nxt.g=g2;\n                nxt.pathActs.emplace_back(2,dir);\n                pq.push(nxt);\n                // undo\n                blocked[bi][bj] ^= 1;\n                rebuildDistSlide();\n            }\n        }\n    }\n    // fallback: plain Manhattan moves\n    vector<pair<int,int>> fallback;\n    int dx = ti - si;\n    int dy = tj - sj;\n    int px = si, py = sj;\n    while(px<ti){ px++; fallback.emplace_back(0,1); }\n    while(px>ti){ px--; fallback.emplace_back(0,0); }\n    while(py<tj){ py++; fallback.emplace_back(0,3); }\n    while(py>tj){ py--; fallback.emplace_back(0,2); }\n    return fallback;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int n,m;\n    cin >> n >> m;\n    assert(n==N && m==M);\n    int si,sj;\n    cin >> si >> sj;\n    vector<int> I(M),J(M);\n    for(int k=0;k<M;k++){\n        cin >> I[k] >> J[k];\n    }\n    // initialise\n    memset(blocked,0,sizeof(blocked));\n    rebuildDistSlide();\n    vector<pair<int,int>> fullPlan;\n    int ci=si, cj=sj;\n    for(int idx=0;idx<M;idx++){\n        int ti = I[idx];\n        int tj = J[idx];\n        auto seg = planSegment(ci,cj,ti,tj);\n        fullPlan.insert(fullPlan.end(), seg.begin(), seg.end());\n        // execute to update real state\n        for(auto [act,dir]: seg){\n            if(act==0){ // Move\n                ci += di[dir];\n                cj += dj[dir];\n            } else if(act==1){ // Slide\n                int ds = distSlide[ci][cj][dir];\n                ci += di[dir]*ds;\n                cj += dj[dir]*ds;\n            } else { // Alter\n                int bi = ci + di[dir];\n                int bj = cj + dj[dir];\n                blocked[bi][bj] ^= 1;\n                rebuildDistSlide();\n            }\n        }\n        assert(ci==ti && cj==tj);\n    }\n    // output\n    cout << fullPlan.size() << \"\\n\";\n    for(auto [act,dir]: fullPlan){\n        cout << actionChar[act] << \" \" << dirChar[dir] << \"\\n\";\n    }\n    return 0;\n}"},"16":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nusing uint = unsigned int;\nusing ull = unsigned long long;\n\n/* ---------- basic geometry ---------- */\nstruct Rect {\n    int a, b, c, d;\n    ll area() const { return (ll)(c - a) * (d - b); }\n    bool contains(double x, double y) const {\n        return a <= x && x <= c && b <= y && y <= d;\n    }\n    // intersection area (0 if disjoint)\n    ll intersect(const Rect &o) const {\n        int A = max(a, o.a), B = max(b, o.b);\n        int C = min(c, o.c), D = min(d, o.d);\n        if (A >= C || B >= D) return 0;\n        return (ll)(C - A) * (D - B);\n    }\n};\nstruct Company {\n    int x, y, r;\n    double cx, cy;   // desired centre\n    Rect  R;\n    double priority() const {      // how far from desired area\n        ll s = R.area();\n        double rat = min((double)s, (double)r) / max((double)s, (double)r);\n        return 1.0 - rat;          // larger \u2192 more urgent\n    }\n};\n\n/* ---------- global ---------- */\nint n;\nvector<Company> co;\nchrono::steady_clock::time_point start;\ndouble time_elapsed() {\n    return chrono::duration<double>(chrono::steady_clock::now() - start).count();\n}\nconst double TIME_LIMIT = 4.8;\n\n/* ---------- overlap utilities ---------- */\nbool overlap(int i, int j) {\n    const Rect &p = co[i].R, &q = co[j].R;\n    return !(p.c <= q.a || q.c <= p.a || p.d <= q.b || q.d <= p.b);\n}\nll total_overlap() {   // total pairwise overlap area\n    ll bad = 0;\n    for (int i = 0; i < n; ++i)\n        for (int j = i + 1; j < n; ++j)\n            bad += co[i].R.intersect(co[j].R);\n    return bad;\n}\n\n/* ---------- priority overlap removal ---------- */\nvoid remove_overlaps_pq() {\n    priority_queue<pair<double, int>> pq; // priority -> index\n    auto push = [&](int i) { pq.emplace(co[i].priority(), i); };\n    for (int i = 0; i < n; ++i) push(i);\n\n    bool progress;\n    do {\n        progress = false;\n        while (!pq.empty()) {\n            int i = pq.top().second; pq.pop();\n            for (int j = 0; j < n; ++j) {\n                if (i == j) continue;\n                if (!overlap(i, j)) continue;\n                progress = true;\n                Rect &u = co[i].R, &v = co[j].R;\n                // shrink the one whose area is further above its r\n                bool shrink_u = (u.area() > co[i].r) ||\n                                (v.area() <= co[j].r && u.area() > v.area());\n                Rect *t = shrink_u ? &u : &v;\n                int dx = t->c - t->a, dy = t->d - t->b;\n                if (dx > dy) {\n                    if (t->c - 1 > t->a) t->c--;\n                    else if (t->a + 1 < t->c) t->a++;\n                    else if (t->d - 1 > t->b) t->d--;\n                    else t->b++;\n                } else {\n                    if (t->d - 1 > t->b) t->d--;\n                    else if (t->b + 1 < t->d) t->b++;\n                    else if (t->c - 1 > t->a) t->c--;\n                    else t->a++;\n                }\n                push(i);\n                push(j);\n                goto next_loop;\n            }\n        }\n        next_loop:;\n    } while (progress && time_elapsed() < TIME_LIMIT);\n}\n\n/* ---------- maximal empty rectangle (MER) ---------- */\nvector<Rect> find_MERs() {\n    // event-based maximal empty rectangles in orthogonal plane\n    // we implement a simplified 1-D maximal gap finder twice (x, y)\n    // and return up to 4*n largest empty rectangles.\n    vector<Rect> merch;\n    { // sweep along x\n        vector<int> xs = {0, 10000};\n        for (int i = 0; i < n; ++i) {\n            xs.push_back(co[i].R.a);\n            xs.push_back(co[i].R.c);\n        }\n        sort(xs.begin(), xs.end());\n        xs.erase(unique(xs.begin(), xs.end()), xs.end());\n        for (size_t i = 0; i + 1 < xs.size(); ++i) {\n            int x1 = xs[i], x2 = xs[i + 1];\n            vector<pair<int, int>> segs;\n            for (int j = 0; j < n; ++j) {\n                if (co[j].R.a <= x1 && x2 <= co[j].R.c) {\n                    segs.emplace_back(co[j].R.b, co[j].R.d);\n                }\n            }\n            sort(segs.begin(), segs.end());\n            int last = 0;\n            for (auto &s : segs) {\n                if (s.first > last) merch.push_back({x1, last, x2, s.first});\n                last = max(last, s.second);\n            }\n            if (last < 10000) merch.push_back({x1, last, x2, 10000});\n        }\n    }\n    // sort by decreasing area\n    sort(merch.begin(), merch.end(),\n         [](const Rect &A, const Rect &B) { return A.area() > B.area(); });\n    if (merch.size() > 4 * n) merch.resize(4 * n);\n    return merch;\n}\n\n/* ---------- try to assign exact r_i into biggest MER containing centre ---------- */\nvoid expand_to_MER() {\n    auto mer = find_MERs();\n    vector<int> ord(n);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(),\n         [&](int i, int j) { return co[i].priority() > co[j].priority(); });\n\n    for (int idx : ord) {\n        Company &C = co[idx];\n        for (const Rect &E : mer) {\n            if (!E.contains(C.cx, C.cy)) continue;\n            ll avail = E.area();\n            if (avail < C.r) continue;\n            // try to build a rectangle inside E, area = C.r, containing centre\n            int want = C.r;\n            int w = E.c - E.a, h = E.d - E.b;\n            // choose integer dimensions (dx,dy) with dx*dy = want, dx<=w, dy<=h\n            int dx = (int)sqrt(want), dy;\n            while (dx > 0) {\n                if (want % dx == 0) {\n                    dy = want / dx;\n                    if (dx <= w && dy <= h) break;\n                }\n                dx--;\n            }\n            if (dx == 0) continue; // cannot fit\n            // centre must be inside new rectangle\n            int nx1 = max(E.a, (int)floor(C.cx - dx / 2.0));\n            int nx2 = nx1 + dx;\n            if (nx2 > E.c) { nx2 = E.c; nx1 = nx2 - dx; }\n            int ny1 = max(E.b, (int)floor(C.cy - dy / 2.0));\n            int ny2 = ny1 + dy;\n            if (ny2 > E.d) { ny2 = E.d; ny1 = ny2 - dy; }\n            Rect cand{nx1, ny1, nx2, ny2};\n            if (!cand.contains(C.cx, C.cy)) continue;\n            // check overlap with others\n            bool ok = true;\n            for (int i = 0; i < n && ok; ++i)\n                if (i != idx && cand.intersect(co[i].R)) ok = false;\n            if (!ok) continue;\n            C.R = cand;\n            break;\n        }\n    }\n}\n\n/* ---------- simulated annealing outer loop ---------- */\ndouble raw_score() {\n    double sum = 0;\n    for (int i = 0; i < n; ++i) {\n        ll s = co[i].R.area();\n        ll r = co[i].r;\n        if (s == r) sum += 1.0;\n        else {\n            double rat = min((double)s, (double)r) / max((double)s, (double)r);\n            sum += 1.0 - (1.0 - rat) * (1.0 - rat);\n        }\n    }\n    return sum;\n}\nvoid anneal() {\n    double T0 = 1e-3, T, cooling = 0.995;\n    double best = raw_score() - 1e6 * total_overlap();\n    double cur = best;\n    mt19937 rng(42);\n    uniform_real_distribution<double> uni(0, 1);\n\n    while (time_elapsed() < TIME_LIMIT) {\n        T = T0;\n        for (int step = 0; step < 300 && time_elapsed() < TIME_LIMIT; ++step, T *= cooling) {\n            // neighbour: random small move\n            int i = uniform_int_distribution<int>(0, n - 1)(rng);\n            Rect old = co[i].R;\n            Rect neo = old;\n            int d = uniform_int_distribution<int>(-2, 2)(rng);\n            int mode = uniform_int_distribution<int>(0, 3)(rng);\n            if (mode == 0) neo.a += d;\n            if (mode == 1) neo.b += d;\n            if (mode == 2) neo.c += d;\n            if (mode == 3) neo.d += d;\n            if (neo.a >= neo.c || neo.b >= neo.d) continue;\n            if (neo.a < 0 || neo.b < 0 || neo.c > 10000 || neo.d > 10000) continue;\n            if (!neo.contains(co[i].cx, co[i].cy)) continue;\n\n            co[i].R = neo;\n            double nxt = raw_score() - 1e6 * total_overlap();\n            double delta = nxt - cur;\n            if (delta > 0 || uni(rng) < exp(delta / T)) {\n                cur = nxt;\n                if (cur > best) best = cur;\n            } else {\n                co[i].R = old;\n            }\n        }\n    }\n}\n\n/* ---------- driver ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    start = chrono::steady_clock::now();\n\n    cin >> n;\n    co.resize(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> co[i].x >> co[i].y >> co[i].r;\n        co[i].cx = co[i].x + 0.5;\n        co[i].cy = co[i].y + 0.5;\n        co[i].R = {co[i].x, co[i].y, co[i].x + 1, co[i].y + 1};\n    }\n\n    remove_overlaps_pq();\n    expand_to_MER();\n    remove_overlaps_pq();\n    anneal();\n\n    for (int i = 0; i < n; ++i)\n        cout << co[i].R.a << ' ' << co[i].R.b << ' '\n             << co[i].R.c << ' ' << co[i].R.d << '\\n';\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nint si, sj;\nint t[50][50];\nint p[50][50];\nint M;\nint bestScore;\nstring bestPath;\n\nconst int dx[4] = {-1,1,0,0};\nconst int dy[4] = {0,0,-1,1};\nconst char dc[4] = {'U','D','L','R'};\n\nchrono::steady_clock::time_point start;\n\ninline bool timeout(double lim = 1.80) {\n    return chrono::duration<double>(chrono::steady_clock::now() - start).count() > lim;\n}\n\ninline vector<int> orderNeigh(int i, int j) {\n    array<pair<int,int>,4> tmp;\n    for(int d=0;d<4;d++){\n        int ni=i+dx[d], nj=j+dy[d];\n        int val = (ni<0||ni>=50||nj<0||nj>=50) ? -1 : p[ni][nj];\n        tmp[d] = {val, d};\n    }\n    sort(tmp.begin(), tmp.end(), greater<pair<int,int>>());\n    vector<int> ord(4);\n    for(int k=0;k<4;k++) ord[k] = tmp[k].second;\n    return ord;\n}\n\nvoid dfs(int i, int j, bitset<2500> used, int score, string path, int depth, int limit) {\n    if (timeout()) return;\n    if (score > bestScore) {\n        bestScore = score;\n        bestPath  = path;\n    }\n    if (depth == limit) return;\n    auto ord = orderNeigh(i, j);\n    for (int d : ord) {\n        int ni = i + dx[d], nj = j + dy[d];\n        if (ni<0||ni>=50||nj<0||nj>=50) continue;\n        int nt = t[ni][nj];\n        if (used[nt]) continue;\n        used[nt] = 1;\n        path.push_back(dc[d]);\n        dfs(ni, nj, used, score + p[ni][nj], path, depth + 1, limit);\n        path.pop_back();\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    start = chrono::steady_clock::now();\n\n    cin >> si >> sj;\n    for(int i=0;i<50;i++)for(int j=0;j<50;j++) cin >> t[i][j];\n    for(int i=0;i<50;i++)for(int j=0;j<50;j++) cin >> p[i][j];\n\n    int maxt = 0;\n    for(int i=0;i<50;i++)for(int j=0;j<50;j++) maxt = max(maxt, t[i][j]);\n    M = maxt + 1;\n\n    bestScore = p[si][sj];   // starting square score\n    bestPath  = \"\";          // empty path = stay once\n\n    for (int limit = 0; limit <= 2000; limit += 50) {  // limit 0 allows snapshotting the start\n        if (timeout()) break;\n        bitset<2500> used;\n        used[t[si][sj]] = 1;          // mark **inside** the first layer\n        dfs(si, sj, used, bestScore, string(), 0, limit);\n        if (timeout()) break;\n    }\n    cout << bestPath << endl;\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int Q = 1000;\n\nstruct Edge {\n    double len = 5000.0, sumObs = 0.0;\n    int cnt = 0;\n    Edge() = default;\n};\n\nint dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1};\n\nvector<vector<Edge>> hEdge(N, vector<Edge>(N - 1));\nvector<vector<Edge>> vEdge(N - 1, vector<Edge>(N));\n\n/* ---------- basic helpers ---------- */\nstring manhattan(int sr, int sc, int tr, int tc) {\n    string s;\n    int d = tr - sr, c = tc - sc;\n    if (d > 0) s.append(d, 'D'); else s.append(-d, 'U');\n    if (c > 0) s.append(c, 'R'); else s.append(-c, 'L');\n    return s;\n}\n\nvector<pair<int, int>> vertices_on_path(int sr, int sc, const string &p) {\n    vector<pair<int, int>> v = {{sr, sc}};\n    int r = sr, c = sc;\n    for (char ch : p) {\n        if (ch == 'U') { --r; }\n        if (ch == 'D') { ++r; }\n        if (ch == 'L') { --c; }\n        if (ch == 'R') { ++c; }\n        v.emplace_back(r, c);\n    }\n    return v;\n}\n\ndouble path_length(const vector<pair<int, int>> &v) {\n    double len = 0;\n    for (size_t i = 0; i + 1 < v.size(); ++i) {\n        int r1 = v[i].first, c1 = v[i].second;\n        int r2 = v[i + 1].first, c2 = v[i + 1].second;\n        if (r1 == r2 && abs(c1 - c2) == 1) {\n            len += hEdge[r1][min(c1, c2)].len;\n        } else if (c1 == c2 && abs(r1 - r2) == 1) {\n            len += vEdge[min(r1, r2)][c1].len;\n        } else {\n            len += 1e18; // invalid edge\n        }\n    }\n    return len;\n}\n\nvoid update_edges(const vector<pair<int, int>> &v, int noisy) {\n    double obs = noisy;\n    for (size_t i = 0; i + 1 < v.size(); ++i) {\n        int r1 = v[i].first, c1 = v[i].second;\n        int r2 = v[i + 1].first, c2 = v[i + 1].second;\n        Edge *e = nullptr;\n        if (r1 == r2 && abs(c1 - c2) == 1) e = &hEdge[r1][min(c1, c2)];\n        if (c1 == c2 && abs(r1 - r2) == 1) e = &vEdge[min(r1, r2)][c1];\n        if (e) {\n            e->sumObs += obs;\n            e->cnt += 1;\n            e->len = e->sumObs / e->cnt;\n        }\n    }\n}\n\n/* ---------- Dijkstra with current estimates ---------- */\nstring dijkstra(int sr, int sc, int tr, int tc) {\n    using P = pair<double, pair<int, int>>;\n    using Cmp = greater<P>;                       // alias avoids >> trouble\n    priority_queue<P, vector<P>, Cmp> pq;         // single > only\n    vector<vector<double>> dist(N, vector<double>(N, 1e18));\n    vector<vector<pair<int, int>>> par(N, vector<pair<int, int>>(N, {-1, -1}));\n    dist[sr][sc] = 0;\n    pq.push({0, {sr, sc}});\n\n    while (!pq.empty()) {\n        auto top = pq.top();\n        pq.pop();\n        double d = top.first;\n        int r = top.second.first, c = top.second.second;\n        if (d > dist[r][c]) continue;\n        if (r == tr && c == tc) break;\n        for (int k = 0; k < 4; ++k) {\n            int nr = r + dr[k], nc = c + dc[k];\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n            double w = 0;\n            if (k == 0) w = vEdge[nr][nc].len;\n            if (k == 1) w = vEdge[r][c].len;\n            if (k == 2) w = hEdge[r][nc].len;\n            if (k == 3) w = hEdge[r][c].len;\n            if (dist[nr][nc] > d + w) {\n                dist[nr][nc] = d + w;\n                par[nr][nc] = {r, c};\n                pq.push({dist[nr][nc], {nr, nc}});\n            }\n        }\n    }\n\n    string path;\n    int r = tr, c = tc;\n    while (par[r][c].first != -1) {\n        int pr = par[r][c].first, pc = par[r][c].second;\n        if (pr == r - 1) path += 'D';\n        else if (pr == r + 1) path += 'U';\n        else if (pc == c - 1) path += 'R';\n        else if (pc == c + 1) path += 'L';\n        r = pr;\n        c = pc;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n/* ---------- main ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    for (int q = 0; q < Q; ++q) {\n        int sr, sc, tr, tc;\n        cin >> sr >> sc >> tr >> tc;\n        string path;\n        if (q < 100) path = manhattan(sr, sc, tr, tc);\n        else path = dijkstra(sr, sc, tr, tc);\n        cout << path << '\\n';\n        cout.flush();\n\n        int noisy;\n        cin >> noisy;\n        auto v = vertices_on_path(sr, sc, path);\n        update_edges(v, noisy);\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const int N = 20;\nstatic const int AL = 8;          // A..H\nstatic const char LET[] = \"ABCDEFGH\";\n\nint M;\nvector<string> S;\nint bestC;\nvector<string> bestGrid;\n\n// ---------- portable RNG ----------\nmt19937_64 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count() ^\n               (uint64_t)random_device{}());\n\ninline int randInt(int l, int r) {   // [l, r]\n    return uniform_int_distribution<int>(l, r)(rng);\n}\n\n// ---------- evaluation ----------\ninline int index(char c) { return c - 'A'; }\n\nint evaluate(const vector<string>& g) {\n    int cnt = 0;\n    for (const auto& s : S) {\n        int L = (int)s.size();\n        bool ok = false;\n        // horizontal\n        for (int i = 0; i < N && !ok; ++i) {\n            for (int st = 0; st < N; ++st) {\n                bool match = true;\n                for (int p = 0; p < L; ++p)\n                    if (g[i][(st + p) % N] != s[p]) { match = false; break; }\n                if (match) { ok = true; break; }\n            }\n        }\n        if (ok) { ++cnt; continue; }\n        // vertical\n        for (int j = 0; j < N && !ok; ++j) {\n            for (int st = 0; st < N; ++st) {\n                bool match = true;\n                for (int p = 0; p < L; ++p)\n                    if (g[(st + p) % N][j] != s[p]) { match = false; break; }\n                if (match) { ok = true; break; }\n            }\n        }\n        if (ok) ++cnt;\n    }\n    return cnt;\n}\n\nint fillCount(const vector<string>& g) {\n    int c = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (g[i][j] != '.') ++c;\n    return c;\n}\n\nvoid printGrid(const vector<string>& g) {\n    for (const auto& row : g) cout << row << '\\n';\n}\n\n// ---------- random grid ----------\nvector<string> randomGrid() {\n    vector<string> g(N, string(N, '.'));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            g[i][j] = LET[randInt(0, AL - 1)];\n    return g;\n}\n\n// ---------- mutation ----------\nvoid mutate1(vector<string>& g) {\n    int i = randInt(0, N - 1);\n    int j = randInt(0, N - 1);\n    char old = g[i][j];\n    char nu;\n    if (bestC == M && randInt(0, 9) == 0) nu = '.';\n    else nu = LET[randInt(0, AL - 1)];\n    g[i][j] = nu;\n    int c = evaluate(g);\n    if (c > bestC || (c == bestC && randInt(0, 1))) {\n        bestC = c;\n        bestGrid = g;\n    } else {\n        g[i][j] = old;\n    }\n}\n\nvoid mutateRow(vector<string>& g) {\n    int i = randInt(0, N - 1);\n    string old = g[i];\n    vector<int> unsat;\n    for (int idx = 0; idx < M; ++idx) {\n        const string& s = S[idx];\n        int L = s.size();\n        bool any = false;\n        for (int st = 0; st < N; ++st) {\n            bool ok = true;\n            for (int p = 0; p < L; ++p)\n                if (g[i][(st + p) % N] != s[p]) { ok = false; break; }\n            if (ok) { any = true; break; }\n        }\n        if (!any) unsat.push_back(idx);\n    }\n    if (unsat.empty()) return;\n    int pick = unsat[randInt(0, (int)unsat.size() - 1)];\n    const string& tgt = S[pick];\n    int L = tgt.size();\n    int st = randInt(0, N - 1);\n    for (int p = 0; p < L; ++p) g[i][(st + p) % N] = tgt[p];\n    int c = evaluate(g);\n    if (c > bestC || (c == bestC && randInt(0, 1))) {\n        bestC = c;\n        bestGrid = g;\n    } else {\n        g[i] = old;\n    }\n}\n\n// ---------- main ----------\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n, m;\n    cin >> n >> m;\n    M = m;\n    S.resize(M);\n    for (int i = 0; i < M; ++i) cin >> S[i];\n\n    bestGrid = randomGrid();\n    bestC = evaluate(bestGrid);\n\n    const double TIME_LIMIT = 2.8;\n    auto start = chrono::steady_clock::now();\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > TIME_LIMIT) break;\n\n        if (bestC < M) {\n            if (randInt(0, 3) == 0) mutateRow(bestGrid);\n            else                      mutate1(bestGrid);\n        } else {\n            mutate1(bestGrid);\n        }\n    }\n\n    // final safe fill pass\n    if (bestC == M) {\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                if (bestGrid[i][j] == '.') {\n                    char old = bestGrid[i][j];\n                    bool ok = false;\n                    for (char c : LET) {\n                        bestGrid[i][j] = c;\n                        if (evaluate(bestGrid) == M) { ok = true; break; }\n                    }\n                    if (!ok) bestGrid[i][j] = old;\n                }\n    }\n\n    printGrid(bestGrid);\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 70;\nconst int INF  = 0x3f3f3f3f;\n\nint N, si, sj;\nchar grid[MAXN][MAXN];\nint  cost[MAXN][MAXN];\nbool isRoad[MAXN][MAXN];\n\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\nchar dirC[] = {'U', 'D', 'L', 'R'};\n\nbitset<MAXN*MAXN> visFrom[MAXN][MAXN];   // what becomes visible\nbitset<MAXN*MAXN> coverage;\nint totalRoads;\n\n/* ---------- visibility precomputation ---------- */\nvoid buildVisibility() {\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (!isRoad[i][j]) continue;\n            auto &bs = visFrom[i][j];\n            // row left\n            for (int jj = j; jj >= 0 && isRoad[i][jj]; --jj) bs.set(i*N + jj);\n            // row right\n            for (int jj = j; jj <  N && isRoad[i][jj]; ++jj) bs.set(i*N + jj);\n            // col up\n            for (int ii = i; ii >= 0 && isRoad[ii][j]; --ii) bs.set(ii*N + j);\n            // col down\n            for (int ii = i; ii <  N && isRoad[ii][j]; ++ii) bs.set(ii*N + j);\n        }\n    }\n}\n\n/* ---------- single Dijkstra ---------- */\nint dist[MAXN][MAXN];\npair<int,int> parent[MAXN][MAXN];\n\nvoid dijkstra(int sr, int sc) {\n    memset(dist, 0x3f, sizeof(dist));\n    using T = tuple<int,int,int>;\n    priority_queue<T, vector<T>, greater<T>> pq;\n    dist[sr][sc] = 0;\n    parent[sr][sc] = {-1,-1};\n    pq.emplace(0, sr, sc);\n    while (!pq.empty()) {\n        auto [d, r, c] = pq.top(); pq.pop();\n        if (d > dist[r][c]) continue;\n        for (int k = 0; k < 4; ++k) {\n            int nr = r + dr[k], nc = c + dc[k];\n            if (nr<0||nr>=N||nc<0||nc>=N || !isRoad[nr][nc]) continue;\n            int nd = d + cost[nr][nc];\n            if (nd < dist[nr][nc]) {\n                dist[nr][nc] = nd;\n                parent[nr][nc] = {r,c};\n                pq.emplace(nd, nr, nc);\n            }\n        }\n    }\n}\n\n/* ---------- path reconstruction ---------- */\nvector<pair<int,int>> reconstruct(int tr, int tc) {\n    vector<pair<int,int>> path;\n    for (int r=tr, c=tc; r!=-1; tie(r,c)=parent[r][c]) path.emplace_back(r,c);\n    reverse(path.begin(), path.end());\n    return path;\n}\nstring toMoves(const vector<pair<int,int>>& path) {\n    string s;\n    for (int i = 1; i < (int)path.size(); ++i) {\n        int dr = path[i].first  - path[i-1].first;\n        int dc = path[i].second - path[i-1].second;\n        if (dr==-1) s+='U'; else if (dr==1) s+='D';\n        else if (dc==-1) s+='L'; else s+='R';\n    }\n    return s;\n}\n\n/* ---------- greedy cover ---------- */\nstring greedyCover() {\n    coverage.reset();\n    int cr = si, cc = sj;\n    string route;\n    coverage |= visFrom[cr][cc];\n\n    while ((int)coverage.count() < totalRoads) {\n        dijkstra(cr, cc);          // single Dijkstra\n        int best_r=-1, best_c=-1, best_gain=0, best_cost=INF;\n        for (int i=0;i<N;++i) {\n            for (int j=0;j<N;++j) {\n                if (!isRoad[i][j] || dist[i][j]==INF) continue;\n                int g = (visFrom[i][j] & ~coverage).count();\n                if (g==0) continue;\n                int c = dist[i][j];\n                if (g>best_gain || (g==best_gain && c<best_cost)) {\n                    best_gain = g; best_cost = c;\n                    best_r = i; best_c = j;\n                }\n            }\n        }\n        if (best_r==-1) break;     // should not happen\n        auto path = reconstruct(best_r, best_c);\n        route += toMoves(path);\n        cr = best_r; cc = best_c;\n        coverage |= visFrom[cr][cc];\n    }\n    // return to start\n    dijkstra(cr, cc);\n    auto pathBack = reconstruct(si, sj);\n    route += toMoves(pathBack);\n    return route;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin>>N>>si>>sj;\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]=='#') isRoad[i][j]=false, cost[i][j]=0;\n            else isRoad[i][j]=true, cost[i][j]=grid[i][j]-'0';\n        }\n    }\n    buildVisibility();\n    totalRoads = 0;\n    for(int i=0;i<N;++i)for(int j=0;j<N;++j)if(isRoad[i][j])++totalRoads;\n\n    string ans = greedyCover();\n    cout<<ans<<'\\n';\n    return 0;\n}","future-contest-2022-qual":"#pragma GCC target(\"avx2,popcnt,lzcnt,abm,bmi,bmi2\")\n#pragma GCC optimize(\"O3,unroll-loops,inline\")\n#include <bits/stdc++.h>\nusing namespace std;\n\nstatic constexpr int MAXK = 20;\nstatic constexpr int MAXM = 20;\nstatic constexpr int MAXN = 1000;\nstatic constexpr int MAXDAY = 2000;\n\nint N, M, K, R;\nalignas(64) int d[MAXN][MAXK];\nint bucketId[MAXN];\nvector<int> adj[MAXN], radj[MAXN];\nint level[MAXN];\nint remPred[MAXN];\nbool done[MAXN];\nint memberTask[MAXM];\nint taskStart[MAXM];\nint taskMember[MAXN];\n\nint Lb[MAXM][MAXK], Ub[MAXM][MAXK];\n\n// ready list: [0..readyTail) are ready; readyTail..readySz are waiting\nint readyBuf[MAXN];\nint readyTail = 0, readySz = 0;\n\ninline void push_ready(int t){ readyBuf[readySz++] = t; }\n\nint globalBucket(int task){\n    int s = 0;\n    for(int k = 0; k < K; k++) s += d[task][k];\n    return s / K;\n}\n\nvoid build_level(){\n    for(int i = 0; i < N; i++){\n        for(int v : adj[i]) level[v] = max(level[v], level[i]+1);\n    }\n}\n\ninline void mark_done(int task){\n    if(done[task]) return;\n    done[task] = true;\n    for(int v : adj[task]){\n        remPred[v]--;\n        if(remPred[v] == 0) push_ready(v);\n    }\n}\n\ninline void belief_update(int j, int task, int dur){\n    const int low  = max(0, dur - 3);\n    const int high = dur + 3;\n    int sumLo = 0, sumHi = 0;\n    #pragma GCC unroll 8\n    for(int k = 0; k < K; k++){\n        const int dk = d[task][k];\n        sumLo += max(0, dk - Ub[j][k]);\n        sumHi += max(0, dk - Lb[j][k]);\n    }\n    if(sumLo > high){\n        int need = sumLo - high;\n        int cnt  = 0;\n        for(int k = 0; k < K; k++){\n            const int dk = d[task][k];\n            if(dk > Lb[j][k] && dk < Ub[j][k]) cnt++;\n        }\n        if(cnt == 0) cnt = 1;\n        int each = (need + cnt - 1) / cnt;\n        for(int k = 0; k < K; k++){\n            const int dk = d[task][k];\n            if(dk > Lb[j][k] && dk < Ub[j][k]){\n                Ub[j][k] = min(Ub[j][k], dk);\n                need -= each;\n                if(need <= 0) break;\n            }\n        }\n    }\n    if(sumHi < low){\n        int need = low - sumHi;\n        int cnt  = 0;\n        for(int k = 0; k < K; k++){\n            const int dk = d[task][k];\n            if(dk > Lb[j][k]) cnt++;\n        }\n        if(cnt == 0) cnt = 1;\n        int each = (need + cnt - 1) / cnt;\n        for(int k = 0; k < K; k++){\n            const int dk = d[task][k];\n            if(dk > Lb[j][k]){\n                Lb[j][k] = max(Lb[j][k], dk - each);\n                need -= each;\n                if(need <= 0) break;\n            }\n        }\n    }\n}\n\ninline pair<int,int> est(int task, int j){\n    int optGap = 0, pesGap = 0;\n    #pragma GCC unroll 8\n    for(int k = 0; k < K; k++){\n        const int dk = d[task][k];\n        optGap += max(0, dk - Ub[j][k]);\n        pesGap += max(0, dk - Lb[j][k]);\n    }\n    const int opt = max(1, optGap - 3);\n    const int pes = max(1, pesGap + 3);\n    return {opt, pes};\n}\n\nvector<pair<int,int>> assign(){\n    if(readyTail == readySz) return {};\n    static int avail[MAXM], nAvail;\n    nAvail = 0;\n    for(int j = 0; j < M; j++) if(memberTask[j] < 0) avail[nAvail++] = j;\n    if(nAvail == 0) return {};\n\n    static tuple<int,int,int> es[MAXM * MAXN];\n    int esz = 0;\n    for(int a = 0; a < nAvail; a++){\n        int j = avail[a];\n        for(int t = readyTail; t < readySz; t++){\n            int i = readyBuf[t];\n            auto [opt, pes] = est(i, j);\n            int w = 3*opt + pes + 2*level[i];\n            es[esz++] = {w, a, t};\n        }\n    }\n    sort(es, es + esz);\n    static char ua[MAXM], ut[MAXN];\n    memset(ua, 0, nAvail);\n    memset(ut, 0, readySz - readyTail);\n    vector<pair<int,int>> ans;\n    ans.reserve(min(nAvail, readySz - readyTail));\n    for(int e = 0; e < esz; e++){\n        auto [w, a, t] = es[e];\n        if(ua[a] || ut[t - readyTail]) continue;\n        ua[a] = ut[t - readyTail] = 1;\n        int j = avail[a];\n        int i = readyBuf[t];\n        ans.emplace_back(j, i);\n    }\n    return ans;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> K >> R;\n    for(int i = 0; i < N; i++){\n        for(int k = 0; k < K; k++) cin >> d[i][k];\n        bucketId[i] = globalBucket(i);\n    }\n    for(int i = 0; i < R; i++){\n        int u,v; cin >> u >> v; u--; v--;\n        adj[u].push_back(v);\n        radj[v].push_back(u);\n    }\n    for(int i = 0; i < N; i++){\n        remPred[i] = radj[i].size();\n        if(remPred[i] == 0) push_ready(i);\n    }\n    build_level();\n\n    for(int j = 0; j < M; j++)\n        for(int k = 0; k < K; k++){\n            Lb[j][k] = 0;\n            Ub[j][k] = 200;\n        }\n    memset(memberTask, -1, sizeof memberTask);\n    memset(taskMember, -1, sizeof taskMember);\n\n    int day = 0;\n    while(day < MAXDAY){\n        day++;\n        auto match = assign();\n        const int m = match.size();\n        cout << m;\n        for(int i = 0; i < m; i++){\n            auto [j, t] = match[i];\n            cout << ' ' << (j+1) << ' ' << (t+1);\n            memberTask[j] = t;\n            taskMember[t] = j;\n            taskStart[j] = day;\n            // mark task as taken (swap with tail and pop)\n            int pos = find(readyBuf + readyTail, readyBuf + readySz, t) - readyBuf;\n            swap(readyBuf[pos], readyBuf[readyTail]);\n            readyTail++;\n        }\n        cout << '\\n';\n        cout.flush();\n\n        int n; \n        if(!(cin >> n)) break;\n        if(n == -1) break;\n        for(int i = 0; i < n; i++){\n            int j; cin >> j; j--;\n            int task = memberTask[j];\n            if(task < 0) continue;\n            int dur = day - taskStart[j] + 1;\n            belief_update(j, task, dur);\n            mark_done(task);\n            memberTask[j] = -1;\n            taskMember[task] = -1;\n        }\n        bool alld = true;\n        for(int i = 0; i < N; i++) if(!done[i]){ alld=false; break; }\n        if(alld) break;\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nstruct P { int x, y; };\nint man(const P& a, const P& b){\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\nstruct Order { P pu, de; int id; };\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<Order> all(1000);\n    for (int i = 0; i < 1000; ++i){\n        cin >> all[i].pu.x >> all[i].pu.y >> all[i].de.x >> all[i].de.y;\n        all[i].id = i;\n    }\n\n    const auto t0 = chrono::steady_clock::now();\n    ll bestT = LLONG_MAX;\n    vector<int> bestSel;\n    vector<P>   bestRoute;\n\n    mt19937 rng(123456);\n\n    const P office{400, 400};\n\n    while (true){\n        auto now = chrono::steady_clock::now();\n        if (chrono::duration<double>(now - t0).count() > 1.96) break;\n\n        /* 1. choose 50 random orders */\n        vector<int> sel(1000);\n        iota(sel.begin(), sel.end(), 0);\n        shuffle(sel.begin(), sel.end(), rng);\n        sel.resize(50);\n        sort(sel.begin(), sel.end());\n\n        /* 2. build initial route: office -> ... -> office */\n        vector<P> route = { office };\n        vector<int> puOf(50, -1), deOf(50, -1); // positions in route\n\n        auto costIns = [&](const P& pt, int at){\n            if (at == 0)\n                return man(office, pt) + man(pt, route[0]) - man(office, route[0]);\n            if (at == (int)route.size())\n                return man(route.back(), pt) + man(pt, office) - man(route.back(), office);\n            return man(route[at-1], pt) + man(pt, route[at]) - man(route[at-1], route[at]);\n        };\n\n        for (int oid = 0; oid < 50; ++oid){\n            const Order& o = all[sel[oid]];\n            ll bestInc = LLONG_MAX;\n            int bestPu = -1, bestDe = -1;\n            for (int pu = 1; pu <= (int)route.size(); ++pu){ // pu after office\n                ll incPu = costIns(o.pu, pu);\n                for (int de = pu + 1; de <= (int)route.size() + 1; ++de){\n                    ll incDe = 0;\n                    int realDe = (de > pu ? de - 1 : de);\n                    incDe = costIns(o.de, realDe);\n                    if (incPu + incDe < bestInc){\n                        bestInc = incPu + incDe;\n                        bestPu  = pu;\n                        bestDe  = de;\n                    }\n                }\n            }\n            route.insert(route.begin() + bestPu, o.pu);\n            int realDe = (bestDe > bestPu ? bestDe : bestDe);\n            route.insert(route.begin() + realDe, o.de);\n            /* rebuild puOf/deOf */\n            for (int i = 0; i < (int)route.size(); ++i){\n                if (route[i].x == o.pu.x && route[i].y == o.pu.y) puOf[oid] = i;\n                if (route[i].x == o.de.x && route[i].y == o.de.y) deOf[oid] = i;\n            }\n        }\n        route.push_back(office);\n\n        /* 3. fast random 2-opt, keeping 0 and n-1 fixed */\n        auto length = [&](const vector<P>& r){\n            ll len = 0;\n            for (int i = 0; i + 1 < (int)r.size(); ++i) len += man(r[i], r[i+1]);\n            return len;\n        };\n\n        uniform_int_distribution<int> uid(1, (int)route.size() - 3);\n        const int MAX_TRIES = 20000;\n        for (int tries = 0; tries < MAX_TRIES; ++tries){\n            int i = uid(rng);\n            int j = uid(rng);\n            if (j <= i) continue;\n            ll old = man(route[i], route[i+1]) + man(route[j], route[j+1]);\n            ll neo = man(route[i], route[j]) + man(route[i+1], route[j+1]);\n            if (neo >= old) continue;\n            /* reverse segment i+1 .. j */\n            reverse(route.begin() + i + 1, route.begin() + j + 1);\n            /* rebuild puOf/deOf and check feasibility */\n            bool ok = true;\n            for (int oid = 0; oid < 50 && ok; ++oid){\n                puOf[oid] = deOf[oid] = -1;\n                for (int p = 0; p < (int)route.size(); ++p){\n                    if (route[p].x == all[sel[oid]].pu.x && route[p].y == all[sel[oid]].pu.y) puOf[oid] = p;\n                    if (route[p].x == all[sel[oid]].de.x && route[p].y == all[sel[oid]].de.y) deOf[oid] = p;\n                }\n                ok &= (puOf[oid] < deOf[oid]);\n            }\n            if (ok) continue; // accept\n            /* rollback */\n            reverse(route.begin() + i + 1, route.begin() + j + 1);\n            for (int oid = 0; oid < 50; ++oid){\n                puOf[oid] = deOf[oid] = -1;\n                for (int p = 0; p < (int)route.size(); ++p){\n                    if (route[p].x == all[sel[oid]].pu.x && route[p].y == all[sel[oid]].pu.y) puOf[oid] = p;\n                    if (route[p].x == all[sel[oid]].de.x && route[p].y == all[sel[oid]].de.y) deOf[oid] = p;\n                }\n            }\n        }\n\n        ll T = length(route);\n        if (T < bestT){\n            bestT = T;\n            bestSel = sel;\n            bestRoute = route;\n        }\n    }\n\n    /* 4. output */\n    cout << 50;\n    for (int x : bestSel) cout << ' ' << x + 1;\n    cout << '\\n';\n    cout << bestRoute.size();\n    for (auto &p : bestRoute) cout << ' ' << p.x << ' ' << p.y;\n    cout << '\\n';\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct UnionFind {\n    vector<int> parent, rank;\n    int components;\n    \n    UnionFind(int n) : parent(n), rank(n, 0), components(n) {\n        for (int i = 0; i < n; i++) {\n            parent[i] = i;\n        }\n    }\n    \n    int find(int x) {\n        if (parent[x] != x) {\n            parent[x] = find(parent[x]);\n        }\n        return parent[x];\n    }\n    \n    bool unite(int x, int y) {\n        int px = find(x), py = find(y);\n        if (px == py) return false;\n        \n        if (rank[px] < rank[py]) {\n            parent[px] = py;\n        } else {\n            parent[py] = px;\n            if (rank[px] == rank[py]) {\n                rank[px]++;\n            }\n        }\n        components--;\n        return true;\n    }\n    \n    bool connected() {\n        return components == 1;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 400, M = 1995;\n    \n    // Read coordinates\n    vector<pair<int, int>> coords(N);\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    // Read edges and calculate expected lengths\n    vector<int> u(M), v(M);\n    vector<int> d(M);\n    \n    for (int i = 0; i < M; i++) {\n        cin >> u[i] >> v[i];\n        \n        // Calculate Euclidean distance\n        double dx = coords[u[i]].first - coords[v[i]].first;\n        double dy = coords[u[i]].second - coords[v[i]].second;\n        double dist = sqrt(dx*dx + dy*dy);\n        d[i] = round(dist);\n    }\n    \n    UnionFind uf(N);\n    int accepted = 0;\n    bool has_spanning_tree = false;\n    \n    // Process each edge\n    for (int i = 0; i < M; i++) {\n        int l;\n        cin >> l;\n        \n        bool adopt = false;\n        double ratio = (double)l / d[i];\n        \n        // RULE 1: Always accept connecting edges - NO EXCEPTIONS\n        if (uf.find(u[i]) != uf.find(v[i])) {\n            adopt = true;\n        }\n        // RULE 2: Accept minimal non-connecting edges\n        else if (!has_spanning_tree && accepted < N && ratio <= 1.12) {\n            adopt = true;\n        }\n        // RULE 3: Post-connectivity: only exceptional deals\n        else if (has_spanning_tree && ratio <= 1.03) {\n            adopt = true;\n        }\n        \n        if (adopt) {\n            bool was_connected = uf.connected();\n            uf.unite(u[i], v[i]);\n            accepted++;\n            \n            if (!was_connected && uf.connected()) {\n                has_spanning_tree = true;\n            }\n            \n            cout << \"1\" << endl;\n        } else {\n            cout << \"0\" << endl;\n        }\n        \n        cout.flush();\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 30, W = 30, TURNS = 300;\nconst int dx[4] = {-1, 1, 0, 0}, dy[4] = {0, 0, -1, 1};\nconst char *dir = \"UDLR\", *Dir = \"UDLR\", *block = \"udlr\";\n\nint N, M;\nstruct Pet {\n    int x, y, t;\n} pets[20];\nstruct Human {\n    int x, y;\n} humans[10];\n\nbool wall[H][W]; // wall[x][y] = true if blocked\nint pet_x[20], pet_y[20];\n\n// BFS reachable squares from (sx,sy), return count and pet count\npair<int, int> bfs_reachable(int sx, int sy) {\n    static bool vis[H][W];\n    memset(vis, 0, sizeof(vis));\n    queue<pair<int, int>> q;\n    if (wall[sx][sy]) return {0, 0};\n    vis[sx][sy] = true;\n    q.push({sx, sy});\n    int cnt = 0, pcnt = 0;\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        cnt++;\n        for (int i = 0; i < N; i++) {\n            if (pet_x[i] == x && pet_y[i] == pcnt++) pcnt--;\n            if (pet_x[i] == x && pet_y[i] == y) pcnt++;\n        }\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n            if (wall[nx][ny] || vis[nx][ny]) continue;\n            vis[nx][ny] = true;\n            q.push({nx, ny});\n        }\n    }\n    return {cnt, pcnt};\n}\n\n// Heuristic score for a human at (x,y)\ndouble heuristic(int x, int y) {\n    auto [r, p] = bfs_reachable(x, y);\n    return r - 900.0 * p / 2.0;\n}\n\n// Check if can block (bx,by) from human at (x,y)\nbool can_block(int x, int y, int bx, int by) {\n    if (abs(bx - x) + abs(by - y) != 1) return false;\n    if (wall[bx][by]) return true; // already blocked\n    // Check if any pet or human is on (bx,by) at start\n    for (int i = 0; i < N; i++) {\n        if (pet_x[i] == bx && pet_y[i] == by) return false;\n    }\n    for (int i = 0; i < M; i++) {\n        if (humans[i].x == bx && humans[i].y == by) return false;\n    }\n    // Check if any pet is adjacent to (bx,by)\n    for (int d = 0; d < 4; d++) {\n        int nx = bx + dx[d], ny = by + dy[d];\n        if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n        for (int i = 0; i < N; i++) {\n            if (pet_x[i] == nx && pet_y[i] == ny) return false;\n        }\n    }\n    return true;\n}\n\n// Simulate pet moves (simplified: assume random for 1-3, greedy for 4-5)\nvoid simulate_pets() {\n    // For types 1-3: random basic moves (here we just do random)\n    // For types 4-5: target and move closer\n    // This is a placeholder: in real code, use BFS and rules\n    for (int i = 0; i < N; i++) {\n        int t = pets[i].t;\n        int &x = pet_x[i], &y = pet_y[i];\n        if (t <= 3) {\n            int steps = t;\n            while (steps--) {\n                vector<int> dirs;\n                for (int d = 0; d < 4; d++) {\n                    int nx = x + dx[d], ny = y + dy[d];\n                    if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n                    if (wall[nx][ny]) continue;\n                    dirs.push_back(d);\n                }\n                if (dirs.empty()) break;\n                int d = dirs[rand() % dirs.size()];\n                x += dx[d]; y += dy[d];\n            }\n        } else if (t == 4) {\n            // Dog: target human, move closer\n            // Simplified: pick random human and move one step closer\n            int ti = rand() % M;\n            int hx = humans[ti].x, hy = humans[ti].y;\n            // BFS to find direction\n            // For now, just move randomly\n            vector<int> dirs;\n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n                if (wall[nx][ny]) continue;\n                dirs.push_back(d);\n            }\n            if (!dirs.empty()) {\n                int d = dirs[rand() % dirs.size()];\n                x += dx[d]; y += dy[d];\n            }\n        } else {\n            // Cat: target square, move closer\n            // Simplified: move randomly\n            vector<int> dirs;\n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n                if (wall[nx][ny]) continue;\n                dirs.push_back(d);\n            }\n            if (!dirs.empty()) {\n                int d = dirs[rand() % dirs.size()];\n                x += dx[d]; y += dy[d];\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    for (int i = 0; i < N; i++) {\n        cin >> pets[i].x >> pets[i].y >> pets[i].t;\n        pets[i].x--; pets[i].y--;\n        pet_x[i] = pets[i].x;\n        pet_y[i] = pets[i].y;\n    }\n    cin >> M;\n    for (int i = 0; i < M; i++) {\n        cin >> humans[i].x >> humans[i].y;\n        humans[i].x--; humans[i].y--;\n    }\n\n    memset(wall, 0, sizeof(wall));\n\n    for (int turn = 0; turn < TURNS; turn++) {\n        string act;\n        for (int i = 0; i < M; i++) {\n            int x = humans[i].x, y = humans[i].y;\n            double best = -1e9;\n            char best_act = '.';\n            // Try stay\n            double sc = heuristic(x, y);\n            if (sc > best) { best = sc; best_act = '.'; }\n            // Try move\n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n                if (wall[nx][ny]) continue;\n                humans[i].x = nx; humans[i].y = ny;\n                sc = heuristic(nx, ny);\n                if (sc > best) { best = sc; best_act = Dir[d]; }\n                humans[i].x = x; humans[i].y = y;\n            }\n            // Try block\n            for (int d = 0; d < 4; d++) {\n                int bx = x + dx[d], by = y + dy[d];\n                if (!can_block(x, y, bx, by)) continue;\n                bool old = wall[bx][by];\n                wall[bx][by] = true;\n                sc = heuristic(x, y);\n                if (sc > best) { best = sc; best_act = block[d]; }\n                wall[bx][by] = old;\n            }\n            act += best_act;\n            // Apply best action\n            if (best_act == '.') {\n                // stay\n            } else if (best_act >= 'U' && best_act <= 'R') {\n                int d = best_act - 'U';\n                humans[i].x += dx[d];\n                humans[i].y += dy[d];\n            } else if (best_act >= 'u' && best_act <= 'r') {\n                int d = best_act - 'u';\n                int bx = x + dx[d], by = y + dy[d];\n                wall[bx][by] = true;\n            }\n        }\n        cout << act << endl;\n        cout.flush();\n\n        // Read pet moves\n        for (int i = 0; i < N; i++) {\n            string s;\n            cin >> s;\n            // Apply pet moves\n            int &x = pet_x[i], &y = pet_y[i];\n            for (char c : s) {\n                int d = -1;\n                if (c == 'U') d = 0;\n                else if (c == 'D') d = 1;\n                else if (c == 'L') d = 2;\n                else if (c == 'R') d = 3;\n                else continue;\n                int nx = x + dx[d], ny = y + dy[d];\n                if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;\n                if (wall[nx][ny]) continue;\n                x = nx; y = ny;\n            }\n        }\n    }\n\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic uint64_t rng_state = 123456789123456789ULL;\ninline uint64_t xorshift64() {\n    uint64_t x = rng_state;\n    x ^= x << 13; x ^= x >> 7; x ^= x << 17;\n    rng_state = x; return x;\n}\ninline int  randint(int l, int r)   { return l + (xorshift64() % (r - l + 1)); }\ninline double rand01()              { return (xorshift64() & ((1ULL<<32)-1)) / double(1ULL<<32); }\n\nint si,sj,ti,tj;\ndouble pforget;\nbool wallh[20][19], wallv[19][20];\nint  dist[20][20];\nstring best_str;\ndouble best_score;\nchrono::steady_clock::time_point start_time;\n\nconst int INF = 1000000;\n\n/* ---------- grid utilities ---------- */\nvoid bfs_dist(){\n    for(int i=0;i<20;i++)for(int j=0;j<20;j++) dist[i][j]=INF;\n    deque<pair<int,int>> dq;\n    dist[ti][tj]=0; dq.push_back({ti,tj});\n    static int di[4]={-1,1,0,0}, dj[4]={0,0,-1,1};\n    while(!dq.empty()){\n        auto [i,j]=dq.front(); dq.pop_front();\n        for(int d=0;d<4;d++){\n            int ni=i+di[d], nj=j+dj[d];\n            if(ni<0||nj<0||ni>=20||nj>=20) continue;\n            if(d==0&&wallv[ni][j]) continue;\n            if(d==1&&wallv[i][j]) continue;\n            if(d==2&&wallh[i][nj]) continue;\n            if(d==3&&wallh[i][j]) continue;\n            if(dist[ni][nj]>dist[i][j]+1){\n                dist[ni][nj]=dist[i][j]+1;\n                dq.push_back({ni,nj});\n            }\n        }\n    }\n}\ninline bool canmove(int i,int j,int d){\n    if(d==0){ if(i==0) return 0; return !wallv[i-1][j]; }\n    if(d==1){ if(i==19)return 0; return !wallv[i][j]; }\n    if(d==2){ if(j==0) return 0; return !wallh[i][j-1]; }\n    if(d==3){ if(j==19)return 0; return !wallh[i][j]; }\n    return 0;\n}\ninline int mi(int i,int d){ return d==0?i-1:(d==1?i+1:i); }\ninline int mj(int j,int d){ return d==2?j-1:(d==3?j+1:j); }\n\n/* ---------- exact evaluator ---------- */\ndouble eval(const string &s){\n    const int L=s.size();\n    static double cur[400], nxt[400];\n    for(int v=0;v<400;v++) cur[v]=0.;\n    int start=si*20+sj;\n    cur[start]=1.0;\n    double succ=0., et=0.;\n    for(int t=0;t<L;t++){\n        for(int v=0;v<400;v++) nxt[v]=0.;\n        for(int v=0;v<400;v++){\n            if(cur[v]<1e-14) continue;\n            int i=v/20, j=v%20;\n            if(i==ti&&j==tj) continue;\n            int nopen=0;\n            for(int d=0;d<4;d++) if(canmove(i,j,d)) nopen++;\n            double pstay = pforget;\n            nxt[v] += cur[v]*pstay;\n            if(nopen>0){\n                double pdir = (1.-pforget)/nopen;\n                for(int d=0;d<4;d++){\n                    if(!canmove(i,j,d)) continue;\n                    int ni=mi(i,d), nj=mj(j,d), u=ni*20+nj;\n                    if(ni==ti&&nj==tj){\n                        double prob=cur[v]*pdir;\n                        succ+=prob; et+=prob*(t+1);\n                    }else nxt[u]+=cur[v]*pdir;\n                }\n            }else nxt[v]+=cur[v]*(1.-pforget);\n        }\n        swap(cur,nxt);\n    }\n    double left=0.; for(int v=0;v<400;v++) left+=cur[v];\n    succ=1.-left;\n    if(succ<1e-14) return 0.;\n    double mean_t=et/succ;\n    double raw=succ*(401.-mean_t);\n    return raw - 0.05*max(0,(int)s.size()-90);\n}\n\n/* ---------- greedy random walk ---------- */\nstring greedy_random_walk(int want_len){\n    string path;\n    int i=si, j=sj;\n    while((int)path.size()<want_len){\n        if(i==ti&&j==tj) break;\n        int dirs[4]={0,1,2,3};\n        for(int k=0;k<4;k++){ int r=randint(k,3); swap(dirs[k],dirs[r]); }\n        double best=-1e9; int bestd=-1;\n        for(int k=0;k<4;k++){\n            int d=dirs[k]; if(!canmove(i,j,d)) continue;\n            int ni=mi(i,d), nj=mj(j,d);\n            double val=-dist[ni][nj]+rand01()*0.3;\n            if(val>best){ best=val; bestd=d; }\n        }\n        if(bestd>=0){ path+=\"UDLR\"[bestd]; i=mi(i,bestd); j=mj(j,bestd); }\n        else path+='U';\n    }\n    while((int)path.size()<want_len){\n        if(i==ti&&j==tj){ path+='R'; continue; }\n        int bestd=-1, bestv=INF;\n        for(int d=0;d<4;d++){\n            if(!canmove(i,j,d)) continue;\n            int ni=mi(i,d), nj=mj(j,d);\n            if(dist[ni][nj]<bestv){ bestv=dist[ni][nj]; bestd=d; }\n        }\n        if(bestd>=0){ path+=\"UDLR\"[bestd]; i=mi(i,bestd); j=mj(j,bestd); }\n        else path+='U';\n    }\n    return path;\n}\n\n/* ---------- segment re-route ---------- */\nstring greedy_segment(int len, int &ri, int &rj){\n    string path;\n    int i=ri, j=rj;\n    while((int)path.size()<len){\n        if(i==ti&&j==tj) break;\n        int dirs[4]={0,1,2,3};\n        for(int k=0;k<4;k++){ int r=randint(k,3); swap(dirs[k],dirs[r]); }\n        double best=-1e9; int bestd=-1;\n        for(int k=0;k<4;k++){\n            int d=dirs[k]; if(!canmove(i,j,d)) continue;\n            int ni=mi(i,d), nj=mj(j,d);\n            double val=-dist[ni][nj]+rand01()*0.3;\n            if(val>best){ best=val; bestd=d; }\n        }\n        if(bestd>=0){ path+=\"UDLR\"[bestd]; i=mi(i,bestd); j=mj(j,bestd); }\n        else path+='U';\n    }\n    while((int)path.size()<len){\n        if(i==ti&&j==tj){ path+='R'; continue; }\n        int bestd=-1, bestv=INF;\n        for(int d=0;d<4;d++){\n            if(!canmove(i,j,d)) continue;\n            int ni=mi(i,d), nj=mj(j,d);\n            if(dist[ni][nj]<bestv){ bestv=dist[ni][nj]; bestd=d; }\n        }\n        if(bestd>=0){ path+=\"UDLR\"[bestd]; i=mi(i,bestd); j=mj(j,bestd); }\n        else path+='U';\n    }\n    ri=i; rj=j;\n    return path;\n}\n\ninline int char2d(char c){\n    return c=='U'?0:(c=='D'?1:(c=='L'?2:3));\n}\n\nstring segment_reroute(const string &s){\n    int L=s.size();\n    if(L<10) return s;\n    int seg_len=randint(5,min(20,L));\n    int pos=randint(0,L-seg_len);\n    int i=si, j=sj;\n    // simulate up to pos\n    for(int k=0;k<pos;k++){\n        int d=char2d(s[k]);\n        if(canmove(i,j,d)){ i=mi(i,d); j=mj(j,d); }\n    }\n    int si_seg=i, sj_seg=j;\n    // simulate the segment to know where we must arrive\n    for(int k=pos;k<pos+seg_len;k++){\n        int d=char2d(s[k]);\n        if(canmove(i,j,d)){ i=mi(i,d); j=mj(j,d); }\n    }\n    // build new segment that starts at (si_seg,sj_seg) and has same length\n    string replacement=greedy_segment(seg_len, si_seg, sj_seg);\n    // patch\n    string nxt=s;\n    nxt.replace(pos,seg_len,replacement);\n    return nxt;\n}\n\n/* ---------- simulated annealing ---------- */\nvoid anneal(){\n    const double T0=0.5, alpha=0.995;\n    string cur=best_str;\n    double cursc=best_score;\n    double T=T0;\n    while(1){\n        auto now=chrono::steady_clock::now();\n        double elapsed=chrono::duration<double>(now - start_time).count();\n        if(elapsed>1.75) break;\n\n        string nxt=cur;\n        int op=randint(0,11);   // 0-7 flip, 8 del, 9 ins, 10-11 reroute\n        if(op<=7){\n            int pos=randint(0,(int)nxt.size()-1);\n            int nd=randint(0,3);\n            nxt[pos]=\"UDLR\"[nd];\n        }else if(op==8){\n            if(nxt.size()<=60) continue;\n            int pos=randint(0,(int)nxt.size()-1);\n            nxt.erase(pos,1);\n        }else if(op==9){\n            if(nxt.size()>=200) continue;\n            int pos=randint(0,(int)nxt.size());\n            int nd=randint(0,3);\n            nxt.insert(pos,1,\"UDLR\"[nd]);\n        }else{\n            nxt=segment_reroute(cur);\n        }\n\n        double nxtsc=eval(nxt);\n        double delta=nxtsc-cursc;\n        if(delta>0 || rand01()<exp(delta/T)){\n            cur=nxt; cursc=nxtsc;\n            if(nxtsc>best_score){\n                best_score=nxtsc;\n                best_str=nxt;\n            }\n        }\n        T*=alpha;\n        if(T<1e-4) T=1e-4;\n    }\n}\n\n/* ---------- final robustness repair ---------- */\nvoid repair_zeros(){\n    for(int attempt=0;attempt<13;attempt++){\n        auto now=chrono::steady_clock::now();\n        double elapsed=chrono::duration<double>(now - start_time).count();\n        if(elapsed>1.98) break;\n        int want=min(200, (int)best_str.size()+30);\n        string cand=greedy_random_walk(want);\n        double sc=eval(cand);\n        if(sc>best_score){ best_score=sc; best_str=cand; }\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    start_time=chrono::steady_clock::now();\n\n    cin>>si>>sj>>ti>>tj>>pforget;\n    for(int i=0;i<20;i++){\n        string row; cin>>row;\n        for(int j=0;j<19;j++) wallh[i][j]=(row[j]=='1');\n    }\n    for(int i=0;i<19;i++){\n        string row; cin>>row;\n        for(int j=0;j<20;j++) wallv[i][j]=(row[j]=='1');\n    }\n    bfs_dist();\n\n    best_score=-1e9;\n    for(int attempt=0;attempt<200;attempt++){\n        int want=randint(60,180);\n        string cand=greedy_random_walk(want);\n        double sc=eval(cand);\n        if(sc>best_score){ best_score=sc; best_str=cand; }\n    }\n    anneal();\n    repair_zeros();\n    cout<<best_str<<\"\\n\";\n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <random>\n#include <algorithm>\n#include <chrono>\n#include <queue>\n#include <unordered_set>\n\nusing namespace std;\n\nconst int SIZE = 30;\nconst int DIR[4][2] = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};\n\nconst int to[8][4] = {\n    {1, 0, -1, -1},  // type 0\n    {3, -1, -1, 0},  // type 1\n    {-1, -1, 3, 2},  // type 2\n    {-1, 2, 1, -1},  // type 3\n    {1, 0, 3, 2},    // type 4\n    {3, 2, 1, 0},    // type 5\n    {2, -1, 0, -1},  // type 6\n    {-1, 3, -1, 1}   // type 7\n};\n\nint grid[SIZE][SIZE];\nint rotation[SIZE][SIZE];\nint best_rotation[SIZE][SIZE];\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\ninline int get_tile_type(int i, int j) {\n    int base_type = grid[i][j];\n    int rot = rotation[i][j];\n    if (base_type <= 3) {\n        return (base_type + rot) % 4;\n    } else if (base_type <= 5) {\n        return 4 + (base_type - 4 + rot) % 2;\n    } else {\n        return 6 + (base_type - 6 + rot) % 2;\n    }\n}\n\nint trace_loop(int si, int sj, int sd) {\n    int i = si, j = sj, d = sd;\n    int length = 0;\n    \n    for (int step = 0; step < 2000; step++) {\n        int tile_type = get_tile_type(i, j);\n        int d2 = to[tile_type][d];\n        if (d2 == -1) return 0;\n        \n        i += DIR[d2][0];\n        j += DIR[d2][1];\n        if (i < 0 || i >= SIZE || j < 0 || j >= SIZE) return 0;\n        \n        d = (d2 + 2) % 4;\n        length++;\n        \n        if (i == si && j == sj && d == sd) return length;\n    }\n    return 0;\n}\n\npair<int, int> find_loops_adaptive() {\n    vector<int> loop_lengths;\n    static vector<pair<int, int>> hotspots;\n    \n    // Initial hotspots\n    if (hotspots.empty()) {\n        // Center and edge areas\n        for (int i = 3; i < SIZE-3; i += 2) {\n            for (int j = 3; j < SIZE-3; j += 2) {\n                hotspots.push_back({i, j});\n            }\n        }\n    }\n    \n    // Check hotspots first\n    for (auto [i, j] : hotspots) {\n        if (i >= 0 && i < SIZE && j >= 0 && j < SIZE) {\n            for (int d = 0; d < 4; d++) {\n                int len = trace_loop(i, j, d);\n                if (len > 8) {\n                    loop_lengths.push_back(len);\n                    // Add neighbors of successful loops as new hotspots\n                    for (int di = -1; di <= 1; di++) {\n                        for (int dj = -1; dj <= 1; dj++) {\n                            if (di != 0 || dj != 0) {\n                                int ni = i + di, nj = j + dj;\n                                if (ni >= 0 && ni < SIZE && nj >= 0 && nj < SIZE) {\n                                    hotspots.push_back({ni, nj});\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Remove duplicates and limit hotspots\n    sort(hotspots.begin(), hotspots.end());\n    hotspots.erase(unique(hotspots.begin(), hotspots.end()), hotspots.end());\n    if (hotspots.size() > 200) {\n        hotspots.resize(200);\n    }\n    \n    // Fill with some random positions if needed\n    while (loop_lengths.size() < 10 && !hotspots.empty()) {\n        int idx = rng() % hotspots.size();\n        int i = hotspots[idx].first;\n        int j = hotspots[idx].second;\n        int d = rng() % 4;\n        int len = trace_loop(i, j, d);\n        if (len > 6) {\n            loop_lengths.push_back(len);\n        }\n        hotspots.erase(hotspots.begin() + idx);\n    }\n    \n    sort(loop_lengths.rbegin(), loop_lengths.rend());\n    if (loop_lengths.size() < 2) return {0, 0};\n    return {loop_lengths[0], loop_lengths[1]};\n}\n\nint calculate_score() {\n    auto [l1, l2] = find_loops_adaptive();\n    return l1 * l2;\n}\n\nvoid pattern_based_search() {\n    int best_score = 0;\n    \n    // Try different initialization patterns\n    vector<void(*)()> init_patterns = {\n        []() { // Smart pattern 1\n            for (int i = 0; i < SIZE; i++) {\n                for (int j = 0; j < SIZE; j++) {\n                    rotation[i][j] = ((i ^ j) + (i + j) / 3) % 4;\n                }\n            }\n        },\n        []() { // Smart pattern 2\n            for (int i = 0; i < SIZE; i++) {\n                for (int j = 0; j < SIZE; j++) {\n                    rotation[i][j] = (i * 2 + j * 3 + (i * j) / 10) % 4;\n                }\n            }\n        },\n        []() { // Random\n            for (int i = 0; i < SIZE; i++) {\n                for (int j = 0; j < SIZE; j++) {\n                    rotation[i][j] = rng() % 4;\n                }\n            }\n        }\n    };\n    \n    for (int pattern_idx = 0; pattern_idx < init_patterns.size(); pattern_idx++) {\n        init_patterns[pattern_idx]();\n        \n        int current_score = calculate_score();\n        int local_best = current_score;\n        \n        // Beam search with multiple candidates\n        const int beam_width = 5;\n        vector<vector<vector<int>>> candidates(beam_width, vector<vector<int>>(SIZE, vector<int>(SIZE)));\n        vector<int> candidate_scores(beam_width, current_score);\n        \n        // Fill initial candidates\n        for (int b = 0; b < beam_width; b++) {\n            for (int i = 0; i < SIZE; i++) {\n                for (int j = 0; j < SIZE; j++) {\n                    candidates[b][i][j] = rotation[i][j];\n                }\n            }\n        }\n        \n        // Iterative improvement\n        for (int iter = 0; iter < 1000; iter++) {\n            vector<pair<int, vector<vector<int>>>> all_candidates;\n            \n            // Generate neighbors for each beam candidate\n            for (int b = 0; b < beam_width; b++) {\n                // Copy current candidate to rotation\n                for (int i = 0; i < SIZE; i++) {\n                    for (int j = 0; j < SIZE; j++) {\n                        rotation[i][j] = candidates[b][i][j];\n                    }\n                }\n                \n                // Try pattern moves\n                for (int pattern = 0; pattern < 3; pattern++) {\n                    int center_i = rng() % (SIZE - 4) + 2;\n                    int center_j = rng() % (SIZE - 4) + 2;\n                    \n                    // Apply 2x2 pattern rotation\n                    for (int di = 0; di < 2; di++) {\n                        for (int dj = 0; dj < 2; dj++) {\n                            int ni = center_i + di;\n                            int nj = center_j + dj;\n                            rotation[ni][nj] = (rotation[ni][nj] + 1 + pattern) % 4;\n                        }\n                    }\n                    \n                    int score = calculate_score();\n                    all_candidates.push_back({score, vector<vector<int>>(SIZE, vector<int>(SIZE))});\n                    \n                    for (int i = 0; i < SIZE; i++) {\n                        for (int j = 0; j < SIZE; j++) {\n                            all_candidates.back().second[i][j] = rotation[i][j];\n                        }\n                    }\n                    \n                    // Revert for next try\n                    for (int di = 0; di < 2; di++) {\n                        for (int dj = 0; dj < 2; dj++) {\n                            int ni = center_i + di;\n                            int nj = center_j + dj;\n                            rotation[ni][nj] = candidates[b][ni][nj];\n                        }\n                    }\n                }\n            }\n            \n            // Keep best candidates\n            sort(all_candidates.rbegin(), all_candidates.rend());\n            int new_beam_size = min(beam_width, (int)all_candidates.size());\n            \n            for (int b = 0; b < new_beam_size; b++) {\n                candidate_scores[b] = all_candidates[b].first;\n                candidates[b] = all_candidates[b].second;\n                \n                if (all_candidates[b].first > local_best) {\n                    local_best = all_candidates[b].first;\n                    for (int i = 0; i < SIZE; i++) {\n                        for (int j = 0; j < SIZE; j++) {\n                            rotation[i][j] = all_candidates[b].second[i][j];\n                        }\n                    }\n                }\n            }\n            \n            if (iter > 200 && local_best == current_score) break;\n            current_score = local_best;\n        }\n        \n        if (current_score > best_score) {\n            best_score = current_score;\n            for (int i = 0; i < SIZE; i++) {\n                for (int j = 0; j < SIZE; j++) {\n                    best_rotation[i][j] = rotation[i][j];\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    for (int i = 0; i < SIZE; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < SIZE; j++) {\n            grid[i][j] = line[j] - '0';\n        }\n    }\n    \n    // Run pattern-based search\n    pattern_based_search();\n    \n    // Output best solution\n    for (int i = 0; i < SIZE; i++) {\n        for (int j = 0; j < SIZE; j++) {\n            cout << best_rotation[i][j];\n        }\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc011":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <chrono>\n#include <algorithm>\n#include <unordered_set>\n#include <random>\n\nusing namespace std;\n\nconst int dx[4] = {-1, 0, 1, 0};\nconst int dy[4] = {0, 1, 0, -1};\nconst char dir_char[4] = {'U', 'R', 'D', 'L'};\n\nint N, T;\nvector<vector<int>> board;\nint empty_row, empty_col;\nstring solution;\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nbool has_line(int tile, int direction) {\n    return (tile >> direction) & 1;\n}\n\nbool can_connect(int tile1, int tile2, int direction) {\n    int opposite = (direction + 2) % 4;\n    return has_line(tile1, direction) && has_line(tile2, opposite);\n}\n\nbool is_valid_move(int r, int c) {\n    return r >= 0 && r < N && c >= 0 && c < N && board[r][c] != 0;\n}\n\nvoid make_move(int direction) {\n    int nr = empty_row + dx[direction];\n    int nc = empty_col + dy[direction];\n    \n    if (!is_valid_move(nr, nc)) return;\n    \n    swap(board[empty_row][empty_col], board[nr][nc]);\n    empty_row = nr;\n    empty_col = nc;\n    solution += dir_char[direction];\n}\n\nint quick_tree_size(int start_r, int start_c, vector<vector<bool>>& visited) {\n    if (board[start_r][start_c] == 0 || visited[start_r][start_c]) return 0;\n    \n    vector<pair<int, int>> stack;\n    stack.push_back({start_r, start_c});\n    visited[start_r][start_c] = true;\n    int size = 0;\n    \n    while (!stack.empty()) {\n        auto [r, c] = stack.back();\n        stack.pop_back();\n        size++;\n        \n        for (int d = 0; d < 4; d++) {\n            int nr = r + dx[d];\n            int nc = c + dy[d];\n            \n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n            if (board[nr][nc] == 0 || visited[nr][nc]) continue;\n            if (!can_connect(board[r][c], board[nr][nc], d)) continue;\n            \n            visited[nr][nc] = true;\n            stack.push_back({nr, nc});\n        }\n    }\n    \n    return size;\n}\n\nint find_largest_tree_quick() {\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    int max_size = 0;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0 || visited[i][j]) continue;\n            max_size = max(max_size, quick_tree_size(i, j, visited));\n        }\n    }\n    \n    return max_size;\n}\n\n// Maximum speed pattern recognition\nint max_speed_pattern(int r, int c, int tile) {\n    int score = 0;\n    int connections = 0;\n    \n    // Maximum speed connection count\n    for (int d = 0; d < 4; d++) {\n        int nr = r + dx[d];\n        int nc = c + dy[d];\n        \n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n        if (board[nr][nc] == 0) continue;\n        \n        if (can_connect(tile, board[nr][nc], d)) {\n            connections++;\n        }\n    }\n    \n    // Maximum speed pattern bonuses\n    if (connections >= 4) score += 160;\n    else if (connections >= 3) score += 85;\n    else if (connections >= 2) score += 40;\n    else if (connections == 1) score += 12;\n    \n    return score + connections * 15;\n}\n\n// Maximum speed bridge detection\nint max_speed_bridge(int r, int c, int tile) {\n    int bridge_score = 0;\n    int component_mask = 0;\n    \n    // Maximum speed component detection\n    for (int d = 0; d < 4; d++) {\n        int nr = r + dx[d];\n        int nc = c + dy[d];\n        \n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n        if (board[nr][nc] == 0) continue;\n        \n        if (has_line(tile, d) && has_line(board[nr][nc], (d + 2) % 4)) {\n            component_mask |= (1 << d);\n        }\n    }\n    \n    // Count unique directions as components\n    int unique_components = __builtin_popcount(component_mask);\n    \n    if (unique_components >= 3) bridge_score += 120;\n    else if (unique_components == 2) bridge_score += 60;\n    else if (unique_components == 1) bridge_score += 15;\n    \n    return bridge_score;\n}\n\n// Maximum speed position evaluation\nint max_speed_position(int r, int c) {\n    // Maximum speed center calculation\n    int center_r = (N-1) >> 1;\n    int center_c = (N-1) >> 1;\n    int dist = abs(r - center_r) + abs(c - center_c);\n    \n    return (N - dist) * 5;\n}\n\n// Maximum speed move evaluation\nint evaluate_max_speed(int direction) {\n    int nr = empty_row + dx[direction];\n    int nc = empty_col + dy[direction];\n    \n    if (!is_valid_move(nr, nc)) return -1000000;\n    \n    int tile = board[nr][nc];\n    \n    // Make temporary move\n    swap(board[empty_row][empty_col], board[nr][nc]);\n    int new_tree = find_largest_tree_quick();\n    \n    // Maximum speed multi-factor evaluation\n    int pattern = max_speed_pattern(nr, nc, tile);\n    int bridge = max_speed_bridge(nr, nc, tile);\n    int position = max_speed_position(nr, nc);\n    \n    // Undo temporary move\n    swap(board[empty_row][empty_col], board[nr][nc]);\n    \n    return new_tree * 1000 + bridge + pattern + position;\n}\n\n// Maximum speed strategic search\nvoid max_speed_strategic_search() {\n    auto start_time = chrono::high_resolution_clock::now();\n    \n    int best_tree = find_largest_tree_quick();\n    int exploration_rate = 6; // Ultra-low for maximum speed\n    int stuck_counter = 0;\n    \n    while (solution.size() < (size_t)T) {\n        auto current_time = chrono::high_resolution_clock::now();\n        auto elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count();\n        if (elapsed > 2895) break;\n        \n        // Adaptive exploration based on performance\n        if (stuck_counter > 20) {\n            exploration_rate = min(35, exploration_rate + 6);\n        } else if (stuck_counter < 2) {\n            exploration_rate = max(2, exploration_rate - 3);\n        }\n        \n        // Maximum speed move selection\n        int best_score = -1000000;\n        vector<int> candidate_moves;\n        \n        for (int d = 0; d < 4; d++) {\n            int score = evaluate_max_speed(d);\n            \n            // Ultra-minimal exploration noise\n            if ((int)(rng() % 100) < exploration_rate) {\n                score += (rng() % 20) - 10;\n            }\n            \n            if (score > best_score) {\n                best_score = score;\n                candidate_moves.clear();\n                candidate_moves.push_back(d);\n            } else if (score == best_score) {\n                candidate_moves.push_back(d);\n            }\n        }\n        \n        if (!candidate_moves.empty()) {\n            int direction = candidate_moves[(int)(rng() % candidate_moves.size())];\n            make_move(direction);\n            \n            int new_tree = find_largest_tree_quick();\n            if (new_tree > best_tree) {\n                best_tree = new_tree;\n                stuck_counter = 0;\n                exploration_rate = max(2, exploration_rate - 4);\n            } else {\n                stuck_counter++;\n            }\n            \n            if (best_tree == N * N - 1) break;\n        }\n        \n        // Maximum speed restart\n        if (stuck_counter > 30) {\n            // Ultra-quick escape sequence\n            for (int i = 0; i < 10 && solution.size() < (size_t)T; i++) {\n                int d = (int)(rng() % 4);\n                int nr = empty_row + dx[d];\n                int nc = empty_col + dy[d];\n                if (is_valid_move(nr, nc)) {\n                    make_move(d);\n                }\n            }\n            stuck_counter = 0;\n            exploration_rate = min(30, exploration_rate + 8);\n        }\n    }\n}\n\n// Maximum speed targeted optimization\nvoid max_speed_targeted_optimization() {\n    auto start_time = chrono::high_resolution_clock::now();\n    \n    // Phase 1: Maximum speed strategic search\n    max_speed_strategic_search();\n    \n    // Phase 2: Target exceptional opportunities\n    int current_tree = find_largest_tree_quick();\n    \n    for (int burst = 0; burst < 6 && solution.size() < (size_t)(T * 0.94); burst++) {\n        bool found_opportunity = false;\n        \n        // Scan for exceptional moves\n        for (int d = 0; d < 4; d++) {\n            int score = evaluate_max_speed(d);\n            if (score > 1180) { // Exceptional move threshold\n                make_move(d);\n                \n                int new_tree = find_largest_tree_quick();\n                if (new_tree > current_tree) {\n                    current_tree = new_tree;\n                    found_opportunity = true;\n                    break;\n                }\n            }\n        }\n        \n        if (!found_opportunity) break;\n    }\n    \n    // Phase 3: Final sprint\n    while (solution.size() < (size_t)T) {\n        auto current_time = chrono::high_resolution_clock::now();\n        auto elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count();\n        if (elapsed > 2960) break;\n        \n        bool improved = false;\n        for (int d = 0; d < 4; d++) {\n            int nr = empty_row + dx[d];\n            int nc = empty_col + dy[d];\n            \n            if (!is_valid_move(nr, nc)) continue;\n            \n            make_move(d);\n            int new_tree = find_largest_tree_quick();\n            \n            if (new_tree >= current_tree) {\n                current_tree = new_tree;\n                improved = true;\n                break;\n            } else {\n                // Undo move\n                int opposite = (d + 2) % 4;\n                make_move(opposite);\n                solution.pop_back();\n                solution.pop_back();\n            }\n        }\n        \n        if (!improved) break;\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> T;\n    board.assign(N, vector<int>(N));\n    \n    for (int i = 0; i < N; i++) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < N; j++) {\n            char c = row[j];\n            if (c == '0') {\n                board[i][j] = 0;\n                empty_row = i;\n                empty_col = j;\n            } else if (c >= '1' && c <= '9') {\n                board[i][j] = c - '0';\n            } else {\n                board[i][j] = c - 'a' + 10;\n            }\n        }\n    }\n    \n    max_speed_targeted_optimization();\n    \n    if (solution.size() > (size_t)T) {\n        solution = solution.substr(0, T);\n    }\n    \n    cout << solution << endl;\n    \n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\nusing int64 = long long;\nusing f64 = long double;\n\n/* ---------- portable hash for bitset<100> ---------- */\ninline uint64_t hash_bits(const bitset<100> &b) {\n    uint64_t lo = 0, hi = 0;\n    for (int i = 0; i < 64; ++i) if (b[i]) lo |= 1ULL << i;\n    for (int i = 64; i < 100; ++i) if (b[i]) hi |= 1ULL << (i - 64);\n    return lo ^ (hi * 0x9e3779b97f4a7c15ULL);\n}\n\n/* ---------- geometry primitives ---------- */\nconst f64 EPS = 1e-9L;\ninline int sign(f64 x) { return (x > EPS) - (x < -EPS); }\n\nstruct Line {\n    f64 A = 0, B = 0, C = 0;\n    Line() = default;\n    Line(f64 a, f64 b, f64 c) : A(a), B(b), C(c) { norm(); }\n    Line(f64 x1, f64 y1, f64 x2, f64 y2) {\n        A = y2 - y1; B = x1 - x2; C = x2*y1 - x1*y2;\n        norm();\n    }\n    void norm() { f64 s = sqrtl(A*A + B*B); if (s > EPS) { A /= s; B /= s; C /= s; } }\n    int side(f64 x, f64 y) const { return sign(A*x + B*y + C); }\n};\n\n/* ---------- input ---------- */\nint N, K;\nvector<int> a(11);\nvector<f64> X, Y;\n\n/* ---------- current state ---------- */\nint kUsed = 0;\nvector<Line> lines;\nusing Bits = bitset<100>;\nvector<Bits> regionCode;\nvector<int> regionCount;\nvector<int> regionIdx;\nunordered_map<uint64_t, int> regMap;\nint have[11] = {};\nint objective = 0;\n\n/* ---------- eval ---------- */\nint eval() {\n    int obj = 0;\n    for (int d = 1; d <= 10; ++d) obj += min(a[d], have[d]);\n    return obj;\n}\n\n/* ---------- add one line (incremental) ---------- */\nvoid addLine(const Line &L) {\n    if (kUsed == K) return;\n    int id = kUsed++;\n    lines[id] = L;\n\n    vector<Bits> sigs;\n    vector<int> cnts;\n    for (int r = 0; r < (int)regionCode.size(); ++r) {\n        int cnt = regionCount[r];\n        if (cnt == 0) continue;\n        Bits oldSig = regionCode[r];\n        Bits sigP = oldSig, sigM = oldSig;\n        sigP.set(id); sigM.reset(id);\n        sigs.push_back(sigP);\n        cnts.push_back(0);\n        sigs.push_back(sigM);\n        cnts.push_back(0);\n    }\n\n    for (int i = 0; i < N; ++i) {\n        int r = regionIdx[i];\n        if (regionCount[r] == 0) continue;\n        int s = L.side(X[i], Y[i]);\n        if (s > 0) cnts[2*r  ]++;\n        else if (s < 0) cnts[2*r+1]++;\n    }\n\n    unordered_map<uint64_t, int> newMap;\n    vector<Bits> newCode;\n    vector<int> newCount;\n    for (size_t i = 0; i < sigs.size(); ++i) {\n        if (cnts[i] == 0) continue;\n        uint64_t h = hash_bits(sigs[i]);\n        auto it = newMap.find(h);\n        if (it == newMap.end()) {\n            newMap[h] = newCount.size();\n            newCode.push_back(sigs[i]);\n            newCount.push_back(cnts[i]);\n        } else {\n            newCount[it->second] += cnts[i];\n        }\n    }\n    regMap.swap(newMap);\n    regionCode.swap(newCode);\n    regionCount.swap(newCount);\n\n    for (int i = 0; i < N; ++i) {\n        Bits sig;\n        for (int j = 0; j <= id; ++j) {\n            int s = lines[j].side(X[i], Y[i]);\n            if (s > 0) sig.set(j);\n        }\n        regionIdx[i] = regMap[hash_bits(sig)];\n    }\n\n    fill(have, have+11, 0);\n    for (int c : regionCount) if (c <= 10) have[c]++;\n    objective = eval();\n}\n\n/* ---------- light greedy \u2013 300 candidates, early exit ---------- */\nLine bestGreedyLine() {\n    static mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> distN(0, N-1);\n    uniform_real_distribution<f64> distA(0, 2*M_PI);\n\n    const int SAMPLE = 300;\n    static vector<Line> pool;\n    pool.clear();\n    for (int t = 0; t < SAMPLE; ++t) {\n        int i = distN(rng);\n        f64 ang = distA(rng);\n        f64 dx = cosl(ang), dy = sinl(ang);\n        pool.emplace_back(X[i], Y[i], X[i] + dx, Y[i] + dy);\n    }\n\n    /* berry counts \u2013 vectorisable loop */\n    vector<int> cp(SAMPLE, 0), cm(SAMPLE, 0);\n    for (int c = 0; c < SAMPLE; ++c) {\n        int &p = cp[c], &m = cm[c];\n#pragma GCC ivdep\n        for (int i = 0; i < N; ++i) {\n            int s = pool[c].side(X[i], Y[i]);\n            if (s > 0) p++; else if (s < 0) m++;\n        }\n    }\n\n    /* marginal gain \u2013 O(SAMPLE \u00d7 11) */\n    int bestGain = 0, bestC = -1;\n    for (int c = 0; c < SAMPLE; ++c) {\n        int tmpHave[11];\n        for (int d = 1; d <= 10; ++d) tmpHave[d] = have[d];\n        /* remove original region counts */\n        for (int r = 0; r < (int)regionCode.size(); ++r) {\n            int cnt = regionCount[r];\n            if (cnt == 0 || cnt > 10) continue;\n            tmpHave[cnt]--;\n        }\n        /* add new children */\n        if (cp[c] <= 10) tmpHave[cp[c]]++;\n        if (cm[c] <= 10) tmpHave[cm[c]]++;\n        int tmpObj = 0;\n        for (int d = 1; d <= 10; ++d) tmpObj += min(a[d], tmpHave[d]);\n        int gain = tmpObj - objective;\n        if (gain > bestGain) { bestGain = gain; bestC = c; }\n    }\n    return bestC == -1 ? Line(0, 0, 1, 0) : pool[bestC];\n}\n\n/* ---------- main ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    auto clk_start = chrono::steady_clock::now();\n\n    cin >> N >> K;\n    for (int d = 1; d <= 10; ++d) cin >> a[d];\n    X.resize(N); Y.resize(N);\n    for (int i = 0; i < N; ++i) cin >> X[i] >> Y[i];\n\n    lines.assign(K, Line());\n    regionCode.clear(); regionCount.clear(); regMap.clear();\n    Bits init; init.reset();\n    regionCode.push_back(init);\n    regionCount.push_back(N);\n    regMap[hash_bits(init)] = 0;\n    regionIdx.assign(N, 0);\n    fill(have, have+11, 0);\n    have[min(N,10)] = 1;\n    objective = eval();\n\n    int bestEver = objective;\n    vector<Line> bestLines;\n    int bestK = 0;\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        if (chrono::duration<double>(now - clk_start).count() > 2.85) break;\n\n        while (kUsed < K) {\n            Line L = bestGreedyLine();\n            if (objective >= bestEver) {\n                bestEver = objective;\n                bestLines = vector<Line>(lines.begin(), lines.begin() + kUsed);\n                bestK = kUsed;\n            }\n            addLine(L);\n        }\n\n        if (kUsed >= 5) {\n            kUsed -= 5;\n            regionCode.clear(); regionCount.clear(); regMap.clear();\n            Bits init; init.reset();\n            regionCode.push_back(init);\n            regionCount.push_back(0);\n            regMap[hash_bits(init)] = 0;\n            for (int i = 0; i < N; ++i) {\n                Bits sig; sig.reset();\n                for (int j = 0; j < kUsed; ++j) {\n                    int s = lines[j].side(X[i], Y[i]);\n                    if (s > 0) sig.set(j);\n                }\n                uint64_t h = hash_bits(sig);\n                auto it = regMap.find(h);\n                int r;\n                if (it == regMap.end()) {\n                    r = regionCode.size();\n                    regMap[h] = r;\n                    regionCode.push_back(sig);\n                    regionCount.push_back(0);\n                } else {\n                    r = it->second;\n                }\n                regionCount[r]++;\n                regionIdx[i] = r;\n            }\n            fill(have, have+11, 0);\n            for (int c : regionCount) if (c <= 10) have[c]++;\n            objective = eval();\n        }\n    }\n\n    cout << bestK << '\\n';\n    cout << fixed << setprecision(0);\n    for (int i = 0; i < bestK; ++i) {\n        f64 A = bestLines[i].A, B = bestLines[i].B, C = bestLines[i].C;\n        int64_t x1, y1, x2, y2;\n        if (fabs(B) > EPS) {\n            x1 = 0; y1 = llround(-C / B);\n            x2 = 1; y2 = llround((-C - A) / B);\n        } else {\n            y1 = 0; x1 = llround(-C / A);\n            y2 = 1; x2 = llround((-C) / A);\n        }\n        cout << x1 << ' ' << y1 << ' ' << x2 << ' ' << y2 << '\\n';\n    }\n    return 0;\n}","ahc014":"#pragma GCC target(\"avx2\")\n#pragma GCC optimize(\"O3\")\n#pragma GCC optimize(\"unroll-loops\")\n#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing ll = long long;\n#define rep(i, n) for (int i = 0; i < (int)(n); i++)\n\n// ---------- \u8fba\u306e\u7b26\u53f7\u5316 ----------\ninline uint64_t ecode(int x1, int y1, int x2, int y2) {\n    if (x1 > x2 || (x1 == x2 && y1 > y2)) {\n        swap(x1, x2); swap(y1, y2);\n    }\n    return ((uint64_t)(uint16_t)x1 << 48) | ((uint64_t)(uint16_t)y1 << 32) |\n           ((uint64_t)(uint16_t)x2 << 16) | (uint64_t)(uint16_t)y2;\n}\n\n// ---------- \u30b0\u30ed\u30fc\u30d0\u30eb ----------\nint N, M;\nint c;\nvector<vector<int>> w;               // \u91cd\u307f\nvector<vector<bool>> dot;            // dot[x][y]\nstd::unordered_set<uint64_t> used_edge;   // \u4fee\u6b63\uff1astd \u3092\u4f7f\u3046\nvector<tuple<int,int,int,int,int,int,int,int>> ops;  // \u64cd\u4f5c\u5c65\u6b74\n\n// ---------- \u65b9\u5411 ----------\nconst int dx45[4] = {1, 1, -1, -1};\nconst int dy45[4] = {1, -1, -1, 1};\nconst int dxax[4] = {1, 0, -1, 0};\nconst int dyax[4] = {0, 1, 0, -1};\n\n// ---------- \u77e9\u5f62\u3092\u8a66\u3059 ----------\nbool try_rect(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    // 4\u9802\u70b9\u306e\u9806\u5e8f\u3092\u6b63\u3057\u304f\u56de\u3057\u3001p1=(x1,y1) \u304c\u7a7a\u3001\u4ed6\u304c dot \u3067\u3042\u308b\u3053\u3068\n    if (!dot[x2][y2] || !dot[x3][y3] || !dot[x4][y4]) return false;\n    if (dot[x1][y1]) return false;\n    // 4\u8fba\u306e\u7b26\u53f7\u5316\n    uint64_t e1 = ecode(x1,y1,x2,y2);\n    uint64_t e2 = ecode(x2,y2,x3,y3);\n    uint64_t e3 = ecode(x3,y3,x4,y4);\n    uint64_t e4 = ecode(x4,y4,x1,y1);\n    if (used_edge.count(e1) || used_edge.count(e2) ||\n        used_edge.count(e3) || used_edge.count(e4)) return false;\n    // \u8fba\u4e0a\u306b\u4ed6\u30c9\u30c3\u30c8\u304c\u306a\u3044\u304b\uff08\u7c21\u6613\uff1agcd \u3067\u7b49\u5206\u70b9\u30c1\u30a7\u30c3\u30af\uff09\n    auto check_edge = [&](int ax, int ay, int bx, int by) {\n        int dx = bx - ax, dy = by - ay;\n        int g = gcd(abs(dx), abs(dy));\n        int stepx = dx / g, stepy = dy / g;\n        for (int t = 1; t < g; t++) {\n            int xx = ax + t * stepx, yy = ay + t * stepy;\n            if (dot[xx][yy]) return false;\n        }\n        return true;\n    };\n    if (!check_edge(x1,y1,x2,y2)) return false;\n    if (!check_edge(x2,y2,x3,y3)) return false;\n    if (!check_edge(x3,y3,x4,y4)) return false;\n    if (!check_edge(x4,y4,x1,y1)) return false;\n    // \u5b9f\u884c\n    dot[x1][y1] = true;\n    used_edge.insert(e1);\n    used_edge.insert(e2);\n    used_edge.insert(e3);\n    used_edge.insert(e4);\n    ops.emplace_back(x1,y1,x2,y2,x3,y3,x4,y4);\n    return true;\n}\n\n// ---------- \u30e1\u30a4\u30f3 ----------\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    auto clk_st = chrono::steady_clock::now();\n\n    cin >> N >> M;\n    c = (N - 1) / 2;\n    w.assign(N, vector<int>(N));\n    dot.assign(N, vector<bool>(N, false));\n    ll S = 0;\n    rep(x,N) rep(y,N) {\n        int wx = (x - c) * (x - c) + (y - c) * (y - c) + 1;\n        w[x][y] = wx;\n        S += wx;\n    }\n    rep(i,M){\n        int x,y; cin >> x >> y;\n        dot[x][y] = true;\n    }\n\n    // \u9ad8\u91cd\u307f\u9806\u306b\u7a7a\u30de\u30b9\u3092\u62fe\u3046\u305f\u3081\u306e\u30ea\u30b9\u30c8\n    vector<pair<int,int>> cells;\n    rep(x,N) rep(y,N) if (!dot[x][y]) cells.emplace_back(x,y);\n    // \u91cd\u307f\u5927\u304d\u3044\u9806\u306b\u30bd\u30fc\u30c8\n    sort(cells.begin(), cells.end(), [&](auto &a, auto &b){\n        return w[a.first][a.second] > w[b.first][b.second];\n    });\n\n    // \u8caa\u6b32\u30e1\u30a4\u30f3\n    const double TIME_LIMIT = 4.8;\n    int iter = 0, total = cells.size();\n    while (1) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - clk_st).count();\n        if (elapsed > TIME_LIMIT) break;\n\n        // \u30e9\u30f3\u30c0\u30e0\u306b\u30d0\u30c3\u30c1\u3092\u62fe\u3046\uff08\u91cd\u3044\u9806\u306b\u3057\u3064\u3064\u30e9\u30f3\u30c0\u30e0\u30cd\u30b9\uff09\n        int batch = min(500, total);\n        vector<int> idx(batch);\n        rep(i,batch) idx[i] = (iter + i) % total;\n        shuffle(idx.begin(), idx.end(), mt19937(iter));\n\n        bool progress = false;\n        for (int i : idx) {\n            auto [x1,y1] = cells[i];\n            if (dot[x1][y1]) continue;\n            // \u8ef8\u5e73\u884c\u9577\u65b9\u5f62\u30924\u65b9\u5411\n            for (int d = 0; d < 4; d++) {\n                int len = 1;\n                while (1) {\n                    int x2 = x1 + len * dxax[d], y2 = y1 + len * dyax[d];\n                    int x3 = x2 + len * dxax[(d+1)&3], y3 = y2 + len * dyax[(d+1)&3];\n                    int x4 = x1 + len * dxax[(d+1)&3], y4 = y1 + len * dyax[(d+1)&3];\n                    if (x2<0||x2>=N||y2<0||y2>=N) break;\n                    if (x3<0||x3>=N||y3<0||y3>=N) break;\n                    if (x4<0||x4>=N||y4<0||y4>=N) break;\n                    if (try_rect(x1,y1,x2,y2,x3,y3,x4,y4)) { progress=true; goto NEXT; }\n                    len++;\n                }\n            }\n            // 45\u00b0\u9577\u65b9\u5f62\u30924\u65b9\u5411\n            for (int d = 0; d < 4; d++) {\n                int len = 1;\n                while (1) {\n                    int x2 = x1 + len * dx45[d], y2 = y1 + len * dy45[d];\n                    int x3 = x2 + len * dx45[(d+1)&3], y3 = y2 + len * dy45[(d+1)&3];\n                    int x4 = x1 + len * dx45[(d+1)&3], y4 = y1 + len * dy45[(d+1)&3];\n                    if (x2<0||x2>=N||y2<0||y2>=N) break;\n                    if (x3<0||x3>=N||y3<0||y3>=N) break;\n                    if (x4<0||x4>=N||y4<0||y4>=N) break;\n                    if (try_rect(x1,y1,x2,y2,x3,y3,x4,y4)) { progress=true; goto NEXT; }\n                    len++;\n                }\n            }\n        }\n        NEXT:\n        iter += batch;\n        if (!progress) break;\n    }\n\n    // \u51fa\u529b\n    cout << ops.size() << \"\\n\";\n    for (auto &[x1,y1,x2,y2,x3,y3,x4,y4] : ops) {\n        cout << x1 << \" \" << y1 << \" \"\n             << x2 << \" \" << y2 << \" \"\n             << x3 << \" \" << y3 << \" \"\n             << x4 << \" \" << y4 << \"\\n\";\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\nusing namespace std::chrono;\n\nconstexpr int H = 10, W = 10, N = 100, C = 3;\nint flavour[N];\nchar dc[4] = {'F','B','L','R'};\n\nmt19937_64 rng(123456789);\n\n/* ---------- bit-packed column-wise board ---------- */\nstruct Grid {\n    uint64_t col[W];\n    Grid(){ memset(col,0,sizeof(col)); }\n    int get(int r,int c) const { return (col[c]>>(r*2))&3ULL; }\n    void set(int r,int c,int v){\n        col[c] &= ~(3ULL<<(r*2));\n        col[c] |= uint64_t(v)<<(r*2);\n    }\n    bool empty(int r,int c) const { return get(r,c)==0; }\n};\n\ninline void gravity(Grid& g,int d){\n    if(d==0){\n        for(int c=0;c<W;c++){\n            uint64_t m = g.col[c];\n            uint64_t occ = 0;\n            for(int r=0;r<H;r++) occ |= (m>>(r*2)&3) ? (1ULL<<r) : 0;\n            int ones = __builtin_popcountll(occ);\n            uint64_t newm = 0;\n            int wr = H-ones;\n            for(int r=0;r<H;r++){\n                int v = (m>>(r*2))&3;\n                if(v){ newm |= uint64_t(v)<<((wr++)*2); }\n            }\n            g.col[c] = newm;\n        }\n    }else if(d==1){\n        for(int c=0;c<W;c++){\n            uint64_t m = g.col[c];\n            uint64_t occ = 0;\n            for(int r=0;r<H;r++) occ |= (m>>(r*2)&3) ? (1ULL<<r) : 0;\n            int ones = __builtin_popcountll(occ);\n            uint64_t newm = 0;\n            int wr = 0;\n            for(int r=0;r<H;r++){\n                int v = (m>>(r*2))&3;\n                if(v){ newm |= uint64_t(v)<<((wr++)*2); }\n            }\n            g.col[c] = newm;\n        }\n    }else if(d==2){\n        Grid ng;\n        for(int r=0;r<H;r++){\n            int w=0;\n            for(int c=0;c<W;c++){\n                int v = g.get(r,c);\n                if(v){ ng.set(r,w,v); w++; }\n            }\n        }\n        g = ng;\n    }else{\n        Grid ng;\n        for(int r=0;r<H;r++){\n            int w=W-1;\n            for(int c=W-1;c>=0;c--){\n                int v = g.get(r,c);\n                if(v){ ng.set(r,w,v); w--; }\n            }\n        }\n        g = ng;\n    }\n}\n\nint evalScore(const Grid& g){\n    static int id[H][W], sz[N], p[N];\n    iota(p,p+N,0);\n    function<int(int)> root=[&](int x){ return p[x]==x?x:p[x]=root(p[x]); };\n    auto unite=[&](int x,int y){ x=root(x); y=root(y); if(x!=y){ if(sz[x]<sz[y]) swap(x,y); p[y]=x; sz[x]+=sz[y]; }};\n\n    memset(id,-1,sizeof(id));\n    int comp = 0;\n    for(int r=0;r<H;r++)for(int c=0;c<W;c++){\n        int v = g.get(r,c);\n        if(v){ id[r][c]=comp; sz[comp]=1; comp++; }\n    }\n    const int dr[4]={-1,1,0,0}, dc[4]={0,0,-1,1};\n    for(int r=0;r<H;r++)for(int c=0;c<W;c++){\n        int v = g.get(r,c);\n        if(!v) continue;\n        for(int d=0;d<4;d++){\n            int nr=r+dr[d], nc=c+dc[d];\n            if(nr<0||nr>=H||nc<0||nc>=W) continue;\n            if(g.get(nr,nc)==v) unite(id[r][c], id[nr][nc]);\n        }\n    }\n    int sum = 0;\n    for(int i=0;i<comp;i++) if(root(i)==i) sum += sz[i]*sz[i];\n    return sum;\n}\n\n/* ---------- dynamic target column per colour ---------- */\nint targetCol[C];  // current target column for each colour\n\nvoid updateTargets(const Grid& g){\n    /* recompute tallest wall per colour */\n    int bestH[C] = {0,0,0};\n    int bestC[C] = {0,4,8};  // default\n    for(int col=0;col<C;col++){\n        int c0 = targetCol[col];\n        int h0 = 0;\n        for(int r=H-1;r>=0;r--){\n            if(g.get(r,c0)==col+1) h0++;\n            else break;\n        }\n        bestH[col] = h0;\n        bestC[col] = c0;\n    }\n    for(int col=0;col<C;col++){\n        for(int c=0;c<W;c++){\n            int h = 0;\n            for(int r=H-1;r>=0;r--){\n                if(g.get(r,c)==col+1) h++;\n                else break;\n            }\n            if(h > bestH[col]){ bestH[col]=h; bestC[col]=c; }\n        }\n    }\n    for(int col=0;col<C;col++) targetCol[col] = bestC[col];\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    for(int i=0;i<N;i++){ cin>>flavour[i]; flavour[i]--; }\n\n    /* off-line: assign initial targets greedily */\n    int cnt[C] = {0,0,0};\n    for(int i=0;i<N;i++) cnt[flavour[i]]++;\n    vector<pair<int,int>> ord;\n    for(int c=0;c<C;c++) ord.emplace_back(-cnt[c],c);\n    sort(ord.begin(),ord.end());\n    int cols[] = {4,5,3,6,2,7,1,8,0,9};  // centre-first\n    for(int i=0;i<C;i++) targetCol[ord[i].second] = cols[i];\n\n    Grid base;\n    for(int t=0;t<N;t++){\n        int p; cin>>p; p--;\n        int cnt=0, rr=-1,cc=-1;\n        for(int i=0;i<H*W;i++){\n            int r=i/W, c=i%W;\n            if(base.empty(r,c)){\n                if(cnt==p){ rr=r; cc=c; break; }\n                cnt++;\n            }\n        }\n        base.set(rr,cc,flavour[t]+1);\n\n        /* update targets after real placement */\n        updateTargets(base);\n\n        int bestDir = 0, bestSum = -1;\n        auto deadline = steady_clock::now() + milliseconds(15);\n        int scores[4]={0,0,0,0}, tries[4]={0,0,0,0};\n\n        while(steady_clock::now() < deadline){\n            for(int cand=0;cand<4;cand++){\n                if(tries[cand]<0) continue;\n                Grid g = base;\n                gravity(g, cand);\n                int myCol = flavour[t];\n                int myTarget = targetCol[myCol];\n                /* simulate future with 70 % biased to current target column */\n                for(int u=t+1;u<N;u++){\n                    int ucol = flavour[u];\n                    int utarg = targetCol[ucol];\n                    int pp;\n                    if(bernoulli_distribution(0.7)(rng)){\n                        vector<int> pref;\n                        for(int r=0;r<H;r++) if(g.empty(r,utarg)) pref.push_back(r*W+utarg);\n                        if(!pref.empty()){\n                            uniform_int_distribution<int> U(0,(int)pref.size()-1);\n                            pp = pref[U(rng)];\n                        }else{\n                            vector<int> all;\n                            for(int i=0;i<H*W;i++) if(g.empty(i/W,i%W)) all.push_back(i);\n                            if(all.empty()) break;\n                            uniform_int_distribution<int> U(0,(int)all.size()-1);\n                            pp = all[U(rng)];\n                        }\n                    }else{\n                        vector<int> all;\n                        for(int i=0;i<H*W;i++) if(g.empty(i/W,i%W)) all.push_back(i);\n                        if(all.empty()) break;\n                        uniform_int_distribution<int> U(0,(int)all.size()-1);\n                        pp = all[U(rng)];\n                    }\n                    int r=pp/W, c=pp%W;\n                    g.set(r,c,ucol+1);\n                    gravity(g, uniform_int_distribution<int>(0,3)(rng));\n                    /* recompute targets every 5 steps to keep adaptivity */\n                    if((u-t)%5==0) updateTargets(g);\n                }\n                int sc = evalScore(g);\n                scores[cand] += sc;\n                tries[cand]++;\n                /* early kill */\n                if(tries[cand]>=50){\n                    double avg = double(scores[cand])/tries[cand];\n                    bool hopeless = false;\n                    for(int o=0;o<4;o++) if(o!=cand && tries[o]>=50){\n                        double avgo = double(scores[o])/tries[o];\n                        if(avgo - avg > 300){ hopeless=true; break; }\n                    }\n                    if(hopeless) tries[cand] = -1;\n                }\n            }\n        }\n        for(int cand=0;cand<4;cand++){\n            if(tries[cand]<=0) continue;\n            double avg = double(scores[cand])/tries[cand];\n            if(int(avg) > bestSum){ bestSum=int(avg); bestDir=cand; }\n        }\n        gravity(base, bestDir);\n        cout << dc[bestDir] << '\\n';\n        cout.flush();\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\n// ---------------  \u57fa\u672c\u8a2d\u5b9a  ----------------\nint M; \ndouble eps;\nconst int MAX_N = 100;\nint N;                       // \u5b9f\u969b\u306b\u9078\u3076\u9802\u70b9\u6570\nint MAX_EDGES;               // N*(N-1)/2\n\n// \u5404 G_k \u306e\u8fba\u96c6\u5408\uff08bitmask \u3067\u3082 vector<bitset<>> \u3067\u3082\u53ef\uff09\n// \u3053\u3053\u3067\u306f\u96a3\u63a5\u884c\u5217\u3092 vector<bitset<MAX_N>> \u3067\u6301\u3064\nvector<bitset<MAX_N>> G[MAX_N*MAX_N]; // G[k][i][j] = 1 \u306a\u3089\u8fba (i,j) \u5b58\u5728\n\n// \u5404 G_k \u306e\u300c\u8fba\u6570\u300d\u304a\u3088\u3073\u300c\u6b21\u6570\u5217\uff08\u30bd\u30fc\u30c8\u6e08\u307f\uff09\u300d\nvector<int> target_edges;   // target_edges[k]\nvector<vector<int>> deg_seq; // deg_seq[k] : \u9577\u3055 N\u3001\u30bd\u30fc\u30c8\u6e08\u307f\n\n// --------------  \u4e8b\u524d\u8a08\u7b97\uff08Binomial \u5bfe\u6570\uff09 --------------\nconst int MAX_BINOM = MAX_N*MAX_N;\ndouble logfact[MAX_BINOM+1];\nvoid init_logfact(){\n    logfact[0] = 0.0;\n    for(int i=1;i<=MAX_BINOM;i++){\n        logfact[i] = logfact[i-1] + log(i);\n    }\n}\ninline double logbinom(int n, int k){\n    if(k<0||k>n) return -1e300;\n    return logfact[n] - logfact[k] - logfact[n-k];\n}\n\n// --------------  \u30b0\u30e9\u30d5\u51fa\u529b\u7528\u30a8\u30f3\u30b3\u30fc\u30c0 -----------------\nstring encode_graph(const vector<bitset<MAX_N>>& adj){\n    string s;\n    for(int i=0;i<N;i++){\n        for(int j=i+1;j<N;j++){\n            s += (adj[i][j] ? '1':'0');\n        }\n    }\n    return s;\n}\n\n// --------------  \u30e9\u30f3\u30c0\u30e0\u8fba\u751f\u6210 ------------------------\nvoid build_random_graph(vector<bitset<MAX_N>>& adj, int m){\n    adj.assign(N, bitset<MAX_N>());\n    int total = N*(N-1)/2;\n    vector<int> idx(total);\n    iota(idx.begin(), idx.end(), 0);\n    shuffle(idx.begin(), idx.end(), mt19937(12345));\n    for(int t=0;t<m;t++){\n        int e = idx[t];\n        int i = 0, j = 1;\n        // e \u756a\u76ee\u306e (i,j) (i<j) \u3092\u5fa9\u5143\n        int cnt = 0;\n        for(i=0;i<N;i++){\n            for(j=i+1;j<N;j++){\n                if(cnt==e) goto found;\n                cnt++;\n            }\n        }\n        found:\n        adj[i][j] = adj[j][i] = 1;\n    }\n}\n\n// --------------  \u6b21\u6570\u5217\u53d6\u5f97 --------------------------\nvector<int> get_degree_sequence(const vector<bitset<MAX_N>>& adj){\n    vector<int> deg(N);\n    for(int i=0;i<N;i++){\n        deg[i] = adj[i].count();\n    }\n    sort(deg.rbegin(), deg.rend());\n    return deg;\n}\n\n// --------------  \u5bfe\u6570\u5c24\u5ea6\u8fd1\u4f3c ------------------------\n// \u8fba\u6570 m \u306e\u307f\u3092\u898b\u308b\u7c21\u6613\u7248\ndouble loglikelihood_edge(int m, int k){\n    int total = N*(N-1)/2;\n    double p = (double)target_edges[k] / total;\n    // \u53cd\u8ee2\u5f8c\u306e\u671f\u5f85\u8fba\u6570\n    double mu = target_edges[k]*(1 - 2*eps) + eps*total;\n    double sigma2 = eps*(1 - eps)*total;\n    // \u6b63\u898f\u8fd1\u4f3c\n    double diff = m - mu;\n    return -0.5 * diff*diff / sigma2;\n}\n\n// --------------  \u30e1\u30a4\u30f3 --------------------------------\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // \u5165\u529b\n    cin >> M >> eps;\n\n    // N \u3092\u6c7a\u5b9a\uff08\u5c0f\u3055\u3044\u307b\u3046\u304c\u30b9\u30b3\u30a2\u500d\u7387\u304c\u9ad8\u3044\u304c\u3001\u8b58\u5225\u80fd\u529b\u304c\u843d\u3061\u308b\uff09\n    // \u3068\u308a\u3042\u3048\u305a N=20 \u3067\u56fa\u5b9a\n    N = 20;\n    MAX_EDGES = N*(N-1)/2;\n\n    // \u5bfe\u6570factorial \u521d\u671f\u5316\n    init_logfact();\n\n    // \u5404 G_k \u306e\u300c\u76ee\u6a19\u8fba\u6570\u300d\u3092\u7b49\u9593\u9694\u306b\n    target_edges.resize(M);\n    double step = (double)MAX_EDGES / (M-1);\n    for(int k=0;k<M;k++){\n        target_edges[k] = (int)round( k * step );\n    }\n\n    // \u5404 G_k \u3092\u751f\u6210 & \u6b21\u6570\u5217\u8a08\u7b97\n    for(int k=0;k<M;k++){\n        build_random_graph(G[k], target_edges[k]);\n        deg_seq.emplace_back( get_degree_sequence(G[k]) );\n    }\n\n    // \u51fa\u529b\n    cout << N << \"\\n\";\n    for(int k=0;k<M;k++){\n        cout << encode_graph(G[k]) << \"\\n\";\n    }\n    cout.flush();\n\n    // \u30af\u30a8\u30ea\u51e6\u7406\n    for(int q=0;q<100;q++){\n        string Hstr;\n        cin >> Hstr;\n        // H \u3092\u96a3\u63a5\u884c\u5217\u306b\n        vector<bitset<MAX_N>> H(N);\n        int ptr = 0;\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                if(Hstr[ptr++]=='1'){\n                    H[i][j] = H[j][i] = 1;\n                }\n            }\n        }\n        // \u8fba\u6570\n        int m = 0;\n        for(int i=0;i<N;i++) m += H[i].count();\n        m /= 2;\n\n        // \u5404 k \u306b\u3064\u3044\u3066\u5bfe\u6570\u5c24\u5ea6\uff08\u8fba\u6570\u306e\u307f\uff09\u3092\u8a08\u7b97\n        int best_k = 0;\n        double best_ll = -1e300;\n        for(int k=0;k<M;k++){\n            double ll = loglikelihood_edge(m, k);\n            if(ll > best_ll){\n                best_ll = ll;\n                best_k = k;\n            }\n        }\n        cout << best_k << \"\\n\";\n        cout.flush();\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 1005;\nconst int MAX_M = 3005;\nconst int INF = 1e9;\n\nint N, M, D, K;\nint u[MAX_M], v[MAX_M], w[MAX_M];\nint x[MAX_N], y[MAX_N];\nint assignment[MAX_M];\nvector<pair<int, int>> adj[MAX_N];\n\n// Proven effective importance calculation from the 153B version\nvector<double> calculate_effective_importance() {\n    vector<double> importance(M, 0.0);\n    \n    for (int e = 0; e < M; e++) {\n        // Factor 1: Local bridge property (proven effective)\n        int common_neighbors = 0;\n        vector<bool> u_neighbors(N, false);\n        for (auto [neighbor, weight] : adj[u[e]]) {\n            u_neighbors[neighbor] = true;\n        }\n        for (auto [neighbor, weight] : adj[v[e]]) {\n            if (u_neighbors[neighbor]) common_neighbors++;\n        }\n        double bridge_score = 12.0 / (common_neighbors + 1);\n        \n        // Factor 2: Weight-spatial ratio (as in successful version)\n        double spatial_dist = sqrt((x[u[e]] - x[v[e]]) * (x[u[e]] - x[v[e]]) + \n                                  (y[u[e]] - y[v[e]]) * (y[u[e]] - y[v[e]]));\n        double weight_score = spatial_dist / (w[e] + 1);\n        \n        // Factor 3: Node degree importance\n        double degree_score = (adj[u[e]].size() + adj[v[e]].size()) / 8.0;\n        \n        // Factor 4: Local density (moderate impact)\n        int local_edges = 0;\n        int region_size = 120;\n        int mid_x = (x[u[e]] + x[v[e]]) / 2;\n        int mid_y = (y[u[e]] + y[v[e]]) / 2;\n        \n        for (int ee = 0; ee < M; ee++) {\n            if (ee != e) {\n                int other_mid_x = (x[u[ee]] + x[v[ee]]) / 2;\n                int other_mid_y = (y[u[ee]] + y[v[ee]]) / 2;\n                int dist = abs(mid_x - other_mid_x) + abs(mid_y - other_mid_y);\n                if (dist < region_size) local_edges++;\n            }\n        }\n        double density_score = 4.0 / (local_edges + 2);\n        \n        importance[e] = bridge_score + weight_score + degree_score + density_score;\n    }\n    \n    return importance;\n}\n\n// Optimized spreading strategy based on the successful 153B approach\nvoid solve_optimized_spreading() {\n    vector<double> importance = calculate_effective_importance();\n    \n    // Create sorted list\n    vector<pair<double, int>> edges_by_importance(M);\n    for (int i = 0; i < M; i++) {\n        edges_by_importance[i] = {importance[i], i};\n    }\n    sort(edges_by_importance.rbegin(), edges_by_importance.rend());\n    \n    vector<int> day_count(D + 1, 0);\n    int max_per_day = K;\n    \n    // Two-phase assignment with optimized spreading\n    int critical_phase_size = min(M * 3 / 4, M);  // 75% of edges get spreading treatment\n    \n    for (int i = 0; i < critical_phase_size; i++) {\n        int e = edges_by_importance[i].second;\n        \n        int best_day = -1;\n        double best_score = -1;\n        \n        for (int day = 1; day <= D; day++) {\n            if (day_count[day] >= max_per_day) continue;\n            \n            double score = 0;\n            \n            // Load balancing (always important)\n            double load_score = 1.0 / (day_count[day] + 1);\n            score += load_score;\n            \n            // Spatial spreading for all critical edges (key insight from 153B version)\n            int region_x = (x[u[e]] + x[v[e]]) / 2 / 140;\n            int region_y = (y[u[e]] + y[v[e]]) / 2 / 140;\n            \n            int region_conflicts = 0;\n            for (int j = 0; j < i; j++) {\n                int other_e = edges_by_importance[j].second;\n                if (assignment[other_e] == day) {\n                    int other_reg_x = (x[u[other_e]] + x[v[other_e]]) / 2 / 140;\n                    int other_reg_y = (y[u[other_e]] + y[v[other_e]]) / 2 / 140;\n                    if (other_reg_x == region_x && other_reg_y == region_y) {\n                        region_conflicts++;\n                    }\n                }\n            }\n            double spread_score = 1.0 / (region_conflicts + 1);\n            score *= spread_score;  // Multiplicative combination (proven effective)\n            \n            if (score > best_score) {\n                best_score = score;\n                best_day = day;\n            }\n        }\n        \n        if (best_day != -1) {\n            assignment[e] = best_day;\n            day_count[best_day]++;\n        }\n    }\n    \n    // Phase 2: Remaining edges get pure load balancing\n    for (int i = critical_phase_size; i < M; i++) {\n        int e = edges_by_importance[i].second;\n        \n        int best_day = 1;\n        for (int day = 2; day <= D; day++) {\n            if (day_count[day] < day_count[best_day] && day_count[day] < max_per_day) {\n                best_day = day;\n            }\n        }\n        \n        assignment[e] = best_day;\n        day_count[best_day]++;\n    }\n}\n\n// Enhanced local optimization with strategic swaps\nvoid enhanced_local_optimization() {\n    vector<int> day_count(D + 1, 0);\n    for (int i = 0; i < M; i++) {\n        day_count[assignment[i]]++;\n    }\n    \n    // Multi-round optimization with different strategies\n    for (int round = 0; round < 3; round++) {\n        int best_improvement = 0;\n        int best_e1 = -1, best_e2 = -1;\n        \n        // Strategic sampling - focus on different day pairs each round\n        vector<pair<int, int>> target_day_pairs;\n        \n        if (round == 0) {\n            // Round 1: Most vs least loaded days\n            int max_day = max_element(day_count.begin() + 1, day_count.end()) - day_count.begin();\n            int min_day = min_element(day_count.begin() + 1, day_count.end()) - day_count.begin();\n            target_day_pairs.push_back({max_day, min_day});\n        } else if (round == 1) {\n            // Round 2: High variance pairs\n            for (int day1 = 1; day1 <= D; day1++) {\n                for (int day2 = day1 + 1; day2 <= D; day2++) {\n                    if (abs(day_count[day1] - day_count[day2]) > 2) {\n                        target_day_pairs.push_back({day1, day2});\n                    }\n                }\n            }\n        } else {\n            // Round 3: Random strategic pairs\n            for (int i = 0; i < 5; i++) {\n                int day1 = rand() % D + 1;\n                int day2 = rand() % D + 1;\n                if (day1 != day2) target_day_pairs.push_back({day1, day2});\n            }\n        }\n        \n        // Search for best swaps in target day pairs\n        for (auto [day1, day2] : target_day_pairs) {\n            for (int sample = 0; sample < 50; sample++) {\n                int e1 = -1, e2 = -1;\n                \n                // Find edges from target days\n                while (e1 == -1 || assignment[e1] != day1) e1 = rand() % M;\n                while (e2 == -1 || assignment[e2] != day2) e2 = rand() % M;\n                \n                int current_diff = abs(day_count[day1] - day_count[day2]);\n                int new_diff = abs((day_count[day1] - 1) - (day_count[day2] + 1));\n                \n                int improvement = current_diff - new_diff;\n                \n                if (improvement > best_improvement) {\n                    best_improvement = improvement;\n                    best_e1 = e1;\n                    best_e2 = e2;\n                }\n            }\n        }\n        \n        if (best_e1 != -1) {\n            // Perform best swap\n            int day1 = assignment[best_e1];\n            int day2 = assignment[best_e2];\n            \n            assignment[best_e1] = day2;\n            assignment[best_e2] = day1;\n            day_count[day1]--;\n            day_count[day2]++;\n            day_count[day1]++;\n            day_count[day2]--;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    srand(42); // Fixed seed for reproducibility\n    \n    cin >> N >> M >> D >> K;\n    \n    for (int i = 0; i < M; i++) {\n        cin >> u[i] >> v[i] >> w[i];\n        u[i]--; v[i]--;\n        adj[u[i]].push_back({v[i], w[i]});\n        adj[v[i]].push_back({u[i], w[i]});\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n    \n    // Optimized spreading assignment (based on successful 153B approach)\n    solve_optimized_spreading();\n    \n    // Enhanced local optimization\n    enhanced_local_optimization();\n    \n    // Output the assignment\n    for (int i = 0; i < M; i++) {\n        cout << assignment[i] << (i == M - 1 ? \"\\n\" : \" \");\n    }\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nusing ull = unsigned long long;\nusing int2 = __int128_t;\n\nstatic constexpr int MAXD = 14;\nstatic constexpr int MAXV = 16;               // max volume of generated blocks\nstatic constexpr int MAXB = 40000;            // max number of generated blocks\nstatic constexpr double TIME_LIMIT = 5.8;\n\nint D, DD, DDD;\nbitset<MAXD*MAXD*MAXD> mandatory[2], sharedMandatory;\nint mandatoryVol[2], sharedVol;\n\nstruct Block {\n    int vol;\n    vector<tuple<int,int,int>> cells;   // original coordinates\n    vector<vector<tuple<int,int,int>>> rot; // 24 rotations\n};\nint nBlocks = 0;\nBlock blocks[MAXB];\n\n// ---------- utilities ----------\ninline int idx(int x, int y, int z) { return x*D*D + y*D + z; }\ninline bool inside(int x, int y, int z) {\n    return 0 <= x && x < D && 0 <= y && y < D && 0 <= z && z < D;\n}\n\n// ---------- rotation ----------\nvector<vector<tuple<int,int,int>>> generateRotations(const vector<tuple<int,int,int>>& src) {\n    vector<vector<tuple<int,int,int>>> res;\n    set<vector<tuple<int,int,int>>> seen;\n    for (int rx = 0; rx < 4; ++rx)\n    for (int ry = 0; ry < 4; ++ry)\n    for (int rz = 0; rz < 4; ++rz) {\n        vector<tuple<int,int,int>> tmp;\n        for (auto [x,y,z] : src) {\n            int cx = x, cy = y, cz = z;\n            // rotate around X\n            for (int k = 0; k < rx; ++k) {\n                int ny = -cz, nz = cy;\n                cy = ny; cz = nz;\n            }\n            // rotate around Y\n            for (int k = 0; k < ry; ++k) {\n                int nx = cz, nz = -cx;\n                cx = nx; cz = nz;\n            }\n            // rotate around Z\n            for (int k = 0; k < rz; ++k) {\n                int nx = -cy, ny = cx;\n                cx = nx; cy = ny;\n            }\n            tmp.emplace_back(cx, cy, cz);\n        }\n        // normalize\n        int minx=INT_MAX, miny=INT_MAX, minz=INT_MAX;\n        for (auto [x,y,z] : tmp) {\n            minx = min(minx, x); miny = min(miny, y); minz = min(minz, z);\n        }\n        for (auto& [x,y,z] : tmp) {\n            x -= minx; y -= miny; z -= minz;\n        }\n        sort(tmp.begin(), tmp.end());\n        if (seen.insert(tmp).second) res.push_back(tmp);\n    }\n    return res;\n}\n\n// ---------- polycube generation ----------\nvoid generateBlocks() {\n    // BFS enumeration of all free polycubes up to volume MAXV\n    map<vector<tuple<int,int,int>>, int> canonicalId;\n    queue<pair<vector<tuple<int,int,int>>, int>> q;\n    q.push({{{0,0,0}}, 1});\n    canonicalId[{{{0,0,0}}}] = 1;\n    int dx[] = {1,-1,0,0,0,0}, dy[] = {0,0,1,-1,0,0}, dz[] = {0,0,0,0,1,-1};\n    while (!q.empty() && nBlocks < MAXB) {\n        auto [shape, vol] = q.front(); q.pop();\n        if (vol > MAXV) continue;\n        // store this shape\n        {\n            Block& B = blocks[nBlocks++];\n            B.vol = vol;\n            B.cells = shape;\n            B.rot = generateRotations(shape);\n        }\n        // expand\n        set<tuple<int,int,int>> frontier;\n        for (auto [x,y,z] : shape)\n        for (int d = 0; d < 6; ++d) {\n            int nx = x+dx[d], ny = y+dy[d], nz = z+dz[d];\n            if (!inside(nx,ny,nz)) continue;\n            if (find(shape.begin(), shape.end(), make_tuple(nx,ny,nz)) != shape.end()) continue;\n            frontier.emplace(nx,ny,nz);\n        }\n        for (auto [x,y,z] : frontier) {\n            auto ns = shape;\n            ns.emplace_back(x,y,z);\n            // normalize\n            int minx=INT_MAX,miny=INT_MAX,minz=INT_MAX;\n            for (auto [xx,yy,zz] : ns) {\n                minx=min(minx,xx); miny=min(miny,yy); minz=min(minz,zz);\n            }\n            for (auto& [xx,yy,zz] : ns) {\n                xx-=minx; yy-=miny; zz-=minz;\n            }\n            sort(ns.begin(), ns.end());\n            if (canonicalId.count(ns)) continue;\n            canonicalId[ns] = 1;\n            q.push({ns, vol+1});\n        }\n    }\n    cerr << \"generated \" << nBlocks << \" blocks up to volume \" << MAXV << \"\\n\";\n}\n\n// ---------- placement ----------\nstruct Placement {\n    bitset<MAXD*MAXD*MAXD> occ;\n    int usedVol;\n    vector<int> blockIds;\n    vector<vector<tuple<int,int,int>>> poses; // for each block, its rotated+translated cells\n};\nPlacement bestP[2];\ndouble bestScore = 1e18;\n\n// try to place block B with rotation r at (bx,by,bz) into grid g\nbool canPlace(const bitset<MAXD*MAXD*MAXD>& g, const Block& B, int r, int bx, int by, int bz) {\n    for (auto [x,y,z] : B.rot[r]) {\n        int xx = x+bx, yy = y+by, zz = z+bz;\n        if (!inside(xx,yy,zz)) return false;\n        if (g.test(idx(xx,yy,zz))) return false;\n    }\n    return true;\n}\nvoid place(bitset<MAXD*MAXD*MAXD>& g, const Block& B, int r, int bx, int by, int bz) {\n    for (auto [x,y,z] : B.rot[r]) {\n        int xx = x+bx, yy = y+by, zz = z+bz;\n        g.set(idx(xx,yy,zz));\n    }\n}\n\n// greedy cover for one silhouette\nPlacement greedyCover(const bitset<MAXD*MAXD*MAXD>& target, int which) {\n    Placement P;\n    P.occ.reset(); P.usedVol = 0;\n    vector<int> order(nBlocks);\n    iota(order.begin(), order.end(), 0);\n    // sort by 1/vol descending\n    sort(order.begin(), order.end(), [&](int a, int b){\n        return blocks[a].vol > blocks[b].vol;\n    });\n    bitset<MAXD*MAXD*MAXD> rem = target;\n    int remVol = target.count();\n    for (int id : order) {\n        if (remVol == 0) break;\n        const Block& B = blocks[id];\n        bool placed = false;\n        // try all rotations and positions\n        for (int r = 0; r < (int)B.rot.size() && !placed; ++r) {\n            int maxx=0,maxy=0,maxz=0;\n            for (auto [x,y,z] : B.rot[r]) {\n                maxx=max(maxx,x); maxy=max(maxy,y); maxz=max(maxz,z);\n            }\n            for (int bx = 0; bx + maxx < D && !placed; ++bx)\n            for (int by = 0; by + maxy < D && !placed; ++by)\n            for (int bz = 0; bz + maxz < D && !placed; ++bz) {\n                if (!canPlace(P.occ, B, r, bx,by,bz)) continue;\n                // check if it covers at least one remaining voxel\n                bool cov = false;\n                for (auto [x,y,z] : B.rot[r]) {\n                    int xx = x+bx, yy = y+by, zz = z+bz;\n                    if (rem.test(idx(xx,yy,zz))) { cov=true; break; }\n                }\n                if (!cov) continue;\n                // place it\n                place(P.occ, B, r, bx,by,bz);\n                P.blockIds.push_back(id);\n                vector<tuple<int,int,int>> pose;\n                for (auto [x,y,z] : B.rot[r]) pose.emplace_back(x+bx, y+by, z+bz);\n                P.poses.push_back(pose);\n                P.usedVol += B.vol;\n                // update rem\n                for (auto [x,y,z] : B.rot[r]) {\n                    int xx = x+bx, yy = y+by, zz = z+bz;\n                    rem.reset(idx(xx,yy,zz));\n                }\n                remVol = rem.count();\n                placed = true;\n            }\n        }\n    }\n    return P;\n}\n\n// ---------- scoring ----------\ndouble eval(const Placement& p1, const Placement& p2) {\n    // build set of used blocks\n    unordered_set<int> used1(p1.blockIds.begin(), p1.blockIds.end());\n    unordered_set<int> used2(p2.blockIds.begin(), p2.blockIds.end());\n    int r1 = 0, r2 = 0;\n    double sumInv = 0.0;\n    for (int i = 0; i < nBlocks; ++i) {\n        bool in1 = used1.count(i), in2 = used2.count(i);\n        if (!in1 && !in2) continue; // not allowed, but we prune earlier\n        if (!in1) r1 += blocks[i].vol;\n        if (!in2) r2 += blocks[i].vol;\n        if (in1 && in2) sumInv += 1.0 / blocks[i].vol;\n    }\n    double score = r1 + r2 + sumInv;\n    return score;\n}\n\n// ---------- output ----------\nvoid output(const Placement& p1, const Placement& p2) {\n    // build global block list\n    unordered_map<int,int> globalId;\n    int nOut = 0;\n    for (int id : p1.blockIds) if (!globalId.count(id)) globalId[id] = nOut++;\n    for (int id : p2.blockIds) if (!globalId.count(id)) globalId[id] = nOut++;\n    cout << nOut << \"\\n\";\n    // output b1\n    vector<int> flat1(D*D*D, 0);\n    for (int i = 0; i < (int)p1.blockIds.size(); ++i) {\n        int gid = globalId[p1.blockIds[i]];\n        for (auto [x,y,z] : p1.poses[i]) {\n            flat1[idx(x,y,z)] = gid+1;\n        }\n    }\n    for (int i = 0; i < DDD; ++i) {\n        if (i) cout << \" \";\n        cout << flat1[i];\n    }\n    cout << \"\\n\";\n    // output b2\n    vector<int> flat2(D*D*D, 0);\n    for (int i = 0; i < (int)p2.blockIds.size(); ++i) {\n        int gid = globalId[p2.blockIds[i]];\n        for (auto [x,y,z] : p2.poses[i]) {\n            flat2[idx(x,y,z)] = gid+1;\n        }\n    }\n    for (int i = 0; i < DDD; ++i) {\n        if (i) cout << \" \";\n        cout << flat2[i];\n    }\n    cout << \"\\n\";\n}\n\n// ---------- main ----------\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    auto clk = chrono::high_resolution_clock::now();\n\n    cin >> D;\n    DD = D*D; DDD = D*D*D;\n    // read silhouettes\n    vector<string> fstr[2], rstr[2];\n    for (int i = 0; i < 2; ++i) {\n        fstr[i].resize(D);\n        for (int z = 0; z < D; ++z) cin >> fstr[i][z];\n        rstr[i].resize(D);\n        for (int z = 0; z < D; ++z) cin >> rstr[i][z];\n    }\n    // build mandatory voxels\n    for (int i = 0; i < 2; ++i) {\n        mandatory[i].reset();\n        for (int x = 0; x < D; ++x)\n        for (int y = 0; y < D; ++y)\n        for (int z = 0; z < D; ++z) {\n            if (fstr[i][z][x]=='1' && rstr[i][z][y]=='1') {\n                mandatory[i].set(idx(x,y,z));\n            }\n        }\n        mandatoryVol[i] = mandatory[i].count();\n    }\n    sharedMandatory = mandatory[0] & mandatory[1];\n    sharedVol = sharedMandatory.count();\n\n    // generate block catalogue\n    generateBlocks();\n\n    // greedy cover for each silhouette\n    bestP[0] = greedyCover(mandatory[0], 0);\n    bestP[1] = greedyCover(mandatory[1], 1);\n    bestScore = eval(bestP[0], bestP[1]);\n\n    // simple iterative improvement: try to replace one block by a larger unused one\n    // (very fast, so we do many iterations)\n    int iter = 0;\n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - clk).count();\n        if (elapsed > TIME_LIMIT) break;\n        iter++;\n        // pick random placement\n        int w = rand()&1;\n        Placement& P = bestP[w];\n        if (P.blockIds.empty()) continue;\n        int k = rand() % P.blockIds.size();\n        int oldId = P.blockIds[k];\n        // try all bigger unused blocks\n        bool improved = false;\n        for (int cand = 0; cand < nBlocks && !improved; ++cand) {\n            if (blocks[cand].vol <= blocks[oldId].vol) continue;\n            // try to place cand instead of oldId\n            Placement tmp = P;\n            // remove oldId\n            tmp.occ.reset();\n            tmp.usedVol -= blocks[oldId].vol;\n            tmp.blockIds.erase(tmp.blockIds.begin()+k);\n            tmp.poses.erase(tmp.poses.begin()+k);\n            // rebuild occ\n            for (int i = 0; i < (int)tmp.blockIds.size(); ++i) {\n                const Block& B = blocks[tmp.blockIds[i]];\n                for (auto [x,y,z] : tmp.poses[i]) tmp.occ.set(idx(x,y,z));\n            }\n            // try to add cand somewhere\n            const Block& B = blocks[cand];\n            bool placed = false;\n            for (int r = 0; r < (int)B.rot.size() && !placed; ++r) {\n                int maxx=0,maxy=0,maxz=0;\n                for (auto [x,y,z] : B.rot[r]) {\n                    maxx=max(maxx,x); maxy=max(maxy,y); maxz=max(maxz,z);\n                }\n                for (int bx = 0; bx + maxx < D && !placed; ++bx)\n                for (int by = 0; by + maxy < D && !placed; ++by)\n                for (int bz = 0; bz + maxz < D && !placed; ++bz) {\n                    if (!canPlace(tmp.occ, B, r, bx,by,bz)) continue;\n                    // check it covers at least one missing voxel\n                    bitset<MAXD*MAXD*MAXD> need = mandatory[w];\n                    for (int i = 0; i < (int)tmp.blockIds.size(); ++i)\n                        for (auto [x,y,z] : tmp.poses[i]) need.reset(idx(x,y,z));\n                    bool cov = false;\n                    for (auto [x,y,z] : B.rot[r]) {\n                        int xx = x+bx, yy = y+by, zz = z+bz;\n                        if (need.test(idx(xx,yy,zz))) { cov=true; break; }\n                    }\n                    if (!cov) continue;\n                    // place it\n                    place(tmp.occ, B, r, bx,by,bz);\n                    tmp.blockIds.push_back(cand);\n                    vector<tuple<int,int,int>> pose;\n                    for (auto [x,y,z] : B.rot[r]) pose.emplace_back(x+bx, y+by, z+bz);\n                    tmp.poses.push_back(pose);\n                    tmp.usedVol += B.vol;\n                    placed = true;\n                }\n            }\n            if (!placed) continue;\n            // finish covering with greedy\n            bitset<MAXD*MAXD*MAXD> rem = mandatory[w];\n            for (int i = 0; i < (int)tmp.blockIds.size(); ++i)\n                for (auto [x,y,z] : tmp.poses[i]) rem.reset(idx(x,y,z));\n            if (rem.any()) {\n                Placement fill = greedyCover(rem, w);\n                for (int i = 0; i < (int)fill.blockIds.size(); ++i) {\n                    tmp.blockIds.push_back(fill.blockIds[i]);\n                    tmp.poses.push_back(fill.poses[i]);\n                    tmp.usedVol += blocks[fill.blockIds[i]].vol;\n                    for (auto [x,y,z] : fill.poses[i]) tmp.occ.set(idx(x,y,z));\n                }\n            }\n            // evaluate\n            double sc = eval(tmp, bestP[w^1]);\n            if (sc < bestScore) {\n                bestScore = sc;\n                bestP[w] = tmp;\n                improved = true;\n            }\n        }\n    }\n\n    cerr << \"iterations \" << iter << \" bestScore \" << bestScore << \"\\n\";\n    output(bestP[0], bestP[1]);\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing int64 = long long;\n\nstatic const int MAXN = 105;\nstatic const int MAXM = 305;\nstatic const int MAXK = 5005;\nstatic const int MAXP = 5000;\n\nint N, M, K;\ndouble x[MAXN], y[MAXN];\nint u_e[MAXM], v_e[MAXM], w_e[MAXM];\ndouble a[MAXK], b[MAXK];\n\n// DSU for Kruskal\nint parent[MAXN];\nint find_set(int v) {\n    if (v == parent[v]) return v;\n    return parent[v] = find_set(parent[v]);\n}\nbool union_set(int u, int v) {\n    u = find_set(u);\n    v = find_set(v);\n    if (u == v) return false;\n    parent[v] = u;\n    return true;\n}\n\n// graph\nvector<pair<int,int>> adj[MAXN]; // (neighbor, edge_index)\n\n// MST flags\nbool in_mst[MAXM];\nint64 total_edge_cost = 0;\n\n// resident -> distance to each vertex\ndouble dist_ik[MAXK][MAXN];\n\n// current solution\nint P[MAXN];\nbool edge_on[MAXM];\n\n// recompute vertex cost and detect uncovered residents\n// returns -1 if some resident has closest > MAXP\nint64 recompute_vertex_cost(const vector<char>& reachable,\n                            vector<int>& bestP)\n{\n    bestP.assign(N, 0);\n    for (int k = 0; k < K; k++) {\n        double best_d = 1e18;\n        int best_i = -1;\n        for (int i = 0; i < N; i++) {\n            if (reachable[i] && dist_ik[k][i] < best_d) {\n                best_d = dist_ik[k][i];\n                best_i = i;\n            }\n        }\n        if (best_d > MAXP) return -1;          // unreachable within limit\n        int need = (int)ceil(best_d);\n        need = min(need, MAXP);\n        bestP[best_i] = max(bestP[best_i], need);\n    }\n    int64 cost = 0;\n    for (int i = 0; i < N; i++) cost += (int64)bestP[i] * bestP[i];\n    return cost;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> K;\n    for(int i = 0; i < N; i++){\n        cin >> x[i] >> y[i];\n    }\n    for(int j = 0; j < M; j++){\n        cin >> u_e[j] >> v_e[j] >> w_e[j];\n        --u_e[j]; --v_e[j];\n    }\n    for(int k = 0; k < K; k++){\n        cin >> a[k] >> b[k];\n    }\n\n    // precompute resident->vertex distances\n    for(int k = 0; k < K; k++){\n        for(int i = 0; i < N; i++){\n            double dx = x[i] - a[k];\n            double dy = y[i] - b[k];\n            dist_ik[k][i] = sqrt(dx*dx + dy*dy);\n        }\n    }\n\n    // Kruskal MST\n    for(int i = 0; i < N; i++) parent[i] = i;\n    vector<int> edges_order(M);\n    iota(edges_order.begin(), edges_order.end(), 0);\n    sort(edges_order.begin(), edges_order.end(),\n         [&](int j1, int j2){ return w_e[j1] < w_e[j2]; });\n\n    fill(in_mst, in_mst + M, false);\n    for(int jj = 0; jj < M; jj++){\n        int j = edges_order[jj];\n        if (union_set(u_e[j], v_e[j])) {\n            in_mst[j] = true;\n            total_edge_cost += w_e[j];\n        }\n    }\n\n    // build adj for BFS\n    for(int j = 0; j < M; j++){\n        if (in_mst[j]){\n            adj[u_e[j]].emplace_back(v_e[j], j);\n            adj[v_e[j]].emplace_back(u_e[j], j);\n        }\n    }\n\n    // initial full reachable\n    vector<char> fullReach(N, true);\n    vector<int>  bestP(N);\n    int64 vertex_cost = recompute_vertex_cost(fullReach, bestP);\n    for(int i = 0; i < N; i++) P[i] = bestP[i];\n    for(int j = 0; j < M; j++) edge_on[j] = in_mst[j];\n\n    // greedy deletion pass: largest weight first\n    vector<int> tree_edges;\n    for(int j = 0; j < M; j++) if (in_mst[j]) tree_edges.push_back(j);\n    sort(tree_edges.begin(), tree_edges.end(),\n         [&](int j1, int j2){ return w_e[j1] > w_e[j2]; });\n\n    bool improved;\n    do {\n        improved = false;\n        for(int j_idx = 0; j_idx < (int)tree_edges.size(); j_idx++){\n            int j = tree_edges[j_idx];\n            if (!edge_on[j]) continue;\n\n            edge_on[j] = false;\n            // BFS reachable\n            vector<char> reach(N, false);\n            queue<int> q;\n            reach[0] = true; q.push(0);\n            while(!q.empty()){\n                int u = q.front(); q.pop();\n                for(auto& [v, eidx] : adj[u]){\n                    if (!edge_on[eidx]) continue;\n                    if (!reach[v]){\n                        reach[v] = true;\n                        q.push(v);\n                    }\n                }\n            }\n            vector<int> newP(N);\n            int64 new_vertex_cost = recompute_vertex_cost(reach, newP);\n            if (new_vertex_cost == -1){\n                // some resident uncovered -> reject\n                edge_on[j] = true;\n                continue;\n            }\n            int64 saved = w_e[j];\n            int64 extra = new_vertex_cost - vertex_cost;\n            if (extra < saved){\n                vertex_cost = new_vertex_cost;\n                for(int i = 0; i < N; i++) P[i] = newP[i];\n                improved = true;\n            } else {\n                edge_on[j] = true;\n            }\n        }\n    } while(improved);\n\n    // output\n    for(int i = 0; i < N; i++){\n        cout << P[i] << (i+1<N?' ':'\\n');\n    }\n    for(int j = 0; j < M; j++){\n        cout << (edge_on[j]?1:0) << (j+1<M?' ':'\\n');\n    }\n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\nconst int N = 30;\nconst int MAX_SWAPS = 10000;\n\nint pyramid[N][N];\nvector<pair<pair<int,int>, pair<int,int>>> swaps;\n\ninline void performSwap(int x1, int y1, int x2, int y2) {\n    swap(pyramid[x1][y1], pyramid[x2][y2]);\n    swaps.push_back({{x1, y1}, {x2, y2}});\n}\n\ninline bool isViolating(int x, int y) {\n    if (x == N-1) return false;\n    return pyramid[x][y] > pyramid[x+1][y] || pyramid[x][y] > pyramid[x+1][y+1];\n}\n\n// Perfected bubble-up\nvoid bubbleUp(int x, int y) {\n    int cx = x, cy = y;\n    while (cx > 0 && swaps.size() < MAX_SWAPS) {\n        if (cy > 0 && pyramid[cx-1][cy-1] > pyramid[cx][cy]) {\n            performSwap(cx, cy, cx-1, cy-1);\n            cx--; cy--;\n        } else if (cy < cx && pyramid[cx-1][cy] > pyramid[cx][cy]) {\n            performSwap(cx, cy, cx-1, cy);\n            cx--;\n        } else {\n            break;\n        }\n    }\n}\n\n// Perfected fix strategy\nvoid fixViolation(int x, int y) {\n    int val = pyramid[x][y];\n    \n    if (val > pyramid[x+1][y] && val > pyramid[x+1][y+1]) {\n        // Both violate - swap with smaller child for optimal cascade\n        if (pyramid[x+1][y] < pyramid[x+1][y+1]) {\n            performSwap(x, y, x+1, y);\n        } else {\n            performSwap(x, y, x+1, y+1);\n        }\n    }\n    else if (val > pyramid[x+1][y]) {\n        performSwap(x, y, x+1, y);\n    }\n    else if (val > pyramid[x+1][y+1]) {\n        performSwap(x, y, x+1, y+1);\n    }\n}\n\n// Optimally perfected solver\nvoid solve() {\n    // Read input\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j <= i; j++) {\n            cin >> pyramid[i][j];\n        }\n    }\n    \n    // Maximum optimization passes\n    for (int pass = 0; pass < 100 && swaps.size() < MAX_SWAPS; pass++) {\n        bool improved = false;\n        \n        // Optimized processing order - middle-out approach\n        for (int x = N-2; x >= 0 && swaps.size() < MAX_SWAPS; x--) {\n            // Process from middle outward for optimal cascade effects\n            int mid = x / 2;\n            for (int offset = 0; offset <= x && swaps.size() < MAX_SWAPS; offset++) {\n                int y1 = mid + offset;\n                int y2 = mid - offset;\n                \n                if (y1 <= x && offset > 0) {\n                    if (isViolating(x, y1)) {\n                        fixViolation(x, y1);\n                        if (isViolating(x, y1)) bubbleUp(x, y1);\n                        improved = true;\n                    }\n                }\n                \n                if (y2 >= 0 && offset > 0 && y2 != y1) {\n                    if (isViolating(x, y2)) {\n                        fixViolation(x, y2);\n                        if (isViolating(x, y2)) bubbleUp(x, y2);\n                        improved = true;\n                    }\n                }\n                \n                if (offset == 0 && y1 == mid) {\n                    if (isViolating(x, y1)) {\n                        fixViolation(x, y1);\n                        if (isViolating(x, y1)) bubbleUp(x, y1);\n                        improved = true;\n                    }\n                }\n            }\n        }\n        \n        if (!improved && pass > 3) break;\n    }\n    \n    // Final perfecting pass\n    for (int x = 0; x < N-1 && swaps.size() < MAX_SWAPS; x++) {\n        for (int y = 0; y <= x && swaps.size() < MAX_SWAPS; y++) {\n            if (isViolating(x, y)) {\n                int val = pyramid[x][y];\n                \n                // Final cleanup\n                if (val > pyramid[x+1][y]) {\n                    performSwap(x, y, x+1, y);\n                } else if (val > pyramid[x+1][y+1]) {\n                    performSwap(x, y, x+1, y+1);\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cout.tie(nullptr);\n    \n    solve();\n    \n    cout << swaps.size() << '\\n';\n    for (const auto& swap : swaps) {\n        cout << swap.first.first << ' ' << swap.first.second << ' ' \n             << swap.second.first << ' ' << swap.second.second << '\\n';\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int D = 9;\nconst int di[] = {-1, 0, 1, 0};\nconst int dj[] = {0, 1, 0, -1};\n\nint N;\nbool obstacle[D][D];\nbool occupied[D][D];\nint container[D][D]; // container[i][j] = t_d if occupied, else -1\nint dist[D][D];\n\nvoid bfs_dist() {\n    queue<pair<int, int>> q;\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            dist[i][j] = -1;\n        }\n    }\n    int si = 0, sj = (D-1)/2;\n    dist[si][sj] = 0;\n    q.emplace(si, sj);\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) continue;\n            if (obstacle[ni][nj] || occupied[ni][nj]) continue;\n            if (dist[ni][nj] == -1) {\n                dist[ni][nj] = dist[i][j] + 1;\n                q.emplace(ni, nj);\n            }\n        }\n    }\n}\n\nbool is_reachable(int i, int j) {\n    if (obstacle[i][j] || occupied[i][j]) return false;\n    bfs_dist();\n    return dist[i][j] != -1;\n}\n\nvector<pair<int, int>> get_reachable() {\n    bfs_dist();\n    vector<pair<int, int>> res;\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            if (!obstacle[i][j] && !occupied[i][j] && dist[i][j] != -1) {\n                res.emplace_back(i, j);\n            }\n        }\n    }\n    return res;\n}\n\npair<int, int> choose_placement(int t) {\n    auto reachable = get_reachable();\n    if (reachable.empty()) {\n        cerr << \"No reachable cells!\" << endl;\n        exit(1);\n    }\n    // Choose the cell with maximum distance from entrance\n    pair<int, int> best = reachable[0];\n    int best_dist = dist[best.first][best.second];\n    for (auto [i, j] : reachable) {\n        if (dist[i][j] > best_dist) {\n            best_dist = dist[i][j];\n            best = {i, j};\n        }\n    }\n    return best;\n}\n\nvector<pair<int, int>> retrieval_order;\n\nvoid compute_retrieval() {\n    // Reset occupied to true where containers are placed\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            occupied[i][j] = (container[i][j] != -1);\n        }\n    }\n    priority_queue<pair<int, pair<int, int>>, vector<pair<int, pair<int, int>>>, greater<pair<int, pair<int, int>>>> pq;\n    // Initial reachable containers\n    bfs_dist();\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            if (container[i][j] != -1 && dist[i][j] != -1) {\n                pq.emplace(container[i][j], make_pair(i, j));\n            }\n        }\n    }\n    while (!pq.empty()) {\n        auto [t, pos] = pq.top(); pq.pop();\n        auto [i, j] = pos;\n        if (container[i][j] == -1) continue; // already removed\n        retrieval_order.emplace_back(i, j);\n        occupied[i][j] = false;\n        container[i][j] = -1;\n        // Update reachability\n        bfs_dist();\n        // Add newly reachable containers\n        for (int ni = 0; ni < D; ++ni) {\n            for (int nj = 0; nj < D; ++nj) {\n                if (container[ni][nj] != -1 && dist[ni][nj] != -1) {\n                    pq.emplace(container[ni][nj], make_pair(ni, nj));\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cout << fixed << setprecision(20);\n\n    cin >> D >> N;\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            obstacle[i][j] = false;\n            occupied[i][j] = false;\n            container[i][j] = -1;\n        }\n    }\n    for (int k = 0; k < N; ++k) {\n        int ri, rj;\n        cin >> ri >> rj;\n        obstacle[ri][rj] = true;\n    }\n\n    int total_containers = D*D - 1 - N;\n    for (int d = 0; d < total_containers; ++d) {\n        int t;\n        cin >> t;\n        auto [i, j] = choose_placement(t);\n        occupied[i][j] = true;\n        container[i][j] = t;\n        cout << i << \" \" << j << endl;\n    }\n\n    compute_retrieval();\n    for (auto [i, j] : retrieval_order) {\n        cout << i << \" \" << j << \"\\n\";\n    }\n    cout.flush();\n\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 50;\nconst int MAX_M = 100;\n\nint n, m;\nint input[MAX_N][MAX_N];\nbool adj[MAX_M + 1][MAX_M + 1];\nbool forbidden_adj[MAX_M + 1][MAX_M + 1];\nint output[MAX_N][MAX_N];\n\n// Directions for adjacency checking\nint dx[] = {-1, 1, 0, 0};\nint dy[] = {0, 0, -1, 1};\n\nvoid extract_adjacencies() {\n    memset(adj, false, sizeof(adj));\n    memset(forbidden_adj, true, sizeof(forbidden_adj));\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int c1 = input[i][j];\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d];\n                int nj = j + dy[d];\n                int c2 = (ni < 0 || ni >= n || nj < 0 || nj >= n) ? 0 : input[ni][nj];\n                \n                if (c1 != c2) {\n                    int u = min(c1, c2);\n                    int v = max(c1, c2);\n                    adj[u][v] = true;\n                    forbidden_adj[u][v] = false;\n                }\n            }\n        }\n    }\n}\n\nbool check_adjacencies() {\n    static bool output_adj[MAX_M + 1][MAX_M + 1];\n    memset(output_adj, false, sizeof(output_adj));\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int c1 = output[i][j];\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d];\n                int nj = j + dy[d];\n                int c2 = (ni < 0 || ni >= n || nj < 0 || nj >= n) ? 0 : output[ni][nj];\n                \n                if (c1 != c2) {\n                    int u = min(c1, c2);\n                    int v = max(c1, c2);\n                    output_adj[u][v] = true;\n                }\n            }\n        }\n    }\n    \n    for (int i = 0; i <= m; i++) {\n        for (int j = i + 1; j <= m; j++) {\n            if (adj[i][j] && !output_adj[i][j]) return false;\n            if (forbidden_adj[i][j] && output_adj[i][j]) return false;\n        }\n    }\n    \n    return true;\n}\n\nbool is_connected(int color) {\n    vector<pair<int, int>> cells;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (output[i][j] == color) {\n                cells.push_back({i, j});\n            }\n        }\n    }\n    \n    if (cells.empty()) return true;\n    \n    vector<vector<bool>> visited(n, vector<bool>(n, false));\n    queue<pair<int, int>> q;\n    q.push(cells[0]);\n    visited[cells[0].first][cells[0].second] = true;\n    int count = 1;\n    \n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        \n        for (int d = 0; d < 4; d++) {\n            int ni = i + dx[d];\n            int nj = j + dy[d];\n            \n            if (ni >= 0 && ni < n && nj >= 0 && nj < n && \n                output[ni][nj] == color && !visited[ni][nj]) {\n                visited[ni][nj] = true;\n                q.push({ni, nj});\n                count++;\n            }\n        }\n    }\n    \n    return count == cells.size();\n}\n\nbool is_zero_connected() {\n    vector<vector<bool>> visited(n, vector<bool>(n, false));\n    queue<pair<int, int>> q;\n    \n    for (int i = 0; i < n; i++) {\n        if (output[i][0] == 0) { q.push({i, 0}); visited[i][0] = true; }\n        if (output[i][n-1] == 0) { q.push({i, n-1}); visited[i][n-1] = true; }\n        if (output[0][i] == 0) { q.push({0, i}); visited[0][i] = true; }\n        if (output[n-1][i] == 0) { q.push({n-1, i}); visited[n-1][i] = true; }\n    }\n    \n    int count = q.size();\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        \n        for (int d = 0; d < 4; d++) {\n            int ni = i + dx[d];\n            int nj = j + dy[d];\n            \n            if (ni >= 0 && ni < n && nj >= 0 && nj < n && \n                output[ni][nj] == 0 && !visited[ni][nj]) {\n                visited[ni][nj] = true;\n                q.push({ni, nj});\n                count++;\n            }\n        }\n    }\n    \n    int total_zeros = 0;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (output[i][j] == 0) total_zeros++;\n        }\n    }\n    \n    return count == total_zeros;\n}\n\nbool is_valid_placement() {\n    if (!check_adjacencies()) return false;\n    if (!is_zero_connected()) return false;\n    \n    for (int color = 1; color <= m; color++) {\n        if (!is_connected(color)) return false;\n    }\n    \n    return true;\n}\n\nint count_zeros() {\n    int count = 0;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (output[i][j] == 0) count++;\n        }\n    }\n    return count;\n}\n\nvoid copy_output(int dest[MAX_N][MAX_N], const int src[MAX_N][MAX_N]) {\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            dest[i][j] = src[i][j];\n        }\n    }\n}\n\nvoid create_connected_initial_solution() {\n    // Start with input map\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            output[i][j] = input[i][j];\n        }\n    }\n    \n    // Remove tiles strategically - focus on interior first\n    vector<pair<int, int>> removal_candidates;\n    \n    // Prioritize tiles with more zero/same-color neighbors\n    for (int i = 1; i < n-1; i++) {\n        for (int j = 1; j < n-1; j++) {\n            if (output[i][j] == 0) continue;\n            \n            int color = output[i][j];\n            int same_neighbors = 0;\n            int zero_neighbors = 0;\n            \n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d];\n                int nj = j + dy[d];\n                if (ni < 0 || ni >= n || nj < 0 || nj >= n) continue;\n                \n                if (output[ni][nj] == color) same_neighbors++;\n                else if (output[ni][nj] == 0) zero_neighbors++;\n            }\n            \n            // Prioritize tiles with many same-color or zero neighbors\n            if (same_neighbors + zero_neighbors >= 3) {\n                removal_candidates.push_back({i, j});\n            }\n        }\n    }\n    \n    // Try to remove candidates\n    for (auto [i, j] : removal_candidates) {\n        int original = output[i][j];\n        output[i][j] = 0;\n        \n        if (is_valid_placement()) {\n            // Successfully removed\n        } else {\n            output[i][j] = original;\n        }\n    }\n}\n\nvoid bridge_detection_optimization() {\n    // Multiple passes to remove non-essential tiles\n    for (int pass = 0; pass < 4; pass++) {\n        for (int color = 1; color <= m; color++) {\n            vector<pair<int, int>> color_tiles;\n            for (int i = 0; i < n; i++) {\n                for (int j = 0; j < n; j++) {\n                    if (output[i][j] == color) {\n                        color_tiles.push_back({i, j});\n                    }\n                }\n            }\n            \n            if (color_tiles.size() <= 2) continue;\n            \n            // Shuffle for better results\n            random_shuffle(color_tiles.begin(), color_tiles.end());\n            \n            for (auto [i, j] : color_tiles) {\n                int original = output[i][j];\n                output[i][j] = 0;\n                \n                if (is_connected(color) && is_valid_placement()) {\n                    // Successfully removed\n                } else {\n                    output[i][j] = original;\n                }\n            }\n        }\n    }\n}\n\nvoid boundary_expansion_optimization() {\n    // Focus on expanding empty regions from boundaries\n    bool improved = true;\n    \n    while (improved) {\n        improved = false;\n        \n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (output[i][j] == 0) continue;\n                \n                // Check if this tile is adjacent to many zeros\n                int zero_neighbors = 0;\n                int total_neighbors = 0;\n                \n                for (int d = 0; d < 4; d++) {\n                    int ni = i + dx[d];\n                    int nj = j + dy[d];\n                    if (ni < 0 || ni >= n || nj < 0 || nj >= n) {\n                        zero_neighbors++; // boundary counts as zero\n                        total_neighbors++;\n                    } else {\n                        total_neighbors++;\n                        if (output[ni][nj] == 0) zero_neighbors++;\n                    }\n                }\n                \n                if (zero_neighbors >= total_neighbors - 1) {\n                    int original = output[i][j];\n                    output[i][j] = 0;\n                    \n                    if (is_valid_placement()) {\n                        improved = true;\n                    } else {\n                        output[i][j] = original;\n                    }\n                }\n            }\n        }\n    }\n}\n\nvoid final_aggressive_optimization() {\n    int best_zeros = count_zeros();\n    \n    // Try more iterations with better candidate selection\n    vector<pair<int, int>> high_priority_candidates;\n    \n    for (int iter = 0; iter < 2000; iter++) {\n        int i = rand() % n;\n        int j = rand() % n;\n        \n        if (output[i][j] == 0) continue;\n        \n        // Score this tile for removability\n        int score = 0;\n        int color = output[i][j];\n        \n        for (int d = 0; d < 4; d++) {\n            int ni = i + dx[d];\n            int nj = j + dy[d];\n            if (ni < 0 || ni >= n || nj < 0 || nj >= n) {\n                score += 2; // boundary bonus\n                continue;\n            }\n            \n            if (output[ni][nj] == 0) score += 3;\n            else if (output[ni][nj] == color) score += 1;\n        }\n        \n        if (score >= 6) {\n            int original = output[i][j];\n            output[i][j] = 0;\n            \n            if (is_valid_placement()) {\n                int zeros = count_zeros();\n                if (zeros > best_zeros) {\n                    best_zeros = zeros;\n                }\n            } else {\n                output[i][j] = original;\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    srand(time(nullptr));\n    \n    cin >> n >> m;\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> input[i][j];\n        }\n    }\n    \n    extract_adjacencies();\n    \n    // Create initial connected solution\n    create_connected_initial_solution();\n    \n    if (!is_valid_placement()) {\n        // Fallback to input with basic removal\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                output[i][j] = input[i][j];\n            }\n        }\n    }\n    \n    // Apply proven optimization strategies\n    bridge_detection_optimization();\n    boundary_expansion_optimization();\n    final_aggressive_optimization();\n    \n    // Output the result\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << output[i][j];\n            if (j < n - 1) cout << \" \";\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int N, D, Q;\n    cin >> N >> D >> Q;\n    \n    static int assignment[100];\n    static int weight_est[100];\n    static int item_order[100];\n    \n    // Initialize\n    for (int i = 0; i < N; i++) {\n        assignment[i] = 0;\n        weight_est[i] = 1;\n        item_order[i] = i;\n    }\n    \n    int queries_used = 0;\n    \n    // Phase 1: Simple but effective comparisons\n    for (int round = 0; round < 2 && queries_used < Q/2; round++) {\n        for (int i = 0; i < N && queries_used < Q/2; i++) {\n            int j = (i + round * 2 + 1) % N;\n            \n            cout << \"1 1 \" << i << \" \" << j << endl;\n            \n            string res;\n            cin >> res;\n            queries_used++;\n            \n            if (res == \">\") {\n                weight_est[i] += 3;\n            } else if (res == \"<\") {\n                weight_est[j] += 3;\n            } else {\n                weight_est[i] += 1;\n                weight_est[j] += 1;\n            }\n        }\n    }\n    \n    // Phase 2: Sort by estimated weight\n    for (int i = 0; i < N-1; i++) {\n        for (int j = 0; j < N-i-1; j++) {\n            if (weight_est[item_order[j]] < weight_est[item_order[j+1]]) {\n                swap(item_order[j], item_order[j+1]);\n            }\n        }\n    }\n    \n    // Phase 3: Simple greedy assignment\n    static long long group_weights[25] = {0};\n    \n    for (int i = 0; i < N; i++) {\n        int item_idx = item_order[i];\n        int weight = weight_est[item_idx];\n        \n        // Find lightest group\n        int best_group = 0;\n        for (int g = 1; g < D; g++) {\n            if (group_weights[g] < group_weights[best_group]) {\n                best_group = g;\n            }\n        }\n        \n        assignment[item_idx] = best_group;\n        group_weights[best_group] += weight;\n    }\n    \n    // Phase 4: Simple remaining query usage\n    while (queries_used < Q) {\n        int a = queries_used % N;\n        int b = (queries_used + N/2) % N;\n        \n        if (a == b) b = (b + 1) % N;\n        \n        cout << \"1 1 \" << a << \" \" << b << endl;\n        string res;\n        cin >> res;\n        queries_used++;\n    }\n    \n    // Output\n    for (int i = 0; i < N; i++) {\n        cout << assignment[i];\n        if (i < N-1) cout << \" \";\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 200;\nconst int MAXM = 10;\n\nint n, m;\nvector<int> st[MAXM];\npair<int,int> where[MAXN+1]; // {stack, index} for box v; stack=-1 if carried\n\nvector<pair<int,int>> ops;\n\n// Carry out box v from stack s\nvoid carry_out(int v, int s) {\n    ops.emplace_back(v, 0);\n    st[s].pop_back();\n    where[v] = {-1, -1};\n}\n\n// Move box v and all above it from stack s to stack t\nvoid move_block(int v, int s, int t) {\n    int idx = where[v].second;\n    int k = st[s].size() - idx; // number of boxes to move\n    ops.emplace_back(v, t+1); // output is 1-indexed\n\n    // Extract block\n    vector<int> block(st[s].begin() + idx, st[s].end());\n    st[s].resize(idx);\n\n    // Append to target\n    for(int x : block) {\n        st[t].push_back(x);\n        where[x] = {t, (int)st[t].size()-1};\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> n >> m;\n    for(int i = 0; i < m; i++) {\n        st[i].resize(n/m);\n        for(int j = 0; j < n/m; j++) {\n            cin >> st[i][j];\n            where[ st[i][j] ] = {i, j};\n        }\n    }\n\n    int next_out = 1;\n\n    while(next_out <= n) {\n        // Phase 1: carry out as many as possible\n        bool progress = true;\n        while(progress && next_out <= n) {\n            progress = false;\n            // Find if next_out is at top of any stack\n            for(int i = 0; i < m; i++) {\n                if(!st[i].empty() && st[i].back() == next_out) {\n                    carry_out(next_out, i);\n                    next_out++;\n                    progress = true;\n                    break;\n                }\n            }\n        }\n        if(next_out > n) break;\n\n        // Phase 2: next_out is buried somewhere\n        int s = -1;\n        for(int i = 0; i < m; i++) {\n            for(int j = 0; j < st[i].size(); j++) {\n                if(st[i][j] == next_out) {\n                    s = i;\n                    break;\n                }\n            }\n            if(s != -1) break;\n        }\n        // s is the stack containing next_out\n        int idx = where[next_out].second;\n        int k = st[s].size() - idx; // boxes from next_out to top\n\n        // Choose target stack t != s with maximum top box\n        int best_t = -1;\n        int best_top = -1;\n        for(int t = 0; t < m; t++) {\n            if(t == s) continue;\n            int top_val = st[t].empty() ? 0 : st[t].back();\n            if(top_val > best_top) {\n                best_top = top_val;\n                best_t = t;\n            }\n        }\n        // Move block to best_t\n        move_block(next_out, s, best_t);\n    }\n\n    // Output operations\n    for(auto [v, i] : ops) {\n        cout << v << \" \" << i << \"\\n\";\n    }\n\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nstatic const int DI[4] = {1,0,-1,0};\nstatic const int DJ[4] = {0,1,0,-1};\nstatic const char DC[4] = {'D','R','U','L'};\n\nint main(){\n  ios::sync_with_stdio(false);\n  cin.tie(nullptr);\n\n  int N; cin>>N;\n  vector<string> hwall(N-1), vwall(N);\n  for(int i=0;i<N-1;i++) cin>>hwall[i];\n  for(int i=0;i<N;  i++) cin>>vwall[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  // build adj\n  auto inside = [&](int i,int j){ return 0<=i&&i<N&&0<=j&&j<N; };\n  vector<vector<array<int,2>>> adj(N*N);\n  auto enc = [&](int i,int j){ return i*N+j; };\n  auto dec = [&](int v){ return array<int,2>{v/N, v%N}; };\n  for(int i=0;i<N;i++){\n    for(int j=0;j<N;j++){\n      int v = enc(i,j);\n      for(int dir=0;dir<4;dir++){\n        int ni=i+DI[dir], nj=j+DJ[dir];\n        if(!inside(ni,nj)) continue;\n        bool ok = true;\n        if(dir==0){ // D\n          if(hwall[i][j]=='1') ok=false;\n        }else if(dir==2){ // U\n          if(hwall[i-1][j]=='1') ok=false;\n        }else if(dir==1){ // R\n          if(vwall[i][j]=='1') ok=false;\n        }else{ // L\n          if(vwall[i][j-1]=='1') ok=false;\n        }\n        if(ok){\n          adj[v].push_back({enc(ni,nj), dir});\n        }\n      }\n    }\n  }\n\n  // 1. basic Euler tour by DFS (simple, ensures all visited)\n  vector<bool> vis(N*N,false);\n  string basic;\n  function<void(int)> dfs = [&](int v){\n    vis[v]=true;\n    auto [i,j]=dec(v);\n    for(auto [u,dir]: adj[v]){\n      if(!vis[u]){\n        basic += DC[dir];\n        dfs(u);\n        basic += DC[dir^2]; // back\n      }\n    }\n  };\n  dfs(0);\n  // basic is already closed at (0,0)\n\n  // 2. enumerate small cycles (length <= 10) for each node\n  const int MAXCYCLE=10;\n  vector<vector<array<int,2>>> cycles(N*N); // cycles[v] = list of {start_index_in_basic, cycle_length}\n  // but we need actual cycle sequences to insert\n  // instead, we precompute for each node v: list of cycles (as string) that start from v and return to v with length <= MAXCYCLE\n  vector<vector<string>> nodeCycles(N*N);\n  vector<int> dist(N*N), parent(N*N), parDir(N*N);\n  for(int sv=0; sv<N*N; sv++){\n    fill(dist.begin(), dist.end(), -1);\n    dist[sv]=0;\n    queue<int> q; q.push(sv);\n    while(!q.empty()){\n      int v=q.front(); q.pop();\n      if(dist[v]>=MAXCYCLE) continue;\n      for(auto [u,dir]: adj[v]){\n        if(dist[u]==-1){\n          dist[u]=dist[v]+1;\n          parent[u]=v;\n          parDir[u]=dir;\n          q.push(u);\n        }\n        // found back to sv\n        if(u==sv && dist[v]+1>=2 && dist[v]+1<=MAXCYCLE){\n          // reconstruct\n          string cyc;\n          int x=v;\n          int len=dist[v]+1;\n          while(x!=sv){\n            cyc += DC[parDir[x]];\n            x = parent[x];\n          }\n          // we are at sv, but we need to close the cycle\n          // last step from v to sv is by 'dir'\n          // but we already have full path\n          // actually we don't need to push last dir, because we are already at sv\n          // the cycle string is cyc (from sv to v) and then one more step dir\n          cyc += DC[dir];\n          // this cycle starts/ends at sv, length = len\n          nodeCycles[sv].push_back(cyc);\n        }\n      }\n    }\n  }\n\n  // 3. compute efficiency = (sum of d on cycle vertices) / (cycle length)\n  vector<tuple<double,int,int,string>> effCycles; // (eff, node, index_in_nodeCycles, cycle_string)\n  for(int v=0;v<N*N;v++){\n    auto [i0,j0]=dec(v);\n    for(auto& cyc: nodeCycles[v]){\n      set<int> verts;\n      int u=v;\n      verts.insert(u);\n      for(char ch: cyc){\n        int dir = string(\"DRUL\").find(ch);\n        auto [i,j]=dec(u);\n        int ni=i+DI[dir], nj=j+DJ[dir];\n        u = enc(ni,nj);\n        verts.insert(u);\n      }\n      long long sd=0;\n      for(int x: verts){\n        auto [i,j]=dec(x);\n        sd += d[i][j];\n      }\n      double eff = (double)sd / (double)cyc.size();\n      effCycles.emplace_back(eff, v, 0, cyc);\n    }\n  }\n  // sort by eff desc\n  sort(effCycles.rbegin(), effCycles.rend());\n\n  // 4. try to insert high-eff cycles into basic as many as possible\n  // we can do: for each occurrence of v in basic, we can insert cycle there\n  // but we do greedy: take highest eff, and insert as many as possible within budget\n  const int LMAX = 100000;\n  int budget = LMAX - (int)basic.size();\n  string route = basic;\n  // we need to know positions of each node in route\n  // but route will be extended dynamically -> we do offline: precompute positions in basic, and insertions\n  // instead, we do simple: for each cycle in effCycles, try to insert at first occurrence of node\n  vector<int> posInBasic(N*N, -1);\n  {\n    int u=0;\n    posInBasic[u]=0;\n    for(int i=0;i<(int)basic.size();i++){\n      char ch=basic[i];\n      int dir=string(\"DRUL\").find(ch);\n      auto [x,y]=dec(u);\n      int nx=x+DI[dir], ny=y+DJ[dir];\n      u = enc(nx,ny);\n      if(posInBasic[u]==-1) posInBasic[u]=i+1;\n    }\n  }\n  // now for each cycle, if node v appears in basic, we can insert at posInBasic[v]\n  // we do greedy: for each cycle, insert as many as possible at that position\n  for(auto& [eff, v, dummy, cyc]: effCycles){\n    if(budget <=0) break;\n    int p = posInBasic[v];\n    if(p==-1) continue;\n    int len = cyc.size();\n    int maxrep = budget / len;\n    if(maxrep<=0) continue;\n    string add;\n    for(int t=0;t<maxrep;t++) add += cyc;\n    // insert at p\n    route.insert(p, add);\n    budget -= maxrep * len;\n  }\n\n  // 5. ensure we are back at (0,0) and length <= 1e5\n  // our basic was closed, and inserted cycles are closed, so whole route is closed\n  if(route.size() > LMAX){\n    route.resize(LMAX);\n  }\n  cout << route << endl;\n\n  return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nconst int INF = 1e9;\nint N, M;\nint si, sj;\narray<array<char, 15>, 15> A;\nvector<string> t(200);\n\n/* ========== basic grid tooling ========== */\nvector<pair<int, int>> pos[26];          // letter -> cells\nint distLetter[26][26];                  // letter -> letter (min steps)\n\nvoid buildDistLetter() {\n    for (int c = 0; c < 26; ++c) {\n        static int d[15][15];\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j) d[i][j] = INF;\n        queue<pair<int, int>> q;\n        for (auto [i, j] : pos[c]) {\n            d[i][j] = 0;\n            q.emplace(i, j);\n        }\n        int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1};\n        while (!q.empty()) {\n            auto [i, j] = q.front(); q.pop();\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + dx[dir], nj = j + dy[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                if (d[ni][nj] > d[i][j] + 1) {\n                    d[ni][nj] = d[i][j] + 1;\n                    q.emplace(ni, nj);\n                }\n            }\n        }\n        for (int c2 = 0; c2 < 26; ++c2) {\n            int best = INF;\n            for (auto [i, j] : pos[c2]) best = min(best, d[i][j]);\n            distLetter[c][c2] = best;\n        }\n    }\n}\n\n/* ========== path reconstruction ========== */\narray<array<pair<int, int>, 15>, 15> pred[26];\nvoid buildPred() {\n    for (int c = 0; c < 26; ++c) {\n        static int d[15][15];\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j) d[i][j] = INF;\n        queue<pair<int, int>> q;\n        for (auto [i, j] : pos[c]) {\n            d[i][j] = 0;\n            pred[c][i][j] = {-1, -1};\n            q.emplace(i, j);\n        }\n        int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1};\n        while (!q.empty()) {\n            auto [i, j] = q.front(); q.pop();\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + dx[dir], nj = j + dy[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                if (d[ni][nj] > d[i][j] + 1) {\n                    d[ni][nj] = d[i][j] + 1;\n                    pred[c][ni][nj] = {i, j};\n                    q.emplace(ni, nj);\n                }\n            }\n        }\n    }\n}\n\n/* ========== overlap ========== */\nint overlap(const string& a, const string& b) {\n    int maxo = 0;\n    int al = a.size(), bl = b.size();\n    int lim = min(al, bl);\n    for (int o = 1; o <= lim; ++o) {\n        bool ok = true;\n        for (int i = 0; i < o; ++i)\n            if (a[al - o + i] != b[i]) { ok = false; break; }\n        if (ok) maxo = o;\n    }\n    return maxo;\n}\n\n/* ========== Aho\u2013Corasick for full check ========== */\nnamespace AC {\n    const int A = 26, N = 200 * 5 + 10;\n    int trie[N][A], fail[N], cnt[N], nodes = 1;\n    int insert(const string& s) {\n        int v = 0;\n        for (char ch : s) {\n            int c = ch - 'A';\n            if (!trie[v][c]) trie[v][c] = nodes++;\n            v = trie[v][c];\n        }\n        cnt[v]++;\n        return v;\n    }\n    void build() {\n        queue<int> q;\n        for (int c = 0; c < A; ++c) if (trie[0][c]) q.push(trie[0][c]);\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            for (int c = 0; c < A; ++c) {\n                int u = trie[v][c];\n                if (!u) { trie[v][c] = trie[fail[v]][c]; continue; }\n                fail[u] = v ? trie[fail[v]][c] : 0;\n                q.push(u);\n            }\n        }\n    }\n    int countMatches(const string& s) {\n        int v = 0, matches = 0;\n        for (char ch : s) {\n            int c = ch - 'A';\n            v = trie[v][c];\n            int tmp = v;\n            while (tmp) { matches += cnt[tmp]; cnt[tmp] = 0; tmp = fail[tmp]; }\n        }\n        return matches;\n    }\n}\n\n/* ========== real path & string ========== */\nvector<pair<int, int>> outPath;\nint curi, curj;\n\nvoid appendMove(int ti, int tj) {\n    if (curi == ti && curj == tj) return;\n    static int d[15][15];\n    static pair<int, int> p[15][15];\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) d[i][j] = INF;\n    queue<pair<int, int>> q;\n    d[curi][curj] = 0;\n    q.emplace(curi, curj);\n    int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1};\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        if (i == ti && j == tj) break;\n        for (int dir = 0; dir < 4; ++dir) {\n            int ni = i + dx[dir], nj = j + dy[dir];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            if (d[ni][nj] > d[i][j] + 1) {\n                d[ni][nj] = d[i][j] + 1;\n                p[ni][nj] = {i, j};\n                q.emplace(ni, nj);\n            }\n        }\n    }\n    vector<pair<int, int>> rev;\n    auto xy = make_pair(ti, tj);\n    while (xy.first != curi || xy.second != curj) {\n        rev.push_back(xy);\n        xy = p[xy.first][xy.second];\n    }\n    reverse(rev.begin(), rev.end());\n    for (auto [i, j] : rev) outPath.emplace_back(i, j);\n    curi = ti; curj = tj;\n}\n\n/* choose concrete cells for a suffix */\nvector<pair<int, int>> chooseCells(const string& s, char nextFirst) {\n    vector<pair<int, int>> res;\n    int nc = nextFirst == 0 ? -1 : nextFirst - 'A';\n    for (char c : s) {\n        int cc = c - 'A';\n        int best = INF;\n        pair<int, int> pick;\n        for (auto [i, j] : pos[cc]) {\n            int dd = abs(i - curi) + abs(j - curj);\n            int centr = abs(i - N / 2) + abs(j - N / 2);\n            int score = dd + centr / 3;\n            if (score < best) { best = score; pick = {i, j}; }\n        }\n        res.push_back(pick);\n        curi = pick.first; curj = pick.second;\n    }\n    return res;\n}\n\n/* build path & extract string S */\nstring buildString(const vector<int>& ord) {\n    outPath.clear();\n    curi = si; curj = sj;\n    string S;\n    S.reserve(6000);\n    auto pushCell = [&](int i, int j) {\n        appendMove(i, j);\n        S.push_back(A[i][j]);\n    };\n    for (int k = 0; k < M; ++k) {\n        int id = ord[k];\n        const string& w = t[id];\n        if (k == 0) {\n            auto cells = chooseCells(w, M > 1 ? t[ord[1]][0] : 0);\n            for (auto [i, j] : cells) pushCell(i, j);\n        } else {\n            int o = overlap(t[ord[k - 1]], w);\n            string suf = w.substr(o);\n            char nf = 0;\n            if (k + 1 < M) nf = t[ord[k + 1]][0];\n            auto cells = chooseCells(suf, nf);\n            for (auto [i, j] : cells) pushCell(i, j);\n        }\n        if (S.size() > 5000) return \"\";          // early give-up\n    }\n    return S;\n}\n\n/* ========== 2-opt on word order ========== */\nvoid twoOpt(vector<int>& ord) {\n    auto costEdge = [&](int l, int r) {\n        char lc = t[ord[l]].back();\n        char fc = t[ord[r]][0];\n        return distLetter[lc - 'A'][fc - 'A'] + 1;\n    };\n    bool improved = true;\n    int iter = 0;\n    while (improved && ++iter < 1000) {\n        improved = false;\n        for (int i = 0; i + 1 < M; ++i)\n            for (int j = i + 1; j < M; ++j) {\n                ll old = costEdge(i - 1, i) + costEdge(i, i + 1)\n                       + costEdge(j - 1, j) + costEdge(j, (j + 1) % M);\n                ll nw = costEdge(i - 1, j) + costEdge(j, i + 1)\n                      + costEdge(j - 1, i) + costEdge(i, (j + 1) % M);\n                if (nw < old) {\n                    swap(ord[i], ord[j]);\n                    improved = true;\n                }\n            }\n    }\n}\n\n/* ========== driver ========== */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M;\n    cin >> si >> sj;\n    for (int i = 0; i < N; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < N; ++j) {\n            A[i][j] = row[j];\n            pos[A[i][j] - 'A'].emplace_back(i, j);\n        }\n    }\n    for (int k = 0; k < M; ++k) cin >> t[k];\n\n    buildDistLetter();\n    buildPred();\n    /* Aho-Corasick */\n    for (const string& s : t) AC::insert(s);\n    AC::build();\n\n    /* greedy initial order */\n    vector<int> ord(M);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int a, int b) {\n        return t[a] < t[b];\n    });\n    twoOpt(ord);\n\n    /* ensure validity */\n    string S = buildString(ord);\n    if ((int)S.size() > 5000 || AC::countMatches(S) < M) {\n        /* fallback: original greedy overlap order */\n        ord.assign(M, 0);\n        iota(ord.begin(), ord.end(), 0);\n        sort(ord.begin(), ord.end(), [&](int a, int b) {\n            int oa = overlap(t[ord[0]], t[a]);\n            int ob = overlap(t[ord[0]], t[b]);\n            if (oa != ob) return oa > ob;\n            return distLetter[t[ord[0]].back() - 'A'][t[a][0] - 'A']\n                 < distLetter[t[ord[0]].back() - 'A'][t[b][0] - 'A'];\n        });\n        S = buildString(ord);\n    }\n\n    /* output path */\n    for (auto [i, j] : outPath) cout << i << ' ' << j << '\\n';\n    return 0;\n}","ahc030":"#include <iostream>\n#include <vector>\n#include <set>\n#include <algorithm>\n\nusing namespace std;\n\nint N, M;\ndouble eps;\nvector<vector<bool>> drilled;\nvector<vector<int>> values;\n\n// Simple query functions\nint drill(int i, int j) {\n    cout << \"q 1 \" << i << \" \" << j << endl;\n    int response;\n    cin >> response;\n    return response;\n}\n\nint divine(const vector<pair<int, int>>& points) {\n    if (points.size() < 2) return 0;\n    \n    cout << \"q \" << points.size();\n    for (auto [i, j] : points) {\n        cout << \" \" << i << \" \" << j;\n    }\n    cout << endl;\n    \n    int response;\n    cin >> response;\n    return max(0, response);  // Ensure non-negative\n}\n\nbool answer(const vector<pair<int, int>>& answer_points) {\n    cout << \"a \" << answer_points.size();\n    for (auto [i, j] : answer_points) {\n        cout << \" \" << i << \" \" << j;\n    }\n    cout << endl;\n    \n    int response;\n    cin >> response;\n    return response == 1;\n}\n\nint main() {\n    // Read input\n    cin >> N >> M >> eps;\n    \n    // Read oil field shapes (we'll use these for intelligent guessing)\n    vector<vector<pair<int, int>>> oil_fields(M);\n    for (int k = 0; k < M; k++) {\n        int d;\n        cin >> d;\n        oil_fields[k].resize(d);\n        for (int i = 0; i < d; i++) {\n            cin >> oil_fields[k][i].first >> oil_fields[k][i].second;\n        }\n    }\n    \n    // Initialize tracking\n    drilled.assign(N, vector<bool>(N, false));\n    values.assign(N, vector<int>(N, -1));\n    \n    vector<pair<int, int>> oil_squares;\n    int operations = 0;\n    const int max_ops = 2 * N * N;\n    \n    // Strategy 1: Use divination to find regions with oil\n    // Divide grid into blocks and divine each block\n    \n    int block_size = 4;  // 4x4 blocks\n    if (N <= 12) block_size = 3;\n    if (N <= 8) block_size = 2;\n    \n    for (int bi = 0; bi < N && operations < max_ops - 50; bi += block_size) {\n        for (int bj = 0; bj < N && operations < max_ops - 50; bj += block_size) {\n            vector<pair<int, int>> block;\n            \n            for (int i = bi; i < min(bi + block_size, N); i++) {\n                for (int j = bj; j < min(bj + block_size, N); j++) {\n                    block.emplace_back(i, j);\n                }\n            }\n            \n            if (block.size() >= 2) {\n                int sum = divine(block);\n                operations++;\n                \n                // If sum is significant, this block likely contains oil\n                if (sum > 0) {\n                    // Drill a few squares in this block to confirm\n                    int to_drill = min(sum, (int)block.size() / 2);\n                    for (int k = 0; k < to_drill && operations < max_ops - 20; k++) {\n                        auto [i, j] = block[k];\n                        if (!drilled[i][j]) {\n                            int val = drill(i, j);\n                            operations++;\n                            drilled[i][j] = true;\n                            values[i][j] = val;\n                            if (val > 0) {\n                                oil_squares.emplace_back(i, j);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Strategy 2: If we found oil, explore around it using shape information\n    if (!oil_squares.empty() && operations < max_ops - 20) {\n        // For each oil square we found, check neighbors that could be part of oil fields\n        set<pair<int, int>> candidates;\n        \n        for (auto [oi, oj] : oil_squares) {\n            // Add all neighbors within reasonable distance\n            for (int di = -3; di <= 3; di++) {\n                for (int dj = -3; dj <= 3; dj++) {\n                    int ni = oi + di, nj = oj + dj;\n                    if (ni >= 0 && ni < N && nj >= 0 && nj < N && !drilled[ni][nj]) {\n                        candidates.insert({ni, nj});\n                    }\n                }\n            }\n        }\n        \n        // Divine groups of candidates\n        vector<pair<int, int>> candidate_list(candidates.begin(), candidates.end());\n        for (int i = 0; i < (int)candidate_list.size() && operations < max_ops - 10; i += 9) {\n            vector<pair<int, int>> group;\n            for (int j = i; j < min(i + 9, (int)candidate_list.size()); j++) {\n                group.push_back(candidate_list[j]);\n            }\n            if (group.size() >= 2) {\n                int sum = divine(group);\n                operations++;\n                \n                // Drill high-probability squares\n                if (sum > 0) {\n                    int to_drill = min(sum, (int)group.size());\n                    for (int k = 0; k < to_drill && operations < max_ops - 5; k++) {\n                        auto [x, y] = group[k];\n                        if (!drilled[x][y]) {\n                            int val = drill(x, y);\n                            operations++;\n                            drilled[x][y] = true;\n                            values[x][y] = val;\n                            if (val > 0) {\n                                oil_squares.emplace_back(x, y);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Strategy 3: Final cleanup - check remaining high-probability areas\n    // Focus on center areas first as oil fields are more likely there\n    vector<pair<int, int>> remaining;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (!drilled[i][j]) {\n                // Priority based on distance to center and existing oil\n                int dist_to_center = abs(i - N/2) + abs(j - N/2);\n                int dist_to_oil = N * 2;\n                for (auto [oi, oj] : oil_squares) {\n                    dist_to_oil = min(dist_to_oil, abs(i - oi) + abs(j - oj));\n                }\n                \n                int priority = dist_to_oil * 2 + dist_to_center;\n                remaining.push_back({i, j});\n            }\n        }\n    }\n    \n    // Drill remaining squares strategically\n    for (int i = 0; i < (int)remaining.size() && operations < max_ops - 1; i++) {\n        auto [x, y] = remaining[i];\n        int val = drill(x, y);\n        operations++;\n        drilled[x][y] = true;\n        values[x][y] = val;\n        if (val > 0) {\n            oil_squares.emplace_back(x, y);\n        }\n    }\n    \n    // Final answer\n    answer(oil_squares);\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nstatic const int W = 1000;\nint D, N;\nvector<vector<int>> a;\n\n// partition bitsets: 1 = partition exists\n// Hseg[i][j] : horizontal segment at row i, columns j..j+1  (i in [1,W-1], j in [0,W-1])\n// Vseg[i][j] : vertical   segment at col j, rows i..i+1    (i in [0,W-1], j in [1,W-1])\nbitset<W> Hseg[W], Vseg[W];\n\nstruct Rect {\n    int i0, j0, i1, j1;\n    int area() const { return (i1 - i0) * (j1 - j0); }\n};\n\n// output rectangles per day\nvector<vector<Rect>> outRect;\n\n// compute partition-change cost versus previous day\nint computeLd(const vector<Rect>& rects) {\n    // new partition maps\n    bitset<W> nH[W], nV[W];\n    for (const auto& r : rects) {\n        int i0 = r.i0, j0 = r.j0, i1 = r.i1, j1 = r.j1;\n        // top edge\n        if (i0 > 0)      for (int j = j0; j < j1; ++j) nH[i0].set(j);\n        // bottom edge\n        if (i1 < W)      for (int j = j0; j < j1; ++j) nH[i1].set(j);\n        // left edge\n        if (j0 > 0)      for (int i = i0; i < i1; ++i) nV[i].set(j0);\n        // right edge\n        if (j1 < W)      for (int i = i0; i < i1; ++i) nV[i].set(j1);\n    }\n    int cost = 0;\n    for (int i = 1; i < W; ++i) {\n        auto diff = Hseg[i] ^ nH[i];\n        cost += diff.count();\n    }\n    for (int j = 1; j < W; ++j) {\n        bitset<W> diff;\n        for (int i = 0; i < W; ++i) diff[i] = Vseg[i][j] ^ nV[i][j];\n        cost += diff.count();\n    }\n    return cost;\n}\n\n// assign rectangles for one day\nvoid solveDay(int d) {\n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    // largest first\n    sort(ord.begin(), ord.end(), [&](int x, int y) {\n        return a[d][x] > a[d][y];\n    });\n\n    // free rectangles\n    vector<Rect> freeList = { {0, 0, W, W} };\n    vector<Rect> assigned(N);\n\n    auto bestSplit = [&](const Rect& hole, int need,\n                         int& bestCost, Rect& bestA, Rect& bestB, bool& bestIsHoriz) {\n        bestCost = INT_MAX;\n        int h = hole.i1 - hole.i0;\n        int w = hole.j1 - hole.j0;\n        // try horizontal split: i0..cut and cut..i1\n        if (h > 1) {\n            int cutLo = hole.i0 + 1;\n            int cutHi = hole.i1 - 1;\n            int step = max(1, (cutHi - cutLo + 1) / 20);\n            for (int cut = cutLo; cut <= cutHi; cut += step) {\n                Rect A = { hole.i0, hole.j0, cut,     hole.j1 };\n                Rect B = { cut,     hole.j0, hole.i1, hole.j1 };\n                if (A.area() < need) continue;\n                // compute extra partition cost\n                int c = 0;\n                // new horizontal segment at 'cut'\n                for (int j = hole.j0; j < hole.j1; ++j) {\n                    bool old = Hseg[cut][j];\n                    if (!old) c++;\n                }\n                if (c < bestCost) {\n                    bestCost = c;\n                    bestA = A;\n                    bestB = B;\n                    bestIsHoriz = true;\n                }\n            }\n        }\n        // try vertical split\n        if (w > 1) {\n            int cutLo = hole.j0 + 1;\n            int cutHi = hole.j1 - 1;\n            int step = max(1, (cutHi - cutLo + 1) / 20);\n            for (int cut = cutLo; cut <= cutHi; cut += step) {\n                Rect A = { hole.i0, hole.j0, hole.i1, cut };\n                Rect B = { hole.i0, cut,     hole.i1, hole.j1 };\n                if (A.area() < need) continue;\n                int c = 0;\n                for (int i = hole.i0; i < hole.i1; ++i) {\n                    bool old = Vseg[i][cut];\n                    if (!old) c++;\n                }\n                if (c < bestCost) {\n                    bestCost = c;\n                    bestA = A;\n                    bestB = B;\n                    bestIsHoriz = false;\n                }\n            }\n        }\n    };\n\n    for (int k : ord) {\n        int need = a[d][k];\n        int bestCost = INT_MAX;\n        Rect bestA, bestB;\n        bool bestIsHoriz = false;\n        int bestIdx = -1;\n        for (int idx = 0; idx < (int)freeList.size(); ++idx) {\n            const Rect& hole = freeList[idx];\n            if (hole.area() < need) continue;\n            int c; Rect A, B; bool ih;\n            bestSplit(hole, need, c, A, B, ih);\n            if (c < bestCost) {\n                bestCost = c;\n                bestA = A;\n                bestB = B;\n                bestIsHoriz = ih;\n                bestIdx = idx;\n            }\n        }\n        assert(bestIdx != -1);\n        assigned[k] = bestA;\n        freeList[bestIdx] = bestB;\n    }\n\n    // store output order\n    outRect[d] = assigned;\n\n    // update global partition maps for next day\n    for (int i = 0; i < W; ++i) Hseg[i].reset();\n    for (int j = 0; j < W; ++j) Vseg[j].reset();\n    for (const auto& r : assigned) {\n        int i0 = r.i0, j0 = r.j0, i1 = r.i1, j1 = r.j1;\n        if (i0 > 0)      for (int j = j0; j < j1; ++j) Hseg[i0].set(j);\n        if (i1 < W)      for (int j = j0; j < j1; ++j) Hseg[i1].set(j);\n        if (j0 > 0)      for (int i = i0; i < i1; ++i) Vseg[i].set(j0);\n        if (j1 < W)      for (int i = i0; i < i1; ++i) Vseg[i].set(j1);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> W >> D >> N;\n    a.assign(D, vector<int>(N));\n    for (int d = 0; d < D; ++d)\n        for (int k = 0; k < N; ++k)\n            cin >> a[d][k];\n\n    outRect.assign(D, vector<Rect>(N));\n\n    // initialize partitions: none\n    for (int i = 0; i < W; ++i) {\n        Hseg[i].reset();\n        Vseg[i].reset();\n    }\n\n    for (int d = 0; d < D; ++d) {\n        solveDay(d);\n    }\n\n    // output\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            const auto& r = outRect[d][k];\n            cout << r.i0 << ' ' << r.j0 << ' ' << r.i1 << ' ' << r.j1 << '\\n';\n        }\n    }\n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <tuple>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\nconst int MOD = 998244353;\nconst int N = 9;\nconst int M = 20;\nconst int K = 81;\n\nint board[N][N];\nint stamps[M][3][3];\nint temp_board[N][N];\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint compute_marginal(int m, int p, int q) {\n    int gain = 0;\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            int original = board[p + i][q + j] % MOD;\n            int new_val = (board[p + i][q + j] + stamps[m][i][j]) % MOD;\n            gain += new_val - original;\n        }\n    }\n    return gain;\n}\n\nvoid apply_stamp(int m, int p, int q) {\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            board[p + i][q + j] = (board[p + i][q + j] + stamps[m][i][j]) % MOD;\n        }\n    }\n}\n\nvoid revert_stamp(int m, int p, int q) {\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            board[p + i][q + j] = (board[p + i][q + j] - stamps[m][i][j] % MOD + MOD) % MOD;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n, m, k;\n    cin >> n >> m >> k;\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cin >> board[i][j];\n        }\n    }\n    for (int mm = 0; mm < m; ++mm) {\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                cin >> stamps[mm][i][j];\n            }\n        }\n    }\n\n    vector<tuple<int, int, int>> operations;\n\n    for (int step = 0; step < k; ++step) {\n        vector<tuple<int, int, int, int>> candidates; // (gain, m, p, q)\n        for (int mm = 0; mm < m; ++mm) {\n            for (int p = 0; p <= n - 3; ++p) {\n                for (int q = 0; q <= n - 3; ++q) {\n                    int gain = compute_marginal(mm, p, q);\n                    candidates.emplace_back(gain, mm, p, q);\n                }\n            }\n        }\n\n        sort(candidates.rbegin(), candidates.rend());\n        bool found = false;\n\n        // Try top 10 candidates with lookahead 2\n        for (int attempt = 0; attempt < min(10, (int)candidates.size()); ++attempt) {\n            auto [gain1, m1, p1, q1] = candidates[attempt];\n            if (gain1 <= 0 && attempt > 0) break;\n\n            apply_stamp(m1, p1, q1);\n\n            // Lookahead: find best second step\n            int best_gain2 = -1e9;\n            int best_m2 = -1, best_p2 = -1, best_q2 = -1;\n            for (int mm = 0; mm < m; ++mm) {\n                for (int p = 0; p <= n - 3; ++p) {\n                    for (int q = 0; q <= n - 3; ++q) {\n                        int gain2 = compute_marginal(mm, p, q);\n                        if (gain2 > best_gain2) {\n                            best_gain2 = gain2;\n                            best_m2 = mm;\n                            best_p2 = p;\n                            best_q2 = q;\n                        }\n                    }\n                }\n            }\n\n            if (gain1 + best_gain2 > 0) {\n                operations.emplace_back(m1, p1, q1);\n                found = true;\n                break;\n            } else {\n                revert_stamp(m1, p1, q1);\n            }\n        }\n\n        if (!found) {\n            // Random exploration\n            uniform_int_distribution<int> dist_m(0, m - 1);\n            uniform_int_distribution<int> dist_p(0, n - 3);\n            uniform_int_distribution<int> dist_q(0, n - 3);\n            int m_rand = dist_m(rng);\n            int p_rand = dist_p(rng);\n            int q_rand = dist_q(rng);\n            operations.emplace_back(m_rand, p_rand, q_rand);\n            apply_stamp(m_rand, p_rand, q_rand);\n        }\n    }\n\n    cout << operations.size() << '\\n';\n    for (auto [mm, p, q] : operations) {\n        cout << mm << ' ' << p << ' ' << q << '\\n';\n    }\n\n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <string>\n\nusing namespace std;\n\nconst int MAX_N = 5;\n\nint N;\nint A[MAX_N][MAX_N];\nvector<string> operations(MAX_N);\n\n// Current state\nint grid[MAX_N][MAX_N];\nint crane_pos[MAX_N][2];\nbool crane_carry[MAX_N];\nint crane_container[MAX_N];\nbool crane_alive[MAX_N];\n\n// Movement planning with collision avoidance\nint planned_positions[MAX_N][2];\nbool has_planned_move[MAX_N];\n\nint get_target_gate(int container) {\n    return container / N;\n}\n\nbool is_valid_position(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N;\n}\n\nbool is_position_occupied(int x, int y, int excluding_crane) {\n    for (int i = 0; i < N; i++) {\n        if (i != excluding_crane && crane_alive[i] && crane_pos[i][0] == x && crane_pos[i][1] == y) {\n            return true;\n        }\n    }\n    return false;\n}\n\nbool can_execute_move(int crane_id, char move) {\n    if (!crane_alive[crane_id]) return false;\n    \n    int new_x = crane_pos[crane_id][0];\n    int new_y = crane_pos[crane_id][1];\n    \n    if (move == 'U') new_x--;\n    else if (move == 'D') new_x++;\n    else if (move == 'L') new_y--;\n    else if (move == 'R') new_y++;\n    else return true; // '.' is always safe\n    \n    if (!is_valid_position(new_x, new_y)) return false;\n    \n    // Comprehensive validation: crane collisions + small crane carrying rule\n    if (is_position_occupied(new_x, new_y, crane_id)) return false;\n    if (crane_id > 0 && crane_carry[crane_id] && grid[new_x][new_y] != -1) return false;\n    \n    return true;\n}\n\nvoid simulate_turn(const vector<char>& moves) {\n    // Step 1: Receive containers\n    static int received_count[MAX_N] = {0};\n    for (int i = 0; i < N; i++) {\n        if (grid[i][0] == -1 && !crane_carry[i] && received_count[i] < N) {\n            bool occupied = false;\n            for (int j = 0; j < N; j++) {\n                if (crane_pos[j][0] == i && crane_pos[j][1] == 0 && crane_alive[j]) {\n                    occupied = true;\n                    break;\n                }\n            }\n            if (!occupied) {\n                grid[i][0] = A[i][received_count[i]];\n                received_count[i]++;\n            }\n        }\n    }\n    \n    // Step 2: Execute crane moves with bulletproof validation\n    for (int i = 0; i < N && i < (int)moves.size(); i++) {\n        if (!crane_alive[i]) continue;\n        \n        char move = moves[i];\n        \n        if (move == 'P') {\n            if (!crane_carry[i] && grid[crane_pos[i][0]][crane_pos[i][1]] != -1) {\n                crane_carry[i] = true;\n                crane_container[i] = grid[crane_pos[i][0]][crane_pos[i][1]];\n                grid[crane_pos[i][0]][crane_pos[i][1]] = -1;\n            }\n        } else if (move == 'Q') {\n            if (crane_carry[i] && grid[crane_pos[i][0]][crane_pos[i][1]] == -1) {\n                crane_carry[i] = false;\n                grid[crane_pos[i][0]][crane_pos[i][1]] = crane_container[i];\n                crane_container[i] = -1;\n            }\n        } else if (move == 'U' && can_execute_move(i, 'U')) {\n            crane_pos[i][0]--;\n        } else if (move == 'D' && can_execute_move(i, 'D')) {\n            crane_pos[i][0]++;\n        } else if (move == 'L' && can_execute_move(i, 'L')) {\n            crane_pos[i][1]--;\n        } else if (move == 'R' && can_execute_move(i, 'R')) {\n            crane_pos[i][1]++;\n        } else if (move == 'B') {\n            if (!crane_carry[i]) {\n                crane_alive[i] = false;\n            }\n        }\n    }\n    \n    // Step 3: Dispatch containers\n    for (int i = 0; i < N; i++) {\n        if (grid[i][N-1] != -1) {\n            grid[i][N-1] = -1;\n        }\n    }\n}\n\nint main() {\n    cin >> N;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> A[i][j];\n        }\n    }\n    \n    // Initialize state\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = -1;\n        }\n        crane_pos[i][0] = i;\n        crane_pos[i][1] = 0;\n        crane_carry[i] = false;\n        crane_container[i] = -1;\n        crane_alive[i] = true;\n        operations[i] = \"\";\n        has_planned_move[i] = false;\n        planned_positions[i][0] = i;\n        planned_positions[i][1] = 0;\n    }\n    \n    // Bulletproof strategy: Sequential planning with comprehensive validation\n    int turns = 0;\n    const int max_turns = 2100; // Conservative improvement\n    \n    while (turns < max_turns) {\n        vector<char> current_moves(N, '.');\n        \n        // Sequential planning with bulletproof safety checks\n        for (int i = 0; i < N; i++) {\n            if (!crane_alive[i]) continue;\n            \n            int x = crane_pos[i][0];\n            int y = crane_pos[i][1];\n            \n            if (!crane_carry[i]) {\n                if (grid[x][y] != -1) {\n                    current_moves[i] = 'P';\n                } else {\n                    // Ultra-safe container hunting with full validation\n                    bool found_target = false;\n                    \n                    // Priority 1: Containers in wrong rows (closest first)\n                    for (int scan_y = N-2; scan_y >= 0 && !found_target; scan_y--) {\n                        for (int scan_x = 0; scan_x < N && !found_target; scan_x++) {\n                            if (grid[scan_x][scan_y] != -1) {\n                                int container = grid[scan_x][scan_y];\n                                int target_gate = get_target_gate(container);\n                                \n                                if (scan_x != target_gate) {\n                                    // Test each direction with bulletproof validation\n                                    if (x < scan_x && can_execute_move(i, 'D')) {\n                                        current_moves[i] = 'D';\n                                        found_target = true;\n                                    } else if (x > scan_x && can_execute_move(i, 'U')) {\n                                        current_moves[i] = 'U';\n                                        found_target = true;\n                                    } else if (y < scan_y && can_execute_move(i, 'R')) {\n                                        current_moves[i] = 'R';\n                                        found_target = true;\n                                    } else if (y > scan_y && can_execute_move(i, 'L')) {\n                                        current_moves[i] = 'L';\n                                        found_target = true;\n                                    }\n                                }\n                            }\n                        }\n                    }\n                    \n                    // Priority 2: Any available container with safe movement\n                    if (!found_target) {\n                        for (int scan_x = 0; scan_x < N && !found_target; scan_x++) {\n                            for (int scan_y = 0; scan_y < N-1 && !found_target; scan_y++) {\n                                if (grid[scan_x][scan_y] != -1) {\n                                    if (x < scan_x && can_execute_move(i, 'D')) {\n                                        current_moves[i] = 'D';\n                                        found_target = true;\n                                    } else if (x > scan_x && can_execute_move(i, 'U')) {\n                                        current_moves[i] = 'U';\n                                        found_target = true;\n                                    } else if (y < scan_y && can_execute_move(i, 'R')) {\n                                        current_moves[i] = 'R';\n                                        found_target = true;\n                                    } else if (y > scan_y && can_execute_move(i, 'L')) {\n                                        current_moves[i] = 'L';\n                                        found_target = true;\n                                    }\n                                }\n                            }\n                        }\n                    }\n                    \n                    // Priority 3: Safe rightward movement\n                    if (!found_target && can_execute_move(i, 'R')) {\n                        current_moves[i] = 'R';\n                    }\n                }\n            } else {\n                // Carrying container - safe dispatch movement\n                int container = crane_container[i];\n                int target_gate = get_target_gate(container);\n                \n                // Safe movement with bulletproof validation\n                if (x < target_gate && can_execute_move(i, 'D')) {\n                    current_moves[i] = 'D';\n                } else if (x > target_gate && can_execute_move(i, 'U')) {\n                    current_moves[i] = 'U';\n                } else if (y < N-1 && can_execute_move(i, 'R')) {\n                    current_moves[i] = 'R';\n                } else if (y == N-1 && can_execute_move(i, 'Q')) {\n                    current_moves[i] = 'Q';\n                }\n            }\n        }\n        \n        simulate_turn(current_moves);\n        \n        // Record operations\n        for (int i = 0; i < N; i++) {\n            operations[i] += current_moves[i];\n        }\n        \n        turns++;\n        \n        // Early termination\n        if (turns > 15) {\n            bool all_clear = true;\n            for (int i = 0; i < N && all_clear; i++) {\n                for (int j = 0; j < N && all_clear; j++) {\n                    if (grid[i][j] != -1) all_clear = false;\n                }\n            }\n            if (all_clear) break;\n        }\n    }\n    \n    // Ensure all strings have same length\n    size_t max_len = 0;\n    for (int i = 0; i < N; i++) {\n        max_len = max(max_len, operations[i].size());\n    }\n    \n    for (int i = 0; i < N; i++) {\n        while (operations[i].size() < max_len) {\n            operations[i] += '.';\n        }\n    }\n    \n    // Output operations\n    for (int i = 0; i < N; i++) {\n        cout << operations[i] << endl;\n    }\n    \n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nint h[20][20];\nvector<string> out;\n\nstruct Pt { int i, j, a; };\nvector<Pt> src, snk;\n\nint md(const Pt &x, const Pt &y) {\n    return abs(x.i - y.i) + abs(x.j - y.j);\n}\n\nvoid go(int di, int dj) {\n    if (di > 0) for (int k = 0; k < di; ++k) out.push_back(\"D\");\n    if (di < 0) for (int k = 0; k < -di; ++k) out.push_back(\"U\");\n    if (dj > 0) for (int k = 0; k < dj; ++k) out.push_back(\"R\");\n    if (dj < 0) for (int k = 0; k < -dj; ++k) out.push_back(\"L\");\n}\n\n// 2-opt \u6539\u5584\u56de\u8def\ntemplate<typename T>\nvoid twoOpt(vector<T> &route, int rounds = 50) {\n    int n = route.size();\n    if (n < 4) return;\n    while (rounds--) {\n        bool improved = false;\n        for (int i = 0; i < n - 1; ++i) {\n            for (int j = i + 2; j < n; ++j) {\n                int old = md(route[i], route[i + 1]) + md(route[j], route[(j + 1) % n]);\n                int neq = md(route[i], route[j]) + md(route[i + 1], route[(j + 1) % n]);\n                if (neq < old) {\n                    reverse(route.begin() + i + 1, route.begin() + j + 1);\n                    improved = true;\n                }\n            }\n        }\n        if (!improved) break;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            cin >> h[i][j];\n            if (h[i][j] > 0) src.push_back({i, j, h[i][j]});\n            else if (h[i][j] < 0) snk.push_back({i, j, -h[i][j]});\n        }\n\n    // 1. \u8ba1\u7b97\u201c\u6e90\u70b9-\u6c47\u70b9\u5bc6\u96c6\u5ea6\u201d\u6743\u91cd\n    vector<long long> weight(src.size());\n    for (size_t i = 0; i < src.size(); ++i)\n        for (auto &t : snk) weight[i] += md(src[i], t);\n    // \u6309\u6743\u91cd\u5347\u5e8f\uff08\u8d8a\u9760\u8fd1\u6c47\u70b9\u5bc6\u96c6\u533a\u8d8a\u5148\u8d70\uff09\n    vector<int> ord(src.size());\n    for (size_t i = 0; i < src.size(); ++i) ord[i] = i;\n    sort(ord.begin(), ord.end(), [&](int x, int y) { return weight[x] < weight[y]; });\n    vector<Pt> srcNew(src.size());\n    for (size_t i = 0; i < src.size(); ++i) srcNew[i] = src[ord[i]];\n    src = srcNew;\n\n    // 2. 2-opt \u4f18\u5316\u7a7a\u8f66\u91cc\u7a0b\n    auto buildNN = [](vector<Pt> &v) {\n        if (v.empty()) return;\n        vector<char> used(v.size(), 0);\n        for (size_t rem = 0; rem < v.size(); ++rem) {\n            if (rem == 0) { used[0] = 1; continue; }\n            int best = INT_MAX, nxt = -1;\n            for (size_t i = 0; i < v.size(); ++i) if (!used[i]) {\n                int d = md(v[rem - 1], v[i]);\n                if (d < best) { best = d; nxt = (int)i; }\n            }\n            used[nxt] = 1;\n            swap(v[rem], v[nxt]);\n        }\n    };\n    buildNN(src);\n    twoOpt(src, 50);\n\n    // 3. \u6876\u54c8\u5e0c\uff08\u540c\u4e0a\u7248\uff09\n    const int B = 5;\n    vector<vector<int>> bucket(B * B);\n    vector<int> need(snk.size());\n    for (size_t i = 0; i < snk.size(); ++i) {\n        need[i] = snk[i].a;\n        int bi = snk[i].i / B, bj = snk[i].j / B;\n        bucket[bi * B + bj].push_back(i);\n    }\n\n    int ci = 0, cj = 0;\n    // 4. \u6309\u6539\u5584\u540e\u7684\u6e90\u5e8f\u6536\u96c6 + \u52a8\u6001 NN \u5378\u8d27\n    auto findNearest = [&](int ci, int cj, int load) -> tuple<int, int> {\n        int bi = clamp(ci / B, 0, B - 1), bj = clamp(cj / B, 0, B - 1);\n        int best = INT_MAX, bidx = -1, bgive = 0;\n        for (int db = -2; db <= 2; ++db) {\n            for (int da = -2; da <= 2; ++da) {\n                int nb = bi + db, na = bj + da;\n                if (nb < 0 || nb >= B || na < 0 || na >= B) continue;\n                auto &vec = bucket[nb * B + na];\n                for (int idx : vec) if (need[idx]) {\n                    int d = md({ci, cj, 0}, snk[idx]);\n                    if (d < best) {\n                        best = d; bidx = idx; bgive = min(load, need[idx]);\n                    }\n                }\n            }\n        }\n        if (bidx == -1) {\n            for (size_t i = 0; i < snk.size(); ++i) if (need[i]) {\n                int d = md({ci, cj, 0}, snk[i]);\n                if (d < best) {\n                    best = d; bidx = (int)i; bgive = min(load, need[i]);\n                }\n            }\n        }\n        return {bidx, bgive};\n    };\n\n    for (auto &s : src) {\n        go(s.i - ci, s.j - cj);\n        ci = s.i; cj = s.j;\n        out.push_back(\"+\" + to_string(s.a));\n        int load = s.a;\n        while (load > 0) {\n            auto [idx, give] = findNearest(ci, cj, load);\n            if (idx == -1) break;\n            auto &t = snk[idx];\n            go(t.i - ci, t.j - cj);\n            ci = t.i; cj = t.j;\n            out.push_back(\"-\" + to_string(give));\n            load -= give;\n            need[idx] -= give;\n        }\n    }\n\n    // 5. \u8865\u6f0f\n    for (size_t i = 0; i < snk.size(); ++i) if (need[i]) {\n        auto &t = snk[i];\n        go(t.i - ci, t.j - cj);\n        ci = t.i; cj = t.j;\n        out.push_back(\"-\" + to_string(need[i]));\n    }\n\n    for (auto &s : out) cout << s << '\\n';\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n\nusing namespace std;\n\nint main() {\n    int N, M, T;\n    cin >> N >> M >> T;\n    \n    const int seed_count = 2 * N * (N - 1);\n    vector<vector<int>> seeds(seed_count, vector<int>(M));\n    vector<int> seed_values(seed_count);\n    \n    // Read initial seeds\n    for (int i = 0; i < seed_count; i++) {\n        for (int j = 0; j < M; j++) {\n            cin >> seeds[i][j];\n        }\n    }\n    \n    for (int turn = 0; turn < T; turn++) {\n        // Calculate current seed values\n        for (int i = 0; i < seed_count; i++) {\n            seed_values[i] = 0;\n            for (int j = 0; j < M; j++) {\n                seed_values[i] += seeds[i][j];\n            }\n        }\n        \n        // Simple strategy: select top 36 seeds by value\n        vector<int> indices(seed_count);\n        for (int i = 0; i < seed_count; i++) {\n            indices[i] = i;\n        }\n        \n        // Sort by value (stable sort)\n        sort(indices.begin(), indices.end(), [&](int a, int b) {\n            return seed_values[a] > seed_values[b];\n        });\n        \n        // Create grid using top seeds\n        vector<vector<int>> grid(N, vector<int>(N));\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int pos = i * N + j;\n                if (pos < 36) {  // Ensure we don't go out of bounds\n                    grid[i][j] = indices[pos];\n                } else {\n                    grid[i][j] = indices[pos % 36];\n                }\n            }\n        }\n        \n        // Output grid\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << grid[i][j];\n                if (j < N - 1) cout << \" \";\n            }\n            cout << endl;\n        }\n        cout.flush();\n        \n        // Read new seeds\n        for (int i = 0; i < seed_count; i++) {\n            for (int j = 0; j < M; j++) {\n                cin >> seeds[i][j];\n            }\n        }\n    }\n    \n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, V;\nvector<string> initial_s, target_t;\nvector<string> current_grid; // Track current state\nvector<vector<int>> children;\nvector<int> parent;\nvector<int> edge_length;\nint root_x, root_y;\n\n// Track current positions of all vertices\nvector<pair<int, int>> vertex_positions;\nvector<int> edge_directions;\n\n// Track held takoyaki\nvector<bool> holding_takoyaki;\n\n// Find positions of 1s in grid\nvector<pair<int, int>> find_positions(const vector<string>& grid) {\n    vector<pair<int, int>> positions;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] == '1') {\n                positions.push_back({i, j});\n            }\n        }\n    }\n    return positions;\n}\n\n// Calculate position of vertex based on parent and edge configuration\npair<int, int> calculate_position(int v) {\n    if (v == 0) return {root_x, root_y};\n    \n    int p = parent[v];\n    auto parent_pos = vertex_positions[p];\n    int dir = edge_directions[v];\n    int len = edge_length[v];\n    \n    int dx[] = {0, 1, 0, -1};\n    int dy[] = {1, 0, -1, 0};\n    \n    return {parent_pos.first + dx[dir] * len, parent_pos.second + dy[dir] * len};\n}\n\n// Update all positions after movement/rotation\nvoid update_positions() {\n    for (int i = 0; i < V; i++) {\n        vertex_positions[i] = calculate_position(i);\n    }\n}\n\n// Build a compact tree with shorter edges\nvoid design_arm() {\n    children.resize(V);\n    parent.resize(V, -1);\n    edge_length.resize(V, 1);\n    vertex_positions.resize(V);\n    edge_directions.resize(V, 0);\n    holding_takoyaki.resize(V, false);\n    \n    // Create a simple structure with clear fingertips\n    if (V >= 3) {\n        // Root -> intermediate -> fingertip structure\n        for (int i = 1; i < V; i++) {\n            parent[i] = i - 1;\n            edge_length[i] = min(2, N / 3);\n            children[i-1].push_back(i);\n        }\n    } else {\n        // Simple chain for small V\n        for (int i = 1; i < V; i++) {\n            parent[i] = 0;\n            edge_length[i] = min(2, N / 3);\n            children[0].push_back(i);\n        }\n    }\n    \n    // Place root in center\n    root_x = N / 2;\n    root_y = N / 2;\n    \n    update_positions();\n}\n\n// Get all leaf nodes (fingertips)\nvector<int> get_fingertips() {\n    vector<int> fingertips;\n    for (int i = 0; i < V; i++) {\n        if (children[i].empty()) {\n            fingertips.push_back(i);\n        }\n    }\n    return fingertips;\n}\n\n// Check if position is valid and contains takoyaki\nbool can_grab_at(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N && current_grid[x][y] == '1';\n}\n\n// Check if position is valid and empty for placement\nbool can_release_at(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N && current_grid[x][y] == '0' && target_t[x][y] == '1';\n}\n\n// Generate intelligent operations\nvector<string> generate_operations() {\n    vector<string> ops;\n    vector<int> fingertips = get_fingertips();\n    vector<pair<int, int>> sources = find_positions(initial_s);\n    vector<pair<int, int>> targets = find_positions(target_t);\n    \n    // Create mapping from positions to track progress\n    set<pair<int, int>> remaining_sources;\n    for (auto& pos : sources) remaining_sources.insert(pos);\n    \n    int turn_count = 0;\n    const int max_turns = 50000;\n    \n    // Systematic coverage with intelligent grab/release\n    for (int sweep = 0; sweep < 4 && turn_count < max_turns; sweep++) {\n        // Spiral inward from corners\n        for (int step = 0; step < N && turn_count < max_turns; step++) {\n            for (int inner = 0; inner < 4 && turn_count < max_turns; inner++) {\n                string op(2 * V, '.');\n                \n                // Move in systematic pattern\n                int target_x = (sweep == 0) ? step : (sweep == 1) ? N-1-step : (sweep == 2) ? step : N-1-step;\n                int target_y = (inner * N/4) % N;\n                \n                // Move root toward target\n                if (root_x < target_x && root_x + 1 < N) {\n                    root_x++;\n                    op[0] = 'D';\n                } else if (root_x > target_x && root_x - 1 >= 0) {\n                    root_x--;\n                    op[0] = 'U';\n                } else if (root_y < target_y && root_y + 1 < N) {\n                    root_y++;\n                    op[0] = 'R';\n                } else if (root_y > target_y && root_y - 1 >= 0) {\n                    root_y--;\n                    op[0] = 'L';\n                }\n                \n                update_positions();\n                \n                // Check each fingertip for possible actions\n                for (int fingertip : fingertips) {\n                    auto pos = vertex_positions[fingertip];\n                    int x = pos.first, y = pos.second;\n                    \n                    if (!holding_takoyaki[fingertip] && can_grab_at(x, y)) {\n                        // Grab takoyaki\n                        op[V + fingertip] = 'P';\n                        holding_takoyaki[fingertip] = true;\n                        current_grid[x][y] = '0';\n                        remaining_sources.erase({x, y});\n                        break; // Only one action per turn\n                    } else if (holding_takoyaki[fingertip] && can_release_at(x, y)) {\n                        // Release takoyaki\n                        op[V + fingertip] = 'P';\n                        holding_takoyaki[fingertip] = false;\n                        current_grid[x][y] = '1';\n                        break; // Only one action per turn\n                    }\n                }\n                \n                ops.push_back(op);\n                turn_count++;\n            }\n        }\n    }\n    \n    return ops;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> V;\n    \n    initial_s.resize(N);\n    target_t.resize(N);\n    \n    for (int i = 0; i < N; i++) {\n        cin >> initial_s[i];\n    }\n    for (int i = 0; i < N; i++) {\n        cin >> target_t[i];\n    }\n    \n    // Initialize current grid\n    current_grid = initial_s;\n    \n    // Design and output arm\n    design_arm();\n    \n    cout << V << \"\\n\";\n    for (int i = 1; i < V; i++) {\n        cout << parent[i] << \" \" << edge_length[i] << \"\\n\";\n    }\n    cout << root_x << \" \" << root_y << \"\\n\";\n    \n    // Generate and output operations\n    auto operations = generate_operations();\n    \n    for (const auto& op : operations) {\n        cout << op << \"\\n\";\n    }\n    \n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    Point(int x = 0, int y = 0) : x(x), y(y) {}\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\nstruct Fish {\n    int x, y, type;\n    Fish(int x = 0, int y = 0, int type = 0) : x(x), y(y), type(type) {}\n};\n\nint N;\nvector<Fish> fishes;\nvector<Point> polygon;\n\n// Ray casting algorithm for point-in-polygon\nbool pointInPolygon(int x, int y, const vector<Point>& poly) {\n    int n = poly.size();\n    bool inside = false;\n    \n    for (int i = 0, j = n - 1; i < n; j = i++) {\n        if (((poly[i].y > y) != (poly[j].y > y)) &&\n            (x < (poly[j].x - poly[i].x) * (y - poly[i].y) / (poly[j].y - poly[i].y) + poly[i].x)) {\n            inside = !inside;\n        }\n    }\n    return inside;\n}\n\n// Count fish inside polygon\npair<int,int> countFishInPolygon(const vector<Point>& poly) {\n    int mackerels = 0, sardines = 0;\n    for (const auto& fish : fishes) {\n        if (pointInPolygon(fish.x, fish.y, poly)) {\n            if (fish.type == 0) mackerels++;\n            else sardines++;\n        }\n    }\n    return {mackerels, sardines};\n}\n\n// Calculate polygon perimeter\nint calculatePerimeter(const vector<Point>& poly) {\n    int perimeter = 0;\n    int n = poly.size();\n    for (int i = 0; i < n; i++) {\n        int j = (i + 1) % n;\n        perimeter += abs(poly[j].x - poly[i].x) + abs(poly[j].y - poly[i].y);\n    }\n    return perimeter;\n}\n\n// Create rectangle polygon\nvector<Point> createRectangle(int x1, int y1, int x2, int y2) {\n    return {Point(x1, y1), Point(x2, y1), Point(x2, y2), Point(x1, y2)};\n}\n\n// HIGH-PERFORMANCE region counting - optimized from our 66k solution\npair<int,int> countFishInRegion(int x1, int y1, int x2, int y2) {\n    int mackerels = 0, sardines = 0;\n    \n    // Optimized loop with likely branch prediction hints\n    for (const auto& fish : fishes) {\n        if (fish.x >= x1 && fish.x <= x2 && fish.y >= y1 && fish.y <= y2) {\n            if (fish.type == 0) mackerels++;\n            else sardines++;\n        }\n    }\n    \n    return {mackerels, sardines};\n}\n\n// Find HIGH-PERFORMANCE rectangles - optimized from 66k solution\nvector<tuple<int,int,int,int,int>> findHighPerformanceRectangles() {\n    vector<tuple<int,int,int,int,int>> rectangles;\n    \n    // Use the exact sizes that gave us 66k - these work!\n    const int SIZES[] = {8000, 12000, 16000, 20000, 24000, 30000};\n    \n    for (int size : SIZES) {\n        int step = size / 3; // This step size worked perfectly\n        \n        for (int x = 0; x + size <= 100000; x += step) {\n            for (int y = 0; y + size <= 100000; y += step) {\n                int x2 = x + size;\n                int y2 = y + size;\n                \n                auto [mackerels, sardines] = countFishInRegion(x, y, x2, y2);\n                \n                // Use the exact threshold that gave us 66k\n                if (mackerels > 15 && mackerels > sardines) {\n                    int score = max(0, mackerels - sardines + 1);\n                    rectangles.push_back(make_tuple(x, y, x2, y2, score));\n                    \n                    // Keep only top performers for speed\n                    if (rectangles.size() > 100) {\n                        sort(rectangles.begin(), rectangles.end(), \n                             [](const auto& a, const auto& b) { return get<4>(a) > get<4>(b); });\n                        rectangles.resize(50); // Keep top 50\n                    }\n                }\n            }\n        }\n    }\n    \n    // Final sort\n    sort(rectangles.begin(), rectangles.end(), \n         [](const auto& a, const auto& b) { return get<4>(a) > get<4>(b); });\n    \n    return rectangles;\n}\n\n// ELITE sardine detection - optimized from our successful approach\nvector<Point> createEliteSardineAwareRectangle(int x1, int y1, int x2, int y2) {\n    auto base_rect = createRectangle(x1, y1, x2, y2);\n    auto [base_m, base_s] = countFishInPolygon(base_rect);\n    int base_score = max(0, base_m - base_s + 1);\n    \n    // Elite edge analysis - the approach that gave us 66k\n    int margin_size = max(1500, min(x2 - x1, y2 - y1) / 5);\n    \n    int sardine_left = 0, sardine_right = 0, sardine_top = 0, sardine_bottom = 0;\n    \n    // Optimized single-pass counting\n    for (const auto& fish : fishes) {\n        if (fish.type == 1 && fish.x >= x1 && fish.x <= x2 && fish.y >= y1 && fish.y <= y2) {\n            if (fish.x < x1 + margin_size) sardine_left++;\n            if (fish.x > x2 - margin_size) sardine_right++;\n            if (fish.y < y1 + margin_size) sardine_bottom++;\n            if (fish.y > y2 - margin_size) sardine_top++;\n        }\n    }\n    \n    // Precise shrinking that gave us elite performance\n    int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;\n    int shrink_amount = margin_size / 2;\n    \n    if (sardine_left > 8) new_x1 = min(x2 - 5000, x1 + shrink_amount);\n    if (sardine_right > 8) new_x2 = max(x1 + 5000, x2 - shrink_amount);\n    if (sardine_bottom > 8) new_y1 = min(y2 - 5000, y1 + shrink_amount);\n    if (sardine_top > 8) new_y2 = max(y1 + 5000, y2 - shrink_amount);\n    \n    auto shrunk_rect = createRectangle(new_x1, new_y1, new_x2, new_y2);\n    auto [new_m, new_s] = countFishInPolygon(shrunk_rect);\n    int new_score = max(0, new_m - new_s + 1);\n    \n    return (new_score > base_score) ? shrunk_rect : base_rect;\n}\n\n// EFFICIENT perimeter optimization - fast but effective\nvector<Point> optimizeEfficientPerimeter(const vector<Point>& rect, int target_perimeter) {\n    if (rect.size() != 4) return rect;\n    \n    int x1 = rect[0].x, y1 = rect[0].y;\n    int x2 = rect[2].x, y2 = rect[2].y;\n    \n    auto [base_m, base_s] = countFishInPolygon(rect);\n    int base_score = max(0, base_m - base_s + 1);\n    int base_perimeter = calculatePerimeter(rect);\n    \n    if (base_perimeter >= target_perimeter) return rect;\n    \n    // Efficient expansion with good step size\n    int expand_budget = target_perimeter - base_perimeter;\n    \n    for (int expand = 1000; expand <= expand_budget/2; expand += 1000) {\n        int new_x1 = max(0, x1 - expand);\n        int new_y1 = max(0, y1 - expand);\n        int new_x2 = min(100000, x2 + expand);\n        int new_y2 = min(100000, y2 + expand);\n        \n        auto expanded = createRectangle(new_x1, new_y1, new_x2, new_y2);\n        auto [new_m, new_s] = countFishInPolygon(expanded);\n        int new_score = max(0, new_m - new_s + 1);\n        \n        if (new_score > base_score) {\n            return expanded;\n        }\n        \n        // Early termination for efficiency\n        if (expand > 3000 && new_score <= base_score * 1.02) break;\n    }\n    \n    return rect;\n}\n\n// Find ELITE regions by density analysis - fast version\nvector<Point> findEliteFast() {\n    // Quick density analysis\n    map<pair<int,int>, int> density_centers;\n    \n    for (const auto& fish : fishes) {\n        if (fish.type == 0) {\n            int cx = (fish.x / 4000) * 4000;\n            int cy = (fish.y / 4000) * 4000;\n            density_centers[{cx, cy}]++;\n        }\n    }\n    \n    // Find top density centers quickly\n    vector<pair<pair<int,int>, int>> top_centers;\n    for (const auto& [center, count] : density_centers) {\n        if (count > 5) { // Only good centers\n            top_centers.push_back({center, count});\n        }\n    }\n    \n    if (top_centers.empty()) {\n        return createRectangle(30000, 30000, 90000, 90000);\n    }\n    \n    sort(top_centers.begin(), top_centers.end(), \n         [](const auto& a, const auto& b) { return a.second > b.second; });\n    \n    // Optimize around top center with proven sizes\n    auto [best_center, count] = top_centers[0];\n    int center_x = best_center.first + 2000;\n    int center_y = best_center.second + 2000;\n    \n    // Use the sizes that gave us 66k - these work perfectly!\n    const int SIZES[] = {12000, 16000, 20000, 24000, 28000};\n    int best_score = -1;\n    int best_x1 = 30000, best_y1 = 30000, best_x2 = 70000, best_y2 = 70000;\n    \n    for (int size : SIZES) {\n        int half = size / 2;\n        int x1 = max(0, center_x - half);\n        int y1 = max(0, center_y - half);\n        int x2 = min(100000, center_x + half);\n        int y2 = min(100000, center_y + half);\n        \n        auto [m, s] = countFishInRegion(x1, y1, x2, y2);\n        int score = max(0, m - s + 1);\n        \n        if (score > best_score) {\n            best_score = score;\n            best_x1 = x1; best_y1 = y1; best_x2 = x2; best_y2 = y2;\n        }\n    }\n    \n    return createRectangle(best_x1, best_y1, best_x2, best_y2);\n}\n\n// Find OPTIMAL high-performance rectangle\nvector<Point> findOptimalHighPerformance() {\n    auto hp_rects = findHighPerformanceRectangles();\n    \n    if (hp_rects.empty()) {\n        return findEliteFast();\n    }\n    \n    // Take the best high-performance rectangle and optimize it\n    auto best_rect = hp_rects[0];\n    int x1 = get<0>(best_rect), y1 = get<1>(best_rect);\n    int x2 = get<2>(best_rect), y2 = get<3>(best_rect);\n    \n    // Create elite sardine-aware version\n    auto optimized = createEliteSardineAwareRectangle(x1, y1, x2, y2);\n    \n    // Efficient perimeter optimization\n    auto final_rect = optimizeEfficientPerimeter(optimized, 365000);\n    \n    return final_rect;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    \n    // Read fish data\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        fishes.push_back({x, y, 0});\n    }\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        fishes.push_back({x, y, 1});\n    }\n    \n    // Find optimal polygon using HIGH-PERFORMANCE algorithm\n    polygon = findOptimalHighPerformance();\n    \n    // Alternative: try elite approach if main one underperforms\n    auto [m1, s1] = countFishInPolygon(polygon);\n    if (max(0, m1 - s1 + 1) < 800) { // If underperforming\n        auto elite = findEliteFast();\n        auto [m2, s2] = countFishInPolygon(elite);\n        if (max(0, m2 - s2 + 1) > max(0, m1 - s1 + 1)) {\n            polygon = elite;\n        }\n    }\n    \n    // Final validation\n    if (polygon.size() != 4) {\n        polygon = createRectangle(35000, 35000, 95000, 95000);\n    }\n    \n    // Remove consecutive duplicates\n    vector<Point> cleaned;\n    for (size_t i = 0; i < polygon.size(); i++) {\n        size_t next = (i + 1) % polygon.size();\n        if (!(polygon[i] == polygon[next])) {\n            cleaned.push_back(polygon[i]);\n        }\n    }\n    polygon = cleaned;\n    \n    if (polygon.size() != 4) {\n        polygon = createRectangle(35000, 35000, 95000, 95000);\n    }\n    \n    cout << polygon.size() << \"\\n\";\n    for (const auto& p : polygon) {\n        cout << p.x << \" \" << p.y << \"\\n\";\n    }\n    \n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\n#include <random>\n#include <chrono>\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint randint(int a, int b) {\n    return uniform_int_distribution<int>(a, b)(rng);\n}\n\nstruct Rect {\n    long long w, h;\n    int idx;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T, sigma;\n    cin >> N >> T >> sigma;\n    vector<Rect> rects(N);\n    for (int i = 0; i < N; i++) {\n        cin >> rects[i].w >> rects[i].h;\n        rects[i].idx = i;\n    }\n\n    const int tries = 200;\n    long long best_obs = LLONG_MAX;\n    vector<tuple<int, int, char, int>> best_seq;\n\n    for (int turn = 0; turn < T; turn++) {\n        const int n = N;\n        vector<long long> xleft(n), ytop(n), width(n), height(n);\n        long long curW = 0, curH = 0;\n        vector<tuple<int, int, char, int>> seq;\n\n        for (int i = 0; i < n; i++) {\n            long long w0 = rects[i].w;\n            long long h0 = rects[i].h;\n\n            int best_r = 0;\n            char best_d = 'U';\n            int best_b = -1;\n            long long best_WH = LLONG_MAX;\n\n            for (int t = 0; t < tries; t++) {\n                int r = randint(0,1);\n                long long wi = (r ? h0 : w0);\n                long long hi = (r ? w0 : h0);\n\n                char d = (randint(0,1) ? 'U' : 'L');\n                int b = -1;\n                if (i > 0) b = randint(-1, i-1);\n\n                long long xi, yi;\n                if (d == 'U') {\n                    xi = (b==-1? 0 : xleft[b] + width[b]);\n                    yi = 0;\n                    for (int j = 0; j < i; j++) {\n                        long long x1 = xi, x2 = xi + wi;\n                        long long ox1 = xleft[j], ox2 = xleft[j] + width[j];\n                        if (x2 > ox1 && x1 < ox2) yi = max(yi, ytop[j] + height[j]);\n                    }\n                } else {\n                    yi = (b==-1? 0 : ytop[b] + height[b]);\n                    xi = 0;\n                    for (int j = 0; j < i; j++) {\n                        long long y1 = yi, y2 = yi + hi;\n                        long long oy1 = ytop[j], oy2 = ytop[j] + height[j];\n                        if (y2 > oy1 && y1 < oy2) xi = max(xi, xleft[j] + width[j]);\n                    }\n                }\n                long long newW = max(curW, xi + wi);\n                long long newH = max(curH, yi + hi);\n                long long WH = newW + newH;\n                if (WH < best_WH) {\n                    best_WH = WH;\n                    best_r = r;\n                    best_d = d;\n                    best_b = b;\n                }\n            }\n\n            long long wi = (best_r ? h0 : w0);\n            long long hi = (best_r ? w0 : h0);\n            long long xi, yi;\n            if (best_d == 'U') {\n                xi = (best_b==-1? 0 : xleft[best_b] + width[best_b]);\n                yi = 0;\n                for (int j = 0; j < i; j++) {\n                    long long x1 = xi, x2 = xi + wi;\n                    long long ox1 = xleft[j], ox2 = xleft[j] + width[j];\n                    if (x2 > ox1 && x1 < ox2) yi = max(yi, ytop[j] + height[j]);\n                }\n            } else {\n                yi = (best_b==-1? 0 : ytop[best_b] + height[best_b]);\n                xi = 0;\n                for (int j = 0; j < i; j++) {\n                    long long y1 = yi, y2 = yi + hi;\n                    long long oy1 = ytop[j], oy2 = ytop[j] + height[j];\n                    if (y2 > oy1 && y1 < oy2) xi = max(xi, xleft[j] + width[j]);\n                }\n            }\n            xleft[i] = xi;\n            ytop[i] = yi;\n            width[i] = wi;\n            height[i] = hi;\n            curW = max(curW, xi + wi);\n            curH = max(curH, yi + hi);\n            seq.emplace_back(i, best_r, best_d, best_b);\n        }\n\n        // exploration / exploitation\n        if (turn >= T / 2 && !best_seq.empty()) {\n            if (randint(0,2) == 0) {\n                // small perturbation\n                auto tmp = best_seq;\n                for (int rep = 0; rep < 3; rep++) {\n                    int k = randint(0, N-1);\n                    auto &[p, r, d, b] = tmp[k];\n                    r ^= 1;\n                    if (k > 0) b = randint(-1, k-1);\n                }\n                cout << N << '\\n';\n                for (auto [pp,rr,dd,bb] : tmp) cout << pp << ' ' << rr << ' ' << dd << ' ' << bb << '\\n';\n                cout.flush();\n            } else {\n                // best sequence\n                cout << N << '\\n';\n                for (auto [p,r,d,b] : best_seq) cout << p << ' ' << r << ' ' << d << ' ' << b << '\\n';\n                cout.flush();\n            }\n        } else {\n            cout << N << '\\n';\n            for (auto [p,r,d,b] : seq) cout << p << ' ' << r << ' ' << d << ' ' << b << '\\n';\n            cout.flush();\n        }\n\n        long long Wp, Hp;\n        cin >> Wp >> Hp;\n        long long obs = Wp + Hp;\n        if (obs < best_obs) {\n            best_obs = obs;\n            best_seq = seq;\n        }\n    }\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\n#include <atcoder/dsu>\nusing namespace std;\nusing namespace atcoder;\n\nusing int64 = long long;\nstatic const int MAXN = 1005;\nstatic const int MAXH = 6;          // H = 5\n\nint N, M, H;\nint A[MAXN];\nvector<int> G[MAXN];\n\nint par[MAXN], depth[MAXN];\nint64 contrib[MAXN];\n\nint64 best_total;\nint best_par[MAXN];\n\nchrono::steady_clock::time_point start;\ndouble elapsed() {\n    return chrono::duration<double>(chrono::steady_clock::now() - start).count();\n}\n\ninline void update_contrib(int v) {\n    contrib[v] = int64(depth[v] + 1) * A[v];\n}\n\n/* ---------- rebuild DSU from current par[] ---------- */\ndsu rebuild_uf() {\n    dsu uf(N);\n    for (int i = 0; i < N; ++i)\n        if (par[i] != -1) uf.merge(i, par[i]);\n    return uf;\n}\n\n/* ---------- bounded-height BFS forest (never exceeds H) ---------- */\nvoid bounded_bfs(int r) {\n    static vector<char> inTree(N, 0);\n    for (int i = 0; i < N; ++i) inTree[i] = 0;\n    queue<int> q;\n    par[r] = -1; depth[r] = 0; inTree[r] = 1; update_contrib(r);\n    q.push(r);\n    while (!q.empty()) {\n        int v = q.front(); q.pop();\n        if (depth[v] == H) continue;\n        for (int u : G[v])\n            if (!inTree[u]) {\n                inTree[u] = 1;\n                par[u] = v;\n                depth[u] = depth[v] + 1;\n                update_contrib(u);\n                q.push(u);\n            }\n    }\n}\n\n/* ---------- validate and re-split component if any vertex > H ---------- */\nvoid validate_and_resplit(int r) {\n    static vector<int> comp;\n    comp.clear();\n    /* collect component */\n    queue<int> q; q.push(r);\n    vector<char> vis(N, 0); vis[r] = 1;\n    while (!q.empty()) {\n        int v = q.front(); q.pop();\n        comp.push_back(v);\n        for (int u : G[v])\n            if (par[u] == v && !vis[u]) { vis[u] = 1; q.push(u); }\n    }\n    /* check heights */\n    bool ok = true;\n    for (int v : comp) if (depth[v] > H) { ok = false; break; }\n    if (ok) return;\n    /* re-split into forest of depth \u2264 H */\n    for (int v : comp) par[v] = -2;\n    for (int v : comp) if (par[v] == -2) bounded_bfs(v);\n}\n\n/* ---------- initial forest ---------- */\nvoid build_random() {\n    dsu uf(N);\n    for (int i = 0; i < N; ++i) par[i] = -2;\n    auto att = [&](int v, int p, int d) {\n        par[v] = p; depth[v] = d; update_contrib(v);\n        if (p != -1) uf.merge(v, p);\n    };\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    shuffle(ord.begin(), ord.end(), rng);\n    sort(ord.begin(), ord.end(), [&](int u, int v){ return A[u] > A[v]; });\n\n    for (int s : ord) if (par[s] == -2) {\n        att(s, -1, 0);\n        queue<int> q; q.push(s);\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            if (depth[v] == H) continue;\n            for (int u : G[v])\n                if (par[u] == -2) {\n                    att(u, v, depth[v] + 1);\n                    q.push(u);\n                }\n        }\n    }\n    /* validate every component once */\n    for (int i = 0; i < N; ++i) if (par[i] == -1) validate_and_resplit(i);\n}\n\n/* ---------- local moves: cycle + height safe ---------- */\nvoid local_moves() {\n    mt19937 rng(1234567 + int(elapsed() * 1e9));\n    vector<int> verts(N);\n    iota(verts.begin(), verts.end(), 0);\n    while (elapsed() < 1.93) {\n        shuffle(verts.begin(), verts.end(), rng);\n        bool improved = false;\n        for (int v : verts) if (par[v] != -1) {\n            int old_p = par[v], old_d = depth[v];\n            int64 old_delta = -contrib[v];\n\n            /* try root */\n            int64 best_inc = int64(1) * A[v] + old_delta;\n            int best_p = -1, best_d = 0;\n\n            /* try neighbours */\n            for (int w : G[v]) if (w != old_p) {\n                int nd = depth[w] + 1;\n                if (nd > H) continue;                 // HEIGHT LIMIT\n                int64 inc = int64(nd + 1) * A[v] - contrib[v];\n                if (inc > best_inc) { best_inc = inc; best_p = w; best_d = nd; }\n            }\n\n            /* cycle check for best_p != -1 */\n            if (best_p != -1) {\n                dsu uf = rebuild_uf();\n                if (uf.same(v, best_p)) best_p = -1, best_d = 0, best_inc = int64(1)*A[v] + old_delta;\n            }\n\n            if (best_inc > 0) {\n                par[v] = best_p; depth[v] = best_d; update_contrib(v);\n                /* validate both old and new component */\n                int root_old = old_p;\n                while (root_old != -1 && par[root_old] != -1) root_old = par[root_old];\n                if (root_old != -1) validate_and_resplit(root_old);\n                int root_new = v;\n                while (par[root_new] != -1) root_new = par[root_new];\n                validate_and_resplit(root_new);\n                improved = true;\n            } else {\n                /* roll back */\n                par[v] = old_p; depth[v] = old_d; update_contrib(v);\n            }\n        }\n        if (!improved) break;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    start = chrono::steady_clock::now();\n\n    cin >> N >> M >> H;\n    for (int i = 0; i < N; ++i) cin >> A[i];\n    for (int i = 0; i < M; ++i) {\n        int u, v; cin >> u >> v;\n        G[u].push_back(v); G[v].push_back(u);\n    }\n    double x, y;\n    for (int i = 0; i < N; ++i) cin >> x >> y;   // discard\n\n    best_total = -1;\n    while (elapsed() < 1.95) {\n        build_random();\n        local_moves();\n        int64 cur = 0;\n        for (int i = 0; i < N; ++i) cur += contrib[i];\n        if (cur > best_total) {\n            best_total = cur;\n            copy(par, par + N, best_par);\n        }\n    }\n    copy(best_par, best_par + N, par);\n    for (int i = 0; i < N; ++i) cout << par[i] << (i + 1 < N ? ' ' : '\\n');\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const int FIXED_N = 20;\nstatic const int NONE = -1;\nchar board[FIXED_N][FIXED_N + 1];\nint  N;\n\nstatic const int L = 0, R = 1, U = 2, D = 3;\nstatic const int BACK[4] = {1, 0, 3, 2};\nstatic const char DIRC[4] = {'L','R','U','D'};\n\nint oni_r[40], oni_c[40], oni_cnt;\nint fuku_r[40], fuku_c[40], fuku_cnt;\nint safe_dir[40];               // current best direction\nint cnt[4][FIXED_N];            // counters\nint total_moves;                // 2 * non_zero\n\nmt19937 rng(12345678);\n\ninline int non_zero() {\n    int nz = 0;\n    for (int d = 0; d < 4; ++d)\n        for (int p = 0; p < FIXED_N; ++p)\n            if (cnt[d][p]) ++nz;\n    return nz;\n}\n\n// ---------- rebuild sequence ----------\nvoid build_sequence(vector<pair<char,int>>& out) {\n    out.clear();\n    static char cur[FIXED_N][FIXED_N + 1];\n    for (int i = 0; i < FIXED_N; ++i) fill(cur[i], cur[i] + FIXED_N, '.');\n    for (int k = 0; k < fuku_cnt; ++k) cur[fuku_r[k]][fuku_c[k]] = 'o';\n    for (int k = 0; k < oni_cnt; ++k)  cur[oni_r[k]][oni_c[k]]  = 'x';\n\n    auto apply = [&](int d, int p) {\n        out.emplace_back(DIRC[d], p);\n        if (d == L) {\n            for (int j = 0; j + 1 < FIXED_N; ++j) cur[p][j] = cur[p][j + 1];\n            cur[p][FIXED_N - 1] = '.';\n        } else if (d == R) {\n            for (int j = FIXED_N - 1; j > 0; --j) cur[p][j] = cur[p][j - 1];\n            cur[p][0] = '.';\n        } else if (d == U) {\n            for (int i = 0; i + 1 < FIXED_N; ++i) cur[i][p] = cur[i + 1][p];\n            cur[FIXED_N - 1][p] = '.';\n        } else { // D\n            for (int i = FIXED_N - 1; i > 0; --i) cur[i][p] = cur[i - 1][p];\n            cur[0][p] = '.';\n        }\n    };\n\n    while (true) {\n        int best = 0, bd = NONE, bp = NONE;\n        for (int d = 0; d < 4; ++d)\n            for (int p = 0; p < FIXED_N; ++p)\n                if (cnt[d][p] > best) { best = cnt[d][p]; bd = d; bp = p; }\n        if (best == 0) break;\n        int len = (bd < 2 ? FIXED_N : FIXED_N);\n        for (int t = 0; t < len; ++t) apply(bd, bp);\n        for (int t = 0; t < len; ++t) apply(BACK[bd], bp);\n        cnt[bd][bp] = 0;\n    }\n}\n\n// ---------- 1 000 randomised greedy starters ----------\nvector<pair<char,int>> best_starter;\nint best_T;\n\nvoid randomised_greedy_starters() {\n    best_T = INT_MAX;\n    uniform_int_distribution<int> uid_d(0, 3);\n    for (int run = 0; run < 1000; ++run) {\n        // randomise safe-dir tie-breaking\n        for (int k = 0; k < oni_cnt; ++k) {\n            int i = oni_r[k], j = oni_c[k];\n            vector<int> safe;\n            for (int d = 0; d < 4; ++d) {\n                bool ok = true;\n                if (d == L){ for(int t=j-1;t>=0;--t)if(board[i][t]=='o')ok=false; }\n                else if(d==R){ for(int t=j+1;t<N;++t)if(board[i][t]=='o')ok=false; }\n                else if(d==U){ for(int t=i-1;t>=0;--t)if(board[t][j]=='o')ok=false; }\n                else { for(int t=i+1;t<N;++t)if(board[t][j]=='o')ok=false; }\n                if (ok) safe.push_back(d);\n            }\n            safe_dir[k] = safe[uid_d(rng) % safe.size()];\n        }\n        memset(cnt, 0, sizeof(cnt));\n        for (int k = 0; k < oni_cnt; ++k) {\n            int d = safe_dir[k];\n            int rc = (d < 2 ? oni_r[k] : oni_c[k]);\n            ++cnt[d][rc];\n        }\n        int T = 2 * non_zero();\n        if (T < best_T) {\n            best_T = T;\n            build_sequence(best_starter);\n        }\n    }\n}\n\n// ---------- main ----------\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    assert(N == FIXED_N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n\n    oni_cnt = fuku_cnt = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 'x') {\n                oni_r[oni_cnt] = i;\n                oni_c[oni_cnt] = j;\n                ++oni_cnt;\n            } else if (board[i][j] == 'o') {\n                fuku_r[fuku_cnt] = i;\n                fuku_c[fuku_cnt] = j;\n                ++fuku_cnt;\n            }\n        }\n\n    // 1. fast randomised starter\n    randomised_greedy_starters();\n    // load best into counters\n    memset(cnt, 0, sizeof(cnt));\n    for (int k = 0; k < oni_cnt; ++k) {\n        int d = safe_dir[k];\n        int rc = (d < 2 ? oni_r[k] : oni_c[k]);\n        ++cnt[d][rc];\n    }\n    total_moves = best_T;\n\n    // 2. SA with single-flip + order-swap\n    uniform_int_distribution<int> uid_k(0, oni_cnt - 1);\n    uniform_int_distribution<int> uid_d(0, 3);\n    uniform_int_distribution<int> uid_op(0, 1); // 0=flip, 1=swap\n\n    const int ITER = 200000;\n    for (int it = 0; it < ITER; ++it) {\n        int op = uid_op(rng);\n        if (op == 0) {\n            // single direction flip\n            int k = uid_k(rng);\n            int i = oni_r[k], j = oni_c[k];\n            int old_d = safe_dir[k];\n            int new_d = uid_d(rng);\n            if (new_d == old_d) continue;\n            bool ok = true;\n            if (new_d == L){ for(int t=j-1;t>=0;--t)if(board[i][t]=='o')ok=false; }\n            else if(new_d==R){ for(int t=j+1;t<N;++t)if(board[i][t]=='o')ok=false; }\n            else if(new_d==U){ for(int t=i-1;t>=0;--t)if(board[t][j]=='o')ok=false; }\n            else { for(int t=i+1;t<N;++t)if(board[t][j]=='o')ok=false; }\n            if (!ok) continue;\n\n            int rc_old = (old_d < 2 ? i : j);\n            int rc_new = (new_d < 2 ? i : j);\n\n            int delta = 0;\n            if (cnt[old_d][rc_old] == 1) delta -= 2;\n            --cnt[old_d][rc_old];\n            if (cnt[old_d][rc_old] == 0) delta += 2;\n\n            if (cnt[new_d][rc_new] == 0) delta -= 2;\n            ++cnt[new_d][rc_new];\n            if (cnt[new_d][rc_new] == 1) delta += 2;\n\n            int new_total = total_moves + delta;\n            if (new_total <= total_moves) {\n                total_moves = new_total;\n                safe_dir[k] = new_d;\n            } else {\n                --cnt[new_d][rc_new];\n                ++cnt[old_d][rc_old];\n            }\n        } else {\n            // swap deletion order of two demons\n            int k1 = uid_k(rng), k2 = uid_k(rng);\n            if (k1 == k2) continue;\n            int d1 = safe_dir[k1], d2 = safe_dir[k2];\n            int rc1 = (d1 < 2 ? oni_r[k1] : oni_c[k1]);\n            int rc2 = (d2 < 2 ? oni_r[k2] : oni_c[k2]);\n            if (rc1 == rc2 && d1 == d2) continue; // same line, same dir \u2013 no change\n\n            // flip them\n            safe_dir[k1] = d2; safe_dir[k2] = d1;\n            memset(cnt, 0, sizeof(cnt));\n            for (int k = 0; k < oni_cnt; ++k) {\n                int d = safe_dir[k];\n                int rc = (d < 2 ? oni_r[k] : oni_c[k]);\n                ++cnt[d][rc];\n            }\n            int new_total = 2 * non_zero();\n            if (new_total <= total_moves) {\n                total_moves = new_total;\n            } else {\n                // rollback\n                safe_dir[k1] = d1; safe_dir[k2] = d2;\n                memset(cnt, 0, sizeof(cnt));\n                for (int k = 0; k < oni_cnt; ++k) {\n                    int d = safe_dir[k];\n                    int rc = (d < 2 ? oni_r[k] : oni_c[k]);\n                    ++cnt[d][rc];\n                }\n            }\n        }\n    }\n\n    // final rebuild\n    memset(cnt, 0, sizeof(cnt));\n    for (int k = 0; k < oni_cnt; ++k) {\n        int d = safe_dir[k];\n        int rc = (d < 2 ? oni_r[k] : oni_c[k]);\n        ++cnt[d][rc];\n    }\n    build_sequence(best_starter);\n    for (auto [d, p] : best_starter) cout << d << ' ' << p << '\\n';\n    return 0;\n}","ahc044":"#include <iostream>\n#include <vector>\n#include <random>\n#include <algorithm>\n#include <chrono>\n\nusing namespace std;\n\nconst int N = 100;\nconst int L = 500000;\n\nint T[N];\nint a[N], b[N];\nint t[N];\nint current_sequence[L];\n\nint simulate() {\n    fill(t, t + N, 0);\n    int current = 0;\n    t[current] = 1;\n    for (int week = 1; week < L; ++week) {\n        int count = t[current];\n        int next;\n        if (count % 2 == 1) {\n            next = a[current];\n        } else {\n            next = b[current];\n        }\n        t[next]++;\n        current = next;\n    }\n    int error = 0;\n    for (int i = 0; i < N; ++i) {\n        error += abs(t[i] - T[i]);\n    }\n    return error;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    for (int i = 0; i < N; ++i) {\n        cin >> T[i];\n    }\n\n    // Initial greedy assignment\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    for (int i = 0; i < N; ++i) {\n        a[i] = uniform_int_distribution<int>(0, N - 1)(rng);\n        b[i] = uniform_int_distribution<int>(0, N - 1)(rng);\n    }\n\n    int best_error = simulate();\n    auto start = chrono::steady_clock::now();\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start).count() > 1800) {\n            break; // Stop after 1.8 seconds to ensure we don't exceed 2 seconds\n        }\n\n        int i = uniform_int_distribution<int>(0, N - 1)(rng);\n        int old_a = a[i], old_b = b[i];\n\n        // Try changing a[i] or b[i]\n        if (uniform_int_distribution<int>(0, 1)(rng) == 0) {\n            a[i] = uniform_int_distribution<int>(0, N - 1)(rng);\n        } else {\n            b[i] = uniform_int_distribution<int>(0, N - 1)(rng);\n        }\n\n        int new_error = simulate();\n        if (new_error < best_error) {\n            best_error = new_error;\n        } else {\n            // Revert\n            a[i] = old_a;\n            b[i] = old_b;\n        }\n    }\n\n    // Output the best found\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 City {\n    int id, lx, rx, ly, ry;\n    int cx() const { return (lx + rx) / 2; }\n    int cy() const { return (ly + ry) / 2; }\n};\n\nint N, M, Q, L, W;\nvector<int> G;\nvector<City> cities;\nvector<vector<int>> groups;\nvector<vector<pair<int, int>>> group_edges;\n\nvector<pair<int, int>> query(const vector<int>& c) {\n    cout << \"? \" << c.size();\n    for (int x : c) cout << \" \" << x;\n    cout << endl;\n    vector<pair<int, int>> edges;\n    for (int i = 0; i < c.size() - 1; ++i) {\n        int a, b;\n        cin >> a >> b;\n        edges.emplace_back(a, b);\n    }\n    return edges;\n}\n\nvoid answer() {\n    cout << \"!\" << endl;\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < groups[i].size(); ++j) {\n            if (j > 0) cout << \" \";\n            cout << groups[i][j];\n        }\n        cout << endl;\n        for (auto [a, b] : group_edges[i]) {\n            cout << a << \" \" << b << endl;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    cities.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> cities[i].lx >> cities[i].rx >> cities[i].ly >> cities[i].ry;\n        cities[i].id = i;\n    }\n\n    // Sort cities by center coordinates\n    sort(cities.begin(), cities.end(), [](const City& a, const City& b) {\n        if (a.cx() != b.cx()) return a.cx() < b.cx();\n        return a.cy() < b.cy();\n    });\n\n    // Assign to groups\n    groups.resize(M);\n    group_edges.resize(M);\n    int ptr = 0;\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < G[i]; ++j) {\n            groups[i].push_back(cities[ptr++].id);\n        }\n    }\n\n    // Use queries to get edges for each group\n    int queries_used = 0;\n    for (int i = 0; i < M; ++i) {\n        int sz = groups[i].size();\n        if (sz <= 1) continue;\n        // Use triplets to cover the group\n        for (int j = 0; j < sz - 1; j += 2) {\n            if (queries_used >= Q) break;\n            vector<int> c;\n            if (j + 2 < sz) {\n                c = {groups[i][j], groups[i][j+1], groups[i][j+2]};\n            } else {\n                c = {groups[i][j], groups[i][j+1]};\n            }\n            auto edges = query(c);\n            for (auto [a, b] : edges) {\n                group_edges[i].emplace_back(a, b);\n            }\n            queries_used++;\n        }\n        // Ensure connectivity by adding edges if necessary\n        // This is a simple heuristic: connect in order\n        if (group_edges[i].size() < sz - 1) {\n            for (int j = 0; j < sz - 1; ++j) {\n                group_edges[i].emplace_back(groups[i][j], groups[i][j+1]);\n            }\n        }\n    }\n\n    answer();\n    return 0;\n}","ahc046":"#pragma GCC optimize(\"O3,unroll-loops\")\n#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nstatic const int N = 20;\nstatic const int M = 40;\nstatic const int LIMIT = 2*N*M;\n\nint target[M];\nint targetLeft;                      // how many still to visit\nbool blocked[N][N];                  // current wall state\nint  distSlide[N][N][4];             // dist to next block/border in 4 dirs\nint  di[] = {-1,1,0,0};\nint  dj[] = {0,0,-1,1};\nchar actionChar[] = {'M','S','A'};\nchar dirChar[]    = {'U','D','L','R'};\n\nstruct Step {\n    int i,j;\n    int g;\n    vector<pair<int,int>> pathActs; // (act,dir) pairs leading here\n    bool operator<(const Step& o) const { return g > o.g; }\n};\n\ninline bool inside(int i,int j){ return i>=0&&i<N&&j>=0&&j<N; }\n\nvoid rebuildDistSlide(){\n    for(int i=0;i<N;i++){\n        // up\n        for(int j=0;j<N;j++){\n            int d=0;\n            for(int ii=i-1;ii>=0;ii--){\n                if(blocked[ii][j]) break;\n                d++;\n            }\n            distSlide[i][j][0]=d;\n        }\n        // down\n        for(int j=0;j<N;j++){\n            int d=0;\n            for(int ii=i+1;ii<N;ii++){\n                if(blocked[ii][j]) break;\n                d++;\n            }\n            distSlide[i][j][1]=d;\n        }\n    }\n    for(int j=0;j<N;j++){\n        // left\n        for(int i=0;i<N;i++){\n            int d=0;\n            for(int jj=j-1;jj>=0;jj--){\n                if(blocked[i][jj]) break;\n                d++;\n            }\n            distSlide[i][j][2]=d;\n        }\n        // right\n        for(int i=0;i<N;i++){\n            int d=0;\n            for(int jj=j+1;jj<N;jj++){\n                if(blocked[i][jj]) break;\n                d++;\n            }\n            distSlide[i][j][3]=d;\n        }\n    }\n}\n\nint heuristic(int si,int sj,int ti,int tj){\n    return abs(si-ti)+abs(sj-tj);\n}\n\nvector<pair<int,int>> planSegment(int si,int sj,int ti,int tj){\n    priority_queue<Step> pq;\n    Step start{si,sj,0,{}};\n    pq.push(start);\n    static char vis[ N ][ N ];\n    memset(vis,0,sizeof(vis));\n    vis[si][sj]=1;\n    const int EXPAND = 20000;\n    int expanded = 0;\n    while(!pq.empty() && expanded < EXPAND){\n        Step cur = pq.top(); pq.pop();\n        expanded++;\n        if(cur.i==ti && cur.j==tj){\n            return cur.pathActs;\n        }\n        int g2 = cur.g+1;\n        for(int dir=0;dir<4;dir++){\n            int ni = cur.i + di[dir];\n            int nj = cur.j + dj[dir];\n            // 1) Move\n            if(inside(ni,nj) && !blocked[ni][nj] && !vis[ni][nj]){\n                vis[ni][nj]=1;\n                Step nxt = cur;\n                nxt.i=ni; nxt.j=nj; nxt.g=g2;\n                nxt.pathActs.emplace_back(0,dir);\n                pq.push(nxt);\n            }\n            // 2) Slide\n            int ds = distSlide[cur.i][cur.j][dir];\n            if(ds>0){\n                int ei = cur.i + di[dir]*ds;\n                int ej = cur.j + dj[dir]*ds;\n                if(!vis[ei][ej]){\n                    vis[ei][ej]=1;\n                    Step nxt = cur;\n                    nxt.i=ei; nxt.j=ej; nxt.g=g2;\n                    nxt.pathActs.emplace_back(1,dir);\n                    pq.push(nxt);\n                }\n            }\n            // 3) Alter\n            int bi = cur.i + di[dir];\n            int bj = cur.j + dj[dir];\n            if(inside(bi,bj)){\n                // toggle\n                blocked[bi][bj] ^= 1;\n                rebuildDistSlide();\n                Step nxt = cur;\n                nxt.g=g2;\n                nxt.pathActs.emplace_back(2,dir);\n                pq.push(nxt);\n                // undo\n                blocked[bi][bj] ^= 1;\n                rebuildDistSlide();\n            }\n        }\n    }\n    // fallback: plain Manhattan moves\n    vector<pair<int,int>> fallback;\n    int dx = ti - si;\n    int dy = tj - sj;\n    int px = si, py = sj;\n    while(px<ti){ px++; fallback.emplace_back(0,1); }\n    while(px>ti){ px--; fallback.emplace_back(0,0); }\n    while(py<tj){ py++; fallback.emplace_back(0,3); }\n    while(py>tj){ py--; fallback.emplace_back(0,2); }\n    return fallback;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int n,m;\n    cin >> n >> m;\n    assert(n==N && m==M);\n    int si,sj;\n    cin >> si >> sj;\n    vector<int> I(M),J(M);\n    for(int k=0;k<M;k++){\n        cin >> I[k] >> J[k];\n    }\n    // initialise\n    memset(blocked,0,sizeof(blocked));\n    rebuildDistSlide();\n    vector<pair<int,int>> fullPlan;\n    int ci=si, cj=sj;\n    for(int idx=0;idx<M;idx++){\n        int ti = I[idx];\n        int tj = J[idx];\n        auto seg = planSegment(ci,cj,ti,tj);\n        fullPlan.insert(fullPlan.end(), seg.begin(), seg.end());\n        // execute to update real state\n        for(auto [act,dir]: seg){\n            if(act==0){ // Move\n                ci += di[dir];\n                cj += dj[dir];\n            } else if(act==1){ // Slide\n                int ds = distSlide[ci][cj][dir];\n                ci += di[dir]*ds;\n                cj += dj[dir]*ds;\n            } else { // Alter\n                int bi = ci + di[dir];\n                int bj = cj + dj[dir];\n                blocked[bi][bj] ^= 1;\n                rebuildDistSlide();\n            }\n        }\n        assert(ci==ti && cj==tj);\n    }\n    // output\n    cout << fullPlan.size() << \"\\n\";\n    for(auto [act,dir]: fullPlan){\n        cout << actionChar[act] << \" \" << dirChar[dir] << \"\\n\";\n    }\n    return 0;\n}"}}}