{"model_name":"gpt-4.1","codes":{"1":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing i64 = int64_t;\n\nstruct Rect {\n    int x1, y1, x2, y2; // [x1,x2), [y1,y2)\n    i64 area() const { return i64(x2-x1) * i64(y2-y1); }\n    bool contains(double x, double y) const {\n        return x > x1 && x < x2 && y > y1 && y < y2;\n    }\n    bool overlap(const Rect& o) const {\n        return !(x2 <= o.x1 || x1 >= o.x2 || y2 <= o.y1 || y1 >= o.y2);\n    }\n};\n\nstruct Company {\n    int id, x, y;\n    i64 r;\n    Rect rect;\n};\n\nconstexpr int GRID_SIZE = 10000;\nconstexpr int MAX_TRY_AREA = 10;\nconstexpr int VARIANTS = 8;\n\nint n;\nvector<Company> companies;\nvector<Rect> placedRects;\n\n// Check overlap with existing placedRects\nbool checkOverlap(const Rect& r) {\n    for (const auto& o : placedRects)\n        if (r.overlap(o)) return true;\n    return false;\n}\n\n// Try to build a rectangle of area close to ri, containing (cx,cy)+0.5, not overlapping any in placedRects\nRect try_place(int cx, int cy, i64 ri) {\n    // Try almost-square sizes, widen search for best fit\n    int best_w = 0, best_h = 0, best_shift_x = 0, best_shift_y = 0;\n    double best_score = 1e9;\n    \n    vector<pair<int,int>> attempts;\n    int sqr = max(1, int(std::sqrt(ri)));\n    for (int dw = -2; dw <= 2; ++dw) {\n        int w = max(1, sqr + dw);\n        int h = max(1, int((ri + w-1)/w));\n        if (i64(w)*h >= ri) attempts.emplace_back(w,h);\n        if (i64(h)*w >= ri) attempts.emplace_back(h,w);\n    }\n    for (auto [w, h]: attempts) {\n        for (int dx=-1;dx<=1;++dx)for(int dy=-1;dy<=1;++dy){\n            int x1 = clamp(cx - w/2 + dx, 0, GRID_SIZE-w);\n            int y1 = clamp(cy - h/2 + dy, 0, GRID_SIZE-h);\n            int x2 = x1+w, y2 = y1+h;\n            Rect r{x1, y1, x2, y2};\n            // must contain target point\n            double xx = cx+0.5, yy = cy+0.5;\n            if (xx <= x1 || xx >= x2 || yy <= y1 || yy >= y2) continue;\n            if (checkOverlap(r)) continue;\n            // favor rectangle closest to area\n            double score = abs((double)r.area() - ri) + 0.1*(w-h)*(w-h);\n            if (score < best_score) {\n                best_score = score; best_w=w; best_h=h; best_shift_x=x1; best_shift_y=y1;\n            }\n        }\n    }\n    // If found feasible\n    if (best_score < 1e8) {\n        return Rect{best_shift_x, best_shift_y, best_shift_x+best_w, best_shift_y+best_h};\n    }\n    // fallback: return an invalid rectangle\n    return Rect{-1,-1,-1,-1};\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    cin >> n;\n    companies.resize(n);\n    for (int i = 0; i < n; ++i) {\n        int x, y; i64 r;\n        cin >> x >> y >> r;\n        companies[i] = Company{i, x, y, r, {}};\n    }\n\n    // Place biggest requests first\n    sort(companies.begin(), companies.end(), [&](const Company& a, const Company& b){\n        return a.r > b.r;\n    });\n\n    placedRects.clear();\n\n    for (auto& comp : companies) {\n        Rect rect;\n        i64 tr = comp.r;\n        // Try to assign area as close as possible, but allow up to 10% reduction if needed\n        int area_shrink = 0;\n        while (area_shrink < 15) {\n            i64 req_area = max(1LL, tr - tr * area_shrink / 100);\n            rect = try_place(comp.x, comp.y, req_area);\n            if (rect.x1 != -1)\n                break; // Success\n            area_shrink += 2;\n        }\n        if (rect.x1 == -1) {\n            // could not place, place a pixel at the position\n            rect = Rect{comp.x, comp.y, comp.x+1, comp.y+1};\n        }\n        comp.rect = rect;\n        placedRects.push_back(rect);\n    }\n\n    // Restore the original order\n    sort(companies.begin(), companies.end(), [&](const Company& a, const Company& b){\n        return a.id < b.id;\n    });\n\n    // Output\n    for (auto& comp : companies) {\n        auto& r = comp.rect;\n        cout << r.x1 << ' ' << r.y1 << ' ' << r.x2 << ' ' << r.y2 << '\\n';\n    }\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Directions: U, D, L, R\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\nconst char dch[4] = {'U', 'D', 'L', 'R'};\nconst int N = 50;\n\nstruct Tile {\n    vector<pair<int, int>> cells;       // All belonging cells\n    set<int> adj;                       // Adjacent tiles\n    int max_val = -1, max_cell_i = -1, max_cell_j = -1;\n};\n\nint si, sj;\nint t[N][N];      // tile id of (i,j)\nint p[N][N];      // score of (i,j)\nvector<Tile> tiles;\nint ntiles;\n\nvoid preprocess() {\n    // Build tile information (cells and adjacents)\n    map<int, vector<pair<int,int>>> tile_cells;\n    for(int i = 0; i < N; ++i) for(int j = 0; j < N; ++j)\n        tile_cells[t[i][j]].emplace_back(i, j);\n    \n    ntiles = tile_cells.size();\n    tiles.resize(ntiles);\n\n    for(auto &[tid, cells] : tile_cells) {\n        Tile tile;\n        tile.cells = std::move(cells);\n        int maxv = -1, maxi = -1, maxj = -1;\n        for(auto &[i, j] : tile.cells) {\n            if(p[i][j] > maxv) {\n                maxv = p[i][j]; maxi = i; maxj = j;\n            }\n        }\n        tile.max_val = maxv;\n        tile.max_cell_i = maxi;\n        tile.max_cell_j = maxj;\n        tiles[tid] = tile;\n    }\n\n    // Compute adjacency between tiles\n    for(int i = 0; i < N; ++i) for(int j = 0; j < N; ++j) {\n        int tid = t[i][j];\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 >= N || nj >= N) continue;\n            int ntid = t[ni][nj];\n            if(ntid != tid)\n                tiles[tid].adj.insert(ntid);\n        }\n    }\n}\n\n// A greedy DFS: always pick the unvisited adjacent tile with the highest-valued entry cell\n// Returns the movement string\nstring greedy_dfs_path() {\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    vector<bool> tile_used(ntiles, false);\n\n    int ci = si, cj = sj;\n    int curr_tid = t[ci][cj];\n\n    tile_used[curr_tid] = true;\n    visited[ci][cj] = true;\n\n    string path;\n    // path.reserve(N*N);\n\n    // We maintain (*ci, *cj) = current position\n    vector<vector<bool>> in_path(N, vector<bool>(N, false)); // Not strictly needed, but could help visualize\n\n    while(true) {\n        // Find which directions to go: only those leading to a tile not yet used\n        int best_score = -1, best_d = -1, best_ni = -1, best_nj = -1;\n        for(int d = 0; d < 4; ++d) {\n            int ni = ci + di[d], nj = cj + dj[d];\n            if(ni < 0 || nj < 0 || ni >= N || nj >= N) continue;\n            int n_tid = t[ni][nj];\n            if(tile_used[n_tid]) continue; // Tile already used\n            // Can move to this direction\n            if(p[ni][nj] > best_score) {\n                best_score = p[ni][nj];\n                best_d = d;\n                best_ni = ni;\n                best_nj = nj;\n            }\n        }\n        if(best_d == -1) break; // No further move possible\n\n        // Move to best_ni, best_nj\n        ci = best_ni; cj = best_nj;\n        curr_tid = t[ci][cj];\n        tile_used[curr_tid] = true;\n        visited[ci][cj] = true;\n        path += dch[best_d];\n    }\n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    // Input\n    cin >> si >> sj;\n    for(int i = 0; i < N; ++i)\n        for(int j = 0; j < N; ++j)\n            cin >> t[i][j];\n\n    for(int i = 0; i < N; ++i)\n        for(int j = 0; j < N; ++j)\n            cin >> p[i][j];\n\n    preprocess();\n\n    string path = greedy_dfs_path();\n\n    cout << path << endl;\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Constants\nconstexpr int N = 30;\nconstexpr int Q = 1000;\nconstexpr int DIR = 4;\nconst char dir_chars[DIR] = {'U','D','L','R'};\nconst int dx[DIR] = {-1,+1,0,0}, dy[DIR] = {0,0,-1,+1};\n\n// Edge structure for statistics\nstruct EdgeInfo {\n    double est = 5000.0;\n    int count = 0;\n    double sum = 0.0;\n    bool known = false;\n    \n    void update(double val) {\n        sum += val;\n        count++;\n        est = sum / count;\n    }\n    void add_sample(double val, double smoothing=0.8) {\n        if (!known) { est = val; known=true; return; }\n        est = smoothing*est + (1-smoothing)*val;\n    }\n};\n\n// Edge model: grid of edge estimates, separate for horizontal and vertical\nEdgeInfo horiz[N][N-1]; // between (i,j) and (i,j+1)\nEdgeInfo vert[N-1][N]; // between (i,j) and (i+1,j)\n\n// For edge encoding\ninline bool in_grid(int i, int j) { return 0<=i && i<N && 0<=j && j<N; }\n\n// Returns list of moves ('U','D','L','R') for s to t using current edge estimates\nvector<char> estimate_path(pair<int,int> s, pair<int,int> t) {\n    using T = tuple<double,int,int,string>; // cost, i, j, path\n    priority_queue<T, vector<T>, greater<>> pq;\n    vector<vector<double>> dist(N, vector<double>(N, 1e18));\n    vector<vector<pair<int,int>>> prev(N, vector<pair<int,int>>(N, {-1,-1}));\n    vector<vector<int>> previdx(N, vector<int>(N, -1));\n    dist[s.first][s.second] = 0;\n    pq.emplace(0.0, s.first, s.second, \"\");\n    while (!pq.empty()) {\n        auto [cost, i, j, p] = pq.top(); pq.pop();\n        if (make_pair(i,j)==t) {\n            // reconstruct path\n            vector<char> res;\n            int x = t.first, y = t.second;\n            while (prev[x][y].first != -1) {\n                int px = prev[x][y].first, py = prev[x][y].second;\n                int d = previdx[x][y];\n                res.push_back(dir_chars[d]);\n                x=px; y=py;\n            }\n            reverse(res.begin(), res.end());\n            return res;\n        }\n        if (cost > dist[i][j]) continue;\n        for (int d=0; d<4; ++d) {\n            int ni = i+dx[d], nj = j+dy[d];\n            if (!in_grid(ni, nj)) continue;\n            double ecost;\n            if (d==0) ecost = vert[i-1][j].est; // up: between (i-1,j)-(i,j)\n            if (d==1) ecost = vert[i][j].est;   // down: between (i,j)-(i+1,j)\n            if (d==2) ecost = horiz[i][j-1].est; // left: between (i,j-1)-(i,j)\n            if (d==3) ecost = horiz[i][j].est;   // right: between (i,j)-(i,j+1)\n            if (dist[ni][nj] > dist[i][j] + ecost) {\n                dist[ni][nj] = dist[i][j]+ecost;\n                prev[ni][nj] = {i,j};\n                previdx[ni][nj] = d;\n                pq.emplace(dist[ni][nj], ni, nj, p + dir_chars[d]);\n            }\n        }\n    }\n    // never reached: should not happen\n    return {};\n}\n\n// Map moves to edges for updating\nvoid update_edges(pair<int,int> s, const vector<char>& path, double total_edge_len) {\n    vector<pair<int,int>> wayp;\n    wayp.push_back(s);\n    int x = s.first, y = s.second;\n    for (char c: path) {\n        if (c=='U') x--;\n        else if (c=='D') x++;\n        else if (c=='L') y--;\n        else if (c=='R') y++;\n        wayp.emplace_back(x,y);\n    }\n    int plen = (int)path.size();\n    if (plen==0) return;\n    double unit = total_edge_len / plen; // naive: assign equally (no better info!)\n    for (int i=0; i<plen; ++i) {\n        int x0 = wayp[i].first, y0 = wayp[i].second;\n        int x1 = wayp[i+1].first, y1 = wayp[i+1].second;\n        // edge direction\n        if (x0==x1 && y0+1==y1) {\n            horiz[x0][y0].add_sample(unit);\n        } else if (x0==x1 && y0-1==y1) {\n            horiz[x0][y1].add_sample(unit);\n        } else if (x0+1==x1 && y0==y1) {\n            vert[x0][y0].add_sample(unit);\n        } else if (x0-1==x1 && y0==y1) {\n            vert[x1][y0].add_sample(unit);\n        } else assert(false);\n    }\n}\n\n// Early in the contest, randomly explore to cover more edges\nvector<char> random_path(pair<int,int> s, pair<int,int> t, mt19937 &rng) {\n    int x = s.first, y = s.second;\n    int tx = t.first, ty = t.second;\n    vector<char> path;\n    int dx_ = tx - x, dy_ = ty - y;\n    vector<char> moves;\n    if (dx_ > 0) moves.insert(moves.end(), dx_, 'D');\n    else moves.insert(moves.end(), -dx_, 'U');\n    if (dy_ > 0) moves.insert(moves.end(), dy_, 'R');\n    else moves.insert(moves.end(), -dy_, 'L');\n    shuffle(moves.begin(), moves.end(), rng); // randomize order\n    // Create actual path via valid movement\n    for(char c : moves) path.push_back(c);\n    return path;\n}\n\n// Readline helpers\nint si, sj, ti, tj;\nvoid fast_scan() { scanf(\"%d%d%d%d\", &si, &sj, &ti, &tj); }\nint fast_int() { int x; scanf(\"%d\", &x); return x; }\n\nint main() {\n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n\n    for (int query=0; query<Q; ++query) {\n        fast_scan();\n        pair<int,int> s = {si, sj}, t = {ti, tj};\n        vector<char> path_chars;\n        if (query < 100) {\n            path_chars = random_path(s, t, rng); // randomize for first 100 queries\n        } else {\n            path_chars = estimate_path(s, t);\n            if (path_chars.size()==0) { // fallback\n                path_chars = random_path(s, t, rng);\n            }\n        }\n        // Output path\n        string out(path_chars.begin(), path_chars.end());\n        printf(\"%s\\n\", out.c_str());\n        fflush(stdout);\n\n        // Input feedback (rounded noisy cost)\n        int feedback = fast_int();\n\n        // Update edge estimates using feedback length\n        update_edges(s, path_chars, feedback);\n\n        // (optional: debug)\n        // if (query%100==99) cerr << \"[[\"<<query<<\"]]\\n\";\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\n// For random numbers\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Returns list of tuples (direction (0=row,1=col), i, shift)\nvector<tuple<int,int,int>> all_positions(int N, int len) {\n    vector<tuple<int,int,int>> positions;\n    for(int dir=0;dir<2;++dir) // 0=row,1=col\n        for(int i=0;i<N;++i)\n            for(int shift=0;shift<N;++shift)\n                positions.emplace_back(dir,i,shift);\n    return positions;\n}\n\n// Try placing s in matrix a at (dir,i,shift)\n// Return if conflict (false if conflict), and collect pos_painted (to mark for this string)\nbool can_place(const vector<string> &a, int N, const string &s,\n               int dir, int i, int shift, vector<pair<int,int>> &pos_painted) {\n    int k = s.size();\n    pos_painted.clear();\n    for(int p=0;p<k;++p){\n        int x = (dir==0)? i : (i+p)%N;\n        int y = (dir==0)? (shift+p)%N : shift;\n        if(a[x][y]=='.' || a[x][y]==s[p]) {\n            pos_painted.emplace_back(x,y);\n        } else {\n            return false;\n        }\n    }\n    return true;\n}\n\n// Place s in matrix a at given places\nvoid do_paint(vector<string> &a, const string &s, const vector<pair<int,int>> &pos_painted, int dir, int i, int shift) {\n    int k = s.size();\n    for(int p=0;p<k;++p){\n        int x = (dir==0)? i : (i+p)%a.size();\n        int y = (dir==0)? (shift+p)%a.size() : shift;\n        a[x][y] = s[p];\n    }\n}\n\n// Checks if s is covered somewhere in matrix a as row/col subsequence (using torus)\nbool is_covered(const vector<string> &a, const string &s) {\n    int N = a.size();\n    int k = s.size();\n    for(int i=0;i<N;++i){\n        for(int shift=0;shift<N;++shift){\n            // Row\n            bool ok=true;\n            for(int p=0;p<k;++p){\n                if(a[i][(shift+p)%N]!=s[p]) { ok=false; break; }\n            }\n            if(ok) return true;\n            // Col\n            ok=true;\n            for(int p=0;p<k;++p){\n                if(a[(i+p)%N][shift]!=s[p]) { ok=false; break; }\n            }\n            if(ok) return true;\n        }\n    }\n    return false;\n}\n\nint main() {\n    ios::sync_with_stdio(0); cin.tie(0);\n    int N, M;\n    cin >> N >> M;\n    vector<string> s(M);\n    for(int i=0;i<M;++i) cin >> s[i];\n\n    vector<string> best_ans;\n    int best_cover = 0;\n\n    // Try several random processings to maximize c\n    int TRIALS = 7; // You can tune this\n    for(int trial=0; trial<TRIALS; ++trial){\n        vector<string> a(N, string(N,'.'));\n        vector<int> idx(M);\n        iota(idx.begin(), idx.end(), 0);\n        shuffle(idx.begin(), idx.end(), rng);\n\n        // Record for each cell the possible frequency of candidates (for later fill)\n        vector<vector<array<int,8>>> freq(N,vector<array<int,8>>(N));\n        for(int t=0;t<M;++t){\n            const string &si = s[t];\n            int k = si.size();\n            for(int dir=0;dir<2;++dir)\n                for(int i=0;i<N;++i)\n                    for(int shift=0;shift<N;++shift){\n                        for(int p=0;p<k;++p) {\n                            int x = (dir==0)? i : (i+p)%N;\n                            int y = (dir==0)? (shift+p)%N : shift;\n                            freq[x][y][si[p]-'A']++;\n                        }\n                    }\n        }\n\n        // Main Greedy: Try to pack as many s[idx[*]] as possible\n        vector<bool> used(M, false);\n        for(int tt=0;tt<M;++tt){\n            int i_s = idx[tt];\n            const string &si = s[i_s];\n            int k = si.size();\n\n            // Find all possible placements without conflict\n            vector<tuple<int,int,int>> possible;\n            vector<pair<int,int>> buf;\n            for(int dir=0;dir<2;++dir)\n                for(int i=0;i<N;++i)\n                    for(int shift=0;shift<N;++shift)\n                        if(can_place(a,N,si,dir,i,shift,buf))\n                            possible.emplace_back(dir,i,shift);\n\n            if(possible.empty()) continue;\n\n            // Pick randomly (could pick \"minimally fills new cells\", or \"max freq\", but use random for now)\n            auto [dir,i,shift] = possible[rng()%possible.size()];\n            // Actually place it\n            do_paint(a, si, buf, dir, i, shift);\n            used[i_s] = true;\n        }\n        // Final fill-in: Remaining '.' fill with most frequent guess (from freq), or 'A'\n        for(int i=0;i<N;++i) for(int j=0;j<N;++j) if(a[i][j]=='.') {\n            int maxv = 0; char c='A';\n            for(int t=0;t<8;++t) if(freq[i][j][t]>maxv) {\n                maxv = freq[i][j][t];\n                c = 'A' + t;\n            }\n            a[i][j] = c;\n        }\n\n        // Now count how many s are matched as subsequence\n        int cover = 0;\n        for(int i=0;i<M;++i) if(is_covered(a, s[i])) cover++;\n\n        if(cover > best_cover) {\n            best_cover = cover;\n            best_ans = a;\n            if(cover == M) break; // optimal (no point in more tries)\n        }\n    }\n    // Output final matrix\n    for(int i=0;i<N;++i)\n        cout << best_ans[i] << '\\n';\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int DX[4] = {-1, +1, 0, 0};\nconstexpr int DY[4] = {0, 0, -1, +1};\nconstexpr char DIRS[4] = {'U', 'D', 'L', 'R'};\n\nusing Pos = pair<int, int>;\n\n// Fast bitset for up to 2500 cells (max roads)\nstruct FastBitSet {\n    vector<uint64_t> bs;\n    int size; // number of bits\n\n    FastBitSet(int n) : size(n), bs((n+63)>>6) {}\n\n    void set(int k) { bs[k>>6] |= (1ULL<<(k&63)); }\n    void reset(int k) { bs[k>>6] &= ~(1ULL<<(k&63)); }\n    bool test(int k) const { return (bs[k>>6]>>(k&63))&1; }\n    void operator|=(const FastBitSet& rhs) {\n        for (int i=0; i<bs.size(); ++i) bs[i] |= rhs.bs[i];\n    }\n    FastBitSet operator|(const FastBitSet& rhs) const {\n        FastBitSet ret(*this);\n        ret |= rhs;\n        return ret;\n    }\n    int count() const {\n        int res = 0;\n        for (auto x: bs) res += __builtin_popcountll(x);\n        return res;\n    }\n    bool all() const {\n        int last = size & 63;\n        for (int i=0; i+1 < bs.size(); ++i) if (bs[i] != ~0ULL) return false;\n        if (last == 0) return bs.back() == ~0ULL;\n        else return (bs.back() & ((1ULL<<last)-1)) == ((1ULL<<last)-1);\n    }\n    int find_first_zero() const {\n        for (int i=0; i<bs.size(); ++i) {\n            if (~bs[i]) {\n                int b = __builtin_ctzll(~bs[i]);\n                int idx = (i<<6)+b;\n                return idx < size ? idx : -1;\n            }\n        }\n        return -1;\n    }\n    vector<int> to_vector() const {\n        vector<int> res;\n        for (int i=0; i<size; ++i) if (test(i)) res.push_back(i);\n        return res;\n    }\n};\n\n// Helper for mapping positions to road cell indices\nstruct RoadMapper {\n    int N;\n    vector<vector<int>> idx_of; // -1 if not a road\n\n    vector<Pos> pos_of; // pos_of[road_id] = (i,j)\n    int num_roads;\n\n    RoadMapper(int N_, const vector<string>& grid) : N(N_) {\n        idx_of.assign(N, vector<int>(N, -1));\n        pos_of.reserve(N*N);\n        int id = 0;\n        for (int i=0;i<N;++i)for(int j=0;j<N;++j){\n            if ('5' <= grid[i][j] && grid[i][j] <= '9') {\n                idx_of[i][j] = id++;\n                pos_of.push_back({i,j});\n            }\n        }\n        num_roads = id;\n    }\n    int id(int i, int j) const { return idx_of[i][j]; }\n    const Pos& pos(int id) const { return pos_of[id]; }\n};\n\nstruct Visibility {\n    int N, num_roads;\n    const vector<string> &grid;\n    RoadMapper& mapper;\n    vector<FastBitSet> visible_from; // [road_id] masks of visible road cells\n\n    Visibility(int N_, RoadMapper& mapper_, const vector<string>& grid_)\n        : N(N_), grid(grid_), mapper(mapper_), num_roads(mapper.num_roads),\n          visible_from(num_roads, FastBitSet(mapper.num_roads)) {\n\n        vector<vector<int>>& idx_of = mapper.idx_of;\n        // For every road cell, precompute visible cells in 4 directions\n        for (int k = 0; k < num_roads; ++k) {\n            auto [i,j] = mapper.pos_of[k];\n            // Row L\n            for (int jj = j; jj >= 0; --jj) {\n                if (idx_of[i][jj] == -1) break;\n                visible_from[k].set(idx_of[i][jj]);\n            }\n            // Row R\n            for (int jj = j+1; jj < N; ++jj) {\n                if (idx_of[i][jj] == -1) break;\n                visible_from[k].set(idx_of[i][jj]);\n            }\n            // Col U\n            for (int ii = i; ii >= 0; --ii) {\n                if (idx_of[ii][j] == -1) break;\n                visible_from[k].set(idx_of[ii][j]);\n            }\n            // Col D\n            for (int ii = i+1; ii < N; ++ii) {\n                if (idx_of[ii][j] == -1) break;\n                visible_from[k].set(idx_of[ii][j]);\n            }\n            // Self\n            visible_from[k].set(k);\n        }\n    }\n};\n\n// BFS for shortest path cost/moves on graph; returns path of cells\nvector<Pos> bfs_shortest_path(\n    const vector<string>& grid, int N,\n    Pos start, Pos end)\n{\n    if (start == end) return {start};\n    vector<vector<Pos>> prev(N, vector<Pos>(N, {-1,-1}));\n    queue<Pos> que;\n    que.push(start);\n    prev[start.first][start.second] = start;\n    while (!que.empty()) {\n        auto [i,j] = que.front(); que.pop();\n        for (int d=0;d<4;++d) {\n            int ni = i + DX[d];\n            int nj = j + DY[d];\n            if (ni<0||nj<0||ni>=N||nj>=N) continue;\n            if (!(grid[ni][nj]>='5' && grid[ni][nj]<='9')) continue;\n            if (prev[ni][nj].first!=-1) continue;\n            prev[ni][nj] = {i,j};\n            if (make_pair(ni,nj) == end) {\n                // Reconstruct\n                vector<Pos> path;\n                Pos cur = end;\n                while (cur != start) {\n                    path.push_back(cur);\n                    cur = prev[cur.first][cur.second];\n                }\n                path.push_back(start);\n                reverse(path.begin(), path.end());\n                return path;\n            }\n            que.push({ni,nj});\n        }\n    }\n    // unreachable!\n    return {};\n}\n\n// For move path between adjacent cells\nchar move_dir(const Pos& from, const Pos& to) {\n    int di = to.first-from.first, dj = to.second-from.second;\n    for (int d=0;d<4;++d) if (di==DX[d]&&dj==DY[d]) return DIRS[d];\n    assert(false);\n    return '?';\n}\n\n// Greedy set cover: At each step, move to position that covers most yet-uncovered cells per cost (or per step)\nvector<Pos> greedy_scan_path(\n    const vector<string>& grid, int N,\n    RoadMapper& mapper, const Visibility& vis, \n    int si, int sj)\n{\n    int num_roads = mapper.num_roads;\n    int cur_id = mapper.id(si,sj);\n    FastBitSet covered(num_roads);\n    covered |= vis.visible_from[cur_id];\n\n    vector<bool> scanned(num_roads);\n    vector<Pos> path = {mapper.pos_of[cur_id]};\n    int cur_i = si, cur_j = sj;\n\n    // List of scan points to visit\n    vector<int> scan_points = {cur_id};\n\n    while (!covered.all()) {\n        // Candidates: all road cells\n        int best_id = -1, best_gain = -1;\n        int best_dist = 1e9; // among same gain, prefer closer\n        // For this quick initial baseline, just consider direct neighbors (fast enough)\n        for (int k = 0; k < num_roads; ++k) {\n            if (k == cur_id) continue;\n            if (scanned[k]) continue;\n            // Only consider cells still providing new coverage\n            int gain = 0;\n            auto& vis_set = vis.visible_from[k];\n            for (int x=0;x<num_roads;++x) {\n                if (vis_set.test(x) && !covered.test(x)) gain++;\n            }\n            if (gain <= 0) continue;\n            // Compute shortest path len to (could cache x BFSes, but ok for small N)\n            auto p1 = mapper.pos_of[cur_id], p2 = mapper.pos_of[k];\n            int dist = abs(p1.first-p2.first)+abs(p1.second-p2.second); // Manhattan approx\n            if (gain > best_gain || (gain == best_gain && dist < best_dist)) {\n                best_gain = gain, best_id = k, best_dist = dist;\n            }\n        }\n        if (best_id == -1) break; // No progress\n\n        // Path to best_id\n        auto from = mapper.pos_of[cur_id];\n        auto to = mapper.pos_of[best_id];\n        vector<Pos> segment = bfs_shortest_path(grid, N, from, to);\n        for (int idx=1; idx<segment.size(); ++idx) {\n            path.push_back(segment[idx]);\n        }\n\n        cur_id = best_id;\n        covered |= vis.visible_from[cur_id];\n        scanned[cur_id] = true;\n        scan_points.push_back(cur_id);\n    }\n\n    // Path home to start\n    if (cur_id != mapper.id(si,sj)) {\n        auto from = mapper.pos_of[cur_id], to = make_pair(si,sj);\n        vector<Pos> segment = bfs_shortest_path(grid, N, from, to);\n        for (int idx=1; idx<segment.size(); ++idx) {\n            path.push_back(segment[idx]);\n        }\n    }\n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N, si, sj;\n    cin >> N >> si >> sj;\n    vector<string> grid(N);\n    for (int i=0;i<N;++i) cin >> grid[i];\n\n    RoadMapper mapper(N, grid);\n    Visibility vis(N, mapper, grid);\n\n    vector<Pos> route = greedy_scan_path(grid, N, mapper, vis, si, sj);\n\n    // Output moves\n    string moves;\n    for (int i=1; i<route.size(); ++i)\n        moves += move_dir(route[i-1], route[i]);\n\n    cout << moves << endl;\n\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 1000;\nconstexpr int M = 20;\nconstexpr int MAX_K = 20;\nconstexpr int MAX_DAY = 2000;\n\n// Input data\nint n, m, k, r;\nvector<vector<int>> d;            // (n x k): d[i][j]: required skill j for task i\nvector<vector<int>> dependencies; // tasks this task depends on (n x ?)\nvector<vector<int>> revdeps;      // tasks that depend on this task (n x ?)\nvector<int> indegree;             // indegree (unresolved dependencies) (n)\nvector<int> status;               // 0: not assigned, 1: assigned, 2: done\n\n// Task management\nqueue<int> ready_tasks;           // tasks that are ready to be assigned\nset<int> waiting_ready_tasks;     // alternative for ready_tasks (for optimal assignment)\n\n// Member states\nstruct MemberState {\n    int busy_until = 0;\n    int current_task = -1;\n    int assigned_day = -1;\n};\n\nvector<MemberState> members(M);\n\n// For skill estimations: we use for each member a vector<double> est_skills\nvector<vector<double>> est_skills; // (m x k), estimated skill\nvector<vector<int>> skill_observations_cnt; // (m x k), number of tasks used for dimension update\n\n// For early exploration, assign each member to tasks with high/low skill requirements in different dimensions\n\nint current_day = 1;\n\nvoid read_input() {\n    cin >> n >> m >> k >> r;\n    d.assign(n, vector<int>(k));\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < k; ++j)\n            cin >> d[i][j];\n    dependencies.assign(n, vector<int>());\n    revdeps.assign(n, vector<int>());\n    indegree.assign(n, 0);\n    for (int i = 0; i < r; ++i) {\n        int u, v;\n        cin >> u >> v;\n        --u; --v;\n        dependencies[v].push_back(u);\n        revdeps[u].push_back(v);\n        indegree[v]++;\n    }\n}\n\nvoid init_ready_tasks() {\n    for (int i = 0; i < n; ++i)\n        if (indegree[i] == 0)\n            waiting_ready_tasks.insert(i);\n}\n\n// Simple skill guess: initialize to zeros\nvoid init_estimated_skills() {\n    est_skills.assign(m, vector<double>(k, 0.0));\n    skill_observations_cnt.assign(m, vector<int>(k, 0));\n}\n\n// Estimate \"match\" between member and a task\ndouble expected_completion_time(int member, int task) {\n    // w_{i,j} = sum_k max(0, d_{i,k} - s_{j,k})\n    double w = 0;\n    for (int dim = 0; dim < k; ++dim) {\n        double need = d[task][dim];\n        double have = est_skills[member][dim];\n        if (need > have) w += (need - have);\n    }\n    // r_i is uniform in [-3,3], mean = 0\n    return max(1.0, w); // best guess: use mean r_i=0\n}\n\n// For updating skills, keep rough min/max\nconst int R_MIN = -3, R_MAX = 3;\n\nvoid update_skill_estimate(int member, int task, int observed_days) {\n    // The possible w_{i,j} = observed_days - r_i, with r_i\\in[-3,3]\n    // So w_{i,j} in [odays-3, odays+3]\n    // w_{i,j} = sum_k max(0, d_{i,k} - s_{j,k})\n    // We'll do a simple conservative update: if odays==1, s>=d; otherwise, s<=d-(w-3)\n    \n    if (observed_days <= 6) {\n        // Possibly w=0 (if r_i positive), but not certain\n        // If odays == 1, possible r_i up to +3, so maybe w=0, meaning skills cover reqs\n        // For now, update only if days >= 4 (unlikely to be pure randomness)\n    }\n    // Optionally, keep a list of assignments to do regression later\n}\n\nvoid process_feedback(const vector<int>& finished_members) {\n    for (int member : finished_members) {\n        MemberState &ms = members[member];\n        int fin_task = ms.current_task;\n        int assigned_day = ms.assigned_day;\n        int obs_days = current_day - assigned_day + 1;\n        status[fin_task] = 2; // done\n        ms.current_task = -1;\n        ms.busy_until = 0;\n        ms.assigned_day = -1;\n\n        // Update dependent tasks for ready queue\n        for (int v : revdeps[fin_task]) {\n            indegree[v]--;\n            if (indegree[v] == 0 && status[v] == 0)\n                waiting_ready_tasks.insert(v);\n        }\n        // Optionally: update skill estimation\n        update_skill_estimate(member, fin_task, obs_days);\n    }\n}\n\n// Assignment heuristic: pick task (from ready) that best matches each free member\nvoid assign_tasks_today(vector<pair<int, int>>& assignments) {\n    vector<int> free_members;\n    for (int i = 0; i < m; ++i) {\n        if (members[i].current_task == -1)\n            free_members.push_back(i);\n    }\n    \n    // For each member, pick the best available task\n    set<int> used_tasks;\n    vector<pair<int, int>> to_assign;\n    for (int member : free_members) {\n        int best_task = -1;\n        double best_score = 1e18;\n        for (const int task : waiting_ready_tasks) {\n            if (status[task] != 0 || used_tasks.count(task)) continue;\n            double expect = expected_completion_time(member, task);\n            // Simple logic: if expect == 1, prefer; otherwise, pick min\n            if (expect < best_score) {\n                best_score = expect;\n                best_task = task;\n                if (expect == 1.0) break; // perfect match\n            }\n        }\n        if (best_task != -1) {\n            to_assign.push_back({member, best_task});\n            used_tasks.insert(best_task);\n        }\n    }\n\n    // Actually assign\n    for (auto [member, task] : to_assign) {\n        assignments.push_back({member, task});\n        status[task] = 1; // assigned\n        members[member].current_task = task;\n        members[member].assigned_day = current_day;\n        waiting_ready_tasks.erase(task);\n    }\n}\n\nvoid print_assignments(const vector<pair<int, int>>& assignments) {\n    cout << assignments.size();\n    for (auto [member, task] : assignments) {\n        // Output as 1-based\n        cout << \" \" << (member + 1) << \" \" << (task + 1);\n    }\n    cout << endl;\n    cout.flush();\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    // --- INITIALIZATION ---\n    read_input();\n    status.assign(n, 0);     // 0: not assigned, 1: assigned, 2: done\n    members.assign(m, MemberState());\n    init_ready_tasks();\n    init_estimated_skills();\n\n    // --- MAIN LOOP ---\n    while (true) {\n        vector<pair<int, int>> assignments;\n        assign_tasks_today(assignments);\n        print_assignments(assignments);\n\n        // READ FEEDBACK\n        string line;\n        getline(cin, line);\n        if (cin.eof()) break;\n        if (line == \"-1\") break;\n        if (line.empty()) getline(cin, line);\n        istringstream iss(line);\n        int nfinish;\n        iss >> nfinish;\n        if (nfinish == -1) break;\n        vector<int> fins;\n        for (int i = 0; i < nfinish; ++i) {\n            int x; iss >> x;\n            fins.push_back(x-1); // 1-based to 0-based\n        }\n        process_feedback(fins);\n        current_day++;\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Order {\n    int id;\n    int ax, ay; // restaurant\n    int cx, cy; // customer\n    int score;  // heuristic\n};\n\nint manh(int x1, int y1, int x2, int y2) {\n    return abs(x1-x2) + abs(y1-y2);\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    vector<Order> orders(1000);\n    for (int i = 0; i < 1000; ++i) {\n        int a, b, c, d;\n        cin >> a >> b >> c >> d;\n        orders[i] = {i, a, b, c, d, 0};\n    }\n\n    // Score each order (lower is better)\n    for (auto& o : orders) {\n        int office = 400;\n        o.score = \n            manh(office, office, o.ax, o.ay)  // office->pickup\n            + manh(o.ax, o.ay, o.cx, o.cy)    // pickup->delivery\n            + manh(o.cx, o.cy, office, office); // delivery->office\n    }\n\n    // Pick 50 best orders\n    sort(orders.begin(), orders.end(), [](const Order& a, const Order& b) {\n        return a.score < b.score;\n    });\n\n    vector<Order> sel_orders(orders.begin(), orders.begin()+50);\n    // For output, we need the 1-based id (id+1)\n    vector<int> sel_ids;\n    for (auto& o: sel_orders) sel_ids.push_back(o.id+1);\n\n    // Build 100 nodes: first 50 pickups, next 50 deliveries\n    struct Node {\n        int x, y;\n        int ord_idx; // index in sel_orders\n        bool is_pickup; // true for pickup, false for delivery\n    };\n    vector<Node> nodes;\n    for (int i = 0; i < 50; ++i) {\n        nodes.push_back({sel_orders[i].ax, sel_orders[i].ay, i, true});\n    }\n    for (int i = 0; i < 50; ++i) {\n        nodes.push_back({sel_orders[i].cx, sel_orders[i].cy, i, false});\n    }\n    int N = nodes.size();\n\n    // Mark which nodes are available for visit\n    vector<bool> visited(N, false);\n    vector<bool> pickup_done(50, false);\n\n    // Start route at office (400,400)\n    vector<pair<int,int>> route = {{400,400}};\n\n    int cur_x = 400, cur_y = 400;\n    for (int step = 0; step < N; ++step) {\n        int best = -1, best_dist = 1e9;\n        for (int i = 0; i < N; ++i) if (!visited[i]) {\n            if (!nodes[i].is_pickup) {\n                // delivery: only available if pickup done\n                if (!pickup_done[nodes[i].ord_idx]) continue;\n            }\n            int dist = manh(cur_x, cur_y, nodes[i].x, nodes[i].y);\n            if (dist < best_dist) {\n                best = i;\n                best_dist = dist;\n            }\n        }\n        // Move to best node\n        visited[best] = true;\n        if (nodes[best].is_pickup)\n            pickup_done[nodes[best].ord_idx] = true;\n        cur_x = nodes[best].x;\n        cur_y = nodes[best].y;\n        route.emplace_back(cur_x, cur_y);\n    }\n    // Return to office\n    if (cur_x != 400 || cur_y != 400)\n        route.emplace_back(400,400);\n\n    // Output\n    cout << \"50\";\n    for (int i = 0; i < 50; ++i) cout << \" \" << sel_ids[i];\n    cout << \"\\n\";\n    cout << route.size();\n    for (auto& p : route) cout << \" \" << p.first << \" \" << p.second;\n    cout << \"\\n\";\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Fast DSU, standard\nstruct DSU {\n    vector<int> parent, sz;\n    DSU(int n) : parent(n), sz(n, 1) {\n        iota(parent.begin(), parent.end(), 0);\n    }\n    int find(int x) {\n        while (parent[x] != x) x = parent[x] = parent[parent[x]];\n        return x;\n    }\n    bool unite(int x, int y) {\n        x = find(x); y = find(y);\n        if (x == y) return false;\n        if (sz[x] < sz[y]) swap(x, y);\n        parent[y] = x; sz[x] += sz[y];\n        return true;\n    }\n    bool same(int x, int y) { return find(x) == find(y); }\n};\n\nstruct Edge {\n    int id; // index in input order\n    int u, v;\n    int d; // Euclidean/rounded\n};\n\n// Main function\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 400, M = 1995;\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    vector<Edge> edges(M);\n    for (int i = 0; i < M; ++i) {\n        int u, v; cin >> u >> v;\n        int x1 = coords[u].first, y1 = coords[u].second;\n        int x2 = coords[v].first, y2 = coords[v].second;\n        double eucl = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));\n        int d = round(eucl);\n        edges[i] = {i, u, v, d};\n    }\n\n    // Build d_i-based MST at the start\n    vector<Edge> sorted_edges = edges;\n    sort(sorted_edges.begin(), sorted_edges.end(), [](const Edge& a, const Edge& b){\n        return a.d < b.d;\n    });\n    DSU dsu0(N);\n    unordered_set<int> mst_edges; // edge ids in MST\n    for (auto &e : sorted_edges) {\n        if (dsu0.unite(e.u, e.v)) {\n            mst_edges.insert(e.id);\n        }\n    }\n    // Optionally: For further safety, we could build a second-best alternative MST edge set etc.\n\n    // Start online phase\n    DSU dsu(N);\n\n    for (int i = 0; i < M; ++i) {\n        int l_i;\n        cin >> l_i;\n        int u = edges[i].u, v = edges[i].v;\n        int d = edges[i].d;\n        bool accepted = false;\n\n        if (!dsu.same(u, v)) {\n            if (mst_edges.count(i)) {\n                // Tune alpha for acceptance greediness/safety\n                double alpha = 1.6;\n                if (l_i <= int(alpha * d)) {\n                    cout << 1 << endl;\n                    accepted = true;\n                    dsu.unite(u, v);\n                }\n            } else {\n                // Non-MST edges: be stricter or relax if close to finishing\n                // Here, only accept if we're running out of ways to connect\n                // But for now, reject\n            }\n        }\n\n        if (!accepted) {\n            cout << 0 << endl;\n        }\n\n        cout << flush;\n    }\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Grid dimensions\nconstexpr int W = 30, H = 30;\nconstexpr int DX[4] = {-1, 1, 0, 0};\nconstexpr int DY[4] = {0, 0, -1, 1};\nconstexpr char MOVES[4] = {'U', 'D', 'L', 'R'};\nconstexpr char WALLS[4] = {'u', 'd', 'l', 'r'};\n\nstruct Pet {\n    int x, y, type;\n};\nstruct Human {\n    int x, y;\n    int dest_x, dest_y; // where he's going!\n    int band_l, band_r;\n};\n\nvector<string> grid(H, string(W, '.')); // .:passable, #:wall, h:human, p:pet\n\n// 0-indexed, returns true if inside grid\ninline bool ins(int x, int y) { return 0 <= x && x < H && 0 <= y && y < W; }\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N; cin >> N;\n    vector<Pet> pets(N);\n    for (int i = 0; i < N; i++) {\n        int x, y, t; cin >> x >> y >> t;\n        --x; --y;\n        pets[i] = {x, y, t};\n        grid[x][y] = 'p'; // mark as pet\n    }\n    int M; cin >> M;\n    vector<Human> humans(M);\n    vector<pair<int,int>> hpos(M);\n    vector<vector<int>> human_grid(H, vector<int>(W, 0)); // count of humans\n    for (int i = 0; i < M; i++) {\n        int x, y; cin >> x >> y;\n        --x; --y;\n        humans[i].x = x;\n        humans[i].y = y;\n        hpos[i] = {x, y};\n        grid[x][y] = 'h';\n        human_grid[x][y]++;\n    }\n\n    // Assign bands (vertical partition)\n    vector<pair<int,int>> band_limits(M);\n    int band_size = W / M;\n    for (int i = 0; i < M; i++) {\n        int l = i * band_size;\n        int r = (i == M-1) ? W-1 : (i+1)*band_size-1;\n        band_limits[i] = {l, r};\n        humans[i].band_l = l;\n        humans[i].band_r = r;\n        humans[i].dest_x = H/2; // central row\n        humans[i].dest_y = (l + r)/2;\n    }\n\n    vector<vector<int>> pet_grid(H, vector<int>(W, 0));\n    for (auto& p : pets) pet_grid[p.x][p.y]++;\n\n    // For each turn\n    int phase_move = 12; // Tuning param: turns spent getting into position\n    for (int turn = 0; turn < 300; ++turn) {\n        string actions(M, '.');\n        // Update grid to remove old h and p marks (we'll re-mark below)\n        for (int i = 0; i < H; ++i)\n            for (int j = 0; j < W; ++j)\n                if (grid[i][j]=='h' || grid[i][j]=='p')\n                    grid[i][j] = '.';\n        fill(&human_grid[0][0], &human_grid[0][0]+H*W, 0);\n        fill(&pet_grid[0][0], &pet_grid[0][0]+H*W, 0);\n        for (int i = 0; i < M; ++i) {\n            grid[humans[i].x][humans[i].y] = 'h';\n            human_grid[humans[i].x][humans[i].y]++;\n        }\n        for (int i = 0; i < N; ++i) {\n            grid[pets[i].x][pets[i].y] = 'p';\n            pet_grid[pets[i].x][pets[i].y]++;\n        }\n\n        // For each human, decide action\n        for (int i = 0; i < M; ++i) {\n            auto& h = humans[i];\n            int cx = h.x, cy = h.y;\n            int xl = h.band_l, xr = h.band_r;\n\n            // PHASE 0: Move to starting pos near center of band in first \"phase_move\" turns\n            if (turn < phase_move) {\n                int destx = h.dest_x, desty = h.dest_y;\n                if (cx < destx)      actions[i] = 'D', h.x++;\n                else if (cx > destx) actions[i] = 'U', h.x--;\n                else if (cy < desty) actions[i] = 'R', h.y++;\n                else if (cy > desty) actions[i] = 'L', h.y--;\n                // else stand\n                continue;\n            }\n\n            // PHASE 1: Build walls on left and right of their region\n            // Try to wall a cell at the edge of their band\n            // Alternate walling at the left and right edge of their band!\n            bool did_wall = false;\n\n            // Let's try right wall first this turn if not at the rightmost column\n            for (int d = 0; d < 4 && !did_wall; ++d) {\n                // Choose priority: right-most, left-most, up, down\n                int dir = d;\n                int tx = cx + DX[dir], ty = cy + DY[dir];\n                // For now, try to build wall on the right-most of our region\n                if (dir == 1 && cy < xr) continue; // D: Not vertical wall, skip\n                if (dir == 0 && cy > xl) continue;\n                if (!ins(tx, ty)) continue;\n                if (grid[tx][ty] == '.' && human_grid[tx][ty]==0 && pet_grid[tx][ty]==0) {\n                    // Check no adjacent pet in 8-neighborhood (stricter than needed: 4-neighborhood is rule!)\n                    bool safe = true;\n                    for (int d2 = 0; d2 < 4; ++d2) {\n                        int nx = tx + DX[d2], ny = ty + DY[d2];\n                        if (ins(nx, ny) && pet_grid[nx][ny]) safe = false;\n                    }\n                    if (safe) {\n                        actions[i] = WALLS[dir];\n                        did_wall = true;\n                    }\n                }\n            }\n            if (did_wall) continue; // Prefer walling\n\n            // Otherwise, do a little patrol: move along boundary if not at an edge\n            if (cy < xl) { actions[i] = 'R'; h.y++; }\n            else if (cy > xr) { actions[i] = 'L'; h.y--; }\n            // else idle\n        }\n\n        cout << actions << '\\n' << flush;\n\n        // INPUT PET MOVES\n        vector<string> pet_moves(N);\n        for (int i = 0; i < N; ++i) {\n            cin >> pet_moves[i];\n        }\n        // Update pet positions\n        for (int i = 0; i < N; ++i) {\n            for (char c : pet_moves[i]) {\n                int dx = 0, dy = 0;\n                if (c == 'U') dx = -1;\n                if (c == 'D') dx = 1;\n                if (c == 'L') dy = -1;\n                if (c == 'R') dy = 1;\n                int nx = pets[i].x + dx, ny = pets[i].y + dy;\n                if (ins(nx, ny)) pets[i].x = nx, pets[i].y = ny;\n            }\n        }\n    }\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Directions: U, D, L, R\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst char DC[] = {'U', 'D', 'L', 'R'};\n\nstruct WallMap {\n    int h[20][19]; // horizontal: right wall of (i, j) is h[i][j]\n    int v[19][20]; // vertical: down wall of (i, j) is v[i][j]\n    bool can_move(int i, int j, int dir) const {\n        // 0:U, 1:D, 2:L, 3:R\n        if(dir==0) { // Up\n            if(i==0) return false;\n            return v[i-1][j]==0;\n        }\n        if(dir==1) { // Down\n            if(i==19) return false;\n            return v[i][j]==0;\n        }\n        if(dir==2) { // Left\n            if(j==0) return false;\n            return h[i][j-1]==0;\n        }\n        if(dir==3) { // Right\n            if(j==19) return false;\n            return h[i][j]==0;\n        }\n        return false;\n    }\n};\n\n// Find one (or all) shortest path(s) using BFS\nvector<int> bfs_shortest_path(const WallMap &wm, int si, int sj, int gi, int gj) {\n    vector<vector<int>> dist(20, vector<int>(20, -1));\n    vector<vector<pair<int,int>>> prev(20, vector<pair<int,int>>(20, {-1,-1}));\n    deque<pair<int,int>> dq;\n    dist[si][sj] = 0;\n    dq.push_back({si, sj});\n    while(!dq.empty()) {\n        auto [i, j] = dq.front(); dq.pop_front();\n        for (int d=0; d<4; ++d) {\n            if(!wm.can_move(i, j, d)) continue;\n            int ni = i + di[d], nj = j + dj[d];\n            if(dist[ni][nj] == -1) {\n                dist[ni][nj] = dist[i][j] + 1;\n                prev[ni][nj] = {i, j};\n                dq.push_back({ni, nj});\n            }\n        }\n    }\n    // Reconstruct path\n    vector<int> path;\n    int ci = gi, cj = gj;\n    if (dist[ci][cj] == -1) {\n        return {}; // No path?\n    }\n    while (!(ci == si && cj == sj)) {\n        auto [pi, pj] = prev[ci][cj];\n        for (int d=0; d<4; ++d) if(pi+di[d]==ci && pj+dj[d]==cj && wm.can_move(pi, pj, d)) {\n            path.push_back(d);\n            break;\n        }\n        tie(ci, cj) = make_pair(pi, pj);\n    }\n    reverse(path.begin(), path.end()); // Now from start to goal\n    return path;\n}\n\n// Optionally interleaved path (DRDR...), or all Ds then all Rs\nvector<int> to_interleaved_path(const vector<int>& dr_path) {\n    // Try to alternate different directions for robustness.\n    // (For a path with equal numbers of D and R, this gives DRDRDR..)\n    vector<int> l2;\n    for (int d: dr_path) {\n        l2.push_back(d);\n    }\n    return l2;\n}\n\n// Turn a path (vector<int> dir) into string, with redundancy\nstring expand_path(const vector<int>& path, int repeat_each, int total_limit=200) {\n    string moves;\n    for (int d: path) {\n        for (int k=0; k<repeat_each; ++k) {\n            if((int)moves.size()<total_limit) moves += DC[d];\n        }\n    }\n    // If there is still room to fill up to total_limit, may repeat full path\n    while((int)moves.size()+int(path.size())<=total_limit) {\n        for(int d: path)\n            if((int)moves.size()<total_limit) moves+=DC[d];\n    }\n    return moves;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n\n    // Parse input\n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n    WallMap wm;\n    for (int i=0;i<20;++i) for (int j=0;j<19;++j) {\n        char c; cin >> c;\n        wm.h[i][j] = c-'0';\n    }\n    for (int i=0;i<19;++i) for (int j=0;j<20;++j) {\n        char c; cin >> c;\n        wm.v[i][j] = c-'0';\n    }\n\n    // Find shortest path (BFS)\n    auto spath = bfs_shortest_path(wm, si, sj, ti, tj);\n\n    // We will output a robust path\n    // Try several candidate parameters for redundancy\n    string best_pgm;\n    double best_score = -1;\n\n    // Try repeat_each = 1,2,3\n    for(int repeat_each=1; repeat_each<=3; repeat_each++) {\n        string prog = expand_path(spath, repeat_each, 200);\n        // Simple output: use the shortest path, repeat moves N times\n        // Optionally do simulation to evaluate\n        // For now, pick the shortest (repeat_each=1) assuming small p, else longer\n        if (best_pgm.empty()) best_pgm = prog;\n    }\n\n    cout << best_pgm << endl;\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Globals for grid size\nconstexpr int N = 30;\n\n// Direction vectors: left, up, right, down \nconst int di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n\n// 'to' array provided in the statement: for each tile type [0-7], maps entry dir to exit dir (else -1)\nconst int to[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1},\n};\n\n// For tile type t and rotation r, returns real type\nint realType(int t, int r) {\n    if (t <= 3)\n        return (t + r) % 4;\n    else if (t == 4)\n        return r % 2 == 0 ? 4 : 5;\n    else if (t == 5)\n        return r % 2 == 0 ? 5 : 4;\n    else if (t == 6)\n        return r % 2 == 0 ? 6 : 7;\n    else /* t == 7 */\n        return r % 2 == 0 ? 7 : 6;\n}\n\n// Returns: vector<lengths> of all loops found, descending order\nvector<int> get_loops(const vector<vector<int>>& tile_types, const vector<vector<int>>& rotations) {\n    // Build current tile states per rotation\n    int st[N][N];\n    for (int i = 0; i < N; i++)\n    for (int j = 0; j < N; j++)\n        st[i][j] = realType(tile_types[i][j], rotations[i][j]);\n    \n    // For each (i,j,d), track if visited\n    // Use 4 directions per tile: visited[i][j][d]\n    bool visited[N][N][4] = {};\n    vector<int> loop_lengths;\n\n    for (int i = 0; i < N; i++)\n    for (int j = 0; j < N; j++)\n    for (int d = 0; d < 4; d++) {\n        if (visited[i][j][d]) continue;\n        int ci = i, cj = j, cd = d, len = 0;\n        while (true) {\n            if (visited[ci][cj][cd]) break; // Already handled by a previous loop/path\n            visited[ci][cj][cd] = true;\n            int nd = to[st[ci][cj]][cd];\n            if (nd == -1) break; // No path\n            int ni = ci + di[nd], nj = cj + dj[nd];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) break; // Out of grid\n            cd = (nd + 2) % 4;\n            ci = ni;\n            cj = nj;\n            len++;\n            if (ci == i && cj == j && cd == d) {\n                loop_lengths.push_back(len);\n                break;\n            }\n        }\n    }\n    sort(loop_lengths.rbegin(), loop_lengths.rend());\n    return loop_lengths;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Input\n    vector<vector<int>> tile_types(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; j++)\n            tile_types[i][j] = s[j] - '0';\n    }\n\n    // ======== STRATEGY 1: All-0s as baseline ========\n    vector<vector<int>> rotations(N, vector<int>(N, 0));\n\n    // (Optional: Replace this block with simulated annealing to optimize rotations)\n    /*\n    srand(time(0));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++)\n        rotations[i][j] = rand() % 4;\n    */\n\n    // (Optional: Greedily improve here...)\n\n    // Compute loops and output score to stderr for debug\n    auto loop_lengths = get_loops(tile_types, rotations);\n    int score = 0;\n    if (loop_lengths.size() >= 2) {\n        score = loop_lengths[0] * loop_lengths[1];\n    }\n    cerr << \"Top loop lengths: \";\n    for (int i = 0; i < min(5, (int)loop_lengths.size()); ++i)\n        cerr << loop_lengths[i] << \" \";\n    cerr << \"Score = \" << score << endl;\n\n    // Output: string of 900 digits, 0-3 (row order)\n    string out;\n    out.reserve(N*N);\n    for (int i = 0; i < N; i++)\n    for (int j = 0; j < N; j++)\n        out += char('0' + rotations[i][j]);\n    cout << out << endl;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nusing pii = pair<int,int>;\n\nchrono::high_resolution_clock::time_point time_start;\ndouble elapsed_sec() {\n    auto t = chrono::high_resolution_clock::now();\n    return chrono::duration<double>(t - time_start).count();\n}\n\n// Directions: UDLR\nconst int dr[] = {-1, 1, 0, 0};\nconst int dc[] = {0, 0, -1, 1};\nconst char dir_char[] = {'U','D','L','R'};\nconst int opp_dir[] = {1,0,3,2};\nconst int bit[] = {1<<1,1<<3,1<<0,1<<2}; // up,down,left,right\n\nstruct Board {\n    int N;\n    vector<vector<int>> grid;\n    pii empty; // (r,c) position of the empty cell\n\n    Board(int N_): N(N_), grid(N, vector<int>(N)) {}\n    Board(const Board &o): N(o.N), grid(o.grid), empty(o.empty) {}\n\n    void read_input() {\n        for(int i=0; i<N; ++i) {\n            string s; cin >> s;\n            for(int j=0; j<N; ++j) {\n                char ch = s[j];\n                if(ch=='0') {\n                    grid[i][j]=0;\n                    empty = {i,j};\n                } else if(isdigit(ch)) {\n                    grid[i][j] = ch-'0';\n                } else {\n                    grid[i][j] = ch-'a'+10;\n                }\n            }\n        }\n    }\n\n    // Can we move in dir d (U/D/L/R)?\n    bool can_move(int d) const {\n        int er = empty.first, ec = empty.second;\n        int nr = er + dr[d], nc = ec + dc[d];\n        return nr>=0 && nr<N && nc>=0 && nc<N;\n    }\n\n    // Do the move in dir d. Assumes move is legal.\n    void do_move(int d) {\n        int er = empty.first, ec = empty.second;\n        int nr = er + dr[d], nc = ec + dc[d];\n        swap(grid[er][ec], grid[nr][nc]);\n        empty = {nr, nc};\n    }\n\n    // For performance, do undo_move doesn't need to be tracked if not required yet.\n};\n\nstruct DSU {\n    vector<int> par, siz;\n    DSU(int n): par(n), siz(n,1) { iota(par.begin(), par.end(), 0); }\n    int find(int x) { return par[x]==x ? x : par[x]=find(par[x]); }\n    bool unite(int x,int y) {\n        x = find(x); y = find(y);\n        if(x==y) return false;\n        if(siz[x]<siz[y]) swap(x,y);\n        par[y]=x; siz[x]+=siz[y];\n        return true;\n    }\n    int size(int x) { return siz[find(x)]; }\n};\n\nstruct TreeChecker {\n    // Build a graph of non-empty tiles, with edges as problem states,\n    // Then find the largest connected component which is also acyclic\n\n    int N;\n    vector<vector<int>> grid;\n    vector<vector<int>> idmap; // for mapping (i,j) to node ids, since one cell is empty\n\n    TreeChecker(const vector<vector<int>> &g): N(g.size()), grid(g) {\n        // Build idmap: -1 for empty, else unique 0...(N*N-2)\n        idmap.assign(N, vector<int>(N,-1));\n        int id=0;\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++) {\n            if(grid[i][j]!=0) idmap[i][j]=id++;\n        }\n    }\n\n    // Returns (largest tree size)\n    int get_largest_tree_size() {\n        int nn = N*N-1;\n        vector<vector<int>> G(nn);\n        // Build undirected edge list\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++) {\n            if(grid[i][j]==0) continue;\n            int t = grid[i][j];\n            int id1 = idmap[i][j];\n            // down\n            if((t&8) && i+1<N && grid[i+1][j]!=0 && (grid[i+1][j]&2))\n                G[id1].push_back(idmap[i+1][j]);\n            // right\n            if((t&4) && j+1<N && grid[i][j+1]!=0 && (grid[i][j+1]&1))\n                G[id1].push_back(idmap[i][j+1]);\n            // (U/L can reverse edge but already covered)\n        }\n        // Find largest connected acyclic component: for each CC, check if no cycles (tree), report largest\n        int res=0;\n        vector<int> vis(nn,0);\n        for(int i=0;i<nn;i++) {\n            if(vis[i]) continue;\n            int size=0, edges=0;\n            bool is_tree=true;\n            function<void(int,int)> dfs=[&](int u, int p){\n                vis[u]=1; size++;\n                for(int v:G[u]) {\n                    if(v==p) continue;\n                    edges++;\n                    if(vis[v]) is_tree=false;\n                    else dfs(v, u);\n                }\n            };\n            dfs(i,-1);\n            if(is_tree && edges/2==size-1) res=max(res,size); // undirected: edges double-counted\n        }\n        return res;\n    }\n};\n\nint main() {\n    time_start = chrono::high_resolution_clock::now();\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T;\n    cin >> N >> T;\n    Board board(N);\n    board.read_input();\n\n    // Naive strategy: try random walks and keep the best\n    string best_moves;\n    int best_score = 0;\n    Board best_board = board;\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    int try_limit = 1500;   // Control based on validated time!\n    int walk_len = min(T, 200); // Try short walks first, might help\n\n    for(int t=0; t<try_limit; ++t) {\n        Board cur_board = board;\n        vector<int> move_hist;\n        string moves = \"\";\n        int prev_move = -1;\n        for(int k=0; k<walk_len; ++k) {\n            // Random legal move, avoid undoing previous\n            vector<int> can_moves;\n            for(int d=0; d<4; ++d) {\n                if( d != opp_dir[prev_move] && cur_board.can_move(d))\n                    can_moves.push_back(d);\n            }\n            if(can_moves.empty()) break;\n            int mv = can_moves[ rng() % can_moves.size() ];\n            cur_board.do_move(mv);\n            moves += dir_char[mv];\n            prev_move = mv;\n        }\n        // Compute score\n        TreeChecker tc(cur_board.grid);\n        int S = tc.get_largest_tree_size();\n        if(S>best_score || (S==best_score && (int)moves.size()<best_moves.size())) {\n            best_score = S;\n            best_moves = moves;\n            best_board = cur_board;\n        }\n        // Time management (1.8sec safety)\n        if(elapsed_sec() > 1.8) break;\n    }\n\n    // Output\n    cout << best_moves << \"\\n\";\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing P = pair<int, int>;\nusing ll = long long;\nconst double PI = acos(-1.0);\nconst int CAKE_RADIUS = 10000;\nconst int K = 100;\n\nstruct Strawberry {\n    int x, y;\n    int idx; // original id\n};\n\nstruct Line {\n    // Represent by ax + by + c = 0\n    // Or two points (px, py), (qx, qy)\n    int px, py, qx, qy;\n};\n\nstruct Piece {\n    vector<int> strawberry_idxs;\n};\n\nint N, K_input;\nvector<int> a; // a[1..10]\nvector<Strawberry> strawberries;\nvector<Line> cuts;\n\n// For bipartition: Given indices of strawberries, try to partition into sizes d and n-d\n// Return (success, (indices in side A, indices in side B), Line to cut by)\ntuple<bool, vector<int>, vector<int>, Line>\nbipartition(const vector<int>& idxs, int d, const vector<Strawberry>& strawbs, mt19937 &rng) {\n    int n = idxs.size();\n    if (n < d || d == 0 || d == n) return {false, {}, {}, {}};\n    vector<pair<double,int>> project(n); // (projection, index in idxs)\n    vector<double> directions;\n    const int tries = 20;\n    uniform_real_distribution<double> angle_dist(0, PI);\n    for(int attempt = 0; attempt < tries; ++attempt) {\n        double ang = angle_dist(rng);\n        double dx = cos(ang), dy = sin(ang);\n        for(int i = 0; i < n; ++i) {\n            const auto &s = strawbs[idxs[i]];\n            project[i] = {s.x*dx + s.y*dy, i};\n        }\n        sort(project.begin(), project.end());\n        // Try split after d-1 points (left: [0,d-1], right: [d,n-1])\n        double cut_left = project[d-1].first;\n        double cut_right = project[d].first;\n        double cut_proj = (cut_left + cut_right) / 2.0; // split position at midpoint\n        // Find two points on this line\n        // For simplicity, pick a point within cake in direction orthogonal to (dx,dy)\n        // e.g., normal vector (-dy, dx)\n        double nx = -dy, ny = dx;\n        // Pick p0 at (0,0) + cake_radius * (nx, ny)\n        double p0x = nx * CAKE_RADIUS, p0y = ny * CAKE_RADIUS;\n        double p1x = -nx * CAKE_RADIUS, p1y = -ny * CAKE_RADIUS;\n        // Shift line along (dx,dy) by cut_proj units: move origin along (dx,dy)\n        p0x += dx * cut_proj;\n        p0y += dy * cut_proj;\n        p1x += dx * cut_proj;\n        p1y += dy * cut_proj;\n        // Round to integer points in [-1e9,1e9]\n        auto clamp = [](double v) -> int64_t {\n            const ll M = 1000000000LL;\n            if (v > M) return M;\n            if (v < -M) return -M;\n            return static_cast<ll>(round(v));\n        };\n        ll px = clamp(p0x), py = clamp(p0y), qx = clamp(p1x), qy = clamp(p1y);\n\n        // Now assign to sides: those with projection < cut_proj on one side, others on other\n        vector<int> A, B;\n        for(int i = 0; i < n; ++i) {\n            int sidx = idxs[project[i].second];\n            if (project[i].first < cut_proj) A.push_back(sidx);\n            else if (project[i].first > cut_proj) B.push_back(sidx);\n            else {\n                // projection == cut_proj:\n                // Looks like a double point, but in practice, can assign to either cake side\n                // Just assign to B for safety (as cut_proj is mid of two projections)\n                B.push_back(sidx);\n            }\n        }\n        // If any strawberry happens to be exactly ON the line, abort this cut\n        // Check for each strawberry:\n        double eps = 1e-8;\n        bool on_cut = false;\n        for(int i = 0; i < n; ++i) {\n            if (abs(project[i].first - cut_proj) < eps) {\n                // A strawberry would be lost; try a new direction\n                on_cut = true;\n                break;\n            }\n        }\n        if (on_cut) continue;\n        // Now, can get exact d in A or B depending on ordering:\n        if (A.size() == d || B.size() == d) {\n            if (A.size() == d) {\n                return {true, A, B, Line{(int)px, (int)py, (int)qx, (int)qy}};\n            } else {\n                return {true, B, A, Line{(int)px, (int)py, (int)qx, (int)qy}};\n            }\n        }\n    }\n    // no suitable split found\n    return {false, {}, {}, {}};\n}\n\nint main(){\n    ios::sync_with_stdio(false); cin.tie(0);\n    cin >> N >> K_input;\n    a.resize(11);\n    int Ncheck = 0;\n    for(int d=1;d<=10; ++d) {\n        cin >> a[d];\n        Ncheck += d * a[d];\n    }\n    strawberries.resize(N);\n    for(int i=0;i<N;++i){\n        int x, y; cin >> x >> y;\n        strawberries[i] = {x, y, i};\n    }\n    // Bookkeeping for pieces:\n    vector<vector<int>> pieces; // each as vector of strawberry indices\n    pieces.push_back(vector<int>(N));\n    iota(pieces[0].begin(), pieces[0].end(), 0);\n\n    // For each d from 10 downto 1 (focus on large pieces first)\n    // Alternatively, weighted by number required; for now, 10..1\n    int remains[11];\n    for(int d=1;d<=10;++d) remains[d]=a[d];\n\n    mt19937 rng(123456 + chrono::steady_clock::now().time_since_epoch().count());\n\n    // For cuts\n    vector<Line> used_cuts;\n\n    // For pieces: maintain multiset by size (for quickly finding suitable ones)\n    // Actually, not necessary for up to 1000 pieces\n\n    // Map: pieces_to_process[d]: indices of pieces of size >= d, and not yet processed\n    // We'll go for greedy: for d from 10..1, try to split pieces down\n    // For now, do as explained: try to generate as many pieces of size d as a[d]\n    for(int d=10; d>=1; --d) {\n        int need = remains[d];\n        if(need == 0) continue;\n        // Look for pieces with size >= d\n        // For each round:\n        bool found;\n        int attempts = 0;\n        while(need > 0) {\n            found = false;\n            for(int pi=0; pi<pieces.size(); ++pi) {\n                vector<int> &piece = pieces[pi];\n                if ((int)piece.size() > d) {\n                    // Try bipartition this piece into d and n-d\n                    auto [ok, groupA, groupB, line] = bipartition(piece, d, strawberries, rng);\n                    if(ok) {\n                        // Accept this cut, add it to cuts\n                        used_cuts.push_back(line);\n                        // Remove piece, add groupA, groupB instead\n                        piece = move(groupA);\n                        pieces.push_back(move(groupB));\n                        // Mark found\n                        found = true;\n                        --need;\n                        break; // do next need\n                    }\n                }\n            }\n            if(!found) break; // Could not perform more for this d\n            if((int)used_cuts.size() >= K) break;\n            ++attempts;\n            if(attempts > 1000) break; // Give up (should not be needed)\n        }\n        if((int)used_cuts.size() >= K) break;\n    }\n\n    // Now, after all splits, count how many pieces of each size, up to a[d] per attendee\n    vector<int> cnt(11, 0);\n    for(const auto &piece: pieces) {\n        int sz = piece.size();\n        if(sz >= 1 && sz <= 10) cnt[sz]++;\n    }\n    int total_given = 0;\n    for(int d=1;d<=10;++d) total_given += min(a[d], cnt[d]);\n    // Output cuts\n    int k_out = used_cuts.size();\n    cout << k_out << \"\\n\";\n    for(const auto &line : used_cuts) {\n        cout << line.px << \" \" << line.py << \" \" << line.qx << \" \" << line.qy << \"\\n\";\n    }\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nusing pii = pair<int, int>;\n\nconstexpr int DX[4] = {1, 0, -1, 0};\nconstexpr int DY[4] = {0, 1, 0, -1};\n\nstruct Edge {\n    int x1, y1, x2, y2;\n    Edge(int a,int b,int c,int d) {\n        if (pii(a, b) < pii(c, d)) {\n            x1 = a; y1 = b; x2 = c; y2 = d;\n        } else {\n            x1 = c; y1 = d; x2 = a; y2 = b;\n        }\n    }\n    bool operator < (const Edge& o) const {\n        return tie(x1,y1,x2,y2) < tie(o.x1,o.y1,o.x2,o.y2);\n    }\n};\n\nint N,M;\nvector<vector<int>> board; // 0: empty, 1: dot placed during play, 2: initial dot\nset<pii> dots; // occupied\nset<Edge> used_edges; // segments of perimeters\n\nvector<vector<ll>> weights;\nll S = 0;\nint CENTER;\nvector<array<int,8>> moves;\n\nvoid input() {\n    cin >> N >> M;\n    board.assign(N, vector<int>(N, 0));\n    for (int i = 0; i < M; ++i) {\n        int x,y;\n        cin >> x >> y;\n        board[x][y] = 2;\n        dots.emplace(x, y);\n    }\n    CENTER = (N-1)/2;\n    \n    weights.assign(N, vector<ll>(N, 0));\n    S = 0;\n    for (int x=0; x<N; ++x)\n        for (int y=0; y<N; ++y) {\n            weights[x][y] = (x-CENTER)*(x-CENTER) + (y-CENTER)*(y-CENTER) + 1;\n            S += weights[x][y];\n        }\n}\n\nbool is_valid(int x, int y) {\n    return x>=0 && x<N && y>=0 && y<N;\n}\n\n// For each empty cell, try all rectangles for which it can be one corner, with 3 dots as the other 3 corners\n// Return all candidate rectangles (with highest scoring p1 positions first)\nvector<array<int,8>> find_candidate_moves() {\n    vector<tuple<ll, array<int,8>>> candidates; // score, move\n    // To avoid too much computation, consider only shells near frontier\n    // Let's try to consider all for now (limit time if slow)\n    for (int x1=0; x1<N; ++x1) for (int y1=0; y1<N; ++y1) {\n        if (board[x1][y1] != 0) continue;\n        // For axis-aligned rectangles\n        for (auto& [dx,dy] : vector<pair<int,int>>{{1,0},{0,1}}) {\n            for (int len=1; len<=min(N-1,7); ++len) {\n                int x2 = x1+dx*len, y2 = y1+dy*len;\n                int x4 = x1+dy*len, y4 = y1-dx*len;\n                int x3 = x2+dy*len, y3 = y2-dx*len;\n                if (!is_valid(x2,y2) || !is_valid(x3,y3) || !is_valid(x4,y4)) continue;\n\n                array<pii,4> pts = {pii(x1,y1), pii(x2,y2), pii(x3,y3), pii(x4,y4)};\n                vector<int> ids = {0,1,2,3};\n\n                // try all 3 choose 3 for which the other three points have dots\n                vector<int> dot_idx;\n                for (int i=1; i<4; ++i) if (dots.count(pts[i])) dot_idx.push_back(i);\n                if ((int)dot_idx.size()<3) continue;\n                // Choose all three-point combinations (should be just one for axis-aligned)\n                for (int p=0; p<3; ++p) {\n                    int i2=dot_idx[p%3], i3=dot_idx[(p+1)%3], i4=dot_idx[(p+2)%3];\n                    array<int,8> move = {pts[0].first, pts[0].second, \n                        pts[i2].first, pts[i2].second,\n                        pts[i3].first, pts[i3].second,\n                        pts[i4].first, pts[i4].second\n                    };\n                    // check that the perimeter (except at corners) is empty and doesn't overlap a previous rect's segment\n                    vector<pii> perim = {pts[0], pts[i2], pts[i3], pts[i4]};\n                    bool ok = true;\n                    int sz = (int)perim.size();\n                    // check dots on perimeter but not at corners\n                    for (int j=0; j<sz; ++j) {\n                        int xA=perim[j].first, yA=perim[j].second;\n                        int xB=perim[(j+1)%sz].first, yB=perim[(j+1)%sz].second;\n                        int dx = (xB-xA)?((xB-xA)/abs(xB-xA)):0, dy = (yB-yA)?((yB-yA)/abs(yB-yA)):0;\n                        for (int xm = xA+dx, ym = yA+dy; \n                             xm!=xB||ym!=yB; xm+=dx, ym+=dy) {\n                            if (dots.count({xm, ym})) { ok=false; break; }\n                        }\n                        // Check perimeter overlap\n                        Edge e(xA,yA,xB,yB);\n                        if (used_edges.count(e)) { ok=false; break;}\n                    }\n                    if (ok) {\n                        candidates.emplace_back(weights[x1][y1], move);\n                    }\n                }\n            }\n        }\n        // 45-degree (diamond) rectangles\n        // For d=1 to limit (side increases as sqrt(2)*d)\n        for (int dx=1; dx<=6; ++dx) { // side length (sqrt(2)*dx)\n            int x2 = x1+dx, y2=y1+dx;\n            int x3 = x1, y3 = y1+2*dx;\n            int x4=x1-dx, y4=y1+dx;\n            if (!is_valid(x2,y2)||!is_valid(x3,y3)||!is_valid(x4,y4)) continue;\n            array<pii,4> pts = {pii(x1,y1), pii(x2,y2), pii(x3,y3), pii(x4,y4)};\n            // check that other three are dots\n            vector<int> dot_idx;\n            for (int i=1; i<4; ++i) if (dots.count(pts[i])) dot_idx.push_back(i);\n            if ((int)dot_idx.size()<3) continue;\n            for (int p=0; p<3; ++p) {\n                int i2=dot_idx[p%3], i3=dot_idx[(p+1)%3], i4=dot_idx[(p+2)%3];\n                array<int,8> move = {pts[0].first, pts[0].second, \n                    pts[i2].first, pts[i2].second,\n                    pts[i3].first, pts[i3].second,\n                    pts[i4].first, pts[i4].second\n                };\n                // perimeter check\n                vector<pii> perim = {pts[0], pts[i2], pts[i3], pts[i4]};\n                bool ok = true;\n                int sz = (int)perim.size();\n                for (int j=0; j<sz; ++j) {\n                    int xA=perim[j].first, yA=perim[j].second;\n                    int xB=perim[(j+1)%sz].first, yB=perim[(j+1)%sz].second;\n                    int dx = (xB-xA)?((xB-xA)/abs(xB-xA)):0, dy = (yB-yA)?((yB-yA)/abs(yB-yA)):0;\n                    for (int xm = xA+dx, ym = yA+dy; xm!=xB||ym!=yB; xm+=dx, ym+=dy) {\n                        if (dots.count({xm, ym})) { ok=false; break; }\n                    }\n                    // Check perimeter overlap\n                    Edge e(xA,yA,xB,yB);\n                    if (used_edges.count(e)) { ok=false; break;}\n                }\n                if (ok) {\n                    candidates.emplace_back(weights[x1][y1], move);\n                }\n            }\n        }\n    }\n    sort(candidates.rbegin(), candidates.rend()); // High weight to low weight\n    vector<array<int,8>> res;\n    for (auto& [score,move] : candidates) res.push_back(move);\n    return res;\n}\n\nvoid make_move(const array<int,8>& mv) {\n    int x1=mv[0], y1=mv[1];\n    int x2=mv[2], y2=mv[3];\n    int x3=mv[4], y3=mv[5];\n    int x4=mv[6], y4=mv[7];\n    board[x1][y1]=1;\n    dots.emplace(x1,y1);\n    // Mark used segments\n    vector<pii> pts = {pii(x1,y1), pii(x2,y2), pii(x3,y3), pii(x4,y4)};\n    int sz = (int)pts.size();\n    for (int i=0;i<sz;++i) {\n        int xA=pts[i].first, yA=pts[i].second;\n        int xB=pts[(i+1)%sz].first, yB=pts[(i+1)%sz].second;\n        used_edges.insert(Edge(xA,yA,xB,yB));\n    }\n    moves.push_back(mv);\n}\n\n// Main solve\nvoid solve() {\n    while (true) {\n        vector<array<int,8>> cands = find_candidate_moves();\n        if (cands.empty()) break;\n        // Pick the best (highest weight gain)\n        make_move(cands[0]);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    input();\n    solve();\n    cout << moves.size() << \"\\n\";\n    for (auto& mv : moves) {\n        for (int i=0; i<8; ++i) cout << mv[i] << \" \";\n        cout << \"\\n\";\n    }\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <array>\n#include <algorithm>\n#include <string>\n#include <cassert>\n\nusing namespace std;\n\n// Grid size\nconstexpr int N = 10;\n\n// Mapping flavor to direction:\n// 1: 'L', 2: 'R', 3: 'F'\nconst char FLAVOR_TO_MOVE[4] = {'Z', 'L', 'R', 'F'};\n\nstruct Pos {\n    int y, x;\n};\n\nvoid flush() {\n    cout << flush;\n}\n\n// Given a list of empty cell positions in (row-major order), return the (y,x) for p_t\nPos get_index_from_pt(const vector<array<int,2>>& empties, int p_t) {\n    // p_t: 1-based index\n    assert(p_t >= 1 && p_t <= (int)empties.size());\n    return {empties[p_t-1][0], empties[p_t-1][1]};\n}\n\nvoid move_board(array<array<int, N>, N>& board, char dir) {\n    // Move candies as per direction\n    if (dir == 'F') {\n        // Move all up (decreasing row index)\n        for (int col = 0; col < N; col++) {\n            int write = 0;\n            for (int row = 0; row < N; row++) {\n                if (board[row][col] != 0) {\n                    if (write != row) {\n                        board[write][col] = board[row][col];\n                        board[row][col] = 0;\n                    }\n                    write++;\n                }\n            }\n        }\n    } else if (dir == 'B') {\n        // Move all down (increasing row index)\n        for (int col = 0; col < N; col++) {\n            int write = N-1;\n            for (int row = N-1; row >= 0; --row) {\n                if (board[row][col] != 0) {\n                    if (write != row) {\n                        board[write][col] = board[row][col];\n                        board[row][col] = 0;\n                    }\n                    write--;\n                }\n            }\n        }\n    } else if (dir == 'L') {\n        // Move all left (decreasing col index)\n        for (int row = 0; row < N; row++) {\n            int write = 0;\n            for (int col = 0; col < N; col++) {\n                if (board[row][col] != 0) {\n                    if (write != col) {\n                        board[row][write] = board[row][col];\n                        board[row][col] = 0;\n                    }\n                    write++;\n                }\n            }\n        }\n    } else if (dir == 'R') {\n        // Move all right (increasing col index)\n        for (int row = 0; row < N; row++) {\n            int write = N-1;\n            for (int col = N-1; col >= 0; --col) {\n                if (board[row][col] != 0) {\n                    if (write != col) {\n                        board[row][write] = board[row][col];\n                        board[row][col] = 0;\n                    }\n                    write--;\n                }\n            }\n        }\n    }\n    // else - invalid\n}\n\n// List empty cells in (row,col) order, as in spec\nvector<array<int,2>> get_empty_cells(const array<array<int, N>, N>& board) {\n    vector<array<int,2>> res;\n    for (int row = 0; row < N; ++row)\n        for (int col = 0; col < N; ++col)\n            if (board[row][col] == 0)\n                res.push_back({row, col});\n    return res;\n}\n\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read flavors up-front\n    vector<int> flavors(100);\n    for (int i = 0; i < 100; ++i) {\n        cin >> flavors[i];\n    }\n\n    array<array<int, N>, N> board{};\n    // Fill with zero (empty)\n\n    for (int step = 0; step < 100; ++step) {\n        int p_t;\n        cin >> p_t;\n\n        // Compute empty cell list\n        vector<array<int,2>> empties = get_empty_cells(board);\n\n        // Where does the new candy go?\n        Pos pos = get_index_from_pt(empties, p_t);\n        int flavor = flavors[step];\n        board[pos.y][pos.x] = flavor;\n\n        // Choose tilt direction \u2014 simple baseline: use pre-assigned direction for this flavor\n        char move_dir = FLAVOR_TO_MOVE[flavor];\n\n        // Move candies by gravity in that direction\n        move_board(board, move_dir);\n\n        // Output move\n        if (step != 99) { // Last step doesn't require a move, as per statement\n            cout << move_dir << '\\n';\n            flush();\n        }\n    }\n\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Convert 2d indices to index in upper triangle bitstring\ninline int edge_idx(int i, int j, int N) {\n    // 0 <= i < j < N\n    return i * (N - 1) - (i*(i+1))/2 + (j - i - 1);\n}\n\nstruct Graph {\n    int N;\n    vector<vector<int>> adj;\n    vector<int> degrees;\n    vector<int> deg_hash;      // node degree + neighbor degree sum (node signature)\n    vector<int> sorted_deg;    // degree sequence sorted\n    string code;               // original (non-permuted) bitstr\n\n    Graph(int N_) : N(N_), adj(N), degrees(N,0), deg_hash(N, 0) {}\n\n    // from bitstring\n    Graph(int N_, const string& s) : N(N_), adj(N), degrees(N,0), deg_hash(N,0), code(s) {\n        int idx = 0;\n        for(int i=0;i<N;i++) for(int j=i+1;j<N;j++) {\n            if(s[idx++]=='1') {\n                adj[i].push_back(j);\n                adj[j].push_back(i);\n                degrees[i]++;\n                degrees[j]++;\n            }\n        }\n        for(int i=0;i<N;i++) {\n            int nh = 0;\n            for(int j:adj[i]) nh += degrees[j];\n            deg_hash[i] = (degrees[i] << 7) + nh;\n        }\n        sorted_deg = degrees;\n        sort(sorted_deg.begin(), sorted_deg.end());\n    }\n\n    void build_deg_hash() {\n        for(int i=0;i<N;i++) {\n            int nh = 0;\n            for(int j:adj[i]) nh += degrees[j];\n            deg_hash[i] = (degrees[i] << 7) + nh;\n        }\n        sorted_deg = degrees;\n        sort(sorted_deg.begin(), sorted_deg.end());\n    }\n\n    // For matching: get sorted tuple of per-node deg_hash (signature)\n    vector<int> get_node_signatures() const {\n        vector<int> sig = deg_hash;\n        sort(sig.begin(), sig.end());\n        return sig;\n    }\n\n    // 1-WL color refinement hash: colors mapped to frequency\n    map<int,int> get_color_hist() const {\n        // Start with degree\n        vector<int> color(N);\n        for(int i=0;i<N;++i) color[i] = degrees[i];\n        // Iterate 2 rounds\n        for(int step=0;step<2;++step) {\n            unordered_map<string, int> color_map;\n            for(int i=0;i<N;++i) {\n                vector<int> nb_col;\n                for(int j:adj[i]) nb_col.push_back(color[j]);\n                sort(nb_col.begin(), nb_col.end());\n                stringstream ss;\n                ss << color[i] << \"|\";\n                for(auto col: nb_col) ss << col << \",\";\n                color_map[ss.str()]++;\n            }\n            // Assign new colors\n            int cid=0;\n            unordered_map<string, int> col2id;\n            for(auto& it: color_map)\n                col2id[it.first] = cid++;\n            for(int i=0;i<N;++i) {\n                vector<int> nb_col;\n                for(int j:adj[i]) nb_col.push_back(color[j]);\n                sort(nb_col.begin(), nb_col.end());\n                stringstream ss;\n                ss << color[i] << \"|\";\n                for(auto col: nb_col) ss << col << \",\";\n                color[i] = col2id[ss.str()];\n            }\n        }\n        map<int,int> h;\n        for(int i=0;i<N;++i) h[color[i]]++;\n        return h;\n    }\n};\n\n// Actually returns the edge bitstring representation\nstring graph_to_str(const vector<vector<int>>& adj) {\n    int N = adj.size();\n    string s(N * (N - 1) / 2, '0');\n    for(int i=0, idx=0; i<N; ++i) {\n        for(int j=i+1; j<N; ++j, ++idx) {\n            if(find(adj[i].begin(), adj[i].end(), j) != adj[i].end()) {\n                s[idx] = '1';\n            }\n        }\n    }\n    return s;\n}\n\n\n// Generate a random regular graph with degree d\nvector<vector<int>> random_regular_graph(int N, int d, mt19937& rng) {\n    // Simple stub: use configuration model\n    vector<int> deg(N, d);\n    vector<int> stubs;\n    for(int i=0;i<N;i++) for(int j=0;j<d;j++) stubs.push_back(i);\n    vector<vector<int>> adj(N);\n    for(int tries=0;tries<10;tries++) {\n        auto st = stubs;\n        shuffle(st.begin(), st.end(), rng);\n        vector<vector<int>> to(N);\n        bool good = true;\n        for(int i=0;i<st.size();i+=2) {\n            int u=st[i],v=st[i+1];\n            if(u==v || find(to[u].begin(), to[u].end(), v)!=to[u].end()) {good=false;break;}\n            to[u].push_back(v);\n            to[v].push_back(u);\n        }\n        if(good) return to;\n    }\n    // Fallback: random simple graphs\n    vector<vector<int>> adj2(N);\n    set<pair<int,int>> S;\n    uniform_int_distribution<int> uid(0,N-1);\n    while(S.size() < N*d/2) {\n        int u=uid(rng),v=uid(rng);\n        if(u==v) goto ng;\n        if(S.count({min(u,v),max(u,v)})) goto ng;\n        S.insert({min(u,v),max(u,v)});\n        adj2[u].push_back(v);\n        adj2[v].push_back(u);\n    ng:;\n    }\n    return adj2;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int M;\n    double epsilon;\n    cin >> M >> epsilon;\n\n    // Determine N (vertices count)\n    int N;\n    if(epsilon < 0.2) N = max(20, M+10);\n    else if(epsilon < 0.3) N = max(30, M+20);\n    else N = min(100, max(50, (int)(M + 50)));\n    N = max(4,min(100,N));\n\n    // For randomness\n    random_device rd;\n    mt19937 rng(rd());\n\n    vector<string> codes;\n    vector<Graph> code_graphs;\n    set<string> already;\n    // Gen M graphs -- dense random, or pseudo-random regular\n    int mindeg=N/2;\n    for(int i=0;i<M;i++) {\n        vector<vector<int>> adj;\n        string s;\n        while(true) {\n            adj = random_regular_graph(N, mindeg, rng);\n            s = graph_to_str(adj);\n            if(already.count(s)==0) {already.insert(s); break;}\n        }\n        codes.push_back(s);\n        code_graphs.push_back(Graph(N, s));\n    }\n\n    // Output stage\n    cout << N << endl;\n    for (int i = 0; i < M; ++i) {\n        cout << codes[i] << endl;\n    }\n    cout.flush();\n\n    // Precompute code hashes for matching\n    vector<vector<int>> code_signs(M);\n    vector<map<int,int>> code_colors(M);\n    for(int i=0;i<M;++i) {\n        code_signs[i] = code_graphs[i].get_node_signatures();\n        code_colors[i] = code_graphs[i].get_color_hist();\n    }\n\n    // For decoding: for 100 queries, process...\n    for(int q=0;q<100;++q) {\n        string hs;\n        cin >> hs;\n        Graph h(N, hs);\n        auto h_sign = h.get_node_signatures();\n        auto h_color = h.get_color_hist();\n\n        int best = 0, best_score = 1e9;\n        for(int i=0;i<M;++i) {\n            // Compare sorted node signatures\n            int diff = 0;\n            for(int j=0;j<N;++j) diff += abs(h_sign[j] - code_signs[i][j]);\n            // Compare color histograms\n            int col_diff = 0;\n            for(auto& pr: code_colors[i]) {\n                col_diff += abs(pr.second - h_color[pr.first]);\n            }\n            // Weighted sum\n            int score = diff + 4*col_diff;\n            if(score < best_score) {best_score=score; best=i;}\n        }\n        cout << best << endl;\n        cout.flush();\n    }\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Random engine\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\nint randint(int a, int b) {\n    return uniform_int_distribution<int>(a, b)(rng);\n}\n\nstruct Edge {\n    int u, v, w, id;\n    Edge(int u=0, int v=0, int w=0, int id=0): u(u), v(v), w(w), id(id) {}\n};\n\n// For all-pairs shortest paths, use Dijkstra from SAMPLES nodes for edge importance\nconst int SAMPLES = 25;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, D, K;\n    cin >> N >> M >> D >> K;\n\n    vector<Edge> edges;\n    vector<vector<pair<int,int>>> g(N);\n\n    for (int i = 0; i < M; ++i) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        --u; --v;\n        edges.emplace_back(u, v, w, i);\n        g[u].emplace_back(v, w);\n        g[v].emplace_back(u, w);\n    }\n\n    // Skip coordinates input\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n    }\n\n    // Step 1: Compute all-pairs shortest paths Dijkstra from SAMPLES nodes\n    vector<vector<int>> base_dist(SAMPLES, vector<int>(N, 1e9));\n    vector<int> sample_src;\n    for (int i = 0; i < SAMPLES; ++i)\n        sample_src.push_back(randint(0, N-1));\n\n    for (int si = 0; si < SAMPLES; ++si) {\n        int src = sample_src[si];\n        // Dijkstra\n        vector<int> dist(N, 1e9); dist[src] = 0;\n        using pli = pair<int, int>;\n        priority_queue<pli, vector<pli>, greater<pli>> pq;\n        pq.emplace(0, src);\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u]) continue;\n            for (auto &[v, w]: g[u]) {\n                if (dist[v] > d + w) {\n                    dist[v] = d + w;\n                    pq.emplace(dist[v], v);\n                }\n            }\n        }\n        base_dist[si] = dist;\n    }\n\n    // Step 2: For each edge, compute its importance\n    vector<double> e_importance(M, 0.0);\n\n    for (int eid = 0; eid < M; ++eid) {\n        // Build adjacency list without this edge\n        int u = edges[eid].u, v = edges[eid].v, w = edges[eid].w;\n        vector<vector<pair<int,int>>> gtmp = g;\n        auto erase1 = [&](int a, int b){\n            auto& vec = gtmp[a];\n            for (auto it = vec.begin(); it != vec.end(); ++it)\n                if (it->first == b) { vec.erase(it); break; }\n        };\n        erase1(u, v);\n        erase1(v, u);\n\n        double damage = 0.0;\n        // For each sampled Dijkstra\n        for (int si = 0; si < SAMPLES; ++si) {\n            int src = sample_src[si];\n            vector<int> dist(N, 1e9); dist[src] = 0;\n            using pli = pair<int, int>;\n            priority_queue<pli, vector<pli>, greater<pli>> pq;\n            pq.emplace(0, src);\n            while (!pq.empty()) {\n                auto [d, uu] = pq.top(); pq.pop();\n                if (d > dist[uu]) continue;\n                for (auto &[vv, ww]: gtmp[uu]) {\n                    if (dist[vv] > d + ww) {\n                        dist[vv] = d + ww;\n                        pq.emplace(dist[vv], vv);\n                    }\n                }\n            }\n            for (int j = 0; j < N; ++j) {\n                if (j == src) continue;\n                int before = base_dist[si][j];\n                int after = dist[j];\n                // If unreachable, treat as extra penalty\n                if (after >= 1e9) after = 1e9;\n                damage += (double)(after - before);\n            }\n        }\n        e_importance[eid] = damage / SAMPLES;\n    }\n\n    // Step 3: Schedule edges (sort by importance, assign in snake/zigzag round-robin)\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n\n    sort(order.begin(), order.end(), [&](int i, int j) { return e_importance[i] > e_importance[j]; });\n\n    vector<int> day_of_edge(M, -1);\n    vector<int> day_counts(D, 0);\n\n    int ptr = 0, dir = 1;\n    for (int idx = 0; idx < M; ++idx) {\n        // Assign next edge in sorted order to day ptr\n        while (day_counts[ptr] >= K) {\n            // Find next non-full day\n            ptr += dir;\n            if (ptr == D) { ptr = D-1; dir = -1; }\n            if (ptr == -1) { ptr = 0; dir = 1; }\n        }\n        int eid = order[idx];\n        day_of_edge[eid] = ptr;\n        day_counts[ptr] += 1;\n        // Move pointer (snake fashion)\n        ptr += dir;\n        if (ptr == D) { ptr = D-1; dir = -1; }\n        if (ptr == -1) { ptr = 0; dir = 1; }\n    }\n\n    // Output: for each edge in input order, print day+1 (1-based)\n    for (int i = 0; i < M; ++i) {\n        cout << (day_of_edge[i]+1) << (i + 1 == M ? '\\n' : ' ');\n    }\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\nusing pii = pair<int, int>;\nusing vi = vector<int>;\nusing vvi = vector<vi>;\n\n// --- Helper types for a shape ---\nusing Shape = vector<array<int,3>>;  // sorted relative positions\n\n// All 24 rotation matrices for cube (no reflection), precalculated\nconst vector<array<array<int,3>,3>> ROTATIONS = []{\n    vector<array<array<int,3>,3>> R;\n    // This code produces all 24 possible cube rotations\n    set<vector<array<int,3>,3>> seen;\n    auto apply = [](const array<array<int,3>,3>& M, array<int,3> v) {\n        array<int,3> r;\n        for(int i=0;i<3;++i) r[i] = M[i][0]*v[0] + M[i][1]*v[1] + M[i][2]*v[2];\n        return r;\n    };\n    auto matmul = [](const array<array<int,3>,3>& A, const array<array<int,3>,3>& B) {\n        array<array<int,3>,3> R{};\n        for(int i=0;i<3;++i) for(int j=0;j<3;++j) for(int k=0;k<3;++k)\n            R[i][j] += A[i][k]*B[k][j];\n        return R;\n    };\n    // Basic face rotations\n    vector<array<array<int,3>,3>> faceRots = {\n        {{{1,0,0},{0,1,0},{0,0,1}}},\n        {{{0,0,1},{0,1,0},{-1,0,0}}},\n        {{{-1,0,0},{0,1,0},{0,0,-1}}},\n        {{{0,0,-1},{0,1,0},{1,0,0}}},\n        {{{1,0,0},{0,0,-1},{0,1,0}}},\n        {{{1,0,0},{0,0,1},{0,-1,0}}}\n    };\n    // 0, 90, 180, 270 deg rotations about Y axis\n    vector<array<array<int,3>,3>> yrots = {\n        {{{1,0,0},{0,1,0},{0,0,1}}},\n        {{{0,0,1},{0,1,0},{-1,0,0}}},\n        {{{-1,0,0},{0,1,0},{0,0,-1}}},\n        {{{0,0,-1},{0,1,0},{1,0,0}}}\n    };\n    for(auto& f: faceRots) for(auto& y: yrots) {\n        auto rot = matmul(y, f);\n        // Unique up to 24\n        if(seen.count(rot)) continue;\n        seen.insert(rot);\n        R.push_back(rot);\n    }\n    return R;\n}();\n\nShape canonicalize(const Shape& shape) {\n    // Centers at (0,0,0), returns smallest lex order under all 24 rotations\n    vector<Shape> candidates;\n\n    for(const auto &rot: ROTATIONS) {\n        Shape s;\n        for(auto p: shape) {\n            array<int,3> q = {0,0,0};\n            for(int i=0;i<3;++i)\n                q[i] = rot[i][0]*p[0] + rot[i][1]*p[1] + rot[i][2]*p[2];\n            s.push_back(q);\n        }\n        // Now, shift min to (0,0,0)\n        int minx=1e9,miny=1e9,minz=1e9;\n        for(auto &q: s) {\n            minx = min(minx, q[0]);\n            miny = min(miny, q[1]);\n            minz = min(minz, q[2]);\n        }\n        for(auto &q: s) {\n            q[0] -= minx;\n            q[1] -= miny;\n            q[2] -= minz;\n        }\n        sort(s.begin(), s.end());\n        candidates.push_back(s);\n    }\n    return *min_element(candidates.begin(), candidates.end());\n}\n\n// Encodes a shape for hash-comparison\nstring shape_to_str(const Shape& s) {\n    string out;\n    for(auto p: s) for(int x:p) out+=\",\"+to_string(x);\n    return out;\n}\n\n// For blocks found inside an object\nstruct FoundBlock {\n    int anchor_x, anchor_y, anchor_z;\n    Shape s;\n    vector<array<int,3>> global_voxels; // absolute position for each cell\n};\n\n// Greedy maximal cube cover of mask\nvector<FoundBlock> greedy_cover(const vector<vector<vector<int>>> &mask, int D) {\n    // 0: empty or already assigned, 1: needs assigning\n    vector<vector<vector<int>>> rem = mask;\n    vector<FoundBlock> blocks;\n    vector<vector<vector<int>>> vis(D, vector<vector<int>>(D,vector<int>(D,0)));\n    // Greedily cover big cubes then lines then single\n    auto inside = [&](int x,int y,int z) {\n        return 0<=x && x<D && 0<=y && y<D && 0<=z && z<D;\n    };\n    int filled=0, total=0;\n    for(int x=0;x<D;++x) for(int y=0;y<D;++y) for(int z=0;z<D;++z)\n        if(mask[x][y][z]) total++;\n    while(filled<total) {\n        int bestV=-1, bx,by,bz,bsize;\n        string bdir; // \"cube\", \"x\", \"y\", \"z\"\n        // Try cube of size sz, largest first\n        for(int sz = min(5,D); sz>=2; --sz) { // Cube SZxSZxSZ\n            for(int x=0;x<=D-sz;++x) for(int y=0;y<=D-sz;++y) for(int z=0;z<=D-sz;++z) {\n                bool ok=1;\n                int cnt=0;\n                for(int dx=0;dx<sz&&ok;++dx) for(int dy=0;dy<sz;++dy) for(int dz=0;dz<sz;++dz)\n                    if(!rem[x+dx][y+dy][z+dz]) { ok=0; break; }\n                if(!ok) continue;\n                cnt = sz*sz*sz;\n                if(cnt>bestV) {\n                    bx=x; by=y; bz=z; bsize=sz; bestV=cnt; bdir=\"cube\";\n                }\n            }\n        }\n        // Try MAX-length lines (x/y/z)\n        for(int d=0;d<3;++d) {\n            for(int sz = min(D,7); sz>=2; --sz) {\n                for(int x=0; x<D; ++x) for(int y=0; y<D; ++y) for(int z=0; z<D; ++z) {\n                    int dx = (d==0), dy=(d==1), dz=(d==2);\n                    bool ok=1;\n                    if(inside(x+(sz-1)*dx,y+(sz-1)*dy,z+(sz-1)*dz)==0) continue;\n                    for(int i=0;i<sz;++i) {\n                        int nx=x+i*dx, ny=y+i*dy, nz=z+i*dz;\n                        if(!rem[nx][ny][nz]) {ok=0;break;}\n                    }\n                    if(!ok) continue;\n                    if(sz > bestV) {\n                        bx=x; by=y; bz=z; bsize=sz; bestV=sz; \n                        if(d==0) bdir=\"x\"; else if(d==1) bdir=\"y\"; else bdir=\"z\";\n                    }\n                }\n            }\n        }\n        if(bestV==-1) {\n            // Just fill random remaining 1 cell\n            for(int x=0;x<D;++x) for(int y=0;y<D;++y) for(int z=0;z<D;++z)\n                if(rem[x][y][z]) {\n                    bx=x; by=y; bz=z; bsize=1; bestV=1; bdir=\"pt\";\n                    goto ok_found;\n                }\n        }\nok_found:;\n        // Build FoundBlock\n        FoundBlock fb;\n        fb.anchor_x = bx; fb.anchor_y = by; fb.anchor_z = bz;\n        Shape s;\n        vector<array<int,3>> vox;\n        if(bdir==\"cube\") {\n            for(int dx=0;dx<bsize;++dx) for(int dy=0;dy<bsize;++dy) for(int dz=0;dz<bsize;++dz) {\n                int x=bx+dx, y=by+dy, z=bz+dz;\n                s.push_back({dx,dy,dz});\n                vox.push_back({x,y,z});\n                rem[x][y][z]=0; filled++;\n            }\n        } else if(bdir==\"x\"||bdir==\"y\"||bdir==\"z\") {\n            int dx=(bdir==\"x\"),dy=(bdir==\"y\"),dz=(bdir==\"z\");\n            for(int i=0;i<bsize;++i) {\n                int x=bx + dx*i, y=by + dy*i, z=bz + dz*i;\n                s.push_back({dx*i,dy*i,dz*i});\n                vox.push_back({x,y,z});\n                rem[x][y][z]=0; filled++;\n            }\n        } else {\n            s.push_back({0,0,0});\n            vox.push_back({bx,by,bz});\n            rem[bx][by][bz]=0; filled++;\n        }\n        fb.s = s;\n        fb.global_voxels = vox;\n        blocks.push_back(fb);\n    }\n    return blocks;\n}\n\n// Now try \"match\" blocks between two silhouette objects by canonical polycube\nvoid assign_block_numbers(\n    vector<FoundBlock>& blocksA, vector<FoundBlock>& blocksB, \n    map<string, vector<pair<int,FoundBlock*>>>& blockDict,\n    map<int,int>& block_to_global_number, int &global_block_counter\n) {\n    // Place all found blocks in dict by canonical form\n    for(int i=0; i<blocksA.size(); ++i) {\n        Shape can = canonicalize(blocksA[i].s);\n        string key = shape_to_str(can);\n        blockDict[key].emplace_back(0, &blocksA[i]);\n    }\n    for(int i=0; i<blocksB.size(); ++i) {\n        Shape can = canonicalize(blocksB[i].s);\n        string key = shape_to_str(can);\n        blockDict[key].emplace_back(1, &blocksB[i]);\n    }\n    // For each unique block (canonical), assign a global number, and set in block_to_global_number\n    for(auto& [key, vec]: blockDict) {\n        // See if used in both A, B\n        bool hasA=0, hasB=0;\n        for(auto& [who,_]:vec) if(who==0) hasA=1; else hasB=1;\n        ++global_block_counter;\n        int my_number = global_block_counter;\n        for(auto& [who,ptr]:vec) {\n            ptr->anchor_x = my_number; // overload to store number for assignment\n        }\n    }\n}\n\n// Output for one object: For each cell in D^3, output block number\nvector<int> gen_assignment(const vector<FoundBlock>& blocks, int D) {\n    vector<int> ans(D*D*D,0);\n    for(auto& fb: blocks) {\n        int block_number = fb.anchor_x;\n        for(auto& q: fb.global_voxels) {\n            int idx = q[0]*D*D + q[1]*D + q[2];\n            ans[idx] = block_number;\n        }\n    }\n    return ans;\n}\n\n// --- Main solution function ---\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int D;\n    cin >> D;\n    vector<vector<string>> F(2, vector<string>(D));\n    vector<vector<string>> R(2, vector<string>(D));\n    for(int s=0;s<2;++s) for(int i=0;i<D;++i) cin>>F[s][i];\n    for(int s=0;s<2;++s) for(int i=0;i<D;++i) cin>>R[s][i];\n\n    // Build 3D mask for each object\n    auto build_mask = [&](int idx) {\n        vector<vector<vector<int>>> mask(D, vector<vector<int>>(D,vector<int>(D,0)));\n        for(int x=0;x<D;++x) for(int y=0;y<D;++y) for(int z=0;z<D;++z) {\n            if(F[idx][z][x]=='1' && R[idx][z][y]=='1')\n                mask[x][y][z]=1;\n        }\n        return mask;\n    };\n    vector<vector<vector<int>>> mask1 = build_mask(0);\n    vector<vector<vector<int>>> mask2 = build_mask(1);\n\n    // Greedy cover for both\n    auto blocksA = greedy_cover(mask1, D);\n    auto blocksB = greedy_cover(mask2, D);\n\n    // Now assign global block numbers (by matching shapes)\n    map<string, vector<pair<int,FoundBlock*>>> blockDict;\n    map<int,int> block_to_global_number;\n    int global_block_counter = 0;\n    assign_block_numbers(blocksA, blocksB, blockDict, block_to_global_number, global_block_counter);\n\n    int n_blocks = global_block_counter;\n    cout << n_blocks << '\\n';\n    // Output for two objects\n    vector<int> out1 = gen_assignment(blocksA, D);\n    vector<int> out2 = gen_assignment(blocksB, D);\n    for(int i=0;i<out1.size();++i) {\n        cout << out1[i];\n        if(i+1!=out1.size()) cout << \" \";\n    }\n    cout << endl;\n    for(int i=0;i<out2.size();++i) {\n        cout << out2[i];\n        if(i+1!=out2.size()) cout << \" \";\n    }\n    cout << endl;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <queue>\n#include <algorithm>\n#include <limits>\nusing namespace std;\n\nstruct Edge {\n    int u, v, idx;\n    long long w;\n    bool operator<(const Edge& o) const { return w < o.w; }\n};\n\nstruct DSU {\n    vector<int> p;\n    DSU(int n): p(n,-1) {}\n    int find(int x) {\n        while (p[x] >= 0) {\n            if (p[p[x]] >= 0) p[x] = p[p[x]];\n            x = p[x];\n        }\n        return x;\n    }\n    bool unite(int x,int y) {\n        x = find(x);\n        y = find(y);\n        if (x == y) return false;\n        if (p[x] > p[y]) swap(x,y);\n        p[x] += p[y];\n        p[y] = x;\n        return true;\n    }\n};\n\nint main() {\n    // Fast IO\n    ios::sync_with_stdio(false); cin.tie(0);\n\n    int N, M, K;\n    cin >> N >> M >> K;\n    vector<pair<int, int>> nodes(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> nodes[i].first >> nodes[i].second;\n    }\n    vector<Edge> edges(M);\n    for (int j = 0; j < M; ++j) {\n        int u, v;\n        long long w;\n        cin >> u >> v >> w;\n        edges[j] = {u-1, v-1, j, w};\n    }\n    vector<pair<int, int>> residents(K);\n    for (int k = 0; k < K; ++k) {\n        cin >> residents[k].first >> residents[k].second;\n    }\n\n    // 1. Build MST for basic connectivity\n    vector<int> on(M, 0);\n    sort(edges.begin(), edges.end());\n    DSU dsu(N);\n    vector<vector<pair<int, int>>> g(N); // Node, edge id\n    int cnt = 0;\n    for (auto& e : edges) {\n        if (dsu.unite(e.u, e.v)) {\n            on[e.idx] = 1;\n            g[e.u].push_back({e.v, e.idx});\n            g[e.v].push_back({e.u, e.idx});\n            ++cnt;\n            if (cnt == N-1) break;\n        }\n    }\n    // BFS from node 0 to get all reachable\n    vector<bool> vis(N, 0);\n    queue<int> q;\n    vis[0] = true;\n    q.push(0);\n    while (!q.empty()) {\n        int v = q.front(); q.pop();\n        for (auto& [to, ei] : g[v]) if (!vis[to]) {\n            vis[to] = true;\n            q.push(to);\n        }\n    }\n    vector<int> reachable;\n    for (int i = 0; i < N; ++i)\n        if (vis[i]) reachable.push_back(i);\n\n    // 2. Assign all residents to their closest broadcasting node\n    vector<int> assigned(K, -1);\n    vector<vector<int>> cell(N);\n    for (int k = 0; k < K; ++k) {\n        int best = -1;\n        long long best_d = numeric_limits<long long>::max();\n        for (int v : reachable) {\n            long long dx = nodes[v].first - residents[k].first;\n            long long dy = nodes[v].second - residents[k].second;\n            long long d2 = dx*dx + dy*dy;\n            if (d2 < best_d) {\n                best = v; best_d = d2;\n            }\n        }\n        assigned[k] = best;\n        cell[best].push_back(k);\n    }\n\n    // 3. For each node, set output strength to minimal for its cell\n    vector<int> Pi(N, 0);\n    for (int v : reachable) {\n        int max_dist = 0;\n        for (int k : cell[v]) {\n            int dx = nodes[v].first - residents[k].first;\n            int dy = nodes[v].second - residents[k].second;\n            int dist = (int)ceil(sqrt(dx*dx + dy*dy));\n            if (dist > max_dist) max_dist = dist;\n        }\n        Pi[v] = max_dist;\n        if (Pi[v] > 5000) Pi[v] = 5000;\n    }\n\n    // Output for contest\n    for (int i = 0; i < N; ++i) cout << Pi[i] << (i+1==N ? '\\n' : ' ');\n    for (int j = 0; j < M; ++j) cout << on[j] << (j+1==M ? '\\n' : ' ');\n\n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <algorithm>\n#include <queue>\n#include <cassert>\n\nusing namespace std;\n\nconstexpr int N = 30;\nconstexpr int NN = N*(N+1)/2;\nconstexpr int MAX_MOVE = 10000;\n\n// For each position (x,y), return its two children (if any)\ninline bool has_child(int x, int y) {\n    return x < N-1;\n}\n\ninline pair<pair<int,int>, pair<int,int>> get_children(int x, int y) {\n    // Returns (x+1,y), (x+1,y+1)\n    return {{x+1, y}, {x+1, y+1}};\n}\n\n// Valid (x,y) if: 0 <= x < N, 0 <= y <= x\ninline bool is_valid(int x, int y) {\n    return 0 <= x && x < N && 0 <= y && y <= x;\n}\n\n// For swaps: list of direction vectors\nconst int dx[6] = {-1, -1, 0, 0, 1, 1};\nconst int dy[6] = {-1, 0, -1, 1, 0, 1};\n\n// Given two (x,y), (x2,y2), are they adjacent in six directions?\ninline bool is_adjacent(int x1, int y1, int x2, int y2) {\n    for(int d=0; d<6; ++d) {\n        if(x1+dx[d]==x2 && y1+dy[d]==y2) return true;\n    }\n    return false;\n}\n\n// Output swap operation; update grid and store move\nstruct MoveRecorder {\n    vector<tuple<int,int,int,int>> moves;\n    int K = 0;\n    vector<vector<int>> &grid;\n    // only to quickly update (label -> position)\n    vector<pair<int,int>> &label_pos;\n\n    MoveRecorder(vector<vector<int>> &g, vector<pair<int,int>> &lp): grid(g), label_pos(lp){}\n    void do_swap(int x1, int y1, int x2, int y2) {\n        using std::swap;\n        assert(is_adjacent(x1, y1, x2, y2));\n        swap(grid[x1][y1], grid[x2][y2]);\n        // update label position\n        label_pos[grid[x1][y1]] = {x1, y1};\n        label_pos[grid[x2][y2]] = {x2, y2};\n        moves.emplace_back(x1, y1, x2, y2);\n        K++;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    // Read grid\n    vector<vector<int>> grid(N);\n    vector<pair<int,int>> label_pos(NN); // label -> (x,y)\n    for(int x=0; x<N; ++x) {\n        grid[x].resize(x+1);\n        for(int y=0; y<=x; ++y) {\n            cin >> grid[x][y];\n            label_pos[grid[x][y]] = {x, y};\n        }\n    }\n\n    MoveRecorder recorder(grid, label_pos);\n\n    int passes = 0;\n    while(recorder.K < MAX_MOVE) {\n        bool changed = false;\n        for(int x=0; x<N-1; ++x) {\n            for(int y=0; y<=x; ++y) {\n                int v = grid[x][y];\n                // Consider two children\n                auto [l, r] = get_children(x, y);\n                int x1=l.first, y1=l.second, x2=r.first, y2=r.second;\n                // if v > left child, bubble down\n                if(grid[x1][y1] < v) {\n                    // To move v down, swap with child, keep going\n                    int cx = x, cy = y;\n                    while(cx < N-1) {\n                        auto [cl, cr] = get_children(cx, cy);\n                        int c1x=cl.first, c1y=cl.second, c2x=cr.first, c2y=cr.second;\n                        int child1 = grid[c1x][c1y], child2 = grid[c2x][c2y];\n                        if(grid[c1x][c1y] < grid[c2x][c2y]) {\n                            // swap with c1\n                            recorder.do_swap(cx, cy, c1x, c1y);\n                            cx = c1x; cy = c1y;\n                        } else {\n                            // swap with c2\n                            recorder.do_swap(cx, cy, c2x, c2y);\n                            cx = c2x; cy = c2y;\n                        }\n                        if(recorder.K >= MAX_MOVE) break;\n                    }\n                    changed = true;\n                    if(recorder.K >= MAX_MOVE) break;\n                }\n                else if(grid[x2][y2] < v) {\n                    // Bubble down to right child\n                    int cx = x, cy = y;\n                    while(cx < N-1) {\n                        auto [cl, cr] = get_children(cx, cy);\n                        int c1x=cl.first, c1y=cl.second, c2x=cr.first, c2y=cr.second;\n                        int child1 = grid[c1x][c1y], child2 = grid[c2x][c2y];\n                        if(grid[c2x][c2y] < grid[c1x][c1y]) {\n                            // swap with c2 (right child)\n                            recorder.do_swap(cx, cy, c2x, c2y);\n                            cx = c2x; cy = c2y;\n                        } else {\n                            // swap with c1\n                            recorder.do_swap(cx, cy, c1x, c1y);\n                            cx = c1x; cy = c1y;\n                        }\n                        if(recorder.K >= MAX_MOVE) break;\n                    }\n                    changed = true;\n                    if(recorder.K >= MAX_MOVE) break;\n                }\n                if(recorder.K >= MAX_MOVE) break;\n            }\n            if(recorder.K >= MAX_MOVE) break;\n        }\n        passes++;\n        if(!changed) break;\n        if(recorder.K >= MAX_MOVE) break;\n    }\n\n    // Output move sequence\n    cout << recorder.K << '\\n';\n    for(const auto& [x1, y1, x2, y2]: recorder.moves) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << \"\\n\";\n    }\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int D = 9;\nconstexpr int ENTRANCE_I = 0;\nconstexpr int ENTRANCE_J = (D-1)/2;\nconst int di[] = {-1,1,0,0}, dj[] = {0,0,-1,1};\n\nstruct Cell {\n    int i, j;\n    Cell(int i=0, int j=0):i(i),j(j){}\n    bool operator==(const Cell& o) const { return i==o.i && j==o.j; }\n    bool operator!=(const Cell& o) const { return !(*this==o); }\n};\n\nostream& operator<<(ostream& os, const Cell& c) {\n    return os << c.i << ' ' << c.j;\n}\n\nbool in_grid(int i, int j) {\n    return 0 <= i && i < D && 0 <= j && j < D;\n}\n\nvector<Cell> adj4(Cell c) {\n    vector<Cell> v;\n    for(int d=0;d<4;++d) {\n        int ni = c.i+di[d], nj = c.j+dj[d];\n        if(in_grid(ni,nj)) v.emplace_back(ni,nj);\n    }\n    return v;\n}\n\n// For quickly assigning container numbers to positions.\nstruct WarehouseSolver {\n    int N;\n    set<Cell> obstacles;\n    set<Cell> not_assignable; // entrance + 3 adjacents + obstacles\n    vector<Cell> assignable_cells; // order by BFS from entrance\n    map<Cell, int> cell_to_bfs_layer;\n\n    // Storage state\n    vector<pair<int,int>> arrivals; // (container number, arrival idx)\n    map<Cell, int> assigned_cell_to_num;\n    map<int, Cell> num_to_cell;\n\n    // Extraction ordering\n    vector<Cell> extraction_order;\n\n    WarehouseSolver() {}\n\n    void initialize() {\n        // Build not_assignable: entrance & its 3 adjacents & obstacles\n        not_assignable.insert(Cell(ENTRANCE_I, ENTRANCE_J));\n        for(int d=0;d<4;++d) {\n            int ni = ENTRANCE_I+di[d], nj = ENTRANCE_J+dj[d];\n            if(in_grid(ni,nj))\n                not_assignable.insert(Cell(ni,nj));\n        }\n        for(auto c: obstacles) not_assignable.insert(c);\n\n        // BFS from entrance to get \"ranked\" assignable cells\n        vector<vector<int>> vis(D, vector<int>(D, -1));\n        queue<Cell> q;\n        q.push(Cell(ENTRANCE_I, ENTRANCE_J));\n        vis[ENTRANCE_I][ENTRANCE_J]=0;\n        int dist = 1;\n        // Pre-mark not_assignable so we don't revisit\n        for(auto c: not_assignable) vis[c.i][c.j]=-2;\n        vis[ENTRANCE_I][ENTRANCE_J]=0; // entrance\n\n        vector<Cell> order;\n        while(!q.empty()) {\n            Cell c = q.front();q.pop();\n            for(auto d: adj4(c)) {\n                if(vis[d.i][d.j] == -1) {\n                    vis[d.i][d.j] = vis[c.i][c.j]+1;\n                    q.push(d);\n                    // If it's assignable (not in not_assignable), add to order\n                    if(not_assignable.count(d) == 0) {\n                        assignable_cells.push_back(d);\n                        cell_to_bfs_layer[d] = vis[d.i][d.j];\n                    }\n                }\n            }\n        }\n    }\n\n    void read_input() {\n        cin >> N;\n        for(int k=0;k<N;++k) {\n            int ri,rj;\n            cin >> ri >> rj;\n            obstacles.insert(Cell(ri,rj));\n        }\n        initialize();\n    }\n\n    void assign_container(int t_d, int arrival_idx) {\n        // Add to arrivals\n        arrivals.emplace_back(t_d, arrival_idx);\n        // We need to select an assignable cell for it.\n\n        // For containers arrived so far, make a sorted list\n        vector<pair<int,int>> sorted_arrivals = arrivals;\n        sort(sorted_arrivals.begin(), sorted_arrivals.end()); // by t_d\n        // Their optimal mapping: map sorted_arrivals[i] to assignable_cells[i]\n        // For current container (arrival_idx), find where it lands\n        int pos = -1;\n        for(int i=0;i<sorted_arrivals.size();++i) {\n            if(sorted_arrivals[i].second == arrival_idx) {\n                pos = i;\n                break;\n            }\n        }\n        assert(pos != -1);\n\n        // Some assignable_cells may already be assigned: must choose the first unassigned slot corresponding to pos (since in rare cases, due to obstacles, not all cells may be left)\n        vector<bool> used(assignable_cells.size(), false);\n        for(auto& kv: assigned_cell_to_num) {\n            // Mark which slots are taken\n            for(int i=0;i<assignable_cells.size();++i) {\n                if(assignable_cells[i]==kv.first) used[i]=true;\n            }\n        }\n        // Assign in sorted order: for the list of arrivals (sorting by t_d), map to available slots in assignable_cells in order, skipping used ones.\n        int assign_slot = -1, cnt = 0;\n        for(int i=0;i<assignable_cells.size();++i) {\n            if(used[i]) continue;\n            if(cnt==pos) { assign_slot=i; break; }\n            cnt++;\n        }\n        assert(assign_slot != -1);\n        Cell assign_cell = assignable_cells[assign_slot];\n\n        // Assign this cell to the container num\n        assigned_cell_to_num[assign_cell] = t_d;\n        num_to_cell[t_d] = assign_cell;\n\n        // Output assignment\n        cout << assign_cell.i << \" \" << assign_cell.j << endl;\n        cout.flush();\n    }\n\n    // After all containers are placed, plan extraction order.\n    void plan_extraction() {\n        // Build grid state: 0=empty, -1=obstacle, >0=container num+1\n        vector<vector<int>> grid(D, vector<int>(D,0));\n        for(auto c: obstacles) grid[c.i][c.j]=-1;\n        for(auto& [cell, num]: assigned_cell_to_num) grid[cell.i][cell.j]=num+1;\n\n        set<int> remaining_nums;\n        for(auto& [num, cell]: num_to_cell) remaining_nums.insert(num);\n\n        extraction_order.clear();\n\n        for(int step=0;step < num_to_cell.size(); ++step) {\n            // Find all containers (cells with grid>0) reachable from entrance\n            queue<Cell> q;\n            vector<vector<bool>> vis(D,vector<bool>(D,false));\n            q.push(Cell(ENTRANCE_I, ENTRANCE_J));\n            vis[ENTRANCE_I][ENTRANCE_J]=true;\n\n            set<Cell> reachable;\n            while(!q.empty()) {\n                Cell c = q.front();q.pop();\n                for(auto d: adj4(c)) {\n                    if(!vis[d.i][d.j]) {\n                        if(grid[d.i][d.j] == 0) {\n                            vis[d.i][d.j]=true;q.push(d);\n                        } else if(grid[d.i][d.j]>0) {\n                            // It's a container\n                            reachable.insert(d);\n                        }\n                    }\n                }\n            }\n            // From reachable, pick container with smallest num\n            int best_num = 1e9;\n            Cell best_cell;\n            for(auto c: reachable) {\n                int num = grid[c.i][c.j]-1;\n                if(num < best_num) { best_num = num; best_cell = c; }\n            }\n            extraction_order.push_back(best_cell);\n\n            // Remove this from grid\n            grid[best_cell.i][best_cell.j] = 0;\n            remaining_nums.erase(best_num);\n        }\n    }\n\n    void output_extraction_order() {\n        for(auto& c: extraction_order) {\n            cout << c.i << \" \" << c.j << endl;\n        }\n        cout.flush();\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D_input, N;\n    cin >> D_input >> N;\n    assert(D_input==D);\n\n    WarehouseSolver solver;\n    solver.N=N;\n    for(int k=0;k<N;++k) {\n        int ri,rj; cin >> ri >> rj;\n        solver.obstacles.insert(Cell(ri,rj));\n    }\n    solver.initialize(); // needs to be called after obstacles are set up\n\n    const int K = D*D-1-N;\n    for(int d=0; d<K; ++d) {\n        int t_d; cin >> t_d;\n        solver.assign_container(t_d, d);\n    }\n    // After all placements\n    solver.plan_extraction();\n    solver.output_extraction_order();\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 50, M = 100, COLORS = 101;\nint n, m;\nint c[N][N];\n\n// For each color, set of adjacent colors (including 0)\nvector<set<int>> adjacency(COLORS);\n// Whether color c touches the edge (adjacent to outside/0)\nvector<bool> touches0(COLORS);\n\n// For output\nint d[N][N];\n\n// Direction vectors\nconstexpr int di[] = {-1, 0, 1, 0};\nconstexpr int dj[] = {0, 1, 0, -1};\n\n// Compose adjacency graph for all colors from input\nvoid build_adjacency() {\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j) {\n            int col = c[i][j];\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir], nj = j + dj[dir];\n                if (ni < 0 || nj < 0 || ni >= n || nj >= n) {\n                    adjacency[col].insert(0);\n                    adjacency[0].insert(col);\n                    touches0[col] = true;\n                } else if (c[ni][nj] != col) {\n                    adjacency[col].insert(c[ni][nj]);\n                }\n            }\n        }\n}\n\n// List of wards (colors)\nvector<int> all_wards() {\n    vector<int> wards;\n    for (int i = 1; i <= m; ++i) wards.push_back(i);\n    return wards;\n}\n\n// Assign output locations for each ward (color)\n// Ensures border-wards go to boundary.\nmap<int, pair<int,int>> assign_ward_positions(const vector<int>& wards) {\n    map<int,pair<int,int>> pos;\n    set<pair<int,int>> used;\n    // 1. Lay out border-wards\n    vector<pair<int,int>> border_spots;\n    for (int i = 0; i < n; ++i) {\n        border_spots.emplace_back(0, i);\n        border_spots.emplace_back(n-1, i);\n    }\n    for (int j = 1; j < n-1; ++j) {\n        border_spots.emplace_back(j, 0);\n        border_spots.emplace_back(j, n-1);\n    }\n    int bi = 0;\n\n    // 2. Inner spots for rest\n    vector<pair<int,int>> inner_spots;\n    for (int i = 1; i < n-1; ++i)\n        for (int j = 1; j < n-1; ++j)\n            inner_spots.emplace_back(i,j);\n    int ii = 0;\n\n    // Wards sorted: priority to those with more adjacents\n    vector<int> order = wards;\n    sort(order.begin(), order.end(), [](int a, int b) {\n        return adjacency[a].size() > adjacency[b].size();\n    });\n\n    for (int ward : order) {\n        if (touches0[ward] && bi < (int)border_spots.size()) {\n            // Assign to border\n            pos[ward] = border_spots[bi++];\n            used.insert(pos[ward]);\n        } else if (ii < (int)inner_spots.size()) {\n            pos[ward] = inner_spots[ii++];\n            used.insert(pos[ward]);\n        } else {\n            // fallback (should not happen)\n            pos[ward] = make_pair(0,0);\n        }\n    }\n    return pos;\n}\n\n// Fill in the output grid according to assigned ward positions and enforce adjacency requirements.\nvoid build_output_map(const map<int, pair<int,int>>& ward_pos) {\n    // Clear to zero\n    for (int i=0;i<n;++i) for (int j=0;j<n;++j) d[i][j]=0;\n\n    // Place all the wards in their assigned cell\n    for (const auto& [ward, p] : ward_pos) {\n        d[p.first][p.second] = ward;\n    }\n\n    // Now, for each adjacency, ensure the pair is represented by a pair of adjacent cells on the grid.\n    // Try to do this with minimal area addition.\n    for (int c = 1; c <= m; ++c) {\n        for (int dcol : adjacency[c]) {\n            if (dcol < c) continue; // Each pair once (and skip dcol=0 for now, handlded by positions on boundary)\n\n            auto [ci, cj] = ward_pos.at(c);\n            auto [di_, dj_] = ward_pos.at(dcol);\n\n            // Are they adjacent in the grid?\n            if (abs(ci-di_)+abs(cj-dj_) ==1) continue;\n\n            // Otherwise, connect them along Manhattan path with their own colors\n            int curi = ci, curj = cj;\n            // Let's make a path from (ci,cj) to (di_,dj_) (no '0' along the way)\n            while (curi != di_) {\n                curi += (di_ > curi) ? 1 : -1;\n                if (d[curi][curj] == 0)\n                    d[curi][curj] = c;\n            }\n            while (curj != dj_) {\n                curj += (dj_ > curj) ? 1 : -1;\n                if (d[curi][curj] == 0)\n                    d[curi][curj] = c;\n            }\n        }\n    }\n}\n\n// Validation helpers (not used in contest submission)\n// Check all same-color cells are connected (DFS)\n// Check adjacencies\n\n// Full solution\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    n = N; m = M;\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j)\n            cin >> c[i][j];\n\n    adjacency.assign(COLORS, set<int>());\n    touches0.assign(COLORS, false);\n\n    build_adjacency();\n\n    vector<int> wards = all_wards();\n\n    auto ward_pos = assign_ward_positions(wards);\n\n    build_output_map(ward_pos);\n\n    // Output result\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cout << d[i][j] << \" \\n\"[j==n-1];\n        }\n    }\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\n// --------------- Fast IO -----------------\nvoid fastio() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); }\nvoid flush() { cout.flush(); }\n\n// --------------- Definitions --------------\nint N, D, Q;  // Number, Divisions, Queries\nint query_count = 0;\n\n// ------ Query balance; ask L vs R; returns -1 (L<R), 0 (L=R), 1 (L>R) ------\nint askBalance(const vector<int>& L, const vector<int>& R) {\n    assert(!L.empty() && !R.empty());\n    assert(query_count < Q);\n    cout << L.size() << \" \" << R.size() << \" \";\n    for(int x : L) cout << x << \" \";\n    for(int x : R) cout << x << \" \";\n    cout << \"\\n\";\n    flush();\n\n    string s; cin >> s;\n    query_count++;\n\n    if(s == \"<\") return -1;\n    if(s == \"=\") return 0;\n    if(s == \">\") return 1;\n    // Should not happen\n    cerr << \"Unknown judge response: \" << s << endl;\n    exit(1);\n}\n\n// Pairwise comparator cache to avoid redundant queries\nvector<vector<int>> compare_cache; // -2 means unset\n\nint cmp_items(int a, int b) {\n    // Return 1 if a > b, -1 if a < b, 0 if tie\n    if(compare_cache[a][b] != -2)\n        return compare_cache[a][b];\n    int res = askBalance({a}, {b});\n    compare_cache[a][b] = res;\n    compare_cache[b][a] = -res;\n    return res;\n}\n\n// --------------- Comparison sort on indices ---------------\n// You can replace this with a merge sort or use std::sort with comp lambda.\nvector<int> sorted_items;\n\nbool cmp_wrapper(int a, int b) {\n    int r = cmp_items(a, b);\n    return (r > 0); // \"a\" goes before \"b\" if a > b\n}\n\n// -------------- Greedy Group Assignment ---------------\n// Assign items in sorted_items (from heavy to light) to D groups, greedily minimizing imbalance\nvector<int> assign_to_groups(const vector<int>& sorted_items) {\n    vector<long long> group_sum(D, 0); // only for simulation, actually unknown\n    vector<vector<int>> groups(D);\n    vector<int> assignment(N, -1); // assignment[i] = d\n\n    // Spread the \"heaviest\" items to different groups first (stripe assignment in order)\n    // Then assign remaining items to group with lowest total so far (greedy fit)\n    for(int idx=0; idx < N; ++idx) {\n        int itm = sorted_items[idx];\n        // First, assign 1 item to each group round-robin (ensures each group nonempty)\n        int d;\n        if(idx < D) d = idx;\n        else {\n            // After initial, assign to \"currently lightest\" group\n            d = min_element(group_sum.begin(), group_sum.end()) - group_sum.begin();\n        }\n        assignment[itm] = d;\n        groups[d].push_back(itm);\n        // (group_sum unknown! If you have an estimate, update it here)\n        // For true scoring, use estimate; here just use index for demonstration\n        group_sum[d] += N - idx; // heavier items first\n    }\n    return assignment;\n}\n\n// ----------------------------- MAIN ----------------------\nint main() {\n    fastio();\n    cin >> N >> D >> Q;\n\n    compare_cache.assign(N, vector<int>(N, -2)); // Initially unset\n\n    // --- Phase 1: sort all items using comparison result ---\n    vector<int> indices(N);\n    iota(indices.begin(), indices.end(), 0);\n\n    // If max Q allows for all pairwise comparisons, could use bubble or insertion sort (N*(N-1)/2 queries)\n    // Else stick to comparison sort.\n    // For N=100, Q ~ 200-3200, so pairwise is too much (would need up to 4950).\n    // So: proceed with std::sort with comparator (up to N*logN)\n\n    sort(indices.begin(), indices.end(), cmp_wrapper); // From heavy to light\n\n    // --- Phase 2: assign greedily to groups ---\n    vector<int> assign = assign_to_groups(indices);\n\n    // --- Output phase ---\n    // Output single line with d_0 ... d_{N-1}\n    for(int i=0; i<N; ++i) {\n        cout << assign[i] << (i+1==N ? '\\n' : ' ');\n    }\n    flush();\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 200;\nconstexpr int M = 10;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int n, m;\n    cin >> n >> m;\n    assert(n == 200 && m == 10);\n\n    vector<vector<int>> stacks(m); // [stack][bottom..top]\n    vector<pair<int,int>> box_pos(n+1); // [box] -> (stack_id, pos_from_bottom)\n\n    for (int i = 0; i < m; ++i) {\n        stacks[i].resize(n/m);\n        for (int j = 0; j < n/m; ++j) {\n            cin >> stacks[i][j];\n            box_pos[stacks[i][j]] = {i, j};\n        }\n    }\n\n    vector<pair<int, int>> ops; // operations: (v, stack_id), stack_id==0 for carry out\n\n    // For each number to be carried out in order\n    vector<int> stack_pointer(m, 0); // number of boxes taken out from bottom of each stack\n\n    for (int target = 1; target <= n; ++target) {\n        // Find where the target box is\n        pair<int,int> pos = box_pos[target];\n        int s = pos.first, idx = pos.second;\n\n        // Since boxes are only removed from top, need to adjust for boxes already taken out from this stack\n        int logical_pos = idx - stack_pointer[s];\n        int stack_size = stacks[s].size();\n\n        // If it's at the top of its stack (adjusted)\n        if (logical_pos == (int)stacks[s].size() - 1) {\n            // Output: (target, 0)\n            ops.emplace_back(target, 0);\n            // Remove from stack\n            stacks[s].pop_back();\n            stack_pointer[s]++;\n        } else {\n            // Need to move [logical_pos, end] to another stack\n            vector<int> to_move;\n            for (int j = logical_pos; j < (int)stacks[s].size(); ++j) to_move.push_back(stacks[s][j]);\n            \n            // Remove from source stack\n            stacks[s].resize(logical_pos);\n\n            // Invalidate pointer for moved boxes\n            for (int box : to_move) box_pos[box] = {-1, -1};\n\n            // Select destination stack (shortest, not s)\n            int dest = -1, minsize = INT_MAX;\n            for (int i = 0; i < m; ++i) {\n                if (i == s) continue;\n                if ((int)stacks[i].size() < minsize) {\n                    minsize = (int)stacks[i].size();\n                    dest = i;\n                }\n            }\n\n            // Place chunk to target stack\n            for (int box : to_move) {\n                stacks[dest].push_back(box);\n            }\n            // Update positions for moved boxes\n            int sz = stacks[dest].size();\n            for (int j = 0; j < (int)to_move.size(); ++j) {\n                box_pos[to_move[j]] = {dest, sz - (int)to_move.size() + j};\n            }\n\n            // Output operation: (target, dest+1)\n            ops.emplace_back(target, dest+1);\n        restart: // We'll loop back as the box may need carry operation in next iteration\n            // Try again in next loop, as now it should be on top at dest stack\n            target--;\n        }\n    }\n    // Output\n    for (auto [v, i] : ops) cout << v << \" \" << i << \"\\n\";\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nconstexpr int di[4] = {-1, 1, 0, 0};\nconstexpr int dj[4] = {0, 0, -1, 1};\nconstexpr char DIR[4] = {'U', 'D', 'L', 'R'};\nconstexpr char INV_DIR[4] = {'D', 'U', 'R', 'L'};\n\nint N;\nvector<string> hwall, vwall;\nvector<vector<int>> dirt;\n\n// Store reconstructed path\nstring path;\n\n// Used for visiting\nvector<vector<bool>> vis;\n\n// For output movement\nstruct Move {\n    int i, j;  // position after move\n    char dir;  // move direction to here\n};\n\nstruct Cell {\n    int i, j, d;\n    bool operator<(const Cell &rhs) const { return d > rhs.d; }\n};\nvector<Cell> cells_by_dirt;\n\ninline bool in_grid(int i, int j) {\n    return 0 <= i && i < N && 0 <= j && j < N;\n}\n\nbool can_move(int i, int j, int dir) {\n    int ni = i + di[dir], nj = j + dj[dir];\n    if (!in_grid(ni, nj)) return false;\n    if (dir == 0) {  // U\n        return hwall[ni][nj] == '0';\n    }\n    if (dir == 1) {  // D\n        return hwall[i][j] == '0';\n    }\n    if (dir == 2) {  // L\n        return vwall[ni][nj] == '0';\n    }\n    if (dir == 3) {  // R\n        return vwall[i][j] == '0';\n    }\n    return false;\n}\n\n/**\n * Enhanced DFS: Recursively traverse unvisited neighbors, preferring high dirtiness.\n */\nvoid dfs(int i, int j) {\n    vis[i][j] = true;\n    // Make a list of neighbor candidates, sort by dirtiness\n    vector<pair<int, int>> nbrs;\n    for (int dir = 0; dir < 4; ++dir) {\n        int ni = i + di[dir], nj = j + dj[dir];\n        if (in_grid(ni, nj) && !vis[ni][nj] && can_move(i, j, dir)) {\n            nbrs.emplace_back(dirt[ni][nj], dir);\n        }\n    }\n    // Prefer higher d neighbors\n    sort(nbrs.rbegin(), nbrs.rend());\n\n    for (auto &[dval, dir] : nbrs) {\n        int ni = i + di[dir], nj = j + dj[dir];\n        path.push_back(DIR[dir]);\n        dfs(ni, nj);\n        path.push_back(INV_DIR[dir]);\n    }\n}\n\n// Add detour loops at high-dirt cells, if budget allows\nvoid insert_high_dirt_loops(int maxLength) {\n    // Top K highest dirt cells\n    int K = min(7, N*N/8);\n    vector<pair<int, int>> loopcells;\n    for (int i = 0; i < K && i < int(cells_by_dirt.size()); ++i) {\n        if (cells_by_dirt[i].i == 0 && cells_by_dirt[i].j == 0) continue;\n        loopcells.emplace_back(cells_by_dirt[i].i, cells_by_dirt[i].j);\n    }\n    // Try to insert short 'loops' around those\n    int insertions = 0;\n    vector<int> insert_pos;\n\n    // Find all path positions at high-dirt cells\n    for (auto &[ci, cj] : loopcells) {\n        for (int idx = 0, pi = 0, pj = 0; idx < int(path.size()); ++idx) {\n            int oldi = pi, oldj = pj;\n            if (path[idx] == 'U') --pi;\n            else if (path[idx] == 'D') ++pi;\n            else if (path[idx] == 'L') --pj;\n            else if (path[idx] == 'R') ++pj;\n            if (pi == ci && pj == cj) {\n                insert_pos.push_back(idx);\n                break;\n            }\n        }\n    }\n\n    // Insert loops (for each, try to find a local 2-move cycle)\n    for (int posidx = 0; posidx < (int)insert_pos.size(); ++posidx) {\n        int insert_at = insert_pos[posidx];\n        int ci = loopcells[posidx].first, cj = loopcells[posidx].second;\n        // Look for a neighbor (not a wall), not out of bounds\n        for (int dir = 0; dir < 4; ++dir) {\n            int ni = ci + di[dir], nj = cj + dj[dir];\n            if (!in_grid(ni, nj)) continue;\n            if (!can_move(ci, cj, dir)) continue;\n            // Insert: go to neighbor and return\n            if ((int)path.size() + 2 <= maxLength) {\n                path.insert(insert_at, 1, DIR[dir]);\n                path.insert(insert_at + 1, 1, INV_DIR[dir]);\n                insert_at += 2;\n                insertions++;\n            }\n            break; // only one for now\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    hwall.resize(N - 1);\n    for (int i = 0; i < N - 1; ++i) cin >> hwall[i];\n    vwall.resize(N);\n    for (int i = 0; i < N; ++i) cin >> vwall[i];\n    dirt.resize(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) cin >> dirt[i][j];\n\n    // Build cell list by dirt\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cells_by_dirt.push_back(Cell{i, j, dirt[i][j]});\n    sort(cells_by_dirt.begin(), cells_by_dirt.end());\n\n    // DFS-based path\n    vis.assign(N, vector<bool>(N, false));\n    dfs(0,0);\n\n    // Ensure we return to (0,0)\n    assert(vis[0][0]);\n    // Optionally: prune if exceeds 100000\n    int maxLength = 100000;\n    if ((int)path.size() > maxLength) {\n        path = path.substr(0, maxLength); // guarantee legality\n    } else if ((int)path.size() < maxLength - 20) {\n        // Try to insert some detour loops at top dirt cells\n        insert_high_dirt_loops(maxLength);\n    }\n    cout << path << endl;\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Grid size\nconst int N = 15;\n\n// Letter to grid positions lookup\nvector<pair<int, int>> letter_pos[26];\n\n// Find maximum overlap of s's suffix and t's prefix\nint max_overlap(const string &s, const string &t) {\n    int maxl = min((int)s.size(), (int)t.size());\n    for (int l = maxl; l >= 1; l--) {\n        if (s.substr(s.size() - l, l) == t.substr(0, l))\n            return l;\n    }\n    return 0;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int n, m;\n    int si, sj;\n    cin >> n >> m >> si >> sj;\n\n    // Read keyboard\n    vector<string> grid(n);\n    for (int i = 0; i < n; ++i)\n        cin >> grid[i];\n\n    // Build lookup for each letter\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j)\n            letter_pos[grid[i][j] - 'A'].push_back({i, j});\n\n    // Read lucky words\n    vector<string> words(m);\n    for (int i = 0; i < m; ++i)\n        cin >> words[i];\n\n    // Superstring construction (greedy, by overlap)\n    vector<bool> used(m, false);\n    string superstring = words[0];\n    used[0] = true;\n    int used_count = 1;\n\n    while (used_count < m) {\n        int best = -1, best_overlap = -1;\n        for (int i = 0; i < m; ++i) {\n            if (used[i]) continue;\n            int ov = max_overlap(superstring, words[i]);\n            if (ov > best_overlap) {\n                best_overlap = ov;\n                best = i;\n            }\n        }\n        // Append the non-overlapping part\n        superstring += words[best].substr(best_overlap);\n        used[best] = true;\n        used_count++;\n    }\n    // Safety: if too long, truncate and drop some tail (suboptimal but stays valid)\n    if (superstring.size() > 5000) superstring = superstring.substr(0, 5000);\n\n    // Optimize route: for each char, pick nearest occurrence\n    vector<pair<int, int>> route;\n    int ci = si, cj = sj;\n    for (char ch : superstring) {\n        int c = ch - 'A';\n        pair<int, int> best_p = letter_pos[c][0];\n        int best_cost = abs(ci - best_p.first) + abs(cj - best_p.second);\n        // Try all positions\n        for (auto &[ni, nj] : letter_pos[c]) {\n            int cost = abs(ci - ni) + abs(cj - nj);\n            if (cost < best_cost) {\n                best_cost = cost;\n                best_p = {ni, nj};\n            }\n        }\n        route.push_back(best_p);\n        ci = best_p.first;\n        cj = best_p.second;\n    }\n\n    // Output move sequence\n    for (auto &[i, j] : route) {\n        cout << i << ' ' << j << '\\n';\n    }\n\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*\n Polyomino Identification via placement elimination (drill-based)\n - For each oil field, generate all possible translations of the shape within bounds.\n - For each oil field, maintain list of possible placements (\"alive\").\n - After each drill (q 1 i j), prune inconsistent placements.\n - When, for all oil fields, there is only one live placement, union them and output as the set with v(i,j)>0.\n*/\n\nconstexpr int DX[4] = {-1,1,0,0};\nconstexpr int DY[4] = {0,0,-1,1};\n\nstruct Polyomino {\n    vector<pair<int,int>> cells; // relative coordinates from (0,0)\n    int h=0, w=0; // bounding box size\n    vector<vector<pair<int,int>>> placements; // all placements (cells in board coord)\n};\n\nint N, M;\ndouble eps;\nvector<Polyomino> oil_fields;\n\n// For each oil field, available placements, as indices into oil_fields[k].placements.\nvector<vector<int>> alivePlacements;\n\nvector<vector<int>> drillValue; // -1=unknown, >=0 revealed\n\n// Construct all legal placements for each polyomino\nvoid enumerate_placements() {\n    for (auto& poly : oil_fields) {\n        // Find bounding box\n        int min_i=1e9,min_j=1e9,max_i=-1e9,max_j=-1e9;\n        for (auto [x, y]: poly.cells) {\n            min_i = min(min_i, x);\n            max_i = max(max_i, x);\n            min_j = min(min_j, y);\n            max_j = max(max_j, y);\n        }\n        poly.h = max_i+1;\n        poly.w = max_j+1;\n        // All valid translations\n        for (int base_i=0; base_i+poly.h <= N; ++base_i) {\n            for (int base_j=0; base_j+poly.w <= N; ++base_j) {\n                vector<pair<int,int>> placement;\n                for (auto [di,dj]: poly.cells) {\n                    placement.emplace_back(base_i+di, base_j+dj);\n                }\n                poly.placements.push_back(placement);\n            }\n        }\n    }\n}\n\n// For fast cell lookup: for each oil field, for each placement, set of covered cells\n// As well as, for each (cell), which (field,placement) cover it (may not be needed for initial version)\n\n// Remove placements inconsistent with known drill values\n// Returns true if at least one placement was eliminated\nbool update_alivePlacements() {\n    bool changed = false;\n    for (int f=0; f<M; ++f) {\n        vector<int> updated;\n        for (int pi : alivePlacements[f]) {\n            const auto& placement = oil_fields[f].placements[pi];\n            bool ok = true;\n            for (auto [ci, cj]: placement) {\n                if (drillValue[ci][cj] != -1 && drillValue[ci][cj] == 0) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) updated.push_back(pi);\n        }\n        if (updated.size() != alivePlacements[f].size()) changed = true;\n        alivePlacements[f] = move(updated);\n    }\n    return changed;\n}\n\n// Sum over all alive placements, for each cell, count how many can have oil (for heuristic)\nvector<vector<int>> plausible_oil_counts() {\n    vector<vector<int>> cnt(N, vector<int>(N));\n    for (int f=0; f<M; ++f) {\n        for (int pi: alivePlacements[f]) {\n            for (auto [ci,cj]: oil_fields[f].placements[pi]) {\n                cnt[ci][cj]++;\n            }\n        }\n    }\n    return cnt;\n}\n\n// Helper: print and flush\nvoid do_query(const string& s) {\n    cout << s << endl;\n    cout << flush;\n}\n\n// Greedy\u2013drill the most uncertain cell: one with most support from still-possible placements, hasn't been drilled\npair<int,int> choose_next_drill() {\n    auto cnt = plausible_oil_counts();\n    int best_val = -1;\n    pair<int,int> best = {-1,-1};\n    for (int i=0; i<N; ++i) for (int j=0; j<N; ++j)\n        if (drillValue[i][j]==-1 && cnt[i][j] > best_val) {\n            best_val = cnt[i][j];\n            best = {i,j};\n        }\n    if (best_val==-1) {\n        // All cells known? Should not happen\n        for (int i=0; i<N; ++i) for (int j=0; j<N; ++j)\n            if (drillValue[i][j]==-1) return {i,j};\n    }\n    return best;\n}\n\n// Return true if all oil fields have unique placement\nbool solved(unique_ptr<set<pair<int,int>>>& result_cells) {\n    set<pair<int,int>> S;\n    for (int f=0; f<M; ++f) {\n        if (alivePlacements[f].size() != 1) return false;\n        for (auto [ci,cj]: oil_fields[f].placements[alivePlacements[f][0]]) {\n            S.emplace(ci,cj);\n        }\n    }\n    result_cells = make_unique<set<pair<int,int>>>(move(S));\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    // Rest input\n    cin >> N >> M >> eps;\n    oil_fields.resize(M);\n    for (int k=0; k<M; ++k) {\n        int d; cin >> d;\n        vector<pair<int,int>> cc;\n        for (int q=0; q<d; ++q) {\n            int x, y; cin >> x >> y;\n            cc.emplace_back(x,y);\n        }\n        oil_fields[k].cells = move(cc);\n    }\n\n    enumerate_placements();\n\n    alivePlacements.clear();\n    for (auto& poly : oil_fields) {\n        int K = poly.placements.size();\n        vector<int> v(K);\n        iota(v.begin(), v.end(), 0);\n        alivePlacements.push_back(move(v));\n    }\n    drillValue.assign(N, vector<int>(N, -1));\n\n    int opcnt = 0;\n    unique_ptr<set<pair<int,int>>> answer_set = nullptr;\n\n    // To ensure progress, for first few steps, random drills (M*2)\n    vector<pair<int,int>> already_drilled;\n    mt19937 rng(12345); // fixed seed for reproducibility in sample solutions\n    while (opcnt < min(2*M, N*N)) {\n        uniform_int_distribution<int> dist(0, N-1);\n        int i = dist(rng), j = dist(rng);\n        if (drillValue[i][j] != -1) continue;\n        do_query(\"q 1 \"+to_string(i)+\" \"+to_string(j));\n        int v;\n        cin >> v;\n        drillValue[i][j] = v;\n        already_drilled.emplace_back(i,j);\n        opcnt++;\n        update_alivePlacements();\n        if (solved(answer_set)) goto finish;\n    }\n\n    // Main loop: maintain alivePlacements; greedily drill most ambiguous cell\n    while (opcnt < 2*N*N) {\n        // Try to propose answer\n        if (solved(answer_set)) break;\n\n        pair<int,int> drill = choose_next_drill();\n        if (drill.first==-1) break; // all known\n        int i=drill.first, j=drill.second;\n\n        do_query(\"q 1 \"+to_string(i)+\" \"+to_string(j));\n        int v; cin >> v;\n        drillValue[i][j] = v;\n        opcnt++;\n        update_alivePlacements();\n    }\n\nfinish:\n\n    // Compose answer set: all cells covered by unique placements of oil fields\n    if (!answer_set) solved(answer_set); // might be already solved\n\n    vector<pair<int,int>> oilCells(answer_set->begin(), answer_set->end());\n    // As required: must include all drilled cells where v(i,j)>0\n    for (auto [i,j]: already_drilled) {\n        if (drillValue[i][j]>0 && !answer_set->count({i,j})) {\n            oilCells.emplace_back(i,j);\n        }\n    }\n\n    cout << \"a \" << oilCells.size();\n    for (auto [i,j] : oilCells) cout << \" \" << i << \" \" << j;\n    cout << endl << flush;\n\n    int res; cin >> res;\n    if (res!=1) {\n        // Should not happen unless output illegal subset\n        cerr << \"#c Output judged incorrect!\" << endl;\n    }\n\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Constants\nconstexpr int W = 1000;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int w, D, N;\n    cin >> w >> D >> N;\n    vector<vector<int>> a(D, vector<int>(N));\n\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            cin >> a[d][k];\n        }\n    }\n\n    // We compute fixed vertical stripe partitions for N rectangles\n    // We'll divide width as evenly as possible between the stripes\n    // Calculate each x-range for k-th rectangle\n    vector<int> stripe_l(N), stripe_r(N);\n    for (int k = 0; k < N; ++k) {\n        // Floor division then assign extra one to first (W % N)\n        int l = (int)((int64_t)k * W / N);\n        int r = (int)((int64_t)(k + 1) * W / N);\n        stripe_l[k] = l;\n        stripe_r[k] = r;\n    }\n\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            int x0 = stripe_l[k];\n            int x1 = stripe_r[k];\n            int y0 = 0;\n            int y1 = W;\n\n            // Stripe is (x0,y0)-(x1,y1), area = (x1-x0)*W\n\n            // If area is less than a[d][k], we could try to\n            // increase the stripe's height, but in this static approach, it's fixed.\n\n            // If stripe is too small, shrink y1 to make sure b >= a[d][k] if possible.\n            int min_area = a[d][k];\n            int width = x1 - x0;\n            int min_height = (min_area + width - 1) / max(width, 1); // Ceil division\n            if (min_height > W) min_height = W;\n            // Prefer to give full height always (to keep partitions unchanged)\n            // But you could do y1 = y0 + min_height;\n            // For now, keep (x0,y0)-(x1,y1)\n            cout << y0 << \" \" << x0 << \" \" << y1 << \" \" << x1 << \"\\n\";\n        }\n    }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 9, M = 20, K = 81;\nconstexpr int MOD = 998244353;\nusing Board = array<array<int, N>, N>;\nusing Stamp = array<array<int,3>,3>;\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n\n    // Input\n    int n, m, k;\n    cin >> n >> m >> k;\n    Board a;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> a[i][j];\n\n    vector<Stamp> stamps(M);\n    for (int t = 0; t < M; ++t)\n        for (int i = 0; i < 3; ++i)\n            for (int j = 0; j < 3; ++j)\n                cin >> stamps[t][i][j];\n\n    Board board = a;\n    // To speed up, we also store b % MOD for each cell\n    array<array<int, N>, N> board_mod;\n    for (int i=0; i<N; ++i)\n        for (int j=0; j<N; ++j)\n            board_mod[i][j] = board[i][j] % MOD;\n\n    // List of (which stamp, y, x)\n    vector<tuple<int,int,int>> ops;\n\n    // Greedy stamping for up to K times\n    for (int step = 0; step < K; ++step) {\n        int best_gain = 0;\n        int best_m = -1, best_p = -1, best_q = -1;\n\n        for (int m_id = 0; m_id < M; ++m_id) {\n            const auto& st = stamps[m_id];\n            for (int p = 0; p <= N - 3; ++p) {\n                for (int q = 0; q <= N - 3; ++q) {\n                    int gain = 0;\n                    // compute modsum gain when placing here\n                    for (int di = 0; di < 3; ++di) {\n                        for (int dj = 0; dj < 3; ++dj) {\n                            int ni = p + di, nj = q + dj;\n                            int before = board_mod[ni][nj];\n                            int after = (board[ni][nj] + st[di][dj]) % MOD;\n                            // Gain is how much modded value increases (could wrap to smaller!)\n                            // To handle wrapping, compute (after-before+MOD)%MOD\n                            int cell_gain = (after - before + MOD) % MOD;\n                            gain += cell_gain;\n                        }\n                    }\n                    if (gain > best_gain) {\n                        best_gain = gain;\n                        best_m = m_id;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n\n        if (best_gain == 0) {\n            // No beneficial stamping left\n            break;\n        }\n\n        // Apply the best operation\n        ops.emplace_back(best_m, best_p, best_q);\n        const auto& st = stamps[best_m];\n        for (int di = 0; di < 3; ++di) {\n            for (int dj = 0; dj < 3; ++dj) {\n                int ni = best_p + di, nj = best_q + dj;\n                board[ni][nj] += st[di][dj];\n                board_mod[ni][nj] = (board_mod[ni][nj] + st[di][dj]) % MOD;\n            }\n        }\n    }\n\n    // Output result\n    cout << ops.size() << '\\n';\n    for (const auto& [m,p,q] : ops) {\n        cout << m << ' ' << p << ' ' << q << '\\n';\n    }\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Constants\nconstexpr int N = 5;\nconstexpr int MAX_TURNS = 10000;\n\n// Container positions (row, col)\nstruct Crane {\n    int row, col;\n    bool large;\n    bool holding = false;\n    int held_container = -1;\n};\n\nstruct Cell {\n    int container = -1;\n    int crane = -1; // crane index occupying this cell, -1 if no crane\n};\n\nvector<vector<int>> A;\n\nstring moveDir(int dr, int dc) {\n    if (dr == -1) return \"U\";\n    if (dr == 1) return \"D\";\n    if (dc == -1) return \"L\";\n    if (dc == 1) return \"R\";\n    return \".\";\n}\n\n// Find shortest path from (r1,c1) to (r2,c2), returns first step, ignoring containers & cranes.\n// Plan for per-row: cranes never leave row, so it is at most abs(c1-c2)\npair<int,int> nextStep(int r1, int c1, int r2, int c2) {\n    if (c1 < c2) return {0,1};\n    if (c1 > c2) return {0,-1};\n    return {0,0}; // Should not move vertically!\n}\n\n// For each row, keep buffer cells: (row,1)-(row,3)\narray<array<Cell, N>, N> board;\narray<Crane, N> cranes;\nvector<string> plan(N);\n\n// For each row\nstruct RowSorter {\n    int row;\n    vector<int> needed; // in dispatch order for this row\n\n    // For each cell, what container is there\n    // 0: receiving gate (row,0), 1..3: buffer, 4: dispatch gate\n\n    int next_need_idx = 0;\n\n    // Where is each container? -1 if not in row (not yet arrived or dispatched)\n    array<int, N> container_pos; // idx 0..4 => col pos - 0=receiving, 1..3 buffer, 4=dispatch\n\n    // For each buffer cell in row, stores container id or -1\n    array<int, N> location; // col 0..4, -1 if empty\n\n    // List of containers in **arrival order**\n    vector<int> arrivals;\n\n    // Target: fill dispatch gate (col=4) in order\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    // Input\n    A.assign(N, vector<int>(N));\n    for(int i=0;i<N;i++) {\n        for(int j=0;j<N;j++) cin >> A[i][j];\n    }\n\n    // Init cranes\n    for(int i=0;i<N;i++) {\n        cranes[i] = Crane{i,0, i==0}; // only 0 is large\n    }\n\n    // Prepare per-row\n    vector<vector<int>> targets(N); // for each row, target order\n    for(int i=0;i<N;i++) {\n        for(int j=0;j<N;j++) {\n            targets[i].push_back(N*i + j); // row i: 5*i..5*i+4\n        }\n    }\n\n    // Set up board state: empty\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++)\n        board[i][j] = Cell{-1, -1};\n\n    // Each turn\n    array<deque<int>, N> receive_queues;\n    for(int i=0;i<N;i++)\n        for(int j=0;j<N;j++)\n            receive_queues[i].push_back(A[i][j]);\n    \n    // Track dispatched containers per row for $M_1$ scoring if you simulate\n    vector<vector<int>> dispatched(N);\n\n    // Each plan entry: action per crane\n    vector<string> actions(N);\n\n    // Each crane's target: for now, all in own row\n    array<int, N> row_target;\n    iota(row_target.begin(), row_target.end(), 0);\n\n    // For each crane, what column is it at (only moving in own row!)\n    array<int, N> crane_col;\n    for(int i=0;i<N;i++) crane_col[i]=0;\n\n    // For each crane, whether holding and what\n    array<bool, N> holding; holding.fill(false);\n    array<int, N> held_container; held_container.fill(-1);\n\n    // For each cell: what container is present (-1 for none)\n    array<array<int, N>, N> container_cell;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++)\n        container_cell[i][j] = -1;\n\n    // For each cell: which crane is present (-1 for none)\n    array<array<int,N>,N> crane_cell;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++)\n        crane_cell[i][j] = -1;\n    for(int i=0;i<N;i++) crane_cell[i][0]=i;\n\n    // Next-needed-by-row\n    array<int, N> next_dispatch; next_dispatch.fill(0);\n\n    // For each row, archive containers in buffer slots as needed\n\n    int max_turns = 0;\n    while (max_turns < MAX_TURNS) {\n        vector<string> turn(N, string(1,'.'));\n\n        // 1. Arrival: for each receiving gate, if empty and crane not holding there, produce next container\n        for(int i=0;i<N;i++) {\n            if(container_cell[i][0]==-1 && !(holding[i] && crane_col[i]==0) && !receive_queues[i].empty()) {\n                int cont = receive_queues[i].front(); receive_queues[i].pop_front();\n                container_cell[i][0]=cont;\n            }\n        }\n        // Copy board state, plan moves for each crane in turn\n        for(int i=0;i<N;i++) {\n            int row = i;\n            int col = crane_col[i];\n            bool is_large = (i==0);\n            // Goal: deliver to (row,4) containers N*row..N*row+4 in order\n            int goal = N*row + next_dispatch[row];\n\n            // If already holding the correct next-needed container, move to col 4 and drop\n            if(holding[i] && held_container[i]==goal) {\n                if(col<4) {\n                    // move right if possible\n                    if(crane_cell[row][col+1]==-1 && (is_large || container_cell[row][col+1]==-1)) {\n                        turn[i]=\"R\";\n                        crane_col[i]++;\n                        crane_cell[row][col]=-1;\n                        crane_cell[row][crane_col[i]]=i;\n                    } else {\n                        // can't move, wait\n                        turn[i]=\".\";\n                    }\n                } else if(col==4) {\n                    // at dispatch gate\n                    // can we drop? (must be empty)\n                    if(container_cell[row][4]==-1) {\n                        turn[i]=\"Q\";\n                        container_cell[row][4]=held_container[i];\n                        holding[i]=false;\n                        held_container[i]=-1;\n                        // Will be dispatched at end of turn\n                        next_dispatch[row]++;\n                    } else {\n                        turn[i]=\".\";\n                    }\n                }\n            }\n            // If holding but not correct, move to nearest buffer to drop\n            else if(holding[i]) {\n                // Find buffer in (row,1..3) that is empty\n                int tgt=-1;\n                for(int c=1;c<=3;c++) {\n                    if(container_cell[row][c]==-1 && crane_cell[row][c]==-1) {\n                        tgt=c; break;\n                    }\n                }\n                if(tgt==-1) {\n                    // no free buffer, wait\n                    turn[i]=\".\";\n                } else if(col<tgt) {\n                    // want to move right\n                    if(crane_cell[row][col+1]==-1 && (is_large || container_cell[row][col+1]==-1)) {\n                        turn[i]=\"R\";\n                        crane_col[i]++;\n                        crane_cell[row][col]=-1;\n                        crane_cell[row][crane_col[i]]=i;\n                    } else {\n                        turn[i]=\".\";\n                    }\n                } else if(col>tgt) {\n                    // want to move left\n                    if(crane_cell[row][col-1]==-1 && (is_large || container_cell[row][col-1]==-1)) {\n                        turn[i]=\"L\";\n                        crane_col[i]--;\n                        crane_cell[row][col]=-1;\n                        crane_cell[row][crane_col[i]]=i;\n                    } else {\n                        turn[i]=\".\";\n                    }\n                } else {\n                    // at target buffer, drop if empty\n                    if(container_cell[row][col]==-1) {\n                        turn[i]=\"Q\";\n                        container_cell[row][col]=held_container[i];\n                        holding[i]=false;\n                        held_container[i]=-1;\n                    } else {\n                        turn[i]=\".\";\n                    }\n                }\n            }\n            // Not holding\n            else {\n                // If at receiving, and has container, pick up if it's the needed one\n                if(col==0 && container_cell[row][0]!=-1) {\n                    int c=container_cell[row][0];\n                    if(c==goal) {\n                        turn[i]=\"P\";\n                        holding[i]=true;\n                        held_container[i]=c;\n                        container_cell[row][0]=-1;\n                    } else {\n                        // Not the one needed; pick up anyway and buffer, if possible\n                        // Option: only pick if buffer space exists\n                        int buf=-1;\n                        for(int bc=1;bc<=3;bc++)\n                            if(container_cell[row][bc]==-1 && crane_cell[row][bc]==-1) { buf=bc; break; }\n                        if(buf!=-1) {\n                            turn[i]=\"P\";\n                            holding[i]=true;\n                            held_container[i]=c;\n                            container_cell[row][0]=-1;\n                        } else {\n                            turn[i]=\".\";\n                        }\n                    }\n                }\n                // If in buffer, and buffer has next-needed container, pick up\n                else if(container_cell[row][col]==goal) {\n                    turn[i]=\"P\";\n                    holding[i]=true;\n                    held_container[i]=goal;\n                    container_cell[row][col]=-1;\n                }\n                // Else, move toward place with goal\n                else {\n                    // Look for goal in buffer (row,1..3)\n                    int goal_pos=-1;\n                    for(int bc=0;bc<=3;bc++)\n                        if(container_cell[row][bc]==goal) { goal_pos=bc; break; }\n                    // Else, in receiving gate but blocked, or not arrived yet\n                    if(goal_pos==-1) {\n                        // nothing to do\n                        turn[i]=\".\";\n                    } else {\n                        if(col<goal_pos) {\n                            // move right\n                            if(crane_cell[row][col+1]==-1 && (is_large || container_cell[row][col+1]==-1)) {\n                                turn[i]=\"R\";\n                                crane_col[i]++;\n                                crane_cell[row][col]=-1;\n                                crane_cell[row][crane_col[i]]=i;\n                            } else {\n                                turn[i]=\".\";\n                            }\n                        } else if(col>goal_pos) {\n                            // move left\n                            if(crane_cell[row][col-1]==-1 && (is_large || container_cell[row][col-1]==-1)) {\n                                turn[i]=\"L\";\n                                crane_col[i]--;\n                                crane_cell[row][col]=-1;\n                                crane_cell[row][crane_col[i]]=i;\n                            } else {\n                                turn[i]=\".\";\n                            }\n                        } else {\n                            // standing on it, but not holding\u2014should have been caught above?\n                            turn[i]=\".\";\n                        }\n                    }\n                }\n            }\n        }\n\n        // Print actions after sim\n        for(int i=0;i<N;i++) actions[i].push_back(turn[i][0]);\n\n        // End of turn: dispatch any container in dispatch gate (row,4)\n        for(int i=0;i<N;i++) {\n            if(container_cell[i][4]!=-1) {\n                // container dispatched\n                // Track in dispatched for scoring\n                dispatched[i].push_back(container_cell[i][4]);\n                container_cell[i][4]=-1;\n            }\n        }\n\n        max_turns++;\n\n        // Terminate if all containers dispatched\n        int dispatched_count=0;\n        for(int i=0;i<N;i++) dispatched_count += dispatched[i].size();\n        if(dispatched_count == N*N) break;\n    }\n\n    // Output action plans\n    for(int i=0;i<N;i++) cout<<actions[i]<<'\\n';\n\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Constants\nconstexpr int N = 20;\nconstexpr int MAX_LOAD = 1'000'000; // But all cell values [-100,100]\n\n// Type aliases\nusing pii = pair<int,int>;\n\nstruct Cell {\n    int y, x;\n    int amount;\n};\n\n// Directions for output char\nconst char DIRS[4] = {'U', 'D', 'L', 'R'};\nconst int DY[4] = {-1, 1, 0, 0};\nconst int DX[4] = {0, 0, -1, 1};\n\n// Pathfinding: output step sequence (U,D,L,R) between two points\nvector<char> get_path(int sy, int sx, int ty, int tx) {\n    vector<char> path;\n    // Move vertically\n    while (sy < ty) { path.push_back('D'); sy++; }\n    while (sy > ty) { path.push_back('U'); sy--; }\n    // Move horizontally\n    while (sx < tx) { path.push_back('R'); sx++; }\n    while (sx > tx) { path.push_back('L'); sx--; }\n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int n; // Should always be 20\n    cin >> n;\n    vector<vector<int>> h(n, vector<int>(n));\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j)\n            cin >> h[i][j];\n\n    // Collect sources (surplus > 0) and sinks (deficit < 0)\n    vector<Cell> supply, demand;\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j) {\n            if (h[i][j] > 0) supply.push_back({i, j, h[i][j]});\n            if (h[i][j] < 0) demand.push_back({i, j, -h[i][j]});\n        }\n\n    // For simplicity, process largest supplies first (sort by amount descending)\n    sort(supply.begin(), supply.end(), [](const Cell& a, const Cell& b) {\n        return a.amount > b.amount;\n    });\n    sort(demand.begin(), demand.end(), [](const Cell& a, const Cell& b) {\n        return a.amount > b.amount;\n    });\n\n    int truck_y = 0, truck_x = 0, truck_load = 0;\n    vector<string> commands;\n\n    // For quick available demands\n    vector<bool> demand_done(demand.size(), false);\n\n    for (int si = 0; si < supply.size(); ++si) {\n        auto &src = supply[si];\n        while (src.amount > 0) {\n            // Find nearest available demand\n            int min_dist = 1e9, di = -1;\n            for (int dj = 0; dj < (int)demand.size(); ++dj) {\n                if (demand_done[dj]) continue;\n                if (demand[dj].amount == 0) continue;\n                int dist = abs(demand[dj].y - src.y) + abs(demand[dj].x - src.x);\n                if (dist < min_dist) {\n                    min_dist = dist;\n                    di = dj;\n                }\n            }\n            if (di == -1) break; // No more demand\n\n            // Plan: truck move to supply, load, move to demand, unload\n            int move_to_src = abs(truck_y - src.y) + abs(truck_x - src.x);\n            vector<char> path_to_src = get_path(truck_y, truck_x, src.y, src.x);\n            for (char c : path_to_src) commands.push_back(string(1, c));\n            truck_y = src.y; truck_x = src.x;\n\n            // Now at src, load as much as possible\n            int load_amt = min(src.amount, demand[di].amount);\n            load_amt = min(load_amt, MAX_LOAD);\n            commands.push_back(\"+\" + to_string(load_amt));\n            truck_load += load_amt;\n            src.amount -= load_amt;\n\n            // Move to demand\n            auto &dst = demand[di];\n            vector<char> path_to_dst = get_path(truck_y, truck_x, dst.y, dst.x);\n            for (char c : path_to_dst) commands.push_back(string(1, c));\n            truck_y = dst.y; truck_x = dst.x;\n\n            // Unload all carried soil to demand\n            commands.push_back(\"-\" + to_string(load_amt));\n            truck_load -= load_amt;\n            dst.amount -= load_amt;\n            if (dst.amount == 0) demand_done[di] = true;\n        }\n    }\n\n    // output all commands\n    for (const auto &cmd : commands) cout << cmd << '\\n';\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 6;\nconstexpr int M = 15;\nconstexpr int T = 10;\nconstexpr int SEED_COUNT = 2 * N * (N - 1);\nconstexpr int GRID_SIZE = N * N;\n\n// For easier seed tracking\nstruct Seed {\n    vector<int> x;       // Features\n    int id;              // Original/new index\n    int v;               // Total value = sum(x)\n\n    Seed(int _id, const vector<int>& _x) : x(_x), id(_id) {\n        v = accumulate(x.begin(), x.end(), 0);\n    }\n};\n\nvoid flush() {\n    cout.flush();\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int n, m, t;\n    cin >> n >> m >> t;\n    assert(n == N && m == M && t == T);\n\n    vector<Seed> seeds;\n    for (int i = 0; i < SEED_COUNT; ++i) {\n        vector<int> x(m);\n        for (int j = 0; j < m; ++j) cin >> x[j];\n        seeds.emplace_back(i, x);\n    }\n\n    // For tracking max per-feature, for scoring/seeding\n    vector<int> feature_max(m, 0);\n\n    mt19937 rng(123456789); // Fixed seed for determinism, can use random_device for true random\n\n    for (int turn = 0; turn < T; ++turn) {\n        // Update feature-wise max\n        fill(feature_max.begin(), feature_max.end(), 0);\n        for (const auto& s : seeds)\n            for (int j = 0; j < m; ++j)\n                feature_max[j] = max(feature_max[j], s.x[j]);\n\n        // Scoring seeds: sum value (+ small bonus for max-per-feature attributes)\n        vector<pair<int, int>> order; // (score,seed_index)\n        vector<int> best_per_feature(m, -1); // seed id with max for each feature\n\n        for (int j = 0; j < m; ++j) {\n            for (const auto& s : seeds)\n                if (s.x[j] == feature_max[j])\n                    best_per_feature[j] = s.id;\n        }\n\n        for (int i = 0; i < (int)seeds.size(); ++i) {\n            int bonus = 0;\n            for (int j = 0; j < m; ++j)\n                if (seeds[i].x[j] == feature_max[j])\n                    bonus += 30; // Having best in a feature is good (tune this)\n            // Add randomness to break ties (and encourage diversity, mainly first few turns)\n            int rnd = uniform_int_distribution<int>(0, 5)(rng);\n            order.emplace_back(seeds[i].v + bonus + rnd, i);\n        }\n        // Take top 36\n        sort(order.rbegin(), order.rend());\n\n        vector<int> chosen_indices;\n        vector<bool> used(seeds.size(), 0);\n\n        // Always pick the current best overall sum, then try to cover all feature maxes\n        for (int i = 0; i < (int)order.size() && (int)chosen_indices.size() < GRID_SIZE; ++i) {\n            chosen_indices.push_back(order[i].second);\n            used[order[i].second] = true;\n        }\n        // Sanity: ensure all feature-max seeds are picked (can remove this for speed)\n        for (int j = 0; j < m; ++j) {\n            int id = best_per_feature[j];\n            if (id == -1) continue;\n            if (!used[id]) {\n                // replace weakest seed in chosen with this seed\n                int minidx = 0;\n                for (int z = 0; z < (int)chosen_indices.size(); ++z)\n                    if (seeds[chosen_indices[z]].v < seeds[chosen_indices[minidx]].v)\n                        minidx = z;\n                used[chosen_indices[minidx]] = false;\n                chosen_indices[minidx] = id;\n                used[id] = true;\n            }\n        }\n\n        // Assign the 36 chosen seeds to grid cells\n        // Place highest V in center and high-degree cells\n        vector<pair<int, int>> grid_cells;\n        for (int i = 0; i < n; ++i)\n            for (int j = 0; j < n; ++j)\n                grid_cells.emplace_back(i, j);\n\n        // Sort cells by number of neighbors, descending (center cells first)\n        sort(grid_cells.begin(), grid_cells.end(), [](pair<int, int> a, pair<int, int> b) {\n            int da = 0, db = 0;\n            auto [ai, aj] = a, [bi, bj] = b;\n            da += (ai > 0) + (ai < N-1) + (aj > 0) + (aj < N-1);\n            db += (bi > 0) + (bi < N-1) + (bj > 0) + (bj < N-1);\n            return da > db;\n        });\n\n        // Greedily assign highest-value seeds to high-degree cells\n        vector<vector<int>> grid(n, vector<int>(n,-1));\n        for (int i = 0; i < GRID_SIZE; ++i)\n            grid[grid_cells[i].first][grid_cells[i].second] = seeds[chosen_indices[i]].id;\n\n        // Output placement\n        for (int i = 0; i < n; ++i) {\n            for (int j = 0; j < n; ++j) {\n                cout << grid[i][j] << (j + 1 < n ? \" \" : \"\\n\");\n            }\n        }\n        flush();\n\n        // Input next set: always 60 seeds, with new feature vectors\n        vector<Seed> next_seeds;\n        for (int k = 0; k < SEED_COUNT; ++k) {\n            vector<int> x(m);\n            for (int j = 0; j < m; ++j) cin >> x[j];\n            next_seeds.emplace_back(k, x);\n        }\n        seeds = move(next_seeds);\n\n        // Optional: print debug\n        int bestV = 0;\n        for (const auto& s : seeds) bestV = max(bestV, s.v);\n        cout << \"# turn=\" << turn << \" bestV=\" << bestV << endl;\n    }\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int INF = 1 << 29;\n\nstruct Pos {\n    int x, y;\n    bool operator==(const Pos& o) const { return x == o.x && y == o.y; }\n    bool operator!=(const Pos& o) const { return !(*this == o); }\n};\n\nvector<Pos> get_leaves(int star_size, int len) {\n    // For star at (0,0) and edges all \"to right\", fingertips are at (0,+len), (0,-len), (+len,0), (-len,0), etc.\n    // We'll spread them as [up,down,left,right,diag up-right...]\n    vector<Pos> dirs = { {0,1},{1,0},{0,-1},{-1,0}, {1,1}, {-1,1}, {1,-1}, {-1,-1} };\n    vector<Pos> leaves;\n    int D = dirs.size();\n    for (int i = 0; i < star_size; i++) {\n        int d = i % D;\n        int mul = 1 + (i/D); // first ring, then doubles if more leaves\n        leaves.push_back(Pos{dirs[d].x * len * mul, dirs[d].y * len * mul});\n    }\n    return leaves;\n}\nPos add(const Pos& a, const Pos& b) { return { a.x + b.x, a.y + b.y }; }\nPos sub(const Pos& a, const Pos& b) { return { a.x - b.x, a.y - b.y }; }\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N, M, V;\n    cin >> N >> M >> V;\n    vector<string> s(N), t(N);\n    for (int i = 0; i < N; i++) cin >> s[i];\n    for (int i = 0; i < N; i++) cin >> t[i];\n\n    // Gather pickup and delivery cell lists\n    vector<Pos> pickups, delivers;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            if (s[i][j] == '1') pickups.push_back({i,j});\n            if (t[i][j] == '1') delivers.push_back({i,j});\n        }\n\n    // Build star-robot arm description\n    int V_ = min(V, 9); // For clearer mapping, \u22648 leaves+root for now; you can try V for more coverage!\n    int L = max(1, N/4); // Or tweak for average case\n    vector<pair<int,int>> parents;\n    for (int i = 1; i < V_; i++) parents.emplace_back(0, L);\n    // Output tree\n    cout << V_ << '\\n';\n    for (auto& [p,l] : parents) cout << p << \" \" << l << \"\\n\";\n\n    // Chose initial root position (upper left for now! try to cover first batch)\n    int root_x = 0, root_y = 0;\n    cout << root_x << \" \" << root_y << '\\n';\n\n    // Compute static fingertips (relative to root)\n    auto leaves = get_leaves(V_-1, L);\n\n    // State per fingertip: currently holding takoyaki?\n    vector<bool> holding(V_-1, false);\n\n    // Used picks/delivs\n    vector<bool> picked(pickups.size(), false), delivered(delivers.size(), false);\n\n    // Keep sets of yet-to-pickup and yet-to-deliver\n    int total_moves = 0;\n    int delivered_cnt = 0;\n    int T_limit = 100000;\n\n    // For visualization: grid status\n    vector<string> curr(N, string(N, '0'));\n    for (auto& pos : pickups) curr[pos.x][pos.y] = '1';\n\n    // For matching: use simple greedy nearest assignment per batch\n\n    size_t pick_idx = 0, deliv_idx = 0;\n    int phase = 0; // 0: pickup phase; 1: delivery phase\n\n    struct FingertipTask { int idx; Pos pos; }; // idx in pickups[]/delivers[]\n\n    vector<FingertipTask> pick_tasks, deliv_tasks;\n    vector<int> fin_to_pickid(V_-1, -1), fin_to_delivid(V_-1, -1);\n\n    vector<string> answers;\n\n    // We alternate: batch pick, walk arm to delivery, batch release\n    while (delivered_cnt < M && total_moves < T_limit) {\n        // 1. Assign up to (V_-1) unpicked takoyakis to fingertips\n        pick_tasks.clear();\n        for (int i = 0; i < pickups.size(); ++i) {\n            if (!picked[i]) pick_tasks.push_back({i, pickups[i]});\n            if ((int)pick_tasks.size() == V_-1) break;\n        }\n        vector<Pos> batch_pick;\n        for (auto& t : pick_tasks) batch_pick.push_back(t.pos);\n\n        if (batch_pick.empty()) break; // no more takoyaki to grab\n\n        // 2. Find a root pos so that with this arm config, all batch picks are at some fingertip\n        // For each cell, check if, after translating root there, the fingertips cover all batch_pick\n        // Brute: try them all, but prioritize upper-left region (speed: grid isn't huge)\n        Pos picked_root = {-1,-1};\n        vector<int> fin_assignment(V_-1, -1); // index into pick_tasks\n\n        for (int rx = 0; rx < N && picked_root.x == -1; rx++)\n          for (int ry = 0; ry < N && picked_root.x == -1; ry++) {\n            vector<int> assign(V_-1, -1);\n            vector<bool> used(V_-1, false);\n            // For each pick cell, try to assign it to a finger\n            bool fail = false;\n            for (int ki = 0; ki < (int)batch_pick.size(); ++ki) {\n                bool matched = false;\n                for (int f = 0; f < V_-1; f++) {\n                    Pos tip = add({rx, ry}, leaves[f]);\n                    if (tip.x == batch_pick[ki].x && tip.y == batch_pick[ki].y && !used[f]) {\n                        assign[f] = ki;\n                        used[f] = true;\n                        matched = true;\n                        break;\n                    }\n                }\n                if (!matched) { fail = true; break; }\n            }\n            if (!fail) {\n                picked_root = {rx, ry};\n                fin_assignment = assign;\n                break;\n            }\n          }\n        if (picked_root.x == -1) {\n            // Cannot fit all, reduce batch size (never happens as long as len is not huge)\n            // In practical: fallback to fewer per batch (or decrease L at design time)\n            assert((int)batch_pick.size() < V_-1); // fallback not implemented here\n            break;\n        }\n\n        // 3. Plan root move sequence to picked_root from current root\n        // Simple greedy: manhattan path by rows, then by cols\n        int dx = picked_root.x - root_x, dy = picked_root.y - root_y;\n        string mv_cmd = \"UDLR\";\n        char cmds[4] = {'D','U','R','L'}; // For negative/positive steps in (dx,dy)\n        vector<string> steps;\n        // Move vertically\n        while (root_x < picked_root.x) { steps.push_back(\"D\"); root_x++; }\n        while (root_x > picked_root.x) { steps.push_back(\"U\"); root_x--; }\n        while (root_y < picked_root.y) { steps.push_back(\"R\"); root_y++; }\n        while (root_y > picked_root.y) { steps.push_back(\"L\"); root_y--; }\n\n        // Create a string of 2V chars: [move][rot*][act*]\n        string emptyrot(V_-1, '.');\n        string emptyact(V_, '.');\n        for (auto& s : steps) {\n            string out(2*V_, '.');\n            out[0] = s[0];\n            answers.push_back(out);\n        }\n\n        // 4. At pickup location: make all fingertips pick up if at their assigned target\n        string op(2*V_, '.');\n        // No move, no rotate\n        for (int f = 0; f < V_-1; ++f) {\n            int ki = fin_assignment[f];\n            if (ki != -1) {\n                // Only if not already picked and fingertip matches\n                op[V_+f+1] = 'P'; // leaves are vertices 1..V_-1\n                picked[pick_tasks[ki].idx] = true;\n                // Remove from grid\n                curr[batch_pick[ki].x][batch_pick[ki].y] = '0';\n                holding[f] = true;\n            } else {\n                op[V_+f+1] = '.';\n            }\n        }\n        answers.push_back(op);\n        ++total_moves;\n\n        // 5. Now, batch deliver: get up to (V_-1) non-delivered targets\n        deliv_tasks.clear();\n        for (int i = 0; i < delivers.size(); ++i) {\n            if (!delivered[i]) deliv_tasks.push_back({i, delivers[i]});\n            if ((int)deliv_tasks.size() == V_-1) break;\n        }\n        vector<Pos> batch_deliv;\n        for (auto& t : deliv_tasks) batch_deliv.push_back(t.pos);\n\n        // As above, try to fit deliver batch\n        Pos deliv_root = {-1,-1};\n        vector<int> fin_d_assign(V_-1, -1);\n        for (int rx = 0; rx < N && deliv_root.x == -1; rx++)\n          for (int ry = 0; ry < N && deliv_root.x == -1; ry++) {\n            vector<int> assign(V_-1, -1);\n            vector<bool> used(V_-1, false);\n            bool fail = false;\n            for (int ki = 0; ki < (int)batch_deliv.size(); ++ki) {\n                bool matched = false;\n                for (int f = 0; f < V_-1; f++) {\n                    Pos tip = add({rx, ry}, leaves[f]);\n                    if (tip.x == batch_deliv[ki].x && tip.y == batch_deliv[ki].y && !used[f] && holding[f]) {\n                        assign[f] = ki;\n                        used[f] = true;\n                        matched = true;\n                        break;\n                    }\n                }\n                if (!matched) { fail = true; break; }\n            }\n            if (!fail) {\n                deliv_root = {rx, ry};\n                fin_d_assign = assign;\n                break;\n            }\n          }\n        assert(deliv_root.x != -1); // Should always succeed\n\n        // Move root to delivery pos\n        dx = deliv_root.x - root_x;\n        dy = deliv_root.y - root_y;\n        // Move vertically\n        while (root_x < deliv_root.x) { string out(2*V_, '.'); out[0] = 'D'; answers.push_back(out); root_x++; }\n        while (root_x > deliv_root.x) { string out(2*V_, '.'); out[0] = 'U'; answers.push_back(out); root_x--; }\n        while (root_y < deliv_root.y) { string out(2*V_, '.'); out[0] = 'R'; answers.push_back(out); root_y++; }\n        while (root_y > deliv_root.y) { string out(2*V_, '.'); out[0] = 'L'; answers.push_back(out); root_y--; }\n\n        // Release at targets\n        string op2(2*V_, '.');\n        for (int f = 0; f < V_-1; ++f) {\n            int ki = fin_d_assign[f];\n            if (ki != -1) {\n                op2[V_+f+1] = 'P';\n                delivered[deliv_tasks[ki].idx] = true;\n                delivered_cnt++;\n                holding[f] = false;\n            } else {\n                op2[V_+f+1] = '.';\n            }\n        }\n        answers.push_back(op2);\n        ++total_moves;\n    }\n    // Output the answers\n    for (auto& a : answers) cout << a << '\\n';\n\n    // Could output a period to use unused moves (valid according to rules)\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing Point = pair<int, int>;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    cin >> N;\n    vector<Point> mackerels(N), sardines(N);\n    set<Point> used;\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n        mackerels[i] = {x, y};\n        used.insert({x, y});\n    }\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n        sardines[i] = {x, y};\n        used.insert({x, y});\n    }\n\n    // Let's try to find a rectangle (xL, yL) to (xH, yH) that catches many mackerel but few sardines\n\n    // First, try baseline: bounding box of all mackerels, but limit box to not be too big\n\n    int best_score = -1;\n    int best_xL=0, best_xH=0, best_yL=0, best_yH=0;\n\n    // 1. Compute overall bounding box of mackerels.\n    int mxL = 1e9, mxH = -1, myL = 1e9, myH = -1;\n    for (auto [x, y] : mackerels) {\n        mxL = min(mxL, x);\n        mxH = max(mxH, x);\n        myL = min(myL, y);\n        myH = max(myH, y);\n    }\n    // We'll expand and contract the bounding box to see if a better area can be found\n\n    vector<int> x_sorted, y_sorted;\n    for (auto [x, y] : mackerels) x_sorted.push_back(x), y_sorted.push_back(y);\n    sort(x_sorted.begin(), x_sorted.end());\n    sort(y_sorted.begin(), y_sorted.end());\n\n    // Let's try various quantiles to define rectangle boundaries, for basic heuristics.\n    for (int xlq = 0; xlq <= 20; ++xlq) {\n        int xL = x_sorted[N*xlq/40]; // from left\n        int xH = x_sorted[N - 1 - N*xlq/40]; // from right\n        for (int ylq = 0; ylq <= 20; ++ylq) {\n            int yL = y_sorted[N*ylq/40];\n            int yH = y_sorted[N - 1 - N*ylq/40];\n            if (xH <= xL || yH <= yL) continue;\n            int perim = 2*(xH-xL) + 2*(yH-yL);\n            if (perim > 400000) continue;\n\n            int mack_in = 0, sard_in = 0;\n            for (auto [x, y] : mackerels) {\n                if (xL <= x && x <= xH && yL <= y && y <= yH) ++mack_in;\n            }\n            for (auto [x, y] : sardines) {\n                if (xL <= x && x <= xH && yL <= y && y <= yH) ++sard_in;\n            }\n            int score = max(0, mack_in - sard_in + 1);\n            if (score > best_score || (score == best_score && perim < 2*(best_xH-best_xL+best_yH-best_yL))) {\n                best_score = score;\n                best_xL = xL;\n                best_xH = xH;\n                best_yL = yL;\n                best_yH = yH;\n            }\n        }\n    }\n\n    // Output 4-vertex rectangle\n    cout << 4 << '\\n';\n    cout << best_xL << ' ' << best_yL << '\\n';\n    cout << best_xL << ' ' << best_yH << '\\n';\n    cout << best_xH << ' ' << best_yH << '\\n';\n    cout << best_xH << ' ' << best_yL << '\\n';\n\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Timer for controlling total execution time if needed\nstruct Timer {\n    chrono::steady_clock::time_point st;\n    Timer() : st(chrono::steady_clock::now()) {}\n    double elapsed() const {\n        return chrono::duration<double>(chrono::steady_clock::now() - st).count();\n    }\n};\n\n// Rectangle structure\nstruct Rect {\n    int idx;         // original index\n    int w, h;        // estimated (noisy) width/height\n};\n\nstruct Placement {\n    int p, r;\n    char d;\n    int b;\n    Placement(int p, int r, char d, int b) : p(p), r(r), d(d), b(b) {}\n};\n\n// Predict placement via simple shelf/strip packing with rotation\nvector<Placement> pack_rectangles(const vector<Rect> &rects, int mode = 0) {\n    // mode: 0 = shelf, 1 = shelf rotated, 2 = tallest first, etc.\n    int N = rects.size();\n    vector<Placement> res;\n\n    // Storage for virtual \"placed rectangles\": x, y, w, h\n    struct Entry { int x, y, w, h, idx; };\n    vector<Entry> shelf; // shelves (row y, height)\n    int cur_x = 0, cur_y = 0, shelf_height = 0;\n    int box_w = 0, box_h = 0;\n\n    // We'll use a working permutation for iterated tests\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n\n    // Different orderings by mode\n    if (mode == 1) {\n        // By decreasing height\n        sort(order.begin(), order.end(), [&](int i, int j) {\n            int ai = max(rects[i].h, rects[i].w), aj = max(rects[j].h, rects[j].w);\n            return ai > aj;\n        });\n    }\n    else if (mode == 2) {\n        // By decreasing area\n        sort(order.begin(), order.end(), [&](int i, int j) {\n            long long ai = 1LL * rects[i].h * rects[i].w, aj = 1LL * rects[j].h * rects[j].w;\n            return ai > aj;\n        });\n    }\n    // Else 0: input order\n\n    // Simple horizontal shelf (pack from left, stacking up)\n    cur_x = 0; cur_y = 0; shelf_height = 0;\n    shelf.clear();\n\n    for (int k = 0; k < N; ++k) {\n        int i = order[k];\n        int wi = rects[i].w, hi = rects[i].h, ri = 0;\n        // Choose rotation for best \"fit\" (min shelf height)\n        if (wi > hi) {\n            // Rotate to make height less or equal\n            swap(wi, hi);\n            ri = 1;\n        }\n        // If doesn't fit on this shelf, start new shelf\n        if (cur_x + wi > 1000000000) { // Should never happen, but just in case...\n            cur_x = 0;\n            cur_y += shelf_height;\n            shelf_height = 0;\n        }\n        // Place at (cur_x, cur_y) (align with y=0)\n        int b_i = -1; // reference\n        char d_i = 'U';\n        if (cur_x == 0) {\n            // Align left edge to 0 with y=cur_y. Place up to y=0.\n            d_i = 'U';\n            b_i = -1;\n        }\n        else {\n            // Place left of previous rectangle in shelf\n            d_i = 'L';\n            b_i = shelf.back().idx;\n        }\n        res.emplace_back(i, ri, d_i, b_i);\n        shelf.push_back({cur_x, cur_y, wi, hi, i});\n        cur_x += wi;\n        shelf_height = max(shelf_height, hi);\n        box_w = max(box_w, cur_x);\n        box_h = max(box_h, cur_y + hi);\n    }\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\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        int w, h;\n        cin >> w >> h;\n        rects[i] = {i, w, h};\n    }\n\n    // Timer to stop before TLE\n    Timer timer;\n    int max_modes = min(T, 3); // try 3 different approaches\n\n    for (int t = 0; t < T; ++t) {\n        // Select mode and pack sequence\n        int mode = t % max_modes;\n        vector<Placement> plan = pack_rectangles(rects, mode);\n\n        cout << plan.size() << '\\n';\n        for (auto &pl : plan) {\n            cout << pl.p << ' ' << pl.r << ' ' << pl.d << ' ' << pl.b << '\\n';\n        }\n        cout << flush;\n\n        // Receive measured box sizes\n        int W_meas, H_meas;\n        cin >> W_meas >> H_meas;\n    }\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Constants\nconstexpr int INF = 1e9+5;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, H;\n    cin >> N >> M >> H;\n    vector<int> A(N);\n    for (auto &x : A) cin >> x;\n\n    vector<vector<int>> adj(N);\n    for (int i=0;i<M;++i) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    vector<pair<int, int>> coords(N);\n    for (int i=0;i<N;++i) {\n        int x, y; cin >> x >> y;\n        coords[i] = {x, y};\n    }\n\n    // Output structures\n    vector<int> parent(N, -1);\n    vector<int> depth(N, -1);\n    vector<bool> assigned(N, false);\n\n    // Prepare node order: high-beauty first\n    vector<int> node_order(N);\n    iota(node_order.begin(), node_order.end(), 0);\n    sort(node_order.begin(), node_order.end(),\n        [&](int i, int j){\n            return A[i] > A[j];\n        });\n\n    int assigned_cnt = 0;\n    for (int ni = 0; ni < N; ++ni) {\n        int v = node_order[ni];\n        if (assigned[v]) continue;\n\n        // Start a new tree rooted at v\n        parent[v] = -1;\n        depth[v] = 0;\n        assigned[v] = true;\n        assigned_cnt++;\n\n        // BFS up to depth H\n        queue<pair<int, int>> q; // (node, depth)\n        q.push({v, 0});\n        while (!q.empty()) {\n            auto [cur, d] = q.front(); q.pop();\n            if (d == H) continue;\n\n            // Get unassigned neighbors, sort by A[.]\n            vector<pair<int, int>> nbrs;\n            for (int to : adj[cur]) {\n                if (!assigned[to]) {\n                    nbrs.emplace_back(-A[to], to);\n                }\n            }\n            sort(nbrs.begin(), nbrs.end()); // high-A comes first\n\n            for (auto& [neg_val, nb] : nbrs) {\n                if (assigned[nb]) continue;\n                parent[nb] = cur;\n                depth[nb] = d+1;\n                assigned[nb] = true;\n                assigned_cnt++;\n                q.push({nb, d+1});\n            }\n        }\n    }\n\n    // Output final parent array\n    for (int i=0; i<N; ++i) {\n        cout << parent[i] << (i+1==N ? '\\n' : ' ');\n    }\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\n// For each Oni, remove in a Fukunokami-free direction, restoring board afterwards.\n\nstruct Move {\n    char dir;\n    int idx;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N;\n    cin >> N;\n    vector<string> board(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> board[i];\n    }\n\n    // Save Oni positions at start\n    vector<pair<int,int>> onis;\n    for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j)\n        if (board[i][j] == 'x') onis.emplace_back(i,j);\n    // For safety, mark the Oni removed as we go\n    vector<string> current = board;\n    vector<Move> moves;\n\n    // We'll keep track of Oni cells left. Remove each one.\n    for (auto [i, j] : onis) {\n        // If the Oni was already shifted off, skip\n        if (current[i][j] != 'x') continue;\n\n        // Try all 4 directions for a safe direction\n        // (Up, Down, Left, Right)\n\n        // Up (remove by shifting col up j times)\n        bool upSafe = true;\n        for (int k = 0; k < i; ++k) if (current[k][j] == 'o') upSafe = false;\n\n        // Down\n        bool downSafe = true;\n        for (int k = i+1; k < N; ++k) if (current[k][j] == 'o') downSafe = false;\n\n        // Left\n        bool leftSafe = true;\n        for (int k = 0; k < j; ++k) if (current[i][k] == 'o') leftSafe = false;\n\n        // Right\n        bool rightSafe = true;\n        for (int k = j+1; k < N; ++k) if (current[i][k] == 'o') rightSafe = false;\n\n        // Remove Oni at (i,j) by safe direction and undo\n        if (upSafe) {\n            // Shift col j up i+1 times, then down i times\n            for (int t = 0; t < i+1; ++t) {\n                moves.push_back({'U', j});\n                // Perform the shift\n                char out = current[0][j];\n                for (int r = 0; r < N-1; ++r)\n                    current[r][j] = current[r+1][j];\n                current[N-1][j] = '.';\n            }\n            for (int t = 0; t < i; ++t) {\n                moves.push_back({'D', j});\n                // Perform the shift\n                char out = current[N-1][j];\n                for (int r = N-1; r > 0; --r)\n                    current[r][j] = current[r-1][j];\n                current[0][j] = '.';\n            }\n            continue;\n        }\n        if (downSafe) {\n            // Shift col j down N-i times, then up N-i-1 times\n            for (int t = 0; t < N-i; ++t) {\n                moves.push_back({'D', j});\n                char out = current[N-1][j];\n                for (int r = N-1; r > 0; --r)\n                    current[r][j] = current[r-1][j];\n                current[0][j] = '.';\n            }\n            for (int t = 0; t < N-i-1; ++t) {\n                moves.push_back({'U', j});\n                char out = current[0][j];\n                for (int r = 0; r < N-1; ++r)\n                    current[r][j] = current[r+1][j];\n                current[N-1][j] = '.';\n            }\n            continue;\n        }\n        if (leftSafe) {\n            // Shift row i left j+1 times, then right j times\n            for (int t = 0; t < j+1; ++t) {\n                moves.push_back({'L', i});\n                char out = current[i][0];\n                for (int c = 0; c < N-1; ++c)\n                    current[i][c] = current[i][c+1];\n                current[i][N-1] = '.';\n            }\n            for (int t = 0; t < j; ++t) {\n                moves.push_back({'R', i});\n                char out = current[i][N-1];\n                for (int c = N-1; c > 0; --c)\n                    current[i][c] = current[i][c-1];\n                current[i][0] = '.';\n            }\n            continue;\n        }\n        if (rightSafe) {\n            // Shift row i right N-j times, then left N-j-1 times\n            for (int t = 0; t < N-j; ++t) {\n                moves.push_back({'R', i});\n                char out = current[i][N-1];\n                for (int c = N-1; c > 0; --c)\n                    current[i][c] = current[i][c-1];\n                current[i][0] = '.';\n            }\n            for (int t = 0; t < N-j-1; ++t) {\n                moves.push_back({'L', i});\n                char out = current[i][0];\n                for (int c = 0; c < N-1; ++c)\n                    current[i][c] = current[i][c+1];\n                current[i][N-1] = '.';\n            }\n            continue;\n        }\n        // If this point reached, something is wrong, but per constraints, won't happen\n        cerr << \"No safe direction for Oni at (\" << i << \",\" << j << \")\\n\";\n        assert(false);\n    }\n\n    // Output\n    cout << moves.size() << '\\n'; // For debugging (optional)\n    for (auto &mv : moves) {\n        cout << mv.dir << ' ' << mv.idx << '\\n';\n    }\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nusing namespace std::chrono;\n\nconstexpr int MAX_N = 100;\nconstexpr int MAX_L = 500000;\n\nint N, L;\nvector<int> T;\n\nvector<int> a, b;\n\n// Simulate the process, return the t_i (empirical frequencies)\nvector<int> simulate(int sim_steps = MAX_L, const vector<int> &a = {}, const vector<int> &b = {}) {\n    vector<int> t(N, 0);\n    int cur = 0;\n    t[0]++;\n    vector<int> count(N, 0);\n    count[0]++;\n    for (int step = 1; step < sim_steps; ++step) {\n        int times = count[cur];\n        int nx = (times % 2 == 1) ? a[cur] : b[cur];\n        cur = nx;\n        t[cur]++;\n        count[cur]++;\n    }\n    return t;\n}\n\n// Compute error between actual and target T\nll compute_error(const vector<int>& t) {\n    ll err = 0;\n    for (int i = 0; i < N; ++i) err += abs(t[i] - T[i]);\n    return err;\n}\n\n// Set a_i and b_i to try to match T_i\nvoid set_initial_ab(vector<int>& a, vector<int>& b) {\n    // For each i, let a_i, b_i be (i+1)%N and (i+2)%N by default (RR)\n    for (int i = 0; i < N; ++i) {\n        a[i] = (i + 1) % N;\n        b[i] = (i + 2) % N;\n    }\n    // Try to bias more towards high T_i: for each i, pick a_i/b_i among top target indices\n    vector<pair<int, int>> t_idx(N);\n    for (int i = 0; i < N; ++i) t_idx[i] = {T[i], i};\n    sort(t_idx.rbegin(), t_idx.rend());\n    int topk = 10;\n    for (int i = 0; i < N; ++i) {\n        int idx1 = t_idx[i % topk].second, idx2 = t_idx[(i+1) % topk].second;\n        if (idx1 == i) idx1 = (idx1+1)%N;\n        if (idx2 == i) idx2 = (idx2+2)%N;\n        a[i] = idx1;\n        b[i] = idx2;\n    }\n}\n\n// Hill climb: try to adjust (a_i, b_i) to minimize error\nvoid tune(vector<int>& a, vector<int>& b, const vector<int>& T, int time_ms = 1700) {\n    auto start_clock = steady_clock::now();\n    mt19937 rng(42);\n    auto best_a = a, best_b = b;\n    auto t = simulate(MAX_L, a, b);\n    auto best_err = compute_error(t);\n\n    vector<int> indices(N);\n    iota(indices.begin(), indices.end(), 0);\n\n    while(duration_cast<milliseconds>(steady_clock::now() - start_clock).count() < time_ms) {\n        int i = rng() % N;\n        int pick = rng() % 2;\n        int old_val = (pick == 0 ? a[i] : b[i]);\n        int new_val = rng() % N;\n        if (new_val == i) continue;\n        if (pick == 0) a[i] = new_val;\n        else           b[i] = new_val;\n\n        auto t2 = simulate(20000, a, b); // shorter sim for speed\n        ll err2 = compute_error(t2);\n        if (err2 < best_err) {\n            // Accept and simulate on the full run\n            auto t_full = simulate(MAX_L, a, b);\n            ll err_full = compute_error(t_full);\n            if (err_full < best_err) {\n                best_err = err_full;\n                best_a = a; best_b = b;\n            } else {\n                if (pick == 0) a[i] = old_val;\n                else           b[i] = old_val;\n            }\n        } else {\n            if (pick == 0) a[i] = old_val;\n            else           b[i] = old_val;\n        }\n    }\n    a = best_a; b = best_b;\n}\n\nint main(){\n    ios::sync_with_stdio(false); cin.tie(0);\n    cin >> N >> L;\n    T.resize(N);\n    for(int i=0; i<N; ++i) cin >> T[i];\n\n    a.assign(N, 0); b.assign(N, 0);\n\n    set_initial_ab(a, b);\n    tune(a, b, T);\n\n    for(int i=0; i<N; ++i) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct City {\n    int id;\n    int lx, rx, ly, ry;\n    double cx, cy; // center\n};\n\nstruct Edge {\n    int u, v;\n    int est_dist; // estimate dist (center dist)\n    Edge(int uu, int vv, int d): u(min(uu, vv)), v(max(uu, vv)), est_dist(d) {}\n    bool operator<(const Edge& o) const {\n        if (est_dist != o.est_dist) return est_dist < o.est_dist;\n        if (u != o.u) return u < o.u;\n        return v < o.v;\n    }\n    bool operator==(const Edge& o) const {\n        return u==o.u && v==o.v && est_dist==o.est_dist;\n    }\n};\n\n// Find root for union-find\nstruct UF {\n    vector<int> par;\n    UF(int n): par(n) { iota(par.begin(), par.end(), 0); }\n    int find(int x) {\n        while (par[x] != x) {\n            par[x] = par[par[x]];\n            x = par[x];\n        }\n        return x;\n    }\n    bool unite(int x, int y) {\n        int rx = find(x), ry = find(y);\n        if (rx == ry) return false;\n        par[ry] = rx; return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, Q, L, W;\n    cin >> N >> M >> Q >> L >> W;\n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n\n    vector<City> cities(N);\n    for (int i = 0; i < N; ++i) {\n        int lx, rx, ly, ry;\n        cin >> lx >> rx >> ly >> ry;\n        double cx = 0.5 * (lx + rx), cy = 0.5 * (ly + ry);\n        cities[i] = {i, lx, rx, ly, ry, cx, cy};\n    }\n\n    // Partition: sort by center-x then center-y\n    vector<int> idx(N); iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int i, int j) {\n        if (cities[i].cx != cities[j].cx) return cities[i].cx < cities[j].cx;\n        return cities[i].cy < cities[j].cy;\n    });\n\n    vector<vector<int>> groups;\n    int ofs = 0;\n    for (int i = 0; i < M; ++i) {\n        vector<int> grp;\n        for (int k = 0; k < G[i]; ++k, ++ofs) {\n            grp.push_back(idx[ofs]);\n        }\n        groups.push_back(grp);\n    }\n\n    set<pair<int, int>> used_query_edges; // Set of (min(u,v), max(u,v)) already output by queries\n\n    vector<vector<pair<int, int>>> mst_edges(M); // Final edge list for each group\n\n    int query_cnt = 0;\n    // For each group: gather MST edges from queries and/or center-MST as fallback patch\n    for (int gi = 0; gi < M; ++gi) {\n        const auto& grp = groups[gi];\n        int sz = grp.size();\n        set<pair<int, int>> group_edges;\n        vector<pair<int, int>> query_edges;\n\n        if (sz <= L && query_cnt < Q) {\n            // Query whole group\n            cout << \"? \" << sz;\n            for (int x : grp) cout << \" \" << x;\n            cout << endl; cout.flush();\n            for (int i = 0; i < sz-1; ++i) {\n                int u, v;\n                cin >> u >> v;\n                if (u > v) swap(u, v);\n                group_edges.emplace(u, v);\n            }\n            query_cnt++;\n        } else {\n            // Sliding windows\n            for (int st = 0; st < sz-1 && query_cnt < Q; st += (L-1)) {\n                int en = min(st+L, sz);\n                int actual = en - st;\n                if (actual < 2) break;\n                vector<int> subset(grp.begin()+st, grp.begin()+en);\n                cout << \"? \" << actual;\n                for (int x : subset) cout << \" \" << x;\n                cout << endl; cout.flush();\n                for (int i = 0; i < actual-1; ++i) {\n                    int u, v;\n                    cin >> u >> v;\n                    if (u > v) swap(u, v);\n                    group_edges.emplace(u, v);\n                }\n                query_cnt++;\n            }\n        }\n\n        // After all queries, collected group_edges may not be enough for tree\n        // Patch with MST on center-points\n        // Build graph (indexed by group vertex list order!)\n        int V = sz;\n        map<int,int> city_to_groupidx;\n        for (int i=0;i<sz;i++) city_to_groupidx[grp[i]]=i;\n\n        // Build conn graph, find CCs\n        UF uf(V);\n        for (auto [u,v]: group_edges) {\n            if (!city_to_groupidx.count(u) || !city_to_groupidx.count(v)) continue;\n            int a = city_to_groupidx[u], b = city_to_groupidx[v];\n            uf.unite(a,b);\n        }\n        // For each component, patch missing links via Kruskal on centers\n        vector<tuple<int,int,int>> center_edges;\n        for (int i = 0; i < sz; ++i) {\n            for (int j = i+1; j < sz; ++j) {\n                int u = grp[i], v = grp[j];\n                double dx = cities[u].cx - cities[v].cx;\n                double dy = cities[u].cy - cities[v].cy;\n                int faux_dist = (int)floor(sqrt(dx*dx+dy*dy));\n                center_edges.emplace_back(faux_dist, i, j);\n            }\n        }\n        sort(center_edges.begin(), center_edges.end());\n\n        // Build MST using (group_edges U center-edges) and output final tree\n        UF final_uf(V);\n        set<pair<int, int>> final_mst_edges = group_edges;\n        // First, union group_edges\n        for (auto [u,v]: group_edges) {\n            if (!city_to_groupidx.count(u) || !city_to_groupidx.count(v)) continue;\n            int a = city_to_groupidx[u], b = city_to_groupidx[v];\n            final_uf.unite(a,b);\n        }\n        // Add center-based edges if needed\n        for (auto [dist, i, j]: center_edges) {\n            if (final_mst_edges.size() >= sz-1) break;\n            if (final_uf.unite(i,j)) {\n                int u = grp[i], v = grp[j];\n                if (u > v) swap(u, v);\n                final_mst_edges.emplace(u, v);\n            }\n        }\n\n        // Output as vector and store\n        mst_edges[gi].clear();\n        for (auto [u,v]: final_mst_edges) {\n            mst_edges[gi].emplace_back(u, v);\n        }\n        // (not needed: extra check for if MST is complete, as final_uf will patch)\n    }\n    // Output answer\n    cout << \"!\" << endl;\n    for (int gi = 0; gi < M; ++gi) {\n        // output group\n        for (int i = 0; i < (int)groups[gi].size(); ++i) {\n            if (i) cout << \" \";\n            cout << groups[gi][i];\n        }\n        cout << endl;\n        // output edges\n        for (auto [u,v]: mst_edges[gi]) {\n            cout << u << \" \" << v << endl;\n        }\n    }\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Constants\nconstexpr int N = 20, M = 40;\nconstexpr int MAX_ACTIONS = 2 * N * M;\n\n// Directions and helpers\nconstexpr int DIRS = 4;\nconst int dx[DIRS] = {-1, 1, 0, 0}; // U, D, L, R\nconst int dy[DIRS] = {0, 0, -1, 1};\nconst char dirC[DIRS] = {'U', 'D', 'L', 'R'};\n\nstruct Pos {\n    int x, y;\n    bool operator==(const Pos& r) const { return x == r.x && y == r.y; }\n};\n\n// Try to slide from p in dir, return last cell we would land on (or -1 if blocked right away)\nPos slide_end(const Pos& p, int d, const vector<vector<bool>>& block) {\n    int nx = p.x, ny = p.y;\n    while (1) {\n        int tx = nx + dx[d], ty = ny + dy[d];\n        if (tx < 0 || tx >= N || ty < 0 || ty >= N) break;\n        if (block[tx][ty]) break;\n        nx = tx; ny = ty;\n    }\n    return {nx, ny};\n}\n\n// Return true if we can clear path between p1 and p2 (line, no block)\n// Assumes p1 and p2 are in the same row or column.\nbool clear_path_between(const Pos& p1, const Pos& p2, const vector<vector<bool>>& block) {\n    if (p1.x == p2.x) {\n        int sy = min(p1.y, p2.y), ey = max(p1.y, p2.y);\n        for (int y = sy + 1; y <= ey - 1; ++y)\n            if (block[p1.x][y])\n                return false;\n        return true;\n    }\n    if (p1.y == p2.y) {\n        int sx = min(p1.x, p2.x), ex = max(p1.x, p2.x);\n        for (int x = sx + 1; x <= ex - 1; ++x)\n            if (block[x][p1.y])\n                return false;\n        return true;\n    }\n    return false;\n}\n\n// Returns a Move sequence to get from src to tgt with Moves (BFS shortest path).\nvector<pair<char, char>> naive_moves(Pos src, Pos tgt, const vector<vector<bool>>& block) {\n    vector<vector<Pos>> prev(N, vector<Pos>(N, {-1, -1}));\n    queue<Pos> que;\n    que.push(src);\n    prev[src.x][src.y] = src;\n    while (!que.empty()) {\n        auto c = que.front(); que.pop();\n        if (c == tgt) break;\n        for (int d = 0; d < DIRS; ++d) {\n            int nx = c.x + dx[d], ny = c.y + dy[d];\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n            if (block[nx][ny]) continue;\n            if (prev[nx][ny].x != -1) continue;\n            prev[nx][ny] = c;\n            que.push({nx, ny});\n        }\n    }\n    // Reconstruct path\n    vector<Pos> path;\n    if (prev[tgt.x][tgt.y].x == -1) return {}; // unreachable\n    for (Pos p = tgt; !(p == src); p = prev[p.x][p.y])\n        path.push_back(p);\n    reverse(path.begin(), path.end());\n    // Convert to action sequence\n    vector<pair<char, char>> res;\n    Pos c = src;\n    for (auto& p : path) {\n        int d = -1;\n        for (int i = 0; i < 4; ++i)\n            if (c.x + dx[i] == p.x && c.y + dy[i] == p.y)\n                d = i;\n        res.emplace_back('M', dirC[d]);\n        c = p;\n    }\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Input\n    int n, m;\n    cin >> n >> m;\n    vector<Pos> targets(m);\n    for (int i = 0; i < m; ++i)\n        cin >> targets[i].x >> targets[i].y;\n\n    vector<vector<bool>> block(N, vector<bool>(N, false));\n    vector<pair<char, char>> actions;\n\n    Pos cur = targets[0];\n\n    for (int i = 1; i < m; ++i) {\n        Pos next = targets[i];\n\n        // If in line (row/col), try to slide\n        bool did = false;\n        for (int d = 0; d < 4; ++d) {\n            int tx = cur.x, ty = cur.y;\n            if ((d == 0 && next.x >= tx && next.y == ty) ||\n                (d == 1 && next.x <= tx && next.y == ty) ||\n                (d == 2 && next.y >= ty && next.x == tx) ||\n                (d == 3 && next.y <= ty && next.x == tx))\n                continue; // wrong direction\n\n            // For our actual d\n            if ((d == 0 || d == 1) && cur.y == next.y && cur.x != next.x) {\n                // same col, check direction\n                int sd = (next.x > cur.x) ? 1 : 0;\n                if (sd != d) continue;\n                if (clear_path_between(cur, next, block)) {\n                    // Would we overshoot sliding in this dir?\n                    Pos landing = slide_end(cur, d, block);\n                    if (landing == next) {\n                        actions.emplace_back('S', dirC[d]);\n                        cur = next;\n                        did = true;\n                        break;\n                    } else if ((d == 0 && next.x > 0 && !block[next.x-1][next.y]) ||\n                               (d == 1 && next.x < N-1 && !block[next.x+1][next.y])) {\n                        // Place a block after the target, so slide will stop on it\n                        int bx = (d == 0) ? next.x-1 : next.x+1;\n                        int by = next.y;\n                        actions.emplace_back('A', dirC[d]);\n                        block[bx][by] = true;\n                        actions.emplace_back('S', dirC[d]);\n                        cur = next;\n                        // Remove the block after\n                        actions.emplace_back('A', dirC[d]);\n                        block[bx][by] = false;\n                        did = true;\n                        break;\n                    }\n                }\n            }\n            else if ((d == 2 || d == 3) && cur.x == next.x && cur.y != next.y) {\n                int sd = (next.y > cur.y) ? 3 : 2;\n                if (sd != d) continue;\n                if (clear_path_between(cur, next, block)) {\n                    Pos landing = slide_end(cur, d, block);\n                    if (landing == next) {\n                        actions.emplace_back('S', dirC[d]);\n                        cur = next;\n                        did = true;\n                        break;\n                    } else if ((d == 2 && next.y > 0 && !block[next.x][next.y-1]) ||\n                               (d == 3 && next.y < N-1 && !block[next.x][next.y+1])) {\n                        int bx = next.x;\n                        int by = (d == 2) ? next.y-1 : next.y+1;\n                        actions.emplace_back('A', dirC[d]);\n                        block[bx][by] = true;\n                        actions.emplace_back('S', dirC[d]);\n                        cur = next;\n                        actions.emplace_back('A', dirC[d]);\n                        block[bx][by] = false;\n                        did = true;\n                        break;\n                    }\n                }\n            }\n        }\n        if (did) continue;\n\n        // Default: just move\n        vector<pair<char, char>> path = naive_moves(cur, next, block);\n        for (auto& act : path) actions.push_back(act);\n        cur = next;\n    }\n\n    // Output actions\n    for (auto& ac : actions)\n        cout << ac.first << ' ' << ac.second << '\\n';\n}"},"2":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing i64 = int64_t;\n\nstruct Rect {\n    int x1, y1, x2, y2; // [x1,x2), [y1,y2)\n    i64 area() const { return i64(x2-x1) * i64(y2-y1); }\n    bool contains(double x, double y) const {\n        return x > x1 && x < x2 && y > y1 && y < y2;\n    }\n    bool overlap(const Rect& o) const {\n        return !(x2 <= o.x1 || x1 >= o.x2 || y2 <= o.y1 || y1 >= o.y2);\n    }\n};\n\nstruct Company {\n    int id, x, y;\n    i64 r;\n    Rect rect;\n};\n\nconstexpr int GRID_SIZE = 10000;\nconstexpr int MAX_TRY_AREA = 10;\nconstexpr int VARIANTS = 8;\n\nint n;\nvector<Company> companies;\nvector<Rect> placedRects;\n\n// Check overlap with existing placedRects\nbool checkOverlap(const Rect& r) {\n    for (const auto& o : placedRects)\n        if (r.overlap(o)) return true;\n    return false;\n}\n\n// Try to build a rectangle of area close to ri, containing (cx,cy)+0.5, not overlapping any in placedRects\nRect try_place(int cx, int cy, i64 ri) {\n    // Try almost-square sizes, widen search for best fit\n    int best_w = 0, best_h = 0, best_shift_x = 0, best_shift_y = 0;\n    double best_score = 1e9;\n    \n    vector<pair<int,int>> attempts;\n    int sqr = max(1, int(std::sqrt(ri)));\n    for (int dw = -2; dw <= 2; ++dw) {\n        int w = max(1, sqr + dw);\n        int h = max(1, int((ri + w-1)/w));\n        if (i64(w)*h >= ri) attempts.emplace_back(w,h);\n        if (i64(h)*w >= ri) attempts.emplace_back(h,w);\n    }\n    for (auto [w, h]: attempts) {\n        for (int dx=-1;dx<=1;++dx)for(int dy=-1;dy<=1;++dy){\n            int x1 = clamp(cx - w/2 + dx, 0, GRID_SIZE-w);\n            int y1 = clamp(cy - h/2 + dy, 0, GRID_SIZE-h);\n            int x2 = x1+w, y2 = y1+h;\n            Rect r{x1, y1, x2, y2};\n            // must contain target point\n            double xx = cx+0.5, yy = cy+0.5;\n            if (xx <= x1 || xx >= x2 || yy <= y1 || yy >= y2) continue;\n            if (checkOverlap(r)) continue;\n            // favor rectangle closest to area\n            double score = abs((double)r.area() - ri) + 0.1*(w-h)*(w-h);\n            if (score < best_score) {\n                best_score = score; best_w=w; best_h=h; best_shift_x=x1; best_shift_y=y1;\n            }\n        }\n    }\n    // If found feasible\n    if (best_score < 1e8) {\n        return Rect{best_shift_x, best_shift_y, best_shift_x+best_w, best_shift_y+best_h};\n    }\n    // fallback: return an invalid rectangle\n    return Rect{-1,-1,-1,-1};\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    cin >> n;\n    companies.resize(n);\n    for (int i = 0; i < n; ++i) {\n        int x, y; i64 r;\n        cin >> x >> y >> r;\n        companies[i] = Company{i, x, y, r, {}};\n    }\n\n    // Place biggest requests first\n    sort(companies.begin(), companies.end(), [&](const Company& a, const Company& b){\n        return a.r > b.r;\n    });\n\n    placedRects.clear();\n\n    for (auto& comp : companies) {\n        Rect rect;\n        i64 tr = comp.r;\n        // Try to assign area as close as possible, but allow up to 10% reduction if needed\n        int area_shrink = 0;\n        while (area_shrink < 15) {\n            i64 req_area = max(1LL, tr - tr * area_shrink / 100);\n            rect = try_place(comp.x, comp.y, req_area);\n            if (rect.x1 != -1)\n                break; // Success\n            area_shrink += 2;\n        }\n        if (rect.x1 == -1) {\n            // could not place, place a pixel at the position\n            rect = Rect{comp.x, comp.y, comp.x+1, comp.y+1};\n        }\n        comp.rect = rect;\n        placedRects.push_back(rect);\n    }\n\n    // Restore the original order\n    sort(companies.begin(), companies.end(), [&](const Company& a, const Company& b){\n        return a.id < b.id;\n    });\n\n    // Output\n    for (auto& comp : companies) {\n        auto& r = comp.rect;\n        cout << r.x1 << ' ' << r.y1 << ' ' << r.x2 << ' ' << r.y2 << '\\n';\n    }\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Directions: U, D, L, R\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\nconst char dch[4] = {'U', 'D', 'L', 'R'};\nconst int N = 50;\n\nstruct Tile {\n    vector<pair<int, int>> cells;       // All belonging cells\n    set<int> adj;                       // Adjacent tiles\n    int max_val = -1, max_cell_i = -1, max_cell_j = -1;\n};\n\nint si, sj;\nint t[N][N];      // tile id of (i,j)\nint p[N][N];      // score of (i,j)\nvector<Tile> tiles;\nint ntiles;\n\nvoid preprocess() {\n    // Build tile information (cells and adjacents)\n    map<int, vector<pair<int,int>>> tile_cells;\n    for(int i = 0; i < N; ++i) for(int j = 0; j < N; ++j)\n        tile_cells[t[i][j]].emplace_back(i, j);\n    \n    ntiles = tile_cells.size();\n    tiles.resize(ntiles);\n\n    for(auto &[tid, cells] : tile_cells) {\n        Tile tile;\n        tile.cells = std::move(cells);\n        int maxv = -1, maxi = -1, maxj = -1;\n        for(auto &[i, j] : tile.cells) {\n            if(p[i][j] > maxv) {\n                maxv = p[i][j]; maxi = i; maxj = j;\n            }\n        }\n        tile.max_val = maxv;\n        tile.max_cell_i = maxi;\n        tile.max_cell_j = maxj;\n        tiles[tid] = tile;\n    }\n\n    // Compute adjacency between tiles\n    for(int i = 0; i < N; ++i) for(int j = 0; j < N; ++j) {\n        int tid = t[i][j];\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 >= N || nj >= N) continue;\n            int ntid = t[ni][nj];\n            if(ntid != tid)\n                tiles[tid].adj.insert(ntid);\n        }\n    }\n}\n\n// A greedy DFS: always pick the unvisited adjacent tile with the highest-valued entry cell\n// Returns the movement string\nstring greedy_dfs_path() {\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    vector<bool> tile_used(ntiles, false);\n\n    int ci = si, cj = sj;\n    int curr_tid = t[ci][cj];\n\n    tile_used[curr_tid] = true;\n    visited[ci][cj] = true;\n\n    string path;\n    // path.reserve(N*N);\n\n    // We maintain (*ci, *cj) = current position\n    vector<vector<bool>> in_path(N, vector<bool>(N, false)); // Not strictly needed, but could help visualize\n\n    while(true) {\n        // Find which directions to go: only those leading to a tile not yet used\n        int best_score = -1, best_d = -1, best_ni = -1, best_nj = -1;\n        for(int d = 0; d < 4; ++d) {\n            int ni = ci + di[d], nj = cj + dj[d];\n            if(ni < 0 || nj < 0 || ni >= N || nj >= N) continue;\n            int n_tid = t[ni][nj];\n            if(tile_used[n_tid]) continue; // Tile already used\n            // Can move to this direction\n            if(p[ni][nj] > best_score) {\n                best_score = p[ni][nj];\n                best_d = d;\n                best_ni = ni;\n                best_nj = nj;\n            }\n        }\n        if(best_d == -1) break; // No further move possible\n\n        // Move to best_ni, best_nj\n        ci = best_ni; cj = best_nj;\n        curr_tid = t[ci][cj];\n        tile_used[curr_tid] = true;\n        visited[ci][cj] = true;\n        path += dch[best_d];\n    }\n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    // Input\n    cin >> si >> sj;\n    for(int i = 0; i < N; ++i)\n        for(int j = 0; j < N; ++j)\n            cin >> t[i][j];\n\n    for(int i = 0; i < N; ++i)\n        for(int j = 0; j < N; ++j)\n            cin >> p[i][j];\n\n    preprocess();\n\n    string path = greedy_dfs_path();\n\n    cout << path << endl;\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Constants\nconstexpr int N = 30;\nconstexpr int Q = 1000;\nconstexpr int DIR = 4;\nconst char dir_chars[DIR] = {'U','D','L','R'};\nconst int dx[DIR] = {-1,+1,0,0}, dy[DIR] = {0,0,-1,+1};\n\n// Edge structure for statistics\nstruct EdgeInfo {\n    double est = 5000.0;\n    int count = 0;\n    double sum = 0.0;\n    bool known = false;\n    \n    void update(double val) {\n        sum += val;\n        count++;\n        est = sum / count;\n    }\n    void add_sample(double val, double smoothing=0.8) {\n        if (!known) { est = val; known=true; return; }\n        est = smoothing*est + (1-smoothing)*val;\n    }\n};\n\n// Edge model: grid of edge estimates, separate for horizontal and vertical\nEdgeInfo horiz[N][N-1]; // between (i,j) and (i,j+1)\nEdgeInfo vert[N-1][N]; // between (i,j) and (i+1,j)\n\n// For edge encoding\ninline bool in_grid(int i, int j) { return 0<=i && i<N && 0<=j && j<N; }\n\n// Returns list of moves ('U','D','L','R') for s to t using current edge estimates\nvector<char> estimate_path(pair<int,int> s, pair<int,int> t) {\n    using T = tuple<double,int,int,string>; // cost, i, j, path\n    priority_queue<T, vector<T>, greater<>> pq;\n    vector<vector<double>> dist(N, vector<double>(N, 1e18));\n    vector<vector<pair<int,int>>> prev(N, vector<pair<int,int>>(N, {-1,-1}));\n    vector<vector<int>> previdx(N, vector<int>(N, -1));\n    dist[s.first][s.second] = 0;\n    pq.emplace(0.0, s.first, s.second, \"\");\n    while (!pq.empty()) {\n        auto [cost, i, j, p] = pq.top(); pq.pop();\n        if (make_pair(i,j)==t) {\n            // reconstruct path\n            vector<char> res;\n            int x = t.first, y = t.second;\n            while (prev[x][y].first != -1) {\n                int px = prev[x][y].first, py = prev[x][y].second;\n                int d = previdx[x][y];\n                res.push_back(dir_chars[d]);\n                x=px; y=py;\n            }\n            reverse(res.begin(), res.end());\n            return res;\n        }\n        if (cost > dist[i][j]) continue;\n        for (int d=0; d<4; ++d) {\n            int ni = i+dx[d], nj = j+dy[d];\n            if (!in_grid(ni, nj)) continue;\n            double ecost;\n            if (d==0) ecost = vert[i-1][j].est; // up: between (i-1,j)-(i,j)\n            if (d==1) ecost = vert[i][j].est;   // down: between (i,j)-(i+1,j)\n            if (d==2) ecost = horiz[i][j-1].est; // left: between (i,j-1)-(i,j)\n            if (d==3) ecost = horiz[i][j].est;   // right: between (i,j)-(i,j+1)\n            if (dist[ni][nj] > dist[i][j] + ecost) {\n                dist[ni][nj] = dist[i][j]+ecost;\n                prev[ni][nj] = {i,j};\n                previdx[ni][nj] = d;\n                pq.emplace(dist[ni][nj], ni, nj, p + dir_chars[d]);\n            }\n        }\n    }\n    // never reached: should not happen\n    return {};\n}\n\n// Map moves to edges for updating\nvoid update_edges(pair<int,int> s, const vector<char>& path, double total_edge_len) {\n    vector<pair<int,int>> wayp;\n    wayp.push_back(s);\n    int x = s.first, y = s.second;\n    for (char c: path) {\n        if (c=='U') x--;\n        else if (c=='D') x++;\n        else if (c=='L') y--;\n        else if (c=='R') y++;\n        wayp.emplace_back(x,y);\n    }\n    int plen = (int)path.size();\n    if (plen==0) return;\n    double unit = total_edge_len / plen; // naive: assign equally (no better info!)\n    for (int i=0; i<plen; ++i) {\n        int x0 = wayp[i].first, y0 = wayp[i].second;\n        int x1 = wayp[i+1].first, y1 = wayp[i+1].second;\n        // edge direction\n        if (x0==x1 && y0+1==y1) {\n            horiz[x0][y0].add_sample(unit);\n        } else if (x0==x1 && y0-1==y1) {\n            horiz[x0][y1].add_sample(unit);\n        } else if (x0+1==x1 && y0==y1) {\n            vert[x0][y0].add_sample(unit);\n        } else if (x0-1==x1 && y0==y1) {\n            vert[x1][y0].add_sample(unit);\n        } else assert(false);\n    }\n}\n\n// Early in the contest, randomly explore to cover more edges\nvector<char> random_path(pair<int,int> s, pair<int,int> t, mt19937 &rng) {\n    int x = s.first, y = s.second;\n    int tx = t.first, ty = t.second;\n    vector<char> path;\n    int dx_ = tx - x, dy_ = ty - y;\n    vector<char> moves;\n    if (dx_ > 0) moves.insert(moves.end(), dx_, 'D');\n    else moves.insert(moves.end(), -dx_, 'U');\n    if (dy_ > 0) moves.insert(moves.end(), dy_, 'R');\n    else moves.insert(moves.end(), -dy_, 'L');\n    shuffle(moves.begin(), moves.end(), rng); // randomize order\n    // Create actual path via valid movement\n    for(char c : moves) path.push_back(c);\n    return path;\n}\n\n// Readline helpers\nint si, sj, ti, tj;\nvoid fast_scan() { scanf(\"%d%d%d%d\", &si, &sj, &ti, &tj); }\nint fast_int() { int x; scanf(\"%d\", &x); return x; }\n\nint main() {\n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n\n    for (int query=0; query<Q; ++query) {\n        fast_scan();\n        pair<int,int> s = {si, sj}, t = {ti, tj};\n        vector<char> path_chars;\n        if (query < 100) {\n            path_chars = random_path(s, t, rng); // randomize for first 100 queries\n        } else {\n            path_chars = estimate_path(s, t);\n            if (path_chars.size()==0) { // fallback\n                path_chars = random_path(s, t, rng);\n            }\n        }\n        // Output path\n        string out(path_chars.begin(), path_chars.end());\n        printf(\"%s\\n\", out.c_str());\n        fflush(stdout);\n\n        // Input feedback (rounded noisy cost)\n        int feedback = fast_int();\n\n        // Update edge estimates using feedback length\n        update_edges(s, path_chars, feedback);\n\n        // (optional: debug)\n        // if (query%100==99) cerr << \"[[\"<<query<<\"]]\\n\";\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\n// For random numbers\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Returns list of tuples (direction (0=row,1=col), i, shift)\nvector<tuple<int,int,int>> all_positions(int N, int len) {\n    vector<tuple<int,int,int>> positions;\n    for(int dir=0;dir<2;++dir) // 0=row,1=col\n        for(int i=0;i<N;++i)\n            for(int shift=0;shift<N;++shift)\n                positions.emplace_back(dir,i,shift);\n    return positions;\n}\n\n// Try placing s in matrix a at (dir,i,shift)\n// Return if conflict (false if conflict), and collect pos_painted (to mark for this string)\nbool can_place(const vector<string> &a, int N, const string &s,\n               int dir, int i, int shift, vector<pair<int,int>> &pos_painted) {\n    int k = s.size();\n    pos_painted.clear();\n    for(int p=0;p<k;++p){\n        int x = (dir==0)? i : (i+p)%N;\n        int y = (dir==0)? (shift+p)%N : shift;\n        if(a[x][y]=='.' || a[x][y]==s[p]) {\n            pos_painted.emplace_back(x,y);\n        } else {\n            return false;\n        }\n    }\n    return true;\n}\n\n// Place s in matrix a at given places\nvoid do_paint(vector<string> &a, const string &s, const vector<pair<int,int>> &pos_painted, int dir, int i, int shift) {\n    int k = s.size();\n    for(int p=0;p<k;++p){\n        int x = (dir==0)? i : (i+p)%a.size();\n        int y = (dir==0)? (shift+p)%a.size() : shift;\n        a[x][y] = s[p];\n    }\n}\n\n// Checks if s is covered somewhere in matrix a as row/col subsequence (using torus)\nbool is_covered(const vector<string> &a, const string &s) {\n    int N = a.size();\n    int k = s.size();\n    for(int i=0;i<N;++i){\n        for(int shift=0;shift<N;++shift){\n            // Row\n            bool ok=true;\n            for(int p=0;p<k;++p){\n                if(a[i][(shift+p)%N]!=s[p]) { ok=false; break; }\n            }\n            if(ok) return true;\n            // Col\n            ok=true;\n            for(int p=0;p<k;++p){\n                if(a[(i+p)%N][shift]!=s[p]) { ok=false; break; }\n            }\n            if(ok) return true;\n        }\n    }\n    return false;\n}\n\nint main() {\n    ios::sync_with_stdio(0); cin.tie(0);\n    int N, M;\n    cin >> N >> M;\n    vector<string> s(M);\n    for(int i=0;i<M;++i) cin >> s[i];\n\n    vector<string> best_ans;\n    int best_cover = 0;\n\n    // Try several random processings to maximize c\n    int TRIALS = 7; // You can tune this\n    for(int trial=0; trial<TRIALS; ++trial){\n        vector<string> a(N, string(N,'.'));\n        vector<int> idx(M);\n        iota(idx.begin(), idx.end(), 0);\n        shuffle(idx.begin(), idx.end(), rng);\n\n        // Record for each cell the possible frequency of candidates (for later fill)\n        vector<vector<array<int,8>>> freq(N,vector<array<int,8>>(N));\n        for(int t=0;t<M;++t){\n            const string &si = s[t];\n            int k = si.size();\n            for(int dir=0;dir<2;++dir)\n                for(int i=0;i<N;++i)\n                    for(int shift=0;shift<N;++shift){\n                        for(int p=0;p<k;++p) {\n                            int x = (dir==0)? i : (i+p)%N;\n                            int y = (dir==0)? (shift+p)%N : shift;\n                            freq[x][y][si[p]-'A']++;\n                        }\n                    }\n        }\n\n        // Main Greedy: Try to pack as many s[idx[*]] as possible\n        vector<bool> used(M, false);\n        for(int tt=0;tt<M;++tt){\n            int i_s = idx[tt];\n            const string &si = s[i_s];\n            int k = si.size();\n\n            // Find all possible placements without conflict\n            vector<tuple<int,int,int>> possible;\n            vector<pair<int,int>> buf;\n            for(int dir=0;dir<2;++dir)\n                for(int i=0;i<N;++i)\n                    for(int shift=0;shift<N;++shift)\n                        if(can_place(a,N,si,dir,i,shift,buf))\n                            possible.emplace_back(dir,i,shift);\n\n            if(possible.empty()) continue;\n\n            // Pick randomly (could pick \"minimally fills new cells\", or \"max freq\", but use random for now)\n            auto [dir,i,shift] = possible[rng()%possible.size()];\n            // Actually place it\n            do_paint(a, si, buf, dir, i, shift);\n            used[i_s] = true;\n        }\n        // Final fill-in: Remaining '.' fill with most frequent guess (from freq), or 'A'\n        for(int i=0;i<N;++i) for(int j=0;j<N;++j) if(a[i][j]=='.') {\n            int maxv = 0; char c='A';\n            for(int t=0;t<8;++t) if(freq[i][j][t]>maxv) {\n                maxv = freq[i][j][t];\n                c = 'A' + t;\n            }\n            a[i][j] = c;\n        }\n\n        // Now count how many s are matched as subsequence\n        int cover = 0;\n        for(int i=0;i<M;++i) if(is_covered(a, s[i])) cover++;\n\n        if(cover > best_cover) {\n            best_cover = cover;\n            best_ans = a;\n            if(cover == M) break; // optimal (no point in more tries)\n        }\n    }\n    // Output final matrix\n    for(int i=0;i<N;++i)\n        cout << best_ans[i] << '\\n';\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int DX[4] = {-1, +1, 0, 0};\nconstexpr int DY[4] = {0, 0, -1, +1};\nconstexpr char DIRS[4] = {'U', 'D', 'L', 'R'};\n\nusing Pos = pair<int, int>;\n\n// Fast bitset for up to 2500 cells (max roads)\nstruct FastBitSet {\n    vector<uint64_t> bs;\n    int size; // number of bits\n\n    FastBitSet(int n) : size(n), bs((n+63)>>6) {}\n\n    void set(int k) { bs[k>>6] |= (1ULL<<(k&63)); }\n    void reset(int k) { bs[k>>6] &= ~(1ULL<<(k&63)); }\n    bool test(int k) const { return (bs[k>>6]>>(k&63))&1; }\n    void operator|=(const FastBitSet& rhs) {\n        for (int i=0; i<bs.size(); ++i) bs[i] |= rhs.bs[i];\n    }\n    FastBitSet operator|(const FastBitSet& rhs) const {\n        FastBitSet ret(*this);\n        ret |= rhs;\n        return ret;\n    }\n    int count() const {\n        int res = 0;\n        for (auto x: bs) res += __builtin_popcountll(x);\n        return res;\n    }\n    bool all() const {\n        int last = size & 63;\n        for (int i=0; i+1 < bs.size(); ++i) if (bs[i] != ~0ULL) return false;\n        if (last == 0) return bs.back() == ~0ULL;\n        else return (bs.back() & ((1ULL<<last)-1)) == ((1ULL<<last)-1);\n    }\n    int find_first_zero() const {\n        for (int i=0; i<bs.size(); ++i) {\n            if (~bs[i]) {\n                int b = __builtin_ctzll(~bs[i]);\n                int idx = (i<<6)+b;\n                return idx < size ? idx : -1;\n            }\n        }\n        return -1;\n    }\n    vector<int> to_vector() const {\n        vector<int> res;\n        for (int i=0; i<size; ++i) if (test(i)) res.push_back(i);\n        return res;\n    }\n};\n\n// Helper for mapping positions to road cell indices\nstruct RoadMapper {\n    int N;\n    vector<vector<int>> idx_of; // -1 if not a road\n\n    vector<Pos> pos_of; // pos_of[road_id] = (i,j)\n    int num_roads;\n\n    RoadMapper(int N_, const vector<string>& grid) : N(N_) {\n        idx_of.assign(N, vector<int>(N, -1));\n        pos_of.reserve(N*N);\n        int id = 0;\n        for (int i=0;i<N;++i)for(int j=0;j<N;++j){\n            if ('5' <= grid[i][j] && grid[i][j] <= '9') {\n                idx_of[i][j] = id++;\n                pos_of.push_back({i,j});\n            }\n        }\n        num_roads = id;\n    }\n    int id(int i, int j) const { return idx_of[i][j]; }\n    const Pos& pos(int id) const { return pos_of[id]; }\n};\n\nstruct Visibility {\n    int N, num_roads;\n    const vector<string> &grid;\n    RoadMapper& mapper;\n    vector<FastBitSet> visible_from; // [road_id] masks of visible road cells\n\n    Visibility(int N_, RoadMapper& mapper_, const vector<string>& grid_)\n        : N(N_), grid(grid_), mapper(mapper_), num_roads(mapper.num_roads),\n          visible_from(num_roads, FastBitSet(mapper.num_roads)) {\n\n        vector<vector<int>>& idx_of = mapper.idx_of;\n        // For every road cell, precompute visible cells in 4 directions\n        for (int k = 0; k < num_roads; ++k) {\n            auto [i,j] = mapper.pos_of[k];\n            // Row L\n            for (int jj = j; jj >= 0; --jj) {\n                if (idx_of[i][jj] == -1) break;\n                visible_from[k].set(idx_of[i][jj]);\n            }\n            // Row R\n            for (int jj = j+1; jj < N; ++jj) {\n                if (idx_of[i][jj] == -1) break;\n                visible_from[k].set(idx_of[i][jj]);\n            }\n            // Col U\n            for (int ii = i; ii >= 0; --ii) {\n                if (idx_of[ii][j] == -1) break;\n                visible_from[k].set(idx_of[ii][j]);\n            }\n            // Col D\n            for (int ii = i+1; ii < N; ++ii) {\n                if (idx_of[ii][j] == -1) break;\n                visible_from[k].set(idx_of[ii][j]);\n            }\n            // Self\n            visible_from[k].set(k);\n        }\n    }\n};\n\n// BFS for shortest path cost/moves on graph; returns path of cells\nvector<Pos> bfs_shortest_path(\n    const vector<string>& grid, int N,\n    Pos start, Pos end)\n{\n    if (start == end) return {start};\n    vector<vector<Pos>> prev(N, vector<Pos>(N, {-1,-1}));\n    queue<Pos> que;\n    que.push(start);\n    prev[start.first][start.second] = start;\n    while (!que.empty()) {\n        auto [i,j] = que.front(); que.pop();\n        for (int d=0;d<4;++d) {\n            int ni = i + DX[d];\n            int nj = j + DY[d];\n            if (ni<0||nj<0||ni>=N||nj>=N) continue;\n            if (!(grid[ni][nj]>='5' && grid[ni][nj]<='9')) continue;\n            if (prev[ni][nj].first!=-1) continue;\n            prev[ni][nj] = {i,j};\n            if (make_pair(ni,nj) == end) {\n                // Reconstruct\n                vector<Pos> path;\n                Pos cur = end;\n                while (cur != start) {\n                    path.push_back(cur);\n                    cur = prev[cur.first][cur.second];\n                }\n                path.push_back(start);\n                reverse(path.begin(), path.end());\n                return path;\n            }\n            que.push({ni,nj});\n        }\n    }\n    // unreachable!\n    return {};\n}\n\n// For move path between adjacent cells\nchar move_dir(const Pos& from, const Pos& to) {\n    int di = to.first-from.first, dj = to.second-from.second;\n    for (int d=0;d<4;++d) if (di==DX[d]&&dj==DY[d]) return DIRS[d];\n    assert(false);\n    return '?';\n}\n\n// Greedy set cover: At each step, move to position that covers most yet-uncovered cells per cost (or per step)\nvector<Pos> greedy_scan_path(\n    const vector<string>& grid, int N,\n    RoadMapper& mapper, const Visibility& vis, \n    int si, int sj)\n{\n    int num_roads = mapper.num_roads;\n    int cur_id = mapper.id(si,sj);\n    FastBitSet covered(num_roads);\n    covered |= vis.visible_from[cur_id];\n\n    vector<bool> scanned(num_roads);\n    vector<Pos> path = {mapper.pos_of[cur_id]};\n    int cur_i = si, cur_j = sj;\n\n    // List of scan points to visit\n    vector<int> scan_points = {cur_id};\n\n    while (!covered.all()) {\n        // Candidates: all road cells\n        int best_id = -1, best_gain = -1;\n        int best_dist = 1e9; // among same gain, prefer closer\n        // For this quick initial baseline, just consider direct neighbors (fast enough)\n        for (int k = 0; k < num_roads; ++k) {\n            if (k == cur_id) continue;\n            if (scanned[k]) continue;\n            // Only consider cells still providing new coverage\n            int gain = 0;\n            auto& vis_set = vis.visible_from[k];\n            for (int x=0;x<num_roads;++x) {\n                if (vis_set.test(x) && !covered.test(x)) gain++;\n            }\n            if (gain <= 0) continue;\n            // Compute shortest path len to (could cache x BFSes, but ok for small N)\n            auto p1 = mapper.pos_of[cur_id], p2 = mapper.pos_of[k];\n            int dist = abs(p1.first-p2.first)+abs(p1.second-p2.second); // Manhattan approx\n            if (gain > best_gain || (gain == best_gain && dist < best_dist)) {\n                best_gain = gain, best_id = k, best_dist = dist;\n            }\n        }\n        if (best_id == -1) break; // No progress\n\n        // Path to best_id\n        auto from = mapper.pos_of[cur_id];\n        auto to = mapper.pos_of[best_id];\n        vector<Pos> segment = bfs_shortest_path(grid, N, from, to);\n        for (int idx=1; idx<segment.size(); ++idx) {\n            path.push_back(segment[idx]);\n        }\n\n        cur_id = best_id;\n        covered |= vis.visible_from[cur_id];\n        scanned[cur_id] = true;\n        scan_points.push_back(cur_id);\n    }\n\n    // Path home to start\n    if (cur_id != mapper.id(si,sj)) {\n        auto from = mapper.pos_of[cur_id], to = make_pair(si,sj);\n        vector<Pos> segment = bfs_shortest_path(grid, N, from, to);\n        for (int idx=1; idx<segment.size(); ++idx) {\n            path.push_back(segment[idx]);\n        }\n    }\n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N, si, sj;\n    cin >> N >> si >> sj;\n    vector<string> grid(N);\n    for (int i=0;i<N;++i) cin >> grid[i];\n\n    RoadMapper mapper(N, grid);\n    Visibility vis(N, mapper, grid);\n\n    vector<Pos> route = greedy_scan_path(grid, N, mapper, vis, si, sj);\n\n    // Output moves\n    string moves;\n    for (int i=1; i<route.size(); ++i)\n        moves += move_dir(route[i-1], route[i]);\n\n    cout << moves << endl;\n\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int MAX_N = 1000;\nconstexpr int MAX_M = 20;\nconstexpr int MAX_K = 20;\n\nint n, m, k, r;\nvector<vector<int>> d;                // d[i][j]: required skill j for task i\nvector<vector<int>> dependencies;     // dependencies[v] = {u,...} (task v depends on u)\nvector<vector<int>> revdeps;          // revdeps[u] = {v,...} (task v depends on u)\nvector<int> indegree;                 // unresolved dependencies per task\nvector<int> status;                   // 0: unassigned, 1: assigned, 2: done\n\nstruct MemberState {\n    int current_task = -1;\n    int assigned_day = -1;\n};\n\nvector<MemberState> members;\nint current_day = 1;\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// ========== SKILL ESTIMATION ==========\n// For each member: for each skill: track min/max possible s_{j,k}\nstruct SkillBound {\n    // Lower bound (no way skill less than this), upper bound (unlikely skill exceeds this)\n    vector<double> min_sk, max_sk;\n    int observations = 0; // number of finished tasks\n    SkillBound(int K = 0) : min_sk(K, 0), max_sk(K, 100) {}\n};\n\nvector<SkillBound> skill_bounds; // per member\n\n// Support for exploration assignment; per member, set of skill dimensions/axes already tested\nvector<set<int>> explored_dims;\n\n// Returns the max requirement (and dimension) for a task\npair<int,int> task_peak_dim(const vector<int>& t) {\n    int mx = -1, idx = -1;\n    for (int i = 0; i < t.size(); ++i)\n        if (t[i] > mx) { mx = t[i]; idx = i; }\n    return make_pair(mx, idx);\n}\n\nvoid read_input() {\n    cin >> n >> m >> k >> r;\n    d.resize(n, vector<int>(k));\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < k; ++j)\n            cin >> d[i][j];\n    dependencies.resize(n);\n    revdeps.resize(n);\n    indegree.assign(n, 0);\n    for (int i = 0; i < r; ++i) {\n        int u, v;\n        cin >> u >> v;\n        --u; --v;\n        dependencies[v].push_back(u);\n        revdeps[u].push_back(v);\n        indegree[v]++;\n    }\n}\n\nvoid initialize() {\n    status.assign(n, 0);\n    members.assign(m, MemberState());\n    skill_bounds.assign(m, SkillBound(k));\n    explored_dims.assign(m, set<int>());\n}\n\n// Fast ready-tasks update: tasks with indegree==0 and not assigned/done\nset<int> ready_tasks;\npriority_queue<pair<int,int>> ready_critical; // (outdeg, taskid) (max heap)\n\nvoid refresh_ready_tasks() {\n    // In practice only update toward 0 (never add tasks that become non-zero)\n    for (int i = 0; i < n; ++i) {\n        if (indegree[i] == 0 && status[i] == 0)\n            ready_tasks.insert(i);\n    }\n    // Optionally, build the critical task heap:\n    for (int x : ready_tasks) {\n        ready_critical.push({(int)revdeps[x].size(), x});\n    }\n}\n\n// --- SKILL ESTIMATION ---\nvoid update_skill_bounds(int member, int task, int observed_days) {\n    // If days==1, w_{i,j}==0 possible if r_i positive, skills cover requirement, so lower bound is at least requirement\n    // If days>1, w_{i,j}=obs_days - r_i \u2265 1 (since r_i in [-3,3]), so skills can't cover some dimensions\n\n    // We can't know which skill dimension is lacking\n    // But we do know sum_k max(0, d_{i,k} - s_{j,k}) \u2208 [obs_days - 3, obs_days + 3]\n    int minw = max(0, observed_days - 3); // min possible w\n    int maxw = observed_days + 3; // max possible w\n    // if minw==0, it's possible s_j\u2265d_i (in all dims), so min_sk = max(min_sk, d_{i,?});\n    // For now: if observed_days==1, bump up lower bound of all skills to d_i, since it's possible s\u2265d\n    if (observed_days == 1) {\n        for (int kk=0;kk<k;++kk)\n            skill_bounds[member].min_sk[kk] = max(skill_bounds[member].min_sk[kk], (double)d[task][kk]);\n    }\n    // (Advanced: If observed_days>=4, it's likely that at least one skill is short by (minw/k), but we skip for now for simplicity)\n    skill_bounds[member].observations++;\n}\n\n// Estimates member's skill vector as the max of the known lower bound and mid-point for unprobed dims\nvector<double> estimate_skills(int member) {\n    // For each skill dimension: use current lower bound as est (or average)\n    vector<double> e(k);\n    for (int kk=0;kk<k;++kk)\n        e[kk] = skill_bounds[member].min_sk[kk]; // always feasible, possibly sub-optimal\n    return e;\n}\n\n// ---------- TASK ASSIGNMENT STRATEGY ----------\n\n// 1. For each member: if they have not been assigned to a task with a particular skill dimension peaking, try to assign such a task to them for exploration.\n// 2. Once each has been probed on different dimensions, switch to greedily picking min expected task time.\n\nvoid assign_tasks_today(vector<pair<int,int>>& assignments) {\n    vector<int> idle_members;\n    for (int j = 0; j < m; ++j)\n        if (members[j].current_task == -1)\n            idle_members.push_back(j);\n\n    set<int> used_tasks;\n\n    // 1. EXPLORATION: Give each idle member a task whose peak dimension hasn't been explored for them\n    for (int j : idle_members) {\n        if (explored_dims[j].size() < k) {\n            // pick a ready task with skill-peak in an unexplored dimension\n            vector<pair<int, int>> candidates;\n            for (int t : ready_tasks)\n                if (!used_tasks.count(t)) {\n                    int dim = task_peak_dim(d[t]).second;\n                    if (explored_dims[j].count(dim) == 0)\n                        candidates.emplace_back(dim, t);\n                }\n            if (!candidates.empty()) {\n                // Pick randomly from among them to avoid bias\n                int idx = rng() % candidates.size();\n                int dim = candidates[idx].first;\n                int tsk = candidates[idx].second;\n                assignments.push_back({j, tsk});\n                explored_dims[j].insert(dim);\n                status[tsk] = 1;\n                members[j].current_task = tsk;\n                members[j].assigned_day = current_day;\n                used_tasks.insert(tsk);\n            }\n        }\n    }\n\n    // 2. EXPLOITATION: For remaining idle members, pick minimal expected task time using estimated skills\n    for (int j : idle_members) {\n        if (members[j].current_task != -1) continue; // already assigned in above phase\n        int best_task = -1;\n        double best_time = 1e9;\n        int best_outdeg = -1;\n\n        vector<double> estsk = estimate_skills(j);\n        for (int t : ready_tasks)\n        if (!used_tasks.count(t)) {\n            // Estimate task time\n            double w = 0;\n            for (int kk=0;kk<k;++kk)\n                if (d[t][kk] > estsk[kk])\n                    w += (d[t][kk] - estsk[kk]);\n            double expected = max(w, 1.0);\n            // Tie-break: outdegree (dependents)\n            int outdeg = revdeps[t].size();\n            if (expected < best_time || (expected == best_time && outdeg > best_outdeg)) {\n                best_time = expected;\n                best_outdeg = outdeg;\n                best_task = t;\n            }\n        }\n        if (best_task != -1) {\n            assignments.push_back({j, best_task});\n            status[best_task] = 1;\n            members[j].current_task = best_task;\n            members[j].assigned_day = current_day;\n            used_tasks.insert(best_task);\n        }\n    }\n}\n\n// Feed-back after a day: update ready tasks, skill bounds, and members.\nvoid process_feedback(const vector<int>& finished_members) {\n    for (int member : finished_members) {\n        auto& ms = members[member];\n        int tsk = ms.current_task;\n        int assigned = ms.assigned_day;\n        int obs_days = current_day - assigned + 1;\n        status[tsk] = 2;\n        ms.current_task = -1;\n        ms.assigned_day = -1;\n        // update skill estimation:\n        update_skill_bounds(member, tsk, obs_days);\n        // open dependent tasks:\n        for (int dv : revdeps[tsk]) {\n            indegree[dv]--;\n            if (indegree[dv] == 0 && status[dv] == 0)\n                ready_tasks.insert(dv);\n        }\n    }\n}\n\nvoid print_assignments(const vector<pair<int, int>>& assignments) {\n    cout << assignments.size();\n    for (auto [member, task] : assignments)\n        cout << ' ' << (member + 1) << ' ' << (task + 1);\n    cout << '\\n';\n    cout.flush();\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    read_input();\n    initialize();\n\n    // Initial ready tasks\n    for (int i = 0; i < n; ++i)\n        if (indegree[i] == 0)\n            ready_tasks.insert(i);\n\n    while (true) {\n        vector<pair<int, int>> assignments;\n        assign_tasks_today(assignments);\n        // Remove assigned from ready_tasks set, assign\n        for(auto& p: assignments) ready_tasks.erase(p.second);\n\n        print_assignments(assignments);\n\n        // Input feedback\n        string line;\n        while (true) {\n            getline(cin, line);\n            if (cin.eof()) exit(0);\n            if (!line.empty()) break;\n        }\n        if (line == \"-1\") break;\n        istringstream iss(line);\n        int cnt; iss >> cnt;\n        if (cnt == -1) break;\n        vector<int> finished;\n        for (int i = 0; i < cnt; ++i) {\n            int x; iss >> x;\n            finished.push_back(x-1);\n        }\n        process_feedback(finished);\n        current_day++;\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\nmt19937 rng(42);\n\nstruct Order {\n    int id;\n    int ax, ay;\n    int cx, cy;\n    int score;\n};\n\nint manh(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n// K-means++ style init\nvector<pair<int,int>> kmeans_init(const vector<pair<int,int>>& pts, int K) {\n    int N = pts.size();\n    vector<pair<int,int>> centers;\n    centers.push_back(pts[rng()%N]);\n    vector<int> dist(N, 1e9);\n    for (int k = 1; k < K; ++k) {\n        int S = 0;\n        for (int i = 0; i < N; ++i) {\n            int d = manh(pts[i].first, pts[i].second, centers.back().first, centers.back().second);\n            if(d < dist[i]) dist[i]=d;\n            S += dist[i];\n        }\n        if(S==0) break;\n        int t = rng()%S, acc=0,i=0;\n        for(;i<N&&acc<t;++i) acc+=dist[i];\n        centers.push_back(pts[(i==N)?N-1:i]);\n    }\n    return centers;\n}\n\nvoid kmeans(const vector<pair<int,int>>& pts, int K, vector<int>& belong, vector<pair<int,int>>& centers, int iters=5) {\n    int N = pts.size();\n    belong.resize(N);\n    // Initialize\n    centers = kmeans_init(pts,K);\n\n    for (int it = 0; it < iters; ++it) {\n        // Assign\n        for (int i = 0; i < N; ++i) {\n            int best = 0, best_d = manh(pts[i].first, pts[i].second, centers[0].first, centers[0].second);\n            for (int k = 1; k < K; ++k) {\n                int d = manh(pts[i].first, pts[i].second, centers[k].first, centers[k].second);\n                if (d < best_d) best_d = d, best = k;\n            }\n            belong[i] = best;\n        }\n        // Update centers\n        vector<int64_t> sx(K, 0), sy(K, 0), sn(K, 0);\n        for (int i = 0; i < N; ++i) {\n            sx[belong[i]] += pts[i].first;\n            sy[belong[i]] += pts[i].second;\n            sn[belong[i]] += 1;\n        }\n        for (int k = 0; k < K; ++k) {\n            if (sn[k]) centers[k] = {int(sx[k]/sn[k]), int(sy[k]/sn[k])};\n        }\n    }\n}\n\nstruct Node {\n    int x, y;\n    int ord_idx;\n    bool is_pickup;\n};\n\nstruct Result {\n    vector<int> sel_ids;\n    vector<pair<int,int>> route;\n    int route_cost;\n};\n\nResult get_route(const vector<Order>& sel_orders, int variant=0) {\n    // Build 100 nodes: pickups [0-49], then deliveries [50-99]\n    vector<Node> nodes;\n    for (int i = 0; i < 50; ++i)\n        nodes.push_back({sel_orders[i].ax, sel_orders[i].ay, i, true});\n    for (int i = 0; i < 50; ++i)\n        nodes.push_back({sel_orders[i].cx, sel_orders[i].cy, i, false});\n    int N = nodes.size();\n\n    vector<bool> visited(N, false);\n    vector<bool> pickup_done(50, false);\n\n    vector<pair<int,int>> route = {{400,400}};\n    int cur_x = 400, cur_y = 400;\n    for (int step = 0; step < N; ++step) {\n        vector<int> avail;\n        for (int i = 0; i < N; ++i) if (!visited[i]) {\n            if (!nodes[i].is_pickup && !pickup_done[nodes[i].ord_idx]) continue;\n            avail.push_back(i);\n        }\n        int best = -1, best_dist = 1e9;\n        // Mix some randomness for similar distance\n        vector<int> candidates;\n        for (int i : avail) {\n            int dist = manh(cur_x, cur_y, nodes[i].x, nodes[i].y);\n            if (dist < best_dist) {\n                best_dist = dist;\n                candidates.clear();\n                candidates.push_back(i);\n            }\n            else if (dist == best_dist) candidates.push_back(i);\n        }\n        if(!candidates.empty()) {\n            if(variant==0)\n                best = candidates[0]; // deterministic\n            else\n                best = candidates[rng()%candidates.size()];\n        } else {\n            best = avail[rng()%avail.size()];\n        }\n        visited[best]=true;\n        if(nodes[best].is_pickup) pickup_done[nodes[best].ord_idx]=true;\n        cur_x = nodes[best].x; cur_y = nodes[best].y;\n        route.emplace_back(cur_x, cur_y);\n    }\n    if(cur_x!=400||cur_y!=400) route.emplace_back(400,400);\n    // Compute cost\n    int cost=0;\n    for(int i=1;i<route.size();++i)\n        cost+=manh(route[i-1].first,route[i-1].second,route[i].first,route[i].second);\n\n    vector<int> sel_ids;\n    for(const auto&o:sel_orders)sel_ids.push_back(o.id+1);\n    return {sel_ids,route,cost};\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    vector<Order> orders(1000);\n    for (int i = 0; i < 1000; ++i) {\n        int a, b, c, d;\n        cin >> a >> b >> c >> d;\n        orders[i] = {i, a, b, c, d, 0};\n    }\n    // Score: office->pickup + pickup->del + del->office\n    for (auto& o : orders) {\n        int office = 400;\n        o.score = manh(office,office,o.ax,o.ay)+manh(o.ax,o.ay,o.cx,o.cy)+manh(o.cx,o.cy,office,office);\n    }\n\n    // K-means clustering on pickups (ax,ay)\n    vector<pair<int,int>> pickups;\n    for (auto&o:orders) pickups.emplace_back(o.ax, o.ay);\n\n    int best_cost = INT_MAX;\n    vector<int> best_sel_ids;\n    vector<pair<int,int>> best_route;\n\n    int K=10;\n    vector<int> belong;\n    vector<pair<int,int>> centers;\n    kmeans(pickups, K, belong, centers, 3);\n\n    vector<int> center_order(K);\n    iota(center_order.begin(),center_order.end(),0);\n    // Sort clusters: those closest to office first\n    sort(center_order.begin(),center_order.end(),[&](int i,int j){\n        int di=manh(400,400,centers[i].first,centers[i].second);\n        int dj=manh(400,400,centers[j].first,centers[j].second);\n        return di<dj;\n    });\n\n    // For best few clusters, generate selection, test greedy/randomized runs\n    int CLUSTER_TRY = min(4,K);\n    int RUNS_PER_CLUSTER = 5;\n    for(int cl=0;cl<CLUSTER_TRY;++cl){\n        int cid = center_order[cl];\n        vector<Order> cand;\n        for(int i=0;i<orders.size();++i)if(belong[i]==cid)\n            cand.push_back(orders[i]);\n        // Select top 50 by original score\n        sort(cand.begin(),cand.end(),[](const Order&a,const Order&b){return a.score<b.score;});\n        while(cand.size()<50){\n            // Supplement with nearest from others\n            int bdist=INT_MAX,bidx=-1;\n            for(int j=0;j<orders.size();++j){\n                if(belong[j]!=cid) {\n                    int d=manh(centers[cid].first,centers[cid].second,orders[j].ax,orders[j].ay);\n                    if(d<bdist){bdist=d;bidx=j;}\n                }\n            }\n            if(bidx>=0) cand.push_back(orders[bidx]);\n            else break;\n        }\n        if(cand.size()>50)cand.resize(50);\n        \n        for(int run=0;run<RUNS_PER_CLUSTER;++run){\n            Result res = get_route(cand, run>0?1:0);\n            if(res.route_cost < best_cost){\n                best_cost = res.route_cost;\n                best_sel_ids=res.sel_ids;\n                best_route=res.route;\n            }\n        }\n    }\n\n    // fallback: previous method, original minimal 50\n    sort(orders.begin(), orders.end(), [](const Order& a, const Order& b) {\n        return a.score < b.score;\n    });\n    vector<Order> top50(orders.begin(), orders.begin()+50);\n    Result res = get_route(top50, 1);\n    if(res.route_cost < best_cost){\n        best_cost = res.route_cost;\n        best_sel_ids=res.sel_ids;\n        best_route=res.route;\n    }\n\n    // Output\n    cout << \"50\";\n    for (int i = 0; i < 50; ++i)\n        cout << \" \" << best_sel_ids[i];\n    cout << \"\\n\";\n    cout << best_route.size();\n    for (auto& p : best_route)\n        cout << \" \" << p.first << \" \" << p.second;\n    cout << \"\\n\";\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    vector<int> parent, sz;\n    DSU(int n) : parent(n), sz(n, 1) { iota(parent.begin(), parent.end(), 0); }\n    int find(int x) {\n        while (parent[x] != x) x = parent[x] = parent[parent[x]];\n        return x;\n    }\n    bool unite(int x, int y) {\n        x = find(x); y = find(y);\n        if (x == y) return false;\n        if (sz[x] < sz[y]) swap(x, y);\n        parent[y] = x; sz[x] += sz[y];\n        return true;\n    }\n    bool same(int x, int y) { return find(x) == find(y); }\n};\n\nstruct Edge {\n    int u, v;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 400, M = 1995;\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    vector<Edge> edges(M);\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        cin >> u >> v;\n        edges[i] = {u, v};\n    }\n    DSU dsu(N);\n    int taken = 0;\n    for (int i = 0; i < M; ++i) {\n        int l_i;\n        cin >> l_i;\n        int u = edges[i].u, v = edges[i].v;\n\n        if (!dsu.same(u, v)) {\n            cout << 1 << endl;\n            cout << flush;\n            dsu.unite(u, v);\n            taken++;\n        } else {\n            cout << 0 << endl;\n            cout << flush;\n        }\n    }\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Grid dimensions\nconstexpr int W = 30, H = 30;\nconstexpr int DX[4] = {-1, 1, 0, 0};\nconstexpr int DY[4] = {0, 0, -1, 1};\nconstexpr char MOVES[4] = {'U', 'D', 'L', 'R'};\nconstexpr char WALLS[4] = {'u', 'd', 'l', 'r'};\n\nstruct Pet {\n    int x, y, type;\n};\nstruct Human {\n    int x, y;\n    int dest_x, dest_y; // where he's going!\n    int band_l, band_r;\n};\n\nvector<string> grid(H, string(W, '.')); // .:passable, #:wall, h:human, p:pet\n\n// 0-indexed, returns true if inside grid\ninline bool ins(int x, int y) { return 0 <= x && x < H && 0 <= y && y < W; }\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N; cin >> N;\n    vector<Pet> pets(N);\n    for (int i = 0; i < N; i++) {\n        int x, y, t; cin >> x >> y >> t;\n        --x; --y;\n        pets[i] = {x, y, t};\n        grid[x][y] = 'p'; // mark as pet\n    }\n    int M; cin >> M;\n    vector<Human> humans(M);\n    vector<pair<int,int>> hpos(M);\n    vector<vector<int>> human_grid(H, vector<int>(W, 0)); // count of humans\n    for (int i = 0; i < M; i++) {\n        int x, y; cin >> x >> y;\n        --x; --y;\n        humans[i].x = x;\n        humans[i].y = y;\n        hpos[i] = {x, y};\n        grid[x][y] = 'h';\n        human_grid[x][y]++;\n    }\n\n    // Assign bands (vertical partition)\n    vector<pair<int,int>> band_limits(M);\n    int band_size = W / M;\n    for (int i = 0; i < M; i++) {\n        int l = i * band_size;\n        int r = (i == M-1) ? W-1 : (i+1)*band_size-1;\n        band_limits[i] = {l, r};\n        humans[i].band_l = l;\n        humans[i].band_r = r;\n        humans[i].dest_x = H/2; // central row\n        humans[i].dest_y = (l + r)/2;\n    }\n\n    vector<vector<int>> pet_grid(H, vector<int>(W, 0));\n    for (auto& p : pets) pet_grid[p.x][p.y]++;\n\n    // For each turn\n    int phase_move = 12; // Tuning param: turns spent getting into position\n    for (int turn = 0; turn < 300; ++turn) {\n        string actions(M, '.');\n        // Update grid to remove old h and p marks (we'll re-mark below)\n        for (int i = 0; i < H; ++i)\n            for (int j = 0; j < W; ++j)\n                if (grid[i][j]=='h' || grid[i][j]=='p')\n                    grid[i][j] = '.';\n        fill(&human_grid[0][0], &human_grid[0][0]+H*W, 0);\n        fill(&pet_grid[0][0], &pet_grid[0][0]+H*W, 0);\n        for (int i = 0; i < M; ++i) {\n            grid[humans[i].x][humans[i].y] = 'h';\n            human_grid[humans[i].x][humans[i].y]++;\n        }\n        for (int i = 0; i < N; ++i) {\n            grid[pets[i].x][pets[i].y] = 'p';\n            pet_grid[pets[i].x][pets[i].y]++;\n        }\n\n        // For each human, decide action\n        for (int i = 0; i < M; ++i) {\n            auto& h = humans[i];\n            int cx = h.x, cy = h.y;\n            int xl = h.band_l, xr = h.band_r;\n\n            // PHASE 0: Move to starting pos near center of band in first \"phase_move\" turns\n            if (turn < phase_move) {\n                int destx = h.dest_x, desty = h.dest_y;\n                if (cx < destx)      actions[i] = 'D', h.x++;\n                else if (cx > destx) actions[i] = 'U', h.x--;\n                else if (cy < desty) actions[i] = 'R', h.y++;\n                else if (cy > desty) actions[i] = 'L', h.y--;\n                // else stand\n                continue;\n            }\n\n            // PHASE 1: Build walls on left and right of their region\n            // Try to wall a cell at the edge of their band\n            // Alternate walling at the left and right edge of their band!\n            bool did_wall = false;\n\n            // Let's try right wall first this turn if not at the rightmost column\n            for (int d = 0; d < 4 && !did_wall; ++d) {\n                // Choose priority: right-most, left-most, up, down\n                int dir = d;\n                int tx = cx + DX[dir], ty = cy + DY[dir];\n                // For now, try to build wall on the right-most of our region\n                if (dir == 1 && cy < xr) continue; // D: Not vertical wall, skip\n                if (dir == 0 && cy > xl) continue;\n                if (!ins(tx, ty)) continue;\n                if (grid[tx][ty] == '.' && human_grid[tx][ty]==0 && pet_grid[tx][ty]==0) {\n                    // Check no adjacent pet in 8-neighborhood (stricter than needed: 4-neighborhood is rule!)\n                    bool safe = true;\n                    for (int d2 = 0; d2 < 4; ++d2) {\n                        int nx = tx + DX[d2], ny = ty + DY[d2];\n                        if (ins(nx, ny) && pet_grid[nx][ny]) safe = false;\n                    }\n                    if (safe) {\n                        actions[i] = WALLS[dir];\n                        did_wall = true;\n                    }\n                }\n            }\n            if (did_wall) continue; // Prefer walling\n\n            // Otherwise, do a little patrol: move along boundary if not at an edge\n            if (cy < xl) { actions[i] = 'R'; h.y++; }\n            else if (cy > xr) { actions[i] = 'L'; h.y--; }\n            // else idle\n        }\n\n        cout << actions << '\\n' << flush;\n\n        // INPUT PET MOVES\n        vector<string> pet_moves(N);\n        for (int i = 0; i < N; ++i) {\n            cin >> pet_moves[i];\n        }\n        // Update pet positions\n        for (int i = 0; i < N; ++i) {\n            for (char c : pet_moves[i]) {\n                int dx = 0, dy = 0;\n                if (c == 'U') dx = -1;\n                if (c == 'D') dx = 1;\n                if (c == 'L') dy = -1;\n                if (c == 'R') dy = 1;\n                int nx = pets[i].x + dx, ny = pets[i].y + dy;\n                if (ins(nx, ny)) pets[i].x = nx, pets[i].y = ny;\n            }\n        }\n    }\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Directions: U, D, L, R\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst char DC[] = {'U', 'D', 'L', 'R'};\n\nstruct WallMap {\n    int h[20][19]; // right wall\n    int v[19][20]; // down wall\n    bool can_move(int i, int j, int dir) const {\n        if(dir==0) { // Up\n            if(i==0) return false;\n            return v[i-1][j]==0;\n        }\n        if(dir==1) { // Down\n            if(i==19) return false;\n            return v[i][j]==0;\n        }\n        if(dir==2) { // Left\n            if(j==0) return false;\n            return h[i][j-1]==0;\n        }\n        if(dir==3) { // Right\n            if(j==19) return false;\n            return h[i][j]==0;\n        }\n        return false;\n    }\n};\n\n// Find shortest path\nvector<int> bfs_shortest_path(const WallMap &wm, int si, int sj, int gi, int gj) {\n    vector<vector<int>> dist(20, vector<int>(20, -1));\n    vector<vector<pair<int,int>>> prev(20, vector<pair<int,int>>(20, {-1,-1}));\n    queue<pair<int,int>> q;\n    dist[si][sj] = 0;\n    q.push({si, sj});\n    while(!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int d=0; d<4; ++d) {\n            if(!wm.can_move(i, j, d)) continue;\n            int ni = i + di[d], nj = j + dj[d];\n            if(dist[ni][nj] == -1) {\n                dist[ni][nj] = dist[i][j] + 1;\n                prev[ni][nj] = {i, j};\n                q.push({ni, nj});\n            }\n        }\n    }\n    vector<int> path;\n    int ci = gi, cj = gj;\n    if (dist[ci][cj] == -1) return {};\n    while (!(ci == si && cj == sj)) {\n        auto [pi, pj] = prev[ci][cj];\n        for (int d=0; d<4; ++d) if(pi+di[d]==ci && pj+dj[d]==cj && wm.can_move(pi, pj, d)) {\n            path.push_back(d);\n            break;\n        }\n        tie(ci, cj) = make_pair(pi, pj);\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n// Generate path: repeat each move k times, total limit\nstring path_repeat_each(const vector<int>& path, int k, int total_limit) {\n    string ret;\n    for(int d: path) for(int rpt=0;rpt<k;++rpt) {\n        if((int)ret.size()<total_limit) ret+=DC[d];\n    }\n    // If space left, fill again with same pattern\n    while((int)ret.size() + (int)path.size()*k <= total_limit) {\n        for(int d: path) for(int rpt=0;rpt<k;++rpt) {\n            if((int)ret.size()<total_limit) ret+=DC[d];\n        }\n    }\n    return ret;\n}\n// Generate path: repeat the whole shortest path to fill n moves\nstring path_repeat_full(const vector<int>& path, int total_limit) {\n    string ret;\n    while((int)ret.size() + (int)path.size() <= total_limit) {\n        for(int d: path) {\n            if((int)ret.size()<total_limit) ret += DC[d];\n        }\n    }\n    // If not filling, pad remaining with anything (e.g., last move)\n    while((int)ret.size()<total_limit && !path.empty()) {\n        ret += DC[path.back()];\n    }\n    return ret;\n}\n\n// Simulate the expected S over many runs for a move string\ndouble simulate(const WallMap& wm, int si, int sj, int gi, int gj, double p, const string& route, int runs=2000) {\n    mt19937_64 rng(7171717); // fixed seed for reproducibility\n    uniform_real_distribution<> rd(0, 1);\n    double sum = 0;\n    for(int it=0;it<runs;++it) {\n        int i = si, j = sj, t=0;\n        bool reached = false;\n        for(t=1; t<=(int)route.size(); ++t) {\n            if(i==gi && j==gj) {reached=true; break;}\n            double coin = rd(rng);\n            if(coin < p) {\n                // Forget: do nothing, stay at (i,j)\n            } else {\n                int d = -1;\n                for(int k=0;k<4;++k) if(route[t-1]==DC[k]){d=k;break;}\n                if(d==-1) continue; // invalid char\n                if(wm.can_move(i,j,d)) {\n                    i += di[d], j += dj[d];\n                }\n                // else blocked by wall, stay in place\n            }\n            if(i==gi && j==gj) {reached=true; break;}\n        }\n        if(i==gi && j==gj) {reached=true;}\n        if(reached) sum += (401 - t + (i==gi && j==gj ? 0 : 1));\n        // We use (401-t), but t increments at least once each loop, so this matches AtCoder's convention.\n        // Reached within route.size()=> good, else fail, S=0.\n    }\n    return sum / runs;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n\n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n    WallMap wm;\n    for (int i=0;i<20;++i) for (int j=0;j<19;++j) {\n        char c; cin >> c;\n        wm.h[i][j] = c-'0';\n    }\n    for (int i=0;i<19;++i) for (int j=0;j<20;++j) {\n        char c; cin >> c;\n        wm.v[i][j] = c-'0';\n    }\n\n    auto spath = bfs_shortest_path(wm, si, sj, ti, tj);\n\n    vector<pair<double, string>> candidates; // {expected S, plan}\n    int route_limit = 200;\n\n    // Make several strategies!\n    // 1. Repeat full shortest path to fill 200\n    string c_full = path_repeat_full(spath, route_limit);\n    double s_full = simulate(wm, si, sj, ti, tj, p, c_full, 1000);\n    candidates.emplace_back(s_full, c_full);\n\n    if (spath.size() <= 95) {\n        // 2. Repeat each move twice\n        string c_rep2 = path_repeat_each(spath, 2, route_limit);\n        double s_rep2 = simulate(wm, si, sj, ti, tj, p, c_rep2, 1000);\n        candidates.emplace_back(s_rep2, c_rep2);\n    }\n\n    if (spath.size() <= 66) {\n        // 3. Repeat each move three times\n        string c_rep3 = path_repeat_each(spath,3,route_limit);\n        double s_rep3 = simulate(wm, si, sj, ti, tj, p, c_rep3, 1000);\n        candidates.emplace_back(s_rep3, c_rep3);\n    }\n\n    // Pick the best!\n    auto [_, bestroute] = *max_element(candidates.begin(), candidates.end());\n\n    cout << bestroute << endl;\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Grid size\nconstexpr int N = 30;\n// Directions: left, up, right, down\nconst int di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n// To-table (from problem statement)\nconst int to[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1},\n};\n\n// Return tile type after r 90deg CCW rotations\nint realType(int t, int r) {\n    if (t <= 3) return (t + r) % 4;\n    else if (t == 4) return r % 2 == 0 ? 4 : 5;\n    else if (t == 5) return r % 2 == 0 ? 5 : 4;\n    else if (t == 6) return r % 2 == 0 ? 6 : 7;\n    else /* t == 7 */ return r % 2 == 0 ? 7 : 6;\n}\n\n// Loop extraction\nvector<int> get_loops(const vector<vector<int>>& tile_types, const vector<vector<int>>& rotations) {\n    int st[N][N];\n    for (int i = 0; i < N; i++)\n    for (int j = 0; j < N; j++)\n        st[i][j] = realType(tile_types[i][j], rotations[i][j]);\n    bool visited[N][N][4] = {};\n    vector<int> loop_lengths;\n\n    for (int i = 0; i < N; i++)\n    for (int j = 0; j < N; j++)\n    for (int d = 0; d < 4; d++) {\n        if (visited[i][j][d]) continue;\n        int ci = i, cj = j, cd = d, len = 0;\n        while (true) {\n            if (visited[ci][cj][cd]) break;\n            visited[ci][cj][cd] = true;\n            int nd = to[st[ci][cj]][cd];\n            if (nd == -1) break;\n            int ni = ci + di[nd], nj = cj + dj[nd];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) break;\n            cd = (nd + 2) % 4;\n            ci = ni;\n            cj = nj;\n            len++;\n            if (ci == i && cj == j && cd == d) {\n                loop_lengths.push_back(len);\n                break;\n            }\n        }\n    }\n    sort(loop_lengths.rbegin(), loop_lengths.rend());\n    return loop_lengths;\n}\n\n// Forcing an edge loop (for given [L, R) x [T, B)) rectangular border, returns success\nbool force_rect_border_loop(int L, int R, int T, int B,\n        const vector<vector<int>>& type,\n        vector<vector<int>>& rot) {\n    // For each border pos, find a rotation so that (for all edges) border connections are open\n    vector<pair<int,int>> path;\n    if (R-L < 2 || B-T < 2) return false; // Too small\n    // Go clockwise: topleft right, topright down, botright left, botleft up\n    for (int j = L; j < R-1; ++j) path.emplace_back(T, j);      // Top row left\u2192right\n    for (int i = T; i < B-1; ++i) path.emplace_back(i, R-1);    // Right col top\u2192down\n    for (int j = R-1; j > L; --j) path.emplace_back(B-1, j);    // Bottom row right\u2192left\n    for (int i = B-1; i > T; --i) path.emplace_back(i, L);      // Left col bottom\u2192up\n\n    int pathlen = path.size();\n    for (int pos = 0; pos < pathlen; ++pos) {\n        auto [i,j] = path[pos];\n        // Direction INTO this tile (from previous in path)\n        auto [pi, pj] = path[(pos-1+pathlen)%pathlen];\n        int into_dir = -1;\n        if (pi==i-1 && pj==j) into_dir=1;    // from up\n        else if (pi==i+1 && pj==j) into_dir=3; // from down\n        else if (pi==i && pj==j-1) into_dir=0; // from left\n        else if (pi==i && pj==j+1) into_dir=2; // from right\n\n        // Direction OUT to next tile\n        auto [ni, nj] = path[(pos+1)%pathlen];\n        int out_dir = -1;\n        if (ni==i-1 && nj==j) out_dir=1;\n        else if (ni==i+1 && nj==j) out_dir=3;\n        else if (ni==i && nj==j-1) out_dir=0;\n        else if (ni==i && nj==j+1) out_dir=2;\n\n        // Try all rotations; pick one where both 'into_dir' and 'out_dir' are supported and connected\n        int best_rot = -1;\n        for (int r=0; r<4; ++r) {\n            int nt = realType(type[i][j], r);\n            // # Must accept 'into_dir', must have output at from into_dir, and that output = out_dir\n            int t_out = to[nt][into_dir];\n            if (t_out == out_dir) {\n                best_rot = r; break;\n            }\n        }\n        if (best_rot == -1) {\n            // Can't make perfect; try a partial connection for at least one of the directions\n            for (int r=0; r<4; ++r) {\n                int nt = realType(type[i][j], r);\n                if (to[nt][into_dir] != -1 || to[nt][out_dir] != -1) {\n                    best_rot = r; break;\n                }\n            }\n        }\n        if (best_rot == -1) best_rot = 0; // fallback\n        rot[i][j] = best_rot;\n    }\n    return true;\n}\n\n// Try to form largest border loop, and optionally, an inner rectangle loop.\nvoid force_double_borders(const vector<vector<int>>& type, vector<vector<int>>& rot) {\n    // Outer border: [0,N) \u00d7 [0,N)\n    force_rect_border_loop(0, N, 0, N, type, rot);\n\n    // Try (optionally) an inner border, largest possible\n    for (int border = 2; border <= N/2; ++border) {\n        // Border width 1, so rectangle from [border, N-border) \u00d7 [border, N-border)\n        if (!force_rect_border_loop(border, N-border, border, N-border, type, rot))\n            break;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<vector<int>> type(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        string s; cin >> s;\n        for (int j = 0; j < N; j++)\n            type[i][j] = s[j] - '0';\n    }\n\n    // Default: all 0\n    vector<vector<int>> rot(N, vector<int>(N, 0));\n\n    // Step 1: Force outer border and a few inner borders loops.\n    force_double_borders(type, rot);\n\n    // (Optionally: for inner tiles, randomize or local greedy improve! Could be added.)\n\n    // Compute loops\n    auto lengths = get_loops(type, rot);\n    int score = 0;\n    if (lengths.size() >= 2) score = lengths[0] * lengths[1];\n\n    cerr << \"Top loops: \";\n    for (int i = 0; i < min(5, int(lengths.size())); ++i) cerr << lengths[i] << \" \";\n    cerr << \"Score = \" << score << endl;\n\n    // Output 900 digits\n    string out;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            out.push_back('0' + rot[i][j]);\n    cout << out << endl;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nusing pii = pair<int,int>;\n\nchrono::high_resolution_clock::time_point time_start;\ndouble elapsed_sec() {\n    auto t = chrono::high_resolution_clock::now();\n    return chrono::duration<double>(t - time_start).count();\n}\n\n// Directions: UDLR\nconst int dr[] = {-1, 1, 0, 0};\nconst int dc[] = {0, 0, -1, 1};\nconst char dir_char[] = {'U','D','L','R'};\nconst int opp_dir[] = {1,0,3,2};\nconst int bit[] = {1<<1,1<<3,1<<0,1<<2}; // up,down,left,right\n\nstruct Board {\n    int N;\n    vector<vector<int>> grid;\n    pii empty; // (r,c) position of the empty cell\n\n    Board(int N_): N(N_), grid(N, vector<int>(N)) {}\n    Board(const Board &o): N(o.N), grid(o.grid), empty(o.empty) {}\n\n    void read_input() {\n        for(int i=0; i<N; ++i) {\n            string s; cin >> s;\n            for(int j=0; j<N; ++j) {\n                char ch = s[j];\n                if(ch=='0') {\n                    grid[i][j]=0;\n                    empty = {i,j};\n                } else if(isdigit(ch)) {\n                    grid[i][j] = ch-'0';\n                } else {\n                    grid[i][j] = ch-'a'+10;\n                }\n            }\n        }\n    }\n\n    // Can we move in dir d (U/D/L/R)?\n    bool can_move(int d) const {\n        int er = empty.first, ec = empty.second;\n        int nr = er + dr[d], nc = ec + dc[d];\n        return nr>=0 && nr<N && nc>=0 && nc<N;\n    }\n\n    // Do the move in dir d. Assumes move is legal.\n    void do_move(int d) {\n        int er = empty.first, ec = empty.second;\n        int nr = er + dr[d], nc = ec + dc[d];\n        swap(grid[er][ec], grid[nr][nc]);\n        empty = {nr, nc};\n    }\n\n    // For performance, do undo_move doesn't need to be tracked if not required yet.\n};\n\nstruct DSU {\n    vector<int> par, siz;\n    DSU(int n): par(n), siz(n,1) { iota(par.begin(), par.end(), 0); }\n    int find(int x) { return par[x]==x ? x : par[x]=find(par[x]); }\n    bool unite(int x,int y) {\n        x = find(x); y = find(y);\n        if(x==y) return false;\n        if(siz[x]<siz[y]) swap(x,y);\n        par[y]=x; siz[x]+=siz[y];\n        return true;\n    }\n    int size(int x) { return siz[find(x)]; }\n};\n\nstruct TreeChecker {\n    // Build a graph of non-empty tiles, with edges as problem states,\n    // Then find the largest connected component which is also acyclic\n\n    int N;\n    vector<vector<int>> grid;\n    vector<vector<int>> idmap; // for mapping (i,j) to node ids, since one cell is empty\n\n    TreeChecker(const vector<vector<int>> &g): N(g.size()), grid(g) {\n        // Build idmap: -1 for empty, else unique 0...(N*N-2)\n        idmap.assign(N, vector<int>(N,-1));\n        int id=0;\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++) {\n            if(grid[i][j]!=0) idmap[i][j]=id++;\n        }\n    }\n\n    // Returns (largest tree size)\n    int get_largest_tree_size() {\n        int nn = N*N-1;\n        vector<vector<int>> G(nn);\n        // Build undirected edge list\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++) {\n            if(grid[i][j]==0) continue;\n            int t = grid[i][j];\n            int id1 = idmap[i][j];\n            // down\n            if((t&8) && i+1<N && grid[i+1][j]!=0 && (grid[i+1][j]&2))\n                G[id1].push_back(idmap[i+1][j]);\n            // right\n            if((t&4) && j+1<N && grid[i][j+1]!=0 && (grid[i][j+1]&1))\n                G[id1].push_back(idmap[i][j+1]);\n            // (U/L can reverse edge but already covered)\n        }\n        // Find largest connected acyclic component: for each CC, check if no cycles (tree), report largest\n        int res=0;\n        vector<int> vis(nn,0);\n        for(int i=0;i<nn;i++) {\n            if(vis[i]) continue;\n            int size=0, edges=0;\n            bool is_tree=true;\n            function<void(int,int)> dfs=[&](int u, int p){\n                vis[u]=1; size++;\n                for(int v:G[u]) {\n                    if(v==p) continue;\n                    edges++;\n                    if(vis[v]) is_tree=false;\n                    else dfs(v, u);\n                }\n            };\n            dfs(i,-1);\n            if(is_tree && edges/2==size-1) res=max(res,size); // undirected: edges double-counted\n        }\n        return res;\n    }\n};\n\nint main() {\n    time_start = chrono::high_resolution_clock::now();\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T;\n    cin >> N >> T;\n    Board board(N);\n    board.read_input();\n\n    // Naive strategy: try random walks and keep the best\n    string best_moves;\n    int best_score = 0;\n    Board best_board = board;\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    int try_limit = 1500;   // Control based on validated time!\n    int walk_len = min(T, 200); // Try short walks first, might help\n\n    for(int t=0; t<try_limit; ++t) {\n        Board cur_board = board;\n        vector<int> move_hist;\n        string moves = \"\";\n        int prev_move = -1;\n        for(int k=0; k<walk_len; ++k) {\n            // Random legal move, avoid undoing previous\n            vector<int> can_moves;\n            for(int d=0; d<4; ++d) {\n                if( d != opp_dir[prev_move] && cur_board.can_move(d))\n                    can_moves.push_back(d);\n            }\n            if(can_moves.empty()) break;\n            int mv = can_moves[ rng() % can_moves.size() ];\n            cur_board.do_move(mv);\n            moves += dir_char[mv];\n            prev_move = mv;\n        }\n        // Compute score\n        TreeChecker tc(cur_board.grid);\n        int S = tc.get_largest_tree_size();\n        if(S>best_score || (S==best_score && (int)moves.size()<best_moves.size())) {\n            best_score = S;\n            best_moves = moves;\n            best_board = cur_board;\n        }\n        // Time management (1.8sec safety)\n        if(elapsed_sec() > 1.8) break;\n    }\n\n    // Output\n    cout << best_moves << \"\\n\";\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing P = pair<int, int>;\nusing ll = long long;\nconst double PI = acos(-1.0);\nconst int CAKE_RADIUS = 10000;\nconst int K = 100;\n\nstruct Strawberry {\n    int x, y;\n    int idx; // original id\n};\n\nstruct Line {\n    // Represent by ax + by + c = 0\n    // Or two points (px, py), (qx, qy)\n    int px, py, qx, qy;\n};\n\nstruct Piece {\n    vector<int> strawberry_idxs;\n};\n\nint N, K_input;\nvector<int> a; // a[1..10]\nvector<Strawberry> strawberries;\nvector<Line> cuts;\n\n// For bipartition: Given indices of strawberries, try to partition into sizes d and n-d\n// Return (success, (indices in side A, indices in side B), Line to cut by)\ntuple<bool, vector<int>, vector<int>, Line>\nbipartition(const vector<int>& idxs, int d, const vector<Strawberry>& strawbs, mt19937 &rng) {\n    int n = idxs.size();\n    if (n < d || d == 0 || d == n) return {false, {}, {}, {}};\n    vector<pair<double,int>> project(n); // (projection, index in idxs)\n    vector<double> directions;\n    const int tries = 20;\n    uniform_real_distribution<double> angle_dist(0, PI);\n    for(int attempt = 0; attempt < tries; ++attempt) {\n        double ang = angle_dist(rng);\n        double dx = cos(ang), dy = sin(ang);\n        for(int i = 0; i < n; ++i) {\n            const auto &s = strawbs[idxs[i]];\n            project[i] = {s.x*dx + s.y*dy, i};\n        }\n        sort(project.begin(), project.end());\n        // Try split after d-1 points (left: [0,d-1], right: [d,n-1])\n        double cut_left = project[d-1].first;\n        double cut_right = project[d].first;\n        double cut_proj = (cut_left + cut_right) / 2.0; // split position at midpoint\n        // Find two points on this line\n        // For simplicity, pick a point within cake in direction orthogonal to (dx,dy)\n        // e.g., normal vector (-dy, dx)\n        double nx = -dy, ny = dx;\n        // Pick p0 at (0,0) + cake_radius * (nx, ny)\n        double p0x = nx * CAKE_RADIUS, p0y = ny * CAKE_RADIUS;\n        double p1x = -nx * CAKE_RADIUS, p1y = -ny * CAKE_RADIUS;\n        // Shift line along (dx,dy) by cut_proj units: move origin along (dx,dy)\n        p0x += dx * cut_proj;\n        p0y += dy * cut_proj;\n        p1x += dx * cut_proj;\n        p1y += dy * cut_proj;\n        // Round to integer points in [-1e9,1e9]\n        auto clamp = [](double v) -> int64_t {\n            const ll M = 1000000000LL;\n            if (v > M) return M;\n            if (v < -M) return -M;\n            return static_cast<ll>(round(v));\n        };\n        ll px = clamp(p0x), py = clamp(p0y), qx = clamp(p1x), qy = clamp(p1y);\n\n        // Now assign to sides: those with projection < cut_proj on one side, others on other\n        vector<int> A, B;\n        for(int i = 0; i < n; ++i) {\n            int sidx = idxs[project[i].second];\n            if (project[i].first < cut_proj) A.push_back(sidx);\n            else if (project[i].first > cut_proj) B.push_back(sidx);\n            else {\n                // projection == cut_proj:\n                // Looks like a double point, but in practice, can assign to either cake side\n                // Just assign to B for safety (as cut_proj is mid of two projections)\n                B.push_back(sidx);\n            }\n        }\n        // If any strawberry happens to be exactly ON the line, abort this cut\n        // Check for each strawberry:\n        double eps = 1e-8;\n        bool on_cut = false;\n        for(int i = 0; i < n; ++i) {\n            if (abs(project[i].first - cut_proj) < eps) {\n                // A strawberry would be lost; try a new direction\n                on_cut = true;\n                break;\n            }\n        }\n        if (on_cut) continue;\n        // Now, can get exact d in A or B depending on ordering:\n        if (A.size() == d || B.size() == d) {\n            if (A.size() == d) {\n                return {true, A, B, Line{(int)px, (int)py, (int)qx, (int)qy}};\n            } else {\n                return {true, B, A, Line{(int)px, (int)py, (int)qx, (int)qy}};\n            }\n        }\n    }\n    // no suitable split found\n    return {false, {}, {}, {}};\n}\n\nint main(){\n    ios::sync_with_stdio(false); cin.tie(0);\n    cin >> N >> K_input;\n    a.resize(11);\n    int Ncheck = 0;\n    for(int d=1;d<=10; ++d) {\n        cin >> a[d];\n        Ncheck += d * a[d];\n    }\n    strawberries.resize(N);\n    for(int i=0;i<N;++i){\n        int x, y; cin >> x >> y;\n        strawberries[i] = {x, y, i};\n    }\n    // Bookkeeping for pieces:\n    vector<vector<int>> pieces; // each as vector of strawberry indices\n    pieces.push_back(vector<int>(N));\n    iota(pieces[0].begin(), pieces[0].end(), 0);\n\n    // For each d from 10 downto 1 (focus on large pieces first)\n    // Alternatively, weighted by number required; for now, 10..1\n    int remains[11];\n    for(int d=1;d<=10;++d) remains[d]=a[d];\n\n    mt19937 rng(123456 + chrono::steady_clock::now().time_since_epoch().count());\n\n    // For cuts\n    vector<Line> used_cuts;\n\n    // For pieces: maintain multiset by size (for quickly finding suitable ones)\n    // Actually, not necessary for up to 1000 pieces\n\n    // Map: pieces_to_process[d]: indices of pieces of size >= d, and not yet processed\n    // We'll go for greedy: for d from 10..1, try to split pieces down\n    // For now, do as explained: try to generate as many pieces of size d as a[d]\n    for(int d=10; d>=1; --d) {\n        int need = remains[d];\n        if(need == 0) continue;\n        // Look for pieces with size >= d\n        // For each round:\n        bool found;\n        int attempts = 0;\n        while(need > 0) {\n            found = false;\n            for(int pi=0; pi<pieces.size(); ++pi) {\n                vector<int> &piece = pieces[pi];\n                if ((int)piece.size() > d) {\n                    // Try bipartition this piece into d and n-d\n                    auto [ok, groupA, groupB, line] = bipartition(piece, d, strawberries, rng);\n                    if(ok) {\n                        // Accept this cut, add it to cuts\n                        used_cuts.push_back(line);\n                        // Remove piece, add groupA, groupB instead\n                        piece = move(groupA);\n                        pieces.push_back(move(groupB));\n                        // Mark found\n                        found = true;\n                        --need;\n                        break; // do next need\n                    }\n                }\n            }\n            if(!found) break; // Could not perform more for this d\n            if((int)used_cuts.size() >= K) break;\n            ++attempts;\n            if(attempts > 1000) break; // Give up (should not be needed)\n        }\n        if((int)used_cuts.size() >= K) break;\n    }\n\n    // Now, after all splits, count how many pieces of each size, up to a[d] per attendee\n    vector<int> cnt(11, 0);\n    for(const auto &piece: pieces) {\n        int sz = piece.size();\n        if(sz >= 1 && sz <= 10) cnt[sz]++;\n    }\n    int total_given = 0;\n    for(int d=1;d<=10;++d) total_given += min(a[d], cnt[d]);\n    // Output cuts\n    int k_out = used_cuts.size();\n    cout << k_out << \"\\n\";\n    for(const auto &line : used_cuts) {\n        cout << line.px << \" \" << line.py << \" \" << line.qx << \" \" << line.qy << \"\\n\";\n    }\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nusing pii = pair<int, int>;\n\nconstexpr int DX[4] = {1, 0, -1, 0};\nconstexpr int DY[4] = {0, 1, 0, -1};\n\nstruct Edge {\n    int x1, y1, x2, y2;\n    Edge(int a,int b,int c,int d) {\n        if (pii(a, b) < pii(c, d)) {\n            x1 = a; y1 = b; x2 = c; y2 = d;\n        } else {\n            x1 = c; y1 = d; x2 = a; y2 = b;\n        }\n    }\n    bool operator < (const Edge& o) const {\n        return tie(x1,y1,x2,y2) < tie(o.x1,o.y1,o.x2,o.y2);\n    }\n};\n\nint N,M;\nvector<vector<int>> board; // 0: empty, 1: dot placed during play, 2: initial dot\nset<pii> dots; // occupied\nset<Edge> used_edges; // segments of perimeters\n\nvector<vector<ll>> weights;\nll S = 0;\nint CENTER;\nvector<array<int,8>> moves;\n\nvoid input() {\n    cin >> N >> M;\n    board.assign(N, vector<int>(N, 0));\n    for (int i = 0; i < M; ++i) {\n        int x,y;\n        cin >> x >> y;\n        board[x][y] = 2;\n        dots.emplace(x, y);\n    }\n    CENTER = (N-1)/2;\n    \n    weights.assign(N, vector<ll>(N, 0));\n    S = 0;\n    for (int x=0; x<N; ++x)\n        for (int y=0; y<N; ++y) {\n            weights[x][y] = (x-CENTER)*(x-CENTER) + (y-CENTER)*(y-CENTER) + 1;\n            S += weights[x][y];\n        }\n}\n\nbool is_valid(int x, int y) {\n    return x>=0 && x<N && y>=0 && y<N;\n}\n\n// For each empty cell, try all rectangles for which it can be one corner, with 3 dots as the other 3 corners\n// Return all candidate rectangles (with highest scoring p1 positions first)\nvector<array<int,8>> find_candidate_moves() {\n    vector<tuple<ll, array<int,8>>> candidates; // score, move\n    // To avoid too much computation, consider only shells near frontier\n    // Let's try to consider all for now (limit time if slow)\n    for (int x1=0; x1<N; ++x1) for (int y1=0; y1<N; ++y1) {\n        if (board[x1][y1] != 0) continue;\n        // For axis-aligned rectangles\n        for (auto& [dx,dy] : vector<pair<int,int>>{{1,0},{0,1}}) {\n            for (int len=1; len<=min(N-1,7); ++len) {\n                int x2 = x1+dx*len, y2 = y1+dy*len;\n                int x4 = x1+dy*len, y4 = y1-dx*len;\n                int x3 = x2+dy*len, y3 = y2-dx*len;\n                if (!is_valid(x2,y2) || !is_valid(x3,y3) || !is_valid(x4,y4)) continue;\n\n                array<pii,4> pts = {pii(x1,y1), pii(x2,y2), pii(x3,y3), pii(x4,y4)};\n                vector<int> ids = {0,1,2,3};\n\n                // try all 3 choose 3 for which the other three points have dots\n                vector<int> dot_idx;\n                for (int i=1; i<4; ++i) if (dots.count(pts[i])) dot_idx.push_back(i);\n                if ((int)dot_idx.size()<3) continue;\n                // Choose all three-point combinations (should be just one for axis-aligned)\n                for (int p=0; p<3; ++p) {\n                    int i2=dot_idx[p%3], i3=dot_idx[(p+1)%3], i4=dot_idx[(p+2)%3];\n                    array<int,8> move = {pts[0].first, pts[0].second, \n                        pts[i2].first, pts[i2].second,\n                        pts[i3].first, pts[i3].second,\n                        pts[i4].first, pts[i4].second\n                    };\n                    // check that the perimeter (except at corners) is empty and doesn't overlap a previous rect's segment\n                    vector<pii> perim = {pts[0], pts[i2], pts[i3], pts[i4]};\n                    bool ok = true;\n                    int sz = (int)perim.size();\n                    // check dots on perimeter but not at corners\n                    for (int j=0; j<sz; ++j) {\n                        int xA=perim[j].first, yA=perim[j].second;\n                        int xB=perim[(j+1)%sz].first, yB=perim[(j+1)%sz].second;\n                        int dx = (xB-xA)?((xB-xA)/abs(xB-xA)):0, dy = (yB-yA)?((yB-yA)/abs(yB-yA)):0;\n                        for (int xm = xA+dx, ym = yA+dy; \n                             xm!=xB||ym!=yB; xm+=dx, ym+=dy) {\n                            if (dots.count({xm, ym})) { ok=false; break; }\n                        }\n                        // Check perimeter overlap\n                        Edge e(xA,yA,xB,yB);\n                        if (used_edges.count(e)) { ok=false; break;}\n                    }\n                    if (ok) {\n                        candidates.emplace_back(weights[x1][y1], move);\n                    }\n                }\n            }\n        }\n        // 45-degree (diamond) rectangles\n        // For d=1 to limit (side increases as sqrt(2)*d)\n        for (int dx=1; dx<=6; ++dx) { // side length (sqrt(2)*dx)\n            int x2 = x1+dx, y2=y1+dx;\n            int x3 = x1, y3 = y1+2*dx;\n            int x4=x1-dx, y4=y1+dx;\n            if (!is_valid(x2,y2)||!is_valid(x3,y3)||!is_valid(x4,y4)) continue;\n            array<pii,4> pts = {pii(x1,y1), pii(x2,y2), pii(x3,y3), pii(x4,y4)};\n            // check that other three are dots\n            vector<int> dot_idx;\n            for (int i=1; i<4; ++i) if (dots.count(pts[i])) dot_idx.push_back(i);\n            if ((int)dot_idx.size()<3) continue;\n            for (int p=0; p<3; ++p) {\n                int i2=dot_idx[p%3], i3=dot_idx[(p+1)%3], i4=dot_idx[(p+2)%3];\n                array<int,8> move = {pts[0].first, pts[0].second, \n                    pts[i2].first, pts[i2].second,\n                    pts[i3].first, pts[i3].second,\n                    pts[i4].first, pts[i4].second\n                };\n                // perimeter check\n                vector<pii> perim = {pts[0], pts[i2], pts[i3], pts[i4]};\n                bool ok = true;\n                int sz = (int)perim.size();\n                for (int j=0; j<sz; ++j) {\n                    int xA=perim[j].first, yA=perim[j].second;\n                    int xB=perim[(j+1)%sz].first, yB=perim[(j+1)%sz].second;\n                    int dx = (xB-xA)?((xB-xA)/abs(xB-xA)):0, dy = (yB-yA)?((yB-yA)/abs(yB-yA)):0;\n                    for (int xm = xA+dx, ym = yA+dy; xm!=xB||ym!=yB; xm+=dx, ym+=dy) {\n                        if (dots.count({xm, ym})) { ok=false; break; }\n                    }\n                    // Check perimeter overlap\n                    Edge e(xA,yA,xB,yB);\n                    if (used_edges.count(e)) { ok=false; break;}\n                }\n                if (ok) {\n                    candidates.emplace_back(weights[x1][y1], move);\n                }\n            }\n        }\n    }\n    sort(candidates.rbegin(), candidates.rend()); // High weight to low weight\n    vector<array<int,8>> res;\n    for (auto& [score,move] : candidates) res.push_back(move);\n    return res;\n}\n\nvoid make_move(const array<int,8>& mv) {\n    int x1=mv[0], y1=mv[1];\n    int x2=mv[2], y2=mv[3];\n    int x3=mv[4], y3=mv[5];\n    int x4=mv[6], y4=mv[7];\n    board[x1][y1]=1;\n    dots.emplace(x1,y1);\n    // Mark used segments\n    vector<pii> pts = {pii(x1,y1), pii(x2,y2), pii(x3,y3), pii(x4,y4)};\n    int sz = (int)pts.size();\n    for (int i=0;i<sz;++i) {\n        int xA=pts[i].first, yA=pts[i].second;\n        int xB=pts[(i+1)%sz].first, yB=pts[(i+1)%sz].second;\n        used_edges.insert(Edge(xA,yA,xB,yB));\n    }\n    moves.push_back(mv);\n}\n\n// Main solve\nvoid solve() {\n    while (true) {\n        vector<array<int,8>> cands = find_candidate_moves();\n        if (cands.empty()) break;\n        // Pick the best (highest weight gain)\n        make_move(cands[0]);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    input();\n    solve();\n    cout << moves.size() << \"\\n\";\n    for (auto& mv : moves) {\n        for (int i=0; i<8; ++i) cout << mv[i] << \" \";\n        cout << \"\\n\";\n    }\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <array>\n#include <algorithm>\n#include <string>\n#include <queue>\n#include <cassert>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n// Grid size\nconstexpr int N = 10;\nusing Board = array<array<int, N>, N>;\nusing Pos = pair<int,int>;\n\nvoid flush() { cout << flush; }\n\n// Standard gravity on a copy of 'board', in direction dir\nvoid move_board(Board& board, char dir) {\n    if (dir == 'F') {\n        for (int x = 0; x < N; x++) {\n            int write = 0;\n            for (int y = 0; y < N; y++) {\n                if (board[y][x] != 0) {\n                    if (write != y) {\n                        board[write][x] = board[y][x];\n                        board[y][x] = 0;\n                    }\n                    write++;\n                }\n            }\n        }\n    } else if (dir == 'B') {\n        for (int x = 0; x < N; x++) {\n            int write = N-1;\n            for (int y = N-1; y >=0; --y) {\n                if (board[y][x] != 0) {\n                    if (write != y) {\n                        board[write][x] = board[y][x];\n                        board[y][x] = 0;\n                    }\n                    write--;\n                }\n            }\n        }\n    } else if (dir == 'L') {\n        for (int y = 0; y < N; y++) {\n            int write = 0;\n            for (int x = 0; x < N; x++) {\n                if (board[y][x] != 0) {\n                    if (write != x) {\n                        board[y][write] = board[y][x];\n                        board[y][x] = 0;\n                    }\n                    write++;\n                }\n            }\n        }\n    } else if (dir == 'R') {\n        for (int y = 0; y < N; y++) {\n            int write = N-1;\n            for (int x = N-1; x >= 0; --x) {\n                if (board[y][x] != 0) {\n                    if (write != x) {\n                        board[y][write] = board[y][x];\n                        board[y][x] = 0;\n                    }\n                    write--;\n                }\n            }\n        }\n    }\n}\n\n// Return empty cells as vector of (y,x)\nvector<array<int,2>> get_empty_cells(const Board& board) {\n    vector<array<int,2>> res;\n    for (int y = 0; y < N; ++y)\n        for (int x = 0; x < N; ++x)\n            if (board[y][x] == 0)\n                res.push_back({y, x});\n    return res;\n}\n\n// To map p_t to (y,x)\nPos get_index_from_pt(const vector<array<int,2>>& empties, int p_t) {\n    assert(p_t >= 1 && p_t <= (int)empties.size());\n    return {empties[p_t-1][0], empties[p_t-1][1]};\n}\n\n// Directions for BFS\nconstexpr int dy[4] = {1, -1,  0,  0};\nconstexpr int dx[4] = {0,  0,  1, -1};\n\n// Calculate sum of squares of all connected components for the board\nint calc_component_score(const Board& board) {\n    array<array<bool,N>,N> visited{};\n    int total_score = 0;\n    for (int y=0; y<N; y++) for (int x=0; x<N; x++) {\n        if (board[y][x]!=0 && !visited[y][x]) {\n            int flavor = board[y][x];\n            int sz = 0;\n            queue<pair<int,int>> q;\n            q.push({y,x});\n            visited[y][x] = true;\n            while (!q.empty()) {\n                auto [cy,cx] = q.front(); q.pop();\n                sz++;\n                for (int d=0; d<4; d++) {\n                    int ny = cy + dy[d], nx = cx + dx[d];\n                    if (ny >=0 && ny < N && nx >=0 && nx < N) {\n                        if (!visited[ny][nx] && board[ny][nx]==flavor) {\n                            visited[ny][nx]=true;\n                            q.push({ny,nx});\n                        }\n                    }\n                }\n            }\n            total_score += sz*sz;\n        }\n    }\n    return total_score;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // For breaking ties randomly\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    // Read flavors for all candies\n    vector<int> flavors(100);\n    for (int i = 0; i < 100; ++i) cin >> flavors[i];\n\n    Board board{}; // initialized to 0 everywhere\n\n    // Directions to try\n    const array<char,4> all_dirs = {'F','B','L','R'};\n\n    for (int step = 0; step < 100; ++step) {\n        int p_t;\n        cin >> p_t;\n        vector<array<int,2>> empties = get_empty_cells(board);\n        Pos pos = get_index_from_pt(empties, p_t);\n        int flavor = flavors[step];\n        board[pos.first][pos.second] = flavor;\n\n        // Simulate all 4 directions, pick the best\n        int best_score = -1;\n        vector<char> best_dirs;\n        for (char dir : all_dirs) {\n            Board temp = board;\n            move_board(temp, dir);\n            int score = calc_component_score(temp);\n            if (score > best_score) {\n                best_score = score;\n                best_dirs = {dir};\n            } else if (score == best_score) {\n                best_dirs.push_back(dir);\n            }\n        }\n        // Break ties randomly for variety, else always take first as deterministic\n        char chosen_dir = best_dirs[rng() % best_dirs.size()];\n\n        // Make the real move\n        move_board(board, chosen_dir);\n\n        if (step != 99) {\n            cout << chosen_dir << '\\n';\n            flush();\n        }\n    }\n\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\n#include <Eigen/Dense>\nusing namespace std;\nusing namespace Eigen;\n\nconst int MAX_N = 100;\nconst int EIGEN_CNT = 10; // Number of eigenvalues to keep\n\n// Helper: string edge list to Eigen adjacency\nvoid string_to_matrix(const string &s, int N, MatrixXd &adj) {\n    adj = MatrixXd::Zero(N, N);\n    int idx = 0;\n    for(int i=0;i<N;i++)for(int j=i+1;j<N;j++) {\n        if(s[idx++]=='1') {\n            adj(i,j) = adj(j,i) = 1.0;\n        }\n    }\n}\n\n// Get sorted degree sequence\nvector<int> get_degseq(const string &s, int N) {\n    vector<int> deg(N, 0);\n    int idx = 0;\n    for(int i=0;i<N;++i) for(int j=i+1;j<N;++j,++idx) {\n        if(s[idx]=='1') {\n            deg[i]++; deg[j]++;\n        }\n    }\n    sort(deg.begin(), deg.end());\n    return deg;\n}\n\n// Get quantized eigenvalues (largest positive & lowest negative EIGEN_CNT/2 each)\nvector<double> get_eigen(const string &s, int N) {\n    MatrixXd adj(N, N);\n    string_to_matrix(s, N, adj);\n    SelfAdjointEigenSolver<MatrixXd> sol(adj);\n    vector<double> eigs(N);\n    for(int i=0;i<N;++i) eigs[i] = sol.eigenvalues()(i);\n    sort(eigs.begin(), eigs.end());\n    // Take lower EIGEN_CNT/2 and upper EIGEN_CNT/2\n    int K = EIGEN_CNT/2;\n    vector<double> v;\n    for(int i=0;i<K;++i) v.push_back(eigs[i]);\n    for(int i=N-K;i<N;++i) v.push_back(eigs[i]);\n    return v;\n}\n\n// Euclidean distance for eigenvectors, and L1 for degree seqs\ndouble eigen_dist(const vector<double>& a, const vector<double>& b) {\n    double d = 0;\n    for(int i=0;i<(int)a.size();++i) d += (a[i]-b[i])*(a[i]-b[i]);\n    return sqrt(d);\n}\nint deg_dist(const vector<int>& a, const vector<int>& b) {\n    int d = 0;\n    for(int i=0;i<(int)a.size();++i) d += abs(a[i]-b[i]);\n    return d;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int M;\n    double eps;\n    cin >> M >> eps;\n\n    // Adaptive N (tuned)\n    int add = (int)(eps * 2.8 * M + 8);\n    int N = min(100, max(4, M + add));\n\n    // Random regular graph generator as before\n    mt19937 rng(1337+M+(int)(eps*10000));\n    auto random_regular_graph = [&](int N, int d) {\n        vector<int> deg(N, d);\n        vector<int> stubs;\n        for(int i=0;i<N;i++) for(int j=0;j<d;j++) stubs.push_back(i);\n        vector<vector<int>> adj(N);\n        for(int tries=0;tries<10;tries++) {\n            auto st = stubs;\n            shuffle(st.begin(), st.end(), rng);\n            vector<vector<int>> to(N);\n            bool good = true;\n            for(int i=0;i<st.size();i+=2) {\n                int u=st[i],v=st[i+1];\n                if(u==v) {good=false;break;}\n                if(find(to[u].begin(), to[u].end(), v)!=to[u].end()) {good=false;break;}\n                to[u].push_back(v);\n                to[v].push_back(u);\n            }\n            if(good) return to;\n        }\n        // Fallback: Erdos-Renyi at density 0.5\n        vector<vector<int>> adj2(N);\n        uniform_real_distribution<double> ud(0,1);\n        for(int i=0;i<N;i++) for(int j=i+1;j<N;j++) {\n            if(ud(rng)<0.5) { adj2[i].push_back(j); adj2[j].push_back(i); }\n        }\n        return adj2;\n    };\n\n    // Prepare graph codes\n    vector<string> graph_codes;\n    set<string> used_code;\n    int target_deg = min(N-1, max(2, N/2 + (int)(eps*N/3)));\n    for(int i=0;i<M;i++) {\n        string code;\n        do {\n            auto adj = random_regular_graph(N, target_deg);\n            string s(N*(N-1)/2,'0');\n            int idx=0;\n            for(int u=0;u<N;u++) for(int v=u+1;v<N;v++,idx++) {\n                if(find(adj[u].begin(), adj[u].end(), v)!=adj[u].end()) s[idx]='1';\n            }\n            code=s;\n        } while(used_code.count(code));\n        used_code.insert(code);\n        graph_codes.push_back(code);\n    }\n\n    // Output M graphs\n    cout << N << endl;\n    for(string& s:graph_codes) cout << s << '\\n';\n    cout.flush();\n\n    // Precompute features for all codes\n    vector< vector<int> > degseqs(M);\n    vector< vector<double> > eigens(M);\n    for(int i=0;i<M;i++) {\n        degseqs[i]=get_degseq(graph_codes[i], N);\n        eigens[i]=get_eigen(graph_codes[i], N);\n    }\n\n    // For each query\n    for(int q=0;q<100;q++) {\n        string query;\n        cin >> query;\n        auto q_degseq = get_degseq(query,N);\n        auto q_eigen = get_eigen(query,N);\n\n        // Find closest code\n        int best = 0;\n        double bestscore = 1e18;\n        for(int i=0;i<M;i++) {\n            int dd = deg_dist(q_degseq, degseqs[i]);\n            double ed = eigen_dist(q_eigen, eigens[i]);\n            double score = 0.11*dd + ed; // Heavy on eigen, degree helps in rare collision\n            if(score < bestscore) {\n                bestscore = score;\n                best = i;\n            }\n        }\n\n        cout << best << '\\n';\n        cout.flush();\n    }\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Random engine\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\nint randint(int a, int b) {\n    return uniform_int_distribution<int>(a, b)(rng);\n}\n\nstruct Edge {\n    int u, v, w, id;\n    Edge(int u=0, int v=0, int w=0, int id=0): u(u), v(v), w(w), id(id) {}\n};\n\n// For all-pairs shortest paths, use Dijkstra from SAMPLES nodes for edge importance\nconst int SAMPLES = 25;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, D, K;\n    cin >> N >> M >> D >> K;\n\n    vector<Edge> edges;\n    vector<vector<pair<int,int>>> g(N);\n\n    for (int i = 0; i < M; ++i) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        --u; --v;\n        edges.emplace_back(u, v, w, i);\n        g[u].emplace_back(v, w);\n        g[v].emplace_back(u, w);\n    }\n\n    // Skip coordinates input\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n    }\n\n    // Step 1: Compute all-pairs shortest paths Dijkstra from SAMPLES nodes\n    vector<vector<int>> base_dist(SAMPLES, vector<int>(N, 1e9));\n    vector<int> sample_src;\n    for (int i = 0; i < SAMPLES; ++i)\n        sample_src.push_back(randint(0, N-1));\n\n    for (int si = 0; si < SAMPLES; ++si) {\n        int src = sample_src[si];\n        // Dijkstra\n        vector<int> dist(N, 1e9); dist[src] = 0;\n        using pli = pair<int, int>;\n        priority_queue<pli, vector<pli>, greater<pli>> pq;\n        pq.emplace(0, src);\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u]) continue;\n            for (auto &[v, w]: g[u]) {\n                if (dist[v] > d + w) {\n                    dist[v] = d + w;\n                    pq.emplace(dist[v], v);\n                }\n            }\n        }\n        base_dist[si] = dist;\n    }\n\n    // Step 2: For each edge, compute its importance\n    vector<double> e_importance(M, 0.0);\n\n    for (int eid = 0; eid < M; ++eid) {\n        // Build adjacency list without this edge\n        int u = edges[eid].u, v = edges[eid].v, w = edges[eid].w;\n        vector<vector<pair<int,int>>> gtmp = g;\n        auto erase1 = [&](int a, int b){\n            auto& vec = gtmp[a];\n            for (auto it = vec.begin(); it != vec.end(); ++it)\n                if (it->first == b) { vec.erase(it); break; }\n        };\n        erase1(u, v);\n        erase1(v, u);\n\n        double damage = 0.0;\n        // For each sampled Dijkstra\n        for (int si = 0; si < SAMPLES; ++si) {\n            int src = sample_src[si];\n            vector<int> dist(N, 1e9); dist[src] = 0;\n            using pli = pair<int, int>;\n            priority_queue<pli, vector<pli>, greater<pli>> pq;\n            pq.emplace(0, src);\n            while (!pq.empty()) {\n                auto [d, uu] = pq.top(); pq.pop();\n                if (d > dist[uu]) continue;\n                for (auto &[vv, ww]: gtmp[uu]) {\n                    if (dist[vv] > d + ww) {\n                        dist[vv] = d + ww;\n                        pq.emplace(dist[vv], vv);\n                    }\n                }\n            }\n            for (int j = 0; j < N; ++j) {\n                if (j == src) continue;\n                int before = base_dist[si][j];\n                int after = dist[j];\n                // If unreachable, treat as extra penalty\n                if (after >= 1e9) after = 1e9;\n                damage += (double)(after - before);\n            }\n        }\n        e_importance[eid] = damage / SAMPLES;\n    }\n\n    // Step 3: Schedule edges (sort by importance, assign in snake/zigzag round-robin)\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n\n    sort(order.begin(), order.end(), [&](int i, int j) { return e_importance[i] > e_importance[j]; });\n\n    vector<int> day_of_edge(M, -1);\n    vector<int> day_counts(D, 0);\n\n    int ptr = 0, dir = 1;\n    for (int idx = 0; idx < M; ++idx) {\n        // Assign next edge in sorted order to day ptr\n        while (day_counts[ptr] >= K) {\n            // Find next non-full day\n            ptr += dir;\n            if (ptr == D) { ptr = D-1; dir = -1; }\n            if (ptr == -1) { ptr = 0; dir = 1; }\n        }\n        int eid = order[idx];\n        day_of_edge[eid] = ptr;\n        day_counts[ptr] += 1;\n        // Move pointer (snake fashion)\n        ptr += dir;\n        if (ptr == D) { ptr = D-1; dir = -1; }\n        if (ptr == -1) { ptr = 0; dir = 1; }\n    }\n\n    // Output: for each edge in input order, print day+1 (1-based)\n    for (int i = 0; i < M; ++i) {\n        cout << (day_of_edge[i]+1) << (i + 1 == M ? '\\n' : ' ');\n    }\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\nusing pii = pair<int, int>;\nusing vi = vector<int>;\nusing vvi = vector<vi>;\n\n// --- Helper types for a shape ---\nusing Shape = vector<array<int,3>>;  // sorted relative positions\n\n// All 24 rotation matrices for cube (no reflection), precalculated\nconst vector<array<array<int,3>,3>> ROTATIONS = []{\n    vector<array<array<int,3>,3>> R;\n    // This code produces all 24 possible cube rotations\n    set<vector<array<int,3>,3>> seen;\n    auto apply = [](const array<array<int,3>,3>& M, array<int,3> v) {\n        array<int,3> r;\n        for(int i=0;i<3;++i) r[i] = M[i][0]*v[0] + M[i][1]*v[1] + M[i][2]*v[2];\n        return r;\n    };\n    auto matmul = [](const array<array<int,3>,3>& A, const array<array<int,3>,3>& B) {\n        array<array<int,3>,3> R{};\n        for(int i=0;i<3;++i) for(int j=0;j<3;++j) for(int k=0;k<3;++k)\n            R[i][j] += A[i][k]*B[k][j];\n        return R;\n    };\n    // Basic face rotations\n    vector<array<array<int,3>,3>> faceRots = {\n        {{{1,0,0},{0,1,0},{0,0,1}}},\n        {{{0,0,1},{0,1,0},{-1,0,0}}},\n        {{{-1,0,0},{0,1,0},{0,0,-1}}},\n        {{{0,0,-1},{0,1,0},{1,0,0}}},\n        {{{1,0,0},{0,0,-1},{0,1,0}}},\n        {{{1,0,0},{0,0,1},{0,-1,0}}}\n    };\n    // 0, 90, 180, 270 deg rotations about Y axis\n    vector<array<array<int,3>,3>> yrots = {\n        {{{1,0,0},{0,1,0},{0,0,1}}},\n        {{{0,0,1},{0,1,0},{-1,0,0}}},\n        {{{-1,0,0},{0,1,0},{0,0,-1}}},\n        {{{0,0,-1},{0,1,0},{1,0,0}}}\n    };\n    for(auto& f: faceRots) for(auto& y: yrots) {\n        auto rot = matmul(y, f);\n        // Unique up to 24\n        if(seen.count(rot)) continue;\n        seen.insert(rot);\n        R.push_back(rot);\n    }\n    return R;\n}();\n\nShape canonicalize(const Shape& shape) {\n    // Centers at (0,0,0), returns smallest lex order under all 24 rotations\n    vector<Shape> candidates;\n\n    for(const auto &rot: ROTATIONS) {\n        Shape s;\n        for(auto p: shape) {\n            array<int,3> q = {0,0,0};\n            for(int i=0;i<3;++i)\n                q[i] = rot[i][0]*p[0] + rot[i][1]*p[1] + rot[i][2]*p[2];\n            s.push_back(q);\n        }\n        // Now, shift min to (0,0,0)\n        int minx=1e9,miny=1e9,minz=1e9;\n        for(auto &q: s) {\n            minx = min(minx, q[0]);\n            miny = min(miny, q[1]);\n            minz = min(minz, q[2]);\n        }\n        for(auto &q: s) {\n            q[0] -= minx;\n            q[1] -= miny;\n            q[2] -= minz;\n        }\n        sort(s.begin(), s.end());\n        candidates.push_back(s);\n    }\n    return *min_element(candidates.begin(), candidates.end());\n}\n\n// Encodes a shape for hash-comparison\nstring shape_to_str(const Shape& s) {\n    string out;\n    for(auto p: s) for(int x:p) out+=\",\"+to_string(x);\n    return out;\n}\n\n// For blocks found inside an object\nstruct FoundBlock {\n    int anchor_x, anchor_y, anchor_z;\n    Shape s;\n    vector<array<int,3>> global_voxels; // absolute position for each cell\n};\n\n// Greedy maximal cube cover of mask\nvector<FoundBlock> greedy_cover(const vector<vector<vector<int>>> &mask, int D) {\n    // 0: empty or already assigned, 1: needs assigning\n    vector<vector<vector<int>>> rem = mask;\n    vector<FoundBlock> blocks;\n    vector<vector<vector<int>>> vis(D, vector<vector<int>>(D,vector<int>(D,0)));\n    // Greedily cover big cubes then lines then single\n    auto inside = [&](int x,int y,int z) {\n        return 0<=x && x<D && 0<=y && y<D && 0<=z && z<D;\n    };\n    int filled=0, total=0;\n    for(int x=0;x<D;++x) for(int y=0;y<D;++y) for(int z=0;z<D;++z)\n        if(mask[x][y][z]) total++;\n    while(filled<total) {\n        int bestV=-1, bx,by,bz,bsize;\n        string bdir; // \"cube\", \"x\", \"y\", \"z\"\n        // Try cube of size sz, largest first\n        for(int sz = min(5,D); sz>=2; --sz) { // Cube SZxSZxSZ\n            for(int x=0;x<=D-sz;++x) for(int y=0;y<=D-sz;++y) for(int z=0;z<=D-sz;++z) {\n                bool ok=1;\n                int cnt=0;\n                for(int dx=0;dx<sz&&ok;++dx) for(int dy=0;dy<sz;++dy) for(int dz=0;dz<sz;++dz)\n                    if(!rem[x+dx][y+dy][z+dz]) { ok=0; break; }\n                if(!ok) continue;\n                cnt = sz*sz*sz;\n                if(cnt>bestV) {\n                    bx=x; by=y; bz=z; bsize=sz; bestV=cnt; bdir=\"cube\";\n                }\n            }\n        }\n        // Try MAX-length lines (x/y/z)\n        for(int d=0;d<3;++d) {\n            for(int sz = min(D,7); sz>=2; --sz) {\n                for(int x=0; x<D; ++x) for(int y=0; y<D; ++y) for(int z=0; z<D; ++z) {\n                    int dx = (d==0), dy=(d==1), dz=(d==2);\n                    bool ok=1;\n                    if(inside(x+(sz-1)*dx,y+(sz-1)*dy,z+(sz-1)*dz)==0) continue;\n                    for(int i=0;i<sz;++i) {\n                        int nx=x+i*dx, ny=y+i*dy, nz=z+i*dz;\n                        if(!rem[nx][ny][nz]) {ok=0;break;}\n                    }\n                    if(!ok) continue;\n                    if(sz > bestV) {\n                        bx=x; by=y; bz=z; bsize=sz; bestV=sz; \n                        if(d==0) bdir=\"x\"; else if(d==1) bdir=\"y\"; else bdir=\"z\";\n                    }\n                }\n            }\n        }\n        if(bestV==-1) {\n            // Just fill random remaining 1 cell\n            for(int x=0;x<D;++x) for(int y=0;y<D;++y) for(int z=0;z<D;++z)\n                if(rem[x][y][z]) {\n                    bx=x; by=y; bz=z; bsize=1; bestV=1; bdir=\"pt\";\n                    goto ok_found;\n                }\n        }\nok_found:;\n        // Build FoundBlock\n        FoundBlock fb;\n        fb.anchor_x = bx; fb.anchor_y = by; fb.anchor_z = bz;\n        Shape s;\n        vector<array<int,3>> vox;\n        if(bdir==\"cube\") {\n            for(int dx=0;dx<bsize;++dx) for(int dy=0;dy<bsize;++dy) for(int dz=0;dz<bsize;++dz) {\n                int x=bx+dx, y=by+dy, z=bz+dz;\n                s.push_back({dx,dy,dz});\n                vox.push_back({x,y,z});\n                rem[x][y][z]=0; filled++;\n            }\n        } else if(bdir==\"x\"||bdir==\"y\"||bdir==\"z\") {\n            int dx=(bdir==\"x\"),dy=(bdir==\"y\"),dz=(bdir==\"z\");\n            for(int i=0;i<bsize;++i) {\n                int x=bx + dx*i, y=by + dy*i, z=bz + dz*i;\n                s.push_back({dx*i,dy*i,dz*i});\n                vox.push_back({x,y,z});\n                rem[x][y][z]=0; filled++;\n            }\n        } else {\n            s.push_back({0,0,0});\n            vox.push_back({bx,by,bz});\n            rem[bx][by][bz]=0; filled++;\n        }\n        fb.s = s;\n        fb.global_voxels = vox;\n        blocks.push_back(fb);\n    }\n    return blocks;\n}\n\n// Now try \"match\" blocks between two silhouette objects by canonical polycube\nvoid assign_block_numbers(\n    vector<FoundBlock>& blocksA, vector<FoundBlock>& blocksB, \n    map<string, vector<pair<int,FoundBlock*>>>& blockDict,\n    map<int,int>& block_to_global_number, int &global_block_counter\n) {\n    // Place all found blocks in dict by canonical form\n    for(int i=0; i<blocksA.size(); ++i) {\n        Shape can = canonicalize(blocksA[i].s);\n        string key = shape_to_str(can);\n        blockDict[key].emplace_back(0, &blocksA[i]);\n    }\n    for(int i=0; i<blocksB.size(); ++i) {\n        Shape can = canonicalize(blocksB[i].s);\n        string key = shape_to_str(can);\n        blockDict[key].emplace_back(1, &blocksB[i]);\n    }\n    // For each unique block (canonical), assign a global number, and set in block_to_global_number\n    for(auto& [key, vec]: blockDict) {\n        // See if used in both A, B\n        bool hasA=0, hasB=0;\n        for(auto& [who,_]:vec) if(who==0) hasA=1; else hasB=1;\n        ++global_block_counter;\n        int my_number = global_block_counter;\n        for(auto& [who,ptr]:vec) {\n            ptr->anchor_x = my_number; // overload to store number for assignment\n        }\n    }\n}\n\n// Output for one object: For each cell in D^3, output block number\nvector<int> gen_assignment(const vector<FoundBlock>& blocks, int D) {\n    vector<int> ans(D*D*D,0);\n    for(auto& fb: blocks) {\n        int block_number = fb.anchor_x;\n        for(auto& q: fb.global_voxels) {\n            int idx = q[0]*D*D + q[1]*D + q[2];\n            ans[idx] = block_number;\n        }\n    }\n    return ans;\n}\n\n// --- Main solution function ---\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int D;\n    cin >> D;\n    vector<vector<string>> F(2, vector<string>(D));\n    vector<vector<string>> R(2, vector<string>(D));\n    for(int s=0;s<2;++s) for(int i=0;i<D;++i) cin>>F[s][i];\n    for(int s=0;s<2;++s) for(int i=0;i<D;++i) cin>>R[s][i];\n\n    // Build 3D mask for each object\n    auto build_mask = [&](int idx) {\n        vector<vector<vector<int>>> mask(D, vector<vector<int>>(D,vector<int>(D,0)));\n        for(int x=0;x<D;++x) for(int y=0;y<D;++y) for(int z=0;z<D;++z) {\n            if(F[idx][z][x]=='1' && R[idx][z][y]=='1')\n                mask[x][y][z]=1;\n        }\n        return mask;\n    };\n    vector<vector<vector<int>>> mask1 = build_mask(0);\n    vector<vector<vector<int>>> mask2 = build_mask(1);\n\n    // Greedy cover for both\n    auto blocksA = greedy_cover(mask1, D);\n    auto blocksB = greedy_cover(mask2, D);\n\n    // Now assign global block numbers (by matching shapes)\n    map<string, vector<pair<int,FoundBlock*>>> blockDict;\n    map<int,int> block_to_global_number;\n    int global_block_counter = 0;\n    assign_block_numbers(blocksA, blocksB, blockDict, block_to_global_number, global_block_counter);\n\n    int n_blocks = global_block_counter;\n    cout << n_blocks << '\\n';\n    // Output for two objects\n    vector<int> out1 = gen_assignment(blocksA, D);\n    vector<int> out2 = gen_assignment(blocksB, D);\n    for(int i=0;i<out1.size();++i) {\n        cout << out1[i];\n        if(i+1!=out1.size()) cout << \" \";\n    }\n    cout << endl;\n    for(int i=0;i<out2.size();++i) {\n        cout << out2[i];\n        if(i+1!=out2.size()) cout << \" \";\n    }\n    cout << endl;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <queue>\n#include <algorithm>\n#include <limits>\n#include <set>\nusing namespace std;\n\nstruct Edge {\n    int u, v, idx;\n    long long w;\n    bool operator<(const Edge& o) const { return w < o.w; }\n};\n\nstruct DSU {\n    vector<int> p;\n    DSU(int n): p(n,-1) {}\n    int find(int x) {\n        while (p[x] >= 0) {\n            if (p[p[x]] >= 0) p[x] = p[p[x]];\n            x = p[x];\n        }\n        return x;\n    }\n    bool unite(int x,int y) {\n        x = find(x);\n        y = find(y);\n        if (x == y) return false;\n        if (p[x] > p[y]) swap(x,y);\n        p[x] += p[y];\n        p[y] = x;\n        return true;\n    }\n};\n\n// Returns indices of edges used and mark in use[]\nvoid build_mst(const vector<Edge>& edges, int N, vector<int>& in_mst, vector<vector<pair<int,int>>>& g) {\n    DSU dsu(N);\n    int cnt = 0;\n    for (auto& e : edges) {\n        if (dsu.unite(e.u, e.v)) {\n            in_mst[e.idx] = 1;\n            g[e.u].emplace_back(e.v, e.idx);\n            g[e.v].emplace_back(e.u, e.idx);\n            if (++cnt == N-1) break;\n        }\n    }\n}\n\n// Returns nodes that can be reached from node 0\nvector<int> get_reachable(const vector<vector<pair<int,int>>>& g){\n    int N = g.size();\n    vector<bool> vis(N, 0);\n    queue<int> q;\n    q.push(0); vis[0]=1;\n    while(!q.empty()){\n        int v = q.front(); q.pop();\n        for(auto& [to, eid]: g[v]){\n            if(!vis[to]){\n                vis[to]=1;\n                q.push(to);\n            }\n        }\n    }\n    vector<int> res;\n    for(int i=0;i<N;++i) if(vis[i]) res.push_back(i);\n    return res;\n}\n\n// Euclidean\ninline int dist(int x0,int y0,int x1,int y1) {\n    return (int)ceil(sqrt(1LL*(x0-x1)*(x0-x1)+1LL*(y0-y1)*(y0-y1)));\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n\n    int N, M, K;\n    cin >> N >> M >> K;\n    vector<pair<int, int>> nodes(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> nodes[i].first >> nodes[i].second;\n    }\n    vector<Edge> edges(M);\n    for (int j = 0; j < M; ++j) {\n        int u, v;\n        long long w;\n        cin >> u >> v >> w;\n        edges[j] = {u-1, v-1, j, w};\n    }\n    vector<pair<int, int>> residents(K);\n    for (int k = 0; k < K; ++k) {\n        cin >> residents[k].first >> residents[k].second;\n    }\n\n    // 1. Build MST for connectivity baseline, then enhance the tree later if wanted\n    vector<int> on(M, 0);\n    sort(edges.begin(), edges.end());\n    vector<vector<pair<int, int>>> g(N);\n    build_mst(edges, N, on, g);\n\n    // BFS from node 0 to get all reachable\n    vector<int> reachable = get_reachable(g);\n\n    // 2. For each node, for each resident, precompute all candidate assignments (within 5000)\n    vector<vector<int>> can_cover(N); // can_cover[i]: residents node i can cover within 5000\n    vector<vector<int>> covering_nodes(K); // covering_nodes[k]: which nodes can cover resident k (within 5000)\n\n    for (int i : reachable) {\n        for (int k = 0; k < K; ++k) {\n            int d = dist(nodes[i].first, nodes[i].second, residents[k].first, residents[k].second);\n            if (d <= 5000) {\n                can_cover[i].push_back(k);\n                covering_nodes[k].push_back(i);\n            }\n        }\n    }\n\n    // 3. Set Cover Heuristic (Greedy)\n    vector<int> Pi(N, 0);\n    vector<bool> covered(K, false);\n    int covered_cnt = 0;\n    set<int> not_covered;\n    for (int k = 0; k < K; ++k) not_covered.insert(k);\n\n    while (!not_covered.empty()) {\n        // For each node, for all not-yet-covered residents, compute the maximum distance\n        int best_node = -1, best_num = 0, best_cost = numeric_limits<int>::max(), best_radius = 0;\n        vector<int> best_covers;\n        // Let's try to find the node that covers the most uncovered residents with minimal additional radius^2 cost.\n        for (int i : reachable) {\n            vector<int> candidate; int maxdist = 0;\n            for (int k : can_cover[i]) if (not_covered.count(k)) {\n                int d = dist(nodes[i].first, nodes[i].second, residents[k].first, residents[k].second);\n                candidate.push_back(k);\n                if (d > maxdist) maxdist = d;\n            }\n            if (candidate.empty()) continue;\n            int inc_cost = maxdist*maxdist; // Only consider coverage power, ignore MST edge add cost for now.\n            // Optionally: could prioritize lower inc_cost or most covered\n            if ((int)candidate.size() > best_num ||\n                ((int)candidate.size() == best_num && inc_cost < best_cost)) {\n                best_node = i;\n                best_num = candidate.size();\n                best_cost = inc_cost;\n                best_covers = candidate;\n                best_radius = maxdist;\n            }\n        }\n        // If best_node found, assign\n        if (best_node == -1) break; // Possibly not all can be covered (should not happen)\n        Pi[best_node] = max(Pi[best_node], best_radius);\n        for (int k : best_covers) {\n            not_covered.erase(k);\n            //covered[k] = true;\n        }\n    }\n    // We may have some residents not covered: fallback (should not happen)\n    // For sanity, assign each uncovered resident to closest node as in original solution\n    if (!not_covered.empty()) {\n        for (int k : not_covered) {\n            int best = -1, best_d = 1e9;\n            for (int v : reachable) {\n                int d = dist(nodes[v].first, nodes[v].second, residents[k].first, residents[k].second);\n                if (d < best_d) { best = v; best_d = d;}\n            }\n            if (best != -1) Pi[best] = max(Pi[best], best_d);\n        }\n    }\n\n    // 4. Prune unnecessary Pi's (turn off nodes not needed to cover)\n    vector<bool> still_covered(K, false);\n    for (int i : reachable) if (Pi[i] > 0) {\n        for (int k = 0; k < K; ++k) {\n            int d = dist(nodes[i].first, nodes[i].second, residents[k].first, residents[k].second);\n            if (d <= Pi[i]) still_covered[k] = true;\n        }\n    }\n    // For any node i with Pi[i]>0, try Pi[i]=0 and see if residents remain covered\n    for (int i : reachable) if (Pi[i] > 0) {\n        bool safe = true;\n        vector<int> need_cover;\n        for (int k = 0; k < K; ++k) {\n            int d = dist(nodes[i].first, nodes[i].second, residents[k].first, residents[k].second);\n            if (d <= Pi[i] && still_covered[k]) need_cover.push_back(k);\n        }\n        // Try zeroing Pi[i]\n        for (int k : need_cover) {\n            bool one_covered = false;\n            for (int j : reachable) if (j != i && Pi[j] > 0) {\n                int d = dist(nodes[j].first, nodes[j].second, residents[k].first, residents[k].second);\n                if (d <= Pi[j]) { one_covered = true; break; }\n            }\n            if (!one_covered) { safe = false; break; }\n        }\n        if (safe) Pi[i] = 0;\n    }\n\n    // Output\n    for (int i = 0; i < N; ++i) cout << Pi[i] << (i+1==N ? '\\n' : ' ');\n    for (int j = 0; j < M; ++j) cout << on[j] << (j+1==M ? '\\n' : ' ');\n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <algorithm>\n#include <queue>\n#include <cassert>\n#include <set>\n#include <limits>\nusing namespace std;\n\nconstexpr int N = 30;\nconstexpr int NN = N*(N+1)/2;\nconstexpr int MAX_MOVE = 10000;\n\n// Directions for hex grid\nconst int dx[6] = {-1, -1, 0, 0, 1, 1};\nconst int dy[6] = {-1, 0, -1, 1, 0, 1};\n\n// Adjacency check\ninline bool is_valid(int x, int y) {\n    return 0 <= x && x < N && 0 <= y && y <= x;\n}\n\ninline bool is_adjacent(int x1, int y1, int x2, int y2) {\n    for(int d=0; d<6; ++d) {\n        if(x1+dx[d]==x2 && y1+dy[d]==y2) return true;\n    }\n    return false;\n}\n\n// Children for pyramid\ninline bool has_child(int x, int y) {\n    return x < N-1;\n}\ninline pair<pair<int,int>, pair<int,int>> get_children(int x, int y) {\n    return {{x+1, y}, {x+1, y+1}};\n}\ninline pair<int,int> get_parentL(int x, int y) {\n    return {x-1, y-1};\n}\ninline pair<int,int> get_parentR(int x, int y) {\n    return {x-1, y};\n}\n\n// Move recorder\nstruct MoveRecorder {\n    vector<tuple<int,int,int,int>> moves;\n    int K = 0;\n    vector<vector<int>> &grid;\n    vector<pair<int,int>> &label_pos;\n    MoveRecorder(vector<vector<int>> &g, vector<pair<int,int>> &lp): grid(g), label_pos(lp){}\n\n    void do_swap(int x1, int y1, int x2, int y2) {\n        using std::swap;\n        assert(is_adjacent(x1, y1, x2, y2));\n        swap(grid[x1][y1], grid[x2][y2]);\n        label_pos[grid[x1][y1]] = {x1, y1};\n        label_pos[grid[x2][y2]] = {x2, y2};\n        moves.emplace_back(x1, y1, x2, y2);\n        K++;\n    }\n};\n\n// Count heap violations\nint count_violation(const vector<vector<int>> &grid) {\n    int res = 0;\n    for (int x = 0; x < N-1; ++x) {\n        for (int y = 0; y <= x; ++y) {\n            auto [l, r] = get_children(x,y);\n            if(grid[x][y] > grid[l.first][l.second]) res++;\n            if(grid[x][y] > grid[r.first][r.second]) res++;\n        }\n    }\n    return res;\n}\n\n// Path-find between two positions: \"move value from pos_from to pos_to by legal swaps\"\n// Returns path (including start, not necessarily end), or empty vector if not found\nvector<pair<int,int>> bfs_path(const vector<vector<int>> &grid, pair<int,int> from, pair<int,int> to, int max_depth=20) {\n    queue<vector<pair<int,int>>> q;\n    set<pair<int,int>> vis;\n    q.push({from});\n    vis.insert(from);\n\n    while(!q.empty()) {\n        auto path = q.front(); q.pop();\n        auto [x, y] = path.back();\n        if(path.size() > max_depth+1) continue;\n        if(make_pair(x,y)==to) return path;\n\n        for(int d=0; d<6; ++d) {\n            int nx=x+dx[d], ny=y+dy[d];\n            if(is_valid(nx,ny) && !vis.count({nx,ny})) {\n                vis.insert({nx,ny});\n                auto np = path;\n                np.emplace_back(nx,ny);\n                q.push(np);\n            }\n        }\n    }\n    return {};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    // Read input\n    vector<vector<int>> grid(N);\n    vector<pair<int,int>> label_pos(NN); // label -> pos\n    for(int x=0; x<N; ++x) {\n        grid[x].resize(x+1);\n        for(int y=0; y<=x; ++y) {\n            cin >> grid[x][y];\n            label_pos[grid[x][y]] = {x, y};\n        }\n    }\n    MoveRecorder recorder(grid, label_pos);\n\n    // Parameters\n    int max_pass = 9; // total main passes to alternate\n    int max_bfs_depth = 12; // for targeted fixer\n    int max_bfs_rep = 130;  // targeted fix trials\n\n    // Phase 1: Repeated top-down and bottom-up bubble passes\n    for(int pass = 0; pass < max_pass && recorder.K < MAX_MOVE; ++pass) {\n        bool changed = false;\n\n        // Top-down bubble-down (like heapify)\n        for(int x=0; x<N-1 && recorder.K < MAX_MOVE; ++x) {\n            for(int y=0; y<=x && recorder.K < MAX_MOVE; ++y) {\n                int v = grid[x][y];\n                auto [l, r] = get_children(x, y);\n                int lval = grid[l.first][l.second];\n                int rval = grid[r.first][r.second];\n                // Bubble-down if parent > any child\n                if(v > lval || v > rval) {\n                    int cx = x, cy = y;\n                    while(cx < N-1 && recorder.K < MAX_MOVE) {\n                        auto [cl, cr] = get_children(cx, cy);\n                        int c1x=cl.first, c1y=cl.second, c2x=cr.first, c2y=cr.second;\n                        int child1 = grid[c1x][c1y], child2 = grid[c2x][c2y];\n                        // Find smaller child (to bring up lower values)\n                        if(grid[c1x][c1y] < grid[c2x][c2y]) {\n                            if(grid[c1x][c1y] < grid[cx][cy]) {\n                                recorder.do_swap(cx, cy, c1x, c1y);\n                                cx = c1x; cy = c1y;\n                                changed = true;\n                            } else break;\n                        } else {\n                            if(grid[c2x][c2y] < grid[cx][cy]) {\n                                recorder.do_swap(cx, cy, c2x, c2y);\n                                cx = c2x; cy = c2y;\n                                changed = true;\n                            } else break;\n                        }\n                    }\n                }\n            }\n        }\n        // Bottom-up bubble-up (swap upwards if child < parent)\n        for(int x=N-1; x>0 && recorder.K < MAX_MOVE; --x) {\n            for(int y=0; y<=x; ++y) {\n                int cur = grid[x][y];\n                if(y > 0) {\n                    auto [px, py] = get_parentL(x, y);\n                    if(is_valid(px, py) && grid[px][py] > cur) {\n                        int cx = x, cy = y;\n                        while(cx > 0 && recorder.K < MAX_MOVE) {\n                            auto [plx, ply] = get_parentL(cx, cy);\n                            if(is_valid(plx, ply) && grid[plx][ply] > grid[cx][cy]) {\n                                recorder.do_swap(plx, ply, cx, cy);\n                                cx = plx; cy = ply;\n                                changed = true;\n                            } else break;\n                        }\n                    }\n                }\n                if(y < x) {\n                    auto [px, py] = get_parentR(x, y);\n                    if(is_valid(px, py) && grid[px][py] > cur) {\n                        int cx = x, cy = y;\n                        while(cx > 0 && recorder.K < MAX_MOVE) {\n                            auto [prx, pry] = get_parentR(cx, cy);\n                            if(is_valid(prx, pry) && grid[prx][pry] > grid[cx][cy]) {\n                                recorder.do_swap(prx, pry, cx, cy);\n                                cx = prx; cy = pry;\n                                changed = true;\n                            } else break;\n                        }\n                    }\n                }\n            }\n        }\n        if(!changed) break;\n    }\n\n    // Phase 2: Targeted Fixing for remaining violations\n    // Build violation list\n    vector<tuple<int,int,int,int>> violations;\n    for (int x = 0; x < N-1; ++x)\n        for (int y = 0; y <= x; ++y) {\n            auto [l, r] = get_children(x, y);\n            if(grid[x][y] > grid[l.first][l.second]) violations.emplace_back(x, y, l.first, l.second);\n            if(grid[x][y] > grid[r.first][r.second]) violations.emplace_back(x, y, r.first, r.second);\n        }\n\n    // Prioritize violations closer to the root\n    sort(violations.begin(), violations.end()); // upper rows first\n\n    int bfs_rep = 0;\n    for(const auto &[x1, y1, x2, y2] : violations) {\n        if(recorder.K >= MAX_MOVE) break;\n        if(grid[x1][y1] <= grid[x2][y2]) continue; // already fixed\n        // Try to move the smaller value from (x2,y2) to (x1,y1) upwards\n        auto path = bfs_path(grid, {x2,y2}, {x1,y1}, max_bfs_depth);\n        if(!path.empty() && path.size() > 1 && (int)path.size()-1 + recorder.K < MAX_MOVE) {\n            // Perform the path in reverse: swap each with its predecessor\n            for(int i=(int)path.size()-2; i >=0; --i) {\n                auto [xa, ya] = path[i+1];\n                auto [xb, yb] = path[i];\n                recorder.do_swap(xa, ya, xb, yb);\n            }\n        }\n        ++bfs_rep;\n        if(bfs_rep>max_bfs_rep) break; // limit for efficiency/speed\n    }\n\n    // Output\n    cout << recorder.K << '\\n';\n    for(const auto &m: recorder.moves) {\n        int x1, y1, x2, y2;\n        tie(x1, y1, x2, y2) = m;\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << '\\n';\n    }\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int D = 9;\nconstexpr int ENTRANCE_I = 0;\nconstexpr int ENTRANCE_J = (D-1)/2;\nconst int di[] = {-1,1,0,0}, dj[] = {0,0,-1,1};\n\nstruct Cell {\n    int i, j;\n    Cell(int i=0, int j=0):i(i),j(j){}\n    bool operator==(const Cell& o) const { return i==o.i && j==o.j; }\n    bool operator!=(const Cell& o) const { return !(*this==o); }\n};\n\nostream& operator<<(ostream& os, const Cell& c) {\n    return os << c.i << ' ' << c.j;\n}\n\nbool in_grid(int i, int j) {\n    return 0 <= i && i < D && 0 <= j && j < D;\n}\n\nvector<Cell> adj4(Cell c) {\n    vector<Cell> v;\n    for(int d=0;d<4;++d) {\n        int ni = c.i+di[d], nj = c.j+dj[d];\n        if(in_grid(ni,nj)) v.emplace_back(ni,nj);\n    }\n    return v;\n}\n\n// For quickly assigning container numbers to positions.\nstruct WarehouseSolver {\n    int N;\n    set<Cell> obstacles;\n    set<Cell> not_assignable; // entrance + 3 adjacents + obstacles\n    vector<Cell> assignable_cells; // order by BFS from entrance\n    map<Cell, int> cell_to_bfs_layer;\n\n    // Storage state\n    vector<pair<int,int>> arrivals; // (container number, arrival idx)\n    map<Cell, int> assigned_cell_to_num;\n    map<int, Cell> num_to_cell;\n\n    // Extraction ordering\n    vector<Cell> extraction_order;\n\n    WarehouseSolver() {}\n\n    void initialize() {\n        // Build not_assignable: entrance & its 3 adjacents & obstacles\n        not_assignable.insert(Cell(ENTRANCE_I, ENTRANCE_J));\n        for(int d=0;d<4;++d) {\n            int ni = ENTRANCE_I+di[d], nj = ENTRANCE_J+dj[d];\n            if(in_grid(ni,nj))\n                not_assignable.insert(Cell(ni,nj));\n        }\n        for(auto c: obstacles) not_assignable.insert(c);\n\n        // BFS from entrance to get \"ranked\" assignable cells\n        vector<vector<int>> vis(D, vector<int>(D, -1));\n        queue<Cell> q;\n        q.push(Cell(ENTRANCE_I, ENTRANCE_J));\n        vis[ENTRANCE_I][ENTRANCE_J]=0;\n        int dist = 1;\n        // Pre-mark not_assignable so we don't revisit\n        for(auto c: not_assignable) vis[c.i][c.j]=-2;\n        vis[ENTRANCE_I][ENTRANCE_J]=0; // entrance\n\n        vector<Cell> order;\n        while(!q.empty()) {\n            Cell c = q.front();q.pop();\n            for(auto d: adj4(c)) {\n                if(vis[d.i][d.j] == -1) {\n                    vis[d.i][d.j] = vis[c.i][c.j]+1;\n                    q.push(d);\n                    // If it's assignable (not in not_assignable), add to order\n                    if(not_assignable.count(d) == 0) {\n                        assignable_cells.push_back(d);\n                        cell_to_bfs_layer[d] = vis[d.i][d.j];\n                    }\n                }\n            }\n        }\n    }\n\n    void read_input() {\n        cin >> N;\n        for(int k=0;k<N;++k) {\n            int ri,rj;\n            cin >> ri >> rj;\n            obstacles.insert(Cell(ri,rj));\n        }\n        initialize();\n    }\n\n    void assign_container(int t_d, int arrival_idx) {\n        // Add to arrivals\n        arrivals.emplace_back(t_d, arrival_idx);\n        // We need to select an assignable cell for it.\n\n        // For containers arrived so far, make a sorted list\n        vector<pair<int,int>> sorted_arrivals = arrivals;\n        sort(sorted_arrivals.begin(), sorted_arrivals.end()); // by t_d\n        // Their optimal mapping: map sorted_arrivals[i] to assignable_cells[i]\n        // For current container (arrival_idx), find where it lands\n        int pos = -1;\n        for(int i=0;i<sorted_arrivals.size();++i) {\n            if(sorted_arrivals[i].second == arrival_idx) {\n                pos = i;\n                break;\n            }\n        }\n        assert(pos != -1);\n\n        // Some assignable_cells may already be assigned: must choose the first unassigned slot corresponding to pos (since in rare cases, due to obstacles, not all cells may be left)\n        vector<bool> used(assignable_cells.size(), false);\n        for(auto& kv: assigned_cell_to_num) {\n            // Mark which slots are taken\n            for(int i=0;i<assignable_cells.size();++i) {\n                if(assignable_cells[i]==kv.first) used[i]=true;\n            }\n        }\n        // Assign in sorted order: for the list of arrivals (sorting by t_d), map to available slots in assignable_cells in order, skipping used ones.\n        int assign_slot = -1, cnt = 0;\n        for(int i=0;i<assignable_cells.size();++i) {\n            if(used[i]) continue;\n            if(cnt==pos) { assign_slot=i; break; }\n            cnt++;\n        }\n        assert(assign_slot != -1);\n        Cell assign_cell = assignable_cells[assign_slot];\n\n        // Assign this cell to the container num\n        assigned_cell_to_num[assign_cell] = t_d;\n        num_to_cell[t_d] = assign_cell;\n\n        // Output assignment\n        cout << assign_cell.i << \" \" << assign_cell.j << endl;\n        cout.flush();\n    }\n\n    // After all containers are placed, plan extraction order.\n    void plan_extraction() {\n        // Build grid state: 0=empty, -1=obstacle, >0=container num+1\n        vector<vector<int>> grid(D, vector<int>(D,0));\n        for(auto c: obstacles) grid[c.i][c.j]=-1;\n        for(auto& [cell, num]: assigned_cell_to_num) grid[cell.i][cell.j]=num+1;\n\n        set<int> remaining_nums;\n        for(auto& [num, cell]: num_to_cell) remaining_nums.insert(num);\n\n        extraction_order.clear();\n\n        for(int step=0;step < num_to_cell.size(); ++step) {\n            // Find all containers (cells with grid>0) reachable from entrance\n            queue<Cell> q;\n            vector<vector<bool>> vis(D,vector<bool>(D,false));\n            q.push(Cell(ENTRANCE_I, ENTRANCE_J));\n            vis[ENTRANCE_I][ENTRANCE_J]=true;\n\n            set<Cell> reachable;\n            while(!q.empty()) {\n                Cell c = q.front();q.pop();\n                for(auto d: adj4(c)) {\n                    if(!vis[d.i][d.j]) {\n                        if(grid[d.i][d.j] == 0) {\n                            vis[d.i][d.j]=true;q.push(d);\n                        } else if(grid[d.i][d.j]>0) {\n                            // It's a container\n                            reachable.insert(d);\n                        }\n                    }\n                }\n            }\n            // From reachable, pick container with smallest num\n            int best_num = 1e9;\n            Cell best_cell;\n            for(auto c: reachable) {\n                int num = grid[c.i][c.j]-1;\n                if(num < best_num) { best_num = num; best_cell = c; }\n            }\n            extraction_order.push_back(best_cell);\n\n            // Remove this from grid\n            grid[best_cell.i][best_cell.j] = 0;\n            remaining_nums.erase(best_num);\n        }\n    }\n\n    void output_extraction_order() {\n        for(auto& c: extraction_order) {\n            cout << c.i << \" \" << c.j << endl;\n        }\n        cout.flush();\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D_input, N;\n    cin >> D_input >> N;\n    assert(D_input==D);\n\n    WarehouseSolver solver;\n    solver.N=N;\n    for(int k=0;k<N;++k) {\n        int ri,rj; cin >> ri >> rj;\n        solver.obstacles.insert(Cell(ri,rj));\n    }\n    solver.initialize(); // needs to be called after obstacles are set up\n\n    const int K = D*D-1-N;\n    for(int d=0; d<K; ++d) {\n        int t_d; cin >> t_d;\n        solver.assign_container(t_d, d);\n    }\n    // After all placements\n    solver.plan_extraction();\n    solver.output_extraction_order();\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 50, M = 100, COLORS = 101;\nint n, m;\nint c[N][N];\n\n// For each color, set of adjacent colors (including 0)\nvector<set<int>> adjacency(COLORS);\n// Whether color c touches the edge (adjacent to outside/0)\nvector<bool> touches0(COLORS);\n\n// For output\nint d[N][N];\n\n// Direction vectors\nconstexpr int di[] = {-1, 0, 1, 0};\nconstexpr int dj[] = {0, 1, 0, -1};\n\n// Compose adjacency graph for all colors from input\nvoid build_adjacency() {\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j) {\n            int col = c[i][j];\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir], nj = j + dj[dir];\n                if (ni < 0 || nj < 0 || ni >= n || nj >= n) {\n                    adjacency[col].insert(0);\n                    adjacency[0].insert(col);\n                    touches0[col] = true;\n                } else if (c[ni][nj] != col) {\n                    adjacency[col].insert(c[ni][nj]);\n                }\n            }\n        }\n}\n\n// List of wards (colors)\nvector<int> all_wards() {\n    vector<int> wards;\n    for (int i = 1; i <= m; ++i) wards.push_back(i);\n    return wards;\n}\n\n// Assign output locations for each ward (color)\n// Ensures border-wards go to boundary.\nmap<int, pair<int,int>> assign_ward_positions(const vector<int>& wards) {\n    map<int,pair<int,int>> pos;\n    set<pair<int,int>> used;\n    // 1. Lay out border-wards\n    vector<pair<int,int>> border_spots;\n    for (int i = 0; i < n; ++i) {\n        border_spots.emplace_back(0, i);\n        border_spots.emplace_back(n-1, i);\n    }\n    for (int j = 1; j < n-1; ++j) {\n        border_spots.emplace_back(j, 0);\n        border_spots.emplace_back(j, n-1);\n    }\n    int bi = 0;\n\n    // 2. Inner spots for rest\n    vector<pair<int,int>> inner_spots;\n    for (int i = 1; i < n-1; ++i)\n        for (int j = 1; j < n-1; ++j)\n            inner_spots.emplace_back(i,j);\n    int ii = 0;\n\n    // Wards sorted: priority to those with more adjacents\n    vector<int> order = wards;\n    sort(order.begin(), order.end(), [](int a, int b) {\n        return adjacency[a].size() > adjacency[b].size();\n    });\n\n    for (int ward : order) {\n        if (touches0[ward] && bi < (int)border_spots.size()) {\n            // Assign to border\n            pos[ward] = border_spots[bi++];\n            used.insert(pos[ward]);\n        } else if (ii < (int)inner_spots.size()) {\n            pos[ward] = inner_spots[ii++];\n            used.insert(pos[ward]);\n        } else {\n            // fallback (should not happen)\n            pos[ward] = make_pair(0,0);\n        }\n    }\n    return pos;\n}\n\n// Fill in the output grid according to assigned ward positions and enforce adjacency requirements.\nvoid build_output_map(const map<int, pair<int,int>>& ward_pos) {\n    // Clear to zero\n    for (int i=0;i<n;++i) for (int j=0;j<n;++j) d[i][j]=0;\n\n    // Place all the wards in their assigned cell\n    for (const auto& [ward, p] : ward_pos) {\n        d[p.first][p.second] = ward;\n    }\n\n    // Now, for each adjacency, ensure the pair is represented by a pair of adjacent cells on the grid.\n    // Try to do this with minimal area addition.\n    for (int c = 1; c <= m; ++c) {\n        for (int dcol : adjacency[c]) {\n            if (dcol < c) continue; // Each pair once (and skip dcol=0 for now, handlded by positions on boundary)\n\n            auto [ci, cj] = ward_pos.at(c);\n            auto [di_, dj_] = ward_pos.at(dcol);\n\n            // Are they adjacent in the grid?\n            if (abs(ci-di_)+abs(cj-dj_) ==1) continue;\n\n            // Otherwise, connect them along Manhattan path with their own colors\n            int curi = ci, curj = cj;\n            // Let's make a path from (ci,cj) to (di_,dj_) (no '0' along the way)\n            while (curi != di_) {\n                curi += (di_ > curi) ? 1 : -1;\n                if (d[curi][curj] == 0)\n                    d[curi][curj] = c;\n            }\n            while (curj != dj_) {\n                curj += (dj_ > curj) ? 1 : -1;\n                if (d[curi][curj] == 0)\n                    d[curi][curj] = c;\n            }\n        }\n    }\n}\n\n// Validation helpers (not used in contest submission)\n// Check all same-color cells are connected (DFS)\n// Check adjacencies\n\n// Full solution\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    n = N; m = M;\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j)\n            cin >> c[i][j];\n\n    adjacency.assign(COLORS, set<int>());\n    touches0.assign(COLORS, false);\n\n    build_adjacency();\n\n    vector<int> wards = all_wards();\n\n    auto ward_pos = assign_ward_positions(wards);\n\n    build_output_map(ward_pos);\n\n    // Output result\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cout << d[i][j] << \" \\n\"[j==n-1];\n        }\n    }\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nvoid fastio() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); }\nvoid flush() { cout.flush(); }\n\n// --------------- Definitions --------------\nint N, D, Q;  // Number, Divisions, Queries\nint query_count = 0;\n\n// Ask a balance between L and R, return -1 (L<R), 0 (=), 1 (L>R)\nint askBalance(const vector<int>& L, const vector<int>& R) {\n    assert(!L.empty() && !R.empty());\n    assert(query_count < Q);\n    cout << L.size() << \" \" << R.size() << \" \";\n    for (int x : L) cout << x << \" \";\n    for (int x : R) cout << x << \" \";\n    cout << \"\\n\";\n    flush();\n    string s; cin >> s;\n    query_count++;\n    if (s == \"<\") return -1;\n    else if (s == \"=\") return 0;\n    else if (s == \">\") return 1;\n    else {\n        cerr << \"Unknown judge response: \" << s << endl;\n        exit(1);\n    }\n}\n\n// Tournament-based win scores\nvector<int> get_win_scores(int N, int Q) {\n    vector<int> win_count(N, 0);\n    vector<vector<int>> compared(N, vector<int>(N, 0)); // 0: not yet, 1: compared\n\n    int max_pairs = Q;\n    // Enumerate all unordered pairs, random order for coverage\n    vector<pair<int,int>> pairs;\n    for (int i = 0; i < N; ++i) {\n        for (int j = i+1; j < N; ++j) {\n            pairs.emplace_back(i, j);\n        }\n    }\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    shuffle(pairs.begin(), pairs.end(), rng);\n\n    int used = 0;\n    for (auto &[i, j]: pairs) {\n        if (used >= max_pairs) break;\n        int res = askBalance({i}, {j});\n        if (res == 1) { win_count[i]++; }\n        else if (res == -1) { win_count[j]++; }\n        // in case of tie (rare), do nothing (or +0.5 to both if desired)\n        // compared[i][j] = compared[j][i] = 1;\n        used++;\n    }\n    return win_count;\n}\n\n// Assign heavy items to lightest groups, greedy stratified assign\nvector<int> assign_to_groups_by_score(const vector<int>& score) {\n    int N = score.size();\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    // Highest win_count first\n    sort(idx.begin(), idx.end(), [&](int i, int j){ return score[i] > score[j]; });\n\n    vector<long long> group_score(D, 0);\n    vector<int> assign(N, -1);\n    for (int t = 0; t < N; ++t) {\n        int i = idx[t];\n        if (t < D) {\n            assign[i] = t; // ensure each group gets at least 1 item\n            group_score[t] += score[i];\n        } else {\n            // assign to current lowest group\n            int gid = min_element(group_score.begin(), group_score.end()) - group_score.begin();\n            assign[i] = gid;\n            group_score[gid] += score[i];\n        }\n    }\n    return assign;\n}\n\nint main() {\n    fastio();\n    cin >> N >> D >> Q;\n\n    // 1. Use up to Q pairwise queries to collect win data\n    vector<int> win_score = get_win_scores(N, Q);\n\n    // 2. Assign by greedy\n    vector<int> assign = assign_to_groups_by_score(win_score);\n\n    // 3. Output\n    for (int i = 0; i < N; ++i) {\n        cout << assign[i] << (i+1 == N ? '\\n' : ' ');\n    }\n    flush();\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 200;\nconstexpr int M = 10;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int n, m;\n    cin >> n >> m;\n    assert(n == 200 && m == 10);\n\n    vector<vector<int>> stacks(m); // [stack][bottom..top]\n    vector<pair<int,int>> box_pos(n+1); // [box] -> (stack_id, pos_from_bottom)\n\n    for (int i = 0; i < m; ++i) {\n        stacks[i].resize(n/m);\n        for (int j = 0; j < n/m; ++j) {\n            cin >> stacks[i][j];\n            box_pos[stacks[i][j]] = {i, j};\n        }\n    }\n\n    vector<pair<int, int>> ops; // operations: (v, stack_id), stack_id==0 for carry out\n\n    // For each number to be carried out in order\n    vector<int> stack_pointer(m, 0); // number of boxes taken out from bottom of each stack\n\n    for (int target = 1; target <= n; ++target) {\n        // Find where the target box is\n        pair<int,int> pos = box_pos[target];\n        int s = pos.first, idx = pos.second;\n\n        // Since boxes are only removed from top, need to adjust for boxes already taken out from this stack\n        int logical_pos = idx - stack_pointer[s];\n        int stack_size = stacks[s].size();\n\n        // If it's at the top of its stack (adjusted)\n        if (logical_pos == (int)stacks[s].size() - 1) {\n            // Output: (target, 0)\n            ops.emplace_back(target, 0);\n            // Remove from stack\n            stacks[s].pop_back();\n            stack_pointer[s]++;\n        } else {\n            // Need to move [logical_pos, end] to another stack\n            vector<int> to_move;\n            for (int j = logical_pos; j < (int)stacks[s].size(); ++j) to_move.push_back(stacks[s][j]);\n            \n            // Remove from source stack\n            stacks[s].resize(logical_pos);\n\n            // Invalidate pointer for moved boxes\n            for (int box : to_move) box_pos[box] = {-1, -1};\n\n            // Select destination stack (shortest, not s)\n            int dest = -1, minsize = INT_MAX;\n            for (int i = 0; i < m; ++i) {\n                if (i == s) continue;\n                if ((int)stacks[i].size() < minsize) {\n                    minsize = (int)stacks[i].size();\n                    dest = i;\n                }\n            }\n\n            // Place chunk to target stack\n            for (int box : to_move) {\n                stacks[dest].push_back(box);\n            }\n            // Update positions for moved boxes\n            int sz = stacks[dest].size();\n            for (int j = 0; j < (int)to_move.size(); ++j) {\n                box_pos[to_move[j]] = {dest, sz - (int)to_move.size() + j};\n            }\n\n            // Output operation: (target, dest+1)\n            ops.emplace_back(target, dest+1);\n        restart: // We'll loop back as the box may need carry operation in next iteration\n            // Try again in next loop, as now it should be on top at dest stack\n            target--;\n        }\n    }\n    // Output\n    for (auto [v, i] : ops) cout << v << \" \" << i << \"\\n\";\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nconstexpr int di[4] = {-1, 1, 0, 0};\nconstexpr int dj[4] = {0, 0, -1, 1};\nconstexpr char DIR[4] = {'U', 'D', 'L', 'R'};\nconstexpr char INV_DIR[4] = {'D', 'U', 'R', 'L'};\n\nint N;\nvector<string> hwall, vwall;\nvector<vector<int>> dirt;\n\n// Store reconstructed path\nstring path;\n\n// Used for visiting\nvector<vector<bool>> vis;\n\n// For output movement\nstruct Move {\n    int i, j;  // position after move\n    char dir;  // move direction to here\n};\n\nstruct Cell {\n    int i, j, d;\n    bool operator<(const Cell &rhs) const { return d > rhs.d; }\n};\nvector<Cell> cells_by_dirt;\n\ninline bool in_grid(int i, int j) {\n    return 0 <= i && i < N && 0 <= j && j < N;\n}\n\nbool can_move(int i, int j, int dir) {\n    int ni = i + di[dir], nj = j + dj[dir];\n    if (!in_grid(ni, nj)) return false;\n    if (dir == 0) {  // U\n        return hwall[ni][nj] == '0';\n    }\n    if (dir == 1) {  // D\n        return hwall[i][j] == '0';\n    }\n    if (dir == 2) {  // L\n        return vwall[ni][nj] == '0';\n    }\n    if (dir == 3) {  // R\n        return vwall[i][j] == '0';\n    }\n    return false;\n}\n\n/**\n * Enhanced DFS: Recursively traverse unvisited neighbors, preferring high dirtiness.\n */\nvoid dfs(int i, int j) {\n    vis[i][j] = true;\n    // Make a list of neighbor candidates, sort by dirtiness\n    vector<pair<int, int>> nbrs;\n    for (int dir = 0; dir < 4; ++dir) {\n        int ni = i + di[dir], nj = j + dj[dir];\n        if (in_grid(ni, nj) && !vis[ni][nj] && can_move(i, j, dir)) {\n            nbrs.emplace_back(dirt[ni][nj], dir);\n        }\n    }\n    // Prefer higher d neighbors\n    sort(nbrs.rbegin(), nbrs.rend());\n\n    for (auto &[dval, dir] : nbrs) {\n        int ni = i + di[dir], nj = j + dj[dir];\n        path.push_back(DIR[dir]);\n        dfs(ni, nj);\n        path.push_back(INV_DIR[dir]);\n    }\n}\n\n// Add detour loops at high-dirt cells, if budget allows\nvoid insert_high_dirt_loops(int maxLength) {\n    // Top K highest dirt cells\n    int K = min(7, N*N/8);\n    vector<pair<int, int>> loopcells;\n    for (int i = 0; i < K && i < int(cells_by_dirt.size()); ++i) {\n        if (cells_by_dirt[i].i == 0 && cells_by_dirt[i].j == 0) continue;\n        loopcells.emplace_back(cells_by_dirt[i].i, cells_by_dirt[i].j);\n    }\n    // Try to insert short 'loops' around those\n    int insertions = 0;\n    vector<int> insert_pos;\n\n    // Find all path positions at high-dirt cells\n    for (auto &[ci, cj] : loopcells) {\n        for (int idx = 0, pi = 0, pj = 0; idx < int(path.size()); ++idx) {\n            int oldi = pi, oldj = pj;\n            if (path[idx] == 'U') --pi;\n            else if (path[idx] == 'D') ++pi;\n            else if (path[idx] == 'L') --pj;\n            else if (path[idx] == 'R') ++pj;\n            if (pi == ci && pj == cj) {\n                insert_pos.push_back(idx);\n                break;\n            }\n        }\n    }\n\n    // Insert loops (for each, try to find a local 2-move cycle)\n    for (int posidx = 0; posidx < (int)insert_pos.size(); ++posidx) {\n        int insert_at = insert_pos[posidx];\n        int ci = loopcells[posidx].first, cj = loopcells[posidx].second;\n        // Look for a neighbor (not a wall), not out of bounds\n        for (int dir = 0; dir < 4; ++dir) {\n            int ni = ci + di[dir], nj = cj + dj[dir];\n            if (!in_grid(ni, nj)) continue;\n            if (!can_move(ci, cj, dir)) continue;\n            // Insert: go to neighbor and return\n            if ((int)path.size() + 2 <= maxLength) {\n                path.insert(insert_at, 1, DIR[dir]);\n                path.insert(insert_at + 1, 1, INV_DIR[dir]);\n                insert_at += 2;\n                insertions++;\n            }\n            break; // only one for now\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    hwall.resize(N - 1);\n    for (int i = 0; i < N - 1; ++i) cin >> hwall[i];\n    vwall.resize(N);\n    for (int i = 0; i < N; ++i) cin >> vwall[i];\n    dirt.resize(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) cin >> dirt[i][j];\n\n    // Build cell list by dirt\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cells_by_dirt.push_back(Cell{i, j, dirt[i][j]});\n    sort(cells_by_dirt.begin(), cells_by_dirt.end());\n\n    // DFS-based path\n    vis.assign(N, vector<bool>(N, false));\n    dfs(0,0);\n\n    // Ensure we return to (0,0)\n    assert(vis[0][0]);\n    // Optionally: prune if exceeds 100000\n    int maxLength = 100000;\n    if ((int)path.size() > maxLength) {\n        path = path.substr(0, maxLength); // guarantee legality\n    } else if ((int)path.size() < maxLength - 20) {\n        // Try to insert some detour loops at top dirt cells\n        insert_high_dirt_loops(maxLength);\n    }\n    cout << path << endl;\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 15;\n\n// Function to find greatest overlap (suffix of a with prefix of b)\nint calc_overlap(const string &a, const string &b) {\n    int maxl = min(a.size(), b.size());\n    for (int len = maxl; len; --len)\n        if (a.substr(a.size() - len, len) == b.substr(0, len))\n            return len;\n    return 0;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int n, m, si, sj;\n    cin >> n >> m >> si >> sj;\n\n    vector<string> grid(n);\n    for (int i = 0; i < n; ++i) cin >> grid[i];\n\n    // Build position list for each letter\n    vector<pair<int, int>> letter_pos[26];\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j)\n            letter_pos[grid[i][j] - 'A'].emplace_back(i, j);\n\n    vector<string> words(m);\n    for (int i = 0; i < m; ++i) cin >> words[i];\n\n    // --- Greedy Minimum Superstring (pairwise) ---\n    // We'll use a merging system: keep all current fragments in a list\n    vector<string> curr_words = words;\n    int step = 0;\n    while (curr_words.size() > 1) {\n        int best_i = -1, best_j = -1, best_ov = -1;\n        // Overlap from i (suffix) to j (prefix)\n        for (int i = 0; i < int(curr_words.size()); ++i) {\n            for (int j = 0; j < int(curr_words.size()); ++j) {\n                if (i == j) continue;\n                int ov = calc_overlap(curr_words[i], curr_words[j]);\n                if (ov > best_ov) {\n                    best_ov = ov;\n                    best_i = i;\n                    best_j = j;\n                }\n            }\n        }\n        // If cannot overlap at all, arbitrarily merge first two\n        if (best_ov <= 0) best_i = 0, best_j = 1, best_ov = 0;\n\n        // Merge: curr_words[best_i] + (suffix of curr_words[best_j])\n        string merged = curr_words[best_i] + curr_words[best_j].substr(best_ov);\n        vector<string> new_words;\n        // Keep all except best_i and best_j\n        for (int i = 0; i < int(curr_words.size()); ++i) {\n            if (i != best_i && i != best_j)\n                new_words.push_back(curr_words[i]);\n        }\n        new_words.push_back(merged);\n        curr_words.swap(new_words);\n\n        // Optionally, stop early if we're over length budget\n        if (curr_words[0].size() > 5000) break;\n        step++;\n    }\n    string superstring = curr_words[0];\n    if (superstring.size() > 5000) superstring = superstring.substr(0, 5000);\n\n    // --- Route: nearest key for each letter ---\n    vector<pair<int, int>> route;\n    int ci = si, cj = sj;\n    for (char ch : superstring) {\n        int c = ch - 'A';\n        int mincost = 1e9, picki = -1, pickj = -1;\n        for (auto &[ni, nj] : letter_pos[c]) {\n            int delta = abs(ci - ni) + abs(cj - nj);\n            if (delta < mincost) {\n                mincost = delta;\n                picki = ni;\n                pickj = nj;\n            }\n        }\n        route.emplace_back(picki, pickj);\n        ci = picki;\n        cj = pickj;\n    }\n\n    for (auto &[i, j] : route) cout << i << \" \" << j << '\\n';\n\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*\n Polyomino Identification via placement elimination (drill-based)\n - For each oil field, generate all possible translations of the shape within bounds.\n - For each oil field, maintain list of possible placements (\"alive\").\n - After each drill (q 1 i j), prune inconsistent placements.\n - When, for all oil fields, there is only one live placement, union them and output as the set with v(i,j)>0.\n*/\n\nconstexpr int DX[4] = {-1,1,0,0};\nconstexpr int DY[4] = {0,0,-1,1};\n\nstruct Polyomino {\n    vector<pair<int,int>> cells; // relative coordinates from (0,0)\n    int h=0, w=0; // bounding box size\n    vector<vector<pair<int,int>>> placements; // all placements (cells in board coord)\n};\n\nint N, M;\ndouble eps;\nvector<Polyomino> oil_fields;\n\n// For each oil field, available placements, as indices into oil_fields[k].placements.\nvector<vector<int>> alivePlacements;\n\nvector<vector<int>> drillValue; // -1=unknown, >=0 revealed\n\n// Construct all legal placements for each polyomino\nvoid enumerate_placements() {\n    for (auto& poly : oil_fields) {\n        // Find bounding box\n        int min_i=1e9,min_j=1e9,max_i=-1e9,max_j=-1e9;\n        for (auto [x, y]: poly.cells) {\n            min_i = min(min_i, x);\n            max_i = max(max_i, x);\n            min_j = min(min_j, y);\n            max_j = max(max_j, y);\n        }\n        poly.h = max_i+1;\n        poly.w = max_j+1;\n        // All valid translations\n        for (int base_i=0; base_i+poly.h <= N; ++base_i) {\n            for (int base_j=0; base_j+poly.w <= N; ++base_j) {\n                vector<pair<int,int>> placement;\n                for (auto [di,dj]: poly.cells) {\n                    placement.emplace_back(base_i+di, base_j+dj);\n                }\n                poly.placements.push_back(placement);\n            }\n        }\n    }\n}\n\n// For fast cell lookup: for each oil field, for each placement, set of covered cells\n// As well as, for each (cell), which (field,placement) cover it (may not be needed for initial version)\n\n// Remove placements inconsistent with known drill values\n// Returns true if at least one placement was eliminated\nbool update_alivePlacements() {\n    bool changed = false;\n    for (int f=0; f<M; ++f) {\n        vector<int> updated;\n        for (int pi : alivePlacements[f]) {\n            const auto& placement = oil_fields[f].placements[pi];\n            bool ok = true;\n            for (auto [ci, cj]: placement) {\n                if (drillValue[ci][cj] != -1 && drillValue[ci][cj] == 0) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) updated.push_back(pi);\n        }\n        if (updated.size() != alivePlacements[f].size()) changed = true;\n        alivePlacements[f] = move(updated);\n    }\n    return changed;\n}\n\n// Sum over all alive placements, for each cell, count how many can have oil (for heuristic)\nvector<vector<int>> plausible_oil_counts() {\n    vector<vector<int>> cnt(N, vector<int>(N));\n    for (int f=0; f<M; ++f) {\n        for (int pi: alivePlacements[f]) {\n            for (auto [ci,cj]: oil_fields[f].placements[pi]) {\n                cnt[ci][cj]++;\n            }\n        }\n    }\n    return cnt;\n}\n\n// Helper: print and flush\nvoid do_query(const string& s) {\n    cout << s << endl;\n    cout << flush;\n}\n\n// Greedy\u2013drill the most uncertain cell: one with most support from still-possible placements, hasn't been drilled\npair<int,int> choose_next_drill() {\n    auto cnt = plausible_oil_counts();\n    int best_val = -1;\n    pair<int,int> best = {-1,-1};\n    for (int i=0; i<N; ++i) for (int j=0; j<N; ++j)\n        if (drillValue[i][j]==-1 && cnt[i][j] > best_val) {\n            best_val = cnt[i][j];\n            best = {i,j};\n        }\n    if (best_val==-1) {\n        // All cells known? Should not happen\n        for (int i=0; i<N; ++i) for (int j=0; j<N; ++j)\n            if (drillValue[i][j]==-1) return {i,j};\n    }\n    return best;\n}\n\n// Return true if all oil fields have unique placement\nbool solved(unique_ptr<set<pair<int,int>>>& result_cells) {\n    set<pair<int,int>> S;\n    for (int f=0; f<M; ++f) {\n        if (alivePlacements[f].size() != 1) return false;\n        for (auto [ci,cj]: oil_fields[f].placements[alivePlacements[f][0]]) {\n            S.emplace(ci,cj);\n        }\n    }\n    result_cells = make_unique<set<pair<int,int>>>(move(S));\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    // Rest input\n    cin >> N >> M >> eps;\n    oil_fields.resize(M);\n    for (int k=0; k<M; ++k) {\n        int d; cin >> d;\n        vector<pair<int,int>> cc;\n        for (int q=0; q<d; ++q) {\n            int x, y; cin >> x >> y;\n            cc.emplace_back(x,y);\n        }\n        oil_fields[k].cells = move(cc);\n    }\n\n    enumerate_placements();\n\n    alivePlacements.clear();\n    for (auto& poly : oil_fields) {\n        int K = poly.placements.size();\n        vector<int> v(K);\n        iota(v.begin(), v.end(), 0);\n        alivePlacements.push_back(move(v));\n    }\n    drillValue.assign(N, vector<int>(N, -1));\n\n    int opcnt = 0;\n    unique_ptr<set<pair<int,int>>> answer_set = nullptr;\n\n    // To ensure progress, for first few steps, random drills (M*2)\n    vector<pair<int,int>> already_drilled;\n    mt19937 rng(12345); // fixed seed for reproducibility in sample solutions\n    while (opcnt < min(2*M, N*N)) {\n        uniform_int_distribution<int> dist(0, N-1);\n        int i = dist(rng), j = dist(rng);\n        if (drillValue[i][j] != -1) continue;\n        do_query(\"q 1 \"+to_string(i)+\" \"+to_string(j));\n        int v;\n        cin >> v;\n        drillValue[i][j] = v;\n        already_drilled.emplace_back(i,j);\n        opcnt++;\n        update_alivePlacements();\n        if (solved(answer_set)) goto finish;\n    }\n\n    // Main loop: maintain alivePlacements; greedily drill most ambiguous cell\n    while (opcnt < 2*N*N) {\n        // Try to propose answer\n        if (solved(answer_set)) break;\n\n        pair<int,int> drill = choose_next_drill();\n        if (drill.first==-1) break; // all known\n        int i=drill.first, j=drill.second;\n\n        do_query(\"q 1 \"+to_string(i)+\" \"+to_string(j));\n        int v; cin >> v;\n        drillValue[i][j] = v;\n        opcnt++;\n        update_alivePlacements();\n    }\n\nfinish:\n\n    // Compose answer set: all cells covered by unique placements of oil fields\n    if (!answer_set) solved(answer_set); // might be already solved\n\n    vector<pair<int,int>> oilCells(answer_set->begin(), answer_set->end());\n    // As required: must include all drilled cells where v(i,j)>0\n    for (auto [i,j]: already_drilled) {\n        if (drillValue[i][j]>0 && !answer_set->count({i,j})) {\n            oilCells.emplace_back(i,j);\n        }\n    }\n\n    cout << \"a \" << oilCells.size();\n    for (auto [i,j] : oilCells) cout << \" \" << i << \" \" << j;\n    cout << endl << flush;\n\n    int res; cin >> res;\n    if (res!=1) {\n        // Should not happen unless output illegal subset\n        cerr << \"#c Output judged incorrect!\" << endl;\n    }\n\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Constants\nconstexpr int W = 1000;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int w, D, N;\n    cin >> w >> D >> N;\n    vector<vector<int>> a(D, vector<int>(N));\n\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            cin >> a[d][k];\n        }\n    }\n\n    // We compute fixed vertical stripe partitions for N rectangles\n    // We'll divide width as evenly as possible between the stripes\n    // Calculate each x-range for k-th rectangle\n    vector<int> stripe_l(N), stripe_r(N);\n    for (int k = 0; k < N; ++k) {\n        // Floor division then assign extra one to first (W % N)\n        int l = (int)((int64_t)k * W / N);\n        int r = (int)((int64_t)(k + 1) * W / N);\n        stripe_l[k] = l;\n        stripe_r[k] = r;\n    }\n\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            int x0 = stripe_l[k];\n            int x1 = stripe_r[k];\n            int y0 = 0;\n            int y1 = W;\n\n            // Stripe is (x0,y0)-(x1,y1), area = (x1-x0)*W\n\n            // If area is less than a[d][k], we could try to\n            // increase the stripe's height, but in this static approach, it's fixed.\n\n            // If stripe is too small, shrink y1 to make sure b >= a[d][k] if possible.\n            int min_area = a[d][k];\n            int width = x1 - x0;\n            int min_height = (min_area + width - 1) / max(width, 1); // Ceil division\n            if (min_height > W) min_height = W;\n            // Prefer to give full height always (to keep partitions unchanged)\n            // But you could do y1 = y0 + min_height;\n            // For now, keep (x0,y0)-(x1,y1)\n            cout << y0 << \" \" << x0 << \" \" << y1 << \" \" << x1 << \"\\n\";\n        }\n    }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 9, M = 20, K = 81;\nconstexpr int MOD = 998244353;\nusing Board = array<array<int, N>, N>;\nusing Stamp = array<array<int,3>,3>;\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n\n    // Input\n    int n, m, k;\n    cin >> n >> m >> k;\n    Board a;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> a[i][j];\n\n    vector<Stamp> stamps(M);\n    for (int t = 0; t < M; ++t)\n        for (int i = 0; i < 3; ++i)\n            for (int j = 0; j < 3; ++j)\n                cin >> stamps[t][i][j];\n\n    Board board = a;\n    // To speed up, we also store b % MOD for each cell\n    array<array<int, N>, N> board_mod;\n    for (int i=0; i<N; ++i)\n        for (int j=0; j<N; ++j)\n            board_mod[i][j] = board[i][j] % MOD;\n\n    // List of (which stamp, y, x)\n    vector<tuple<int,int,int>> ops;\n\n    // Greedy stamping for up to K times\n    for (int step = 0; step < K; ++step) {\n        int best_gain = 0;\n        int best_m = -1, best_p = -1, best_q = -1;\n\n        for (int m_id = 0; m_id < M; ++m_id) {\n            const auto& st = stamps[m_id];\n            for (int p = 0; p <= N - 3; ++p) {\n                for (int q = 0; q <= N - 3; ++q) {\n                    int gain = 0;\n                    // compute modsum gain when placing here\n                    for (int di = 0; di < 3; ++di) {\n                        for (int dj = 0; dj < 3; ++dj) {\n                            int ni = p + di, nj = q + dj;\n                            int before = board_mod[ni][nj];\n                            int after = (board[ni][nj] + st[di][dj]) % MOD;\n                            // Gain is how much modded value increases (could wrap to smaller!)\n                            // To handle wrapping, compute (after-before+MOD)%MOD\n                            int cell_gain = (after - before + MOD) % MOD;\n                            gain += cell_gain;\n                        }\n                    }\n                    if (gain > best_gain) {\n                        best_gain = gain;\n                        best_m = m_id;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n\n        if (best_gain == 0) {\n            // No beneficial stamping left\n            break;\n        }\n\n        // Apply the best operation\n        ops.emplace_back(best_m, best_p, best_q);\n        const auto& st = stamps[best_m];\n        for (int di = 0; di < 3; ++di) {\n            for (int dj = 0; dj < 3; ++dj) {\n                int ni = best_p + di, nj = best_q + dj;\n                board[ni][nj] += st[di][dj];\n                board_mod[ni][nj] = (board_mod[ni][nj] + st[di][dj]) % MOD;\n            }\n        }\n    }\n\n    // Output result\n    cout << ops.size() << '\\n';\n    for (const auto& [m,p,q] : ops) {\n        cout << m << ' ' << p << ' ' << q << '\\n';\n    }\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Constants for grid size\nconstexpr int N = 5;\nconstexpr int MAX_TURNS = 10000;\n\n// Crane state\nstruct Crane {\n    int row, col;\n    bool large;\n    bool holding = false;\n    int held_container = -1;\n    bool bomd = false;\n};\n\nstruct Cell {\n    int container = -1; // -1: none\n    int crane = -1;     // -1: none\n};\n\nvector<vector<int>> A; // The input per-row incoming container plans\n\n// Directions\nint drow[4] = {-1, 1, 0, 0};\nint dcol[4] = {0, 0, -1, 1};\nchar DIR[4] = {'U', 'D', 'L', 'R'};\n\n// For each move, check validity (no crane collision & movement rule)\ninline bool can_go(int r, int c) {\n    return r >= 0 && r < N && c >= 0 && c < N;\n}\n\nint main() {\n    ios::sync_with_stdio(0);\n    cin.tie(0);\n\n    // Input\n    A.assign(N, vector<int>(N));\n    for(int i=0;i<N;i++)\n        for(int j=0;j<N;j++) cin >> A[i][j];\n\n    // Construct per-row receiving queues\n    array<queue<int>, N> arrivals;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) arrivals[i].push(A[i][j]);\n\n    // Board state: container on cell, -1 means empty\n    array<array<int,N>,N> cont;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) cont[i][j] = -1;\n\n    // Cranes: [0] is large, [1..N-1] are small\n    vector<Crane> cranes(N);\n    for(int i=0;i<N;i++) cranes[i] = {i,0, i==0,false,-1,false};\n\n    // Place cranes on board\n    array<array<int,N>,N> who_crane;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) who_crane[i][j]=-1;\n    for(int i=0;i<N;i++) who_crane[i][0]=i;\n\n    // Dispatched per row for scoring (not needed during contest)\n    vector<vector<int>> dispatched(N);\n\n    // Plan to print\n    vector<string> action_logs(N);\n\n    // Next dispatch index per row\n    array<int, N> next_dispatch; next_dispatch.fill(0);\n\n    // For quick lookup: buffered positions\n    auto buffer_positions = [](int row) {\n        // Only (row,1..3)\n        vector<pair<int,int>> pos;\n        for(int j=1;j<=3;j++) pos.emplace_back(row,j);\n        return pos;\n    };\n\n    // Each turn\n    for(int turn=0; turn<MAX_TURNS; ++turn) {\n        // ARRIVAL: Place containers into gates when possible\n        for(int i=0;i<N;i++) {\n            if(cont[i][0]==-1 && !cranes[i].holding && !arrivals[i].empty())\n                cont[i][0]=arrivals[i].front(), arrivals[i].pop();\n        }\n\n        vector<char> acts(N,'.');\n\n        // Mark crane locations for this turn\n        array<array<int,N>,N> where_crane = who_crane;\n\n        // PHASE 1: Plan task per crane\n        for(int k=0;k<N;k++) {\n            auto& cr=cranes[k];\n            if(cr.bomd) { acts[k]='.'; continue; }\n\n            int r=cr.row, c=cr.col;\n            int dispatch_goal = N*r + next_dispatch[r]; // e.g. 0,1,... for row 0\n\n            // If already finished all dispatches in this row, and large crane, help elsewhere\n            if(next_dispatch[r]>=N && cr.large) {\n                // Find most-blocked row: which row has fewest dispatched\n                int tgt=-1, min_togo=N+1;\n                for(int i=0;i<N;i++) {\n                    int undone=N-next_dispatch[i];\n                    if(undone>0 && undone<min_togo) min_togo=undone, tgt=i;\n                }\n                if(tgt!=-1 && tgt!=r) {\n                    // Go to leftmost of that row if possible, else idle\n                    if(r < tgt) {\n                        if(who_crane[r+1][c]==-1)\n                            { acts[k]='D'; cr.row++; who_crane[r][c]=-1; who_crane[cr.row][cr.col]=k; }\n                        else acts[k]='.';\n                    } else if(r > tgt) {\n                        if(who_crane[r-1][c]==-1)\n                            { acts[k]='U'; cr.row--; who_crane[r][c]=-1; who_crane[cr.row][cr.col]=k; }\n                        else acts[k]='.';\n                    } else if(c>0) {\n                        if(who_crane[r][c-1]==-1)\n                            { acts[k]='L'; cr.col--; who_crane[r][c]=-1; who_crane[cr.row][cr.col]=k; }\n                        else acts[k]='.';\n                    } else acts[k]='.';\n                    continue;\n                }\n            }\n\n            // If holding goal container and at dispatch gate, can drop?\n            if(cr.holding && cr.held_container==dispatch_goal && c==N-1) {\n                if(cont[r][N-1]==-1) {\n                    acts[k]='Q';\n                    cont[r][c]=cr.held_container; cr.holding=false; cr.held_container=-1;\n                    next_dispatch[r]++;\n                    continue;\n                } else {\n                    acts[k]='.'; continue;\n                }\n            }\n\n            // If not holding, if goal is ready under him, pick up\n            if(!cr.holding && cont[r][c]==dispatch_goal) {\n                acts[k]='P';\n                cr.holding=true;\n                cr.held_container=cont[r][c]; cont[r][c]=-1;\n                continue;\n            }\n\n            // If holding the goal container: go toward dispatch gate\n            if(cr.holding && cr.held_container==dispatch_goal) {\n                if(c<N-1) {\n                    int cc=c+1;\n                    if(who_crane[r][cc]==-1 && (cr.large || cont[r][cc]==-1)) {\n                        acts[k]='R';\n                        cr.col++; who_crane[r][c]=-1; who_crane[cr.row][cr.col]=k;\n                    } else acts[k]='.';\n                } else acts[k]='.';\n                continue;\n            }\n\n            // If holding a non-goal container, put it in the leftmost available buffer\n            if(cr.holding) {\n                bool done=false;\n                for(int bc=1;bc<=3;bc++) {\n                    if(cont[r][bc]==-1 && who_crane[r][bc]==-1) {\n                        // Move to buffer cell\n                        if(c < bc) {\n                            if(who_crane[r][c+1]==-1 && (cr.large || cont[r][c+1]==-1)) {\n                                acts[k]='R';\n                                cr.col++; who_crane[r][c]=-1; who_crane[cr.row][cr.col]=k;\n                                done=true; break;\n                            }\n                        } else if(c > bc) {\n                            if(who_crane[r][c-1]==-1 && (cr.large || cont[r][c-1]==-1)) {\n                                acts[k]='L';\n                                cr.col--; who_crane[r][c]=-1; who_crane[cr.row][cr.col]=k;\n                                done=true; break;\n                            }\n                        } else if(cont[r][c]==-1) {\n                            acts[k]='Q';\n                            cont[r][c]=cr.held_container;\n                            cr.holding=false; cr.held_container=-1;\n                            done=true; break;\n                        }\n                    }\n                }\n                if(!done) acts[k]='.'; // No buffer available\n                continue;\n            }\n\n            // Not holding,\n            // Priority 1: goal in buffer or receiving -> go to it, pick it\n            int pos_goal=-1;\n            for(int bc=0;bc<=3;bc++)\n                if(cont[r][bc]==dispatch_goal) { pos_goal=bc; break; }\n            if(pos_goal!=-1) {\n                if(c < pos_goal) {\n                    if(who_crane[r][c+1]==-1)\n                        { acts[k]='R'; cr.col++; who_crane[r][c]=-1; who_crane[r][cr.col]=k;}\n                    else acts[k]='.';\n                } else if(c > pos_goal) {\n                    if(who_crane[r][c-1]==-1)\n                        { acts[k]='L'; cr.col--; who_crane[r][c]=-1; who_crane[r][cr.col]=k;}\n                    else acts[k]='.';\n                } else if(cont[r][c]==dispatch_goal) {\n                    acts[k]='P'; cr.holding=true; cr.held_container=cont[r][c]; cont[r][c]=-1;\n                }\n                continue;\n            }\n\n            // Priority 2: if receiving gate has a *wrong* container, go pick and buffer it (buffering aggressively)\n            if(c==0 && cont[r][0]!=-1) {\n                acts[k]='P'; cr.holding=true; cr.held_container=cont[r][0]; cont[r][0]=-1;\n                continue;\n            } else if(c!=0 && cont[r][0]!=-1) {\n                if(c < 0) {\n                    if(who_crane[r][c+1]==-1) { acts[k]='R'; cr.col++; who_crane[r][c]=-1; who_crane[r][cr.col]=k;}\n                    else acts[k]='.';\n                } else if(c > 0) {\n                    if(who_crane[r][c-1]==-1) { acts[k]='L'; cr.col--; who_crane[r][c]=-1; who_crane[r][cr.col]=k;}\n                    else acts[k]='.';\n                }\n                continue;\n            }\n\n            // Priority 3: if any buffer cell is empty, move to it, so standing on free buffer cell when goal arrives\n            if(!cr.holding) {\n                for(int bc=1;bc<=3;bc++) {\n                    if(cont[r][bc]==-1 && who_crane[r][bc]==-1) {\n                        // Move towards it (if not there already)\n                        if(c < bc) {\n                            if(who_crane[r][c+1]==-1) { acts[k]='R'; cr.col++; who_crane[r][c]=-1; who_crane[r][cr.col]=k;}\n                            else acts[k]='.';\n                        } else if(c > bc) {\n                            if(who_crane[r][c-1]==-1) { acts[k]='L'; cr.col--; who_crane[r][c]=-1; who_crane[r][cr.col]=k;}\n                            else acts[k]='.';\n                        } else { acts[k]='.'; }\n                        goto PHASE1_ENDED; // move.\n                    }\n                }\n            }\n            // Else idle\n            acts[k]='.';\n\n            PHASE1_ENDED:;\n        }\n        // Write actions\n        for(int i=0;i<N;i++) action_logs[i].push_back(acts[i]);\n\n        // PHASE 2: Dispatch from rightmost if container there\n        for(int i=0;i<N;i++) {\n            if(cont[i][N-1]!=-1) {\n                dispatched[i].push_back(cont[i][N-1]);\n                cont[i][N-1]=-1;\n            }\n        }\n        // PHASE 3: Quit if all dispatched\n        int dispatched_cnt=0; for(int i=0;i<N;i++) dispatched_cnt += dispatched[i].size();\n        if(dispatched_cnt==N*N) break;\n    }\n\n    // Output action plans (padded)\n    size_t maxlen=0; for(auto&s:action_logs) maxlen=max(maxlen,s.size());\n    for(auto&s:action_logs) {\n        if(s.size()<maxlen) s+=string(maxlen-s.size(),'.');\n        cout<<s<<'\\n';\n    }\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 20;\nconstexpr int MAX_LOAD = 1000000;\n\nusing pii = pair<int,int>;\n\nstruct Cell {\n    int y, x;\n    int amount;\n    bool operator<(const Cell& o) const { // For nearest search\n        return amount < o.amount;\n    }\n};\n\n// Pathfinding: output step sequence (U,D,L,R) between two points\nvector<char> get_path(int sy, int sx, int ty, int tx) {\n    vector<char> path;\n    while (sy < ty) { path.push_back('D'); sy++; }\n    while (sy > ty) { path.push_back('U'); sy--; }\n    while (sx < tx) { path.push_back('R'); sx++; }\n    while (sx > tx) { path.push_back('L'); sx--; }\n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int n;\n    cin >> n;\n    vector<vector<int>> h(n, vector<int>(n));\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j)\n            cin >> h[i][j];\n\n    // Collect supplies and demands, positive and negative respectively\n    vector<Cell> supplies, demands;\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j) {\n            if (h[i][j] > 0) supplies.push_back({i, j, h[i][j]});\n            else if (h[i][j] < 0) demands.push_back({i, j, -h[i][j]}); // store as positive amount\n        }\n\n    vector<string> commands;\n    int ty = 0, tx = 0; // truck position\n    int load = 0;       // truck load\n\n    vector<vector<int>> supply_grid(n, vector<int>(n, 0)), demand_grid(n, vector<int>(n, 0));\n    for (auto& s : supplies) supply_grid[s.y][s.x] = s.amount;\n    for (auto& d : demands) demand_grid[d.y][d.x] = d.amount;\n\n    auto find_nearest = [&](int cy, int cx, vector<Cell>& pool) -> tuple<int,int,int> {\n        int best_dist = 1e9, idx = -1;\n        for (int i=0; i<(int)pool.size(); ++i) {\n            if (pool[i].amount==0) continue;\n            int dist = abs(pool[i].y - cy) + abs(pool[i].x - cx);\n            if (dist < best_dist) {best_dist = dist; idx = i;}\n        }\n        if (idx==-1) return {-1, -1, -1};\n        return {idx, pool[idx].y, pool[idx].x};\n    };\n\n    // Continue until all supplies/demands done\n    while (true) {\n        // Truck EMPTY, find the nearest supply\n        if (load==0) {\n            // Remove finished supplies\n            auto closest = find_nearest(ty, tx, supplies);\n            int sidx, sy, sx;\n            tie(sidx, sy, sx) = closest;\n            if (sidx==-1) break; // Done\n\n            // Move to supply\n            auto path = get_path(ty, tx, sy, sx);\n            for (char c : path) commands.push_back(string(1,c));\n            ty = sy; tx = sx;\n\n            // Load as much as possible from here\n            int amt = min(supplies[sidx].amount, MAX_LOAD);\n            commands.push_back(\"+\"+to_string(amt));\n            load += amt;\n            supplies[sidx].amount -= amt;\n            supply_grid[sy][sx] -= amt;\n        }\n        // Truck LOADED, visit demands (multi-drop)\n        else {\n            while (load>0) {\n                // Find the nearest demand, regardless of amount\n                auto closest = find_nearest(ty, tx, demands);\n                int didx, dy, dx;\n                tie(didx, dy, dx) = closest;\n                if (didx == -1) {\n                    // No more demands, but still carrying dirt? Shouldn't happen.\n                    load = 0; break;\n                }\n                // Move to demand cell\n                auto path = get_path(ty, tx, dy, dx);\n                for (char c : path) commands.push_back(string(1,c));\n                ty = dy; tx = dx;\n\n                // Unload as much as possible here\n                int can_unload = min(load, demands[didx].amount);\n                commands.push_back(\"-\"+to_string(can_unload));\n                load -= can_unload;\n                demands[didx].amount -= can_unload;\n                demand_grid[dy][dx] -= can_unload;\n            }\n        }\n    }\n\n    // Output answer\n    for (auto& s : commands) cout<<s<<\"\\n\";\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 6;\nconstexpr int M = 15;\nconstexpr int T = 10;\nconstexpr int SEED_COUNT = 2 * N * (N - 1);\nconstexpr int GRID_SIZE = N * N;\n\n// For easier seed tracking\nstruct Seed {\n    vector<int> x;       // Features\n    int id;              // Original/new index\n    int v;               // Total value = sum(x)\n\n    Seed(int _id, const vector<int>& _x) : x(_x), id(_id) {\n        v = accumulate(x.begin(), x.end(), 0);\n    }\n};\n\nvoid flush() {\n    cout.flush();\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int n, m, t;\n    cin >> n >> m >> t;\n    assert(n == N && m == M && t == T);\n\n    vector<Seed> seeds;\n    for (int i = 0; i < SEED_COUNT; ++i) {\n        vector<int> x(m);\n        for (int j = 0; j < m; ++j) cin >> x[j];\n        seeds.emplace_back(i, x);\n    }\n\n    // For tracking max per-feature, for scoring/seeding\n    vector<int> feature_max(m, 0);\n\n    mt19937 rng(123456789); // Fixed seed for determinism, can use random_device for true random\n\n    for (int turn = 0; turn < T; ++turn) {\n        // Update feature-wise max\n        fill(feature_max.begin(), feature_max.end(), 0);\n        for (const auto& s : seeds)\n            for (int j = 0; j < m; ++j)\n                feature_max[j] = max(feature_max[j], s.x[j]);\n\n        // Scoring seeds: sum value (+ small bonus for max-per-feature attributes)\n        vector<pair<int, int>> order; // (score,seed_index)\n        vector<int> best_per_feature(m, -1); // seed id with max for each feature\n\n        for (int j = 0; j < m; ++j) {\n            for (const auto& s : seeds)\n                if (s.x[j] == feature_max[j])\n                    best_per_feature[j] = s.id;\n        }\n\n        for (int i = 0; i < (int)seeds.size(); ++i) {\n            int bonus = 0;\n            for (int j = 0; j < m; ++j)\n                if (seeds[i].x[j] == feature_max[j])\n                    bonus += 30; // Having best in a feature is good (tune this)\n            // Add randomness to break ties (and encourage diversity, mainly first few turns)\n            int rnd = uniform_int_distribution<int>(0, 5)(rng);\n            order.emplace_back(seeds[i].v + bonus + rnd, i);\n        }\n        // Take top 36\n        sort(order.rbegin(), order.rend());\n\n        vector<int> chosen_indices;\n        vector<bool> used(seeds.size(), 0);\n\n        // Always pick the current best overall sum, then try to cover all feature maxes\n        for (int i = 0; i < (int)order.size() && (int)chosen_indices.size() < GRID_SIZE; ++i) {\n            chosen_indices.push_back(order[i].second);\n            used[order[i].second] = true;\n        }\n        // Sanity: ensure all feature-max seeds are picked (can remove this for speed)\n        for (int j = 0; j < m; ++j) {\n            int id = best_per_feature[j];\n            if (id == -1) continue;\n            if (!used[id]) {\n                // replace weakest seed in chosen with this seed\n                int minidx = 0;\n                for (int z = 0; z < (int)chosen_indices.size(); ++z)\n                    if (seeds[chosen_indices[z]].v < seeds[chosen_indices[minidx]].v)\n                        minidx = z;\n                used[chosen_indices[minidx]] = false;\n                chosen_indices[minidx] = id;\n                used[id] = true;\n            }\n        }\n\n        // Assign the 36 chosen seeds to grid cells\n        // Place highest V in center and high-degree cells\n        vector<pair<int, int>> grid_cells;\n        for (int i = 0; i < n; ++i)\n            for (int j = 0; j < n; ++j)\n                grid_cells.emplace_back(i, j);\n\n        // Sort cells by number of neighbors, descending (center cells first)\n        sort(grid_cells.begin(), grid_cells.end(), [](pair<int, int> a, pair<int, int> b) {\n            int da = 0, db = 0;\n            auto [ai, aj] = a, [bi, bj] = b;\n            da += (ai > 0) + (ai < N-1) + (aj > 0) + (aj < N-1);\n            db += (bi > 0) + (bi < N-1) + (bj > 0) + (bj < N-1);\n            return da > db;\n        });\n\n        // Greedily assign highest-value seeds to high-degree cells\n        vector<vector<int>> grid(n, vector<int>(n,-1));\n        for (int i = 0; i < GRID_SIZE; ++i)\n            grid[grid_cells[i].first][grid_cells[i].second] = seeds[chosen_indices[i]].id;\n\n        // Output placement\n        for (int i = 0; i < n; ++i) {\n            for (int j = 0; j < n; ++j) {\n                cout << grid[i][j] << (j + 1 < n ? \" \" : \"\\n\");\n            }\n        }\n        flush();\n\n        // Input next set: always 60 seeds, with new feature vectors\n        vector<Seed> next_seeds;\n        for (int k = 0; k < SEED_COUNT; ++k) {\n            vector<int> x(m);\n            for (int j = 0; j < m; ++j) cin >> x[j];\n            next_seeds.emplace_back(k, x);\n        }\n        seeds = move(next_seeds);\n\n        // Optional: print debug\n        int bestV = 0;\n        for (const auto& s : seeds) bestV = max(bestV, s.v);\n        cout << \"# turn=\" << turn << \" bestV=\" << bestV << endl;\n    }\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int INF = 1 << 29;\n\nstruct Pos {\n    int x, y;\n    bool operator==(const Pos& o) const { return x == o.x && y == o.y; }\n    bool operator!=(const Pos& o) const { return !(*this == o); }\n};\n\nvector<Pos> get_leaves(int star_size, int len) {\n    // For star at (0,0) and edges all \"to right\", fingertips are at (0,+len), (0,-len), (+len,0), (-len,0), etc.\n    // We'll spread them as [up,down,left,right,diag up-right...]\n    vector<Pos> dirs = { {0,1},{1,0},{0,-1},{-1,0}, {1,1}, {-1,1}, {1,-1}, {-1,-1} };\n    vector<Pos> leaves;\n    int D = dirs.size();\n    for (int i = 0; i < star_size; i++) {\n        int d = i % D;\n        int mul = 1 + (i/D); // first ring, then doubles if more leaves\n        leaves.push_back(Pos{dirs[d].x * len * mul, dirs[d].y * len * mul});\n    }\n    return leaves;\n}\nPos add(const Pos& a, const Pos& b) { return { a.x + b.x, a.y + b.y }; }\nPos sub(const Pos& a, const Pos& b) { return { a.x - b.x, a.y - b.y }; }\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N, M, V;\n    cin >> N >> M >> V;\n    vector<string> s(N), t(N);\n    for (int i = 0; i < N; i++) cin >> s[i];\n    for (int i = 0; i < N; i++) cin >> t[i];\n\n    // Gather pickup and delivery cell lists\n    vector<Pos> pickups, delivers;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            if (s[i][j] == '1') pickups.push_back({i,j});\n            if (t[i][j] == '1') delivers.push_back({i,j});\n        }\n\n    // Build star-robot arm description\n    int V_ = min(V, 9); // For clearer mapping, \u22648 leaves+root for now; you can try V for more coverage!\n    int L = max(1, N/4); // Or tweak for average case\n    vector<pair<int,int>> parents;\n    for (int i = 1; i < V_; i++) parents.emplace_back(0, L);\n    // Output tree\n    cout << V_ << '\\n';\n    for (auto& [p,l] : parents) cout << p << \" \" << l << \"\\n\";\n\n    // Chose initial root position (upper left for now! try to cover first batch)\n    int root_x = 0, root_y = 0;\n    cout << root_x << \" \" << root_y << '\\n';\n\n    // Compute static fingertips (relative to root)\n    auto leaves = get_leaves(V_-1, L);\n\n    // State per fingertip: currently holding takoyaki?\n    vector<bool> holding(V_-1, false);\n\n    // Used picks/delivs\n    vector<bool> picked(pickups.size(), false), delivered(delivers.size(), false);\n\n    // Keep sets of yet-to-pickup and yet-to-deliver\n    int total_moves = 0;\n    int delivered_cnt = 0;\n    int T_limit = 100000;\n\n    // For visualization: grid status\n    vector<string> curr(N, string(N, '0'));\n    for (auto& pos : pickups) curr[pos.x][pos.y] = '1';\n\n    // For matching: use simple greedy nearest assignment per batch\n\n    size_t pick_idx = 0, deliv_idx = 0;\n    int phase = 0; // 0: pickup phase; 1: delivery phase\n\n    struct FingertipTask { int idx; Pos pos; }; // idx in pickups[]/delivers[]\n\n    vector<FingertipTask> pick_tasks, deliv_tasks;\n    vector<int> fin_to_pickid(V_-1, -1), fin_to_delivid(V_-1, -1);\n\n    vector<string> answers;\n\n    // We alternate: batch pick, walk arm to delivery, batch release\n    while (delivered_cnt < M && total_moves < T_limit) {\n        // 1. Assign up to (V_-1) unpicked takoyakis to fingertips\n        pick_tasks.clear();\n        for (int i = 0; i < pickups.size(); ++i) {\n            if (!picked[i]) pick_tasks.push_back({i, pickups[i]});\n            if ((int)pick_tasks.size() == V_-1) break;\n        }\n        vector<Pos> batch_pick;\n        for (auto& t : pick_tasks) batch_pick.push_back(t.pos);\n\n        if (batch_pick.empty()) break; // no more takoyaki to grab\n\n        // 2. Find a root pos so that with this arm config, all batch picks are at some fingertip\n        // For each cell, check if, after translating root there, the fingertips cover all batch_pick\n        // Brute: try them all, but prioritize upper-left region (speed: grid isn't huge)\n        Pos picked_root = {-1,-1};\n        vector<int> fin_assignment(V_-1, -1); // index into pick_tasks\n\n        for (int rx = 0; rx < N && picked_root.x == -1; rx++)\n          for (int ry = 0; ry < N && picked_root.x == -1; ry++) {\n            vector<int> assign(V_-1, -1);\n            vector<bool> used(V_-1, false);\n            // For each pick cell, try to assign it to a finger\n            bool fail = false;\n            for (int ki = 0; ki < (int)batch_pick.size(); ++ki) {\n                bool matched = false;\n                for (int f = 0; f < V_-1; f++) {\n                    Pos tip = add({rx, ry}, leaves[f]);\n                    if (tip.x == batch_pick[ki].x && tip.y == batch_pick[ki].y && !used[f]) {\n                        assign[f] = ki;\n                        used[f] = true;\n                        matched = true;\n                        break;\n                    }\n                }\n                if (!matched) { fail = true; break; }\n            }\n            if (!fail) {\n                picked_root = {rx, ry};\n                fin_assignment = assign;\n                break;\n            }\n          }\n        if (picked_root.x == -1) {\n            // Cannot fit all, reduce batch size (never happens as long as len is not huge)\n            // In practical: fallback to fewer per batch (or decrease L at design time)\n            assert((int)batch_pick.size() < V_-1); // fallback not implemented here\n            break;\n        }\n\n        // 3. Plan root move sequence to picked_root from current root\n        // Simple greedy: manhattan path by rows, then by cols\n        int dx = picked_root.x - root_x, dy = picked_root.y - root_y;\n        string mv_cmd = \"UDLR\";\n        char cmds[4] = {'D','U','R','L'}; // For negative/positive steps in (dx,dy)\n        vector<string> steps;\n        // Move vertically\n        while (root_x < picked_root.x) { steps.push_back(\"D\"); root_x++; }\n        while (root_x > picked_root.x) { steps.push_back(\"U\"); root_x--; }\n        while (root_y < picked_root.y) { steps.push_back(\"R\"); root_y++; }\n        while (root_y > picked_root.y) { steps.push_back(\"L\"); root_y--; }\n\n        // Create a string of 2V chars: [move][rot*][act*]\n        string emptyrot(V_-1, '.');\n        string emptyact(V_, '.');\n        for (auto& s : steps) {\n            string out(2*V_, '.');\n            out[0] = s[0];\n            answers.push_back(out);\n        }\n\n        // 4. At pickup location: make all fingertips pick up if at their assigned target\n        string op(2*V_, '.');\n        // No move, no rotate\n        for (int f = 0; f < V_-1; ++f) {\n            int ki = fin_assignment[f];\n            if (ki != -1) {\n                // Only if not already picked and fingertip matches\n                op[V_+f+1] = 'P'; // leaves are vertices 1..V_-1\n                picked[pick_tasks[ki].idx] = true;\n                // Remove from grid\n                curr[batch_pick[ki].x][batch_pick[ki].y] = '0';\n                holding[f] = true;\n            } else {\n                op[V_+f+1] = '.';\n            }\n        }\n        answers.push_back(op);\n        ++total_moves;\n\n        // 5. Now, batch deliver: get up to (V_-1) non-delivered targets\n        deliv_tasks.clear();\n        for (int i = 0; i < delivers.size(); ++i) {\n            if (!delivered[i]) deliv_tasks.push_back({i, delivers[i]});\n            if ((int)deliv_tasks.size() == V_-1) break;\n        }\n        vector<Pos> batch_deliv;\n        for (auto& t : deliv_tasks) batch_deliv.push_back(t.pos);\n\n        // As above, try to fit deliver batch\n        Pos deliv_root = {-1,-1};\n        vector<int> fin_d_assign(V_-1, -1);\n        for (int rx = 0; rx < N && deliv_root.x == -1; rx++)\n          for (int ry = 0; ry < N && deliv_root.x == -1; ry++) {\n            vector<int> assign(V_-1, -1);\n            vector<bool> used(V_-1, false);\n            bool fail = false;\n            for (int ki = 0; ki < (int)batch_deliv.size(); ++ki) {\n                bool matched = false;\n                for (int f = 0; f < V_-1; f++) {\n                    Pos tip = add({rx, ry}, leaves[f]);\n                    if (tip.x == batch_deliv[ki].x && tip.y == batch_deliv[ki].y && !used[f] && holding[f]) {\n                        assign[f] = ki;\n                        used[f] = true;\n                        matched = true;\n                        break;\n                    }\n                }\n                if (!matched) { fail = true; break; }\n            }\n            if (!fail) {\n                deliv_root = {rx, ry};\n                fin_d_assign = assign;\n                break;\n            }\n          }\n        assert(deliv_root.x != -1); // Should always succeed\n\n        // Move root to delivery pos\n        dx = deliv_root.x - root_x;\n        dy = deliv_root.y - root_y;\n        // Move vertically\n        while (root_x < deliv_root.x) { string out(2*V_, '.'); out[0] = 'D'; answers.push_back(out); root_x++; }\n        while (root_x > deliv_root.x) { string out(2*V_, '.'); out[0] = 'U'; answers.push_back(out); root_x--; }\n        while (root_y < deliv_root.y) { string out(2*V_, '.'); out[0] = 'R'; answers.push_back(out); root_y++; }\n        while (root_y > deliv_root.y) { string out(2*V_, '.'); out[0] = 'L'; answers.push_back(out); root_y--; }\n\n        // Release at targets\n        string op2(2*V_, '.');\n        for (int f = 0; f < V_-1; ++f) {\n            int ki = fin_d_assign[f];\n            if (ki != -1) {\n                op2[V_+f+1] = 'P';\n                delivered[deliv_tasks[ki].idx] = true;\n                delivered_cnt++;\n                holding[f] = false;\n            } else {\n                op2[V_+f+1] = '.';\n            }\n        }\n        answers.push_back(op2);\n        ++total_moves;\n    }\n    // Output the answers\n    for (auto& a : answers) cout << a << '\\n';\n\n    // Could output a period to use unused moves (valid according to rules)\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing Point = pair<int, int>;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    cin >> N;\n    vector<Point> mackerels(N), sardines(N);\n    set<Point> used;\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n        mackerels[i] = {x, y};\n        used.insert({x, y});\n    }\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n        sardines[i] = {x, y};\n        used.insert({x, y});\n    }\n\n    // Let's try to find a rectangle (xL, yL) to (xH, yH) that catches many mackerel but few sardines\n\n    // First, try baseline: bounding box of all mackerels, but limit box to not be too big\n\n    int best_score = -1;\n    int best_xL=0, best_xH=0, best_yL=0, best_yH=0;\n\n    // 1. Compute overall bounding box of mackerels.\n    int mxL = 1e9, mxH = -1, myL = 1e9, myH = -1;\n    for (auto [x, y] : mackerels) {\n        mxL = min(mxL, x);\n        mxH = max(mxH, x);\n        myL = min(myL, y);\n        myH = max(myH, y);\n    }\n    // We'll expand and contract the bounding box to see if a better area can be found\n\n    vector<int> x_sorted, y_sorted;\n    for (auto [x, y] : mackerels) x_sorted.push_back(x), y_sorted.push_back(y);\n    sort(x_sorted.begin(), x_sorted.end());\n    sort(y_sorted.begin(), y_sorted.end());\n\n    // Let's try various quantiles to define rectangle boundaries, for basic heuristics.\n    for (int xlq = 0; xlq <= 20; ++xlq) {\n        int xL = x_sorted[N*xlq/40]; // from left\n        int xH = x_sorted[N - 1 - N*xlq/40]; // from right\n        for (int ylq = 0; ylq <= 20; ++ylq) {\n            int yL = y_sorted[N*ylq/40];\n            int yH = y_sorted[N - 1 - N*ylq/40];\n            if (xH <= xL || yH <= yL) continue;\n            int perim = 2*(xH-xL) + 2*(yH-yL);\n            if (perim > 400000) continue;\n\n            int mack_in = 0, sard_in = 0;\n            for (auto [x, y] : mackerels) {\n                if (xL <= x && x <= xH && yL <= y && y <= yH) ++mack_in;\n            }\n            for (auto [x, y] : sardines) {\n                if (xL <= x && x <= xH && yL <= y && y <= yH) ++sard_in;\n            }\n            int score = max(0, mack_in - sard_in + 1);\n            if (score > best_score || (score == best_score && perim < 2*(best_xH-best_xL+best_yH-best_yL))) {\n                best_score = score;\n                best_xL = xL;\n                best_xH = xH;\n                best_yL = yL;\n                best_yH = yH;\n            }\n        }\n    }\n\n    // Output 4-vertex rectangle\n    cout << 4 << '\\n';\n    cout << best_xL << ' ' << best_yL << '\\n';\n    cout << best_xL << ' ' << best_yH << '\\n';\n    cout << best_xH << ' ' << best_yH << '\\n';\n    cout << best_xH << ' ' << best_yL << '\\n';\n\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Timer {\n    chrono::steady_clock::time_point st;\n    Timer() : st(chrono::steady_clock::now()) {}\n    double elapsed() const { return chrono::duration<double>(chrono::steady_clock::now()-st).count(); }\n};\n\nstruct Rect {\n    int idx;\n    int w, h;\n};\n\nstruct Placed {\n    int x, y, w, h;\n};\n\nstruct Placement {\n    int p, r;\n    char d;\n    int b;\n};\n\n// Trivial packing: place in index order, try two directions for each, greedily\nvector<Placement> pack_in_index_order(const vector<Rect>& rects) {\n    int N = rects.size();\n    vector<Placement> res;\n    vector<Placed> placed;\n\n    for (int i = 0; i < N; ++i) {\n        // Try both rotations and pick the better for our shelf heuristic\n        int best_r = 0, best_b = -1, best_x = 0, best_y = 0;\n        char best_d = 'U';\n        int best_w = 0, best_h = 0;\n        // For `d` in {U, L}, b in -1 or i-1, r in {0,1}\n        for (int r = 0; r <= 1; ++r) {\n            int wi = (r == 0 ? rects[i].w : rects[i].h);\n            int hi = (r == 0 ? rects[i].h : rects[i].w);\n            // Direction U (up): align left edge to x=0 (b=-1) or right edge of b\n            for (char d : {'U', 'L'}) {\n                if (d == 'U') {\n                    // Try b == -1 (left side), or try aligning right next to previous rect(s)\n                    // For now, always b = -1 for simplicity\n                    int x = 0, y = 0;\n                    if (i > 0) {\n                        // Try stacking to the right of previous rectangle\n                        x = placed.back().x + placed.back().w;\n                    }\n                    y = 0;\n                    int right = x + wi, down = y + hi;\n                    // Find overall bounding box\n                    int max_x = right, max_y = down;\n                    for (auto& pl : placed) {\n                        max_x = max(max_x, pl.x + pl.w);\n                        max_y = max(max_y, pl.y + pl.h);\n                    }\n                    // Minimize bounding box perimeter (could use area)\n                    if (res.empty() || max_x + max_y < best_w + best_h) {\n                        best_r = r;\n                        best_d = d;\n                        best_b = (x == 0 ? -1 : i-1);\n                        best_x = x;\n                        best_y = y;\n                        best_w = max_x;\n                        best_h = max_y;\n                    }\n                } else {\n                    // d == 'L'\n                    // Align at y=0 (b=-1), or below previous rectangle\n                    int x = 0, y = 0;\n                    if (i > 0) {\n                        y = placed.back().y + placed.back().h;\n                    }\n                    x = 0;\n                    int right = x + wi, down = y + hi;\n                    int max_x = right, max_y = down;\n                    for (auto& pl : placed) {\n                        max_x = max(max_x, pl.x + pl.w);\n                        max_y = max(max_y, pl.y + pl.h);\n                    }\n                    if (res.empty() || max_x + max_y < best_w + best_h) {\n                        best_r = r;\n                        best_d = d;\n                        best_b = (y == 0 ? -1 : i-1);\n                        best_x = x;\n                        best_y = y;\n                        best_w = max_x;\n                        best_h = max_y;\n                    }\n                }\n            }\n        }\n        res.emplace_back(rects[i].idx, best_r, best_d, best_b);\n        // Place it physically for our box calculations\n        int wi = (best_r == 0 ? rects[i].w : rects[i].h);\n        int hi = (best_r == 0 ? rects[i].h : rects[i].w);\n        placed.push_back({best_x, best_y, wi, hi});\n    }\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\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        int w, h;\n        cin >> w >> h;\n        rects[i] = {i, w, h};\n    }\n\n    Timer timer;\n    for (int t = 0; t < T; ++t) {\n        // Always use index order, legal!\n        vector<Placement> plan = pack_in_index_order(rects);\n\n        cout << plan.size() << '\\n';\n        for (auto &pl : plan) {\n            cout << pl.p << ' ' << pl.r << ' ' << pl.d << ' ' << pl.b << '\\n';\n        }\n        cout << flush;\n\n        int W_meas, H_meas;\n        cin >> W_meas >> H_meas;\n    }\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Constants\nconstexpr int INF = 1e9+5;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, H;\n    cin >> N >> M >> H;\n    vector<int> A(N);\n    for (auto &x : A) cin >> x;\n\n    vector<vector<int>> adj(N);\n    for (int i=0;i<M;++i) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    vector<pair<int, int>> coords(N);\n    for (int i=0;i<N;++i) {\n        int x, y; cin >> x >> y;\n        coords[i] = {x, y};\n    }\n\n    // Output structures\n    vector<int> parent(N, -1);\n    vector<int> depth(N, -1);\n    vector<bool> assigned(N, false);\n\n    // Prepare node order: high-beauty first\n    vector<int> node_order(N);\n    iota(node_order.begin(), node_order.end(), 0);\n    sort(node_order.begin(), node_order.end(),\n        [&](int i, int j){\n            return A[i] > A[j];\n        });\n\n    int assigned_cnt = 0;\n    for (int ni = 0; ni < N; ++ni) {\n        int v = node_order[ni];\n        if (assigned[v]) continue;\n\n        // Start a new tree rooted at v\n        parent[v] = -1;\n        depth[v] = 0;\n        assigned[v] = true;\n        assigned_cnt++;\n\n        // BFS up to depth H\n        queue<pair<int, int>> q; // (node, depth)\n        q.push({v, 0});\n        while (!q.empty()) {\n            auto [cur, d] = q.front(); q.pop();\n            if (d == H) continue;\n\n            // Get unassigned neighbors, sort by A[.]\n            vector<pair<int, int>> nbrs;\n            for (int to : adj[cur]) {\n                if (!assigned[to]) {\n                    nbrs.emplace_back(-A[to], to);\n                }\n            }\n            sort(nbrs.begin(), nbrs.end()); // high-A comes first\n\n            for (auto& [neg_val, nb] : nbrs) {\n                if (assigned[nb]) continue;\n                parent[nb] = cur;\n                depth[nb] = d+1;\n                assigned[nb] = true;\n                assigned_cnt++;\n                q.push({nb, d+1});\n            }\n        }\n    }\n\n    // Output final parent array\n    for (int i=0; i<N; ++i) {\n        cout << parent[i] << (i+1==N ? '\\n' : ' ');\n    }\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\n// For each Oni, find a safe direction in the initial board and output shift sequence\n// Don't update the board as Oni are \"removed\" -- just as per the guarantee\n\nstruct Move {\n    char dir;\n    int idx;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N;\n    cin >> N;\n    vector<string> board(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> board[i];\n    }\n\n    // Save Oni positions at start\n    vector<pair<int,int>> onis;\n    for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j)\n        if (board[i][j] == 'x') onis.emplace_back(i,j);\n\n    vector<Move> moves;\n\n    // For safety, mark direction per Oni before generating commands\n    // Board is NOT mutated!\n    for (auto [i, j] : onis) {\n        // Try all 4 directions in the initial board\n        // Up (remove by shifting col up i+1 times)\n        bool upSafe = true;\n        for (int k = 0; k < i; ++k) if (board[k][j] == 'o') { upSafe = false; break; }\n\n        // Down\n        bool downSafe = true;\n        for (int k = i+1; k < N; ++k) if (board[k][j] == 'o') { downSafe = false; break; }\n\n        // Left\n        bool leftSafe = true;\n        for (int k = 0; k < j; ++k) if (board[i][k] == 'o') { leftSafe = false; break; }\n\n        // Right\n        bool rightSafe = true;\n        for (int k = j+1; k < N; ++k) if (board[i][k] == 'o') { rightSafe = false; break; }\n\n        // Remove Oni at (i,j) by safe direction and undo\n        if (upSafe) {\n            // Shift col j up i+1 times, then down i times\n            for (int t = 0; t < i+1; ++t)\n                moves.push_back({'U', j});\n            for (int t = 0; t < i; ++t)\n                moves.push_back({'D', j});\n            continue;\n        }\n        if (downSafe) {\n            // Shift col j down N-i times, then up N-i-1 times\n            for (int t = 0; t < N-i; ++t)\n                moves.push_back({'D', j});\n            for (int t = 0; t < N-i-1; ++t)\n                moves.push_back({'U', j});\n            continue;\n        }\n        if (leftSafe) {\n            // Shift row i left j+1 times, then right j times\n            for (int t = 0; t < j+1; ++t)\n                moves.push_back({'L', i});\n            for (int t = 0; t < j; ++t)\n                moves.push_back({'R', i});\n            continue;\n        }\n        if (rightSafe) {\n            // Shift row i right N-j times, then left N-j-1 times\n            for (int t = 0; t < N-j; ++t)\n                moves.push_back({'R', i});\n            for (int t = 0; t < N-j-1; ++t)\n                moves.push_back({'L', i});\n            continue;\n        }\n        // If this point is reached, the guarantee is violated (shouldn't happen)\n        cerr << \"No safe direction for Oni at (\" << i << \",\" << j << \") in initial board\\n\";\n        assert(false);\n    }\n\n    for (auto &mv : moves) {\n        cout << mv.dir << ' ' << mv.idx << '\\n';\n    }\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\n// Constants\nconstexpr int N = 100;\nconstexpr int L = 500000;\n\nint T[N];\nint a[N], b[N];\n\n// Estimate frequencies by fast simulation, possibly multiple starts to break short cycles\nvector<double> estimate_freq(const int a[N], const int b[N], int steps = 100000) {\n    vector<double> freq(N, 0.0);\n    int repeat = 3;\n    for(int starter = 0; starter < repeat; ++starter) {\n        vector<int> count(N, 0);\n        int cur = starter % N;\n        vector<int> visited(N, 0);\n        count[cur]++;\n        visited[cur]=1;\n        for(int step = 1; step < steps; ++step) {\n            int occ = count[cur];\n            int nxt = (occ % 2 == 1) ? a[cur] : b[cur];\n            cur = nxt;\n            count[cur]++;\n            visited[cur]=1;\n        }\n        // Ignore nodes never visited in this segment\n        int sm = 0;\n        for(int i=0; i<N; ++i) sm += count[i];\n        for(int i=0; i<N; ++i) freq[i] += double(count[i])/repeat;\n    }\n    // Normalize for steps\n    double tot = accumulate(freq.begin(), freq.end(), 0.0);\n    for(int i=0; i<N; ++i) freq[i] /= tot;\n    return freq;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    int n, l;\n    cin >> n >> l;\n    for(int i=0; i<N; ++i) cin >> T[i];\n\n    // STEP 1: Initial assignment, degree-proportional assignment\n    // Calculate quotas\n    vector<pair<double,int>> q;\n    for(int i=0; i<N; ++i) \n        q.emplace_back((double)T[i]/L,i);\n    sort(q.rbegin(),q.rend());\n\n    // Distribute incoming edges roughly according to quota\n    vector<int> indeg(N,0);\n    for(int i=0; i<N; ++i) {\n        set<int> pickset;\n        while(pickset.size() < 2) {\n            // Weighted selection\n            int idx = 0;\n            double sel = double(rand())/RAND_MAX;\n            double s = 0;\n            for(auto& [p,j]: q) {\n                s += p;\n                if(sel<=s && j!=i) { idx=j; break;}\n            }\n            if(idx==i || pickset.count(idx)) continue;\n            pickset.insert(idx);\n        }\n        auto it = pickset.begin();\n        a[i]=*it++;\n        b[i]=*it;\n        indeg[a[i]]++; indeg[b[i]]++;\n    }\n    \n    // Minor fix to remove self-loops\n    for(int i=0; i<N; ++i) {\n        if(a[i]==i || b[i]==i) {\n            int other = a[i]==i ? b[i] : a[i];\n            for(int j=0;j<N;++j) {\n                if(j!=i && a[j]!=i && b[j]!=i && a[j]!=b[j]) {\n                    if(a[i]==i) a[i]=j; else b[i]=j;\n                    break;\n                }\n            }\n        }\n    }\n\n    // Main tuning\n    auto start_time = chrono::steady_clock::now();\n    const double TIME_LIMIT = 1.8;\n\n    // Prepare fast random engine\n    mt19937 rng(123456);\n\n    // Run iterative rebalancing and local search\n    int loopct = 0;\n    double best_error = 1e18;\n    int best_a[N], best_b[N];\n    memcpy(best_a,a,sizeof(a));\n    memcpy(best_b,b,sizeof(b));\n    vector<double> best_freq;\n    while(true) {\n        ++loopct;\n        // Estimate freq\n        auto freq = estimate_freq(a,b,350000);\n        // Compute actual t_i\n        double score = 0;\n        for(int i=0;i<N;++i) score += abs(freq[i]*L-T[i]);\n        if(score < best_error) {\n            best_error = score;\n            memcpy(best_a,a,sizeof(a));\n            memcpy(best_b,b,sizeof(b));\n            best_freq = freq;\n        }\n        // Check time\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if(elapsed > TIME_LIMIT) break;\n\n        // Find most over/under assigned\n        int over=-1, under=-1;\n        double max_over=0, max_under=0;\n        for(int i=0;i<N;++i) {\n            double diff = freq[i]*L - T[i];\n            if(diff > max_over) { max_over = diff; over = i; }\n            if(diff < max_under) { max_under = diff; under = i; }\n        }\n        if(over == -1 || under == -1) break; // (Actually perfect)\n\n        // Try to reroute some edges from over to under\n        bool changed = false;\n        // Try changing some a_j or b_j that point to 'over'\n        vector<int> candidates;\n        for(int j=0;j<N;++j) if(a[j]==over || b[j]==over) candidates.push_back(j);\n        shuffle(candidates.begin(),candidates.end(),rng);\n        for(int cand: candidates) {\n            if(a[cand]==over && under!=cand) {\n                int old=a[cand]; a[cand]=under;\n                auto f2=estimate_freq(a,b,50000);\n                double s2 = 0;\n                for(int i=0;i<N;++i) s2 += abs(f2[i]*L-T[i]);\n                if(s2 < score) { changed=true; break;}\n                a[cand]=old;\n            }\n            if(b[cand]==over && under!=cand) {\n                int old=b[cand]; b[cand]=under;\n                auto f2=estimate_freq(a,b,50000);\n                double s2 = 0;\n                for(int i=0;i<N;++i) s2 += abs(f2[i]*L-T[i]);\n                if(s2 < score) { changed=true; break;}\n                b[cand]=old;\n            }\n        }\n        if(!changed) {\n            // As fallback, random swap for diversity\n            int i = rng()%N;\n            int pos = rng()%2;\n            int nv = rng()%N;\n            if(nv==i) continue;\n            if(pos==0) a[i]=nv; else b[i]=nv;\n        }\n    }\n    // Output\n    for(int i=0; i<N; ++i) \n        cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct City {\n    int id;\n    int lx, rx, ly, ry;\n    double cx, cy; // center\n};\n\nstruct Edge {\n    int u, v;\n    int est_dist; // estimate dist (center dist)\n    Edge(int uu, int vv, int d): u(min(uu, vv)), v(max(uu, vv)), est_dist(d) {}\n    bool operator<(const Edge& o) const {\n        if (est_dist != o.est_dist) return est_dist < o.est_dist;\n        if (u != o.u) return u < o.u;\n        return v < o.v;\n    }\n    bool operator==(const Edge& o) const {\n        return u==o.u && v==o.v && est_dist==o.est_dist;\n    }\n};\n\n// Find root for union-find\nstruct UF {\n    vector<int> par;\n    UF(int n): par(n) { iota(par.begin(), par.end(), 0); }\n    int find(int x) {\n        while (par[x] != x) {\n            par[x] = par[par[x]];\n            x = par[x];\n        }\n        return x;\n    }\n    bool unite(int x, int y) {\n        int rx = find(x), ry = find(y);\n        if (rx == ry) return false;\n        par[ry] = rx; return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, Q, L, W;\n    cin >> N >> M >> Q >> L >> W;\n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n\n    vector<City> cities(N);\n    for (int i = 0; i < N; ++i) {\n        int lx, rx, ly, ry;\n        cin >> lx >> rx >> ly >> ry;\n        double cx = 0.5 * (lx + rx), cy = 0.5 * (ly + ry);\n        cities[i] = {i, lx, rx, ly, ry, cx, cy};\n    }\n\n    // Partition: sort by center-x then center-y\n    vector<int> idx(N); iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int i, int j) {\n        if (cities[i].cx != cities[j].cx) return cities[i].cx < cities[j].cx;\n        return cities[i].cy < cities[j].cy;\n    });\n\n    vector<vector<int>> groups;\n    int ofs = 0;\n    for (int i = 0; i < M; ++i) {\n        vector<int> grp;\n        for (int k = 0; k < G[i]; ++k, ++ofs) {\n            grp.push_back(idx[ofs]);\n        }\n        groups.push_back(grp);\n    }\n\n    set<pair<int, int>> used_query_edges; // Set of (min(u,v), max(u,v)) already output by queries\n\n    vector<vector<pair<int, int>>> mst_edges(M); // Final edge list for each group\n\n    int query_cnt = 0;\n    // For each group: gather MST edges from queries and/or center-MST as fallback patch\n    for (int gi = 0; gi < M; ++gi) {\n        const auto& grp = groups[gi];\n        int sz = grp.size();\n        set<pair<int, int>> group_edges;\n        vector<pair<int, int>> query_edges;\n\n        if (sz <= L && query_cnt < Q) {\n            // Query whole group\n            cout << \"? \" << sz;\n            for (int x : grp) cout << \" \" << x;\n            cout << endl; cout.flush();\n            for (int i = 0; i < sz-1; ++i) {\n                int u, v;\n                cin >> u >> v;\n                if (u > v) swap(u, v);\n                group_edges.emplace(u, v);\n            }\n            query_cnt++;\n        } else {\n            // Sliding windows\n            for (int st = 0; st < sz-1 && query_cnt < Q; st += (L-1)) {\n                int en = min(st+L, sz);\n                int actual = en - st;\n                if (actual < 2) break;\n                vector<int> subset(grp.begin()+st, grp.begin()+en);\n                cout << \"? \" << actual;\n                for (int x : subset) cout << \" \" << x;\n                cout << endl; cout.flush();\n                for (int i = 0; i < actual-1; ++i) {\n                    int u, v;\n                    cin >> u >> v;\n                    if (u > v) swap(u, v);\n                    group_edges.emplace(u, v);\n                }\n                query_cnt++;\n            }\n        }\n\n        // After all queries, collected group_edges may not be enough for tree\n        // Patch with MST on center-points\n        // Build graph (indexed by group vertex list order!)\n        int V = sz;\n        map<int,int> city_to_groupidx;\n        for (int i=0;i<sz;i++) city_to_groupidx[grp[i]]=i;\n\n        // Build conn graph, find CCs\n        UF uf(V);\n        for (auto [u,v]: group_edges) {\n            if (!city_to_groupidx.count(u) || !city_to_groupidx.count(v)) continue;\n            int a = city_to_groupidx[u], b = city_to_groupidx[v];\n            uf.unite(a,b);\n        }\n        // For each component, patch missing links via Kruskal on centers\n        vector<tuple<int,int,int>> center_edges;\n        for (int i = 0; i < sz; ++i) {\n            for (int j = i+1; j < sz; ++j) {\n                int u = grp[i], v = grp[j];\n                double dx = cities[u].cx - cities[v].cx;\n                double dy = cities[u].cy - cities[v].cy;\n                int faux_dist = (int)floor(sqrt(dx*dx+dy*dy));\n                center_edges.emplace_back(faux_dist, i, j);\n            }\n        }\n        sort(center_edges.begin(), center_edges.end());\n\n        // Build MST using (group_edges U center-edges) and output final tree\n        UF final_uf(V);\n        set<pair<int, int>> final_mst_edges = group_edges;\n        // First, union group_edges\n        for (auto [u,v]: group_edges) {\n            if (!city_to_groupidx.count(u) || !city_to_groupidx.count(v)) continue;\n            int a = city_to_groupidx[u], b = city_to_groupidx[v];\n            final_uf.unite(a,b);\n        }\n        // Add center-based edges if needed\n        for (auto [dist, i, j]: center_edges) {\n            if (final_mst_edges.size() >= sz-1) break;\n            if (final_uf.unite(i,j)) {\n                int u = grp[i], v = grp[j];\n                if (u > v) swap(u, v);\n                final_mst_edges.emplace(u, v);\n            }\n        }\n\n        // Output as vector and store\n        mst_edges[gi].clear();\n        for (auto [u,v]: final_mst_edges) {\n            mst_edges[gi].emplace_back(u, v);\n        }\n        // (not needed: extra check for if MST is complete, as final_uf will patch)\n    }\n    // Output answer\n    cout << \"!\" << endl;\n    for (int gi = 0; gi < M; ++gi) {\n        // output group\n        for (int i = 0; i < (int)groups[gi].size(); ++i) {\n            if (i) cout << \" \";\n            cout << groups[gi][i];\n        }\n        cout << endl;\n        // output edges\n        for (auto [u,v]: mst_edges[gi]) {\n            cout << u << \" \" << v << endl;\n        }\n    }\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Constants\nconstexpr int N = 20, M = 40;\nconstexpr int MAX_ACTIONS = 2 * N * M;\n\n// Directions and helpers\nconstexpr int DIRS = 4;\nconst int dx[DIRS] = {-1, 1, 0, 0}; // U, D, L, R\nconst int dy[DIRS] = {0, 0, -1, 1};\nconst char dirC[DIRS] = {'U', 'D', 'L', 'R'};\n\nstruct Pos {\n    int x, y;\n    bool operator==(const Pos& r) const { return x == r.x && y == r.y; }\n};\n\n// Try to slide from p in dir, return last cell we would land on (or -1 if blocked right away)\nPos slide_end(const Pos& p, int d, const vector<vector<bool>>& block) {\n    int nx = p.x, ny = p.y;\n    while (1) {\n        int tx = nx + dx[d], ty = ny + dy[d];\n        if (tx < 0 || tx >= N || ty < 0 || ty >= N) break;\n        if (block[tx][ty]) break;\n        nx = tx; ny = ty;\n    }\n    return {nx, ny};\n}\n\n// Return true if we can clear path between p1 and p2 (line, no block)\n// Assumes p1 and p2 are in the same row or column.\nbool clear_path_between(const Pos& p1, const Pos& p2, const vector<vector<bool>>& block) {\n    if (p1.x == p2.x) {\n        int sy = min(p1.y, p2.y), ey = max(p1.y, p2.y);\n        for (int y = sy + 1; y <= ey - 1; ++y)\n            if (block[p1.x][y])\n                return false;\n        return true;\n    }\n    if (p1.y == p2.y) {\n        int sx = min(p1.x, p2.x), ex = max(p1.x, p2.x);\n        for (int x = sx + 1; x <= ex - 1; ++x)\n            if (block[x][p1.y])\n                return false;\n        return true;\n    }\n    return false;\n}\n\n// Returns a Move sequence to get from src to tgt with Moves (BFS shortest path).\nvector<pair<char, char>> naive_moves(Pos src, Pos tgt, const vector<vector<bool>>& block) {\n    vector<vector<Pos>> prev(N, vector<Pos>(N, {-1, -1}));\n    queue<Pos> que;\n    que.push(src);\n    prev[src.x][src.y] = src;\n    while (!que.empty()) {\n        auto c = que.front(); que.pop();\n        if (c == tgt) break;\n        for (int d = 0; d < DIRS; ++d) {\n            int nx = c.x + dx[d], ny = c.y + dy[d];\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n            if (block[nx][ny]) continue;\n            if (prev[nx][ny].x != -1) continue;\n            prev[nx][ny] = c;\n            que.push({nx, ny});\n        }\n    }\n    // Reconstruct path\n    vector<Pos> path;\n    if (prev[tgt.x][tgt.y].x == -1) return {}; // unreachable\n    for (Pos p = tgt; !(p == src); p = prev[p.x][p.y])\n        path.push_back(p);\n    reverse(path.begin(), path.end());\n    // Convert to action sequence\n    vector<pair<char, char>> res;\n    Pos c = src;\n    for (auto& p : path) {\n        int d = -1;\n        for (int i = 0; i < 4; ++i)\n            if (c.x + dx[i] == p.x && c.y + dy[i] == p.y)\n                d = i;\n        res.emplace_back('M', dirC[d]);\n        c = p;\n    }\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Input\n    int n, m;\n    cin >> n >> m;\n    vector<Pos> targets(m);\n    for (int i = 0; i < m; ++i)\n        cin >> targets[i].x >> targets[i].y;\n\n    vector<vector<bool>> block(N, vector<bool>(N, false));\n    vector<pair<char, char>> actions;\n\n    Pos cur = targets[0];\n\n    for (int i = 1; i < m; ++i) {\n        Pos next = targets[i];\n\n        // If in line (row/col), try to slide\n        bool did = false;\n        for (int d = 0; d < 4; ++d) {\n            int tx = cur.x, ty = cur.y;\n            if ((d == 0 && next.x >= tx && next.y == ty) ||\n                (d == 1 && next.x <= tx && next.y == ty) ||\n                (d == 2 && next.y >= ty && next.x == tx) ||\n                (d == 3 && next.y <= ty && next.x == tx))\n                continue; // wrong direction\n\n            // For our actual d\n            if ((d == 0 || d == 1) && cur.y == next.y && cur.x != next.x) {\n                // same col, check direction\n                int sd = (next.x > cur.x) ? 1 : 0;\n                if (sd != d) continue;\n                if (clear_path_between(cur, next, block)) {\n                    // Would we overshoot sliding in this dir?\n                    Pos landing = slide_end(cur, d, block);\n                    if (landing == next) {\n                        actions.emplace_back('S', dirC[d]);\n                        cur = next;\n                        did = true;\n                        break;\n                    } else if ((d == 0 && next.x > 0 && !block[next.x-1][next.y]) ||\n                               (d == 1 && next.x < N-1 && !block[next.x+1][next.y])) {\n                        // Place a block after the target, so slide will stop on it\n                        int bx = (d == 0) ? next.x-1 : next.x+1;\n                        int by = next.y;\n                        actions.emplace_back('A', dirC[d]);\n                        block[bx][by] = true;\n                        actions.emplace_back('S', dirC[d]);\n                        cur = next;\n                        // Remove the block after\n                        actions.emplace_back('A', dirC[d]);\n                        block[bx][by] = false;\n                        did = true;\n                        break;\n                    }\n                }\n            }\n            else if ((d == 2 || d == 3) && cur.x == next.x && cur.y != next.y) {\n                int sd = (next.y > cur.y) ? 3 : 2;\n                if (sd != d) continue;\n                if (clear_path_between(cur, next, block)) {\n                    Pos landing = slide_end(cur, d, block);\n                    if (landing == next) {\n                        actions.emplace_back('S', dirC[d]);\n                        cur = next;\n                        did = true;\n                        break;\n                    } else if ((d == 2 && next.y > 0 && !block[next.x][next.y-1]) ||\n                               (d == 3 && next.y < N-1 && !block[next.x][next.y+1])) {\n                        int bx = next.x;\n                        int by = (d == 2) ? next.y-1 : next.y+1;\n                        actions.emplace_back('A', dirC[d]);\n                        block[bx][by] = true;\n                        actions.emplace_back('S', dirC[d]);\n                        cur = next;\n                        actions.emplace_back('A', dirC[d]);\n                        block[bx][by] = false;\n                        did = true;\n                        break;\n                    }\n                }\n            }\n        }\n        if (did) continue;\n\n        // Default: just move\n        vector<pair<char, char>> path = naive_moves(cur, next, block);\n        for (auto& act : path) actions.push_back(act);\n        cur = next;\n    }\n\n    // Output actions\n    for (auto& ac : actions)\n        cout << ac.first << ' ' << ac.second << '\\n';\n}"},"4":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing i64 = int64_t;\n\nstruct Rect {\n    int x1, y1, x2, y2; // [x1,x2), [y1,y2)\n    i64 area() const { return i64(x2-x1) * i64(y2-y1); }\n    bool contains(double x, double y) const {\n        return x > x1 && x < x2 && y > y1 && y < y2;\n    }\n    bool overlap(const Rect& o) const {\n        // Proper area overlap (no just touch)\n        return !(x2 <= o.x1 || x1 >= o.x2 || y2 <= o.y1 || y1 >= o.y2);\n    }\n};\n\nstruct Company {\n    int id, x, y;\n    i64 r;\n    Rect rect;\n};\n\nconstexpr int GRID_SIZE = 10000;\n\nint n;\nvector<Company> companies;\nvector<Rect> placedRects;\n\nbool checkOverlap(const Rect& r) {\n    for (const auto& o : placedRects)\n        if (r.overlap(o)) return true;\n    return false;\n}\n\nRect try_place(int cx, int cy, i64 ri) {\n    int best_w = 0, best_h = 0, best_shift_x = 0, best_shift_y = 0;\n    double best_score = 1e18;\n    vector<pair<int,int>> attempts;\n    int sqr = max(1, int(std::sqrt(double(ri))));\n    for (int dw = -2; dw <= 2; ++dw) {\n        int w = max(1, sqr + dw);\n        int h = max(1, int((ri + w-1)/w));\n        if (i64(w)*h >= ri) attempts.emplace_back(w,h);\n        if (i64(h)*w >= ri && h!=w) attempts.emplace_back(h,w);\n    }\n    for (auto [w, h]: attempts) {\n        for (int dx=-1;dx<=1;++dx)for(int dy=-1;dy<=1;++dy){\n            int x1 = std::clamp(cx - w/2 + dx, 0, GRID_SIZE-w);\n            int y1 = std::clamp(cy - h/2 + dy, 0, GRID_SIZE-h);\n            int x2 = x1+w, y2 = y1+h;\n            if (!(x1 < x2 && y1 < y2)) continue;\n            Rect r{x1, y1, x2, y2};\n            double xx = cx+0.5, yy = cy+0.5;\n            if (xx <= x1 || xx >= x2 || yy <= y1 || yy >= y2) continue;\n            if (checkOverlap(r)) continue;\n            double score = abs(double(r.area() - ri)) + 0.1*(w-h)*(w-h);\n            if (score < best_score) {\n                best_score = score; best_w=w; best_h=h; best_shift_x=x1; best_shift_y=y1;\n            }\n        }\n    }\n    if (best_score < 1e17) {\n        return Rect{best_shift_x, best_shift_y, best_shift_x+best_w, best_shift_y+best_h};\n    }\n    return Rect{-1,-1,-1,-1};\n}\n\nRect emergency_fallback(int px, int py) {\n    vector<pair<int,int>> deltas = {\n        {0,0},{-1,0},{1,0},{0,-1},{0,1},\n        {-1,-1},{-1,1},{1,-1},{1,1},\n        {-2,0},{2,0},{0,-2},{0,2}\n    };\n    for (auto [dx,dy] : deltas) {\n        int x = px + dx, y = py + dy;\n        if (x < 0 || x >= GRID_SIZE) continue;\n        if (y < 0 || y >= GRID_SIZE) continue;\n        Rect r{x, y, x+1, y+1};\n        if (!checkOverlap(r)) return r;\n    }\n    for (int dist = 1; dist <= 20; ++dist) {\n        for (int dx = -dist; dx <= dist; ++dx) {\n            for (int dy = -dist; dy <= dist; ++dy) {\n                if (abs(dx) != dist && abs(dy) != dist) continue;\n                int x = px + dx, y = py + dy;\n                if (x < 0 || x >= GRID_SIZE) continue;\n                if (y < 0 || y >= GRID_SIZE) continue;\n                Rect r{x, y, x+1, y+1};\n                if (!checkOverlap(r)) return r;\n            }\n        }\n    }\n    for (int x = 0; x < GRID_SIZE; ++x) for (int y = 0; y < GRID_SIZE; ++y) {\n        Rect r{x,y,x+1,y+1};\n        if (!checkOverlap(r)) return r;\n    }\n    return Rect{0,0,1,1};\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    cin >> n;\n    companies.resize(n);\n    for (int i = 0; i < n; ++i) {\n        int x, y; i64 r;\n        cin >> x >> y >> r;\n        companies[i] = Company{i, x, y, r, {}};\n    }\n    sort(companies.begin(), companies.end(), [&](const Company& a, const Company& b){\n        return a.r > b.r;\n    });\n    placedRects.clear();\n    for (auto& comp : companies) {\n        Rect rect;\n        i64 tr = comp.r;\n        bool placed = false;\n        int area_shrink = 0;\n        while (area_shrink < 15) {\n            i64 req_area = std::max(i64(1), tr - tr * area_shrink / 100);\n            rect = try_place(comp.x, comp.y, req_area);\n            if (rect.x1 != -1) {\n                placed = true;\n                break;\n            }\n            area_shrink += 2;\n        }\n        if (!placed) {\n            rect = emergency_fallback(comp.x, comp.y);\n        }\n        comp.rect = rect;\n        placedRects.push_back(rect);\n    }\n    sort(companies.begin(), companies.end(), [&](const Company& a, const Company& b){\n        return a.id < b.id;\n    });\n    for (auto& comp : companies) {\n        auto& r = comp.rect;\n        cout << r.x1 << ' ' << r.y1 << ' ' << r.x2 << ' ' << r.y2 << '\\n';\n    }\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Directions: U, D, L, R\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\nconst char dch[4] = {'U', 'D', 'L', 'R'};\nconst int N = 50;\nconst int BEAM_WIDTH = 32;  // you can try 24, 32, or 40 (bench it!)\n\nstruct Tile {\n    vector<pair<int, int>> cells;\n    set<int> adj;\n    int max_val = -1, max_cell_i = -1, max_cell_j = -1, sum_val = 0;\n};\n\nint si, sj;\nint t[N][N];      // tile id of (i,j)\nint p[N][N];      // score of (i,j)\nvector<Tile> tiles;\nint ntiles;\n\nvoid preprocess() {\n    map<int, vector<pair<int,int>>> tile_cells;\n    for(int i = 0; i < N; ++i) for(int j = 0; j < N; ++j)\n        tile_cells[t[i][j]].emplace_back(i, j);\n    ntiles = tile_cells.size();\n    tiles.assign(ntiles, Tile());\n    for(const auto &[tid, cells] : tile_cells) {\n        Tile tile;\n        tile.cells = cells;\n        int maxv = -1, maxi = -1, maxj = -1, sumv = 0;\n        for(auto &[i, j] : tile.cells) {\n            sumv += p[i][j];\n            if(p[i][j] > maxv) { maxv = p[i][j]; maxi = i; maxj = j; }\n        }\n        tile.max_val = maxv;\n        tile.max_cell_i = maxi;\n        tile.max_cell_j = maxj;\n        tile.sum_val = sumv;\n        tiles[tid] = tile;\n    }\n    for(int i = 0; i < N; ++i) for(int j = 0; j < N; ++j) {\n        int tid = t[i][j];\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 >= N || nj >= N) continue;\n            int ntid = t[ni][nj];\n            if(ntid != tid)\n                tiles[tid].adj.insert(ntid);\n        }\n    }\n}\n\nstruct State {\n    int ci, cj;\n    int curr_tile;\n    int score;\n    vector<bool> tile_used;\n    string path;\n    State() = default;\n    State(int _i, int _j)\n        : ci(_i), cj(_j), curr_tile(t[_i][_j]), score(p[_i][_j]),\n            tile_used(ntiles, false), path(\"\") { tile_used[curr_tile] = true; }\n    State(int _ci, int _cj, int _curr_tile, int _score, const vector<bool> &_tile_used, const string &_path)\n        : ci(_ci), cj(_cj), curr_tile(_curr_tile), score(_score),\n          tile_used(_tile_used), path(_path) {}\n    State(int _ci, int _cj, int _curr_tile, int _score, vector<bool> &&_tile_used, string &&_path)\n        : ci(_ci), cj(_cj), curr_tile(_curr_tile), score(_score),\n          tile_used(std::move(_tile_used)), path(std::move(_path)) {}\n    bool operator<(const State& o) const {\n        if(score != o.score) return score > o.score;\n        return path.size() > o.path.size();\n    }\n};\n\nstd::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count());\n\nstring beam_search_path() {\n    State initial(si, sj);\n    vector<State> beam;\n    beam.emplace_back(initial);\n\n    int best_score = initial.score;\n    string best_path = \"\";\n\n    while (!beam.empty()) {\n        vector<State> next_beam;\n        for (const auto& state : beam) {\n            vector<tuple<int, int, int, int, int, int>> cand; //(score2, random, d, ni, nj, n_tid)\n            for(int d = 0; d < 4; ++d) {\n                int ni = state.ci + di[d], nj = state.cj + dj[d];\n                if(ni < 0 || nj < 0 || ni >= N || nj >= N) continue;\n                int n_tid = t[ni][nj];\n                if(state.tile_used[n_tid]) continue;\n                int adj_nextbest = 0;\n                // Depth-2 lookahead: if we move there, what's the best next tile score?\n                vector<bool> used2 = state.tile_used; used2[n_tid]=true;\n                for(int d2=0; d2<4; ++d2) {\n                    int ni2=ni+di[d2], nj2=nj+dj[d2];\n                    if(ni2<0||nj2<0||ni2>=N||nj2>=N)continue;\n                    int n2_tid = t[ni2][nj2];\n                    if(used2[n2_tid])continue;\n                    adj_nextbest = max(adj_nextbest, p[ni2][nj2]);\n                }\n                int score2 = 10000*p[ni][nj] + adj_nextbest;\n                int r = uniform_int_distribution<int>(0, 9999)(rng);\n                cand.emplace_back(score2, r, d, ni, nj, n_tid);\n            }\n            if(cand.empty()) {\n                if(state.score > best_score) { best_score = state.score; best_path = state.path; }\n                continue;\n            }\n            sort(cand.rbegin(), cand.rend());\n            for (size_t kk = 0; kk < cand.size(); ++kk) {\n                auto [valh, rnd, d, ni, nj, n_tid] = cand[kk];\n                auto next_tile_used = state.tile_used;\n                next_tile_used[n_tid] = true;\n                string npath = state.path + dch[d];\n                next_beam.emplace_back(ni, nj, n_tid, state.score + p[ni][nj], std::move(next_tile_used), std::move(npath));\n            }\n        }\n        if(next_beam.empty()) break;\n        if((int)next_beam.size() > BEAM_WIDTH) {\n            std::partial_sort(next_beam.begin(), next_beam.begin() + BEAM_WIDTH, next_beam.end());\n            next_beam.resize(BEAM_WIDTH);\n        }else{\n            sort(next_beam.begin(), next_beam.end());\n        }\n        beam = std::move(next_beam);\n    }\n    if(best_path.empty() && !beam.empty()) best_path = beam.front().path;\n    return best_path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    cin >> si >> sj;\n    for(int i = 0; i < N; ++i)\n        for(int j = 0; j < N; ++j)\n            cin >> t[i][j];\n    for(int i = 0; i < N; ++i)\n        for(int j = 0; j < N; ++j)\n            cin >> p[i][j];\n    preprocess();\n    string path = beam_search_path();\n    cout << path << '\\n';\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Constants\nconstexpr int N = 30;\nconstexpr int Q = 1000;\nconstexpr int DIR = 4;\nconst char dir_chars[DIR] = {'U','D','L','R'};\nconst int dx[DIR] = {-1,+1,0,0}, dy[DIR] = {0,0,-1,+1};\n\n// Edge structure for statistics\nstruct EdgeInfo {\n    double est = 5000.0;\n    int count = 0;\n    double sum = 0.0;\n    bool known = false;\n    \n    void update(double val) {\n        sum += val;\n        count++;\n        est = sum / count;\n    }\n    void add_sample(double val, double smoothing=0.8) {\n        if (!known) { est = val; known=true; return; }\n        est = smoothing*est + (1-smoothing)*val;\n    }\n};\n\n// Edge model: grid of edge estimates, separate for horizontal and vertical\nEdgeInfo horiz[N][N-1]; // between (i,j) and (i,j+1)\nEdgeInfo vert[N-1][N]; // between (i,j) and (i+1,j)\n\n// For edge encoding\ninline bool in_grid(int i, int j) { return 0<=i && i<N && 0<=j && j<N; }\n\n// Returns list of moves ('U','D','L','R') for s to t using current edge estimates\nvector<char> estimate_path(pair<int,int> s, pair<int,int> t) {\n    using T = tuple<double,int,int,string>; // cost, i, j, path\n    priority_queue<T, vector<T>, greater<>> pq;\n    vector<vector<double>> dist(N, vector<double>(N, 1e18));\n    vector<vector<pair<int,int>>> prev(N, vector<pair<int,int>>(N, {-1,-1}));\n    vector<vector<int>> previdx(N, vector<int>(N, -1));\n    dist[s.first][s.second] = 0;\n    pq.emplace(0.0, s.first, s.second, \"\");\n    while (!pq.empty()) {\n        auto [cost, i, j, p] = pq.top(); pq.pop();\n        if (make_pair(i,j)==t) {\n            // reconstruct path\n            vector<char> res;\n            int x = t.first, y = t.second;\n            while (prev[x][y].first != -1) {\n                int px = prev[x][y].first, py = prev[x][y].second;\n                int d = previdx[x][y];\n                res.push_back(dir_chars[d]);\n                x=px; y=py;\n            }\n            reverse(res.begin(), res.end());\n            return res;\n        }\n        if (cost > dist[i][j]) continue;\n        for (int d=0; d<4; ++d) {\n            int ni = i+dx[d], nj = j+dy[d];\n            if (!in_grid(ni, nj)) continue;\n            double ecost;\n            if (d==0) ecost = vert[i-1][j].est; // up: between (i-1,j)-(i,j)\n            if (d==1) ecost = vert[i][j].est;   // down: between (i,j)-(i+1,j)\n            if (d==2) ecost = horiz[i][j-1].est; // left: between (i,j-1)-(i,j)\n            if (d==3) ecost = horiz[i][j].est;   // right: between (i,j)-(i,j+1)\n            if (dist[ni][nj] > dist[i][j] + ecost) {\n                dist[ni][nj] = dist[i][j]+ecost;\n                prev[ni][nj] = {i,j};\n                previdx[ni][nj] = d;\n                pq.emplace(dist[ni][nj], ni, nj, p + dir_chars[d]);\n            }\n        }\n    }\n    // never reached: should not happen\n    return {};\n}\n\n// Map moves to edges for updating\nvoid update_edges(pair<int,int> s, const vector<char>& path, double total_edge_len) {\n    vector<pair<int,int>> wayp;\n    wayp.push_back(s);\n    int x = s.first, y = s.second;\n    for (char c: path) {\n        if (c=='U') x--;\n        else if (c=='D') x++;\n        else if (c=='L') y--;\n        else if (c=='R') y++;\n        wayp.emplace_back(x,y);\n    }\n    int plen = (int)path.size();\n    if (plen==0) return;\n    double unit = total_edge_len / plen; // naive: assign equally (no better info!)\n    for (int i=0; i<plen; ++i) {\n        int x0 = wayp[i].first, y0 = wayp[i].second;\n        int x1 = wayp[i+1].first, y1 = wayp[i+1].second;\n        // edge direction\n        if (x0==x1 && y0+1==y1) {\n            horiz[x0][y0].add_sample(unit);\n        } else if (x0==x1 && y0-1==y1) {\n            horiz[x0][y1].add_sample(unit);\n        } else if (x0+1==x1 && y0==y1) {\n            vert[x0][y0].add_sample(unit);\n        } else if (x0-1==x1 && y0==y1) {\n            vert[x1][y0].add_sample(unit);\n        } else assert(false);\n    }\n}\n\n// Early in the contest, randomly explore to cover more edges\nvector<char> random_path(pair<int,int> s, pair<int,int> t, mt19937 &rng) {\n    int x = s.first, y = s.second;\n    int tx = t.first, ty = t.second;\n    vector<char> path;\n    int dx_ = tx - x, dy_ = ty - y;\n    vector<char> moves;\n    if (dx_ > 0) moves.insert(moves.end(), dx_, 'D');\n    else moves.insert(moves.end(), -dx_, 'U');\n    if (dy_ > 0) moves.insert(moves.end(), dy_, 'R');\n    else moves.insert(moves.end(), -dy_, 'L');\n    shuffle(moves.begin(), moves.end(), rng); // randomize order\n    // Create actual path via valid movement\n    for(char c : moves) path.push_back(c);\n    return path;\n}\n\n// Readline helpers\nint si, sj, ti, tj;\nvoid fast_scan() { scanf(\"%d%d%d%d\", &si, &sj, &ti, &tj); }\nint fast_int() { int x; scanf(\"%d\", &x); return x; }\n\nint main() {\n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n\n    for (int query=0; query<Q; ++query) {\n        fast_scan();\n        pair<int,int> s = {si, sj}, t = {ti, tj};\n        vector<char> path_chars;\n        if (query < 100) {\n            path_chars = random_path(s, t, rng); // randomize for first 100 queries\n        } else {\n            path_chars = estimate_path(s, t);\n            if (path_chars.size()==0) { // fallback\n                path_chars = random_path(s, t, rng);\n            }\n        }\n        // Output path\n        string out(path_chars.begin(), path_chars.end());\n        printf(\"%s\\n\", out.c_str());\n        fflush(stdout);\n\n        // Input feedback (rounded noisy cost)\n        int feedback = fast_int();\n\n        // Update edge estimates using feedback length\n        update_edges(s, path_chars, feedback);\n\n        // (optional: debug)\n        // if (query%100==99) cerr << \"[[\"<<query<<\"]]\\n\";\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\n// For random numbers\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Returns list of tuples (direction (0=row,1=col), i, shift)\nvector<tuple<int,int,int>> all_positions(int N, int len) {\n    vector<tuple<int,int,int>> positions;\n    for(int dir=0;dir<2;++dir) // 0=row,1=col\n        for(int i=0;i<N;++i)\n            for(int shift=0;shift<N;++shift)\n                positions.emplace_back(dir,i,shift);\n    return positions;\n}\n\n// Try placing s in matrix a at (dir,i,shift)\n// Return if conflict (false if conflict), and collect pos_painted (to mark for this string)\nbool can_place(const vector<string> &a, int N, const string &s,\n               int dir, int i, int shift, vector<pair<int,int>> &pos_painted) {\n    int k = s.size();\n    pos_painted.clear();\n    for(int p=0;p<k;++p){\n        int x = (dir==0)? i : (i+p)%N;\n        int y = (dir==0)? (shift+p)%N : shift;\n        if(a[x][y]=='.' || a[x][y]==s[p]) {\n            pos_painted.emplace_back(x,y);\n        } else {\n            return false;\n        }\n    }\n    return true;\n}\n\n// Place s in matrix a at given places\nvoid do_paint(vector<string> &a, const string &s, const vector<pair<int,int>> &pos_painted, int dir, int i, int shift) {\n    int k = s.size();\n    for(int p=0;p<k;++p){\n        int x = (dir==0)? i : (i+p)%a.size();\n        int y = (dir==0)? (shift+p)%a.size() : shift;\n        a[x][y] = s[p];\n    }\n}\n\n// Checks if s is covered somewhere in matrix a as row/col subsequence (using torus)\nbool is_covered(const vector<string> &a, const string &s) {\n    int N = a.size();\n    int k = s.size();\n    for(int i=0;i<N;++i){\n        for(int shift=0;shift<N;++shift){\n            // Row\n            bool ok=true;\n            for(int p=0;p<k;++p){\n                if(a[i][(shift+p)%N]!=s[p]) { ok=false; break; }\n            }\n            if(ok) return true;\n            // Col\n            ok=true;\n            for(int p=0;p<k;++p){\n                if(a[(i+p)%N][shift]!=s[p]) { ok=false; break; }\n            }\n            if(ok) return true;\n        }\n    }\n    return false;\n}\n\nint main() {\n    ios::sync_with_stdio(0); cin.tie(0);\n    int N, M;\n    cin >> N >> M;\n    vector<string> s(M);\n    for(int i=0;i<M;++i) cin >> s[i];\n\n    vector<string> best_ans;\n    int best_cover = 0;\n\n    // Try several random processings to maximize c\n    int TRIALS = 7; // You can tune this\n    for(int trial=0; trial<TRIALS; ++trial){\n        vector<string> a(N, string(N,'.'));\n        vector<int> idx(M);\n        iota(idx.begin(), idx.end(), 0);\n        shuffle(idx.begin(), idx.end(), rng);\n\n        // Record for each cell the possible frequency of candidates (for later fill)\n        vector<vector<array<int,8>>> freq(N,vector<array<int,8>>(N));\n        for(int t=0;t<M;++t){\n            const string &si = s[t];\n            int k = si.size();\n            for(int dir=0;dir<2;++dir)\n                for(int i=0;i<N;++i)\n                    for(int shift=0;shift<N;++shift){\n                        for(int p=0;p<k;++p) {\n                            int x = (dir==0)? i : (i+p)%N;\n                            int y = (dir==0)? (shift+p)%N : shift;\n                            freq[x][y][si[p]-'A']++;\n                        }\n                    }\n        }\n\n        // Main Greedy: Try to pack as many s[idx[*]] as possible\n        vector<bool> used(M, false);\n        for(int tt=0;tt<M;++tt){\n            int i_s = idx[tt];\n            const string &si = s[i_s];\n            int k = si.size();\n\n            // Find all possible placements without conflict\n            vector<tuple<int,int,int>> possible;\n            vector<pair<int,int>> buf;\n            for(int dir=0;dir<2;++dir)\n                for(int i=0;i<N;++i)\n                    for(int shift=0;shift<N;++shift)\n                        if(can_place(a,N,si,dir,i,shift,buf))\n                            possible.emplace_back(dir,i,shift);\n\n            if(possible.empty()) continue;\n\n            // Pick randomly (could pick \"minimally fills new cells\", or \"max freq\", but use random for now)\n            auto [dir,i,shift] = possible[rng()%possible.size()];\n            // Actually place it\n            do_paint(a, si, buf, dir, i, shift);\n            used[i_s] = true;\n        }\n        // Final fill-in: Remaining '.' fill with most frequent guess (from freq), or 'A'\n        for(int i=0;i<N;++i) for(int j=0;j<N;++j) if(a[i][j]=='.') {\n            int maxv = 0; char c='A';\n            for(int t=0;t<8;++t) if(freq[i][j][t]>maxv) {\n                maxv = freq[i][j][t];\n                c = 'A' + t;\n            }\n            a[i][j] = c;\n        }\n\n        // Now count how many s are matched as subsequence\n        int cover = 0;\n        for(int i=0;i<M;++i) if(is_covered(a, s[i])) cover++;\n\n        if(cover > best_cover) {\n            best_cover = cover;\n            best_ans = a;\n            if(cover == M) break; // optimal (no point in more tries)\n        }\n    }\n    // Output final matrix\n    for(int i=0;i<N;++i)\n        cout << best_ans[i] << '\\n';\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int DX[4] = {-1, 1, 0, 0};\nconstexpr int DY[4] = {0, 0, -1, 1};\nconstexpr char DIRS[4] = {'U', 'D', 'L', 'R'};\n\nusing Pos = pair<int, int>;\n\n// ---- Bitset ----\nstruct FastBitSet {\n    vector<uint64_t> bs;\n    int size;\n    FastBitSet(int n) : size(n), bs((n+63)>>6) {}\n    void set(int k) { bs[k>>6] |= 1ULL<<(k&63); }\n    void reset(int k) { bs[k>>6] &= ~(1ULL<<(k&63)); }\n    bool test(int k) const { return (bs[k>>6]>>(k&63))&1; }\n    void operator|=(const FastBitSet& rhs) {\n        for (int i=0; i<bs.size(); ++i) bs[i] |= rhs.bs[i];\n    }\n    FastBitSet operator|(const FastBitSet& rhs) const {\n        FastBitSet ret(*this); ret |= rhs; return ret;\n    }\n    int count() const { int res=0; for(auto x:bs) res+=__builtin_popcountll(x); return res; }\n    bool all() const {\n        int lim = size, full = lim/64, rest=lim%64;\n        for(int i=0;i<full;++i) if(bs[i]!=~0ULL) return false;\n        if(rest) return (bs[full]&((1ULL<<rest)-1))==((1ULL<<rest)-1);\n        return true;\n    }\n    vector<int> to_vector() const {vector<int> r; for(int i=0;i<size;++i)if(test(i))r.push_back(i); return r;}\n};\n\n// ---- Utility Mapping (i,j) <-> id ----\nstruct RoadMapper {\n    int N;\n    vector<vector<int>> idx_of;\n    vector<Pos> pos_of;\n    int num_roads;\n    RoadMapper(int N_, const vector<string>& grid):N(N_){\n        idx_of.assign(N,vector<int>(N,-1));\n        int id=0;\n        for(int i=0;i<N;++i)for(int j=0;j<N;++j)\n            if('5'<=grid[i][j]&&grid[i][j]<='9'){idx_of[i][j]=id++;pos_of.push_back({i,j});}\n        num_roads=id;\n    }\n    int id(int i,int j) const {return (0<=i&&i<N&&0<=j&&j<N)?idx_of[i][j]:-1;}\n};\n// ---- Visibility Table ----\nstruct Visibility {\n    int N,num_roads;\n    RoadMapper& mapper;\n    vector<FastBitSet> vis;\n    Visibility(int N_,RoadMapper&m,const vector<string>&grid)\n        :N(N_),mapper(m),num_roads(m.num_roads),vis(num_roads,FastBitSet(m.num_roads)) {\n        auto& idx=mapper.idx_of;\n        for(int k=0;k<num_roads;++k){\n            auto [i,j]=mapper.pos_of[k];\n            // row left\n            for(int jj=j;jj>=0;--jj){\n                if(idx[i][jj]==-1)break;\n                vis[k].set(idx[i][jj]);\n            }\n            // row right\n            for(int jj=j+1;jj<N;++jj){\n                if(idx[i][jj]==-1)break;\n                vis[k].set(idx[i][jj]);\n            }\n            // col up\n            for(int ii=i;ii>=0;--ii){\n                if(idx[ii][j]==-1)break;\n                vis[k].set(idx[ii][j]);\n            }\n            // col down\n            for(int ii=i+1;ii<N;++ii){\n                if(idx[ii][j]==-1)break;\n                vis[k].set(idx[ii][j]);\n            }\n            vis[k].set(k);\n        }\n    }\n};\n// ---- BFS Path ---\nvector<Pos> bfs_shortest_path(const vector<string>& grid, int N, Pos st, Pos gl) {\n    if (st == gl) return {st};\n    vector<vector<Pos>> pre(N, vector<Pos>(N, {-1,-1}));\n    queue<Pos> que; que.push(st);\n    pre[st.first][st.second]=st;\n    while(!que.empty()){\n        auto [i,j]=que.front();que.pop();\n        for(int d=0;d<4;++d){\n            int ni=i+DX[d], nj=j+DY[d];\n            if(ni<0||nj<0||ni>=N||nj>=N)continue;\n            if(!(grid[ni][nj]>='5'&&grid[ni][nj]<='9'))continue;\n            if(pre[ni][nj].first!=-1)continue;\n            pre[ni][nj]={i,j};\n            if(make_pair(ni,nj)==gl){\n                vector<Pos> ret;\n                Pos cur=gl;\n                while(cur!=st){ret.push_back(cur);cur=pre[cur.first][cur.second];}\n                ret.push_back(st);\n                reverse(ret.begin(),ret.end());\n                return ret;\n            }\n            que.push({ni,nj});\n        }\n    }\n    return {};\n}\nint path_length(const vector<string>& grid, int N, Pos st, Pos gl, const vector<vector<int>>& move_cost){\n    if(st==gl)return 0;\n    // Dijkstra: cost is \"move to cell\" cost\n    priority_queue<tuple<int,int,int>,vector<tuple<int,int,int>>,greater<>> pq;\n    vector<vector<int>> dist(N,vector<int>(N,INT_MAX));\n    pq.emplace(0,st.first,st.second); dist[st.first][st.second]=0;\n    while(!pq.empty()){\n        auto [d,i,j]=pq.top();pq.pop();\n        if(make_pair(i,j)==gl) return d;\n        if(dist[i][j]<d)continue;\n        for(int dir=0;dir<4;++dir){\n            int ni=i+DX[dir],nj=j+DY[dir];\n            if(ni<0||nj<0||ni>=N||nj>=N)continue;\n            if(move_cost[ni][nj]<0)continue;\n            int nd=d+move_cost[ni][nj];\n            if(dist[ni][nj]>nd){\n                dist[ni][nj]=nd; pq.emplace(nd,ni,nj);\n            }\n        }\n    }\n    return INT_MAX;\n}\nchar move_dir(const Pos& from, const Pos& to){\n    int di=to.first-from.first,dj=to.second-from.second;\n    for(int d=0;d<4;++d)if(di==DX[d]&&dj==DY[d])return DIRS[d];\n    return '\\0';\n}\n\n// ---- Greedy Set Cover: Pick scan points ----\nvector<int> greedy_scan_cover(const RoadMapper& m, const Visibility& vis, int si, int sj){\n    int num=m.num_roads;\n    FastBitSet covered(num);\n    int start_id=m.id(si,sj);\n    covered|=vis.vis[start_id];\n    vector<int> scan_pts; scan_pts.push_back(start_id);\n    vector<bool> used(num,false);\n    used[start_id]=true;\n    while(!covered.all()){\n        int best=-1,gain=-1;\n        for(int k=0;k<num;++k){\n            if(used[k])continue;\n            int cnt=0;\n            for(int x=0;x<num;++x)\n                if(vis.vis[k].test(x)&&!covered.test(x)) ++cnt;\n            if(cnt>gain){gain=cnt;best=k;}\n        }\n        if(best==-1)break;\n        scan_pts.push_back(best);\n        covered|=vis.vis[best];\n        used[best]=true;\n    }\n    return scan_pts;\n}\n\n// ---- Order scan points (NN) ----\nvector<int> order_scan_points(const vector<int>& scan_pts, int start_idx, int N, const vector<string>& grid, const RoadMapper& m){\n    int L=scan_pts.size();\n    vector<vector<int>> dist(L, vector<int>(L, INT_MAX));\n    vector<vector<int>> move_cost(N,vector<int>(N,-1));\n    for(int i=0;i<N;++i)for(int j=0;j<N;++j)\n        if('5'<=grid[i][j]&&grid[i][j]<='9') move_cost[i][j]=grid[i][j]-'0';\n    // Precompute all-pairs costs (real movement cost)\n    for(int i=0;i<L;++i) for(int j=0;j<L;++j){\n        if(i==j){dist[i][j]=0; continue;}\n        int t=path_length(grid,N,m.pos_of[scan_pts[i]],m.pos_of[scan_pts[j]],move_cost);\n        dist[i][j]=t;\n    }\n    // Nearest Neighbor TSP\n    vector<int> order={start_idx};\n    vector<bool> vis(L,false); vis[start_idx]=true;\n    int cur=start_idx;\n    for(int step=1;step<L;++step){\n        int nxt=-1,best=INT_MAX;\n        for(int i=0;i<L;++i){\n            if(vis[i])continue;\n            if(dist[cur][i]<best){best=dist[cur][i];nxt=i;}\n        }\n        order.push_back(nxt); vis[nxt]=true;\n        cur=nxt;\n    }\n    // Ensure return-to-start logic in main\n    return order;\n}\n\n// ---- Build Actual Route (including segment walks) ----\nvector<Pos> build_route(const vector<int>& scan_pts, const vector<int>& order, const RoadMapper& m, const vector<string>& grid){\n    vector<Pos> route;\n    for(int ix=0;ix<order.size();++ix){\n        int cur_pt=scan_pts[order[ix]];\n        Pos cur_pos=m.pos_of[cur_pt];\n        if(route.empty()){route.push_back(cur_pos);}\n        else{\n            auto seg=bfs_shortest_path(grid,grid.size(),route.back(),cur_pos);\n            for(int i=1;i<seg.size();++i) route.push_back(seg[i]);\n        }\n    }\n    // tour: return to origin\n    if(route.front()!=route.back()){\n        auto seg=bfs_shortest_path(grid,grid.size(),route.back(),route.front());\n        for(int i=1;i<seg.size();++i) route.push_back(seg[i]);\n    }\n    // remove duplicate consecutive\n    vector<Pos> clean{route[0]};\n    for(int i=1;i<route.size();++i)\n        if(route[i]!=route[i-1]) clean.push_back(route[i]);\n    return clean;\n}\n\n// ---- Output ----\nint main() {\n    ios::sync_with_stdio(0);cin.tie(0);\n    int N,si,sj; cin>>N>>si>>sj;\n    vector<string> grid(N);\n    for(int i=0;i<N;++i)cin>>grid[i];\n    RoadMapper m(N,grid);\n    Visibility vis(N,m,grid);\n\n    // 1. Set cover\n    auto scan_pts=greedy_scan_cover(m,vis,si,sj);\n    int start_idx=0;\n    for(int i=0;i<scan_pts.size();++i)\n        if(m.pos_of[scan_pts[i]]==Pos(si,sj)) start_idx=i;\n    // 2. Order visit\n    auto order=order_scan_points(scan_pts,start_idx,N,grid,m);\n    // 3. Build path\n    auto route=build_route(scan_pts,order,m,grid);\n\n    // 4. Output moves\n    string res;\n    bool ok = true;\n    for(int i=1;i<route.size();++i){\n        char c=move_dir(route[i-1],route[i]);\n        if(c=='\\0') ok=false;\n        res+=c;\n    }\n    // Validate/correct\n    int ci=si,cj=sj;\n    for(char c:res){\n        int d=find(DIRS,DIRS+4,c)-DIRS;\n        if(d>=4){ok=false; break;}\n        int ni=ci+DX[d],nj=cj+DY[d];\n        if(ni<0||nj<0||ni>=N||nj>=N||!(grid[ni][nj]>='5'&&grid[ni][nj]<='9')){ok=false;break;}\n        ci=ni; cj=nj;\n    }\n    if(!ok||ci!=si||cj!=sj) { cout<<'\\n'; return 0; }\n    cout<<res<<endl;\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int MAX_K = 20;\n\nint n, m, k, r;\nvector<vector<int>> d;                // d[i][j]: required skill j for task i\nvector<vector<int>> dependencies;\nvector<vector<int>> revdeps;\nvector<int> indegree;\nvector<int> status;                   // 0: unassigned, 1: assigned, 2: done\n\nstruct MemberState {\n    int current_task = -1;\n    int assigned_day = -1;\n};\n\nvector<MemberState> members;\nint current_day = 1;\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// For each member, store (for each dimension):\n// - min d_i,k for all tasks finished in 1 day where k is peak\n// - best estimate (lowest) for all completions (including t > 1)\nstruct SkillStat {\n    vector<int> min1d;    // per dimension: min d_{i, k} with 1-day finish and k peak\n    vector<int> minall;   // per dimension: min d_{i, k} - (t-1) across any finished task\n    SkillStat(int K) : min1d(K, INT_MAX), minall(K, INT_MAX) {}\n};\nvector<SkillStat> skillstats;\n\n// For each member: list of (task, days) finished\nvector<vector<pair<int,int>>> member_finished_tasks;\n\n// Ready set and critical task info\nset<int> ready_tasks;\nvector<int> task_criticality; // e.g., outdegree + critical path\n\n// Helper: compute critical path\nvector<int> compute_critical_path() {\n    vector<int> critical(n, 0);\n    vector<int> topo;\n    vector<int> indeg_tmp = indegree;\n    queue<int> q;\n    for (int i = 0; i < n; ++i) if (indeg_tmp[i] == 0) q.push(i);\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        topo.push_back(u);\n        for (int v : revdeps[u]) {\n            --indeg_tmp[v];\n            if (indeg_tmp[v] == 0) q.push(v);\n        }\n    }\n    reverse(topo.begin(), topo.end());\n    for (int u : topo) {\n        for (int v : revdeps[u]) {\n            critical[u] = max(critical[u], critical[v]+1);\n        }\n    }\n    return critical;\n}\n\nvoid read_input() {\n    cin >> n >> m >> k >> r;\n    d.resize(n, vector<int>(k));\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < k; ++j)\n            cin >> d[i][j];\n    dependencies.resize(n);\n    revdeps.resize(n);\n    indegree.assign(n, 0);\n    for (int i = 0; i < r; ++i) {\n        int u, v;\n        cin >> u >> v;\n        --u; --v;\n        dependencies[v].push_back(u);\n        revdeps[u].push_back(v);\n        indegree[v]++;\n    }\n}\n\nvoid initialize() {\n    status.assign(n, 0);\n    members.assign(m, MemberState());\n    skillstats.assign(m, SkillStat(k));\n    member_finished_tasks.assign(m, {});\n    vector<int> crit = compute_critical_path();\n    task_criticality = crit;\n}\n\nvoid add_ready_tasks() {\n    for (int i = 0; i < n; ++i)\n        if (indegree[i] == 0 && status[i] == 0)\n            ready_tasks.insert(i);\n}\n\nvector<vector<double>> estimate_skills() {\n    // For each member/dimension, estimate as:\n    // - If any 1-day peak task finished: set skill to that task's d\n    // - Otherwise, minall (across all finished) else zero if none\n    int K = k;\n    vector<vector<double>> est(m, vector<double>(K, 0.0));\n    for (int j = 0; j < m; ++j) {\n        for (int x = 0; x < K; ++x) {\n            if (skillstats[j].min1d[x] != INT_MAX)\n                est[j][x] = skillstats[j].min1d[x];\n            else if (skillstats[j].minall[x] != INT_MAX)\n                est[j][x] = max(0, skillstats[j].minall[x]);\n            else\n                est[j][x] = 0; // don't risk\n        }\n    }\n    return est;\n}\n\n// Assign ready tasks to members\nvoid assign_tasks_today(vector<pair<int,int>>& assignments) {\n    vector<int> idle_members;\n    for (int j = 0; j < m; ++j)\n        if (members[j].current_task == -1)\n            idle_members.push_back(j);\n    set<int> used_tasks;\n    auto est_sk = estimate_skills();\n\n    // For each idle member, assign the best task (min exp_time, then highest criticality)\n    for (int j : idle_members) {\n        double best_score = 1e9; int best_task = -1; int best_crit = -1;\n        vector<int> candidates;\n        for (int t : ready_tasks) if (!used_tasks.count(t)) {\n            // Estimate time: sum over (requirement - estimated skill)+\n            double w = 0;\n            for (int kk = 0; kk < k; ++kk) {\n                if (d[t][kk] > est_sk[j][kk])\n                    w += (d[t][kk] - est_sk[j][kk]);\n            }\n            double expect = max(1.0, w);\n            int crit = task_criticality[t];\n            double score = expect - crit * 0.2; // emphasize critical tasks more!\n            if (score < best_score) {\n                best_score = score;\n                best_task = t;\n                best_crit = crit;\n                candidates.clear();\n                candidates.push_back(t);\n            } else if (score == best_score) {\n                candidates.push_back(t);\n            }\n        }\n        if (!candidates.empty()) {\n            // tie-breaker\n            int tsel = candidates[rng()%candidates.size()];\n            assignments.push_back({j, tsel});\n            used_tasks.insert(tsel);\n            status[tsel] = 1;\n            members[j].current_task = tsel;\n            members[j].assigned_day = current_day;\n        }\n    }\n}\n\nvoid process_feedback(const vector<int>& finished_members) {\n    for (int member : finished_members) {\n        auto& ms = members[member];\n        int tsk = ms.current_task;\n        int assigned = ms.assigned_day;\n        int obs_days = current_day - assigned + 1;\n        status[tsk] = 2;\n        ms.current_task = -1;\n        ms.assigned_day = -1;\n\n        member_finished_tasks[member].emplace_back(tsk, obs_days);\n        // For all skill dims: update min observed as needed\n        // Find peak dim\n        int peakv = -1, peakd = -1;\n        for(int kk=0;kk<k;++kk) if(d[tsk][kk]>peakv) { peakv=d[tsk][kk]; peakd=kk;}\n        if (obs_days == 1) skillstats[member].min1d[peakd] = min(skillstats[member].min1d[peakd], d[tsk][peakd]);\n        for (int kk = 0; kk < k; ++kk) {\n            int guess = d[tsk][kk] - max(0, obs_days-1);\n            skillstats[member].minall[kk] = min(skillstats[member].minall[kk], guess);\n        }\n        for (int dv : revdeps[tsk]) {\n            --indegree[dv];\n            if (indegree[dv] == 0 && status[dv] == 0)\n                ready_tasks.insert(dv);\n        }\n    }\n}\n\nvoid print_assignments(const vector<pair<int, int>>& assignments) {\n    cout << assignments.size();\n    for (auto [member, task] : assignments)\n        cout << ' ' << (member + 1) << ' ' << (task + 1);\n    cout << '\\n';\n    cout.flush();\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    read_input();\n    initialize();\n    add_ready_tasks();\n\n    while (true) {\n        vector<pair<int, int>> assignments;\n        assign_tasks_today(assignments);\n        for (auto &p : assignments)\n            ready_tasks.erase(p.second);\n        print_assignments(assignments);\n\n        // Input feedback\n        string line;\n        while (true) {\n            getline(cin, line);\n            if (cin.eof()) exit(0);\n            if (!line.empty()) break;\n        }\n        if (line == \"-1\") break;\n        istringstream iss(line);\n        int cnt; iss >> cnt;\n        if (cnt == -1) break;\n        vector<int> finished;\n        for (int i = 0; i < cnt; ++i) {\n            int x; iss >> x;\n            finished.push_back(x-1);\n        }\n        process_feedback(finished);\n        current_day++;\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\nmt19937 rng(42);\n\nstruct Order {\n    int id;\n    int ax, ay;\n    int cx, cy;\n    int score;\n};\n\nint manh(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n// K-means++ style init\nvector<pair<int,int>> kmeans_init(const vector<pair<int,int>>& pts, int K) {\n    int N = pts.size();\n    vector<pair<int,int>> centers;\n    centers.push_back(pts[rng()%N]);\n    vector<int> dist(N, 1e9);\n    for (int k = 1; k < K; ++k) {\n        int S = 0;\n        for (int i = 0; i < N; ++i) {\n            int d = manh(pts[i].first, pts[i].second, centers.back().first, centers.back().second);\n            if(d < dist[i]) dist[i]=d;\n            S += dist[i];\n        }\n        if(S==0) break;\n        int t = rng()%S, acc=0,i=0;\n        for(;i<N&&acc<t;++i) acc+=dist[i];\n        centers.push_back(pts[(i==N)?N-1:i]);\n    }\n    return centers;\n}\n\nvoid kmeans(const vector<pair<int,int>>& pts, int K, vector<int>& belong, vector<pair<int,int>>& centers, int iters=5) {\n    int N = pts.size();\n    belong.resize(N);\n    centers = kmeans_init(pts,K);\n\n    for (int it = 0; it < iters; ++it) {\n        for (int i = 0; i < N; ++i) {\n            int best = 0, best_d = manh(pts[i].first, pts[i].second, centers[0].first, centers[0].second);\n            for (int k = 1; k < K; ++k) {\n                int d = manh(pts[i].first, pts[i].second, centers[k].first, centers[k].second);\n                if (d < best_d) best_d = d, best = k;\n            }\n            belong[i] = best;\n        }\n        vector<int64_t> sx(K, 0), sy(K, 0), sn(K, 0);\n        for (int i = 0; i < N; ++i) {\n            sx[belong[i]] += pts[i].first;\n            sy[belong[i]] += pts[i].second;\n            sn[belong[i]] += 1;\n        }\n        for (int k = 0; k < K; ++k) {\n            if (sn[k]) centers[k] = {int(sx[k]/sn[k]), int(sy[k]/sn[k])};\n        }\n    }\n}\n\nstruct Node {\n    int x, y;\n    int ord_idx;\n    bool is_pickup;\n};\n\nstruct Result {\n    vector<int> sel_ids;\n    vector<pair<int,int>> route;\n    int route_cost;\n};\n\nResult get_route(const vector<Order>& sel_orders, int variant=0) {\n    vector<Node> nodes;\n    for (int i = 0; i < 50; ++i)\n        nodes.push_back({sel_orders[i].ax, sel_orders[i].ay, i, true});\n    for (int i = 0; i < 50; ++i)\n        nodes.push_back({sel_orders[i].cx, sel_orders[i].cy, i, false});\n    int N = nodes.size();\n\n    vector<bool> visited(N, false);\n    vector<bool> pickup_done(50, false);\n\n    vector<pair<int,int>> route = {{400,400}};\n    int cur_x = 400, cur_y = 400;\n    for (int step = 0; step < N; ++step) {\n        vector<int> avail;\n        for (int i = 0; i < N; ++i) if (!visited[i]) {\n            if (!nodes[i].is_pickup && !pickup_done[nodes[i].ord_idx]) continue;\n            avail.push_back(i);\n        }\n        int best = -1, best_dist = 1e9;\n        vector<int> candidates;\n        for (int i : avail) {\n            int dist = manh(cur_x, cur_y, nodes[i].x, nodes[i].y);\n            if (dist < best_dist) {\n                best_dist = dist;\n                candidates.clear();\n                candidates.push_back(i);\n            }\n            else if (dist == best_dist) candidates.push_back(i);\n        }\n        if(!candidates.empty()) {\n            if(variant==0)\n                best = candidates[0];\n            else\n                best = candidates[rng()%candidates.size()];\n        } else {\n            best = avail[rng()%avail.size()];\n        }\n        visited[best]=true;\n        if(nodes[best].is_pickup) pickup_done[nodes[best].ord_idx]=true;\n        cur_x = nodes[best].x; cur_y = nodes[best].y;\n        route.emplace_back(cur_x, cur_y);\n    }\n    if(cur_x!=400||cur_y!=400) route.emplace_back(400,400);\n    int cost=0;\n    for(int i=1;i<route.size();++i)\n        cost+=manh(route[i-1].first,route[i-1].second,route[i].first,route[i].second);\n\n    vector<int> sel_ids;\n    for(const auto&o:sel_orders)sel_ids.push_back(o.id+1);\n    return {sel_ids,route,cost};\n}\n\n// Local-improvement: swap a chosen order for an unchosen one if it improves the route\nvoid improve_order_set(vector<Order>& orders_all, vector<Order>& sel_orders, int imp_trials=40, int imp_nb_out=8, int imp_nb_in=12) {\n    set<int> chosen;\n    for(auto&o:sel_orders) chosen.insert(o.id);\n    vector<Order> unchosen;\n    for(const auto&o:orders_all) if(!chosen.count(o.id)) unchosen.push_back(o);\n\n    int best_cost = get_route(sel_orders, 1).route_cost;\n\n    for(int trial=0; trial<imp_trials; ++trial){\n        vector<int> idx_out;\n        for(int i=0;i<sel_orders.size();++i) idx_out.push_back(i);\n        shuffle(idx_out.begin(),idx_out.end(),rng);\n        idx_out.resize(min((int)idx_out.size(),imp_nb_out));\n\n        vector<int> idx_in;\n        for(int i=0;i<unchosen.size();++i) idx_in.push_back(i);\n        shuffle(idx_in.begin(),idx_in.end(),rng);\n        idx_in.resize(min((int)idx_in.size(),imp_nb_in));\n\n        bool changed = false;\n        for(int oi:idx_out) {\n            for(int ii:idx_in) {\n                Order out = sel_orders[oi];\n                Order in = unchosen[ii];\n                sel_orders[oi] = in;\n                set<int> checkset;\n                for(auto&o:sel_orders) checkset.insert(o.id);\n                if(checkset.size()<50) {\n                    sel_orders[oi] = out;\n                    continue;\n                }\n                int cost = get_route(sel_orders, 1).route_cost;\n                if(cost < best_cost) {\n                    best_cost = cost;\n                    unchosen[ii] = out;\n                    changed = true;\n                    break;\n                } else {\n                    sel_orders[oi] = out;\n                }\n            }\n            if(changed) break;\n        }\n        if(!changed) break;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    vector<Order> orders(1000);\n    for (int i = 0; i < 1000; ++i) {\n        int a, b, c, d;\n        cin >> a >> b >> c >> d;\n        orders[i] = {i, a, b, c, d, 0};\n    }\n    for (auto& o : orders) {\n        int office = 400;\n        o.score = manh(office,office,o.ax,o.ay)+manh(o.ax,o.ay,o.cx,o.cy)+manh(o.cx,o.cy,office,office);\n    }\n\n    vector<pair<int,int>> pickups;\n    for (auto&o:orders) pickups.emplace_back(o.ax, o.ay);\n\n    int best_cost = INT_MAX;\n    vector<int> best_sel_ids;\n    vector<pair<int,int>> best_route;\n\n    int K=10;\n    vector<int> belong;\n    vector<pair<int,int>> centers;\n    kmeans(pickups, K, belong, centers, 3);\n\n    vector<int> center_order(K);\n    iota(center_order.begin(),center_order.end(),0);\n    sort(center_order.begin(),center_order.end(),[&](int i,int j){\n        int di=manh(400,400,centers[i].first,centers[i].second);\n        int dj=manh(400,400,centers[j].first,centers[j].second);\n        return di<dj;\n    });\n\n    int CLUSTER_TRY = min(6,K);\n    int RUNS_PER_CLUSTER = 6;\n    for(int cl=0;cl<CLUSTER_TRY;++cl){\n        int cid = center_order[cl];\n        vector<Order> cand;\n        for(int i=0;i<orders.size();++i)if(belong[i]==cid)\n            cand.push_back(orders[i]);\n        sort(cand.begin(),cand.end(),[](const Order&a,const Order&b){return a.score<b.score;});\n        while(cand.size()<50){\n            int bdist=INT_MAX,bidx=-1;\n            for(int j=0;j<orders.size();++j){\n                if(belong[j]!=cid) {\n                    int d=manh(centers[cid].first,centers[cid].second,orders[j].ax,orders[j].ay);\n                    if(d<bdist){bdist=d;bidx=j;}\n                }\n            }\n            if(bidx>=0) cand.push_back(orders[bidx]);\n            else break;\n        }\n        if(cand.size()>50)cand.resize(50);\n\n        improve_order_set(orders, cand);\n\n        for(int run=0;run<RUNS_PER_CLUSTER;++run){\n            Result res = get_route(cand, run>0?1:0);\n            if(res.route_cost < best_cost){\n                best_cost = res.route_cost;\n                best_sel_ids=res.sel_ids;\n                best_route=res.route;\n            }\n        }\n    }\n\n    sort(orders.begin(), orders.end(), [](const Order& a, const Order& b) {\n        return a.score < b.score;\n    });\n    vector<Order> top50(orders.begin(), orders.begin()+50);\n\n    improve_order_set(orders, top50);\n\n    Result res = get_route(top50, 1);\n    if(res.route_cost < best_cost){\n        best_cost = res.route_cost;\n        best_sel_ids=res.sel_ids;\n        best_route=res.route;\n    }\n\n    cout << \"50\";\n    for (int i = 0; i < 50; ++i)\n        cout << \" \" << best_sel_ids[i];\n    cout << \"\\n\";\n    cout << best_route.size();\n    for (auto& p : best_route)\n        cout << \" \" << p.first << \" \" << p.second;\n    cout << \"\\n\";\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    vector<int> parent, sz;\n    DSU(int n) : parent(n), sz(n, 1) { iota(parent.begin(), parent.end(), 0); }\n    int find(int x) {\n        while (parent[x] != x) x = parent[x] = parent[parent[x]];\n        return x;\n    }\n    bool unite(int x, int y) {\n        x = find(x); y = find(y);\n        if (x == y) return false;\n        if (sz[x] < sz[y]) swap(x, y);\n        parent[y] = x; sz[x] += sz[y];\n        return true;\n    }\n    bool same(int x, int y) { return find(x) == find(y); }\n};\n\nstruct Edge {\n    int u, v;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 400, M = 1995;\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    vector<Edge> edges(M);\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        cin >> u >> v;\n        edges[i] = {u, v};\n    }\n    DSU dsu(N);\n    int taken = 0;\n    for (int i = 0; i < M; ++i) {\n        int l_i;\n        cin >> l_i;\n        int u = edges[i].u, v = edges[i].v;\n\n        if (!dsu.same(u, v)) {\n            cout << 1 << endl;\n            cout << flush;\n            dsu.unite(u, v);\n            taken++;\n        } else {\n            cout << 0 << endl;\n            cout << flush;\n        }\n    }\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Grid dimensions\nconstexpr int W = 30, H = 30;\nconstexpr int DX[4] = {-1, 1, 0, 0};\nconstexpr int DY[4] = {0, 0, -1, 1};\nconstexpr char MOVES[4] = {'U', 'D', 'L', 'R'};\nconstexpr char WALLS[4] = {'u', 'd', 'l', 'r'};\n\nstruct Pet {\n    int x, y, type;\n};\nstruct Human {\n    int x, y;\n    int dest_x, dest_y; // where he's going!\n    int band_l, band_r;\n};\n\nvector<string> grid(H, string(W, '.')); // .:passable, #:wall, h:human, p:pet\n\n// 0-indexed, returns true if inside grid\ninline bool ins(int x, int y) { return 0 <= x && x < H && 0 <= y && y < W; }\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N; cin >> N;\n    vector<Pet> pets(N);\n    for (int i = 0; i < N; i++) {\n        int x, y, t; cin >> x >> y >> t;\n        --x; --y;\n        pets[i] = {x, y, t};\n        grid[x][y] = 'p'; // mark as pet\n    }\n    int M; cin >> M;\n    vector<Human> humans(M);\n    vector<pair<int,int>> hpos(M);\n    vector<vector<int>> human_grid(H, vector<int>(W, 0)); // count of humans\n    for (int i = 0; i < M; i++) {\n        int x, y; cin >> x >> y;\n        --x; --y;\n        humans[i].x = x;\n        humans[i].y = y;\n        hpos[i] = {x, y};\n        grid[x][y] = 'h';\n        human_grid[x][y]++;\n    }\n\n    // Assign bands (vertical partition)\n    vector<pair<int,int>> band_limits(M);\n    int band_size = W / M;\n    for (int i = 0; i < M; i++) {\n        int l = i * band_size;\n        int r = (i == M-1) ? W-1 : (i+1)*band_size-1;\n        band_limits[i] = {l, r};\n        humans[i].band_l = l;\n        humans[i].band_r = r;\n        humans[i].dest_x = H/2; // central row\n        humans[i].dest_y = (l + r)/2;\n    }\n\n    vector<vector<int>> pet_grid(H, vector<int>(W, 0));\n    for (auto& p : pets) pet_grid[p.x][p.y]++;\n\n    // For each turn\n    int phase_move = 12; // Tuning param: turns spent getting into position\n    for (int turn = 0; turn < 300; ++turn) {\n        string actions(M, '.');\n        // Update grid to remove old h and p marks (we'll re-mark below)\n        for (int i = 0; i < H; ++i)\n            for (int j = 0; j < W; ++j)\n                if (grid[i][j]=='h' || grid[i][j]=='p')\n                    grid[i][j] = '.';\n        fill(&human_grid[0][0], &human_grid[0][0]+H*W, 0);\n        fill(&pet_grid[0][0], &pet_grid[0][0]+H*W, 0);\n        for (int i = 0; i < M; ++i) {\n            grid[humans[i].x][humans[i].y] = 'h';\n            human_grid[humans[i].x][humans[i].y]++;\n        }\n        for (int i = 0; i < N; ++i) {\n            grid[pets[i].x][pets[i].y] = 'p';\n            pet_grid[pets[i].x][pets[i].y]++;\n        }\n\n        // For each human, decide action\n        for (int i = 0; i < M; ++i) {\n            auto& h = humans[i];\n            int cx = h.x, cy = h.y;\n            int xl = h.band_l, xr = h.band_r;\n\n            // PHASE 0: Move to starting pos near center of band in first \"phase_move\" turns\n            if (turn < phase_move) {\n                int destx = h.dest_x, desty = h.dest_y;\n                if (cx < destx)      actions[i] = 'D', h.x++;\n                else if (cx > destx) actions[i] = 'U', h.x--;\n                else if (cy < desty) actions[i] = 'R', h.y++;\n                else if (cy > desty) actions[i] = 'L', h.y--;\n                // else stand\n                continue;\n            }\n\n            // PHASE 1: Build walls on left and right of their region\n            // Try to wall a cell at the edge of their band\n            // Alternate walling at the left and right edge of their band!\n            bool did_wall = false;\n\n            // Let's try right wall first this turn if not at the rightmost column\n            for (int d = 0; d < 4 && !did_wall; ++d) {\n                // Choose priority: right-most, left-most, up, down\n                int dir = d;\n                int tx = cx + DX[dir], ty = cy + DY[dir];\n                // For now, try to build wall on the right-most of our region\n                if (dir == 1 && cy < xr) continue; // D: Not vertical wall, skip\n                if (dir == 0 && cy > xl) continue;\n                if (!ins(tx, ty)) continue;\n                if (grid[tx][ty] == '.' && human_grid[tx][ty]==0 && pet_grid[tx][ty]==0) {\n                    // Check no adjacent pet in 8-neighborhood (stricter than needed: 4-neighborhood is rule!)\n                    bool safe = true;\n                    for (int d2 = 0; d2 < 4; ++d2) {\n                        int nx = tx + DX[d2], ny = ty + DY[d2];\n                        if (ins(nx, ny) && pet_grid[nx][ny]) safe = false;\n                    }\n                    if (safe) {\n                        actions[i] = WALLS[dir];\n                        did_wall = true;\n                    }\n                }\n            }\n            if (did_wall) continue; // Prefer walling\n\n            // Otherwise, do a little patrol: move along boundary if not at an edge\n            if (cy < xl) { actions[i] = 'R'; h.y++; }\n            else if (cy > xr) { actions[i] = 'L'; h.y--; }\n            // else idle\n        }\n\n        cout << actions << '\\n' << flush;\n\n        // INPUT PET MOVES\n        vector<string> pet_moves(N);\n        for (int i = 0; i < N; ++i) {\n            cin >> pet_moves[i];\n        }\n        // Update pet positions\n        for (int i = 0; i < N; ++i) {\n            for (char c : pet_moves[i]) {\n                int dx = 0, dy = 0;\n                if (c == 'U') dx = -1;\n                if (c == 'D') dx = 1;\n                if (c == 'L') dy = -1;\n                if (c == 'R') dy = 1;\n                int nx = pets[i].x + dx, ny = pets[i].y + dy;\n                if (ins(nx, ny)) pets[i].x = nx, pets[i].y = ny;\n            }\n        }\n    }\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Directions: U, D, L, R\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst char DC[] = {'U', 'D', 'L', 'R'};\n\nstruct WallMap {\n    int h[20][19]; // right wall\n    int v[19][20]; // down wall\n    bool can_move(int i, int j, int dir) const {\n        if(dir==0) { // Up\n            if(i==0) return false;\n            return v[i-1][j]==0;\n        }\n        if(dir==1) { // Down\n            if(i==19) return false;\n            return v[i][j]==0;\n        }\n        if(dir==2) { // Left\n            if(j==0) return false;\n            return h[i][j-1]==0;\n        }\n        if(dir==3) { // Right\n            if(j==19) return false;\n            return h[i][j]==0;\n        }\n        return false;\n    }\n};\n\nvector<int> bfs_shortest_path(const WallMap &wm, int si, int sj, int gi, int gj) {\n    vector<vector<int>> dist(20, vector<int>(20, -1));\n    vector<vector<pair<int,int>>> prev(20, vector<pair<int,int>>(20, {-1,-1}));\n    queue<pair<int,int>> q;\n    dist[si][sj] = 0;\n    q.push({si, sj});\n    while(!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int d=0; d<4; ++d) {\n            if(!wm.can_move(i, j, d)) continue;\n            int ni = i + di[d], nj = j + dj[d];\n            if(dist[ni][nj] == -1) {\n                dist[ni][nj] = dist[i][j] + 1;\n                prev[ni][nj] = {i, j};\n                q.push({ni, nj});\n            }\n        }\n    }\n    vector<int> path;\n    int ci = gi, cj = gj;\n    if (dist[ci][cj] == -1) return {};\n    while (!(ci == si && cj == sj)) {\n        auto [pi, pj] = prev[ci][cj];\n        for (int d=0; d<4; ++d) if(pi+di[d]==ci && pj+dj[d]==cj && wm.can_move(pi, pj, d)) {\n            path.push_back(d);\n            break;\n        }\n        tie(ci, cj) = make_pair(pi, pj);\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nstring path_repeat_each(const vector<int>& path, int k, int total_limit) {\n    string ret;\n    for(int d: path) for(int rpt=0;rpt<k;++rpt) {\n        if((int)ret.size()<total_limit) ret+=DC[d];\n    }\n    while((int)ret.size() + (int)path.size()*k <= total_limit) {\n        for(int d: path) for(int rpt=0;rpt<k;++rpt) {\n            if((int)ret.size()<total_limit) ret+=DC[d];\n        }\n    }\n    return ret;\n}\n\nstring path_repeat_full(const vector<int>& path, int total_limit) {\n    string ret;\n    while((int)ret.size() + (int)path.size() <= total_limit) {\n        for(int d: path) {\n            if((int)ret.size()<total_limit) ret += DC[d];\n        }\n    }\n    while((int)ret.size()<total_limit && !path.empty()) {\n        ret += DC[path.back()];\n    }\n    return ret;\n}\n\n// \"Snake\" path: interleaved DRDR if shortest path is mostly D+R\nstring path_snake(const vector<int>& path, int total_limit) {\n    // Count D/R\n    int cntD=0, cntR=0;\n    for(int d: path) if(d==1)cntD++; else if(d==3)cntR++;\n    string ret;\n    int cD=0, cR=0;\n    while((int)ret.size()<total_limit && (cD<cntD || cR<cntR)) {\n        if(cD<cntD) { ret+='D'; cD++;}\n        if((int)ret.size()>=total_limit)break;\n        if(cR<cntR) { ret+='R'; cR++;}\n    }\n    // Repeat to fill\n    while((int)ret.size()+cntD+cntR<=total_limit) {\n        int tD=0,tR=0;\n        while((tD<cntD || tR<cntR) && (int)ret.size()<total_limit) {\n            if(tD<cntD) { ret+='D'; tD++;}\n            if((int)ret.size()>=total_limit)break;\n            if(tR<cntR) { ret+='R'; tR++;}\n        }\n    }\n    // Pad\n    while((int)ret.size()<total_limit) ret+='D';\n    return ret;\n}\n\n// Adaptive greedy BFS plan: at each move, from current position, plan to goal, take first step, repeat\nstring greedy_bfs_plan(const WallMap& wm, int si, int sj, int gi, int gj, int total_limit) {\n    int i=si, j=sj;\n    string ret;\n    for(int step=0;step<total_limit;++step) {\n        if(i==gi && j==gj) break;\n        vector<vector<int>> dist(20, vector<int>(20, -1));\n        vector<vector<int>> firstdir(20, vector<int>(20, -1));\n        queue<pair<int,int>> q;\n        dist[i][j]=0;\n        q.push({i,j});\n        firstdir[i][j] = -1;\n        while(!q.empty()) {\n            auto [ci,cj] = q.front(); q.pop();\n            for(int d=0;d<4;++d) {\n                if(!wm.can_move(ci,cj,d)) continue;\n                int ni=ci+di[d], nj=cj+dj[d];\n                if(dist[ni][nj]!=-1) continue;\n                dist[ni][nj]=dist[ci][cj]+1;\n                firstdir[ni][nj] = (dist[ci][cj]==0 ? d : firstdir[ci][cj]);\n                q.push({ni,nj});\n            }\n        }\n        if(dist[gi][gj]==-1) break; // unreachable\n        int move = firstdir[gi][gj];\n        if(move==-1) break;\n        ret+=DC[move];\n        // Simulate move (assume not forgotten, for plan)\n        if(wm.can_move(i,j,move)) { i+=di[move]; j+=dj[move]; }\n    }\n    // Pad with last move for roundness\n    if(!ret.empty()) while((int)ret.size()<total_limit) ret+=ret.back();\n    return ret;\n}\n\ndouble simulate(const WallMap& wm, int si, int sj, int gi, int gj, double p, const string& route, int runs=1500) {\n    mt19937_64 rng(7171717); // fixed seed\n    uniform_real_distribution<> rd(0, 1);\n    double sum = 0;\n    for(int it=0;it<runs;++it) {\n        int i = si, j = sj, t=0;\n        bool reached = false;\n        for(t=1; t<=(int)route.size(); ++t) {\n            if(i==gi && j==gj) {reached=true; break;}\n            double coin = rd(rng);\n            if(coin < p) {\n                // Forget: do nothing\n            } else {\n                int d = -1;\n                for(int k=0;k<4;++k) if(route[t-1]==DC[k]){d=k;break;}\n                if(wm.can_move(i,j,d)) {\n                    i += di[d], j += dj[d];\n                }\n            }\n            if(i==gi && j==gj) {reached=true; break;}\n        }\n        if(i==gi && j==gj) {reached=true;}\n        if(reached) sum += (401 - t + (i==gi && j==gj ? 0 : 1));\n    }\n    return sum / runs;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n\n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n    WallMap wm;\n    for (int i=0;i<20;++i) for (int j=0;j<19;++j) {\n        char c; cin >> c;\n        wm.h[i][j] = c-'0';\n    }\n    for (int i=0;i<19;++i) for (int j=0;j<20;++j) {\n        char c; cin >> c;\n        wm.v[i][j] = c-'0';\n    }\n\n    auto spath = bfs_shortest_path(wm, si, sj, ti, tj);\n    int route_limit = 200;\n\n    vector<pair<double, string>> candidates;\n\n    // Candidate 1: Repeat full shortest path\n    string c1 = path_repeat_full(spath, route_limit);\n    candidates.emplace_back(simulate(wm, si, sj, ti, tj, p, c1, 1000), c1);\n\n    // Candidate 2: Repeat each move 2x\n    if(spath.size()*2 <= route_limit) {\n        string c2 = path_repeat_each(spath, 2, route_limit);\n        candidates.emplace_back(simulate(wm, si, sj, ti, tj, p, c2, 1000), c2);\n    }\n    // Candidate 3: Repeat each move 3x\n    if(spath.size()*3 <= route_limit) {\n        string c3 = path_repeat_each(spath, 3, route_limit);\n        candidates.emplace_back(simulate(wm, si, sj, ti, tj, p, c3, 1000), c3);\n    }\n    // Candidate 4: \"Snake path\" (DRDR), only for nearly axis-aligned path and short ones\n    int Ds = 0, Rs = 0, Ls = 0, Us = 0;\n    for(int d: spath) switch(d){case 0:Us++;break;case 1:Ds++;break;case 2:Ls++;break;case 3:Rs++;break;}\n    if((Us==0||Ds==0) && (Ls==0||Rs==0)) { // axis-aligned\n        string c4 = path_snake(spath, route_limit);\n        candidates.emplace_back(simulate(wm, si, sj, ti, tj, p, c4, 1000), c4);\n    }\n    // Candidate 5: Greedy BFS replanner\n    string c5 = greedy_bfs_plan(wm, si, sj, ti, tj, route_limit);\n    candidates.emplace_back(simulate(wm, si, sj, ti, tj, p, c5, 700), c5); // simulation heavier, use fewer runs\n\n    // Pick the best\n    auto [_, bestroute] = *max_element(candidates.begin(), candidates.end());\n    cout << bestroute << endl;\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Grid size and directions\nconstexpr int N = 30;\nconst int di[4] = {0, -1, 0, 1};   // left, up, right, down\nconst int dj[4] = {-1, 0, 1, 0};\nconst int to[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1},\n};\n\nint realType(int t, int r) {\n    if (t <= 3) return (t + r) % 4;\n    else if (t == 4) return r % 2 == 0 ? 4 : 5;\n    else if (t == 5) return r % 2 == 0 ? 5 : 4;\n    else if (t == 6) return r % 2 == 0 ? 6 : 7;\n    else /* t == 7 */ return r % 2 == 0 ? 7 : 6;\n}\n\n// Get all loop lengths for this rotation setup\nvector<int> get_loops(const vector<vector<int>>& tile_types, const vector<vector<int>>& rotations) {\n    int st[N][N];\n    for (int i = 0; i < N; i++)\n    for (int j = 0; j < N; j++)\n        st[i][j] = realType(tile_types[i][j], rotations[i][j]);\n    bool visited[N][N][4] = {};\n    vector<int> loop_lengths;\n\n    for (int i = 0; i < N; i++)\n    for (int j = 0; j < N; j++)\n    for (int d = 0; d < 4; d++) {\n        if (visited[i][j][d]) continue;\n        int ci = i, cj = j, cd = d, len = 0;\n        while (true) {\n            if (visited[ci][cj][cd]) break;\n            visited[ci][cj][cd] = true;\n            int nd = to[st[ci][cj]][cd];\n            if (nd == -1) break;\n            int ni = ci + di[nd], nj = cj + dj[nd];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) break;\n            cd = (nd + 2) % 4;\n            ci = ni;\n            cj = nj;\n            len++;\n            if (ci == i && cj == j && cd == d) {\n                loop_lengths.push_back(len);\n                break;\n            }\n        }\n    }\n    sort(loop_lengths.rbegin(), loop_lengths.rend());\n    return loop_lengths;\n}\n\n// Greedy fitting for all tiles to maximize (local) edge matches\nvoid greedy_fit_rotations(const vector<vector<int>>& type, vector<vector<int>>& rot) {\n    for (int sweep = 0; sweep < 3; ++sweep) { // 1-3 sweeps to propagate neighbor info\n        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) {\n            int best = -1, bestr = 0;\n            for (int r = 0; r < 4; ++r) {\n                int nt = realType(type[i][j], r);\n                int connect = 0;\n                for (int d = 0; d < 4; ++d) {\n                    int nd = to[nt][d];\n                    if (nd == -1) continue;\n                    int ni = i + di[nd], nj = j + dj[nd];\n                    // Is this edge on the grid?\n                    if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                    int backdir = (nd+2)%4;\n                    // Neighbor's rotation and type\n                    int neighbor_type = type[ni][nj];\n                    int neighbor_rot = rot[ni][nj];\n                    int neighbor_real = realType(neighbor_type, neighbor_rot);\n                    // Will neighbor accept a path from our current direction?\n                    if (to[neighbor_real][backdir] != -1) {\n                        connect++;\n                    }\n                }\n                // Prefer maximally many local matches, break ties by random\n                if (connect > best || (connect == best && rand()%2)) {\n                    best = connect; bestr = r;\n                }\n            }\n            rot[i][j] = bestr;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<vector<int>> type(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        string s; cin >> s;\n        for (int j = 0; j < N; j++)\n            type[i][j] = s[j] - '0';\n    }\n\n    vector<vector<int>> rot(N, vector<int>(N, 0));\n    srand((unsigned)time(0));\n\n    greedy_fit_rotations(type, rot);\n\n    // Evaluate\n    auto loop_lengths = get_loops(type, rot);\n    int score = 0;\n    if (loop_lengths.size() >= 2)\n        score = loop_lengths[0] * loop_lengths[1];\n\n    cerr << \"Top loops: \";\n    for (int i = 0; i < min(5, int(loop_lengths.size())); ++i)\n        cerr << loop_lengths[i] << \" \";\n    cerr << \"Score = \" << score << endl;\n\n    // Output format\n    string out;\n    out.reserve(N*N);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            out += char('0' + rot[i][j]);\n    cout << out << endl;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nusing pii = pair<int,int>;\n\nchrono::high_resolution_clock::time_point time_start;\ndouble elapsed_sec() {\n    auto t = chrono::high_resolution_clock::now();\n    return chrono::duration<double>(t - time_start).count();\n}\n\n// Directions: UDLR\nconst int dr[] = {-1, 1, 0, 0};\nconst int dc[] = {0, 0, -1, 1};\nconst char dir_char[] = {'U','D','L','R'};\nconst int opp_dir[] = {1,0,3,2};\nconst int bit[] = {1<<1,1<<3,1<<0,1<<2}; // up,down,left,right\n\nstruct Board {\n    int N;\n    vector<vector<int>> grid;\n    pii empty; // (r,c) position of the empty cell\n\n    Board(int N_): N(N_), grid(N, vector<int>(N)) {}\n    Board(const Board &o): N(o.N), grid(o.grid), empty(o.empty) {}\n\n    void read_input() {\n        for(int i=0; i<N; ++i) {\n            string s; cin >> s;\n            for(int j=0; j<N; ++j) {\n                char ch = s[j];\n                if(ch=='0') {\n                    grid[i][j]=0;\n                    empty = {i,j};\n                } else if(isdigit(ch)) {\n                    grid[i][j] = ch-'0';\n                } else {\n                    grid[i][j] = ch-'a'+10;\n                }\n            }\n        }\n    }\n\n    // Can we move in dir d (U/D/L/R)?\n    bool can_move(int d) const {\n        int er = empty.first, ec = empty.second;\n        int nr = er + dr[d], nc = ec + dc[d];\n        return nr>=0 && nr<N && nc>=0 && nc<N;\n    }\n\n    // Do the move in dir d. Assumes move is legal.\n    void do_move(int d) {\n        int er = empty.first, ec = empty.second;\n        int nr = er + dr[d], nc = ec + dc[d];\n        swap(grid[er][ec], grid[nr][nc]);\n        empty = {nr, nc};\n    }\n\n    // For performance, do undo_move doesn't need to be tracked if not required yet.\n};\n\nstruct DSU {\n    vector<int> par, siz;\n    DSU(int n): par(n), siz(n,1) { iota(par.begin(), par.end(), 0); }\n    int find(int x) { return par[x]==x ? x : par[x]=find(par[x]); }\n    bool unite(int x,int y) {\n        x = find(x); y = find(y);\n        if(x==y) return false;\n        if(siz[x]<siz[y]) swap(x,y);\n        par[y]=x; siz[x]+=siz[y];\n        return true;\n    }\n    int size(int x) { return siz[find(x)]; }\n};\n\nstruct TreeChecker {\n    // Build a graph of non-empty tiles, with edges as problem states,\n    // Then find the largest connected component which is also acyclic\n\n    int N;\n    vector<vector<int>> grid;\n    vector<vector<int>> idmap; // for mapping (i,j) to node ids, since one cell is empty\n\n    TreeChecker(const vector<vector<int>> &g): N(g.size()), grid(g) {\n        // Build idmap: -1 for empty, else unique 0...(N*N-2)\n        idmap.assign(N, vector<int>(N,-1));\n        int id=0;\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++) {\n            if(grid[i][j]!=0) idmap[i][j]=id++;\n        }\n    }\n\n    // Returns (largest tree size)\n    int get_largest_tree_size() {\n        int nn = N*N-1;\n        vector<vector<int>> G(nn);\n        // Build undirected edge list\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++) {\n            if(grid[i][j]==0) continue;\n            int t = grid[i][j];\n            int id1 = idmap[i][j];\n            // down\n            if((t&8) && i+1<N && grid[i+1][j]!=0 && (grid[i+1][j]&2))\n                G[id1].push_back(idmap[i+1][j]);\n            // right\n            if((t&4) && j+1<N && grid[i][j+1]!=0 && (grid[i][j+1]&1))\n                G[id1].push_back(idmap[i][j+1]);\n            // (U/L can reverse edge but already covered)\n        }\n        // Find largest connected acyclic component: for each CC, check if no cycles (tree), report largest\n        int res=0;\n        vector<int> vis(nn,0);\n        for(int i=0;i<nn;i++) {\n            if(vis[i]) continue;\n            int size=0, edges=0;\n            bool is_tree=true;\n            function<void(int,int)> dfs=[&](int u, int p){\n                vis[u]=1; size++;\n                for(int v:G[u]) {\n                    if(v==p) continue;\n                    edges++;\n                    if(vis[v]) is_tree=false;\n                    else dfs(v, u);\n                }\n            };\n            dfs(i,-1);\n            if(is_tree && edges/2==size-1) res=max(res,size); // undirected: edges double-counted\n        }\n        return res;\n    }\n};\n\nint main() {\n    time_start = chrono::high_resolution_clock::now();\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T;\n    cin >> N >> T;\n    Board board(N);\n    board.read_input();\n\n    // Naive strategy: try random walks and keep the best\n    string best_moves;\n    int best_score = 0;\n    Board best_board = board;\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    int try_limit = 1500;   // Control based on validated time!\n    int walk_len = min(T, 200); // Try short walks first, might help\n\n    for(int t=0; t<try_limit; ++t) {\n        Board cur_board = board;\n        vector<int> move_hist;\n        string moves = \"\";\n        int prev_move = -1;\n        for(int k=0; k<walk_len; ++k) {\n            // Random legal move, avoid undoing previous\n            vector<int> can_moves;\n            for(int d=0; d<4; ++d) {\n                if( d != opp_dir[prev_move] && cur_board.can_move(d))\n                    can_moves.push_back(d);\n            }\n            if(can_moves.empty()) break;\n            int mv = can_moves[ rng() % can_moves.size() ];\n            cur_board.do_move(mv);\n            moves += dir_char[mv];\n            prev_move = mv;\n        }\n        // Compute score\n        TreeChecker tc(cur_board.grid);\n        int S = tc.get_largest_tree_size();\n        if(S>best_score || (S==best_score && (int)moves.size()<best_moves.size())) {\n            best_score = S;\n            best_moves = moves;\n            best_board = cur_board;\n        }\n        // Time management (1.8sec safety)\n        if(elapsed_sec() > 1.8) break;\n    }\n\n    // Output\n    cout << best_moves << \"\\n\";\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing P = pair<int, int>;\nusing ll = long long;\nconst double PI = acos(-1.0);\nconst int CAKE_RADIUS = 10000;\nconst int K = 100;\n\nstruct Strawberry {\n    int x, y;\n    int idx; // original id\n};\n\nstruct Line {\n    // Represent by ax + by + c = 0\n    // Or two points (px, py), (qx, qy)\n    int px, py, qx, qy;\n};\n\nstruct Piece {\n    vector<int> strawberry_idxs;\n};\n\nint N, K_input;\nvector<int> a; // a[1..10]\nvector<Strawberry> strawberries;\nvector<Line> cuts;\n\n// For bipartition: Given indices of strawberries, try to partition into sizes d and n-d\n// Return (success, (indices in side A, indices in side B), Line to cut by)\ntuple<bool, vector<int>, vector<int>, Line>\nbipartition(const vector<int>& idxs, int d, const vector<Strawberry>& strawbs, mt19937 &rng) {\n    int n = idxs.size();\n    if (n < d || d == 0 || d == n) return {false, {}, {}, {}};\n    vector<pair<double,int>> project(n); // (projection, index in idxs)\n    vector<double> directions;\n    const int tries = 20;\n    uniform_real_distribution<double> angle_dist(0, PI);\n    for(int attempt = 0; attempt < tries; ++attempt) {\n        double ang = angle_dist(rng);\n        double dx = cos(ang), dy = sin(ang);\n        for(int i = 0; i < n; ++i) {\n            const auto &s = strawbs[idxs[i]];\n            project[i] = {s.x*dx + s.y*dy, i};\n        }\n        sort(project.begin(), project.end());\n        // Try split after d-1 points (left: [0,d-1], right: [d,n-1])\n        double cut_left = project[d-1].first;\n        double cut_right = project[d].first;\n        double cut_proj = (cut_left + cut_right) / 2.0; // split position at midpoint\n        // Find two points on this line\n        // For simplicity, pick a point within cake in direction orthogonal to (dx,dy)\n        // e.g., normal vector (-dy, dx)\n        double nx = -dy, ny = dx;\n        // Pick p0 at (0,0) + cake_radius * (nx, ny)\n        double p0x = nx * CAKE_RADIUS, p0y = ny * CAKE_RADIUS;\n        double p1x = -nx * CAKE_RADIUS, p1y = -ny * CAKE_RADIUS;\n        // Shift line along (dx,dy) by cut_proj units: move origin along (dx,dy)\n        p0x += dx * cut_proj;\n        p0y += dy * cut_proj;\n        p1x += dx * cut_proj;\n        p1y += dy * cut_proj;\n        // Round to integer points in [-1e9,1e9]\n        auto clamp = [](double v) -> int64_t {\n            const ll M = 1000000000LL;\n            if (v > M) return M;\n            if (v < -M) return -M;\n            return static_cast<ll>(round(v));\n        };\n        ll px = clamp(p0x), py = clamp(p0y), qx = clamp(p1x), qy = clamp(p1y);\n\n        // Now assign to sides: those with projection < cut_proj on one side, others on other\n        vector<int> A, B;\n        for(int i = 0; i < n; ++i) {\n            int sidx = idxs[project[i].second];\n            if (project[i].first < cut_proj) A.push_back(sidx);\n            else if (project[i].first > cut_proj) B.push_back(sidx);\n            else {\n                // projection == cut_proj:\n                // Looks like a double point, but in practice, can assign to either cake side\n                // Just assign to B for safety (as cut_proj is mid of two projections)\n                B.push_back(sidx);\n            }\n        }\n        // If any strawberry happens to be exactly ON the line, abort this cut\n        // Check for each strawberry:\n        double eps = 1e-8;\n        bool on_cut = false;\n        for(int i = 0; i < n; ++i) {\n            if (abs(project[i].first - cut_proj) < eps) {\n                // A strawberry would be lost; try a new direction\n                on_cut = true;\n                break;\n            }\n        }\n        if (on_cut) continue;\n        // Now, can get exact d in A or B depending on ordering:\n        if (A.size() == d || B.size() == d) {\n            if (A.size() == d) {\n                return {true, A, B, Line{(int)px, (int)py, (int)qx, (int)qy}};\n            } else {\n                return {true, B, A, Line{(int)px, (int)py, (int)qx, (int)qy}};\n            }\n        }\n    }\n    // no suitable split found\n    return {false, {}, {}, {}};\n}\n\nint main(){\n    ios::sync_with_stdio(false); cin.tie(0);\n    cin >> N >> K_input;\n    a.resize(11);\n    int Ncheck = 0;\n    for(int d=1;d<=10; ++d) {\n        cin >> a[d];\n        Ncheck += d * a[d];\n    }\n    strawberries.resize(N);\n    for(int i=0;i<N;++i){\n        int x, y; cin >> x >> y;\n        strawberries[i] = {x, y, i};\n    }\n    // Bookkeeping for pieces:\n    vector<vector<int>> pieces; // each as vector of strawberry indices\n    pieces.push_back(vector<int>(N));\n    iota(pieces[0].begin(), pieces[0].end(), 0);\n\n    // For each d from 10 downto 1 (focus on large pieces first)\n    // Alternatively, weighted by number required; for now, 10..1\n    int remains[11];\n    for(int d=1;d<=10;++d) remains[d]=a[d];\n\n    mt19937 rng(123456 + chrono::steady_clock::now().time_since_epoch().count());\n\n    // For cuts\n    vector<Line> used_cuts;\n\n    // For pieces: maintain multiset by size (for quickly finding suitable ones)\n    // Actually, not necessary for up to 1000 pieces\n\n    // Map: pieces_to_process[d]: indices of pieces of size >= d, and not yet processed\n    // We'll go for greedy: for d from 10..1, try to split pieces down\n    // For now, do as explained: try to generate as many pieces of size d as a[d]\n    for(int d=10; d>=1; --d) {\n        int need = remains[d];\n        if(need == 0) continue;\n        // Look for pieces with size >= d\n        // For each round:\n        bool found;\n        int attempts = 0;\n        while(need > 0) {\n            found = false;\n            for(int pi=0; pi<pieces.size(); ++pi) {\n                vector<int> &piece = pieces[pi];\n                if ((int)piece.size() > d) {\n                    // Try bipartition this piece into d and n-d\n                    auto [ok, groupA, groupB, line] = bipartition(piece, d, strawberries, rng);\n                    if(ok) {\n                        // Accept this cut, add it to cuts\n                        used_cuts.push_back(line);\n                        // Remove piece, add groupA, groupB instead\n                        piece = move(groupA);\n                        pieces.push_back(move(groupB));\n                        // Mark found\n                        found = true;\n                        --need;\n                        break; // do next need\n                    }\n                }\n            }\n            if(!found) break; // Could not perform more for this d\n            if((int)used_cuts.size() >= K) break;\n            ++attempts;\n            if(attempts > 1000) break; // Give up (should not be needed)\n        }\n        if((int)used_cuts.size() >= K) break;\n    }\n\n    // Now, after all splits, count how many pieces of each size, up to a[d] per attendee\n    vector<int> cnt(11, 0);\n    for(const auto &piece: pieces) {\n        int sz = piece.size();\n        if(sz >= 1 && sz <= 10) cnt[sz]++;\n    }\n    int total_given = 0;\n    for(int d=1;d<=10;++d) total_given += min(a[d], cnt[d]);\n    // Output cuts\n    int k_out = used_cuts.size();\n    cout << k_out << \"\\n\";\n    for(const auto &line : used_cuts) {\n        cout << line.px << \" \" << line.py << \" \" << line.qx << \" \" << line.qy << \"\\n\";\n    }\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nusing pii = pair<int, int>;\n\nconstexpr int DX[4] = {1, 0, -1, 0};\nconstexpr int DY[4] = {0, 1, 0, -1};\n\nstruct Edge {\n    int x1, y1, x2, y2;\n    Edge(int a,int b,int c,int d) {\n        if (pii(a, b) < pii(c, d)) {\n            x1 = a; y1 = b; x2 = c; y2 = d;\n        } else {\n            x1 = c; y1 = d; x2 = a; y2 = b;\n        }\n    }\n    bool operator < (const Edge& o) const {\n        return tie(x1,y1,x2,y2) < tie(o.x1,o.y1,o.x2,o.y2);\n    }\n};\n\nint N,M;\nvector<vector<int>> board; // 0: empty, 1: dot placed during play, 2: initial dot\nset<pii> dots; // occupied\nset<Edge> used_edges; // segments of perimeters\n\nvector<vector<ll>> weights;\nll S = 0;\nint CENTER;\nvector<array<int,8>> moves;\n\nvoid input() {\n    cin >> N >> M;\n    board.assign(N, vector<int>(N, 0));\n    for (int i = 0; i < M; ++i) {\n        int x,y;\n        cin >> x >> y;\n        board[x][y] = 2;\n        dots.emplace(x, y);\n    }\n    CENTER = (N-1)/2;\n    \n    weights.assign(N, vector<ll>(N, 0));\n    S = 0;\n    for (int x=0; x<N; ++x)\n        for (int y=0; y<N; ++y) {\n            weights[x][y] = (x-CENTER)*(x-CENTER) + (y-CENTER)*(y-CENTER) + 1;\n            S += weights[x][y];\n        }\n}\n\nbool is_valid(int x, int y) {\n    return x>=0 && x<N && y>=0 && y<N;\n}\n\n// For each empty cell, try all rectangles for which it can be one corner, with 3 dots as the other 3 corners\n// Return all candidate rectangles (with highest scoring p1 positions first)\nvector<array<int,8>> find_candidate_moves() {\n    vector<tuple<ll, array<int,8>>> candidates; // score, move\n    // To avoid too much computation, consider only shells near frontier\n    // Let's try to consider all for now (limit time if slow)\n    for (int x1=0; x1<N; ++x1) for (int y1=0; y1<N; ++y1) {\n        if (board[x1][y1] != 0) continue;\n        // For axis-aligned rectangles\n        for (auto& [dx,dy] : vector<pair<int,int>>{{1,0},{0,1}}) {\n            for (int len=1; len<=min(N-1,7); ++len) {\n                int x2 = x1+dx*len, y2 = y1+dy*len;\n                int x4 = x1+dy*len, y4 = y1-dx*len;\n                int x3 = x2+dy*len, y3 = y2-dx*len;\n                if (!is_valid(x2,y2) || !is_valid(x3,y3) || !is_valid(x4,y4)) continue;\n\n                array<pii,4> pts = {pii(x1,y1), pii(x2,y2), pii(x3,y3), pii(x4,y4)};\n                vector<int> ids = {0,1,2,3};\n\n                // try all 3 choose 3 for which the other three points have dots\n                vector<int> dot_idx;\n                for (int i=1; i<4; ++i) if (dots.count(pts[i])) dot_idx.push_back(i);\n                if ((int)dot_idx.size()<3) continue;\n                // Choose all three-point combinations (should be just one for axis-aligned)\n                for (int p=0; p<3; ++p) {\n                    int i2=dot_idx[p%3], i3=dot_idx[(p+1)%3], i4=dot_idx[(p+2)%3];\n                    array<int,8> move = {pts[0].first, pts[0].second, \n                        pts[i2].first, pts[i2].second,\n                        pts[i3].first, pts[i3].second,\n                        pts[i4].first, pts[i4].second\n                    };\n                    // check that the perimeter (except at corners) is empty and doesn't overlap a previous rect's segment\n                    vector<pii> perim = {pts[0], pts[i2], pts[i3], pts[i4]};\n                    bool ok = true;\n                    int sz = (int)perim.size();\n                    // check dots on perimeter but not at corners\n                    for (int j=0; j<sz; ++j) {\n                        int xA=perim[j].first, yA=perim[j].second;\n                        int xB=perim[(j+1)%sz].first, yB=perim[(j+1)%sz].second;\n                        int dx = (xB-xA)?((xB-xA)/abs(xB-xA)):0, dy = (yB-yA)?((yB-yA)/abs(yB-yA)):0;\n                        for (int xm = xA+dx, ym = yA+dy; \n                             xm!=xB||ym!=yB; xm+=dx, ym+=dy) {\n                            if (dots.count({xm, ym})) { ok=false; break; }\n                        }\n                        // Check perimeter overlap\n                        Edge e(xA,yA,xB,yB);\n                        if (used_edges.count(e)) { ok=false; break;}\n                    }\n                    if (ok) {\n                        candidates.emplace_back(weights[x1][y1], move);\n                    }\n                }\n            }\n        }\n        // 45-degree (diamond) rectangles\n        // For d=1 to limit (side increases as sqrt(2)*d)\n        for (int dx=1; dx<=6; ++dx) { // side length (sqrt(2)*dx)\n            int x2 = x1+dx, y2=y1+dx;\n            int x3 = x1, y3 = y1+2*dx;\n            int x4=x1-dx, y4=y1+dx;\n            if (!is_valid(x2,y2)||!is_valid(x3,y3)||!is_valid(x4,y4)) continue;\n            array<pii,4> pts = {pii(x1,y1), pii(x2,y2), pii(x3,y3), pii(x4,y4)};\n            // check that other three are dots\n            vector<int> dot_idx;\n            for (int i=1; i<4; ++i) if (dots.count(pts[i])) dot_idx.push_back(i);\n            if ((int)dot_idx.size()<3) continue;\n            for (int p=0; p<3; ++p) {\n                int i2=dot_idx[p%3], i3=dot_idx[(p+1)%3], i4=dot_idx[(p+2)%3];\n                array<int,8> move = {pts[0].first, pts[0].second, \n                    pts[i2].first, pts[i2].second,\n                    pts[i3].first, pts[i3].second,\n                    pts[i4].first, pts[i4].second\n                };\n                // perimeter check\n                vector<pii> perim = {pts[0], pts[i2], pts[i3], pts[i4]};\n                bool ok = true;\n                int sz = (int)perim.size();\n                for (int j=0; j<sz; ++j) {\n                    int xA=perim[j].first, yA=perim[j].second;\n                    int xB=perim[(j+1)%sz].first, yB=perim[(j+1)%sz].second;\n                    int dx = (xB-xA)?((xB-xA)/abs(xB-xA)):0, dy = (yB-yA)?((yB-yA)/abs(yB-yA)):0;\n                    for (int xm = xA+dx, ym = yA+dy; xm!=xB||ym!=yB; xm+=dx, ym+=dy) {\n                        if (dots.count({xm, ym})) { ok=false; break; }\n                    }\n                    // Check perimeter overlap\n                    Edge e(xA,yA,xB,yB);\n                    if (used_edges.count(e)) { ok=false; break;}\n                }\n                if (ok) {\n                    candidates.emplace_back(weights[x1][y1], move);\n                }\n            }\n        }\n    }\n    sort(candidates.rbegin(), candidates.rend()); // High weight to low weight\n    vector<array<int,8>> res;\n    for (auto& [score,move] : candidates) res.push_back(move);\n    return res;\n}\n\nvoid make_move(const array<int,8>& mv) {\n    int x1=mv[0], y1=mv[1];\n    int x2=mv[2], y2=mv[3];\n    int x3=mv[4], y3=mv[5];\n    int x4=mv[6], y4=mv[7];\n    board[x1][y1]=1;\n    dots.emplace(x1,y1);\n    // Mark used segments\n    vector<pii> pts = {pii(x1,y1), pii(x2,y2), pii(x3,y3), pii(x4,y4)};\n    int sz = (int)pts.size();\n    for (int i=0;i<sz;++i) {\n        int xA=pts[i].first, yA=pts[i].second;\n        int xB=pts[(i+1)%sz].first, yB=pts[(i+1)%sz].second;\n        used_edges.insert(Edge(xA,yA,xB,yB));\n    }\n    moves.push_back(mv);\n}\n\n// Main solve\nvoid solve() {\n    while (true) {\n        vector<array<int,8>> cands = find_candidate_moves();\n        if (cands.empty()) break;\n        // Pick the best (highest weight gain)\n        make_move(cands[0]);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    input();\n    solve();\n    cout << moves.size() << \"\\n\";\n    for (auto& mv : moves) {\n        for (int i=0; i<8; ++i) cout << mv[i] << \" \";\n        cout << \"\\n\";\n    }\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <array>\n#include <algorithm>\n#include <string>\n#include <queue>\n#include <cassert>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n// Grid size\nconstexpr int N = 10;\nusing Board = array<array<int, N>, N>;\nusing Pos = pair<int,int>;\n\nvoid flush() { cout << flush; }\n\n// Standard gravity on a copy of 'board', in direction dir\nvoid move_board(Board& board, char dir) {\n    if (dir == 'F') {\n        for (int x = 0; x < N; x++) {\n            int write = 0;\n            for (int y = 0; y < N; y++) {\n                if (board[y][x] != 0) {\n                    if (write != y) {\n                        board[write][x] = board[y][x];\n                        board[y][x] = 0;\n                    }\n                    write++;\n                }\n            }\n        }\n    } else if (dir == 'B') {\n        for (int x = 0; x < N; x++) {\n            int write = N-1;\n            for (int y = N-1; y >=0; --y) {\n                if (board[y][x] != 0) {\n                    if (write != y) {\n                        board[write][x] = board[y][x];\n                        board[y][x] = 0;\n                    }\n                    write--;\n                }\n            }\n        }\n    } else if (dir == 'L') {\n        for (int y = 0; y < N; y++) {\n            int write = 0;\n            for (int x = 0; x < N; x++) {\n                if (board[y][x] != 0) {\n                    if (write != x) {\n                        board[y][write] = board[y][x];\n                        board[y][x] = 0;\n                    }\n                    write++;\n                }\n            }\n        }\n    } else if (dir == 'R') {\n        for (int y = 0; y < N; y++) {\n            int write = N-1;\n            for (int x = N-1; x >= 0; --x) {\n                if (board[y][x] != 0) {\n                    if (write != x) {\n                        board[y][write] = board[y][x];\n                        board[y][x] = 0;\n                    }\n                    write--;\n                }\n            }\n        }\n    }\n}\n\n// Return empty cells as vector of (y,x)\nvector<array<int,2>> get_empty_cells(const Board& board) {\n    vector<array<int,2>> res;\n    for (int y = 0; y < N; ++y)\n        for (int x = 0; x < N; ++x)\n            if (board[y][x] == 0)\n                res.push_back({y, x});\n    return res;\n}\n\n// To map p_t to (y,x)\nPos get_index_from_pt(const vector<array<int,2>>& empties, int p_t) {\n    assert(p_t >= 1 && p_t <= (int)empties.size());\n    return {empties[p_t-1][0], empties[p_t-1][1]};\n}\n\n// Directions for BFS\nconstexpr int dy[4] = {1, -1,  0,  0};\nconstexpr int dx[4] = {0,  0,  1, -1};\n\n// Calculate sum of squares of all connected components for the board\nint calc_component_score(const Board& board) {\n    array<array<bool,N>,N> visited{};\n    int total_score = 0;\n    for (int y=0; y<N; y++) for (int x=0; x<N; x++) {\n        if (board[y][x]!=0 && !visited[y][x]) {\n            int flavor = board[y][x];\n            int sz = 0;\n            queue<pair<int,int>> q;\n            q.push({y,x});\n            visited[y][x] = true;\n            while (!q.empty()) {\n                auto [cy,cx] = q.front(); q.pop();\n                sz++;\n                for (int d=0; d<4; d++) {\n                    int ny = cy + dy[d], nx = cx + dx[d];\n                    if (ny >=0 && ny < N && nx >=0 && nx < N) {\n                        if (!visited[ny][nx] && board[ny][nx]==flavor) {\n                            visited[ny][nx]=true;\n                            q.push({ny,nx});\n                        }\n                    }\n                }\n            }\n            total_score += sz*sz;\n        }\n    }\n    return total_score;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // For breaking ties randomly\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    // Read flavors for all candies\n    vector<int> flavors(100);\n    for (int i = 0; i < 100; ++i) cin >> flavors[i];\n\n    Board board{}; // initialized to 0 everywhere\n\n    // Directions to try\n    const array<char,4> all_dirs = {'F','B','L','R'};\n\n    for (int step = 0; step < 100; ++step) {\n        int p_t;\n        cin >> p_t;\n        vector<array<int,2>> empties = get_empty_cells(board);\n        Pos pos = get_index_from_pt(empties, p_t);\n        int flavor = flavors[step];\n        board[pos.first][pos.second] = flavor;\n\n        // Simulate all 4 directions, pick the best\n        int best_score = -1;\n        vector<char> best_dirs;\n        for (char dir : all_dirs) {\n            Board temp = board;\n            move_board(temp, dir);\n            int score = calc_component_score(temp);\n            if (score > best_score) {\n                best_score = score;\n                best_dirs = {dir};\n            } else if (score == best_score) {\n                best_dirs.push_back(dir);\n            }\n        }\n        // Break ties randomly for variety, else always take first as deterministic\n        char chosen_dir = best_dirs[rng() % best_dirs.size()];\n\n        // Make the real move\n        move_board(board, chosen_dir);\n\n        if (step != 99) {\n            cout << chosen_dir << '\\n';\n            flush();\n        }\n    }\n\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\n#include <Eigen/Dense>\nusing namespace std;\nusing namespace Eigen;\n\nconst int MAX_N = 100;\nconst int EIGEN_CNT = 10; // Number of eigenvalues to keep\n\n// Helper: string edge list to Eigen adjacency\nvoid string_to_matrix(const string &s, int N, MatrixXd &adj) {\n    adj = MatrixXd::Zero(N, N);\n    int idx = 0;\n    for(int i=0;i<N;i++)for(int j=i+1;j<N;j++) {\n        if(s[idx++]=='1') {\n            adj(i,j) = adj(j,i) = 1.0;\n        }\n    }\n}\n\n// Get sorted degree sequence\nvector<int> get_degseq(const string &s, int N) {\n    vector<int> deg(N, 0);\n    int idx = 0;\n    for(int i=0;i<N;++i) for(int j=i+1;j<N;++j,++idx) {\n        if(s[idx]=='1') {\n            deg[i]++; deg[j]++;\n        }\n    }\n    sort(deg.begin(), deg.end());\n    return deg;\n}\n\n// Get quantized eigenvalues (largest positive & lowest negative EIGEN_CNT/2 each)\nvector<double> get_eigen(const string &s, int N) {\n    MatrixXd adj(N, N);\n    string_to_matrix(s, N, adj);\n    SelfAdjointEigenSolver<MatrixXd> sol(adj);\n    vector<double> eigs(N);\n    for(int i=0;i<N;++i) eigs[i] = sol.eigenvalues()(i);\n    sort(eigs.begin(), eigs.end());\n    // Take lower EIGEN_CNT/2 and upper EIGEN_CNT/2\n    int K = EIGEN_CNT/2;\n    vector<double> v;\n    for(int i=0;i<K;++i) v.push_back(eigs[i]);\n    for(int i=N-K;i<N;++i) v.push_back(eigs[i]);\n    return v;\n}\n\n// Euclidean distance for eigenvectors, and L1 for degree seqs\ndouble eigen_dist(const vector<double>& a, const vector<double>& b) {\n    double d = 0;\n    for(int i=0;i<(int)a.size();++i) d += (a[i]-b[i])*(a[i]-b[i]);\n    return sqrt(d);\n}\nint deg_dist(const vector<int>& a, const vector<int>& b) {\n    int d = 0;\n    for(int i=0;i<(int)a.size();++i) d += abs(a[i]-b[i]);\n    return d;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int M;\n    double eps;\n    cin >> M >> eps;\n\n    // Adaptive N (tuned)\n    int add = (int)(eps * 2.8 * M + 8);\n    int N = min(100, max(4, M + add));\n\n    // Random regular graph generator as before\n    mt19937 rng(1337+M+(int)(eps*10000));\n    auto random_regular_graph = [&](int N, int d) {\n        vector<int> deg(N, d);\n        vector<int> stubs;\n        for(int i=0;i<N;i++) for(int j=0;j<d;j++) stubs.push_back(i);\n        vector<vector<int>> adj(N);\n        for(int tries=0;tries<10;tries++) {\n            auto st = stubs;\n            shuffle(st.begin(), st.end(), rng);\n            vector<vector<int>> to(N);\n            bool good = true;\n            for(int i=0;i<st.size();i+=2) {\n                int u=st[i],v=st[i+1];\n                if(u==v) {good=false;break;}\n                if(find(to[u].begin(), to[u].end(), v)!=to[u].end()) {good=false;break;}\n                to[u].push_back(v);\n                to[v].push_back(u);\n            }\n            if(good) return to;\n        }\n        // Fallback: Erdos-Renyi at density 0.5\n        vector<vector<int>> adj2(N);\n        uniform_real_distribution<double> ud(0,1);\n        for(int i=0;i<N;i++) for(int j=i+1;j<N;j++) {\n            if(ud(rng)<0.5) { adj2[i].push_back(j); adj2[j].push_back(i); }\n        }\n        return adj2;\n    };\n\n    // Prepare graph codes\n    vector<string> graph_codes;\n    set<string> used_code;\n    int target_deg = min(N-1, max(2, N/2 + (int)(eps*N/3)));\n    for(int i=0;i<M;i++) {\n        string code;\n        do {\n            auto adj = random_regular_graph(N, target_deg);\n            string s(N*(N-1)/2,'0');\n            int idx=0;\n            for(int u=0;u<N;u++) for(int v=u+1;v<N;v++,idx++) {\n                if(find(adj[u].begin(), adj[u].end(), v)!=adj[u].end()) s[idx]='1';\n            }\n            code=s;\n        } while(used_code.count(code));\n        used_code.insert(code);\n        graph_codes.push_back(code);\n    }\n\n    // Output M graphs\n    cout << N << endl;\n    for(string& s:graph_codes) cout << s << '\\n';\n    cout.flush();\n\n    // Precompute features for all codes\n    vector< vector<int> > degseqs(M);\n    vector< vector<double> > eigens(M);\n    for(int i=0;i<M;i++) {\n        degseqs[i]=get_degseq(graph_codes[i], N);\n        eigens[i]=get_eigen(graph_codes[i], N);\n    }\n\n    // For each query\n    for(int q=0;q<100;q++) {\n        string query;\n        cin >> query;\n        auto q_degseq = get_degseq(query,N);\n        auto q_eigen = get_eigen(query,N);\n\n        // Find closest code\n        int best = 0;\n        double bestscore = 1e18;\n        for(int i=0;i<M;i++) {\n            int dd = deg_dist(q_degseq, degseqs[i]);\n            double ed = eigen_dist(q_eigen, eigens[i]);\n            double score = 0.11*dd + ed; // Heavy on eigen, degree helps in rare collision\n            if(score < bestscore) {\n                bestscore = score;\n                best = i;\n            }\n        }\n\n        cout << best << '\\n';\n        cout.flush();\n    }\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\nint randint(int a, int b) { return uniform_int_distribution<int>(a, b)(rng); }\n\nstruct Edge {\n    int u, v, w, id;\n    Edge(int u=0, int v=0, int w=0, int id=0): u(u), v(v), w(w), id(id) {}\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, D, K;\n    cin >> N >> M >> D >> K;\n\n    vector<Edge> edges;\n    vector<vector<pair<int,int>>> g(N);\n    map<pair<int,int>, int> uv2eid;\n\n    for (int i = 0; i < M; ++i) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        --u; --v;\n        edges.emplace_back(u, v, w, i);\n        g[u].emplace_back(v, w);\n        g[v].emplace_back(u, w);\n        int uu=u, vv=v; if (uu>vv) swap(uu,vv);\n        uv2eid[make_pair(uu,vv)] = i;\n    }\n\n    // skip coordinates\n    for (int i = 0; i < N; ++i) { int x, y; cin >> x >> y; }\n\n    // Faster Edge Importance: Approx edge-betweenness via SPT\n    const int SAMPLES = 12;\n    vector<int> sample_src;\n    unordered_set<int> used;\n    while ((int)sample_src.size() < SAMPLES) {\n        int s = randint(0, N-1);\n        if (!used.count(s)) sample_src.push_back(s), used.insert(s);\n    }\n\n    vector<int> e_importance(M, 0);\n    for (int si : sample_src) {\n        vector<int> dist(N, INT_MAX), from(N, -1);\n        dist[si]=0;\n        using pli=pair<int,int>;\n        priority_queue<pli,vector<pli>,greater<pli>> pq;\n        pq.emplace(0,si);\n        while (!pq.empty()) {\n            auto[d,u]=pq.top(); pq.pop();\n            if (d>dist[u]) continue;\n            for (auto &[v,w]:g[u]) {\n                if (dist[v]>d+w) {\n                    dist[v]=d+w;\n                    from[v]=u;\n                    pq.emplace(dist[v],v);\n                }\n            }\n        }\n        // record all edges (parent-children)\n        for (int v=0; v<N; ++v) {\n            int u = from[v];\n            if (u == -1) continue;\n            int uu=u, vv=v; if (uu>vv) swap(uu,vv);\n            int eid = uv2eid[{uu,vv}];\n            e_importance[eid] += 1;\n        }\n    }\n\n    // Assign schedule\n\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b){return e_importance[a]>e_importance[b];});\n\n    vector<int> day_of_edge(M, -1);\n    vector<int> day_counts(D, 0);\n    vector<int> day_damage(D, 0);\n    vector<set<int>> day_verts(D);\n    \n    // Step 1: Assign top X edges with strong anti-adjacency\n    int topX = M/8; // e.g. 1/8 of edges\n    if (topX < D) topX = D;\n    int assign_idx = 0;\n    vector<int> cur_day_cand(D, 0); // for round robin\n    for (int i = 0; i < topX; ++i) {\n        int eid = order[i];\n        int u = edges[eid].u, v = edges[eid].v;\n        // Pick next day round robin until not adjacent to current day's scheduled edges\n        int attempts = 0, d = assign_idx % D;\n        for (; attempts < D; ++attempts) {\n            d = (assign_idx + attempts) % D;\n            if (day_counts[d] >= K) continue;\n            if (!day_verts[d].count(u) && !day_verts[d].count(v)) break;\n        }\n        if (day_counts[d] >= K) {\n            // should not happen unless K is tight; fallback find any with room\n            for (d=0;d<D;++d) if (day_counts[d]<K) break;\n        }\n        day_of_edge[eid] = d;\n        day_counts[d]++;\n        day_damage[d] += e_importance[eid];\n        day_verts[d].insert(u);\n        day_verts[d].insert(v);\n        assign_idx = d+1;\n    }\n\n    // Step 2: Greedy balance for the rest\n    for (int idx = topX; idx < M; ++idx) {\n        int eid = order[idx];\n        int u = edges[eid].u, v = edges[eid].v;\n        int best_day = -1, best_score = INT_MAX;\n        for (int d = 0; d < D; ++d) {\n            if (day_counts[d] >= K) continue;\n            int score = day_damage[d];\n            // Large penalty for adjacency for moderately top edges\n            if (idx < M/2 && (day_verts[d].count(u) || day_verts[d].count(v))) score += SAMPLES*6;\n            if (score < best_score) {\n                best_score = score;\n                best_day = d;\n            }\n        }\n        // fallback: find any day with room\n        if (best_day == -1) for (int d=0; d<D; ++d) if (day_counts[d]<K) { best_day=d; break; }\n        day_of_edge[eid] = best_day;\n        day_counts[best_day]++;\n        day_damage[best_day] += e_importance[eid];\n        day_verts[best_day].insert(u); day_verts[best_day].insert(v);\n    }\n\n    for (int i = 0; i < M; ++i) {\n        cout << (day_of_edge[i]+1) << (i+1==M ? '\\n' : ' ');\n    }\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\nusing pii = pair<int, int>;\nusing vi = vector<int>;\nusing vvi = vector<vi>;\n\n// --- Helper types for a shape ---\nusing Shape = vector<array<int,3>>;  // sorted relative positions\n\n// All 24 rotation matrices for cube (no reflection), precalculated\nconst vector<array<array<int,3>,3>> ROTATIONS = []{\n    vector<array<array<int,3>,3>> R;\n    // This code produces all 24 possible cube rotations\n    set<vector<array<int,3>,3>> seen;\n    auto apply = [](const array<array<int,3>,3>& M, array<int,3> v) {\n        array<int,3> r;\n        for(int i=0;i<3;++i) r[i] = M[i][0]*v[0] + M[i][1]*v[1] + M[i][2]*v[2];\n        return r;\n    };\n    auto matmul = [](const array<array<int,3>,3>& A, const array<array<int,3>,3>& B) {\n        array<array<int,3>,3> R{};\n        for(int i=0;i<3;++i) for(int j=0;j<3;++j) for(int k=0;k<3;++k)\n            R[i][j] += A[i][k]*B[k][j];\n        return R;\n    };\n    // Basic face rotations\n    vector<array<array<int,3>,3>> faceRots = {\n        {{{1,0,0},{0,1,0},{0,0,1}}},\n        {{{0,0,1},{0,1,0},{-1,0,0}}},\n        {{{-1,0,0},{0,1,0},{0,0,-1}}},\n        {{{0,0,-1},{0,1,0},{1,0,0}}},\n        {{{1,0,0},{0,0,-1},{0,1,0}}},\n        {{{1,0,0},{0,0,1},{0,-1,0}}}\n    };\n    // 0, 90, 180, 270 deg rotations about Y axis\n    vector<array<array<int,3>,3>> yrots = {\n        {{{1,0,0},{0,1,0},{0,0,1}}},\n        {{{0,0,1},{0,1,0},{-1,0,0}}},\n        {{{-1,0,0},{0,1,0},{0,0,-1}}},\n        {{{0,0,-1},{0,1,0},{1,0,0}}}\n    };\n    for(auto& f: faceRots) for(auto& y: yrots) {\n        auto rot = matmul(y, f);\n        // Unique up to 24\n        if(seen.count(rot)) continue;\n        seen.insert(rot);\n        R.push_back(rot);\n    }\n    return R;\n}();\n\nShape canonicalize(const Shape& shape) {\n    // Centers at (0,0,0), returns smallest lex order under all 24 rotations\n    vector<Shape> candidates;\n\n    for(const auto &rot: ROTATIONS) {\n        Shape s;\n        for(auto p: shape) {\n            array<int,3> q = {0,0,0};\n            for(int i=0;i<3;++i)\n                q[i] = rot[i][0]*p[0] + rot[i][1]*p[1] + rot[i][2]*p[2];\n            s.push_back(q);\n        }\n        // Now, shift min to (0,0,0)\n        int minx=1e9,miny=1e9,minz=1e9;\n        for(auto &q: s) {\n            minx = min(minx, q[0]);\n            miny = min(miny, q[1]);\n            minz = min(minz, q[2]);\n        }\n        for(auto &q: s) {\n            q[0] -= minx;\n            q[1] -= miny;\n            q[2] -= minz;\n        }\n        sort(s.begin(), s.end());\n        candidates.push_back(s);\n    }\n    return *min_element(candidates.begin(), candidates.end());\n}\n\n// Encodes a shape for hash-comparison\nstring shape_to_str(const Shape& s) {\n    string out;\n    for(auto p: s) for(int x:p) out+=\",\"+to_string(x);\n    return out;\n}\n\n// For blocks found inside an object\nstruct FoundBlock {\n    int anchor_x, anchor_y, anchor_z;\n    Shape s;\n    vector<array<int,3>> global_voxels; // absolute position for each cell\n};\n\n// Greedy maximal cube cover of mask\nvector<FoundBlock> greedy_cover(const vector<vector<vector<int>>> &mask, int D) {\n    // 0: empty or already assigned, 1: needs assigning\n    vector<vector<vector<int>>> rem = mask;\n    vector<FoundBlock> blocks;\n    vector<vector<vector<int>>> vis(D, vector<vector<int>>(D,vector<int>(D,0)));\n    // Greedily cover big cubes then lines then single\n    auto inside = [&](int x,int y,int z) {\n        return 0<=x && x<D && 0<=y && y<D && 0<=z && z<D;\n    };\n    int filled=0, total=0;\n    for(int x=0;x<D;++x) for(int y=0;y<D;++y) for(int z=0;z<D;++z)\n        if(mask[x][y][z]) total++;\n    while(filled<total) {\n        int bestV=-1, bx,by,bz,bsize;\n        string bdir; // \"cube\", \"x\", \"y\", \"z\"\n        // Try cube of size sz, largest first\n        for(int sz = min(5,D); sz>=2; --sz) { // Cube SZxSZxSZ\n            for(int x=0;x<=D-sz;++x) for(int y=0;y<=D-sz;++y) for(int z=0;z<=D-sz;++z) {\n                bool ok=1;\n                int cnt=0;\n                for(int dx=0;dx<sz&&ok;++dx) for(int dy=0;dy<sz;++dy) for(int dz=0;dz<sz;++dz)\n                    if(!rem[x+dx][y+dy][z+dz]) { ok=0; break; }\n                if(!ok) continue;\n                cnt = sz*sz*sz;\n                if(cnt>bestV) {\n                    bx=x; by=y; bz=z; bsize=sz; bestV=cnt; bdir=\"cube\";\n                }\n            }\n        }\n        // Try MAX-length lines (x/y/z)\n        for(int d=0;d<3;++d) {\n            for(int sz = min(D,7); sz>=2; --sz) {\n                for(int x=0; x<D; ++x) for(int y=0; y<D; ++y) for(int z=0; z<D; ++z) {\n                    int dx = (d==0), dy=(d==1), dz=(d==2);\n                    bool ok=1;\n                    if(inside(x+(sz-1)*dx,y+(sz-1)*dy,z+(sz-1)*dz)==0) continue;\n                    for(int i=0;i<sz;++i) {\n                        int nx=x+i*dx, ny=y+i*dy, nz=z+i*dz;\n                        if(!rem[nx][ny][nz]) {ok=0;break;}\n                    }\n                    if(!ok) continue;\n                    if(sz > bestV) {\n                        bx=x; by=y; bz=z; bsize=sz; bestV=sz; \n                        if(d==0) bdir=\"x\"; else if(d==1) bdir=\"y\"; else bdir=\"z\";\n                    }\n                }\n            }\n        }\n        if(bestV==-1) {\n            // Just fill random remaining 1 cell\n            for(int x=0;x<D;++x) for(int y=0;y<D;++y) for(int z=0;z<D;++z)\n                if(rem[x][y][z]) {\n                    bx=x; by=y; bz=z; bsize=1; bestV=1; bdir=\"pt\";\n                    goto ok_found;\n                }\n        }\nok_found:;\n        // Build FoundBlock\n        FoundBlock fb;\n        fb.anchor_x = bx; fb.anchor_y = by; fb.anchor_z = bz;\n        Shape s;\n        vector<array<int,3>> vox;\n        if(bdir==\"cube\") {\n            for(int dx=0;dx<bsize;++dx) for(int dy=0;dy<bsize;++dy) for(int dz=0;dz<bsize;++dz) {\n                int x=bx+dx, y=by+dy, z=bz+dz;\n                s.push_back({dx,dy,dz});\n                vox.push_back({x,y,z});\n                rem[x][y][z]=0; filled++;\n            }\n        } else if(bdir==\"x\"||bdir==\"y\"||bdir==\"z\") {\n            int dx=(bdir==\"x\"),dy=(bdir==\"y\"),dz=(bdir==\"z\");\n            for(int i=0;i<bsize;++i) {\n                int x=bx + dx*i, y=by + dy*i, z=bz + dz*i;\n                s.push_back({dx*i,dy*i,dz*i});\n                vox.push_back({x,y,z});\n                rem[x][y][z]=0; filled++;\n            }\n        } else {\n            s.push_back({0,0,0});\n            vox.push_back({bx,by,bz});\n            rem[bx][by][bz]=0; filled++;\n        }\n        fb.s = s;\n        fb.global_voxels = vox;\n        blocks.push_back(fb);\n    }\n    return blocks;\n}\n\n// Now try \"match\" blocks between two silhouette objects by canonical polycube\nvoid assign_block_numbers(\n    vector<FoundBlock>& blocksA, vector<FoundBlock>& blocksB, \n    map<string, vector<pair<int,FoundBlock*>>>& blockDict,\n    map<int,int>& block_to_global_number, int &global_block_counter\n) {\n    // Place all found blocks in dict by canonical form\n    for(int i=0; i<blocksA.size(); ++i) {\n        Shape can = canonicalize(blocksA[i].s);\n        string key = shape_to_str(can);\n        blockDict[key].emplace_back(0, &blocksA[i]);\n    }\n    for(int i=0; i<blocksB.size(); ++i) {\n        Shape can = canonicalize(blocksB[i].s);\n        string key = shape_to_str(can);\n        blockDict[key].emplace_back(1, &blocksB[i]);\n    }\n    // For each unique block (canonical), assign a global number, and set in block_to_global_number\n    for(auto& [key, vec]: blockDict) {\n        // See if used in both A, B\n        bool hasA=0, hasB=0;\n        for(auto& [who,_]:vec) if(who==0) hasA=1; else hasB=1;\n        ++global_block_counter;\n        int my_number = global_block_counter;\n        for(auto& [who,ptr]:vec) {\n            ptr->anchor_x = my_number; // overload to store number for assignment\n        }\n    }\n}\n\n// Output for one object: For each cell in D^3, output block number\nvector<int> gen_assignment(const vector<FoundBlock>& blocks, int D) {\n    vector<int> ans(D*D*D,0);\n    for(auto& fb: blocks) {\n        int block_number = fb.anchor_x;\n        for(auto& q: fb.global_voxels) {\n            int idx = q[0]*D*D + q[1]*D + q[2];\n            ans[idx] = block_number;\n        }\n    }\n    return ans;\n}\n\n// --- Main solution function ---\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int D;\n    cin >> D;\n    vector<vector<string>> F(2, vector<string>(D));\n    vector<vector<string>> R(2, vector<string>(D));\n    for(int s=0;s<2;++s) for(int i=0;i<D;++i) cin>>F[s][i];\n    for(int s=0;s<2;++s) for(int i=0;i<D;++i) cin>>R[s][i];\n\n    // Build 3D mask for each object\n    auto build_mask = [&](int idx) {\n        vector<vector<vector<int>>> mask(D, vector<vector<int>>(D,vector<int>(D,0)));\n        for(int x=0;x<D;++x) for(int y=0;y<D;++y) for(int z=0;z<D;++z) {\n            if(F[idx][z][x]=='1' && R[idx][z][y]=='1')\n                mask[x][y][z]=1;\n        }\n        return mask;\n    };\n    vector<vector<vector<int>>> mask1 = build_mask(0);\n    vector<vector<vector<int>>> mask2 = build_mask(1);\n\n    // Greedy cover for both\n    auto blocksA = greedy_cover(mask1, D);\n    auto blocksB = greedy_cover(mask2, D);\n\n    // Now assign global block numbers (by matching shapes)\n    map<string, vector<pair<int,FoundBlock*>>> blockDict;\n    map<int,int> block_to_global_number;\n    int global_block_counter = 0;\n    assign_block_numbers(blocksA, blocksB, blockDict, block_to_global_number, global_block_counter);\n\n    int n_blocks = global_block_counter;\n    cout << n_blocks << '\\n';\n    // Output for two objects\n    vector<int> out1 = gen_assignment(blocksA, D);\n    vector<int> out2 = gen_assignment(blocksB, D);\n    for(int i=0;i<out1.size();++i) {\n        cout << out1[i];\n        if(i+1!=out1.size()) cout << \" \";\n    }\n    cout << endl;\n    for(int i=0;i<out2.size();++i) {\n        cout << out2[i];\n        if(i+1!=out2.size()) cout << \" \";\n    }\n    cout << endl;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <queue>\n#include <algorithm>\n#include <limits>\n#include <set>\n#include <array>\nusing namespace std;\n\nstruct Edge {\n    int u, v, idx;\n    long long w;\n    bool operator<(const Edge& o) const { return w < o.w; }\n};\n\nstruct DSU {\n    vector<int> p;\n    DSU(int n): p(n,-1) {}\n    int find(int x) {\n        while (p[x] >= 0) {\n            if (p[p[x]] >= 0) p[x] = p[p[x]];\n            x = p[x];\n        }\n        return x;\n    }\n    bool unite(int x,int y) {\n        x = find(x);\n        y = find(y);\n        if (x == y) return false;\n        if (p[x] > p[y]) swap(x,y);\n        p[x] += p[y];\n        p[y] = x;\n        return true;\n    }\n};\n\ninline int dist(int x0,int y0,int x1,int y1) {\n    return (int)ceil(sqrt(1LL*(x0-x1)*(x0-x1) + 1LL*(y0-y1)*(y0-y1)));\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n\n    int N, M, K;\n    cin >> N >> M >> K;\n    vector<pair<int, int>> nodes(N);\n    for (int i = 0; i < N; ++i)\n        cin >> nodes[i].first >> nodes[i].second;\n    vector<Edge> edges(M);\n    vector<vector<pair<int, pair<int,long long>>>> g(N);\n    for (int j = 0; j < M; ++j) {\n        int u, v; long long w;\n        cin >> u >> v >> w;\n        edges[j] = {u-1, v-1, j, w};\n        g[u-1].emplace_back(v-1, make_pair(j, w));\n        g[v-1].emplace_back(u-1, make_pair(j, w));\n    }\n    vector<pair<int, int>> residents(K);\n    for (int k = 0; k < K; ++k)\n        cin >> residents[k].first >> residents[k].second;\n\n    // Build MST for initial connectivity\n    vector<int> on(M, 0);\n    sort(edges.begin(), edges.end());\n    DSU dsu(N);\n    int cnt = 0;\n    for (auto& e : edges) {\n        if (dsu.unite(e.u, e.v)) {\n            on[e.idx] = 1;\n            if (++cnt == N-1) break;\n        }\n    }\n    // BFS for reachability\n    vector<int> reachable(N,0);\n    queue<int> q;\n    vector<bool> vis(N,0); vis[0]=true; q.push(0);\n    while(!q.empty()){\n        int v = q.front(); q.pop();\n        reachable[v]=1;\n        for(auto& [to, ep]: g[v]) if(!vis[to]) {\n            vis[to]=1; q.push(to);\n        }\n    }\n    // For each node, for each resident, precompute all candidate assignments (within 5000)\n    vector<vector<int>> can_cover(N); // can_cover[i]: residents node i can cover within 5000\n    for (int i = 0; i < N; ++i) if (reachable[i]) {\n        for (int k = 0; k < K; ++k) {\n            int d = dist(nodes[i].first, nodes[i].second, residents[k].first, residents[k].second);\n            if (d <= 5000) can_cover[i].push_back(k);\n        }\n    }\n    // Greedy Set Cover\n    vector<int> Pi(N, 0);\n    set<int> not_covered;\n    for (int k = 0; k < K; ++k) not_covered.insert(k);\n    while (!not_covered.empty()) {\n        int best_node = -1, best_num = 0, best_cost = numeric_limits<int>::max(), best_radius = 0;\n        vector<int> best_covers;\n        for (int i = 0; i < N; ++i) if (reachable[i]) {\n            vector<int> candidate; int maxdist = 0;\n            for (int k : can_cover[i]) if (not_covered.count(k)) {\n                int d = dist(nodes[i].first, nodes[i].second, residents[k].first, residents[k].second);\n                candidate.push_back(k);\n                if (d > maxdist) maxdist = d;\n            }\n            if (candidate.empty()) continue;\n            int inc_cost = maxdist*maxdist;\n            if ((int)candidate.size() > best_num ||\n                ((int)candidate.size() == best_num && inc_cost < best_cost)) {\n                best_node = i;\n                best_num = candidate.size();\n                best_cost = inc_cost;\n                best_covers = candidate;\n                best_radius = maxdist;\n            }\n        }\n        if (best_node == -1) break;\n        Pi[best_node] = max(Pi[best_node], best_radius);\n        for (int k : best_covers) not_covered.erase(k);\n    }\n    // Fallback: assign missing if any (should not be needed)\n    if (!not_covered.empty()) {\n        for (int k : not_covered) {\n            int best = -1, best_d = 1e9;\n            for (int v = 0; v < N; ++v) if (reachable[v]) {\n                int d = dist(nodes[v].first, nodes[v].second, residents[k].first, residents[k].second);\n                if (d < best_d) { best = v; best_d = d;}\n            }\n            if (best != -1) Pi[best] = max(Pi[best], best_d);\n        }\n    }\n    // Prune unnecessary Pi's\n    vector<bool> still_covered(K, false);\n    for (int i = 0; i < N; ++i) if (Pi[i] > 0) {\n        for (int k = 0; k < K; ++k) {\n            int d = dist(nodes[i].first, nodes[i].second, residents[k].first, residents[k].second);\n            if (d <= Pi[i]) still_covered[k] = true;\n        }\n    }\n    for (int i = 0; i < N; ++i) if (Pi[i] > 0) {\n        bool safe = true;\n        vector<int> need_cover;\n        for (int k = 0; k < K; ++k) {\n            int d = dist(nodes[i].first, nodes[i].second, residents[k].first, residents[k].second);\n            if (d <= Pi[i] && still_covered[k]) need_cover.push_back(k);\n        }\n        for (int k : need_cover) {\n            bool one_covered = false;\n            for (int j = 0; j < N; ++j) if (j != i && Pi[j] > 0) {\n                int d = dist(nodes[j].first, nodes[j].second, residents[k].first, residents[k].second);\n                if (d <= Pi[j]) { one_covered = true; break; }\n            }\n            if (!one_covered) { safe = false; break; }\n        }\n        if (safe) Pi[i] = 0;\n    }\n\n    // ----------- Fix: Guaranteed Connectivity ----------- //\n    vector<int> new_on(M, 0);\n    set<int> need_connect;\n    for (int i = 0; i < N; ++i)\n        if (Pi[i] > 0) need_connect.insert(i);\n    for (int src : need_connect) {\n        // Dijkstra from `src` to 0 to find path (reverse, as 0 is unique root)\n        vector<long long> d(N, 1e18);\n        vector<int> par(N, -1), pareid(N, -1);\n        using pli = pair<long long,int>;\n        priority_queue<pli, vector<pli>, greater<pli>> pq;\n        d[src] = 0; pq.push({0,src});\n        while (!pq.empty()) {\n            auto [cost, v] = pq.top(); pq.pop();\n            if (cost > d[v]) continue;\n            for (auto& [to, epr] : g[v]) {\n                int eid = epr.first; long long ew = epr.second;\n                if (d[to] > d[v] + ew) {\n                    d[to] = d[v] + ew;\n                    par[to] = v;\n                    pareid[to] = eid;\n                    pq.push({d[to],to});\n                }\n            }\n        }\n        // Traverse from src to 0\n        int v = 0;\n        while (v != src && par[v] != -1) {\n            new_on[pareid[v]] = 1;\n            v = par[v];\n        }\n    }\n    // Also turn on edge from 0 to itself in case Pi[0]>0 (no effect)\n    on = new_on;\n\n    // Output\n    for (int i = 0; i < N; ++i) cout << Pi[i] << (i+1==N ? '\\n' : ' ');\n    for (int j = 0; j < M; ++j) cout << on[j] << (j+1==M ? '\\n' : ' ');\n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <algorithm>\n#include <queue>\n#include <cassert>\n#include <set>\nusing namespace std;\n\nconstexpr int N = 30;\nconstexpr int NN = N*(N+1)/2;\nconstexpr int MAX_MOVE = 10000;\n\nconst int dx[6] = {-1, -1, 0, 0, 1, 1};\nconst int dy[6] = {-1, 0, -1, 1, 0, 1};\n\ninline bool is_valid(int x, int y) {\n    return 0 <= x && x < N && 0 <= y && y <= x;\n}\ninline bool is_adjacent(int x1, int y1, int x2, int y2) {\n    for(int d=0; d<6; ++d)\n        if(x1+dx[d]==x2 && y1+dy[d]==y2) return true;\n    return false;\n}\ninline bool has_child(int x, int y) { return x < N-1; }\ninline pair<pair<int,int>, pair<int,int>> get_children(int x, int y) {\n    return {{x+1,y}, {x+1,y+1}};\n}\ninline pair<int,int> get_parentL(int x, int y) { return {x-1,y-1}; }\ninline pair<int,int> get_parentR(int x, int y) { return {x-1,y}; }\n\nstruct MoveRecorder {\n    vector<tuple<int,int,int,int>> moves;\n    int K = 0;\n    vector<vector<int>> &grid;\n    vector<pair<int,int>> &label_pos;\n    MoveRecorder(vector<vector<int>> &g, vector<pair<int,int>> &lp): grid(g), label_pos(lp) {}\n    void do_swap(int x1, int y1, int x2, int y2) {\n        using std::swap;\n        assert(is_adjacent(x1, y1, x2, y2));\n        swap(grid[x1][y1], grid[x2][y2]);\n        label_pos[grid[x1][y1]] = {x1, y1};\n        label_pos[grid[x2][y2]] = {x2, y2};\n        moves.emplace_back(x1, y1, x2, y2);\n        K++;\n    }\n};\n\nint count_violation(const vector<vector<int>> &grid) {\n    int res = 0;\n    for (int x = 0; x < N-1; ++x)\n        for (int y = 0; y <= x; ++y) {\n            auto [l, r] = get_children(x,y);\n            if(grid[x][y] > grid[l.first][l.second]) res++;\n            if(grid[x][y] > grid[r.first][r.second]) res++;\n        }\n    return res;\n}\n\nvector<pair<int,int>> bfs_path(const vector<vector<int>> &grid, pair<int,int> from, pair<int,int> to, int max_depth=16) {\n    // Early out\n    if(from == to) return {from};\n    queue<vector<pair<int,int>>> q;\n    set<pair<int,int>> vis;\n    q.push({from});\n    vis.insert(from);\n    while(!q.empty()) {\n        auto path = q.front(); q.pop();\n        auto [x,y] = path.back();\n        if((int)path.size() > max_depth+1) continue;\n        for(int d=0; d<6; ++d) {\n            int nx = x+dx[d], ny = y+dy[d];\n            if(is_valid(nx,ny) && !vis.count({nx,ny})) {\n                auto np = path; np.emplace_back(nx,ny);\n                if(make_pair(nx,ny)==to) return np;\n                q.push(np); vis.insert({nx,ny});\n            }\n        }\n    }\n    return {};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    vector<vector<int>> grid(N);\n    vector<pair<int,int>> label_pos(NN);\n    for(int x=0; x<N; ++x) {\n        grid[x].resize(x+1);\n        for(int y=0; y<=x; ++y){\n            cin >> grid[x][y];\n            label_pos[grid[x][y]] = {x, y};\n        }\n    }\n    MoveRecorder recorder(grid, label_pos);\n\n    // Alternate multi-directional passes\n    int max_pass = 13;\n    for(int pass = 0; pass < max_pass && recorder.K < MAX_MOVE; ++pass) {\n        bool changed = false;\n        // Top-down\n        for(int x=0; x<N-1 && recorder.K < MAX_MOVE; ++x) {\n            int sy = (pass&1?x:0), ey = (pass&1? -1:x+1), delta = (pass&1? -1:1);\n            for(int y=sy; y!=ey && recorder.K < MAX_MOVE; y+=delta) {\n                int v = grid[x][y];\n                auto [l,r] = get_children(x, y);\n                int lval = grid[l.first][l.second], rval = grid[r.first][r.second];\n                if(v > lval || v > rval) {\n                    int cx = x, cy = y;\n                    while(cx < N-1 && recorder.K < MAX_MOVE) {\n                        auto [cl,cr] = get_children(cx, cy);\n                        int clx=cl.first, cly=cl.second, crx=cr.first, cry=cr.second;\n                        int cv = grid[cx][cy], clv = grid[clx][cly], crv = grid[crx][cry];\n                        if(clv < crv && clv < cv) {\n                            recorder.do_swap(cx, cy, clx, cly);\n                            cx = clx; cy = cly; changed = true;\n                        }else if(crv < clv && crv < cv) {\n                            recorder.do_swap(cx, cy, crx, cry);\n                            cx = crx; cy = cry; changed = true;\n                        }else break;\n                    }\n                }\n            }\n        }\n        // Bottom-up\n        for(int x=N-1; x>0 && recorder.K < MAX_MOVE; --x) {\n            int sy = (pass&1?x:0), ey = (pass&1? -1:x+1), delta = (pass&1? -1:1);\n            for(int y=sy; y!=ey && recorder.K < MAX_MOVE; y+=delta) {\n                int cv = grid[x][y];\n                // left parent\n                if(y > 0) {\n                    auto [plx,ply] = get_parentL(x,y);\n                    if(is_valid(plx,ply) && grid[plx][ply] > cv) {\n                        int cx = x, cy = y;\n                        while(cx>0 && recorder.K<MAX_MOVE) {\n                            auto [plnx,plny] = get_parentL(cx,cy);\n                            if(is_valid(plnx,plny) && grid[plnx][plny] > grid[cx][cy]) {\n                                recorder.do_swap(plnx,plny,cx,cy);\n                                cx=plnx;cy=plny;changed=true;\n                            } else break;\n                        }\n                    }\n                }\n                // right parent\n                if(y < x) {\n                    auto [prx, pry] = get_parentR(x, y);\n                    if(is_valid(prx,pry) && grid[prx][pry] > cv) {\n                        int cx = x, cy = y;\n                        while(cx>0 && recorder.K<MAX_MOVE) {\n                            auto [prnx,prny] = get_parentR(cx,cy);\n                            if(is_valid(prnx,prny) && grid[prnx][prny] > grid[cx][cy]) {\n                                recorder.do_swap(prnx,prny,cx,cy);\n                                cx=prnx;cy=prny;changed=true;\n                            }else break;\n                        }\n                    }\n                }\n            }\n        }\n        if(!changed) break;\n    }\n    // Build violation list, highest first\n    vector<tuple<int,int,int,int,int>> vios; // x, y, cx, cy, tier\n    for (int x = 0; x < N-1; ++x)\n        for (int y = 0; y <= x; ++y) {\n            auto [l, r] = get_children(x,y);\n            if(grid[x][y] > grid[l.first][l.second]) vios.emplace_back(x,y, l.first,l.second, x);\n            if(grid[x][y] > grid[r.first][r.second]) vios.emplace_back(x,y, r.first,r.second, x);\n        }\n    // Sort by uppermost tier first\n    sort(vios.begin(), vios.end(), [](auto &a, auto &b){ return get<4>(a) < get<4>(b); });\n\n    int max_try = 200; // Try more BFS corrections\n    int done = 0;\n    int max_bfs_depth = 14; // High but not too high\n    for(auto &[x1,y1,x2,y2,tier]: vios) {\n        if(recorder.K >= MAX_MOVE) break;\n        if(grid[x1][y1] <= grid[x2][y2]) continue;\n        auto path = bfs_path(grid, {x2,y2}, {x1,y1}, max_bfs_depth);\n        if(!path.empty() && path.size() > 1 && (int)path.size()-1 + recorder.K < MAX_MOVE) {\n            for(int i=(int)path.size()-2; i>=0; --i)\n                recorder.do_swap(path[i+1].first,path[i+1].second,path[i].first,path[i].second);\n            done++;\n        }\n        if(done > max_try) break;\n    }\n    // Output\n    cout << recorder.K << '\\n';\n    for(const auto& [x1,y1,x2,y2]: recorder.moves)\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << \"\\n\";\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int D = 9;\nconstexpr int ENTRANCE_I = 0;\nconstexpr int ENTRANCE_J = (D-1)/2;\nconst int di[] = {-1,1,0,0}, dj[] = {0,0,-1,1};\n\nstruct Cell {\n    int i, j;\n    Cell(int i=0, int j=0):i(i),j(j){}\n    bool operator==(const Cell& o) const { return i==o.i && j==o.j; }\n    bool operator!=(const Cell& o) const { return !(*this==o); }\n};\n\nostream& operator<<(ostream& os, const Cell& c) {\n    return os << c.i << ' ' << c.j;\n}\n\nbool in_grid(int i, int j) {\n    return 0 <= i && i < D && 0 <= j && j < D;\n}\n\nvector<Cell> adj4(Cell c) {\n    vector<Cell> v;\n    for(int d=0;d<4;++d) {\n        int ni = c.i+di[d], nj = c.j+dj[d];\n        if(in_grid(ni,nj)) v.emplace_back(ni,nj);\n    }\n    return v;\n}\n\n// For quickly assigning container numbers to positions.\nstruct WarehouseSolver {\n    int N;\n    set<Cell> obstacles;\n    set<Cell> not_assignable; // entrance + 3 adjacents + obstacles\n    vector<Cell> assignable_cells; // order by BFS from entrance\n    map<Cell, int> cell_to_bfs_layer;\n\n    // Storage state\n    vector<pair<int,int>> arrivals; // (container number, arrival idx)\n    map<Cell, int> assigned_cell_to_num;\n    map<int, Cell> num_to_cell;\n\n    // Extraction ordering\n    vector<Cell> extraction_order;\n\n    WarehouseSolver() {}\n\n    void initialize() {\n        // Build not_assignable: entrance & its 3 adjacents & obstacles\n        not_assignable.insert(Cell(ENTRANCE_I, ENTRANCE_J));\n        for(int d=0;d<4;++d) {\n            int ni = ENTRANCE_I+di[d], nj = ENTRANCE_J+dj[d];\n            if(in_grid(ni,nj))\n                not_assignable.insert(Cell(ni,nj));\n        }\n        for(auto c: obstacles) not_assignable.insert(c);\n\n        // BFS from entrance to get \"ranked\" assignable cells\n        vector<vector<int>> vis(D, vector<int>(D, -1));\n        queue<Cell> q;\n        q.push(Cell(ENTRANCE_I, ENTRANCE_J));\n        vis[ENTRANCE_I][ENTRANCE_J]=0;\n        int dist = 1;\n        // Pre-mark not_assignable so we don't revisit\n        for(auto c: not_assignable) vis[c.i][c.j]=-2;\n        vis[ENTRANCE_I][ENTRANCE_J]=0; // entrance\n\n        vector<Cell> order;\n        while(!q.empty()) {\n            Cell c = q.front();q.pop();\n            for(auto d: adj4(c)) {\n                if(vis[d.i][d.j] == -1) {\n                    vis[d.i][d.j] = vis[c.i][c.j]+1;\n                    q.push(d);\n                    // If it's assignable (not in not_assignable), add to order\n                    if(not_assignable.count(d) == 0) {\n                        assignable_cells.push_back(d);\n                        cell_to_bfs_layer[d] = vis[d.i][d.j];\n                    }\n                }\n            }\n        }\n    }\n\n    void read_input() {\n        cin >> N;\n        for(int k=0;k<N;++k) {\n            int ri,rj;\n            cin >> ri >> rj;\n            obstacles.insert(Cell(ri,rj));\n        }\n        initialize();\n    }\n\n    void assign_container(int t_d, int arrival_idx) {\n        // Add to arrivals\n        arrivals.emplace_back(t_d, arrival_idx);\n        // We need to select an assignable cell for it.\n\n        // For containers arrived so far, make a sorted list\n        vector<pair<int,int>> sorted_arrivals = arrivals;\n        sort(sorted_arrivals.begin(), sorted_arrivals.end()); // by t_d\n        // Their optimal mapping: map sorted_arrivals[i] to assignable_cells[i]\n        // For current container (arrival_idx), find where it lands\n        int pos = -1;\n        for(int i=0;i<sorted_arrivals.size();++i) {\n            if(sorted_arrivals[i].second == arrival_idx) {\n                pos = i;\n                break;\n            }\n        }\n        assert(pos != -1);\n\n        // Some assignable_cells may already be assigned: must choose the first unassigned slot corresponding to pos (since in rare cases, due to obstacles, not all cells may be left)\n        vector<bool> used(assignable_cells.size(), false);\n        for(auto& kv: assigned_cell_to_num) {\n            // Mark which slots are taken\n            for(int i=0;i<assignable_cells.size();++i) {\n                if(assignable_cells[i]==kv.first) used[i]=true;\n            }\n        }\n        // Assign in sorted order: for the list of arrivals (sorting by t_d), map to available slots in assignable_cells in order, skipping used ones.\n        int assign_slot = -1, cnt = 0;\n        for(int i=0;i<assignable_cells.size();++i) {\n            if(used[i]) continue;\n            if(cnt==pos) { assign_slot=i; break; }\n            cnt++;\n        }\n        assert(assign_slot != -1);\n        Cell assign_cell = assignable_cells[assign_slot];\n\n        // Assign this cell to the container num\n        assigned_cell_to_num[assign_cell] = t_d;\n        num_to_cell[t_d] = assign_cell;\n\n        // Output assignment\n        cout << assign_cell.i << \" \" << assign_cell.j << endl;\n        cout.flush();\n    }\n\n    // After all containers are placed, plan extraction order.\n    void plan_extraction() {\n        // Build grid state: 0=empty, -1=obstacle, >0=container num+1\n        vector<vector<int>> grid(D, vector<int>(D,0));\n        for(auto c: obstacles) grid[c.i][c.j]=-1;\n        for(auto& [cell, num]: assigned_cell_to_num) grid[cell.i][cell.j]=num+1;\n\n        set<int> remaining_nums;\n        for(auto& [num, cell]: num_to_cell) remaining_nums.insert(num);\n\n        extraction_order.clear();\n\n        for(int step=0;step < num_to_cell.size(); ++step) {\n            // Find all containers (cells with grid>0) reachable from entrance\n            queue<Cell> q;\n            vector<vector<bool>> vis(D,vector<bool>(D,false));\n            q.push(Cell(ENTRANCE_I, ENTRANCE_J));\n            vis[ENTRANCE_I][ENTRANCE_J]=true;\n\n            set<Cell> reachable;\n            while(!q.empty()) {\n                Cell c = q.front();q.pop();\n                for(auto d: adj4(c)) {\n                    if(!vis[d.i][d.j]) {\n                        if(grid[d.i][d.j] == 0) {\n                            vis[d.i][d.j]=true;q.push(d);\n                        } else if(grid[d.i][d.j]>0) {\n                            // It's a container\n                            reachable.insert(d);\n                        }\n                    }\n                }\n            }\n            // From reachable, pick container with smallest num\n            int best_num = 1e9;\n            Cell best_cell;\n            for(auto c: reachable) {\n                int num = grid[c.i][c.j]-1;\n                if(num < best_num) { best_num = num; best_cell = c; }\n            }\n            extraction_order.push_back(best_cell);\n\n            // Remove this from grid\n            grid[best_cell.i][best_cell.j] = 0;\n            remaining_nums.erase(best_num);\n        }\n    }\n\n    void output_extraction_order() {\n        for(auto& c: extraction_order) {\n            cout << c.i << \" \" << c.j << endl;\n        }\n        cout.flush();\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D_input, N;\n    cin >> D_input >> N;\n    assert(D_input==D);\n\n    WarehouseSolver solver;\n    solver.N=N;\n    for(int k=0;k<N;++k) {\n        int ri,rj; cin >> ri >> rj;\n        solver.obstacles.insert(Cell(ri,rj));\n    }\n    solver.initialize(); // needs to be called after obstacles are set up\n\n    const int K = D*D-1-N;\n    for(int d=0; d<K; ++d) {\n        int t_d; cin >> t_d;\n        solver.assign_container(t_d, d);\n    }\n    // After all placements\n    solver.plan_extraction();\n    solver.output_extraction_order();\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 50, M = 100, COLORS = 101;\nint n, m;\nint c[N][N];\n\n// For each color, set of adjacent colors (including 0)\nvector<set<int>> adjacency(COLORS);\n// Whether color c touches the edge (adjacent to outside/0)\nvector<bool> touches0(COLORS);\n\n// For output\nint d[N][N];\n\n// Direction vectors\nconstexpr int di[] = {-1, 0, 1, 0};\nconstexpr int dj[] = {0, 1, 0, -1};\n\n// Compose adjacency graph for all colors from input\nvoid build_adjacency() {\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j) {\n            int col = c[i][j];\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir], nj = j + dj[dir];\n                if (ni < 0 || nj < 0 || ni >= n || nj >= n) {\n                    adjacency[col].insert(0);\n                    adjacency[0].insert(col);\n                    touches0[col] = true;\n                } else if (c[ni][nj] != col) {\n                    adjacency[col].insert(c[ni][nj]);\n                }\n            }\n        }\n}\n\n// List of wards (colors)\nvector<int> all_wards() {\n    vector<int> wards;\n    for (int i = 1; i <= m; ++i) wards.push_back(i);\n    return wards;\n}\n\n// Assign output locations for each ward (color)\n// Ensures border-wards go to boundary.\nmap<int, pair<int,int>> assign_ward_positions(const vector<int>& wards) {\n    map<int,pair<int,int>> pos;\n    set<pair<int,int>> used;\n    // 1. Lay out border-wards\n    vector<pair<int,int>> border_spots;\n    for (int i = 0; i < n; ++i) {\n        border_spots.emplace_back(0, i);\n        border_spots.emplace_back(n-1, i);\n    }\n    for (int j = 1; j < n-1; ++j) {\n        border_spots.emplace_back(j, 0);\n        border_spots.emplace_back(j, n-1);\n    }\n    int bi = 0;\n\n    // 2. Inner spots for rest\n    vector<pair<int,int>> inner_spots;\n    for (int i = 1; i < n-1; ++i)\n        for (int j = 1; j < n-1; ++j)\n            inner_spots.emplace_back(i,j);\n    int ii = 0;\n\n    // Wards sorted: priority to those with more adjacents\n    vector<int> order = wards;\n    sort(order.begin(), order.end(), [](int a, int b) {\n        return adjacency[a].size() > adjacency[b].size();\n    });\n\n    for (int ward : order) {\n        if (touches0[ward] && bi < (int)border_spots.size()) {\n            // Assign to border\n            pos[ward] = border_spots[bi++];\n            used.insert(pos[ward]);\n        } else if (ii < (int)inner_spots.size()) {\n            pos[ward] = inner_spots[ii++];\n            used.insert(pos[ward]);\n        } else {\n            // fallback (should not happen)\n            pos[ward] = make_pair(0,0);\n        }\n    }\n    return pos;\n}\n\n// Fill in the output grid according to assigned ward positions and enforce adjacency requirements.\nvoid build_output_map(const map<int, pair<int,int>>& ward_pos) {\n    // Clear to zero\n    for (int i=0;i<n;++i) for (int j=0;j<n;++j) d[i][j]=0;\n\n    // Place all the wards in their assigned cell\n    for (const auto& [ward, p] : ward_pos) {\n        d[p.first][p.second] = ward;\n    }\n\n    // Now, for each adjacency, ensure the pair is represented by a pair of adjacent cells on the grid.\n    // Try to do this with minimal area addition.\n    for (int c = 1; c <= m; ++c) {\n        for (int dcol : adjacency[c]) {\n            if (dcol < c) continue; // Each pair once (and skip dcol=0 for now, handlded by positions on boundary)\n\n            auto [ci, cj] = ward_pos.at(c);\n            auto [di_, dj_] = ward_pos.at(dcol);\n\n            // Are they adjacent in the grid?\n            if (abs(ci-di_)+abs(cj-dj_) ==1) continue;\n\n            // Otherwise, connect them along Manhattan path with their own colors\n            int curi = ci, curj = cj;\n            // Let's make a path from (ci,cj) to (di_,dj_) (no '0' along the way)\n            while (curi != di_) {\n                curi += (di_ > curi) ? 1 : -1;\n                if (d[curi][curj] == 0)\n                    d[curi][curj] = c;\n            }\n            while (curj != dj_) {\n                curj += (dj_ > curj) ? 1 : -1;\n                if (d[curi][curj] == 0)\n                    d[curi][curj] = c;\n            }\n        }\n    }\n}\n\n// Validation helpers (not used in contest submission)\n// Check all same-color cells are connected (DFS)\n// Check adjacencies\n\n// Full solution\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    n = N; m = M;\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j)\n            cin >> c[i][j];\n\n    adjacency.assign(COLORS, set<int>());\n    touches0.assign(COLORS, false);\n\n    build_adjacency();\n\n    vector<int> wards = all_wards();\n\n    auto ward_pos = assign_ward_positions(wards);\n\n    build_output_map(ward_pos);\n\n    // Output result\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cout << d[i][j] << \" \\n\"[j==n-1];\n        }\n    }\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nvoid fastio() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); }\nvoid flush() { cout.flush(); }\n\n// --------------- Definitions --------------\nint N, D, Q;  // Number, Divisions, Queries\nint query_count = 0;\n\n// Ask a balance between L and R, return -1 (L<R), 0 (=), 1 (L>R)\nint askBalance(const vector<int>& L, const vector<int>& R) {\n    assert(!L.empty() && !R.empty());\n    assert(query_count < Q);\n    cout << L.size() << \" \" << R.size() << \" \";\n    for (int x : L) cout << x << \" \";\n    for (int x : R) cout << x << \" \";\n    cout << \"\\n\";\n    flush();\n    string s; cin >> s;\n    query_count++;\n    if (s == \"<\") return -1;\n    else if (s == \"=\") return 0;\n    else if (s == \">\") return 1;\n    else {\n        cerr << \"Unknown judge response: \" << s << endl;\n        exit(1);\n    }\n}\n\n// Tournament-based win scores\nvector<int> get_win_scores(int N, int Q) {\n    vector<int> win_count(N, 0);\n    vector<vector<int>> compared(N, vector<int>(N, 0)); // 0: not yet, 1: compared\n\n    int max_pairs = Q;\n    // Enumerate all unordered pairs, random order for coverage\n    vector<pair<int,int>> pairs;\n    for (int i = 0; i < N; ++i) {\n        for (int j = i+1; j < N; ++j) {\n            pairs.emplace_back(i, j);\n        }\n    }\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    shuffle(pairs.begin(), pairs.end(), rng);\n\n    int used = 0;\n    for (auto &[i, j]: pairs) {\n        if (used >= max_pairs) break;\n        int res = askBalance({i}, {j});\n        if (res == 1) { win_count[i]++; }\n        else if (res == -1) { win_count[j]++; }\n        // in case of tie (rare), do nothing (or +0.5 to both if desired)\n        // compared[i][j] = compared[j][i] = 1;\n        used++;\n    }\n    return win_count;\n}\n\n// Assign heavy items to lightest groups, greedy stratified assign\nvector<int> assign_to_groups_by_score(const vector<int>& score) {\n    int N = score.size();\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    // Highest win_count first\n    sort(idx.begin(), idx.end(), [&](int i, int j){ return score[i] > score[j]; });\n\n    vector<long long> group_score(D, 0);\n    vector<int> assign(N, -1);\n    for (int t = 0; t < N; ++t) {\n        int i = idx[t];\n        if (t < D) {\n            assign[i] = t; // ensure each group gets at least 1 item\n            group_score[t] += score[i];\n        } else {\n            // assign to current lowest group\n            int gid = min_element(group_score.begin(), group_score.end()) - group_score.begin();\n            assign[i] = gid;\n            group_score[gid] += score[i];\n        }\n    }\n    return assign;\n}\n\nint main() {\n    fastio();\n    cin >> N >> D >> Q;\n\n    // 1. Use up to Q pairwise queries to collect win data\n    vector<int> win_score = get_win_scores(N, Q);\n\n    // 2. Assign by greedy\n    vector<int> assign = assign_to_groups_by_score(win_score);\n\n    // 3. Output\n    for (int i = 0; i < N; ++i) {\n        cout << assign[i] << (i+1 == N ? '\\n' : ' ');\n    }\n    flush();\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 200;\nconstexpr int M = 10;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int n, m;\n    cin >> n >> m;\n    assert(n == 200 && m == 10);\n\n    vector<vector<int>> stacks(m); // [stack][bottom..top]\n    vector<pair<int,int>> box_pos(n+1); // [box] -> (stack_id, pos_from_bottom)\n\n    for (int i = 0; i < m; ++i) {\n        stacks[i].resize(n/m);\n        for (int j = 0; j < n/m; ++j) {\n            cin >> stacks[i][j];\n            box_pos[stacks[i][j]] = {i, j};\n        }\n    }\n\n    vector<pair<int, int>> ops; // operations: (v, stack_id), stack_id==0 for carry out\n\n    // For each number to be carried out in order\n    vector<int> stack_pointer(m, 0); // number of boxes taken out from bottom of each stack\n\n    for (int target = 1; target <= n; ++target) {\n        // Find where the target box is\n        pair<int,int> pos = box_pos[target];\n        int s = pos.first, idx = pos.second;\n\n        // Since boxes are only removed from top, need to adjust for boxes already taken out from this stack\n        int logical_pos = idx - stack_pointer[s];\n        int stack_size = stacks[s].size();\n\n        // If it's at the top of its stack (adjusted)\n        if (logical_pos == (int)stacks[s].size() - 1) {\n            // Output: (target, 0)\n            ops.emplace_back(target, 0);\n            // Remove from stack\n            stacks[s].pop_back();\n            stack_pointer[s]++;\n        } else {\n            // Need to move [logical_pos, end] to another stack\n            vector<int> to_move;\n            for (int j = logical_pos; j < (int)stacks[s].size(); ++j) to_move.push_back(stacks[s][j]);\n            \n            // Remove from source stack\n            stacks[s].resize(logical_pos);\n\n            // Invalidate pointer for moved boxes\n            for (int box : to_move) box_pos[box] = {-1, -1};\n\n            // Select destination stack (shortest, not s)\n            int dest = -1, minsize = INT_MAX;\n            for (int i = 0; i < m; ++i) {\n                if (i == s) continue;\n                if ((int)stacks[i].size() < minsize) {\n                    minsize = (int)stacks[i].size();\n                    dest = i;\n                }\n            }\n\n            // Place chunk to target stack\n            for (int box : to_move) {\n                stacks[dest].push_back(box);\n            }\n            // Update positions for moved boxes\n            int sz = stacks[dest].size();\n            for (int j = 0; j < (int)to_move.size(); ++j) {\n                box_pos[to_move[j]] = {dest, sz - (int)to_move.size() + j};\n            }\n\n            // Output operation: (target, dest+1)\n            ops.emplace_back(target, dest+1);\n        restart: // We'll loop back as the box may need carry operation in next iteration\n            // Try again in next loop, as now it should be on top at dest stack\n            target--;\n        }\n    }\n    // Output\n    for (auto [v, i] : ops) cout << v << \" \" << i << \"\\n\";\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nconstexpr int di[4] = {-1, 1, 0, 0};\nconstexpr int dj[4] = {0, 0, -1, 1};\nconstexpr char DIR[4] = {'U', 'D', 'L', 'R'};\nconstexpr char INV_DIR[4] = {'D', 'U', 'R', 'L'};\n\nint N;\nvector<string> hwall, vwall;\nvector<vector<int>> dirt;\n\n// Store reconstructed path\nstring path;\n\n// Used for visiting\nvector<vector<bool>> vis;\n\n// For output movement\nstruct Move {\n    int i, j;  // position after move\n    char dir;  // move direction to here\n};\n\nstruct Cell {\n    int i, j, d;\n    bool operator<(const Cell &rhs) const { return d > rhs.d; }\n};\nvector<Cell> cells_by_dirt;\n\ninline bool in_grid(int i, int j) {\n    return 0 <= i && i < N && 0 <= j && j < N;\n}\n\nbool can_move(int i, int j, int dir) {\n    int ni = i + di[dir], nj = j + dj[dir];\n    if (!in_grid(ni, nj)) return false;\n    if (dir == 0) {  // U\n        return hwall[ni][nj] == '0';\n    }\n    if (dir == 1) {  // D\n        return hwall[i][j] == '0';\n    }\n    if (dir == 2) {  // L\n        return vwall[ni][nj] == '0';\n    }\n    if (dir == 3) {  // R\n        return vwall[i][j] == '0';\n    }\n    return false;\n}\n\n/**\n * Enhanced DFS: Recursively traverse unvisited neighbors, preferring high dirtiness.\n */\nvoid dfs(int i, int j) {\n    vis[i][j] = true;\n    // Make a list of neighbor candidates, sort by dirtiness\n    vector<pair<int, int>> nbrs;\n    for (int dir = 0; dir < 4; ++dir) {\n        int ni = i + di[dir], nj = j + dj[dir];\n        if (in_grid(ni, nj) && !vis[ni][nj] && can_move(i, j, dir)) {\n            nbrs.emplace_back(dirt[ni][nj], dir);\n        }\n    }\n    // Prefer higher d neighbors\n    sort(nbrs.rbegin(), nbrs.rend());\n\n    for (auto &[dval, dir] : nbrs) {\n        int ni = i + di[dir], nj = j + dj[dir];\n        path.push_back(DIR[dir]);\n        dfs(ni, nj);\n        path.push_back(INV_DIR[dir]);\n    }\n}\n\n// Add detour loops at high-dirt cells, if budget allows\nvoid insert_high_dirt_loops(int maxLength) {\n    // Top K highest dirt cells\n    int K = min(7, N*N/8);\n    vector<pair<int, int>> loopcells;\n    for (int i = 0; i < K && i < int(cells_by_dirt.size()); ++i) {\n        if (cells_by_dirt[i].i == 0 && cells_by_dirt[i].j == 0) continue;\n        loopcells.emplace_back(cells_by_dirt[i].i, cells_by_dirt[i].j);\n    }\n    // Try to insert short 'loops' around those\n    int insertions = 0;\n    vector<int> insert_pos;\n\n    // Find all path positions at high-dirt cells\n    for (auto &[ci, cj] : loopcells) {\n        for (int idx = 0, pi = 0, pj = 0; idx < int(path.size()); ++idx) {\n            int oldi = pi, oldj = pj;\n            if (path[idx] == 'U') --pi;\n            else if (path[idx] == 'D') ++pi;\n            else if (path[idx] == 'L') --pj;\n            else if (path[idx] == 'R') ++pj;\n            if (pi == ci && pj == cj) {\n                insert_pos.push_back(idx);\n                break;\n            }\n        }\n    }\n\n    // Insert loops (for each, try to find a local 2-move cycle)\n    for (int posidx = 0; posidx < (int)insert_pos.size(); ++posidx) {\n        int insert_at = insert_pos[posidx];\n        int ci = loopcells[posidx].first, cj = loopcells[posidx].second;\n        // Look for a neighbor (not a wall), not out of bounds\n        for (int dir = 0; dir < 4; ++dir) {\n            int ni = ci + di[dir], nj = cj + dj[dir];\n            if (!in_grid(ni, nj)) continue;\n            if (!can_move(ci, cj, dir)) continue;\n            // Insert: go to neighbor and return\n            if ((int)path.size() + 2 <= maxLength) {\n                path.insert(insert_at, 1, DIR[dir]);\n                path.insert(insert_at + 1, 1, INV_DIR[dir]);\n                insert_at += 2;\n                insertions++;\n            }\n            break; // only one for now\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    hwall.resize(N - 1);\n    for (int i = 0; i < N - 1; ++i) cin >> hwall[i];\n    vwall.resize(N);\n    for (int i = 0; i < N; ++i) cin >> vwall[i];\n    dirt.resize(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) cin >> dirt[i][j];\n\n    // Build cell list by dirt\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cells_by_dirt.push_back(Cell{i, j, dirt[i][j]});\n    sort(cells_by_dirt.begin(), cells_by_dirt.end());\n\n    // DFS-based path\n    vis.assign(N, vector<bool>(N, false));\n    dfs(0,0);\n\n    // Ensure we return to (0,0)\n    assert(vis[0][0]);\n    // Optionally: prune if exceeds 100000\n    int maxLength = 100000;\n    if ((int)path.size() > maxLength) {\n        path = path.substr(0, maxLength); // guarantee legality\n    } else if ((int)path.size() < maxLength - 20) {\n        // Try to insert some detour loops at top dirt cells\n        insert_high_dirt_loops(maxLength);\n    }\n    cout << path << endl;\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 15;\n\n// Function to find greatest overlap (suffix of a with prefix of b)\nint calc_overlap(const string &a, const string &b) {\n    int maxl = min(a.size(), b.size());\n    for (int len = maxl; len; --len)\n        if (a.substr(a.size() - len, len) == b.substr(0, len))\n            return len;\n    return 0;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int n, m, si, sj;\n    cin >> n >> m >> si >> sj;\n\n    vector<string> grid(n);\n    for (int i = 0; i < n; ++i) cin >> grid[i];\n\n    // Build position list for each letter\n    vector<pair<int, int>> letter_pos[26];\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j)\n            letter_pos[grid[i][j] - 'A'].emplace_back(i, j);\n\n    vector<string> words(m);\n    for (int i = 0; i < m; ++i) cin >> words[i];\n\n    // --- Greedy Minimum Superstring (pairwise) ---\n    // We'll use a merging system: keep all current fragments in a list\n    vector<string> curr_words = words;\n    int step = 0;\n    while (curr_words.size() > 1) {\n        int best_i = -1, best_j = -1, best_ov = -1;\n        // Overlap from i (suffix) to j (prefix)\n        for (int i = 0; i < int(curr_words.size()); ++i) {\n            for (int j = 0; j < int(curr_words.size()); ++j) {\n                if (i == j) continue;\n                int ov = calc_overlap(curr_words[i], curr_words[j]);\n                if (ov > best_ov) {\n                    best_ov = ov;\n                    best_i = i;\n                    best_j = j;\n                }\n            }\n        }\n        // If cannot overlap at all, arbitrarily merge first two\n        if (best_ov <= 0) best_i = 0, best_j = 1, best_ov = 0;\n\n        // Merge: curr_words[best_i] + (suffix of curr_words[best_j])\n        string merged = curr_words[best_i] + curr_words[best_j].substr(best_ov);\n        vector<string> new_words;\n        // Keep all except best_i and best_j\n        for (int i = 0; i < int(curr_words.size()); ++i) {\n            if (i != best_i && i != best_j)\n                new_words.push_back(curr_words[i]);\n        }\n        new_words.push_back(merged);\n        curr_words.swap(new_words);\n\n        // Optionally, stop early if we're over length budget\n        if (curr_words[0].size() > 5000) break;\n        step++;\n    }\n    string superstring = curr_words[0];\n    if (superstring.size() > 5000) superstring = superstring.substr(0, 5000);\n\n    // --- Route: nearest key for each letter ---\n    vector<pair<int, int>> route;\n    int ci = si, cj = sj;\n    for (char ch : superstring) {\n        int c = ch - 'A';\n        int mincost = 1e9, picki = -1, pickj = -1;\n        for (auto &[ni, nj] : letter_pos[c]) {\n            int delta = abs(ci - ni) + abs(cj - nj);\n            if (delta < mincost) {\n                mincost = delta;\n                picki = ni;\n                pickj = nj;\n            }\n        }\n        route.emplace_back(picki, pickj);\n        ci = picki;\n        cj = pickj;\n    }\n\n    for (auto &[i, j] : route) cout << i << \" \" << j << '\\n';\n\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Polyomino {\n    vector<pair<int,int>> cells;\n    int h = 0, w = 0;\n    vector<vector<pair<int,int>>> placements;\n};\n\nint N, M;\ndouble eps;\nvector<Polyomino> oil_fields;\nvector<vector<int>> drillValue;\nvector<vector<int>> alivePlacements;\n\nvoid enumerate_placements() {\n    for (auto &poly : oil_fields) {\n        int min_i = 1e9, min_j = 1e9, max_i = -1e9, max_j = -1e9;\n        for (auto [x, y] : poly.cells) {\n            min_i = min(min_i, x);\n            max_i = max(max_i, x);\n            min_j = min(min_j, y);\n            max_j = max(max_j, y);\n        }\n        poly.h = max_i + 1;\n        poly.w = max_j + 1;\n        for (int base_i = 0; base_i + poly.h <= N; ++base_i) {\n            for (int base_j = 0; base_j + poly.w <= N; ++base_j) {\n                vector<pair<int,int>> placement;\n                for (auto [di, dj]: poly.cells) {\n                    placement.emplace_back(base_i + di, base_j + dj);\n                }\n                poly.placements.push_back(placement);\n            }\n        }\n    }\n}\n\nvector<vector<int>> plausible_oil_counts() {\n    vector<vector<int>> cnt(N, vector<int>(N));\n    for (int f = 0; f < M; ++f) {\n        for (int pi: alivePlacements[f]) {\n            for (auto [ci, cj]: oil_fields[f].placements[pi]) {\n                cnt[ci][cj]++;\n            }\n        }\n    }\n    return cnt;\n}\n\nvoid do_query(const string& s) {\n    cout << s << endl;\n    cout << flush;\n}\n\nbool update_alivePlacements() {\n    bool changed = false;\n    for (int f = 0; f < M; ++f) {\n        vector<int> updated;\n        for (int pi : alivePlacements[f]) {\n            const auto& placement = oil_fields[f].placements[pi];\n            bool ok = true;\n            for (auto [ci, cj]: placement) {\n                if (drillValue[ci][cj] == 0) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (!ok) continue;\n            for (auto [ci, cj]: placement) {\n                if (drillValue[ci][cj] > 0) {\n                    int possible = 1;\n                    for (int ff = 0; ff < M; ++ff) if (ff != f) {\n                        for (int pi2 : alivePlacements[ff]) {\n                            for (auto [ci2, cj2]: oil_fields[ff].placements[pi2]) {\n                                if (ci2 == ci && cj2 == cj) {\n                                    possible++;\n                                    goto donecount;\n                                }\n                            }\n                        }\n                        donecount:;\n                    }\n                    if (possible < drillValue[ci][cj]) {\n                        ok = false;\n                        break;\n                    }\n                }\n            }\n            if (ok) updated.push_back(pi);\n        }\n        if ((int)updated.size() != (int)alivePlacements[f].size()) changed = true;\n        alivePlacements[f] = move(updated);\n    }\n    return changed;\n}\n\npair<int,int> choose_next_drill() {\n    auto cnt = plausible_oil_counts();\n    int best_val = -1;\n    pair<int,int> best = {-1, -1};\n    for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j)\n        if (drillValue[i][j] == -1 && cnt[i][j] > best_val) {\n            best_val = cnt[i][j];\n            best = {i, j};\n        }\n    if (best_val == -1) {\n        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j)\n            if (drillValue[i][j] == -1) return {i, j};\n    }\n    return best;\n}\n\nbool solved(set<pair<int,int>> &result_cells) {\n    set<pair<int,int>> S;\n    for (int f=0; f<M; ++f) {\n        if (alivePlacements[f].size() != 1) return false;\n        for (auto [ci,cj]: oil_fields[f].placements[alivePlacements[f][0]]) {\n            S.emplace(ci,cj);\n        }\n    }\n    result_cells = move(S);\n    return true;\n}\n\nvoid fallback_brute(set<pair<int,int>>& answer_set, vector<pair<int,int>>& already_drilled) {\n    // Drill remaining cells\n    for (int i=0; i<N; ++i) for(int j=0; j<N; ++j)\n        if (drillValue[i][j] == -1) {\n            do_query(\"q 1 \" + to_string(i) + \" \" + to_string(j));\n            int v; cin >> v;\n            drillValue[i][j] = v;\n        }\n    // Collect oil cells\n    answer_set.clear();\n    for (int i=0; i<N; ++i) for(int j=0; j<N; ++j)\n        if (drillValue[i][j] > 0) answer_set.emplace(i,j);\n    for (auto [i,j]: already_drilled) {\n        if (drillValue[i][j] > 0) answer_set.emplace(i,j);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    cin >> N >> M >> eps;\n    oil_fields.resize(M);\n    for (int k=0; k<M; ++k) {\n        int d; cin >> d;\n        vector<pair<int,int>> cc;\n        for (int q=0; q<d; ++q) {\n            int x, y; cin >> x >> y;\n            cc.emplace_back(x, y);\n        }\n        oil_fields[k].cells = move(cc);\n    }\n\n    enumerate_placements();\n\n    alivePlacements.clear();\n    for (auto &poly : oil_fields) {\n        int K = poly.placements.size();\n        vector<int> v(K);\n        iota(v.begin(), v.end(), 0);\n        alivePlacements.push_back(move(v));\n    }\n    drillValue.assign(N, vector<int>(N, -1));\n\n    set<pair<int,int>> answer_set;\n    vector<pair<int,int>> already_drilled;\n\n    // Start (at most M) random drills\n    mt19937 rng(12345);\n    int opcnt = 0;\n    int max_trials = min(M, N*N);\n    bool found = false;\n    for (; opcnt < max_trials; ) {\n        uniform_int_distribution<int> dist(0, N-1);\n        int i = dist(rng), j = dist(rng);\n        if (drillValue[i][j] != -1) continue;\n        do_query(\"q 1 \" + to_string(i) + \" \" + to_string(j));\n        int v; cin >> v;\n        drillValue[i][j] = v;\n        already_drilled.emplace_back(i,j);\n        opcnt++;\n        update_alivePlacements();\n        if (solved(answer_set)) { found = true; break; }\n    }\n\n    int alive_total = 0;\n    for (auto& pl : alivePlacements) alive_total += pl.size();\n    // Elimination loop (if necessary)\n    while (!found && opcnt < 2 * N * N && alive_total < 1000) {\n        if (solved(answer_set)) { found = true; break;}\n        pair<int,int> drill = choose_next_drill();\n        if (drill.first == -1) break;\n        int i = drill.first, j = drill.second;\n        do_query(\"q 1 \" + to_string(i) + \" \" + to_string(j));\n        int v; cin >> v;\n        drillValue[i][j] = v;\n        already_drilled.emplace_back(i,j);\n        opcnt++;\n        update_alivePlacements();\n        alive_total = 0;\n        for (auto& pl : alivePlacements) alive_total += pl.size();\n    }\n\n    if (!found) {\n        fallback_brute(answer_set, already_drilled);\n    }\n    else {\n        // Ensure all positive drilled cells present\n        for (auto [i,j]: already_drilled) {\n            if (drillValue[i][j] > 0) answer_set.emplace(i,j);\n        }\n    }\n\n    vector<pair<int,int>> oilCells(answer_set.begin(), answer_set.end());\n    cout << \"a \" << oilCells.size();\n    for (auto [i,j]: oilCells) cout << \" \" << i << \" \" << j;\n    cout << endl << flush;\n\n    int res = 0;\n    cin >> res; // Must always read final input!\n    if (res != 1) {\n        cerr << \"# Output judged incorrect!\" << endl;\n    }\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int W = 1000;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int w, D, N;\n    cin >> w >> D >> N;\n    vector<vector<int>> a(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    for (int d = 0; d < D; ++d) {\n        int64_t total_area = 0;\n        for (int k = 0; k < N; ++k)\n            total_area += a[d][k];\n\n        vector<int> widths(N);\n        int used = 0;\n        for (int k = 0; k < N; ++k) {\n            if (k + 1 == N) {\n                widths[k] = W - used;\n            } else {\n                widths[k] = (int)((a[d][k] * W) / max((int64_t)total_area, int64_t(1)));\n                widths[k] = max(1, widths[k]);\n                used += widths[k];\n            }\n        }\n        if (used + widths[N - 1] > W) {\n            widths[N - 1] -= used + widths[N - 1] - W;\n        }\n\n        vector<int> x_l(N + 1, 0);\n        for (int k = 0; k < N; ++k)\n            x_l[k + 1] = x_l[k] + widths[k];\n\n        for (int k = 0; k < N; ++k) {\n            int y0 = 0, y1 = W;\n            int x0 = x_l[k], x1 = x_l[k + 1];\n            cout << y0 << ' ' << x0 << ' ' << y1 << ' ' << x1 << '\\n';\n        }\n    }\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 9, M = 20, K = 81;\nconstexpr int MOD = 998244353;\nusing Board = array<array<int, N>, N>;\nusing Stamp = array<array<int,3>,3>;\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n\n    // Input\n    int n, m, k;\n    cin >> n >> m >> k;\n    Board a;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> a[i][j];\n\n    vector<Stamp> stamps(M);\n    for (int t = 0; t < M; ++t)\n        for (int i = 0; i < 3; ++i)\n            for (int j = 0; j < 3; ++j)\n                cin >> stamps[t][i][j];\n\n    Board board = a;\n    // To speed up, we also store b % MOD for each cell\n    array<array<int, N>, N> board_mod;\n    for (int i=0; i<N; ++i)\n        for (int j=0; j<N; ++j)\n            board_mod[i][j] = board[i][j] % MOD;\n\n    // List of (which stamp, y, x)\n    vector<tuple<int,int,int>> ops;\n\n    // Greedy stamping for up to K times\n    for (int step = 0; step < K; ++step) {\n        int best_gain = 0;\n        int best_m = -1, best_p = -1, best_q = -1;\n\n        for (int m_id = 0; m_id < M; ++m_id) {\n            const auto& st = stamps[m_id];\n            for (int p = 0; p <= N - 3; ++p) {\n                for (int q = 0; q <= N - 3; ++q) {\n                    int gain = 0;\n                    // compute modsum gain when placing here\n                    for (int di = 0; di < 3; ++di) {\n                        for (int dj = 0; dj < 3; ++dj) {\n                            int ni = p + di, nj = q + dj;\n                            int before = board_mod[ni][nj];\n                            int after = (board[ni][nj] + st[di][dj]) % MOD;\n                            // Gain is how much modded value increases (could wrap to smaller!)\n                            // To handle wrapping, compute (after-before+MOD)%MOD\n                            int cell_gain = (after - before + MOD) % MOD;\n                            gain += cell_gain;\n                        }\n                    }\n                    if (gain > best_gain) {\n                        best_gain = gain;\n                        best_m = m_id;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n\n        if (best_gain == 0) {\n            // No beneficial stamping left\n            break;\n        }\n\n        // Apply the best operation\n        ops.emplace_back(best_m, best_p, best_q);\n        const auto& st = stamps[best_m];\n        for (int di = 0; di < 3; ++di) {\n            for (int dj = 0; dj < 3; ++dj) {\n                int ni = best_p + di, nj = best_q + dj;\n                board[ni][nj] += st[di][dj];\n                board_mod[ni][nj] = (board_mod[ni][nj] + st[di][dj]) % MOD;\n            }\n        }\n    }\n\n    // Output result\n    cout << ops.size() << '\\n';\n    for (const auto& [m,p,q] : ops) {\n        cout << m << ' ' << p << ' ' << q << '\\n';\n    }\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Constants for grid size\nconstexpr int N = 5;\nconstexpr int MAX_TURNS = 10000;\n\n// Crane state\nstruct Crane {\n    int row, col;\n    bool large;\n    bool holding = false;\n    int held_container = -1;\n    bool bomd = false;\n};\n\nstruct Cell {\n    int container = -1; // -1: none\n    int crane = -1;     // -1: none\n};\n\nvector<vector<int>> A; // The input per-row incoming container plans\n\n// Directions\nint drow[4] = {-1, 1, 0, 0};\nint dcol[4] = {0, 0, -1, 1};\nchar DIR[4] = {'U', 'D', 'L', 'R'};\n\n// For each move, check validity (no crane collision & movement rule)\ninline bool can_go(int r, int c) {\n    return r >= 0 && r < N && c >= 0 && c < N;\n}\n\nint main() {\n    ios::sync_with_stdio(0);\n    cin.tie(0);\n\n    // Input\n    A.assign(N, vector<int>(N));\n    for(int i=0;i<N;i++)\n        for(int j=0;j<N;j++) cin >> A[i][j];\n\n    // Construct per-row receiving queues\n    array<queue<int>, N> arrivals;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) arrivals[i].push(A[i][j]);\n\n    // Board state: container on cell, -1 means empty\n    array<array<int,N>,N> cont;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) cont[i][j] = -1;\n\n    // Cranes: [0] is large, [1..N-1] are small\n    vector<Crane> cranes(N);\n    for(int i=0;i<N;i++) cranes[i] = {i,0, i==0,false,-1,false};\n\n    // Place cranes on board\n    array<array<int,N>,N> who_crane;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) who_crane[i][j]=-1;\n    for(int i=0;i<N;i++) who_crane[i][0]=i;\n\n    // Dispatched per row for scoring (not needed during contest)\n    vector<vector<int>> dispatched(N);\n\n    // Plan to print\n    vector<string> action_logs(N);\n\n    // Next dispatch index per row\n    array<int, N> next_dispatch; next_dispatch.fill(0);\n\n    // For quick lookup: buffered positions\n    auto buffer_positions = [](int row) {\n        // Only (row,1..3)\n        vector<pair<int,int>> pos;\n        for(int j=1;j<=3;j++) pos.emplace_back(row,j);\n        return pos;\n    };\n\n    // Each turn\n    for(int turn=0; turn<MAX_TURNS; ++turn) {\n        // ARRIVAL: Place containers into gates when possible\n        for(int i=0;i<N;i++) {\n            if(cont[i][0]==-1 && !cranes[i].holding && !arrivals[i].empty())\n                cont[i][0]=arrivals[i].front(), arrivals[i].pop();\n        }\n\n        vector<char> acts(N,'.');\n\n        // Mark crane locations for this turn\n        array<array<int,N>,N> where_crane = who_crane;\n\n        // PHASE 1: Plan task per crane\n        for(int k=0;k<N;k++) {\n            auto& cr=cranes[k];\n            if(cr.bomd) { acts[k]='.'; continue; }\n\n            int r=cr.row, c=cr.col;\n            int dispatch_goal = N*r + next_dispatch[r]; // e.g. 0,1,... for row 0\n\n            // If already finished all dispatches in this row, and large crane, help elsewhere\n            if(next_dispatch[r]>=N && cr.large) {\n                // Find most-blocked row: which row has fewest dispatched\n                int tgt=-1, min_togo=N+1;\n                for(int i=0;i<N;i++) {\n                    int undone=N-next_dispatch[i];\n                    if(undone>0 && undone<min_togo) min_togo=undone, tgt=i;\n                }\n                if(tgt!=-1 && tgt!=r) {\n                    // Go to leftmost of that row if possible, else idle\n                    if(r < tgt) {\n                        if(who_crane[r+1][c]==-1)\n                            { acts[k]='D'; cr.row++; who_crane[r][c]=-1; who_crane[cr.row][cr.col]=k; }\n                        else acts[k]='.';\n                    } else if(r > tgt) {\n                        if(who_crane[r-1][c]==-1)\n                            { acts[k]='U'; cr.row--; who_crane[r][c]=-1; who_crane[cr.row][cr.col]=k; }\n                        else acts[k]='.';\n                    } else if(c>0) {\n                        if(who_crane[r][c-1]==-1)\n                            { acts[k]='L'; cr.col--; who_crane[r][c]=-1; who_crane[cr.row][cr.col]=k; }\n                        else acts[k]='.';\n                    } else acts[k]='.';\n                    continue;\n                }\n            }\n\n            // If holding goal container and at dispatch gate, can drop?\n            if(cr.holding && cr.held_container==dispatch_goal && c==N-1) {\n                if(cont[r][N-1]==-1) {\n                    acts[k]='Q';\n                    cont[r][c]=cr.held_container; cr.holding=false; cr.held_container=-1;\n                    next_dispatch[r]++;\n                    continue;\n                } else {\n                    acts[k]='.'; continue;\n                }\n            }\n\n            // If not holding, if goal is ready under him, pick up\n            if(!cr.holding && cont[r][c]==dispatch_goal) {\n                acts[k]='P';\n                cr.holding=true;\n                cr.held_container=cont[r][c]; cont[r][c]=-1;\n                continue;\n            }\n\n            // If holding the goal container: go toward dispatch gate\n            if(cr.holding && cr.held_container==dispatch_goal) {\n                if(c<N-1) {\n                    int cc=c+1;\n                    if(who_crane[r][cc]==-1 && (cr.large || cont[r][cc]==-1)) {\n                        acts[k]='R';\n                        cr.col++; who_crane[r][c]=-1; who_crane[cr.row][cr.col]=k;\n                    } else acts[k]='.';\n                } else acts[k]='.';\n                continue;\n            }\n\n            // If holding a non-goal container, put it in the leftmost available buffer\n            if(cr.holding) {\n                bool done=false;\n                for(int bc=1;bc<=3;bc++) {\n                    if(cont[r][bc]==-1 && who_crane[r][bc]==-1) {\n                        // Move to buffer cell\n                        if(c < bc) {\n                            if(who_crane[r][c+1]==-1 && (cr.large || cont[r][c+1]==-1)) {\n                                acts[k]='R';\n                                cr.col++; who_crane[r][c]=-1; who_crane[cr.row][cr.col]=k;\n                                done=true; break;\n                            }\n                        } else if(c > bc) {\n                            if(who_crane[r][c-1]==-1 && (cr.large || cont[r][c-1]==-1)) {\n                                acts[k]='L';\n                                cr.col--; who_crane[r][c]=-1; who_crane[cr.row][cr.col]=k;\n                                done=true; break;\n                            }\n                        } else if(cont[r][c]==-1) {\n                            acts[k]='Q';\n                            cont[r][c]=cr.held_container;\n                            cr.holding=false; cr.held_container=-1;\n                            done=true; break;\n                        }\n                    }\n                }\n                if(!done) acts[k]='.'; // No buffer available\n                continue;\n            }\n\n            // Not holding,\n            // Priority 1: goal in buffer or receiving -> go to it, pick it\n            int pos_goal=-1;\n            for(int bc=0;bc<=3;bc++)\n                if(cont[r][bc]==dispatch_goal) { pos_goal=bc; break; }\n            if(pos_goal!=-1) {\n                if(c < pos_goal) {\n                    if(who_crane[r][c+1]==-1)\n                        { acts[k]='R'; cr.col++; who_crane[r][c]=-1; who_crane[r][cr.col]=k;}\n                    else acts[k]='.';\n                } else if(c > pos_goal) {\n                    if(who_crane[r][c-1]==-1)\n                        { acts[k]='L'; cr.col--; who_crane[r][c]=-1; who_crane[r][cr.col]=k;}\n                    else acts[k]='.';\n                } else if(cont[r][c]==dispatch_goal) {\n                    acts[k]='P'; cr.holding=true; cr.held_container=cont[r][c]; cont[r][c]=-1;\n                }\n                continue;\n            }\n\n            // Priority 2: if receiving gate has a *wrong* container, go pick and buffer it (buffering aggressively)\n            if(c==0 && cont[r][0]!=-1) {\n                acts[k]='P'; cr.holding=true; cr.held_container=cont[r][0]; cont[r][0]=-1;\n                continue;\n            } else if(c!=0 && cont[r][0]!=-1) {\n                if(c < 0) {\n                    if(who_crane[r][c+1]==-1) { acts[k]='R'; cr.col++; who_crane[r][c]=-1; who_crane[r][cr.col]=k;}\n                    else acts[k]='.';\n                } else if(c > 0) {\n                    if(who_crane[r][c-1]==-1) { acts[k]='L'; cr.col--; who_crane[r][c]=-1; who_crane[r][cr.col]=k;}\n                    else acts[k]='.';\n                }\n                continue;\n            }\n\n            // Priority 3: if any buffer cell is empty, move to it, so standing on free buffer cell when goal arrives\n            if(!cr.holding) {\n                for(int bc=1;bc<=3;bc++) {\n                    if(cont[r][bc]==-1 && who_crane[r][bc]==-1) {\n                        // Move towards it (if not there already)\n                        if(c < bc) {\n                            if(who_crane[r][c+1]==-1) { acts[k]='R'; cr.col++; who_crane[r][c]=-1; who_crane[r][cr.col]=k;}\n                            else acts[k]='.';\n                        } else if(c > bc) {\n                            if(who_crane[r][c-1]==-1) { acts[k]='L'; cr.col--; who_crane[r][c]=-1; who_crane[r][cr.col]=k;}\n                            else acts[k]='.';\n                        } else { acts[k]='.'; }\n                        goto PHASE1_ENDED; // move.\n                    }\n                }\n            }\n            // Else idle\n            acts[k]='.';\n\n            PHASE1_ENDED:;\n        }\n        // Write actions\n        for(int i=0;i<N;i++) action_logs[i].push_back(acts[i]);\n\n        // PHASE 2: Dispatch from rightmost if container there\n        for(int i=0;i<N;i++) {\n            if(cont[i][N-1]!=-1) {\n                dispatched[i].push_back(cont[i][N-1]);\n                cont[i][N-1]=-1;\n            }\n        }\n        // PHASE 3: Quit if all dispatched\n        int dispatched_cnt=0; for(int i=0;i<N;i++) dispatched_cnt += dispatched[i].size();\n        if(dispatched_cnt==N*N) break;\n    }\n\n    // Output action plans (padded)\n    size_t maxlen=0; for(auto&s:action_logs) maxlen=max(maxlen,s.size());\n    for(auto&s:action_logs) {\n        if(s.size()<maxlen) s+=string(maxlen-s.size(),'.');\n        cout<<s<<'\\n';\n    }\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 20;\nconstexpr int MAX_LOAD = 1000000;\n\nusing pii = pair<int,int>;\n\nstruct Cell {\n    int y, x;\n    int amount;\n    bool operator<(const Cell& o) const { // For nearest search\n        return amount < o.amount;\n    }\n};\n\n// Pathfinding: output step sequence (U,D,L,R) between two points\nvector<char> get_path(int sy, int sx, int ty, int tx) {\n    vector<char> path;\n    while (sy < ty) { path.push_back('D'); sy++; }\n    while (sy > ty) { path.push_back('U'); sy--; }\n    while (sx < tx) { path.push_back('R'); sx++; }\n    while (sx > tx) { path.push_back('L'); sx--; }\n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int n;\n    cin >> n;\n    vector<vector<int>> h(n, vector<int>(n));\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j)\n            cin >> h[i][j];\n\n    // Collect supplies and demands, positive and negative respectively\n    vector<Cell> supplies, demands;\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j) {\n            if (h[i][j] > 0) supplies.push_back({i, j, h[i][j]});\n            else if (h[i][j] < 0) demands.push_back({i, j, -h[i][j]}); // store as positive amount\n        }\n\n    vector<string> commands;\n    int ty = 0, tx = 0; // truck position\n    int load = 0;       // truck load\n\n    vector<vector<int>> supply_grid(n, vector<int>(n, 0)), demand_grid(n, vector<int>(n, 0));\n    for (auto& s : supplies) supply_grid[s.y][s.x] = s.amount;\n    for (auto& d : demands) demand_grid[d.y][d.x] = d.amount;\n\n    auto find_nearest = [&](int cy, int cx, vector<Cell>& pool) -> tuple<int,int,int> {\n        int best_dist = 1e9, idx = -1;\n        for (int i=0; i<(int)pool.size(); ++i) {\n            if (pool[i].amount==0) continue;\n            int dist = abs(pool[i].y - cy) + abs(pool[i].x - cx);\n            if (dist < best_dist) {best_dist = dist; idx = i;}\n        }\n        if (idx==-1) return {-1, -1, -1};\n        return {idx, pool[idx].y, pool[idx].x};\n    };\n\n    // Continue until all supplies/demands done\n    while (true) {\n        // Truck EMPTY, find the nearest supply\n        if (load==0) {\n            // Remove finished supplies\n            auto closest = find_nearest(ty, tx, supplies);\n            int sidx, sy, sx;\n            tie(sidx, sy, sx) = closest;\n            if (sidx==-1) break; // Done\n\n            // Move to supply\n            auto path = get_path(ty, tx, sy, sx);\n            for (char c : path) commands.push_back(string(1,c));\n            ty = sy; tx = sx;\n\n            // Load as much as possible from here\n            int amt = min(supplies[sidx].amount, MAX_LOAD);\n            commands.push_back(\"+\"+to_string(amt));\n            load += amt;\n            supplies[sidx].amount -= amt;\n            supply_grid[sy][sx] -= amt;\n        }\n        // Truck LOADED, visit demands (multi-drop)\n        else {\n            while (load>0) {\n                // Find the nearest demand, regardless of amount\n                auto closest = find_nearest(ty, tx, demands);\n                int didx, dy, dx;\n                tie(didx, dy, dx) = closest;\n                if (didx == -1) {\n                    // No more demands, but still carrying dirt? Shouldn't happen.\n                    load = 0; break;\n                }\n                // Move to demand cell\n                auto path = get_path(ty, tx, dy, dx);\n                for (char c : path) commands.push_back(string(1,c));\n                ty = dy; tx = dx;\n\n                // Unload as much as possible here\n                int can_unload = min(load, demands[didx].amount);\n                commands.push_back(\"-\"+to_string(can_unload));\n                load -= can_unload;\n                demands[didx].amount -= can_unload;\n                demand_grid[dy][dx] -= can_unload;\n            }\n        }\n    }\n\n    // Output answer\n    for (auto& s : commands) cout<<s<<\"\\n\";\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 6;\nconstexpr int M = 15;\nconstexpr int T = 10;\nconstexpr int SEED_COUNT = 2 * N * (N - 1);\nconstexpr int GRID_SIZE = N * N;\n\n// For easier seed tracking\nstruct Seed {\n    vector<int> x;       // Features\n    int id;              // Original/new index\n    int v;               // Total value = sum(x)\n\n    Seed(int _id, const vector<int>& _x) : x(_x), id(_id) {\n        v = accumulate(x.begin(), x.end(), 0);\n    }\n};\n\nvoid flush() {\n    cout.flush();\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int n, m, t;\n    cin >> n >> m >> t;\n    assert(n == N && m == M && t == T);\n\n    vector<Seed> seeds;\n    for (int i = 0; i < SEED_COUNT; ++i) {\n        vector<int> x(m);\n        for (int j = 0; j < m; ++j) cin >> x[j];\n        seeds.emplace_back(i, x);\n    }\n\n    // For tracking max per-feature, for scoring/seeding\n    vector<int> feature_max(m, 0);\n\n    mt19937 rng(123456789); // Fixed seed for determinism, can use random_device for true random\n\n    for (int turn = 0; turn < T; ++turn) {\n        // Update feature-wise max\n        fill(feature_max.begin(), feature_max.end(), 0);\n        for (const auto& s : seeds)\n            for (int j = 0; j < m; ++j)\n                feature_max[j] = max(feature_max[j], s.x[j]);\n\n        // Scoring seeds: sum value (+ small bonus for max-per-feature attributes)\n        vector<pair<int, int>> order; // (score,seed_index)\n        vector<int> best_per_feature(m, -1); // seed id with max for each feature\n\n        for (int j = 0; j < m; ++j) {\n            for (const auto& s : seeds)\n                if (s.x[j] == feature_max[j])\n                    best_per_feature[j] = s.id;\n        }\n\n        for (int i = 0; i < (int)seeds.size(); ++i) {\n            int bonus = 0;\n            for (int j = 0; j < m; ++j)\n                if (seeds[i].x[j] == feature_max[j])\n                    bonus += 30; // Having best in a feature is good (tune this)\n            // Add randomness to break ties (and encourage diversity, mainly first few turns)\n            int rnd = uniform_int_distribution<int>(0, 5)(rng);\n            order.emplace_back(seeds[i].v + bonus + rnd, i);\n        }\n        // Take top 36\n        sort(order.rbegin(), order.rend());\n\n        vector<int> chosen_indices;\n        vector<bool> used(seeds.size(), 0);\n\n        // Always pick the current best overall sum, then try to cover all feature maxes\n        for (int i = 0; i < (int)order.size() && (int)chosen_indices.size() < GRID_SIZE; ++i) {\n            chosen_indices.push_back(order[i].second);\n            used[order[i].second] = true;\n        }\n        // Sanity: ensure all feature-max seeds are picked (can remove this for speed)\n        for (int j = 0; j < m; ++j) {\n            int id = best_per_feature[j];\n            if (id == -1) continue;\n            if (!used[id]) {\n                // replace weakest seed in chosen with this seed\n                int minidx = 0;\n                for (int z = 0; z < (int)chosen_indices.size(); ++z)\n                    if (seeds[chosen_indices[z]].v < seeds[chosen_indices[minidx]].v)\n                        minidx = z;\n                used[chosen_indices[minidx]] = false;\n                chosen_indices[minidx] = id;\n                used[id] = true;\n            }\n        }\n\n        // Assign the 36 chosen seeds to grid cells\n        // Place highest V in center and high-degree cells\n        vector<pair<int, int>> grid_cells;\n        for (int i = 0; i < n; ++i)\n            for (int j = 0; j < n; ++j)\n                grid_cells.emplace_back(i, j);\n\n        // Sort cells by number of neighbors, descending (center cells first)\n        sort(grid_cells.begin(), grid_cells.end(), [](pair<int, int> a, pair<int, int> b) {\n            int da = 0, db = 0;\n            auto [ai, aj] = a, [bi, bj] = b;\n            da += (ai > 0) + (ai < N-1) + (aj > 0) + (aj < N-1);\n            db += (bi > 0) + (bi < N-1) + (bj > 0) + (bj < N-1);\n            return da > db;\n        });\n\n        // Greedily assign highest-value seeds to high-degree cells\n        vector<vector<int>> grid(n, vector<int>(n,-1));\n        for (int i = 0; i < GRID_SIZE; ++i)\n            grid[grid_cells[i].first][grid_cells[i].second] = seeds[chosen_indices[i]].id;\n\n        // Output placement\n        for (int i = 0; i < n; ++i) {\n            for (int j = 0; j < n; ++j) {\n                cout << grid[i][j] << (j + 1 < n ? \" \" : \"\\n\");\n            }\n        }\n        flush();\n\n        // Input next set: always 60 seeds, with new feature vectors\n        vector<Seed> next_seeds;\n        for (int k = 0; k < SEED_COUNT; ++k) {\n            vector<int> x(m);\n            for (int j = 0; j < m; ++j) cin >> x[j];\n            next_seeds.emplace_back(k, x);\n        }\n        seeds = move(next_seeds);\n\n        // Optional: print debug\n        int bestV = 0;\n        for (const auto& s : seeds) bestV = max(bestV, s.v);\n        cout << \"# turn=\" << turn << \" bestV=\" << bestV << endl;\n    }\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int INF = 1 << 29;\n\nstruct Pos {\n    int x, y;\n    bool operator==(const Pos& o) const { return x == o.x && y == o.y; }\n    bool operator!=(const Pos& o) const { return !(*this == o); }\n};\n\nvector<Pos> get_leaves(int star_size, int len) {\n    // For star at (0,0) and edges all \"to right\", fingertips are at (0,+len), (0,-len), (+len,0), (-len,0), etc.\n    // We'll spread them as [up,down,left,right,diag up-right...]\n    vector<Pos> dirs = { {0,1},{1,0},{0,-1},{-1,0}, {1,1}, {-1,1}, {1,-1}, {-1,-1} };\n    vector<Pos> leaves;\n    int D = dirs.size();\n    for (int i = 0; i < star_size; i++) {\n        int d = i % D;\n        int mul = 1 + (i/D); // first ring, then doubles if more leaves\n        leaves.push_back(Pos{dirs[d].x * len * mul, dirs[d].y * len * mul});\n    }\n    return leaves;\n}\nPos add(const Pos& a, const Pos& b) { return { a.x + b.x, a.y + b.y }; }\nPos sub(const Pos& a, const Pos& b) { return { a.x - b.x, a.y - b.y }; }\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N, M, V;\n    cin >> N >> M >> V;\n    vector<string> s(N), t(N);\n    for (int i = 0; i < N; i++) cin >> s[i];\n    for (int i = 0; i < N; i++) cin >> t[i];\n\n    // Gather pickup and delivery cell lists\n    vector<Pos> pickups, delivers;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            if (s[i][j] == '1') pickups.push_back({i,j});\n            if (t[i][j] == '1') delivers.push_back({i,j});\n        }\n\n    // Build star-robot arm description\n    int V_ = min(V, 9); // For clearer mapping, \u22648 leaves+root for now; you can try V for more coverage!\n    int L = max(1, N/4); // Or tweak for average case\n    vector<pair<int,int>> parents;\n    for (int i = 1; i < V_; i++) parents.emplace_back(0, L);\n    // Output tree\n    cout << V_ << '\\n';\n    for (auto& [p,l] : parents) cout << p << \" \" << l << \"\\n\";\n\n    // Chose initial root position (upper left for now! try to cover first batch)\n    int root_x = 0, root_y = 0;\n    cout << root_x << \" \" << root_y << '\\n';\n\n    // Compute static fingertips (relative to root)\n    auto leaves = get_leaves(V_-1, L);\n\n    // State per fingertip: currently holding takoyaki?\n    vector<bool> holding(V_-1, false);\n\n    // Used picks/delivs\n    vector<bool> picked(pickups.size(), false), delivered(delivers.size(), false);\n\n    // Keep sets of yet-to-pickup and yet-to-deliver\n    int total_moves = 0;\n    int delivered_cnt = 0;\n    int T_limit = 100000;\n\n    // For visualization: grid status\n    vector<string> curr(N, string(N, '0'));\n    for (auto& pos : pickups) curr[pos.x][pos.y] = '1';\n\n    // For matching: use simple greedy nearest assignment per batch\n\n    size_t pick_idx = 0, deliv_idx = 0;\n    int phase = 0; // 0: pickup phase; 1: delivery phase\n\n    struct FingertipTask { int idx; Pos pos; }; // idx in pickups[]/delivers[]\n\n    vector<FingertipTask> pick_tasks, deliv_tasks;\n    vector<int> fin_to_pickid(V_-1, -1), fin_to_delivid(V_-1, -1);\n\n    vector<string> answers;\n\n    // We alternate: batch pick, walk arm to delivery, batch release\n    while (delivered_cnt < M && total_moves < T_limit) {\n        // 1. Assign up to (V_-1) unpicked takoyakis to fingertips\n        pick_tasks.clear();\n        for (int i = 0; i < pickups.size(); ++i) {\n            if (!picked[i]) pick_tasks.push_back({i, pickups[i]});\n            if ((int)pick_tasks.size() == V_-1) break;\n        }\n        vector<Pos> batch_pick;\n        for (auto& t : pick_tasks) batch_pick.push_back(t.pos);\n\n        if (batch_pick.empty()) break; // no more takoyaki to grab\n\n        // 2. Find a root pos so that with this arm config, all batch picks are at some fingertip\n        // For each cell, check if, after translating root there, the fingertips cover all batch_pick\n        // Brute: try them all, but prioritize upper-left region (speed: grid isn't huge)\n        Pos picked_root = {-1,-1};\n        vector<int> fin_assignment(V_-1, -1); // index into pick_tasks\n\n        for (int rx = 0; rx < N && picked_root.x == -1; rx++)\n          for (int ry = 0; ry < N && picked_root.x == -1; ry++) {\n            vector<int> assign(V_-1, -1);\n            vector<bool> used(V_-1, false);\n            // For each pick cell, try to assign it to a finger\n            bool fail = false;\n            for (int ki = 0; ki < (int)batch_pick.size(); ++ki) {\n                bool matched = false;\n                for (int f = 0; f < V_-1; f++) {\n                    Pos tip = add({rx, ry}, leaves[f]);\n                    if (tip.x == batch_pick[ki].x && tip.y == batch_pick[ki].y && !used[f]) {\n                        assign[f] = ki;\n                        used[f] = true;\n                        matched = true;\n                        break;\n                    }\n                }\n                if (!matched) { fail = true; break; }\n            }\n            if (!fail) {\n                picked_root = {rx, ry};\n                fin_assignment = assign;\n                break;\n            }\n          }\n        if (picked_root.x == -1) {\n            // Cannot fit all, reduce batch size (never happens as long as len is not huge)\n            // In practical: fallback to fewer per batch (or decrease L at design time)\n            assert((int)batch_pick.size() < V_-1); // fallback not implemented here\n            break;\n        }\n\n        // 3. Plan root move sequence to picked_root from current root\n        // Simple greedy: manhattan path by rows, then by cols\n        int dx = picked_root.x - root_x, dy = picked_root.y - root_y;\n        string mv_cmd = \"UDLR\";\n        char cmds[4] = {'D','U','R','L'}; // For negative/positive steps in (dx,dy)\n        vector<string> steps;\n        // Move vertically\n        while (root_x < picked_root.x) { steps.push_back(\"D\"); root_x++; }\n        while (root_x > picked_root.x) { steps.push_back(\"U\"); root_x--; }\n        while (root_y < picked_root.y) { steps.push_back(\"R\"); root_y++; }\n        while (root_y > picked_root.y) { steps.push_back(\"L\"); root_y--; }\n\n        // Create a string of 2V chars: [move][rot*][act*]\n        string emptyrot(V_-1, '.');\n        string emptyact(V_, '.');\n        for (auto& s : steps) {\n            string out(2*V_, '.');\n            out[0] = s[0];\n            answers.push_back(out);\n        }\n\n        // 4. At pickup location: make all fingertips pick up if at their assigned target\n        string op(2*V_, '.');\n        // No move, no rotate\n        for (int f = 0; f < V_-1; ++f) {\n            int ki = fin_assignment[f];\n            if (ki != -1) {\n                // Only if not already picked and fingertip matches\n                op[V_+f+1] = 'P'; // leaves are vertices 1..V_-1\n                picked[pick_tasks[ki].idx] = true;\n                // Remove from grid\n                curr[batch_pick[ki].x][batch_pick[ki].y] = '0';\n                holding[f] = true;\n            } else {\n                op[V_+f+1] = '.';\n            }\n        }\n        answers.push_back(op);\n        ++total_moves;\n\n        // 5. Now, batch deliver: get up to (V_-1) non-delivered targets\n        deliv_tasks.clear();\n        for (int i = 0; i < delivers.size(); ++i) {\n            if (!delivered[i]) deliv_tasks.push_back({i, delivers[i]});\n            if ((int)deliv_tasks.size() == V_-1) break;\n        }\n        vector<Pos> batch_deliv;\n        for (auto& t : deliv_tasks) batch_deliv.push_back(t.pos);\n\n        // As above, try to fit deliver batch\n        Pos deliv_root = {-1,-1};\n        vector<int> fin_d_assign(V_-1, -1);\n        for (int rx = 0; rx < N && deliv_root.x == -1; rx++)\n          for (int ry = 0; ry < N && deliv_root.x == -1; ry++) {\n            vector<int> assign(V_-1, -1);\n            vector<bool> used(V_-1, false);\n            bool fail = false;\n            for (int ki = 0; ki < (int)batch_deliv.size(); ++ki) {\n                bool matched = false;\n                for (int f = 0; f < V_-1; f++) {\n                    Pos tip = add({rx, ry}, leaves[f]);\n                    if (tip.x == batch_deliv[ki].x && tip.y == batch_deliv[ki].y && !used[f] && holding[f]) {\n                        assign[f] = ki;\n                        used[f] = true;\n                        matched = true;\n                        break;\n                    }\n                }\n                if (!matched) { fail = true; break; }\n            }\n            if (!fail) {\n                deliv_root = {rx, ry};\n                fin_d_assign = assign;\n                break;\n            }\n          }\n        assert(deliv_root.x != -1); // Should always succeed\n\n        // Move root to delivery pos\n        dx = deliv_root.x - root_x;\n        dy = deliv_root.y - root_y;\n        // Move vertically\n        while (root_x < deliv_root.x) { string out(2*V_, '.'); out[0] = 'D'; answers.push_back(out); root_x++; }\n        while (root_x > deliv_root.x) { string out(2*V_, '.'); out[0] = 'U'; answers.push_back(out); root_x--; }\n        while (root_y < deliv_root.y) { string out(2*V_, '.'); out[0] = 'R'; answers.push_back(out); root_y++; }\n        while (root_y > deliv_root.y) { string out(2*V_, '.'); out[0] = 'L'; answers.push_back(out); root_y--; }\n\n        // Release at targets\n        string op2(2*V_, '.');\n        for (int f = 0; f < V_-1; ++f) {\n            int ki = fin_d_assign[f];\n            if (ki != -1) {\n                op2[V_+f+1] = 'P';\n                delivered[deliv_tasks[ki].idx] = true;\n                delivered_cnt++;\n                holding[f] = false;\n            } else {\n                op2[V_+f+1] = '.';\n            }\n        }\n        answers.push_back(op2);\n        ++total_moves;\n    }\n    // Output the answers\n    for (auto& a : answers) cout << a << '\\n';\n\n    // Could output a period to use unused moves (valid according to rules)\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing Point = pair<int, int>;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    cin >> N;\n    vector<Point> mackerels(N), sardines(N);\n    set<Point> used;\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n        mackerels[i] = {x, y};\n        used.insert({x, y});\n    }\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n        sardines[i] = {x, y};\n        used.insert({x, y});\n    }\n\n    // Let's try to find a rectangle (xL, yL) to (xH, yH) that catches many mackerel but few sardines\n\n    // First, try baseline: bounding box of all mackerels, but limit box to not be too big\n\n    int best_score = -1;\n    int best_xL=0, best_xH=0, best_yL=0, best_yH=0;\n\n    // 1. Compute overall bounding box of mackerels.\n    int mxL = 1e9, mxH = -1, myL = 1e9, myH = -1;\n    for (auto [x, y] : mackerels) {\n        mxL = min(mxL, x);\n        mxH = max(mxH, x);\n        myL = min(myL, y);\n        myH = max(myH, y);\n    }\n    // We'll expand and contract the bounding box to see if a better area can be found\n\n    vector<int> x_sorted, y_sorted;\n    for (auto [x, y] : mackerels) x_sorted.push_back(x), y_sorted.push_back(y);\n    sort(x_sorted.begin(), x_sorted.end());\n    sort(y_sorted.begin(), y_sorted.end());\n\n    // Let's try various quantiles to define rectangle boundaries, for basic heuristics.\n    for (int xlq = 0; xlq <= 20; ++xlq) {\n        int xL = x_sorted[N*xlq/40]; // from left\n        int xH = x_sorted[N - 1 - N*xlq/40]; // from right\n        for (int ylq = 0; ylq <= 20; ++ylq) {\n            int yL = y_sorted[N*ylq/40];\n            int yH = y_sorted[N - 1 - N*ylq/40];\n            if (xH <= xL || yH <= yL) continue;\n            int perim = 2*(xH-xL) + 2*(yH-yL);\n            if (perim > 400000) continue;\n\n            int mack_in = 0, sard_in = 0;\n            for (auto [x, y] : mackerels) {\n                if (xL <= x && x <= xH && yL <= y && y <= yH) ++mack_in;\n            }\n            for (auto [x, y] : sardines) {\n                if (xL <= x && x <= xH && yL <= y && y <= yH) ++sard_in;\n            }\n            int score = max(0, mack_in - sard_in + 1);\n            if (score > best_score || (score == best_score && perim < 2*(best_xH-best_xL+best_yH-best_yL))) {\n                best_score = score;\n                best_xL = xL;\n                best_xH = xH;\n                best_yL = yL;\n                best_yH = yH;\n            }\n        }\n    }\n\n    // Output 4-vertex rectangle\n    cout << 4 << '\\n';\n    cout << best_xL << ' ' << best_yL << '\\n';\n    cout << best_xL << ' ' << best_yH << '\\n';\n    cout << best_xH << ' ' << best_yH << '\\n';\n    cout << best_xH << ' ' << best_yL << '\\n';\n\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Timer {\n    chrono::steady_clock::time_point st;\n    Timer() : st(chrono::steady_clock::now()) {}\n    double elapsed() const { return chrono::duration<double>(chrono::steady_clock::now()-st).count(); }\n};\n\nstruct Rect {\n    int idx;\n    int w, h;\n};\n\nstruct PlacedRect {\n    int idx, x, y, w, h;\n};\n\nstruct Placement {\n    int p, r;     // rect index, rotation\n    char d;       // direction 'U'/'L'\n    int b;        // base: -1 or one of 0..(p-1)\n    Placement(int p, int r, char d, int b) : p(p), r(r), d(d), b(b) {}\n};\n\nbool overlap(const PlacedRect& a, const PlacedRect& b) {\n    return !(a.x + a.w <= b.x || b.x + b.w <= a.x ||\n             a.y + a.h <= b.y || b.y + b.h <= a.y);\n}\n\nint rect_right(const PlacedRect& r) { return r.x + r.w; }\nint rect_bottom(const PlacedRect& r) { return r.y + r.h; }\n\n// Place rectangle i (w,h) in direction d wrt base b, with already-placed rectangles \"placed\", return (x,y)\ntuple<int, int, bool> compute_placement(const vector<PlacedRect>& placed, int iidx, int w, int h, char d, int bidx) {\n    int x=0, y=0;\n    if (d == 'U') {\n        // Move up: align left with base's right edge or with x=0\n        x = (bidx == -1) ? 0 : placed[bidx].x;\n        // What is the largest y such that (x..x+w) touches an underside of a previous (or y=0)?\n        int max_y = 0;\n        for (const auto& r : placed) {\n            if (bidx!=-1 && r.idx==placed[bidx].idx) continue; // Skip base rect\n            // Do x/w overlap horizontally?\n            int overlap_left = max(x, r.x);\n            int overlap_right = min(x + w, r.x + r.w);\n            if (overlap_left < overlap_right) {\n                max_y = max(max_y, r.y + r.h);\n            }\n        }\n        y = max_y;\n    } else { // 'L'\n        // Move left: align top with base's bottom edge or with y=0\n        y = (bidx == -1) ? 0 : placed[bidx].y;\n        int max_x = 0;\n        for (const auto& r : placed) {\n            if (bidx!=-1 && r.idx==placed[bidx].idx) continue;\n            int overlap_top = max(y, r.y);\n            int overlap_bot = min(y + h, r.y + r.h);\n            if (overlap_top < overlap_bot) {\n                max_x = max(max_x, r.x + r.w);\n            }\n        }\n        x = max_x;\n    }\n    if (x < 0 || y < 0) return make_tuple(0, 0, false);\n    return make_tuple(x, y, true);\n}\n\npair<vector<Placement>, int> best_bottom_left_order(const vector<Rect>& rects, const vector<int>& mask) {\n    int n = mask.size();\n    vector<Placement> res;\n    vector<PlacedRect> placed;\n    int box_w = 0, box_h = 0;\n\n    for (int iidx = 0; iidx < n; ++iidx) {\n        int i = mask[iidx];\n\n        // For all rotations:\n        int best_r = 0, best_b = -1;\n        char best_d = 'U';\n        int best_x = -1, best_y = -1;\n        int min_score = INT_MAX, min_yx = INT_MAX, min_xy = INT_MAX;\n        vector<tuple<int,int,int,int,char,int>> candidates;\n\n        for (int r = 0; r < 2; ++r) {\n            int wi = (r == 0 ? rects[i].w : rects[i].h);\n            int hi = (r == 0 ? rects[i].h : rects[i].w);\n\n            for (char d : {'U', 'L'}) {\n                // Try all previous rectangles (including -1 as origin)\n                for (int bidx = -1; bidx < (int)placed.size(); ++bidx) {\n                    int px, py;\n                    bool valid;\n                    tie(px, py, valid) = compute_placement(placed, iidx, wi, hi, d, bidx);\n                    if (!valid) continue;\n                    PlacedRect test = {i, px, py, wi, hi};\n                    // Check for overlap\n                    bool ok = true;\n                    for (const auto& pr : placed) {\n                        if (overlap(pr, test)) {ok = false; break;}\n                    }\n                    if (!ok) continue;\n                    // Compute new bounding box\n                    int max_x = px + wi, max_y = py + hi;\n                    for (const auto& pr : placed) {\n                        max_x = max(max_x, pr.x + pr.w);\n                        max_y = max(max_y, pr.y + pr.h);\n                    }\n                    int score = max_x + max_y;\n                    candidates.emplace_back(score, py, px, r, d, bidx);\n                }\n            }\n        }\n        if (!candidates.empty()) {\n            // Sort by score (perimeter) then lowest y/x (\"bottom-left\" heuristic)\n            sort(candidates.begin(), candidates.end());\n            int _, sel_y, sel_x, sel_r, sel_d, sel_b;\n            tie(ignore, sel_y, sel_x, sel_r, sel_d, sel_b) = candidates[0];\n            best_r = sel_r; best_d = (char)sel_d; best_b = sel_b;\n            best_x = sel_x; best_y = sel_y;\n        } else {\n            // fallback: place far right\n            best_r = 0;\n            best_d = 'U';\n            best_b = -1;\n            best_x = box_w;\n            best_y = 0;\n        }\n        res.emplace_back(rects[i].idx, best_r, best_d, (best_b == -1 ? -1 : placed[best_b].idx));\n        int wi = (best_r == 0 ? rects[i].w : rects[i].h);\n        int hi = (best_r == 0 ? rects[i].h : rects[i].w);\n        placed.push_back({rects[i].idx, best_x, best_y, wi, hi});\n        box_w = max(box_w, best_x + wi);\n        box_h = max(box_h, best_y + hi);\n    }\n    int perimeter = box_w + box_h;\n    return {res, perimeter};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\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        int w, h;\n        cin >> w >> h;\n        rects[i] = {i, w, h};\n    }\n\n    Timer timer;\n    int turns_to_try = min(T, 5);\n\n    vector<int> all_indices(N);\n    iota(all_indices.begin(), all_indices.end(), 0);\n\n    vector<vector<int>> test_masks;\n    test_masks.push_back(all_indices);\n    if (N >= 2) {\n        vector<int> v = all_indices;\n        v.pop_back();\n        test_masks.push_back(v);\n    }\n    if (N >= 2) {\n        int bigi = 0, bigv = rects[0].w + rects[0].h;\n        for (int i = 1; i < N; ++i) {\n            if (rects[i].w + rects[i].h > bigv) {\n                bigi = i; bigv = rects[i].w + rects[i].h;\n            }\n        }\n        vector<int> v;\n        for (int i = 0; i < N; ++i) if (i != bigi) v.push_back(i);\n        test_masks.push_back(v);\n    }\n    if (N >= 2) {\n        int besti = -1;\n        int best_delta = 0;\n        int basep;\n        tie(ignore, basep) = best_bottom_left_order(rects, all_indices);\n        for (int i = 0; i < N; ++i) {\n            vector<int> mask;\n            for (int j = 0; j < N; ++j) if (j != i) mask.push_back(j);\n            int peri;\n            tie(ignore, peri) = best_bottom_left_order(rects, mask);\n            int delta = basep - peri - (rects[i].w + rects[i].h); // net gain\n            if (delta > best_delta) {\n                besti = i;\n                best_delta = delta;\n            }\n        }\n        if (besti != -1) {\n            vector<int> v;\n            for (int i = 0; i < N; ++i) if (i != besti) v.push_back(i);\n            test_masks.push_back(v);\n        }\n    }\n    if (N >= 2) {\n        int skip = ((rects[0].w*31+rects[N-1].h*7) % N);\n        vector<int> v;\n        for (int i = 0; i < N; ++i) if (i != skip) v.push_back(i);\n        test_masks.push_back(v);\n    }\n    while ((int)test_masks.size() < turns_to_try) test_masks.push_back(all_indices);\n\n    for (int t = 0; t < T; ++t) {\n        int tidx = t % (int)test_masks.size();\n        vector<int>& mask = test_masks[tidx];\n        auto [plan, estimated_score] = best_bottom_left_order(rects, mask);\n\n        cout << plan.size() << '\\n';\n        for (auto &pl : plan) {\n            cout << pl.p << ' ' << pl.r << ' ' << pl.d << ' ' << pl.b << '\\n';\n        }\n        cout << flush;\n\n        int W_meas, H_meas;\n        cin >> W_meas >> H_meas;\n    }\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Constants\nconstexpr int INF = 1e9+5;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, H;\n    cin >> N >> M >> H;\n    vector<int> A(N);\n    for (auto &x : A) cin >> x;\n\n    vector<vector<int>> adj(N);\n    for (int i=0;i<M;++i) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    vector<pair<int, int>> coords(N);\n    for (int i=0;i<N;++i) {\n        int x, y; cin >> x >> y;\n        coords[i] = {x, y};\n    }\n\n    // Output structures\n    vector<int> parent(N, -1);\n    vector<int> depth(N, -1);\n    vector<bool> assigned(N, false);\n\n    // Prepare node order: high-beauty first\n    vector<int> node_order(N);\n    iota(node_order.begin(), node_order.end(), 0);\n    sort(node_order.begin(), node_order.end(),\n        [&](int i, int j){\n            return A[i] > A[j];\n        });\n\n    int assigned_cnt = 0;\n    for (int ni = 0; ni < N; ++ni) {\n        int v = node_order[ni];\n        if (assigned[v]) continue;\n\n        // Start a new tree rooted at v\n        parent[v] = -1;\n        depth[v] = 0;\n        assigned[v] = true;\n        assigned_cnt++;\n\n        // BFS up to depth H\n        queue<pair<int, int>> q; // (node, depth)\n        q.push({v, 0});\n        while (!q.empty()) {\n            auto [cur, d] = q.front(); q.pop();\n            if (d == H) continue;\n\n            // Get unassigned neighbors, sort by A[.]\n            vector<pair<int, int>> nbrs;\n            for (int to : adj[cur]) {\n                if (!assigned[to]) {\n                    nbrs.emplace_back(-A[to], to);\n                }\n            }\n            sort(nbrs.begin(), nbrs.end()); // high-A comes first\n\n            for (auto& [neg_val, nb] : nbrs) {\n                if (assigned[nb]) continue;\n                parent[nb] = cur;\n                depth[nb] = d+1;\n                assigned[nb] = true;\n                assigned_cnt++;\n                q.push({nb, d+1});\n            }\n        }\n    }\n\n    // Output final parent array\n    for (int i=0; i<N; ++i) {\n        cout << parent[i] << (i+1==N ? '\\n' : ' ');\n    }\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\n// For each Oni, find a safe direction in the initial board and output shift sequence\n// Don't update the board as Oni are \"removed\" -- just as per the guarantee\n\nstruct Move {\n    char dir;\n    int idx;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N;\n    cin >> N;\n    vector<string> board(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> board[i];\n    }\n\n    // Save Oni positions at start\n    vector<pair<int,int>> onis;\n    for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j)\n        if (board[i][j] == 'x') onis.emplace_back(i,j);\n\n    vector<Move> moves;\n\n    // For safety, mark direction per Oni before generating commands\n    // Board is NOT mutated!\n    for (auto [i, j] : onis) {\n        // Try all 4 directions in the initial board\n        // Up (remove by shifting col up i+1 times)\n        bool upSafe = true;\n        for (int k = 0; k < i; ++k) if (board[k][j] == 'o') { upSafe = false; break; }\n\n        // Down\n        bool downSafe = true;\n        for (int k = i+1; k < N; ++k) if (board[k][j] == 'o') { downSafe = false; break; }\n\n        // Left\n        bool leftSafe = true;\n        for (int k = 0; k < j; ++k) if (board[i][k] == 'o') { leftSafe = false; break; }\n\n        // Right\n        bool rightSafe = true;\n        for (int k = j+1; k < N; ++k) if (board[i][k] == 'o') { rightSafe = false; break; }\n\n        // Remove Oni at (i,j) by safe direction and undo\n        if (upSafe) {\n            // Shift col j up i+1 times, then down i times\n            for (int t = 0; t < i+1; ++t)\n                moves.push_back({'U', j});\n            for (int t = 0; t < i; ++t)\n                moves.push_back({'D', j});\n            continue;\n        }\n        if (downSafe) {\n            // Shift col j down N-i times, then up N-i-1 times\n            for (int t = 0; t < N-i; ++t)\n                moves.push_back({'D', j});\n            for (int t = 0; t < N-i-1; ++t)\n                moves.push_back({'U', j});\n            continue;\n        }\n        if (leftSafe) {\n            // Shift row i left j+1 times, then right j times\n            for (int t = 0; t < j+1; ++t)\n                moves.push_back({'L', i});\n            for (int t = 0; t < j; ++t)\n                moves.push_back({'R', i});\n            continue;\n        }\n        if (rightSafe) {\n            // Shift row i right N-j times, then left N-j-1 times\n            for (int t = 0; t < N-j; ++t)\n                moves.push_back({'R', i});\n            for (int t = 0; t < N-j-1; ++t)\n                moves.push_back({'L', i});\n            continue;\n        }\n        // If this point is reached, the guarantee is violated (shouldn't happen)\n        cerr << \"No safe direction for Oni at (\" << i << \",\" << j << \") in initial board\\n\";\n        assert(false);\n    }\n\n    for (auto &mv : moves) {\n        cout << mv.dir << ' ' << mv.idx << '\\n';\n    }\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\n// Constants\nconstexpr int N = 100;\nconstexpr int L = 500000;\n\nint T[N];\nint a[N], b[N];\n\n// Estimate frequencies by fast simulation, possibly multiple starts to break short cycles\nvector<double> estimate_freq(const int a[N], const int b[N], int steps = 100000) {\n    vector<double> freq(N, 0.0);\n    int repeat = 3;\n    for(int starter = 0; starter < repeat; ++starter) {\n        vector<int> count(N, 0);\n        int cur = starter % N;\n        vector<int> visited(N, 0);\n        count[cur]++;\n        visited[cur]=1;\n        for(int step = 1; step < steps; ++step) {\n            int occ = count[cur];\n            int nxt = (occ % 2 == 1) ? a[cur] : b[cur];\n            cur = nxt;\n            count[cur]++;\n            visited[cur]=1;\n        }\n        // Ignore nodes never visited in this segment\n        int sm = 0;\n        for(int i=0; i<N; ++i) sm += count[i];\n        for(int i=0; i<N; ++i) freq[i] += double(count[i])/repeat;\n    }\n    // Normalize for steps\n    double tot = accumulate(freq.begin(), freq.end(), 0.0);\n    for(int i=0; i<N; ++i) freq[i] /= tot;\n    return freq;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    int n, l;\n    cin >> n >> l;\n    for(int i=0; i<N; ++i) cin >> T[i];\n\n    // STEP 1: Initial assignment, degree-proportional assignment\n    // Calculate quotas\n    vector<pair<double,int>> q;\n    for(int i=0; i<N; ++i) \n        q.emplace_back((double)T[i]/L,i);\n    sort(q.rbegin(),q.rend());\n\n    // Distribute incoming edges roughly according to quota\n    vector<int> indeg(N,0);\n    for(int i=0; i<N; ++i) {\n        set<int> pickset;\n        while(pickset.size() < 2) {\n            // Weighted selection\n            int idx = 0;\n            double sel = double(rand())/RAND_MAX;\n            double s = 0;\n            for(auto& [p,j]: q) {\n                s += p;\n                if(sel<=s && j!=i) { idx=j; break;}\n            }\n            if(idx==i || pickset.count(idx)) continue;\n            pickset.insert(idx);\n        }\n        auto it = pickset.begin();\n        a[i]=*it++;\n        b[i]=*it;\n        indeg[a[i]]++; indeg[b[i]]++;\n    }\n    \n    // Minor fix to remove self-loops\n    for(int i=0; i<N; ++i) {\n        if(a[i]==i || b[i]==i) {\n            int other = a[i]==i ? b[i] : a[i];\n            for(int j=0;j<N;++j) {\n                if(j!=i && a[j]!=i && b[j]!=i && a[j]!=b[j]) {\n                    if(a[i]==i) a[i]=j; else b[i]=j;\n                    break;\n                }\n            }\n        }\n    }\n\n    // Main tuning\n    auto start_time = chrono::steady_clock::now();\n    const double TIME_LIMIT = 1.8;\n\n    // Prepare fast random engine\n    mt19937 rng(123456);\n\n    // Run iterative rebalancing and local search\n    int loopct = 0;\n    double best_error = 1e18;\n    int best_a[N], best_b[N];\n    memcpy(best_a,a,sizeof(a));\n    memcpy(best_b,b,sizeof(b));\n    vector<double> best_freq;\n    while(true) {\n        ++loopct;\n        // Estimate freq\n        auto freq = estimate_freq(a,b,350000);\n        // Compute actual t_i\n        double score = 0;\n        for(int i=0;i<N;++i) score += abs(freq[i]*L-T[i]);\n        if(score < best_error) {\n            best_error = score;\n            memcpy(best_a,a,sizeof(a));\n            memcpy(best_b,b,sizeof(b));\n            best_freq = freq;\n        }\n        // Check time\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if(elapsed > TIME_LIMIT) break;\n\n        // Find most over/under assigned\n        int over=-1, under=-1;\n        double max_over=0, max_under=0;\n        for(int i=0;i<N;++i) {\n            double diff = freq[i]*L - T[i];\n            if(diff > max_over) { max_over = diff; over = i; }\n            if(diff < max_under) { max_under = diff; under = i; }\n        }\n        if(over == -1 || under == -1) break; // (Actually perfect)\n\n        // Try to reroute some edges from over to under\n        bool changed = false;\n        // Try changing some a_j or b_j that point to 'over'\n        vector<int> candidates;\n        for(int j=0;j<N;++j) if(a[j]==over || b[j]==over) candidates.push_back(j);\n        shuffle(candidates.begin(),candidates.end(),rng);\n        for(int cand: candidates) {\n            if(a[cand]==over && under!=cand) {\n                int old=a[cand]; a[cand]=under;\n                auto f2=estimate_freq(a,b,50000);\n                double s2 = 0;\n                for(int i=0;i<N;++i) s2 += abs(f2[i]*L-T[i]);\n                if(s2 < score) { changed=true; break;}\n                a[cand]=old;\n            }\n            if(b[cand]==over && under!=cand) {\n                int old=b[cand]; b[cand]=under;\n                auto f2=estimate_freq(a,b,50000);\n                double s2 = 0;\n                for(int i=0;i<N;++i) s2 += abs(f2[i]*L-T[i]);\n                if(s2 < score) { changed=true; break;}\n                b[cand]=old;\n            }\n        }\n        if(!changed) {\n            // As fallback, random swap for diversity\n            int i = rng()%N;\n            int pos = rng()%2;\n            int nv = rng()%N;\n            if(nv==i) continue;\n            if(pos==0) a[i]=nv; else b[i]=nv;\n        }\n    }\n    // Output\n    for(int i=0; i<N; ++i) \n        cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct City {\n    int id;\n    int lx, rx, ly, ry;\n    double cx, cy;\n};\n\nstruct UF {\n    vector<int> par;\n    UF(int n) : par(n) { iota(par.begin(), par.end(), 0); }\n    int find(int x) {\n        if (par[x] == x) return x;\n        return par[x] = find(par[x]);\n    }\n    bool unite(int x, int y) {\n        int rx = find(x), ry = find(y);\n        if (rx == ry) return false;\n        par[ry] = rx; return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, Q, L, W;\n    cin >> N >> M >> Q >> L >> W;\n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n\n    vector<City> cities(N);\n    for (int i = 0; i < N; ++i) {\n        int lx, rx, ly, ry;\n        cin >> lx >> rx >> ly >> ry;\n        cities[i] = {i, lx, rx, ly, ry, 0.5 * (lx + rx), 0.5 * (ly + ry)};\n    }\n\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int i, int j) {\n        if (abs(cities[i].cx - cities[j].cx) > 1e-6)\n            return cities[i].cx < cities[j].cx;\n        return cities[i].cy < cities[j].cy;\n    });\n\n    vector<vector<int>> groups;\n    int ofs = 0;\n    for (int i = 0; i < M; ++i) {\n        vector<int> grp;\n        for (int k = 0; k < G[i]; ++k, ++ofs)\n            grp.push_back(idx[ofs]);\n        groups.push_back(grp);\n    }\n\n    vector<vector<pair<int, int>>> all_edges(M);\n\n    int queries_used = 0;\n    for (int gi = 0; gi < M; ++gi) {\n        const auto& grp = groups[gi];\n        int sz = grp.size();\n        set<pair<int, int>> group_edges;\n\n        if (sz == 1) {\n            // No edge required for single-node group.\n        } else if (sz <= L && queries_used < Q) {\n            cout << \"? \" << sz;\n            for (int x : grp) cout << \" \" << x;\n            cout << endl; cout.flush();\n            for (int i = 0; i < sz - 1; ++i) {\n                int u, v;\n                cin >> u >> v;\n                if (u > v) swap(u, v);\n                group_edges.emplace(u, v);\n            }\n            ++queries_used;\n        } else {\n            for (int st = 0; st < sz && queries_used < Q; st += (L - 1)) {\n                int en = min(sz, st + L);\n                int actual = en - st;\n                if (actual < 2) continue;\n                vector<int> subset(grp.begin() + st, grp.begin() + en);\n                unordered_set<int> subset_set(subset.begin(), subset.end());\n                cout << \"? \" << actual;\n                for (int x : subset) cout << \" \" << x;\n                cout << endl; cout.flush();\n                for (int i = 0; i < actual - 1; ++i) {\n                    int u, v;\n                    cin >> u >> v;\n                    if (u > v) swap(u, v);\n                    // Defensive: only add if both endpoints belong to the group\n                    if (subset_set.count(u) && subset_set.count(v)) {\n                        group_edges.emplace(u, v);\n                    }\n                }\n                ++queries_used;\n            }\n        }\n\n        // Defensive group index mapping\n        int V = sz;\n        map<int, int> city_to_groupidx;\n        for (int i = 0; i < sz; ++i)\n            city_to_groupidx[grp[i]] = i;\n\n        UF uf(V);\n        for (auto [u, v] : group_edges) {\n            auto it_u = city_to_groupidx.find(u);\n            auto it_v = city_to_groupidx.find(v);\n            if (it_u != city_to_groupidx.end() && it_v != city_to_groupidx.end()) {\n                uf.unite(it_u->second, it_v->second);\n            }\n        }\n        vector<tuple<int, int, int>> center_edges;\n        for (int i = 0; i < sz; ++i) {\n            for (int j = i + 1; j < sz; ++j) {\n                int u = grp[i], v = grp[j];\n                double dx = cities[u].cx - cities[v].cx, dy = cities[u].cy - cities[v].cy;\n                int d = (int)floor(hypot(dx, dy));\n                center_edges.emplace_back(d, i, j);\n            }\n        }\n        sort(center_edges.begin(), center_edges.end());\n        UF final_uf(V);\n        set<pair<int, int>> final_edges = group_edges;\n        for (auto [u, v] : group_edges) {\n            auto it_u = city_to_groupidx.find(u);\n            auto it_v = city_to_groupidx.find(v);\n            if (it_u != city_to_groupidx.end() && it_v != city_to_groupidx.end())\n                final_uf.unite(it_u->second, it_v->second);\n        }\n        for (auto [d, i, j] : center_edges) {\n            if ((int)final_edges.size() >= sz - 1) break;\n            if (final_uf.unite(i, j)) {\n                int u = grp[i], v = grp[j];\n                if (u > v) swap(u, v);\n                final_edges.emplace(u, v);\n            }\n        }\n        all_edges[gi].assign(final_edges.begin(), final_edges.end());\n    }\n\n    cout << \"!\" << endl;\n    for (int gi = 0; gi < M; ++gi) {\n        const auto &grp = groups[gi];\n        for (int i = 0; i < (int)grp.size(); ++i) {\n            if (i) cout << \" \";\n            cout << grp[i];\n        }\n        cout << endl;\n        for (auto [u, v] : all_edges[gi])\n            cout << u << \" \" << v << endl;\n    }\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Constants\nconstexpr int N = 20, M = 40;\nconstexpr int MAX_ACTIONS = 2 * N * M;\n\n// Directions and helpers\nconstexpr int DIRS = 4;\nconst int dx[DIRS] = {-1, 1, 0, 0}; // U, D, L, R\nconst int dy[DIRS] = {0, 0, -1, 1};\nconst char dirC[DIRS] = {'U', 'D', 'L', 'R'};\n\nstruct Pos {\n    int x, y;\n    bool operator==(const Pos& r) const { return x == r.x && y == r.y; }\n};\n\n// Try to slide from p in dir, return last cell we would land on (or -1 if blocked right away)\nPos slide_end(const Pos& p, int d, const vector<vector<bool>>& block) {\n    int nx = p.x, ny = p.y;\n    while (1) {\n        int tx = nx + dx[d], ty = ny + dy[d];\n        if (tx < 0 || tx >= N || ty < 0 || ty >= N) break;\n        if (block[tx][ty]) break;\n        nx = tx; ny = ty;\n    }\n    return {nx, ny};\n}\n\n// Return true if we can clear path between p1 and p2 (line, no block)\n// Assumes p1 and p2 are in the same row or column.\nbool clear_path_between(const Pos& p1, const Pos& p2, const vector<vector<bool>>& block) {\n    if (p1.x == p2.x) {\n        int sy = min(p1.y, p2.y), ey = max(p1.y, p2.y);\n        for (int y = sy + 1; y <= ey - 1; ++y)\n            if (block[p1.x][y])\n                return false;\n        return true;\n    }\n    if (p1.y == p2.y) {\n        int sx = min(p1.x, p2.x), ex = max(p1.x, p2.x);\n        for (int x = sx + 1; x <= ex - 1; ++x)\n            if (block[x][p1.y])\n                return false;\n        return true;\n    }\n    return false;\n}\n\n// Returns a Move sequence to get from src to tgt with Moves (BFS shortest path).\nvector<pair<char, char>> naive_moves(Pos src, Pos tgt, const vector<vector<bool>>& block) {\n    vector<vector<Pos>> prev(N, vector<Pos>(N, {-1, -1}));\n    queue<Pos> que;\n    que.push(src);\n    prev[src.x][src.y] = src;\n    while (!que.empty()) {\n        auto c = que.front(); que.pop();\n        if (c == tgt) break;\n        for (int d = 0; d < DIRS; ++d) {\n            int nx = c.x + dx[d], ny = c.y + dy[d];\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n            if (block[nx][ny]) continue;\n            if (prev[nx][ny].x != -1) continue;\n            prev[nx][ny] = c;\n            que.push({nx, ny});\n        }\n    }\n    // Reconstruct path\n    vector<Pos> path;\n    if (prev[tgt.x][tgt.y].x == -1) return {}; // unreachable\n    for (Pos p = tgt; !(p == src); p = prev[p.x][p.y])\n        path.push_back(p);\n    reverse(path.begin(), path.end());\n    // Convert to action sequence\n    vector<pair<char, char>> res;\n    Pos c = src;\n    for (auto& p : path) {\n        int d = -1;\n        for (int i = 0; i < 4; ++i)\n            if (c.x + dx[i] == p.x && c.y + dy[i] == p.y)\n                d = i;\n        res.emplace_back('M', dirC[d]);\n        c = p;\n    }\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Input\n    int n, m;\n    cin >> n >> m;\n    vector<Pos> targets(m);\n    for (int i = 0; i < m; ++i)\n        cin >> targets[i].x >> targets[i].y;\n\n    vector<vector<bool>> block(N, vector<bool>(N, false));\n    vector<pair<char, char>> actions;\n\n    Pos cur = targets[0];\n\n    for (int i = 1; i < m; ++i) {\n        Pos next = targets[i];\n\n        // If in line (row/col), try to slide\n        bool did = false;\n        for (int d = 0; d < 4; ++d) {\n            int tx = cur.x, ty = cur.y;\n            if ((d == 0 && next.x >= tx && next.y == ty) ||\n                (d == 1 && next.x <= tx && next.y == ty) ||\n                (d == 2 && next.y >= ty && next.x == tx) ||\n                (d == 3 && next.y <= ty && next.x == tx))\n                continue; // wrong direction\n\n            // For our actual d\n            if ((d == 0 || d == 1) && cur.y == next.y && cur.x != next.x) {\n                // same col, check direction\n                int sd = (next.x > cur.x) ? 1 : 0;\n                if (sd != d) continue;\n                if (clear_path_between(cur, next, block)) {\n                    // Would we overshoot sliding in this dir?\n                    Pos landing = slide_end(cur, d, block);\n                    if (landing == next) {\n                        actions.emplace_back('S', dirC[d]);\n                        cur = next;\n                        did = true;\n                        break;\n                    } else if ((d == 0 && next.x > 0 && !block[next.x-1][next.y]) ||\n                               (d == 1 && next.x < N-1 && !block[next.x+1][next.y])) {\n                        // Place a block after the target, so slide will stop on it\n                        int bx = (d == 0) ? next.x-1 : next.x+1;\n                        int by = next.y;\n                        actions.emplace_back('A', dirC[d]);\n                        block[bx][by] = true;\n                        actions.emplace_back('S', dirC[d]);\n                        cur = next;\n                        // Remove the block after\n                        actions.emplace_back('A', dirC[d]);\n                        block[bx][by] = false;\n                        did = true;\n                        break;\n                    }\n                }\n            }\n            else if ((d == 2 || d == 3) && cur.x == next.x && cur.y != next.y) {\n                int sd = (next.y > cur.y) ? 3 : 2;\n                if (sd != d) continue;\n                if (clear_path_between(cur, next, block)) {\n                    Pos landing = slide_end(cur, d, block);\n                    if (landing == next) {\n                        actions.emplace_back('S', dirC[d]);\n                        cur = next;\n                        did = true;\n                        break;\n                    } else if ((d == 2 && next.y > 0 && !block[next.x][next.y-1]) ||\n                               (d == 3 && next.y < N-1 && !block[next.x][next.y+1])) {\n                        int bx = next.x;\n                        int by = (d == 2) ? next.y-1 : next.y+1;\n                        actions.emplace_back('A', dirC[d]);\n                        block[bx][by] = true;\n                        actions.emplace_back('S', dirC[d]);\n                        cur = next;\n                        actions.emplace_back('A', dirC[d]);\n                        block[bx][by] = false;\n                        did = true;\n                        break;\n                    }\n                }\n            }\n        }\n        if (did) continue;\n\n        // Default: just move\n        vector<pair<char, char>> path = naive_moves(cur, next, block);\n        for (auto& act : path) actions.push_back(act);\n        cur = next;\n    }\n\n    // Output actions\n    for (auto& ac : actions)\n        cout << ac.first << ' ' << ac.second << '\\n';\n}"},"8":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing i64 = int64_t;\n\nstruct Rect {\n    int x1, y1, x2, y2; // [x1,x2), [y1,y2)\n    i64 area() const { return i64(x2-x1) * i64(y2-y1); }\n    bool contains(double x, double y) const {\n        return x > x1 && x < x2 && y > y1 && y < y2;\n    }\n    bool overlap(const Rect& o) const {\n        return !(x2 <= o.x1 || x1 >= o.x2 || y2 <= o.y1 || y1 >= o.y2);\n    }\n};\n\n// For greedy expansion, keep indices\nstruct PlacedRect {\n    int idx;\n    Rect r;\n};\n\nstruct Company {\n    int id, x, y;\n    i64 r;\n    Rect rect;\n};\n\nconstexpr int GRID_SIZE = 10000;\n\nint n;\nvector<Company> companies;\nvector<PlacedRect> placedRects;\n\nbool checkOverlap(const Rect& r, int skip=-1) {\n    for (const auto& o : placedRects)\n        if (o.idx != skip && r.overlap(o.r)) return true;\n    return false;\n}\n\nRect try_place(int cx, int cy, i64 ri) {\n    int best_w = 0, best_h = 0, best_shift_x = 0, best_shift_y = 0;\n    double best_score = 1e18;\n    // Try more shapes (ratio from square to fat)\n    for (int ratio = -10; ratio <= 10; ++ratio) {\n        int w = max(1, int(std::sqrt(double(ri)) + ratio));\n        int h = max(1, int((ri + w-1)/w));\n        if (i64(w)*h < ri) continue;\n        for (int dx = -1; dx <= 1; ++dx) for (int dy = -1; dy <= 1; ++dy) {\n            int x1 = std::clamp(cx - w/2 + dx, 0, GRID_SIZE-w);\n            int y1 = std::clamp(cy - h/2 + dy, 0, GRID_SIZE-h);\n            int x2 = x1+w, y2 = y1+h;\n            if (!(x1 < x2 && y1 < y2)) continue;\n            Rect r{x1, y1, x2, y2};\n            double xx = cx+0.5, yy = cy+0.5;\n            if (xx <= x1 || xx >= x2 || yy <= y1 || yy >= y2) continue;\n            if (checkOverlap(r)) continue;\n            double score = abs(double(r.area() - ri)) + 0.1*(w-h)*(w-h);\n            if (score < best_score) {\n                best_score = score; best_w=w; best_h=h; best_shift_x=x1; best_shift_y=y1;\n            }\n        }\n    }\n    if (best_score < 1e17) {\n        return Rect{best_shift_x, best_shift_y, best_shift_x+best_w, best_shift_y+best_h};\n    }\n    return Rect{-1,-1,-1,-1};\n}\n\nRect emergency_fallback(int px, int py) {\n    vector<pair<int,int>> deltas = {\n        {0,0},{-1,0},{1,0},{0,-1},{0,1},\n        {-1,-1},{-1,1},{1,-1},{1,1},{-2,0},{2,0},{0,-2},{0,2}\n    };\n    for (auto [dx,dy] : deltas) {\n        int x = px + dx, y = py + dy;\n        if (x < 0 || x >= GRID_SIZE) continue;\n        if (y < 0 || y >= GRID_SIZE) continue;\n        Rect r{x, y, x+1, y+1};\n        if (!checkOverlap(r)) return r;\n    }\n    for (int dist = 1; dist <= 20; ++dist) {\n        for (int dx = -dist; dx <= dist; ++dx) {\n            for (int dy = -dist; dy <= dist; ++dy) {\n                if (abs(dx) != dist && abs(dy) != dist) continue;\n                int x = px + dx, y = py + dy;\n                if (x < 0 || x >= GRID_SIZE) continue;\n                if (y < 0 || y >= GRID_SIZE) continue;\n                Rect r{x, y, x+1, y+1};\n                if (!checkOverlap(r)) return r;\n            }\n        }\n    }\n    for (int x = 0; x < GRID_SIZE; ++x) for (int y = 0; y < GRID_SIZE; ++y) {\n        Rect r{x,y,x+1,y+1};\n        if (!checkOverlap(r)) return r;\n    }\n    return Rect{0,0,1,1};\n}\n\n// Expand rectangle as much as possible without causing overlap, maintaining that it contains the original (x,y)\n// Returns the expanded rectangle.\nRect expand_rect(const Rect& ini, int cx, int cy, int idx, i64 area_limit = 1e8) {\n    Rect r = ini;\n    // Try all 4 sides, one step at a time\n    bool advanced = true;\n    int rounds = 0;\n    while (advanced && r.area() < area_limit && rounds < 200) {\n        advanced = false;\n        // Left\n        if (r.x1 > 0 && r.x1-1 <= cx && !checkOverlap(Rect{r.x1-1, r.y1, r.x2, r.y2}, idx)) {\n            r.x1--, advanced = true;\n        }\n        // Right\n        if (r.x2 < GRID_SIZE && r.x2 > cx+1 && !checkOverlap(Rect{r.x1, r.y1, r.x2+1, r.y2}, idx)) {\n            r.x2++, advanced = true;\n        }\n        // Up\n        if (r.y1 > 0 && r.y1-1 <= cy && !checkOverlap(Rect{r.x1, r.y1-1, r.x2, r.y2}, idx)) {\n            r.y1--, advanced = true;\n        }\n        // Down\n        if (r.y2 < GRID_SIZE && r.y2 > cy+1 && !checkOverlap(Rect{r.x1, r.y1, r.x2, r.y2+1}, idx)) {\n            r.y2++, advanced = true;\n        }\n        rounds++;\n    }\n    // If still can expand in any way (in any direction), do so but prioritize area growth up to company r_i:\n    int dx[] = {-1,0,1,0}, dy[]={0,-1,0,1}; // left, up, right, down\n    bool done = false;\n    while (!done && r.area() < area_limit && rounds < 500) {\n        done = true;\n        for (int dir=0;dir<4;++dir) {\n            Rect candidate = r;\n            if (dir==0 && r.x1>0) candidate.x1--;\n            if (dir==1 && r.y1>0) candidate.y1--;\n            if (dir==2 && r.x2<GRID_SIZE) candidate.x2++;\n            if (dir==3 && r.y2<GRID_SIZE) candidate.y2++;\n            if (candidate.contains(cx+0.5, cy+0.5) && candidate.area() <= area_limit && !checkOverlap(candidate, idx)) {\n                r = candidate; done = false;\n            }\n        }\n        rounds++;\n    }\n    return r;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    cin >> n;\n    companies.resize(n);\n    for (int i = 0; i < n; ++i) {\n        int x, y; i64 r;\n        cin >> x >> y >> r;\n        companies[i] = Company{i, x, y, r, {}};\n    }\n\n    // Instead of largest first, use input order (hydrid), or sort by r (try both for best result)\n    //sort(companies.begin(), companies.end(), [&](const Company& a, const Company& b){\n    //    return a.r > b.r;\n    //});\n\n    placedRects.clear();\n    for (auto& comp : companies) {\n        Rect rect;\n        i64 tr = comp.r;\n        bool placed = false;\n        int area_shrink = 0;\n        while (area_shrink < 15) {\n            i64 req_area = std::max(i64(1), tr - tr * area_shrink / 100);\n            rect = try_place(comp.x, comp.y, req_area);\n            if (rect.x1 != -1) {\n                placed = true;\n                break;\n            }\n            area_shrink += 2;\n        }\n        if (!placed) {\n            rect = emergency_fallback(comp.x, comp.y);\n        }\n        comp.rect = rect;\n        placedRects.push_back({comp.id, rect});\n    }\n\n    // --- GREEDY EXPANSION ---\n    // For each rectangle, try to grow each direction as much as possible without violating constraints\n    for (auto& comp : companies) {\n        int idx = comp.id;\n        Rect ini = comp.rect;\n        i64 target = comp.r;\n        // Limit greed: don't expand unbounded, but try to get close to r\n        Rect grown = expand_rect(ini, comp.x, comp.y, idx, 2*target);\n        // Final overlap check, just in case\n        if (!checkOverlap(grown, idx)) {\n            comp.rect = grown;\n            for (auto& pr : placedRects) if (pr.idx == idx) pr.r = grown;\n        }\n    }\n\n    // Output in input order\n    sort(companies.begin(), companies.end(), [&](const Company& a, const Company& b){\n        return a.id < b.id;\n    });\n    for (auto& comp : companies) {\n        auto& r = comp.rect;\n        cout << r.x1 << ' ' << r.y1 << ' ' << r.x2 << ' ' << r.y2 << '\\n';\n    }\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 50;\nconst int di[4] = {-1, 1, 0, 0}, dj[4] = {0, 0, -1, 1};\nconst char dch[4] = {'U', 'D', 'L', 'R'};\n\nstruct Tile {\n    vector<pair<int, int>> cells;\n    set<int> adj;\n    int max_val = -1, max_cell_i = -1, max_cell_j = -1, sum_val = 0;\n};\n\nint si, sj, t[N][N], p[N][N], ntiles;\nvector<Tile> tiles;\n\nvoid preprocess() {\n    map<int, vector<pair<int,int>>> tile_cells;\n    for(int i = 0; i < N; ++i) for(int j = 0; j < N; ++j)\n        tile_cells[t[i][j]].emplace_back(i, j);\n    ntiles = tile_cells.size();\n    tiles.assign(ntiles, Tile());\n    for(const auto &[tid, cells] : tile_cells) {\n        Tile tile;\n        tile.cells = cells;\n        int maxv = -1, maxi = -1, maxj = -1, sumv = 0;\n        for(auto &[i, j] : tile.cells) {\n            sumv += p[i][j];\n            if(p[i][j] > maxv) { maxv = p[i][j]; maxi = i; maxj = j; }\n        }\n        tile.max_val = maxv;\n        tile.max_cell_i = maxi;\n        tile.max_cell_j = maxj;\n        tile.sum_val = sumv;\n        tiles[tid] = tile;\n    }\n    for(int i = 0; i < N; ++i) for(int j = 0; j < N; ++j) {\n        int tid = t[i][j];\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 >= N || nj >= N) continue;\n            int ntid = t[ni][nj];\n            if(ntid != tid)\n                tiles[tid].adj.insert(ntid);\n        }\n    }\n}\n\nstruct State {\n    int ci, cj, curr_tile, score;\n    vector<bool> tile_used;\n    string path;\n    State() = default;\n    State(int _i, int _j)\n        : ci(_i), cj(_j), curr_tile(t[_i][_j]), score(p[_i][_j]),\n            tile_used(ntiles, false), path(\"\") { tile_used[curr_tile] = true; }\n    State(int _ci, int _cj, int _curr_tile, int _score, const vector<bool> &_tile_used, const string &_path)\n        : ci(_ci), cj(_cj), curr_tile(_curr_tile), score(_score),\n          tile_used(_tile_used), path(_path) {}\n    State(int _ci, int _cj, int _curr_tile, int _score, vector<bool> &&_tile_used, string &&_path)\n        : ci(_ci), cj(_cj), curr_tile(_curr_tile), score(_score),\n          tile_used(std::move(_tile_used)), path(std::move(_path)) {}\n    bool operator<(const State& o) const {\n        if(score != o.score) return score > o.score;\n        return path.size() > o.path.size();\n    }\n};\n\n// Play a semi-random path from a state for up to steps, return sum\nint rollout(int ci, int cj, vector<bool> tile_used, int score, mt19937& rng, int steps=12) {\n    int curr_tid = t[ci][cj];\n    for(int s=0; s<steps; ++s) {\n        vector<pair<int,int>> moves;\n        for(int d=0; d<4; ++d) {\n            int ni=ci+di[d], nj=cj+dj[d];\n            if(ni<0||nj<0||ni>=N||nj>=N) continue;\n            int n_tid = t[ni][nj];\n            if(tile_used[n_tid]) continue;\n            moves.emplace_back(ni,nj);\n        }\n        if(moves.empty()) break;\n        // Bias toward higher-value moves\n        int mx_val = -1;\n        for(auto [ni, nj]: moves) mx_val = max(mx_val, p[ni][nj]);\n        vector<pair<int,int>> opts;\n        for(auto [ni, nj]: moves)\n            if(p[ni][nj]+2 >= mx_val) opts.push_back({ni,nj});\n        auto [nni, nnj] = opts[rng()%opts.size()];\n        ci=nni; cj=nnj;\n        int n_tid = t[ci][cj];\n        tile_used[n_tid]=true;\n        score += p[ci][cj];\n    }\n    return score;\n}\n\nstring multi_restart_beam_search() {\n    const int BEAM_WIDTH = 32;\n    const int MAX_TRIES = 16;\n    const double TIME_LIMIT = 1.92;\n    const int ROLLS_PER_CANDIDATE = 2;\n    const int ROLL_STEPS = 12;\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    int best_score = 0;\n    string best_path = \"\";\n    auto start = chrono::high_resolution_clock::now();\n    int tries = 0;\n    while(tries < MAX_TRIES) {\n        State initial(si, sj);\n        vector<State> beam{initial};\n        int local_best_score = initial.score;\n        string local_best_path = \"\";\n\n        while (!beam.empty()) {\n            vector<State> next_beam;\n            for (const auto& state : beam) {\n                vector<tuple<int, int, int, int, int, int, int>> cand; // (heur, openness, random, d, ni, nj, n_tid)\n                for(int d = 0; d < 4; ++d) {\n                    int ni = state.ci + di[d], nj = state.cj + dj[d];\n                    if(ni < 0 || nj < 0 || ni >= N || nj >= N) continue;\n                    int n_tid = t[ni][nj];\n                    if(state.tile_used[n_tid]) continue;\n                    int openness = 0;\n                    vector<bool> used2 = state.tile_used; used2[n_tid]=true;\n                    for(int dd=0; dd<4; ++dd) {\n                        int nni=ni+di[dd], nnj=nj+dj[dd];\n                        if(nni<0||nnj<0||nni>=N||nnj>=N)continue;\n                        int n2_tid = t[nni][nnj];\n                        if(used2[n2_tid])continue;\n                        openness++;\n                    }\n                    // Monte Carlo rollout as heuristic\n                    int total=0;\n                    for(int roll=0; roll<ROLLS_PER_CANDIDATE; ++roll)\n                        total+=rollout(ni,nj,used2,state.score+p[ni][nj],rng,ROLL_STEPS);\n                    int eval = total / ROLLS_PER_CANDIDATE;\n                    int r = uniform_int_distribution<int>(0, 9999)(rng);\n                    cand.emplace_back(eval, openness, r, d, ni, nj, n_tid);\n                }\n                if(cand.empty()) {\n                    if(state.score > local_best_score) { local_best_score = state.score; local_best_path = state.path; }\n                    continue;\n                }\n                sort(cand.rbegin(), cand.rend());\n                int take = min<int>(cand.size(), 3);\n                for (int kk = 0; kk < take; ++kk) {\n                    auto [valh, openness, rnd, d, ni, nj, n_tid] = cand[kk];\n                    auto next_tile_used = state.tile_used;\n                    next_tile_used[n_tid] = true;\n                    string npath = state.path + dch[d];\n                    next_beam.emplace_back(ni, nj, n_tid, state.score + p[ni][nj],\n                                           std::move(next_tile_used), std::move(npath));\n                }\n            }\n            if(next_beam.empty()) break;\n            if((int)next_beam.size() > BEAM_WIDTH) {\n                std::partial_sort(next_beam.begin(), next_beam.begin() + BEAM_WIDTH, next_beam.end());\n                next_beam.resize(BEAM_WIDTH);\n            }\n            else sort(next_beam.begin(), next_beam.end());\n            beam = std::move(next_beam);\n        }\n        if(local_best_path.empty() && !beam.empty())\n            local_best_path = beam.front().path;\n        if(local_best_score < initial.score && !beam.empty()) {\n            int ci = si, cj = sj;\n            vector<bool> used(ntiles, false);\n            int score = p[ci][cj]; used[t[ci][cj]] = true;\n            for(char ch : beam.front().path){\n                int dir = -1;\n                if(ch == 'U') dir = 0;\n                else if(ch == 'D') dir = 1;\n                else if(ch == 'L') dir = 2;\n                else if(ch == 'R') dir = 3;\n                ci += di[dir]; cj += dj[dir];\n                score += p[ci][cj];\n                used[t[ci][cj]] = true;\n            }\n            local_best_score = score;\n        }\n        if(local_best_score > best_score) {\n            best_score = local_best_score;\n            best_path = local_best_path;\n        }\n        tries++;\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > TIME_LIMIT) break;\n    }\n    return best_path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    cin >> si >> sj;\n    for(int i = 0; i < N; ++i)\n        for(int j = 0; j < N; ++j)\n            cin >> t[i][j];\n    for(int i = 0; i < N; ++i)\n        for(int j = 0; j < N; ++j)\n            cin >> p[i][j];\n    preprocess();\n    string path = multi_restart_beam_search();\n    cout << path << '\\n';\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Constants\nconstexpr int N = 30;\nconstexpr int Q = 1000;\nconstexpr int DIR = 4;\nconst char dir_chars[DIR] = {'U','D','L','R'};\nconst int dx[DIR] = {-1,+1,0,0}, dy[DIR] = {0,0,-1,+1};\n\n// Edge structure for statistics\nstruct EdgeInfo {\n    double est = 5000.0;\n    int count = 0;\n    double sum = 0.0;\n    bool known = false;\n    \n    void update(double val) {\n        sum += val;\n        count++;\n        est = sum / count;\n    }\n    void add_sample(double val, double smoothing=0.8) {\n        if (!known) { est = val; known=true; return; }\n        est = smoothing*est + (1-smoothing)*val;\n    }\n};\n\n// Edge model: grid of edge estimates, separate for horizontal and vertical\nEdgeInfo horiz[N][N-1]; // between (i,j) and (i,j+1)\nEdgeInfo vert[N-1][N]; // between (i,j) and (i+1,j)\n\n// For edge encoding\ninline bool in_grid(int i, int j) { return 0<=i && i<N && 0<=j && j<N; }\n\n// Returns list of moves ('U','D','L','R') for s to t using current edge estimates\nvector<char> estimate_path(pair<int,int> s, pair<int,int> t) {\n    using T = tuple<double,int,int,string>; // cost, i, j, path\n    priority_queue<T, vector<T>, greater<>> pq;\n    vector<vector<double>> dist(N, vector<double>(N, 1e18));\n    vector<vector<pair<int,int>>> prev(N, vector<pair<int,int>>(N, {-1,-1}));\n    vector<vector<int>> previdx(N, vector<int>(N, -1));\n    dist[s.first][s.second] = 0;\n    pq.emplace(0.0, s.first, s.second, \"\");\n    while (!pq.empty()) {\n        auto [cost, i, j, p] = pq.top(); pq.pop();\n        if (make_pair(i,j)==t) {\n            // reconstruct path\n            vector<char> res;\n            int x = t.first, y = t.second;\n            while (prev[x][y].first != -1) {\n                int px = prev[x][y].first, py = prev[x][y].second;\n                int d = previdx[x][y];\n                res.push_back(dir_chars[d]);\n                x=px; y=py;\n            }\n            reverse(res.begin(), res.end());\n            return res;\n        }\n        if (cost > dist[i][j]) continue;\n        for (int d=0; d<4; ++d) {\n            int ni = i+dx[d], nj = j+dy[d];\n            if (!in_grid(ni, nj)) continue;\n            double ecost;\n            if (d==0) ecost = vert[i-1][j].est; // up: between (i-1,j)-(i,j)\n            if (d==1) ecost = vert[i][j].est;   // down: between (i,j)-(i+1,j)\n            if (d==2) ecost = horiz[i][j-1].est; // left: between (i,j-1)-(i,j)\n            if (d==3) ecost = horiz[i][j].est;   // right: between (i,j)-(i,j+1)\n            if (dist[ni][nj] > dist[i][j] + ecost) {\n                dist[ni][nj] = dist[i][j]+ecost;\n                prev[ni][nj] = {i,j};\n                previdx[ni][nj] = d;\n                pq.emplace(dist[ni][nj], ni, nj, p + dir_chars[d]);\n            }\n        }\n    }\n    // never reached: should not happen\n    return {};\n}\n\n// Map moves to edges for updating\nvoid update_edges(pair<int,int> s, const vector<char>& path, double total_edge_len) {\n    vector<pair<int,int>> wayp;\n    wayp.push_back(s);\n    int x = s.first, y = s.second;\n    for (char c: path) {\n        if (c=='U') x--;\n        else if (c=='D') x++;\n        else if (c=='L') y--;\n        else if (c=='R') y++;\n        wayp.emplace_back(x,y);\n    }\n    int plen = (int)path.size();\n    if (plen==0) return;\n    double unit = total_edge_len / plen; // naive: assign equally (no better info!)\n    for (int i=0; i<plen; ++i) {\n        int x0 = wayp[i].first, y0 = wayp[i].second;\n        int x1 = wayp[i+1].first, y1 = wayp[i+1].second;\n        // edge direction\n        if (x0==x1 && y0+1==y1) {\n            horiz[x0][y0].add_sample(unit);\n        } else if (x0==x1 && y0-1==y1) {\n            horiz[x0][y1].add_sample(unit);\n        } else if (x0+1==x1 && y0==y1) {\n            vert[x0][y0].add_sample(unit);\n        } else if (x0-1==x1 && y0==y1) {\n            vert[x1][y0].add_sample(unit);\n        } else assert(false);\n    }\n}\n\n// Early in the contest, randomly explore to cover more edges\nvector<char> random_path(pair<int,int> s, pair<int,int> t, mt19937 &rng) {\n    int x = s.first, y = s.second;\n    int tx = t.first, ty = t.second;\n    vector<char> path;\n    int dx_ = tx - x, dy_ = ty - y;\n    vector<char> moves;\n    if (dx_ > 0) moves.insert(moves.end(), dx_, 'D');\n    else moves.insert(moves.end(), -dx_, 'U');\n    if (dy_ > 0) moves.insert(moves.end(), dy_, 'R');\n    else moves.insert(moves.end(), -dy_, 'L');\n    shuffle(moves.begin(), moves.end(), rng); // randomize order\n    // Create actual path via valid movement\n    for(char c : moves) path.push_back(c);\n    return path;\n}\n\n// Readline helpers\nint si, sj, ti, tj;\nvoid fast_scan() { scanf(\"%d%d%d%d\", &si, &sj, &ti, &tj); }\nint fast_int() { int x; scanf(\"%d\", &x); return x; }\n\nint main() {\n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n\n    for (int query=0; query<Q; ++query) {\n        fast_scan();\n        pair<int,int> s = {si, sj}, t = {ti, tj};\n        vector<char> path_chars;\n        if (query < 100) {\n            path_chars = random_path(s, t, rng); // randomize for first 100 queries\n        } else {\n            path_chars = estimate_path(s, t);\n            if (path_chars.size()==0) { // fallback\n                path_chars = random_path(s, t, rng);\n            }\n        }\n        // Output path\n        string out(path_chars.begin(), path_chars.end());\n        printf(\"%s\\n\", out.c_str());\n        fflush(stdout);\n\n        // Input feedback (rounded noisy cost)\n        int feedback = fast_int();\n\n        // Update edge estimates using feedback length\n        update_edges(s, path_chars, feedback);\n\n        // (optional: debug)\n        // if (query%100==99) cerr << \"[[\"<<query<<\"]]\\n\";\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\n// For random numbers\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Returns list of tuples (direction (0=row,1=col), i, shift)\nvector<tuple<int,int,int>> all_positions(int N, int len) {\n    vector<tuple<int,int,int>> positions;\n    for(int dir=0;dir<2;++dir) // 0=row,1=col\n        for(int i=0;i<N;++i)\n            for(int shift=0;shift<N;++shift)\n                positions.emplace_back(dir,i,shift);\n    return positions;\n}\n\n// Try placing s in matrix a at (dir,i,shift)\n// Return if conflict (false if conflict), and collect pos_painted (to mark for this string)\nbool can_place(const vector<string> &a, int N, const string &s,\n               int dir, int i, int shift, vector<pair<int,int>> &pos_painted) {\n    int k = s.size();\n    pos_painted.clear();\n    for(int p=0;p<k;++p){\n        int x = (dir==0)? i : (i+p)%N;\n        int y = (dir==0)? (shift+p)%N : shift;\n        if(a[x][y]=='.' || a[x][y]==s[p]) {\n            pos_painted.emplace_back(x,y);\n        } else {\n            return false;\n        }\n    }\n    return true;\n}\n\n// Place s in matrix a at given places\nvoid do_paint(vector<string> &a, const string &s, const vector<pair<int,int>> &pos_painted, int dir, int i, int shift) {\n    int k = s.size();\n    for(int p=0;p<k;++p){\n        int x = (dir==0)? i : (i+p)%a.size();\n        int y = (dir==0)? (shift+p)%a.size() : shift;\n        a[x][y] = s[p];\n    }\n}\n\n// Checks if s is covered somewhere in matrix a as row/col subsequence (using torus)\nbool is_covered(const vector<string> &a, const string &s) {\n    int N = a.size();\n    int k = s.size();\n    for(int i=0;i<N;++i){\n        for(int shift=0;shift<N;++shift){\n            // Row\n            bool ok=true;\n            for(int p=0;p<k;++p){\n                if(a[i][(shift+p)%N]!=s[p]) { ok=false; break; }\n            }\n            if(ok) return true;\n            // Col\n            ok=true;\n            for(int p=0;p<k;++p){\n                if(a[(i+p)%N][shift]!=s[p]) { ok=false; break; }\n            }\n            if(ok) return true;\n        }\n    }\n    return false;\n}\n\nint main() {\n    ios::sync_with_stdio(0); cin.tie(0);\n    int N, M;\n    cin >> N >> M;\n    vector<string> s(M);\n    for(int i=0;i<M;++i) cin >> s[i];\n\n    vector<string> best_ans;\n    int best_cover = 0;\n\n    // Try several random processings to maximize c\n    int TRIALS = 7; // You can tune this\n    for(int trial=0; trial<TRIALS; ++trial){\n        vector<string> a(N, string(N,'.'));\n        vector<int> idx(M);\n        iota(idx.begin(), idx.end(), 0);\n        shuffle(idx.begin(), idx.end(), rng);\n\n        // Record for each cell the possible frequency of candidates (for later fill)\n        vector<vector<array<int,8>>> freq(N,vector<array<int,8>>(N));\n        for(int t=0;t<M;++t){\n            const string &si = s[t];\n            int k = si.size();\n            for(int dir=0;dir<2;++dir)\n                for(int i=0;i<N;++i)\n                    for(int shift=0;shift<N;++shift){\n                        for(int p=0;p<k;++p) {\n                            int x = (dir==0)? i : (i+p)%N;\n                            int y = (dir==0)? (shift+p)%N : shift;\n                            freq[x][y][si[p]-'A']++;\n                        }\n                    }\n        }\n\n        // Main Greedy: Try to pack as many s[idx[*]] as possible\n        vector<bool> used(M, false);\n        for(int tt=0;tt<M;++tt){\n            int i_s = idx[tt];\n            const string &si = s[i_s];\n            int k = si.size();\n\n            // Find all possible placements without conflict\n            vector<tuple<int,int,int>> possible;\n            vector<pair<int,int>> buf;\n            for(int dir=0;dir<2;++dir)\n                for(int i=0;i<N;++i)\n                    for(int shift=0;shift<N;++shift)\n                        if(can_place(a,N,si,dir,i,shift,buf))\n                            possible.emplace_back(dir,i,shift);\n\n            if(possible.empty()) continue;\n\n            // Pick randomly (could pick \"minimally fills new cells\", or \"max freq\", but use random for now)\n            auto [dir,i,shift] = possible[rng()%possible.size()];\n            // Actually place it\n            do_paint(a, si, buf, dir, i, shift);\n            used[i_s] = true;\n        }\n        // Final fill-in: Remaining '.' fill with most frequent guess (from freq), or 'A'\n        for(int i=0;i<N;++i) for(int j=0;j<N;++j) if(a[i][j]=='.') {\n            int maxv = 0; char c='A';\n            for(int t=0;t<8;++t) if(freq[i][j][t]>maxv) {\n                maxv = freq[i][j][t];\n                c = 'A' + t;\n            }\n            a[i][j] = c;\n        }\n\n        // Now count how many s are matched as subsequence\n        int cover = 0;\n        for(int i=0;i<M;++i) if(is_covered(a, s[i])) cover++;\n\n        if(cover > best_cover) {\n            best_cover = cover;\n            best_ans = a;\n            if(cover == M) break; // optimal (no point in more tries)\n        }\n    }\n    // Output final matrix\n    for(int i=0;i<N;++i)\n        cout << best_ans[i] << '\\n';\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int DX[4] = {-1, 1, 0, 0};\nconstexpr int DY[4] = {0, 0, -1, 1};\nconstexpr char DIRS[4] = {'U', 'D', 'L', 'R'};\n\nusing Pos = pair<int, int>;\n\n// FastBitSet (as before) ...\nstruct FastBitSet {\n    vector<uint64_t> bs;\n    int size;\n    FastBitSet(int n) : size(n), bs((n+63)>>6) {}\n    void set(int k) { bs[k>>6] |= 1ULL<<(k&63); }\n    void reset(int k) { bs[k>>6] &= ~(1ULL<<(k&63)); }\n    bool test(int k) const { return (bs[k>>6]>>(k&63))&1; }\n    void operator|=(const FastBitSet& rhs) {\n        for (int i=0; i<bs.size(); ++i) bs[i] |= rhs.bs[i];\n    }\n    FastBitSet operator|(const FastBitSet& rhs) const {\n        FastBitSet ret(*this); ret |= rhs; return ret;\n    }\n    int count() const { int res=0; for(auto x:bs) res+=__builtin_popcountll(x); return res; }\n    bool all() const {\n        int lim = size, full = lim/64, rest=lim%64;\n        for(int i=0;i<full;++i) if(bs[i]!=~0ULL) return false;\n        if(rest) return (bs[full]&((1ULL<<rest)-1))==((1ULL<<rest)-1);\n        return true;\n    }\n    vector<int> to_vector() const {vector<int> r; for(int i=0;i<size;++i)if(test(i))r.push_back(i); return r;}\n};\n\nstruct RoadMapper {\n    int N;\n    vector<vector<int>> idx_of;\n    vector<Pos> pos_of;\n    int num_roads;\n    RoadMapper(int N_, const vector<string>& grid):N(N_){\n        idx_of.assign(N,vector<int>(N,-1));\n        int id=0;\n        for(int i=0;i<N;++i)for(int j=0;j<N;++j)\n            if('5'<=grid[i][j]&&grid[i][j]<='9'){idx_of[i][j]=id++;pos_of.push_back({i,j});}\n        num_roads=id;\n    }\n    int id(int i,int j) const {return (0<=i&&i<N&&0<=j&&j<N)?idx_of[i][j]:-1;}\n};\n\nstruct Visibility {\n    int N,num_roads;\n    RoadMapper& mapper;\n    vector<FastBitSet> vis;\n    Visibility(int N_,RoadMapper&m,const vector<string>&grid)\n        :N(N_),mapper(m),num_roads(m.num_roads),vis(num_roads,FastBitSet(m.num_roads)) {\n        auto& idx=mapper.idx_of;\n        for(int k=0;k<num_roads;++k){\n            auto [i,j]=mapper.pos_of[k];\n            for(int jj=j;jj>=0;--jj){ if(idx[i][jj]==-1)break; vis[k].set(idx[i][jj]); }\n            for(int jj=j+1;jj<N;++jj){ if(idx[i][jj]==-1)break; vis[k].set(idx[i][jj]); }\n            for(int ii=i;ii>=0;--ii){ if(idx[ii][j]==-1)break; vis[k].set(idx[ii][j]); }\n            for(int ii=i+1;ii<N;++ii){ if(idx[ii][j]==-1)break; vis[k].set(idx[ii][j]); }\n            vis[k].set(k);\n        }\n    }\n};\nvector<vector<int>> make_move_cost(const vector<string>& grid){\n    int N=grid.size();\n    vector<vector<int>> move_cost(N,vector<int>(N,-1));\n    for(int i=0;i<N;++i)for(int j=0;j<N;++j)\n        if('5'<=grid[i][j]&&grid[i][j]<='9') move_cost[i][j]=grid[i][j]-'0';\n    return move_cost;\n}\nint path_length(const vector<string>& grid, int N, Pos st, Pos gl, const vector<vector<int>>& move_cost){\n    if(st==gl)return 0;\n    priority_queue<tuple<int,int,int>,vector<tuple<int,int,int>>,greater<>> pq;\n    vector<vector<int>> dist(N,vector<int>(N,INT_MAX));\n    pq.emplace(0,st.first,st.second); dist[st.first][st.second]=0;\n    while(!pq.empty()){\n        auto [d,i,j]=pq.top();pq.pop();\n        if(make_pair(i,j)==gl) return d;\n        if(dist[i][j]<d)continue;\n        for(int dir=0;dir<4;++dir){\n            int ni=i+DX[dir],nj=j+DY[dir];\n            if(ni<0||nj<0||ni>=N||nj>=N)continue;\n            if(move_cost[ni][nj]<0)continue;\n            int nd=d+move_cost[ni][nj];\n            if(dist[ni][nj]>nd){\n                dist[ni][nj]=nd; pq.emplace(nd,ni,nj);\n            }\n        }\n    }\n    return INT_MAX;\n}\nvector<Pos> bfs_shortest_path(const vector<string>& grid, int N, Pos st, Pos gl) {\n    if (st == gl) return {st};\n    vector<vector<Pos>> pre(N, vector<Pos>(N, {-1,-1}));\n    queue<Pos> que; que.push(st);\n    pre[st.first][st.second]=st;\n    while(!que.empty()){\n        auto [i,j]=que.front();que.pop();\n        for(int d=0;d<4;++d){\n            int ni=i+DX[d], nj=j+DY[d];\n            if(ni<0||nj<0||ni>=N||nj>=N)continue;\n            if(!(grid[ni][nj]>='5'&&grid[ni][nj]<='9'))continue;\n            if(pre[ni][nj].first!=-1)continue;\n            pre[ni][nj]={i,j};\n            if(make_pair(ni,nj)==gl){\n                vector<Pos> ret;\n                Pos cur=gl;\n                while(cur!=st){ret.push_back(cur);cur=pre[cur.first][cur.second];}\n                ret.push_back(st);\n                reverse(ret.begin(),ret.end());\n                return ret;\n            }\n            que.push({ni,nj});\n        }\n    }\n    return {};\n}\nchar move_dir(const Pos& from, const Pos& to){\n    int di=to.first-from.first,dj=to.second-from.second;\n    for(int d=0;d<4;++d)if(di==DX[d]&&dj==DY[d])return DIRS[d];\n    return '\\0';\n}\nvector<int> greedy_scan_cover(const RoadMapper& m, const Visibility& vis, int si, int sj, mt19937& rng, int topK = 4){\n    int num=m.num_roads;\n    FastBitSet covered(num);\n    int start_id=m.id(si,sj);\n    covered|=vis.vis[start_id];\n    vector<int> scan_pts; scan_pts.push_back(start_id);\n    vector<bool> used(num,false);\n    used[start_id]=true;\n    while(!covered.all()){\n        vector<pair<int,int>> cand;\n        for(int k=0;k<num;++k){\n            if(used[k])continue;\n            int cnt=0;\n            for(int x=0;x<num;++x)\n                if(vis.vis[k].test(x)&&!covered.test(x)) ++cnt;\n            if(cnt>0) cand.emplace_back(-cnt,k);\n        }\n        if(cand.empty()) break;\n        sort(cand.begin(), cand.end());\n        int k = min(topK, (int)cand.size());\n        uniform_int_distribution<int> distr(0,k-1);\n        int idx = distr(rng);\n        int pick = cand[idx].second;\n        scan_pts.push_back(pick);\n        covered|=vis.vis[pick];\n        used[pick]=true;\n    }\n    return scan_pts;\n}\nvoid compute_all_pairs(vector<vector<int>>& dist, const vector<int>& scan_pts, const vector<string>& grid, const RoadMapper& m, const vector<vector<int>>& move_cost){\n    int L=scan_pts.size();\n    for(int i=0;i<L;++i)for(int j=0;j<L;++j){\n        if(i==j){dist[i][j]=0; continue;}\n        int t=path_length(grid,grid.size(), m.pos_of[scan_pts[i]], m.pos_of[scan_pts[j]], move_cost);\n        dist[i][j]=t;\n    }\n}\nvector<int> nearest_neighbor_scan_order(const vector<int>& scan_pts, int start_idx, const vector<vector<int>>& dist){\n    int L=scan_pts.size();\n    vector<int> order={start_idx};\n    vector<bool> vis(L,false); vis[start_idx]=true;\n    int cur=start_idx;\n    for(int step=1;step<L;++step){\n        int nxt=-1,best=INT_MAX;\n        for(int i=0;i<L;++i)\n            if(!vis[i] && dist[cur][i]<best){best=dist[cur][i];nxt=i;}\n        order.push_back(nxt); vis[nxt]=true; cur=nxt;\n    }\n    return order;\n}\nvoid tsp2opt(vector<int>& order, const vector<vector<int>>& dist, int max_rounds=2){\n    int L=order.size();\n    for(int rep=0;rep<max_rounds;++rep){\n        bool updated = false;\n        for(int i=1;i<L-2;++i){\n            for(int j=i+1;j<L-1;++j){\n                int before = dist[order[i-1]][order[i]] + dist[order[j]][order[j+1]];\n                int after  = dist[order[i-1]][order[j]] + dist[order[i]][order[j+1]];\n                if(after < before){\n                    reverse(order.begin()+i,order.begin()+j+1);\n                    updated=true;\n                }\n            }\n        }\n        if(!updated) break;\n    }\n}\nvector<Pos> build_route(const vector<int>& scan_pts, const vector<int>& order, const RoadMapper& m, const vector<string>& grid){\n    vector<Pos> route;\n    for(int ix=0;ix<order.size();++ix){\n        int cur_pt=scan_pts[order[ix]];\n        Pos cur_pos=m.pos_of[cur_pt];\n        if(route.empty()){route.push_back(cur_pos);}\n        else{\n            auto seg=bfs_shortest_path(grid,grid.size(),route.back(),cur_pos);\n            for(int i=1;i<seg.size();++i) route.push_back(seg[i]);\n        }\n    }\n    if(route.front()!=route.back()){\n        auto seg=bfs_shortest_path(grid,grid.size(),route.back(),route.front());\n        for(int i=1;i<seg.size();++i) route.push_back(seg[i]);\n    }\n    vector<Pos> clean{route[0]};\n    for(int i=1;i<route.size();++i)\n        if(route[i]!=route[i-1]) clean.push_back(route[i]);\n    return clean;\n}\nvoid prune_scan_pts(vector<int>& scan_pts, int si, int sj, const RoadMapper& m, const Visibility& vis) {\n    int num=m.num_roads;\n    int start_id = m.id(si,sj);\n    for(int iter=0; iter<2; ++iter){\n        for(int i=scan_pts.size()-1;i>=0;--i){\n            if(scan_pts[i]==start_id) continue;\n            vector<int> tscan = scan_pts;\n            tscan.erase(tscan.begin()+i);\n            FastBitSet covered(num);\n            for(int id:tscan) covered |= vis.vis[id];\n            if(covered.all()){\n                scan_pts = tscan;\n            }\n        }\n    }\n}\nint route_cost(const vector<Pos>& route, const vector<string>& grid){\n    int cost=0;\n    for(size_t i=1;i<route.size();++i){\n        auto [ni, nj] = route[i];\n        cost += grid[ni][nj] - '0';\n    }\n    return cost;\n}\nint main() {\n    ios::sync_with_stdio(0);cin.tie(0);\n    int N,si,sj; cin>>N>>si>>sj;\n    vector<string> grid(N);\n    for(int i=0;i<N;++i)cin>>grid[i];\n    RoadMapper m(N,grid);\n    Visibility vis(N,m,grid);\n\n    constexpr int MAXRAND=12;\n    constexpr int SCANPT_LIMIT=90;\n    constexpr double SOFTTIME=2.65;\n    auto startclock=chrono::steady_clock::now();\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()+si*31+sj);\n\n    auto move_cost = make_move_cost(grid);\n    int best_cost = INT_MAX;\n    string best_moves;\n\n    for(int randtry=0;randtry<MAXRAND;++randtry){\n        auto clocknow=chrono::steady_clock::now();\n        if(chrono::duration<double>(clocknow-startclock).count()>SOFTTIME) break;\n        auto scan_pts=greedy_scan_cover(m,vis,si,sj,rng,4);\n        if(scan_pts.size() > SCANPT_LIMIT) continue;\n        prune_scan_pts(scan_pts, si, sj, m, vis);\n        if(scan_pts.size()>SCANPT_LIMIT) continue;\n        int start_idx=0;\n        for(int i=0;i<scan_pts.size();++i)\n            if(m.pos_of[scan_pts[i]]==Pos(si,sj)) start_idx=i;\n        int L=scan_pts.size();\n        vector<vector<int>> dist(L,vector<int>(L, 1e9));\n        compute_all_pairs(dist, scan_pts, grid, m, move_cost);\n        auto order = nearest_neighbor_scan_order(scan_pts, start_idx, dist);\n        tsp2opt(order, dist, 8);\n        auto route=build_route(scan_pts,order,m,grid);\n        int cost=route_cost(route,grid);\n        if(route.front()!=route.back()) continue;\n        string res; bool ok = true;\n        for(int i=1;i<route.size();++i){\n            char c=move_dir(route[i-1],route[i]);\n            if(c=='\\0') ok=false;\n            res+=c;\n        }\n        int ci=si,cj=sj;\n        for(char c:res){\n            int d=find(DIRS,DIRS+4,c)-DIRS;\n            if(d>=4){ok=false; break;}\n            int ni=ci+DX[d],nj=cj+DY[d];\n            if(ni<0||nj<0||ni>=N||nj>=N||!(grid[ni][nj]>='5'&&grid[ni][nj]<='9')){ok=false;break;}\n            ci=ni; cj=nj;\n        }\n        if(!ok||ci!=si||cj!=sj) continue;\n        if(cost<best_cost){\n            best_cost=cost;\n            best_moves=res;\n        }\n    }\n    if(best_moves.empty()) { cout<<'\\n'; return 0; }\n    cout<<best_moves<<endl;\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int MAX_K = 20, MAX_M = 20, MAX_N = 1000;\n\nint n, m, k, r;\nvector<vector<int>> d;\nvector<vector<int>> dependencies, revdeps;\nvector<int> indegree;\nvector<int> status;\n\nstruct MemberState {\n    int current_task = -1;\n    int assigned_day = -1;\n};\n\nvector<MemberState> members;\nint current_day = 1;\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// For structured exploration/bootstrapping\nstruct ProbeInfo {\n    vector<bool> axis_probed;\n    int probes_done = 0;\n    int boot_done = 0;\n    ProbeInfo(int K = MAX_K) : axis_probed(K, false) {}\n};\nvector<ProbeInfo> probeinfo;\n\n// For skill tracking: per-member, per-axis\nstruct FastSkillEstimate {\n    vector<int> estimate; // Skill per dimension\n    FastSkillEstimate(int K) : estimate(K, 0) {}\n};\nvector<FastSkillEstimate> skillstats;\n\nvector<vector<pair<int,int>>> member_finished_tasks;\nvector<int> task_criticality;\n\nvoid read_input() {\n    cin >> n >> m >> k >> r;\n    d.resize(n, vector<int>(k));\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < k; ++j)\n            cin >> d[i][j];\n    dependencies.assign(n, {});\n    revdeps.assign(n, {});\n    indegree.assign(n, 0);\n    for (int i = 0; i < r; ++i) {\n        int u, v; cin >> u >> v; --u; --v;\n        dependencies[v].push_back(u);\n        revdeps[u].push_back(v);\n        indegree[v]++;\n    }\n}\n\nvector<int> compute_critical_path() {\n    vector<int> critical(n, 0);\n    vector<int> topo;\n    vector<int> indeg_tmp = indegree;\n    queue<int> q;\n    for (int i = 0; i < n; ++i) if (indeg_tmp[i] == 0) q.push(i);\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        topo.push_back(u);\n        for (int v : revdeps[u]) {\n            --indeg_tmp[v];\n            if (indeg_tmp[v] == 0) q.push(v);\n        }\n    }\n    reverse(topo.begin(), topo.end());\n    for (int u : topo)\n        for (int v : revdeps[u])\n            critical[u] = max(critical[u], critical[v] + 1);\n    return critical;\n}\n\nvoid initialize() {\n    status.assign(n, 0);\n    members.assign(m, MemberState());\n    probeinfo.assign(m, ProbeInfo(k));\n    skillstats.assign(m, FastSkillEstimate(k));\n    member_finished_tasks.assign(m, {});\n    task_criticality = compute_critical_path();\n}\n\nset<int> ready_tasks;\nvoid add_ready_tasks() {\n    for (int i = 0; i < n; ++i)\n        if (indegree[i] == 0 && status[i] == 0)\n            ready_tasks.insert(i);\n}\n\nvector<vector<double>> estimate_skills() {\n    vector<vector<double>> est(m, vector<double>(k, 0.0));\n    for (int mi = 0; mi < m; ++mi)\n        for (int dim = 0; dim < k; ++dim)\n            est[mi][dim] = max(0, skillstats[mi].estimate[dim]);\n    return est;\n}\n\nvoid assign_tasks_today(vector<pair<int, int>>& assignments) {\n    vector<int> idle_members;\n    for (int j = 0; j < m; ++j)\n        if (members[j].current_task == -1)\n            idle_members.push_back(j);\n    set<int> used_tasks;\n    auto est_sk = estimate_skills();\n\n    for (int j : idle_members) {\n        // --- BOOTSTRAP: pick easiest tasks for fast/weaker-member skill estimation ---\n        if (probeinfo[j].boot_done < 2) {\n            int best_t = -1, best_sum = INT_MAX, best_crit = -1;\n            for (int t: ready_tasks) if (!used_tasks.count(t)) {\n                int sum = 0;\n                for (int kk = 0; kk < k; ++kk) sum += d[t][kk];\n                int tot=(int)revdeps[t].size();\n                if (sum < best_sum || (sum==best_sum && tot>best_crit)) {\n                    best_t = t; best_sum=sum; best_crit=tot;\n                }\n            }\n            if (best_t != -1) {\n                assignments.emplace_back(j, best_t);\n                used_tasks.insert(best_t);\n                status[best_t] = 1;\n                members[j].current_task = best_t;\n                members[j].assigned_day = current_day;\n                probeinfo[j].boot_done++;\n                continue;\n            }\n        }\n\n        // --- EXPLORATION: assign member to any unprobed axis ---\n        if (probeinfo[j].probes_done < k) {\n            for (int dim = 0; dim < k; ++dim) {\n                if (!probeinfo[j].axis_probed[dim]) {\n                    // Find a ready task whose max axis is dim (prefer lower diff)\n                    int best_t = -1, best_req = INT_MAX, best_crit = -1;\n                    for (int t: ready_tasks) if (!used_tasks.count(t)) {\n                        int peakval = -1, peakd=-1;\n                        for (int kk=0;kk<k;++kk)\n                            if (d[t][kk]>peakval) {peakval=d[t][kk]; peakd=kk;}\n                        if (peakd==dim) {\n                            int tot=(int)revdeps[t].size();\n                            if (d[t][peakd] < best_req || (d[t][peakd]==best_req && tot>best_crit)) {\n                                best_t = t; best_req=d[t][peakd]; best_crit=tot;\n                            }\n                        }\n                    }\n                    if (best_t != -1) {\n                        assignments.emplace_back(j, best_t);\n                        used_tasks.insert(best_t);\n                        status[best_t] = 1;\n                        members[j].current_task = best_t;\n                        members[j].assigned_day = current_day;\n                        break;\n                    }\n                }\n            }\n            if(members[j].current_task != -1) continue;\n            // If not found, fall through to exploitation\n        }\n\n        // --- EXPLOITATION ---\n        double best_score = 1e9; int best_task = -1; int best_crit = -1;\n        vector<int> candidates;\n        for (int t : ready_tasks) if (!used_tasks.count(t)) {\n            double w = 0;\n            for (int kk = 0; kk < k; ++kk)\n                if (d[t][kk] > est_sk[j][kk])\n                    w += (d[t][kk] - est_sk[j][kk]);\n            double expect = max(1.0, w);\n            int crit = task_criticality[t];\n            double score = expect - crit * 0.2;\n            if (score < best_score-1e-8) {\n                best_score = score;\n                best_task = t;\n                best_crit = crit;\n                candidates.clear();\n                candidates.push_back(t);\n            } else if (abs(score-best_score)<1e-8) {\n                candidates.push_back(t);\n            }\n        }\n        if (!candidates.empty()) {\n            int tsel = candidates[rng()%candidates.size()];\n            assignments.emplace_back(j, tsel);\n            used_tasks.insert(tsel);\n            status[tsel] = 1;\n            members[j].current_task = tsel;\n            members[j].assigned_day = current_day;\n        }\n    }\n}\n\nvoid process_feedback(const vector<int>& finished_members) {\n    for (int member : finished_members) {\n        auto& ms = members[member];\n        int tsk = ms.current_task, t0 = ms.assigned_day, obs_days = current_day - t0 + 1;\n        status[tsk] = 2;\n        ms.current_task = -1;\n        ms.assigned_day = -1;\n        member_finished_tasks[member].emplace_back(tsk, obs_days);\n\n        // If in bootstrap, aggressive update: for t=1, set all est dims at least d[tsk][k]\n        if(probeinfo[member].boot_done>0 && probeinfo[member].boot_done<=2){\n            if(obs_days==1)\n                for(int kk=0;kk<k;++kk)\n                    skillstats[member].estimate[kk]=max(skillstats[member].estimate[kk],d[tsk][kk]);\n        }\n        // Structured probe info update\n        int peakv=-1, peakd=-1;\n        for(int kk=0;kk<k;++kk) if(d[tsk][kk]>peakv){ peakv=d[tsk][kk]; peakd=kk;}\n        if(!probeinfo[member].axis_probed[peakd]){\n            probeinfo[member].axis_probed[peakd]=true;\n            probeinfo[member].probes_done++;\n        }\n        // Update skill estimates: boost dimension if a fast finish\n        for(int kk=0;kk<k;++kk){\n            int val = d[tsk][kk] - max(0, obs_days-1);\n            skillstats[member].estimate[kk] = max(skillstats[member].estimate[kk], val);\n        }\n        for (int dv : revdeps[tsk]) {\n            --indegree[dv];\n            if (indegree[dv] == 0 && status[dv] == 0)\n                ready_tasks.insert(dv);\n        }\n    }\n}\n\nvoid print_assignments(const vector<pair<int, int>>& assignments) {\n    cout << assignments.size();\n    for (auto [member, task] : assignments)\n        cout << ' ' << (member + 1) << ' ' << (task + 1);\n    cout << '\\n';\n    cout.flush();\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    read_input();\n    initialize();\n    add_ready_tasks();\n\n    while (true) {\n        vector<pair<int, int>> assignments;\n        assign_tasks_today(assignments);\n        for (auto &p : assignments)\n            ready_tasks.erase(p.second);\n        print_assignments(assignments);\n\n        string line;\n        while (true) {\n            getline(cin, line);\n            if (cin.eof()) exit(0);\n            if (!line.empty()) break;\n        }\n        if (line==\"-1\") break;\n        istringstream iss(line);\n        int cnt; iss >> cnt;\n        if (cnt==-1) break;\n        vector<int> finished(cnt);\n        for (int i = 0; i < cnt; ++i) { int x; iss >> x; finished[i]=x-1;}\n        process_feedback(finished);\n        current_day++;\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\nmt19937 rng(42);\n\nstruct Order {\n    int id;\n    int ax, ay;\n    int cx, cy;\n    int score;\n};\n\nint manh(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\nvector<pair<int,int>> kmeans_init(const vector<pair<int,int>>& pts, int K) {\n    int N = pts.size();\n    vector<pair<int,int>> centers;\n    centers.push_back(pts[rng()%N]);\n    vector<int> dist(N, 1e9);\n    for (int k = 1; k < K; ++k) {\n        int S = 0;\n        for (int i = 0; i < N; ++i) {\n            int d = manh(pts[i].first, pts[i].second, centers.back().first, centers.back().second);\n            if(d < dist[i]) dist[i]=d;\n            S += dist[i];\n        }\n        if(S==0) break;\n        int t = rng()%S, acc=0,i=0;\n        for(;i<N&&acc<t;++i) acc+=dist[i];\n        centers.push_back(pts[(i==N)?N-1:i]);\n    }\n    return centers;\n}\n\nvoid kmeans(const vector<pair<int,int>>& pts, int K, vector<int>& belong, vector<pair<int,int>>& centers, int iters=4) {\n    int N = pts.size();\n    belong.resize(N);\n    centers = kmeans_init(pts,K);\n\n    for (int it = 0; it < iters; ++it) {\n        for (int i = 0; i < N; ++i) {\n            int best = 0, best_d = manh(pts[i].first, pts[i].second, centers[0].first, centers[0].second);\n            for (int k = 1; k < K; ++k) {\n                int d = manh(pts[i].first, pts[i].second, centers[k].first, centers[k].second);\n                if (d < best_d) best_d = d, best = k;\n            }\n            belong[i] = best;\n        }\n        vector<int64_t> sx(K, 0), sy(K, 0), sn(K, 0);\n        for (int i = 0; i < N; ++i) {\n            sx[belong[i]] += pts[i].first;\n            sy[belong[i]] += pts[i].second;\n            sn[belong[i]] += 1;\n        }\n        for (int k = 0; k < K; ++k) {\n            if (sn[k]) centers[k] = {int(sx[k]/sn[k]), int(sy[k]/sn[k])};\n        }\n    }\n}\n\nstruct Node {\n    int x, y;\n    int ord_idx;\n    bool is_pickup;\n};\nstruct Result {\n    vector<int> sel_ids;\n    vector<pair<int,int>> route;\n    int route_cost;\n};\n\nResult get_route(const vector<Order>& sel_orders, int variant=0) {\n    vector<Node> nodes;\n    for (int i = 0; i < 50; ++i)\n        nodes.push_back({sel_orders[i].ax, sel_orders[i].ay, i, true});\n    for (int i = 0; i < 50; ++i)\n        nodes.push_back({sel_orders[i].cx, sel_orders[i].cy, i, false});\n    int N = nodes.size();\n\n    vector<bool> visited(N, false);\n    vector<bool> pickup_done(50, false);\n\n    vector<pair<int,int>> route = {{400,400}};\n    int cur_x = 400, cur_y = 400;\n    for (int step = 0; step < N; ++step) {\n        vector<int> avail;\n        for (int i = 0; i < N; ++i) if (!visited[i]) {\n            if (!nodes[i].is_pickup && !pickup_done[nodes[i].ord_idx]) continue;\n            avail.push_back(i);\n        }\n        int best = -1, best_dist = 1e9;\n        vector<int> candidates;\n        for (int i : avail) {\n            int dist = manh(cur_x, cur_y, nodes[i].x, nodes[i].y);\n            if (dist < best_dist) {\n                best_dist = dist;\n                candidates.clear();\n                candidates.push_back(i);\n            }\n            else if (dist == best_dist) candidates.push_back(i);\n        }\n        if(!candidates.empty()) {\n            if(variant==0)\n                best = candidates[0];\n            else\n                best = candidates[rng()%candidates.size()];\n        } else {\n            best = avail[rng()%avail.size()];\n        }\n        visited[best]=true;\n        if(nodes[best].is_pickup) pickup_done[nodes[best].ord_idx]=true;\n        cur_x = nodes[best].x; cur_y = nodes[best].y;\n        route.emplace_back(cur_x, cur_y);\n    }\n    if(cur_x!=400||cur_y!=400) route.emplace_back(400,400);\n    int cost=0;\n    for(int i=1;i<route.size();++i)\n        cost += manh(route[i-1].first,route[i-1].second,route[i].first,route[i].second);\n\n    vector<int> sel_ids;\n    for(const auto&o:sel_orders)sel_ids.push_back(o.id+1);\n    return {sel_ids,route,cost};\n}\n\n// Local-improvement: swap a chosen order for an unchosen one if it improves the route\nvoid improve_order_set(const vector<Order>& orders_all, vector<Order>& sel_orders, int imp_trials=12, int imp_nb_out=5, int imp_nb_in=7) {\n    set<int> chosen;\n    for(auto&o:sel_orders) chosen.insert(o.id);\n    vector<Order> unchosen;\n    for(const auto&o:orders_all) if(!chosen.count(o.id)) unchosen.push_back(o);\n\n    int best_cost = get_route(sel_orders, 1).route_cost;\n\n    for(int trial=0; trial<imp_trials; ++trial){\n        vector<int> idx_out;\n        for(int i=0;i<(int)sel_orders.size();++i) idx_out.push_back(i);\n        shuffle(idx_out.begin(),idx_out.end(),rng);\n        idx_out.resize(min((int)idx_out.size(),imp_nb_out));\n\n        vector<int> idx_in;\n        for(int i=0;i<(int)unchosen.size();++i) idx_in.push_back(i);\n        shuffle(idx_in.begin(),idx_in.end(),rng);\n        idx_in.resize(min((int)idx_in.size(),imp_nb_in));\n\n        bool changed = false;\n        for(int oi:idx_out) {\n            for(int ii:idx_in) {\n                Order out = sel_orders[oi];\n                Order in = unchosen[ii];\n                sel_orders[oi] = in;\n                set<int> checkset;\n                for(auto&o:sel_orders) checkset.insert(o.id);\n                if(checkset.size()<50) {\n                    sel_orders[oi] = out;\n                    continue;\n                }\n                int cost = get_route(sel_orders, 1).route_cost;\n                if(cost < best_cost) {\n                    best_cost = cost;\n                    unchosen[ii] = out;\n                    changed = true;\n                    break;\n                } else {\n                    sel_orders[oi] = out;\n                }\n            }\n            if(changed) break;\n        }\n        if(!changed) break;\n    }\n}\n\n// Smart filler: use minimum distance to selected, plus order score\nvoid fill_to_50_smart(vector<Order>& sel, const vector<Order>& all, int nfill) {\n    set<int> curids;\n    for(auto&o:sel) curids.insert(o.id);\n\n    vector<pair<int,int>> sel_pts;\n    for(auto&o:sel) {\n        sel_pts.emplace_back(o.ax, o.ay);\n        sel_pts.emplace_back(o.cx, o.cy);\n    }\n\n    vector<pair<double,int>> can_add; // (heuristic, idx in all)\n    for(int i=0;i<(int)all.size();++i) if(!curids.count(all[i].id)) {\n        int min_dist = INT_MAX;\n        for(const auto&pt : sel_pts)\n            min_dist = min(min_dist, manh(pt.first, pt.second, all[i].ax, all[i].ay));\n        double h = all[i].score + 0.5 * min_dist;\n        can_add.push_back({h, i});\n    }\n    sort(can_add.begin(), can_add.end());\n    for(int add=0;add<nfill && add<(int)can_add.size();++add) {\n        sel.push_back(all[can_add[add].second]);\n    }\n}\n\n// The routine (cluster, centers, ... as before)\nvoid run_strategy(\n    const vector<Order> &orders, \n    const vector<int> &belong, const vector<pair<int,int>> &centers,\n    int CLUSTER_TRY, int RUNS_PER_CLUSTER,\n    int &best_cost, vector<int>& best_sel_ids, vector<pair<int,int>>& best_route\n) {\n    int K = centers.size();\n    vector<int> center_order(K);\n    iota(center_order.begin(),center_order.end(),0);\n    sort(center_order.begin(),center_order.end(),[&](int i,int j){\n        int di=manh(400,400,centers[i].first,centers[i].second);\n        int dj=manh(400,400,centers[j].first,centers[j].second);\n        return di<dj;\n    });\n\n    for(int cl=0;cl<CLUSTER_TRY;++cl){\n        int cid = center_order[cl];\n        vector<Order> cand0;\n        for(int i=0;i<orders.size();++i)if(belong[i]==cid)\n            cand0.push_back(orders[i]);\n        sort(cand0.begin(),cand0.end(),[](const Order&a,const Order&b){return a.score<b.score;});\n        int in_cluster = min((int)cand0.size(),38);\n        vector<Order> candA(cand0.begin(),cand0.begin()+in_cluster);\n        fill_to_50_smart(candA, orders, 50-in_cluster);\n        improve_order_set(orders, candA, 12, 5, 6);\n\n        for(int run=0;run<RUNS_PER_CLUSTER;++run){\n            Result res = get_route(candA, run>0?1:0);\n            if(res.route_cost < best_cost){\n                best_cost = res.route_cost;\n                best_sel_ids=res.sel_ids;\n                best_route=res.route;\n            }\n        }\n    }\n}\n\n// Pair strategy for multi-cluster merges\nvoid run_pair_strategy(\n    const vector<Order> &orders, \n    const vector<int> &belong, const vector<pair<int,int>> &centers,\n    int PAIR_TRY, int subsize,\n    int &best_cost, vector<int>& best_sel_ids, vector<pair<int,int>>& best_route\n) {\n    int K = centers.size();\n    vector<pair<int,int>> cluster_ord; // (distance to office, index)\n    for(int i=0;i<K;++i)\n        cluster_ord.emplace_back(manh(400,400,centers[i].first, centers[i].second), i);\n    sort(cluster_ord.begin(),cluster_ord.end());\n    // Try PAIR_TRY best cluster pairs\n    int pszs = subsize;\n    int cnt = 0;\n    for(int p1=0;p1<min(K,4);++p1) {\n        for(int p2=p1+1;p2<min(K,7);++p2) {\n            if(cnt++ > PAIR_TRY) break;\n            int c1 = cluster_ord[p1].second;\n            int c2 = cluster_ord[p2].second;\n            vector<Order> c1s, c2s;\n            for(int i=0;i<(int)orders.size();++i) if(belong[i]==c1) c1s.push_back(orders[i]);\n            for(int i=0;i<(int)orders.size();++i) if(belong[i]==c2) c2s.push_back(orders[i]);\n            sort(c1s.begin(),c1s.end(),[](const Order&a,const Order&b){return a.score<b.score;});\n            sort(c2s.begin(),c2s.end(),[](const Order&a,const Order&b){return a.score<b.score;});\n            int m1 = min(pszs, (int)c1s.size());\n            int m2 = min(pszs, (int)c2s.size());\n            set<int> ids;\n            vector<Order> cand;\n            for(int i=0; i<m1 && (int)cand.size()<50; ++i) {\n                if(!ids.count(c1s[i].id)) {\n                    ids.insert(c1s[i].id);\n                    cand.push_back(c1s[i]);\n                }\n            }\n            for(int i=0; i<m2 && (int)cand.size()<50; ++i) {\n                if(!ids.count(c2s[i].id)) {\n                    ids.insert(c2s[i].id);\n                    cand.push_back(c2s[i]);\n                }\n            }\n            fill_to_50_smart(cand, orders, 50-cand.size());\n            improve_order_set(orders, cand, 10, 4, 4);\n            Result res = get_route(cand, 1);\n            if(res.route_cost < best_cost){\n                best_cost = res.route_cost;\n                best_sel_ids=res.sel_ids;\n                best_route=res.route;\n            }\n        }\n        if(cnt > PAIR_TRY) break;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    vector<Order> orders(1000);\n    for (int i = 0; i < 1000; ++i) {\n        int a, b, c, d;\n        cin >> a >> b >> c >> d;\n        orders[i] = {i, a, b, c, d, 0};\n    }\n    for (auto& o : orders) {\n        int office = 400;\n        o.score = manh(400,400,o.ax,o.ay) + manh(o.ax,o.ay,o.cx,o.cy) + manh(o.cx,o.cy,400,400);\n    }\n\n    int best_cost = INT_MAX;\n    vector<int> best_sel_ids;\n    vector<pair<int,int>> best_route;\n\n    int K=10, CLUSTER_TRY=6, RUNS_PER_CLUSTER=4;\n\n    // Pickup and delivery clustering\n    vector<pair<int,int>> pickups, deliveries;\n    for (auto&o:orders) {\n        pickups.emplace_back(o.ax, o.ay);\n        deliveries.emplace_back(o.cx, o.cy);\n    }\n    vector<int> belong_pick, belong_del;\n    vector<pair<int,int>> centers_pick, centers_del;\n    kmeans(pickups, K, belong_pick, centers_pick, 3);\n    kmeans(deliveries, K, belong_del, centers_del, 3);\n\n    run_strategy(orders, belong_pick, centers_pick, CLUSTER_TRY, RUNS_PER_CLUSTER, best_cost, best_sel_ids, best_route);\n    run_strategy(orders, belong_del, centers_del, CLUSTER_TRY, RUNS_PER_CLUSTER, best_cost, best_sel_ids, best_route);\n\n    // Try best couple-pair strategies (multicluster merge)\n    run_pair_strategy(orders, belong_pick, centers_pick, 8, 26, best_cost, best_sel_ids, best_route);\n    run_pair_strategy(orders, belong_del, centers_del, 8, 26, best_cost, best_sel_ids, best_route);\n\n    // fallback: global best 50\n    sort(orders.begin(), orders.end(), [](const Order& a, const Order& b) {\n        return a.score < b.score;\n    });\n    vector<Order> top50(orders.begin(), orders.begin()+50);\n\n    improve_order_set(orders, top50, 8, 4, 5);\n\n    Result res = get_route(top50, 1);\n    if(res.route_cost < best_cost){\n        best_cost = res.route_cost;\n        best_sel_ids=res.sel_ids;\n        best_route=res.route;\n    }\n\n    cout << \"50\";\n    for (int i = 0; i < 50; ++i)\n        cout << \" \" << best_sel_ids[i];\n    cout << \"\\n\";\n    cout << best_route.size();\n    for (auto& p : best_route)\n        cout << \" \" << p.first << \" \" << p.second;\n    cout << \"\\n\";\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 400, M = 1995;\n\nstruct DSU {\n    vector<int> par, sz;\n    vector<bitset<N>> members;\n    DSU(int n) : par(n), sz(n, 1), members(n) {\n        iota(par.begin(), par.end(), 0);\n        for(int i=0; i<n; i++) members[i].set(i);\n    }\n    int find(int x) {\n        if (par[x] == x) return x;\n        return par[x] = find(par[x]);\n    }\n    bool unite(int x, int y) {\n        x = find(x); y = find(y);\n        if (x == y) return false;\n        if (sz[x]<sz[y]) swap(x,y);\n        par[y]=x; sz[x]+=sz[y];\n        members[x] |= members[y];\n        members[y].reset();\n        return true;\n    }\n    bitset<N>& get_members(int x) { return members[find(x)]; }\n};\n\nstruct Edge { int u, v, d; };\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<pair<int,int>> coords(N);\n    for(int i=0; i<N; ++i) cin >> coords[i].first >> coords[i].second;\n    vector<Edge> edges(M);\n    vector<vector<queue<int>>> pair_edge_ids(N, vector<queue<int>>(N));\n    for(int i=0; i<M; ++i) {\n        int u, v; cin >> u >> v;\n        int x1 = coords[u].first, y1 = coords[u].second;\n        int x2 = coords[v].first, y2 = coords[v].second;\n        int d = round(sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));\n        edges[i] = {u, v, d};\n        pair_edge_ids[min(u,v)][max(u,v)].push(i);\n    }\n    DSU dsu(N);\n\n    int num_components = N;\n    // You can tweak this. E.g., relax when few components left.\n    double cheap_factor_base = 1.07, cheap_factor_final = 1.15;\n\n    for(int i=0; i<M; ++i) {\n        int l_i; cin >> l_i;\n        int u = edges[i].u, v = edges[i].v, d = edges[i].d;\n        bool accepted = false;\n        int ru = dsu.find(u), rv = dsu.find(v);\n        if (ru == rv) {\n            pair_edge_ids[min(u,v)][max(u,v)].pop();\n            cout << 0 << endl; cout << flush;\n            continue;\n        }\n\n        auto &q = pair_edge_ids[min(u,v)][max(u,v)];\n        q.pop();\n\n        // Dynamic threshold: be stricter early, relax late\n        double cheap_factor = (num_components > 100) ? cheap_factor_base :\n                              (num_components > 20) ? (cheap_factor_base + 0.5*(cheap_factor_final - cheap_factor_base)) :\n                              cheap_factor_final;\n\n        // Is there ANY remaining edge between current components?\n        bool must_accept = true;\n        // Using bitsets for fast scan\n        auto &A = dsu.get_members(ru);\n        auto &B = dsu.get_members(rv);\n        for (int a = A._Find_first(); a < N; a = A._Find_next(a)) {\n            for (int b = B._Find_first(); b < N; b = B._Find_next(b)) {\n                if (a == b) continue;\n                if (!pair_edge_ids[min(a,b)][max(a,b)].empty()) {\n                    must_accept = false;\n                    goto done; // early escape, at least one pair remains\n                }\n            }\n        }\n        done:;\n        if (must_accept) {\n            cout << 1 << endl; cout << flush;\n            dsu.unite(u, v);\n            --num_components;\n            accepted = true;\n        } else if (l_i <= int(cheap_factor * d)) {\n            cout << 1 << endl; cout << flush;\n            dsu.unite(u, v);\n            --num_components;\n            accepted = true;\n        }\n        if (!accepted) {\n            cout << 0 << endl; cout << flush;\n        }\n    }\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int W = 30, H = 30;\nconstexpr int DX[4] = {-1, 1, 0, 0};\nconstexpr int DY[4] = {0, 0, -1, 1};\nconstexpr char MOVES[4] = {'U', 'D', 'L', 'R'};\nconstexpr char WALLS[4] = {'u', 'd', 'l', 'r'};\n\ninline bool ins(int x, int y) { return 0 <= x && x < H && 0 <= y && y < W; }\n\nstruct Pet { int x, y, type; };\nstruct Human { int x, y, dest_x, dest_y, band_l, band_r; };\n\nint get_dir_wall(char c) { if (c=='u')return 0; if (c=='d')return 1; if (c=='l')return 2; if (c=='r')return 3; return -1; }\nint get_dir_move(char c) { if (c=='U')return 0; if (c=='D')return 1; if (c=='L')return 2; if (c=='R')return 3; return -1; }\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n\n    int N; cin >> N;\n    vector<Pet> pets(N);\n    vector<string> grid(H, string(W, '.'));\n    for (int i = 0; i < N; i++) {\n        int x, y, t; cin >> x >> y >> t; --x; --y;\n        pets[i] = {x, y, t}; grid[x][y] = 'p';\n    }\n    int M; cin >> M;\n    vector<Human> humans(M);\n    for (int i = 0; i < M; i++) {\n        int x, y; cin >> x >> y; --x; --y;\n        humans[i].x = x; humans[i].y = y; grid[x][y] = 'h';\n    }\n    int band_size = W / M;\n    for (int i = 0; i < M; i++) {\n        int l = i * band_size, r = (i == M-1 ? W-1 : (i+1)*band_size-1);\n        humans[i].band_l=l; humans[i].band_r=r;\n        humans[i].dest_x=H/2; humans[i].dest_y=(l+r)/2;\n    }\n\n    vector<vector<int>> pet_grid(H, vector<int>(W, 0));\n    int phase_move = 12;\n    vector<vector<bool>> will_wall(H, vector<bool>(W, false));\n    for (int turn = 0; turn < 300; ++turn) {\n        string actions(M, '.');\n        for (int i = 0; i < H; ++i)\n            for (int j = 0; j < W; ++j)\n                if (grid[i][j]=='h' || grid[i][j]=='p') grid[i][j] = '.';\n        for (int i = 0; i < H; ++i) fill(pet_grid[i].begin(), pet_grid[i].end(), 0);\n        vector<vector<int>> human_grid(H, vector<int>(W, 0));\n        for (int i = 0; i < M; ++i) {\n            grid[humans[i].x][humans[i].y] = 'h';\n            human_grid[humans[i].x][humans[i].y]++;\n        }\n        for (int i = 0; i < N; ++i) {\n            grid[pets[i].x][pets[i].y] = 'p';\n            pet_grid[pets[i].x][pets[i].y]++;\n        }\n        for (int i = 0; i < H; ++i) fill(will_wall[i].begin(), will_wall[i].end(), false);\n\n        // 1. Mark all will_wall positions (plan all wall placements for this turn)\n        for (int i = 0; i < M; ++i) {\n            auto& h = humans[i];\n            int cx=h.x, cy=h.y, xl=h.band_l, xr=h.band_r;\n            if (turn < phase_move) continue;\n            for (int d = 0; d < 4; ++d) {\n                int tx=cx+DX[d], ty=cy+DY[d];\n                if (!ins(tx,ty)) continue;\n                if (!(ty == xl-1 || ty == xr+1)) continue;\n                if (grid[tx][ty]!='.') continue;\n                if (human_grid[tx][ty]!=0 || pet_grid[tx][ty]!=0) continue;\n                bool safe=true;\n                for (int d2=0; d2<4; ++d2) {\n                    int nx=tx+DX[d2], ny=ty+DY[d2];\n                    if (ins(nx,ny)&&pet_grid[nx][ny]) {safe=false; break;}\n                }\n                if (safe) will_wall[tx][ty]=true;\n            }\n        }\n\n        // 2. Now assign actions, disallowing movement into \"will_wall\" cells!\n        for (int i = 0; i < M; ++i) {\n            auto& h = humans[i];\n            int cx=h.x, cy=h.y, xl=h.band_l, xr=h.band_r;\n            if (turn < phase_move) {\n                int destx=h.dest_x, desty=h.dest_y;\n                if (cx < destx && ins(cx+1,cy) && grid[cx+1][cy]=='.' && !will_wall[cx+1][cy]) actions[i]='D';\n                else if (cx > destx && ins(cx-1,cy) && grid[cx-1][cy]=='.' && !will_wall[cx-1][cy]) actions[i]='U';\n                else if (cy < desty && ins(cx,cy+1) && grid[cx][cy+1]=='.' && !will_wall[cx][cy+1]) actions[i]='R';\n                else if (cy > desty && ins(cx,cy-1) && grid[cx][cy-1]=='.' && !will_wall[cx][cy-1]) actions[i]='L';\n                continue;\n            }\n            bool did_wall=false;\n            for (int d=0; d<4 && !did_wall; ++d) {\n                int tx=cx+DX[d], ty=cy+DY[d];\n                if (!ins(tx,ty)) continue;\n                if (!(ty == xl-1 || ty == xr+1)) continue;\n                if (grid[tx][ty]!='.') continue;\n                if (human_grid[tx][ty]!=0 || pet_grid[tx][ty]!=0) continue;\n                bool safe=true;\n                for (int d2=0; d2<4; ++d2) {\n                    int nx=tx+DX[d2], ny=ty+DY[d2];\n                    if (ins(nx,ny)&&pet_grid[nx][ny]) {safe=false; break;}\n                }\n                if (safe&&!will_wall[tx][ty]) { actions[i]=WALLS[d]; did_wall=true; }\n            }\n            if (did_wall) continue;\n            if (cy < xl && ins(cx,cy+1) && grid[cx][cy+1]=='.' && !will_wall[cx][cy+1]) actions[i]='R';\n            else if (cy > xr && ins(cx,cy-1) && grid[cx][cy-1]=='.' && !will_wall[cx][cy-1]) actions[i]='L';\n        }\n        cout << actions << '\\n' << flush;\n\n        // Wall placements\n        for (int i = 0; i < M; ++i) {\n            int dir = get_dir_wall(actions[i]);\n            if (dir >= 0) {\n                int wx=humans[i].x+DX[dir], wy=humans[i].y+DY[dir];\n                if (ins(wx,wy)) grid[wx][wy]='#';\n            }\n        }\n        vector<string> pet_moves(N);\n        for (int i = 0; i < N; ++i) cin >> pet_moves[i];\n        for (int i = 0; i < M; ++i) {\n            int dir=get_dir_move(actions[i]), nx=humans[i].x, ny=humans[i].y;\n            if (dir>=0) {\n                nx+=DX[dir], ny+=DY[dir];\n                if (ins(nx,ny)&&grid[nx][ny]=='.'&& !will_wall[nx][ny]) {humans[i].x=nx; humans[i].y=ny;}\n            }\n        }\n        for (int i = 0; i < N; ++i) for (char c : pet_moves[i]) {\n            int dir=get_dir_move(c), nx=pets[i].x, ny=pets[i].y;\n            if (dir>=0) {\n                nx+=DX[dir]; ny+=DY[dir];\n                if (ins(nx,ny)&&grid[nx][ny]!='#') pets[i].x=nx,pets[i].y=ny;\n            }\n        }\n    }\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Directions: U, D, L, R\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst char DC[] = {'U', 'D', 'L', 'R'};\n\nstruct WallMap {\n    int h[20][19]; // right wall\n    int v[19][20]; // down wall\n    bool can_move(int i, int j, int dir) const {\n        if(dir==0) { // Up\n            if(i==0) return false;\n            return v[i-1][j]==0;\n        }\n        if(dir==1) { // Down\n            if(i==19) return false;\n            return v[i][j]==0;\n        }\n        if(dir==2) { // Left\n            if(j==0) return false;\n            return h[i][j-1]==0;\n        }\n        if(dir==3) { // Right\n            if(j==19) return false;\n            return h[i][j]==0;\n        }\n        return false;\n    }\n};\n\nvector<int> bfs_shortest_path(const WallMap &wm, int si, int sj, int gi, int gj) {\n    vector<vector<int>> dist(20, vector<int>(20, -1));\n    vector<vector<pair<int,int>>> prev(20, vector<pair<int,int>>(20, {-1,-1}));\n    queue<pair<int,int>> q;\n    dist[si][sj] = 0;\n    q.push({si, sj});\n    while(!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int d=0; d<4; ++d) {\n            if(!wm.can_move(i, j, d)) continue;\n            int ni = i + di[d], nj = j + dj[d];\n            if(dist[ni][nj] == -1) {\n                dist[ni][nj] = dist[i][j] + 1;\n                prev[ni][nj] = {i, j};\n                q.push({ni, nj});\n            }\n        }\n    }\n    vector<int> path;\n    int ci = gi, cj = gj;\n    if (dist[ci][cj] == -1) return {};\n    while (!(ci == si && cj == sj)) {\n        auto [pi, pj] = prev[ci][cj];\n        for (int d=0; d<4; ++d) if(pi+di[d]==ci && pj+dj[d]==cj && wm.can_move(pi, pj, d)) {\n            path.push_back(d);\n            break;\n        }\n        tie(ci, cj) = make_pair(pi, pj);\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nstring path_repeat_each(const vector<int>& path, int k, int total_limit) {\n    string ret;\n    for(int d: path) for(int rpt=0;rpt<k;++rpt) {\n        if((int)ret.size()<total_limit) ret+=DC[d];\n    }\n    while((int)ret.size() + (int)path.size()*k <= total_limit) {\n        for(int d: path) for(int rpt=0;rpt<k;++rpt) {\n            if((int)ret.size()<total_limit) ret+=DC[d];\n        }\n    }\n    return ret;\n}\n\nstring path_repeat_full(const vector<int>& path, int total_limit) {\n    string ret;\n    while((int)ret.size() + (int)path.size() <= total_limit) {\n        for(int d: path) {\n            if((int)ret.size()<total_limit) ret += DC[d];\n        }\n    }\n    while((int)ret.size()<total_limit && !path.empty()) {\n        ret += DC[path.back()];\n    }\n    return ret;\n}\n\n// \"Snake\" path: interleaved DRDR if shortest path is mostly D+R\nstring path_snake(const vector<int>& path, int total_limit) {\n    // Count D/R\n    int cntD=0, cntR=0;\n    for(int d: path) if(d==1)cntD++; else if(d==3)cntR++;\n    string ret;\n    int cD=0, cR=0;\n    while((int)ret.size()<total_limit && (cD<cntD || cR<cntR)) {\n        if(cD<cntD) { ret+='D'; cD++;}\n        if((int)ret.size()>=total_limit)break;\n        if(cR<cntR) { ret+='R'; cR++;}\n    }\n    // Repeat to fill\n    while((int)ret.size()+cntD+cntR<=total_limit) {\n        int tD=0,tR=0;\n        while((tD<cntD || tR<cntR) && (int)ret.size()<total_limit) {\n            if(tD<cntD) { ret+='D'; tD++;}\n            if((int)ret.size()>=total_limit)break;\n            if(tR<cntR) { ret+='R'; tR++;}\n        }\n    }\n    // Pad\n    while((int)ret.size()<total_limit) ret+='D';\n    return ret;\n}\n\n// Adaptive greedy BFS plan: at each move, from current position, plan to goal, take first step, repeat\nstring greedy_bfs_plan(const WallMap& wm, int si, int sj, int gi, int gj, int total_limit) {\n    int i=si, j=sj;\n    string ret;\n    for(int step=0;step<total_limit;++step) {\n        if(i==gi && j==gj) break;\n        vector<vector<int>> dist(20, vector<int>(20, -1));\n        vector<vector<int>> firstdir(20, vector<int>(20, -1));\n        queue<pair<int,int>> q;\n        dist[i][j]=0;\n        q.push({i,j});\n        firstdir[i][j] = -1;\n        while(!q.empty()) {\n            auto [ci,cj] = q.front(); q.pop();\n            for(int d=0;d<4;++d) {\n                if(!wm.can_move(ci,cj,d)) continue;\n                int ni=ci+di[d], nj=cj+dj[d];\n                if(dist[ni][nj]!=-1) continue;\n                dist[ni][nj]=dist[ci][cj]+1;\n                firstdir[ni][nj] = (dist[ci][cj]==0 ? d : firstdir[ci][cj]);\n                q.push({ni,nj});\n            }\n        }\n        if(dist[gi][gj]==-1) break; // unreachable\n        int move = firstdir[gi][gj];\n        if(move==-1) break;\n        ret+=DC[move];\n        // Simulate move (assume not forgotten, for plan)\n        if(wm.can_move(i,j,move)) { i+=di[move]; j+=dj[move]; }\n    }\n    // Pad with last move for roundness\n    if(!ret.empty()) while((int)ret.size()<total_limit) ret+=ret.back();\n    return ret;\n}\n\ndouble simulate(const WallMap& wm, int si, int sj, int gi, int gj, double p, const string& route, int runs=1500) {\n    mt19937_64 rng(7171717); // fixed seed\n    uniform_real_distribution<> rd(0, 1);\n    double sum = 0;\n    for(int it=0;it<runs;++it) {\n        int i = si, j = sj, t=0;\n        bool reached = false;\n        for(t=1; t<=(int)route.size(); ++t) {\n            if(i==gi && j==gj) {reached=true; break;}\n            double coin = rd(rng);\n            if(coin < p) {\n                // Forget: do nothing\n            } else {\n                int d = -1;\n                for(int k=0;k<4;++k) if(route[t-1]==DC[k]){d=k;break;}\n                if(wm.can_move(i,j,d)) {\n                    i += di[d], j += dj[d];\n                }\n            }\n            if(i==gi && j==gj) {reached=true; break;}\n        }\n        if(i==gi && j==gj) {reached=true;}\n        if(reached) sum += (401 - t + (i==gi && j==gj ? 0 : 1));\n    }\n    return sum / runs;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n\n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n    WallMap wm;\n    for (int i=0;i<20;++i) for (int j=0;j<19;++j) {\n        char c; cin >> c;\n        wm.h[i][j] = c-'0';\n    }\n    for (int i=0;i<19;++i) for (int j=0;j<20;++j) {\n        char c; cin >> c;\n        wm.v[i][j] = c-'0';\n    }\n\n    auto spath = bfs_shortest_path(wm, si, sj, ti, tj);\n    int route_limit = 200;\n\n    vector<pair<double, string>> candidates;\n\n    // Candidate 1: Repeat full shortest path\n    string c1 = path_repeat_full(spath, route_limit);\n    candidates.emplace_back(simulate(wm, si, sj, ti, tj, p, c1, 1000), c1);\n\n    // Candidate 2: Repeat each move 2x\n    if(spath.size()*2 <= route_limit) {\n        string c2 = path_repeat_each(spath, 2, route_limit);\n        candidates.emplace_back(simulate(wm, si, sj, ti, tj, p, c2, 1000), c2);\n    }\n    // Candidate 3: Repeat each move 3x\n    if(spath.size()*3 <= route_limit) {\n        string c3 = path_repeat_each(spath, 3, route_limit);\n        candidates.emplace_back(simulate(wm, si, sj, ti, tj, p, c3, 1000), c3);\n    }\n    // Candidate 4: \"Snake path\" (DRDR), only for nearly axis-aligned path and short ones\n    int Ds = 0, Rs = 0, Ls = 0, Us = 0;\n    for(int d: spath) switch(d){case 0:Us++;break;case 1:Ds++;break;case 2:Ls++;break;case 3:Rs++;break;}\n    if((Us==0||Ds==0) && (Ls==0||Rs==0)) { // axis-aligned\n        string c4 = path_snake(spath, route_limit);\n        candidates.emplace_back(simulate(wm, si, sj, ti, tj, p, c4, 1000), c4);\n    }\n    // Candidate 5: Greedy BFS replanner\n    string c5 = greedy_bfs_plan(wm, si, sj, ti, tj, route_limit);\n    candidates.emplace_back(simulate(wm, si, sj, ti, tj, p, c5, 700), c5); // simulation heavier, use fewer runs\n\n    // Pick the best\n    auto [_, bestroute] = *max_element(candidates.begin(), candidates.end());\n    cout << bestroute << endl;\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 30;\nconst int di[4] = {0, -1, 0, 1};   // left, up, right, down\nconst int dj[4] = {-1, 0, 1, 0};\nconst int to[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1},\n};\n\nint realType(int t, int r) {\n    if (t <= 3) return (t + r) % 4;\n    else if (t == 4) return r % 2 == 0 ? 4 : 5;\n    else if (t == 5) return r % 2 == 0 ? 5 : 4;\n    else if (t == 6) return r % 2 == 0 ? 6 : 7;\n    else /* t == 7 */ return r % 2 == 0 ? 7 : 6;\n}\n\nvector<int> get_loops(const vector<vector<int>>& tile_types, const vector<vector<int>>& rotations) {\n    int st[N][N];\n    for (int i = 0; i < N; i++)\n    for (int j = 0; j < N; j++)\n        st[i][j] = realType(tile_types[i][j], rotations[i][j]);\n    bool visited[N][N][4] = {};\n    vector<int> loop_lengths;\n\n    for (int i = 0; i < N; i++)\n    for (int j = 0; j < N; j++)\n    for (int d = 0; d < 4; d++) {\n        if (visited[i][j][d]) continue;\n        int ci = i, cj = j, cd = d, len = 0;\n        while (true) {\n            if (visited[ci][cj][cd]) break;\n            visited[ci][cj][cd] = true;\n            int nd = to[st[ci][cj]][cd];\n            if (nd == -1) break;\n            int ni = ci + di[nd], nj = cj + dj[nd];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) break;\n            cd = (nd + 2) % 4;\n            ci = ni;\n            cj = nj;\n            len++;\n            if (ci == i && cj == j && cd == d) {\n                loop_lengths.push_back(len);\n                break;\n            }\n        }\n    }\n    sort(loop_lengths.rbegin(), loop_lengths.rend());\n    return loop_lengths;\n}\n\nvector<vector<bool>> force_rect_border_loop(int L, int R, int T, int B,\n    const vector<vector<int>>& type, vector<vector<int>>& rot) {\n    vector<vector<bool>> used(N, vector<bool>(N, false));\n    vector<pair<int,int>> path;\n    if (R - L < 2 || B - T < 2) return used;\n    for (int j = L; j < R - 1; ++j) path.emplace_back(T, j);\n    for (int i = T; i < B - 1; ++i) path.emplace_back(i, R - 1);\n    for (int j = R - 1; j > L; --j) path.emplace_back(B - 1, j);\n    for (int i = B - 1; i > T; --i) path.emplace_back(i, L);\n\n    int pathlen = path.size();\n    for (int pos = 0; pos < pathlen; ++pos) {\n        auto [i, j] = path[pos];\n        used[i][j] = true;\n        auto [pi, pj] = path[(pos - 1 + pathlen) % pathlen];\n        int into_dir = -1;\n        if (pi == i - 1 && pj == j) into_dir = 1;\n        else if (pi == i + 1 && pj == j) into_dir = 3;\n        else if (pi == i && pj == j - 1) into_dir = 0;\n        else if (pi == i && pj == j + 1) into_dir = 2;\n        auto [ni, nj] = path[(pos + 1) % pathlen];\n        int out_dir = -1;\n        if (ni == i - 1 && nj == j) out_dir = 1;\n        else if (ni == i + 1 && nj == j) out_dir = 3;\n        else if (ni == i && nj == j - 1) out_dir = 0;\n        else if (ni == i && nj == j + 1) out_dir = 2;\n        int best_rot = -1;\n        for (int r = 0; r < 4; ++r) {\n            int nt = realType(type[i][j], r);\n            int t_out = to[nt][into_dir];\n            if (t_out == out_dir) {\n                best_rot = r; break;\n            }\n        }\n        if (best_rot == -1) {\n            for (int r = 0; r < 4; ++r) {\n                int nt = realType(type[i][j], r);\n                if (to[nt][into_dir] != -1 || to[nt][out_dir] != -1) {\n                    best_rot = r; break;\n                }\n            }\n        }\n        if (best_rot == -1) best_rot = 0;\n        rot[i][j] = best_rot;\n    }\n    return used;\n}\n\nvoid greedy_fit_rotations(const vector<vector<int>>& type, vector<vector<int>>& rot, const vector<vector<bool>>& forced) {\n    for (int sweep = 0; sweep < 7; ++sweep) { // more sweeps for better propagation\n        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) {\n            if (forced[i][j]) continue;\n            int best = -1, bestr = 0;\n            for (int r = 0; r < 4; ++r) {\n                int nt = realType(type[i][j], r);\n                int connect = 0;\n                for (int d = 0; d < 4; ++d) {\n                    int nd = to[nt][d];\n                    if (nd == -1) continue;\n                    int ni = i + di[nd], nj = j + dj[nd];\n                    if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                    int backdir = (nd + 2) % 4;\n                    int neighbor_type = type[ni][nj];\n                    int neighbor_rot = rot[ni][nj];\n                    int neighbor_real = realType(neighbor_type, neighbor_rot);\n                    if (to[neighbor_real][backdir] != -1) {\n                        connect++;\n                    }\n                }\n                if (connect > best || (connect == best && rand() % 2)) {\n                    best = connect; bestr = r;\n                }\n            }\n            rot[i][j] = bestr;\n        }\n    }\n}\n\nvector<vector<int>> try_partitioned_loops(const vector<vector<int>>& type) {\n    vector<vector<int>> rot_best(N, vector<int>(N, 0));\n    int best_score = 0;\n\n    // Try vertical split: left half [0,14], right half [15,29]\n    {\n        vector<vector<int>> rot(N, vector<int>(N, 0));\n        vector<vector<bool>> forced(N, vector<bool>(N, false));\n        auto left_forced = force_rect_border_loop(0, N / 2, 0, N, type, rot);\n        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j)\n            forced[i][j] = forced[i][j] || left_forced[i][j];\n        auto right_forced = force_rect_border_loop(N / 2, N, 0, N, type, rot);\n        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j)\n            forced[i][j] = forced[i][j] || right_forced[i][j];\n        greedy_fit_rotations(type, rot, forced);\n\n        auto loops = get_loops(type, rot);\n        int score = 0;\n        if (loops.size() >= 2) score = loops[0] * loops[1];\n\n        if (score > best_score) {\n            best_score = score;\n            rot_best = rot;\n        }\n    }\n    {\n        vector<vector<int>> rot(N, vector<int>(N, 0));\n        vector<vector<bool>> forced(N, vector<bool>(N, false));\n        auto top_forced = force_rect_border_loop(0, N, 0, N / 2, type, rot);\n        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j)\n            forced[i][j] = forced[i][j] || top_forced[i][j];\n        auto bottom_forced = force_rect_border_loop(0, N, N / 2, N, type, rot);\n        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j)\n            forced[i][j] = forced[i][j] || bottom_forced[i][j];\n        greedy_fit_rotations(type, rot, forced);\n\n        auto loops = get_loops(type, rot);\n        int score = 0;\n        if (loops.size() >= 2) score = loops[0] * loops[1];\n\n        if (score > best_score) {\n            best_score = score;\n            rot_best = rot;\n        }\n    }\n    // Try concentric border frames\n    {\n        vector<vector<int>> rot(N, vector<int>(N, 0));\n        vector<vector<bool>> forced(N, vector<bool>(N, false));\n        for (int border = 0; border <= N / 2 - 2; ++border) {\n            int L = border, R = N - border, T = border, B = N - border;\n            auto frame_forced = force_rect_border_loop(L, R, T, B, type, rot);\n            int border_count = 2 * (R-L + B-T) - 4;\n            int actual_filled = 0;\n            for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j)\n                if (frame_forced[i][j]) actual_filled++;\n            if ((3*actual_filled >= 2*border_count)) {\n                for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j)\n                    forced[i][j] = forced[i][j] || frame_forced[i][j];\n            } else {\n                break;\n            }\n        }\n        greedy_fit_rotations(type, rot, forced);\n\n        auto loops = get_loops(type, rot);\n        int score = 0;\n        if (loops.size() >= 2) score = loops[0] * loops[1];\n        if (score > best_score) {\n            best_score = score;\n            rot_best = rot;\n        }\n    }\n    if (best_score == 0) {\n        vector<vector<int>> rot(N, vector<int>(N, 0));\n        vector<vector<bool>> forced(N, vector<bool>(N, false));\n        greedy_fit_rotations(type, rot, forced);\n        rot_best = rot;\n    }\n    return rot_best;\n}\n\n// --- HILL CLIMB OPTIMIZATION (NEW) --- //\nvoid local_hillclimb(vector<vector<int>>& rot, const vector<vector<int>>& type, int steps = 3) {\n    auto score_func = [&](const vector<vector<int>>& rot) -> int {\n        auto loops = get_loops(type, rot);\n        if (loops.size() < 2) return 0;\n        return loops[0] * loops[1];\n    };\n    int cur_score = score_func(rot);\n\n    for (int sweep = 0; sweep < steps; ++sweep) {\n        bool improved = false;\n        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) {\n            int bestr = rot[i][j];\n            int bestscore = cur_score;\n            for (int r = 0; r < 4; ++r) {\n                if (r == rot[i][j]) continue;\n                int old = rot[i][j];\n                rot[i][j] = r;\n                int s = score_func(rot);\n                if (s > bestscore) {\n                    bestscore = s;\n                    bestr = r;\n                }\n                rot[i][j] = old;\n            }\n            if (bestr != rot[i][j]) {\n                rot[i][j] = bestr;\n                cur_score = bestscore;\n                improved = true;\n            }\n        }\n        if (!improved) break;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<vector<int>> type(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        string s; cin >> s;\n        for (int j = 0; j < N; j++)\n            type[i][j] = s[j] - '0';\n    }\n\n    srand((unsigned)time(0));\n\n    auto rot = try_partitioned_loops(type);\n    // FINAL STEP: local hill climbing\n    local_hillclimb(rot, type, 2); // 2 passes is a decent contest tradeoff\n\n    auto loop_lengths = get_loops(type, rot);\n    int score = 0;\n    if (loop_lengths.size() >= 2)\n        score = loop_lengths[0] * loop_lengths[1];\n\n    cerr << \"Top loops: \";\n    for (int i = 0; i < min(5, int(loop_lengths.size())); ++i)\n        cerr << loop_lengths[i] << \" \";\n    cerr << \"Score = \" << score << endl;\n\n    string out;\n    out.reserve(N*N);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            out += char('0' + rot[i][j]);\n    cout << out << endl;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nusing pii = pair<int,int>;\n\nchrono::high_resolution_clock::time_point time_start;\ndouble elapsed_sec() {\n    auto t = chrono::high_resolution_clock::now();\n    return chrono::duration<double>(t - time_start).count();\n}\n\n// Directions: UDLR\nconst int dr[] = {-1, 1, 0, 0};\nconst int dc[] = {0, 0, -1, 1};\nconst char dir_char[] = {'U','D','L','R'};\nconst int opp_dir[] = {1,0,3,2};\nconst int bit[] = {1<<1,1<<3,1<<0,1<<2}; // up,down,left,right\n\nstruct Board {\n    int N;\n    vector<vector<int>> grid;\n    pii empty; // (r,c) position of the empty cell\n\n    Board(int N_): N(N_), grid(N, vector<int>(N)) {}\n    Board(const Board &o): N(o.N), grid(o.grid), empty(o.empty) {}\n\n    void read_input() {\n        for(int i=0; i<N; ++i) {\n            string s; cin >> s;\n            for(int j=0; j<N; ++j) {\n                char ch = s[j];\n                if(ch=='0') {\n                    grid[i][j]=0;\n                    empty = {i,j};\n                } else if(isdigit(ch)) {\n                    grid[i][j] = ch-'0';\n                } else {\n                    grid[i][j] = ch-'a'+10;\n                }\n            }\n        }\n    }\n\n    // Can we move in dir d (U/D/L/R)?\n    bool can_move(int d) const {\n        int er = empty.first, ec = empty.second;\n        int nr = er + dr[d], nc = ec + dc[d];\n        return nr>=0 && nr<N && nc>=0 && nc<N;\n    }\n\n    // Do the move in dir d. Assumes move is legal.\n    void do_move(int d) {\n        int er = empty.first, ec = empty.second;\n        int nr = er + dr[d], nc = ec + dc[d];\n        swap(grid[er][ec], grid[nr][nc]);\n        empty = {nr, nc};\n    }\n\n    // For performance, do undo_move doesn't need to be tracked if not required yet.\n};\n\nstruct DSU {\n    vector<int> par, siz;\n    DSU(int n): par(n), siz(n,1) { iota(par.begin(), par.end(), 0); }\n    int find(int x) { return par[x]==x ? x : par[x]=find(par[x]); }\n    bool unite(int x,int y) {\n        x = find(x); y = find(y);\n        if(x==y) return false;\n        if(siz[x]<siz[y]) swap(x,y);\n        par[y]=x; siz[x]+=siz[y];\n        return true;\n    }\n    int size(int x) { return siz[find(x)]; }\n};\n\nstruct TreeChecker {\n    // Build a graph of non-empty tiles, with edges as problem states,\n    // Then find the largest connected component which is also acyclic\n\n    int N;\n    vector<vector<int>> grid;\n    vector<vector<int>> idmap; // for mapping (i,j) to node ids, since one cell is empty\n\n    TreeChecker(const vector<vector<int>> &g): N(g.size()), grid(g) {\n        // Build idmap: -1 for empty, else unique 0...(N*N-2)\n        idmap.assign(N, vector<int>(N,-1));\n        int id=0;\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++) {\n            if(grid[i][j]!=0) idmap[i][j]=id++;\n        }\n    }\n\n    // Returns (largest tree size)\n    int get_largest_tree_size() {\n        int nn = N*N-1;\n        vector<vector<int>> G(nn);\n        // Build undirected edge list\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++) {\n            if(grid[i][j]==0) continue;\n            int t = grid[i][j];\n            int id1 = idmap[i][j];\n            // down\n            if((t&8) && i+1<N && grid[i+1][j]!=0 && (grid[i+1][j]&2))\n                G[id1].push_back(idmap[i+1][j]);\n            // right\n            if((t&4) && j+1<N && grid[i][j+1]!=0 && (grid[i][j+1]&1))\n                G[id1].push_back(idmap[i][j+1]);\n            // (U/L can reverse edge but already covered)\n        }\n        // Find largest connected acyclic component: for each CC, check if no cycles (tree), report largest\n        int res=0;\n        vector<int> vis(nn,0);\n        for(int i=0;i<nn;i++) {\n            if(vis[i]) continue;\n            int size=0, edges=0;\n            bool is_tree=true;\n            function<void(int,int)> dfs=[&](int u, int p){\n                vis[u]=1; size++;\n                for(int v:G[u]) {\n                    if(v==p) continue;\n                    edges++;\n                    if(vis[v]) is_tree=false;\n                    else dfs(v, u);\n                }\n            };\n            dfs(i,-1);\n            if(is_tree && edges/2==size-1) res=max(res,size); // undirected: edges double-counted\n        }\n        return res;\n    }\n};\n\nint main() {\n    time_start = chrono::high_resolution_clock::now();\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T;\n    cin >> N >> T;\n    Board board(N);\n    board.read_input();\n\n    // Naive strategy: try random walks and keep the best\n    string best_moves;\n    int best_score = 0;\n    Board best_board = board;\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    int try_limit = 1500;   // Control based on validated time!\n    int walk_len = min(T, 200); // Try short walks first, might help\n\n    for(int t=0; t<try_limit; ++t) {\n        Board cur_board = board;\n        vector<int> move_hist;\n        string moves = \"\";\n        int prev_move = -1;\n        for(int k=0; k<walk_len; ++k) {\n            // Random legal move, avoid undoing previous\n            vector<int> can_moves;\n            for(int d=0; d<4; ++d) {\n                if( d != opp_dir[prev_move] && cur_board.can_move(d))\n                    can_moves.push_back(d);\n            }\n            if(can_moves.empty()) break;\n            int mv = can_moves[ rng() % can_moves.size() ];\n            cur_board.do_move(mv);\n            moves += dir_char[mv];\n            prev_move = mv;\n        }\n        // Compute score\n        TreeChecker tc(cur_board.grid);\n        int S = tc.get_largest_tree_size();\n        if(S>best_score || (S==best_score && (int)moves.size()<best_moves.size())) {\n            best_score = S;\n            best_moves = moves;\n            best_board = cur_board;\n        }\n        // Time management (1.8sec safety)\n        if(elapsed_sec() > 1.8) break;\n    }\n\n    // Output\n    cout << best_moves << \"\\n\";\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing P = pair<int, int>;\nusing ll = long long;\nconst double PI = acos(-1.0);\nconst int CAKE_RADIUS = 10000;\nconst int K = 100;\n\nstruct Strawberry {\n    int x, y;\n    int idx; // original id\n};\n\nstruct Line {\n    // Represent by ax + by + c = 0\n    // Or two points (px, py), (qx, qy)\n    int px, py, qx, qy;\n};\n\nstruct Piece {\n    vector<int> strawberry_idxs;\n};\n\nint N, K_input;\nvector<int> a; // a[1..10]\nvector<Strawberry> strawberries;\nvector<Line> cuts;\n\n// For bipartition: Given indices of strawberries, try to partition into sizes d and n-d\n// Return (success, (indices in side A, indices in side B), Line to cut by)\ntuple<bool, vector<int>, vector<int>, Line>\nbipartition(const vector<int>& idxs, int d, const vector<Strawberry>& strawbs, mt19937 &rng) {\n    int n = idxs.size();\n    if (n < d || d == 0 || d == n) return {false, {}, {}, {}};\n    vector<pair<double,int>> project(n); // (projection, index in idxs)\n    vector<double> directions;\n    const int tries = 20;\n    uniform_real_distribution<double> angle_dist(0, PI);\n    for(int attempt = 0; attempt < tries; ++attempt) {\n        double ang = angle_dist(rng);\n        double dx = cos(ang), dy = sin(ang);\n        for(int i = 0; i < n; ++i) {\n            const auto &s = strawbs[idxs[i]];\n            project[i] = {s.x*dx + s.y*dy, i};\n        }\n        sort(project.begin(), project.end());\n        // Try split after d-1 points (left: [0,d-1], right: [d,n-1])\n        double cut_left = project[d-1].first;\n        double cut_right = project[d].first;\n        double cut_proj = (cut_left + cut_right) / 2.0; // split position at midpoint\n        // Find two points on this line\n        // For simplicity, pick a point within cake in direction orthogonal to (dx,dy)\n        // e.g., normal vector (-dy, dx)\n        double nx = -dy, ny = dx;\n        // Pick p0 at (0,0) + cake_radius * (nx, ny)\n        double p0x = nx * CAKE_RADIUS, p0y = ny * CAKE_RADIUS;\n        double p1x = -nx * CAKE_RADIUS, p1y = -ny * CAKE_RADIUS;\n        // Shift line along (dx,dy) by cut_proj units: move origin along (dx,dy)\n        p0x += dx * cut_proj;\n        p0y += dy * cut_proj;\n        p1x += dx * cut_proj;\n        p1y += dy * cut_proj;\n        // Round to integer points in [-1e9,1e9]\n        auto clamp = [](double v) -> int64_t {\n            const ll M = 1000000000LL;\n            if (v > M) return M;\n            if (v < -M) return -M;\n            return static_cast<ll>(round(v));\n        };\n        ll px = clamp(p0x), py = clamp(p0y), qx = clamp(p1x), qy = clamp(p1y);\n\n        // Now assign to sides: those with projection < cut_proj on one side, others on other\n        vector<int> A, B;\n        for(int i = 0; i < n; ++i) {\n            int sidx = idxs[project[i].second];\n            if (project[i].first < cut_proj) A.push_back(sidx);\n            else if (project[i].first > cut_proj) B.push_back(sidx);\n            else {\n                // projection == cut_proj:\n                // Looks like a double point, but in practice, can assign to either cake side\n                // Just assign to B for safety (as cut_proj is mid of two projections)\n                B.push_back(sidx);\n            }\n        }\n        // If any strawberry happens to be exactly ON the line, abort this cut\n        // Check for each strawberry:\n        double eps = 1e-8;\n        bool on_cut = false;\n        for(int i = 0; i < n; ++i) {\n            if (abs(project[i].first - cut_proj) < eps) {\n                // A strawberry would be lost; try a new direction\n                on_cut = true;\n                break;\n            }\n        }\n        if (on_cut) continue;\n        // Now, can get exact d in A or B depending on ordering:\n        if (A.size() == d || B.size() == d) {\n            if (A.size() == d) {\n                return {true, A, B, Line{(int)px, (int)py, (int)qx, (int)qy}};\n            } else {\n                return {true, B, A, Line{(int)px, (int)py, (int)qx, (int)qy}};\n            }\n        }\n    }\n    // no suitable split found\n    return {false, {}, {}, {}};\n}\n\nint main(){\n    ios::sync_with_stdio(false); cin.tie(0);\n    cin >> N >> K_input;\n    a.resize(11);\n    int Ncheck = 0;\n    for(int d=1;d<=10; ++d) {\n        cin >> a[d];\n        Ncheck += d * a[d];\n    }\n    strawberries.resize(N);\n    for(int i=0;i<N;++i){\n        int x, y; cin >> x >> y;\n        strawberries[i] = {x, y, i};\n    }\n    // Bookkeeping for pieces:\n    vector<vector<int>> pieces; // each as vector of strawberry indices\n    pieces.push_back(vector<int>(N));\n    iota(pieces[0].begin(), pieces[0].end(), 0);\n\n    // For each d from 10 downto 1 (focus on large pieces first)\n    // Alternatively, weighted by number required; for now, 10..1\n    int remains[11];\n    for(int d=1;d<=10;++d) remains[d]=a[d];\n\n    mt19937 rng(123456 + chrono::steady_clock::now().time_since_epoch().count());\n\n    // For cuts\n    vector<Line> used_cuts;\n\n    // For pieces: maintain multiset by size (for quickly finding suitable ones)\n    // Actually, not necessary for up to 1000 pieces\n\n    // Map: pieces_to_process[d]: indices of pieces of size >= d, and not yet processed\n    // We'll go for greedy: for d from 10..1, try to split pieces down\n    // For now, do as explained: try to generate as many pieces of size d as a[d]\n    for(int d=10; d>=1; --d) {\n        int need = remains[d];\n        if(need == 0) continue;\n        // Look for pieces with size >= d\n        // For each round:\n        bool found;\n        int attempts = 0;\n        while(need > 0) {\n            found = false;\n            for(int pi=0; pi<pieces.size(); ++pi) {\n                vector<int> &piece = pieces[pi];\n                if ((int)piece.size() > d) {\n                    // Try bipartition this piece into d and n-d\n                    auto [ok, groupA, groupB, line] = bipartition(piece, d, strawberries, rng);\n                    if(ok) {\n                        // Accept this cut, add it to cuts\n                        used_cuts.push_back(line);\n                        // Remove piece, add groupA, groupB instead\n                        piece = move(groupA);\n                        pieces.push_back(move(groupB));\n                        // Mark found\n                        found = true;\n                        --need;\n                        break; // do next need\n                    }\n                }\n            }\n            if(!found) break; // Could not perform more for this d\n            if((int)used_cuts.size() >= K) break;\n            ++attempts;\n            if(attempts > 1000) break; // Give up (should not be needed)\n        }\n        if((int)used_cuts.size() >= K) break;\n    }\n\n    // Now, after all splits, count how many pieces of each size, up to a[d] per attendee\n    vector<int> cnt(11, 0);\n    for(const auto &piece: pieces) {\n        int sz = piece.size();\n        if(sz >= 1 && sz <= 10) cnt[sz]++;\n    }\n    int total_given = 0;\n    for(int d=1;d<=10;++d) total_given += min(a[d], cnt[d]);\n    // Output cuts\n    int k_out = used_cuts.size();\n    cout << k_out << \"\\n\";\n    for(const auto &line : used_cuts) {\n        cout << line.px << \" \" << line.py << \" \" << line.qx << \" \" << line.qy << \"\\n\";\n    }\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nusing pii = pair<int, int>;\n\nconstexpr int DX[4] = {1, 0, -1, 0};\nconstexpr int DY[4] = {0, 1, 0, -1};\n\nstruct Edge {\n    int x1, y1, x2, y2;\n    Edge(int a,int b,int c,int d) {\n        if (pii(a, b) < pii(c, d)) {\n            x1 = a; y1 = b; x2 = c; y2 = d;\n        } else {\n            x1 = c; y1 = d; x2 = a; y2 = b;\n        }\n    }\n    bool operator < (const Edge& o) const {\n        return tie(x1,y1,x2,y2) < tie(o.x1,o.y1,o.x2,o.y2);\n    }\n};\n\nint N,M;\nvector<vector<int>> board; // 0: empty, 1: dot placed during play, 2: initial dot\nset<pii> dots; // occupied\nset<Edge> used_edges; // segments of perimeters\n\nvector<vector<ll>> weights;\nll S = 0;\nint CENTER;\nvector<array<int,8>> moves;\n\nvoid input() {\n    cin >> N >> M;\n    board.assign(N, vector<int>(N, 0));\n    for (int i = 0; i < M; ++i) {\n        int x,y;\n        cin >> x >> y;\n        board[x][y] = 2;\n        dots.emplace(x, y);\n    }\n    CENTER = (N-1)/2;\n    \n    weights.assign(N, vector<ll>(N, 0));\n    S = 0;\n    for (int x=0; x<N; ++x)\n        for (int y=0; y<N; ++y) {\n            weights[x][y] = (x-CENTER)*(x-CENTER) + (y-CENTER)*(y-CENTER) + 1;\n            S += weights[x][y];\n        }\n}\n\nbool is_valid(int x, int y) {\n    return x>=0 && x<N && y>=0 && y<N;\n}\n\n// For each empty cell, try all rectangles for which it can be one corner, with 3 dots as the other 3 corners\n// Return all candidate rectangles (with highest scoring p1 positions first)\nvector<array<int,8>> find_candidate_moves() {\n    vector<tuple<ll, array<int,8>>> candidates; // score, move\n    // To avoid too much computation, consider only shells near frontier\n    // Let's try to consider all for now (limit time if slow)\n    for (int x1=0; x1<N; ++x1) for (int y1=0; y1<N; ++y1) {\n        if (board[x1][y1] != 0) continue;\n        // For axis-aligned rectangles\n        for (auto& [dx,dy] : vector<pair<int,int>>{{1,0},{0,1}}) {\n            for (int len=1; len<=min(N-1,7); ++len) {\n                int x2 = x1+dx*len, y2 = y1+dy*len;\n                int x4 = x1+dy*len, y4 = y1-dx*len;\n                int x3 = x2+dy*len, y3 = y2-dx*len;\n                if (!is_valid(x2,y2) || !is_valid(x3,y3) || !is_valid(x4,y4)) continue;\n\n                array<pii,4> pts = {pii(x1,y1), pii(x2,y2), pii(x3,y3), pii(x4,y4)};\n                vector<int> ids = {0,1,2,3};\n\n                // try all 3 choose 3 for which the other three points have dots\n                vector<int> dot_idx;\n                for (int i=1; i<4; ++i) if (dots.count(pts[i])) dot_idx.push_back(i);\n                if ((int)dot_idx.size()<3) continue;\n                // Choose all three-point combinations (should be just one for axis-aligned)\n                for (int p=0; p<3; ++p) {\n                    int i2=dot_idx[p%3], i3=dot_idx[(p+1)%3], i4=dot_idx[(p+2)%3];\n                    array<int,8> move = {pts[0].first, pts[0].second, \n                        pts[i2].first, pts[i2].second,\n                        pts[i3].first, pts[i3].second,\n                        pts[i4].first, pts[i4].second\n                    };\n                    // check that the perimeter (except at corners) is empty and doesn't overlap a previous rect's segment\n                    vector<pii> perim = {pts[0], pts[i2], pts[i3], pts[i4]};\n                    bool ok = true;\n                    int sz = (int)perim.size();\n                    // check dots on perimeter but not at corners\n                    for (int j=0; j<sz; ++j) {\n                        int xA=perim[j].first, yA=perim[j].second;\n                        int xB=perim[(j+1)%sz].first, yB=perim[(j+1)%sz].second;\n                        int dx = (xB-xA)?((xB-xA)/abs(xB-xA)):0, dy = (yB-yA)?((yB-yA)/abs(yB-yA)):0;\n                        for (int xm = xA+dx, ym = yA+dy; \n                             xm!=xB||ym!=yB; xm+=dx, ym+=dy) {\n                            if (dots.count({xm, ym})) { ok=false; break; }\n                        }\n                        // Check perimeter overlap\n                        Edge e(xA,yA,xB,yB);\n                        if (used_edges.count(e)) { ok=false; break;}\n                    }\n                    if (ok) {\n                        candidates.emplace_back(weights[x1][y1], move);\n                    }\n                }\n            }\n        }\n        // 45-degree (diamond) rectangles\n        // For d=1 to limit (side increases as sqrt(2)*d)\n        for (int dx=1; dx<=6; ++dx) { // side length (sqrt(2)*dx)\n            int x2 = x1+dx, y2=y1+dx;\n            int x3 = x1, y3 = y1+2*dx;\n            int x4=x1-dx, y4=y1+dx;\n            if (!is_valid(x2,y2)||!is_valid(x3,y3)||!is_valid(x4,y4)) continue;\n            array<pii,4> pts = {pii(x1,y1), pii(x2,y2), pii(x3,y3), pii(x4,y4)};\n            // check that other three are dots\n            vector<int> dot_idx;\n            for (int i=1; i<4; ++i) if (dots.count(pts[i])) dot_idx.push_back(i);\n            if ((int)dot_idx.size()<3) continue;\n            for (int p=0; p<3; ++p) {\n                int i2=dot_idx[p%3], i3=dot_idx[(p+1)%3], i4=dot_idx[(p+2)%3];\n                array<int,8> move = {pts[0].first, pts[0].second, \n                    pts[i2].first, pts[i2].second,\n                    pts[i3].first, pts[i3].second,\n                    pts[i4].first, pts[i4].second\n                };\n                // perimeter check\n                vector<pii> perim = {pts[0], pts[i2], pts[i3], pts[i4]};\n                bool ok = true;\n                int sz = (int)perim.size();\n                for (int j=0; j<sz; ++j) {\n                    int xA=perim[j].first, yA=perim[j].second;\n                    int xB=perim[(j+1)%sz].first, yB=perim[(j+1)%sz].second;\n                    int dx = (xB-xA)?((xB-xA)/abs(xB-xA)):0, dy = (yB-yA)?((yB-yA)/abs(yB-yA)):0;\n                    for (int xm = xA+dx, ym = yA+dy; xm!=xB||ym!=yB; xm+=dx, ym+=dy) {\n                        if (dots.count({xm, ym})) { ok=false; break; }\n                    }\n                    // Check perimeter overlap\n                    Edge e(xA,yA,xB,yB);\n                    if (used_edges.count(e)) { ok=false; break;}\n                }\n                if (ok) {\n                    candidates.emplace_back(weights[x1][y1], move);\n                }\n            }\n        }\n    }\n    sort(candidates.rbegin(), candidates.rend()); // High weight to low weight\n    vector<array<int,8>> res;\n    for (auto& [score,move] : candidates) res.push_back(move);\n    return res;\n}\n\nvoid make_move(const array<int,8>& mv) {\n    int x1=mv[0], y1=mv[1];\n    int x2=mv[2], y2=mv[3];\n    int x3=mv[4], y3=mv[5];\n    int x4=mv[6], y4=mv[7];\n    board[x1][y1]=1;\n    dots.emplace(x1,y1);\n    // Mark used segments\n    vector<pii> pts = {pii(x1,y1), pii(x2,y2), pii(x3,y3), pii(x4,y4)};\n    int sz = (int)pts.size();\n    for (int i=0;i<sz;++i) {\n        int xA=pts[i].first, yA=pts[i].second;\n        int xB=pts[(i+1)%sz].first, yB=pts[(i+1)%sz].second;\n        used_edges.insert(Edge(xA,yA,xB,yB));\n    }\n    moves.push_back(mv);\n}\n\n// Main solve\nvoid solve() {\n    while (true) {\n        vector<array<int,8>> cands = find_candidate_moves();\n        if (cands.empty()) break;\n        // Pick the best (highest weight gain)\n        make_move(cands[0]);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    input();\n    solve();\n    cout << moves.size() << \"\\n\";\n    for (auto& mv : moves) {\n        for (int i=0; i<8; ++i) cout << mv[i] << \" \";\n        cout << \"\\n\";\n    }\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <array>\n#include <algorithm>\n#include <queue>\n#include <cassert>\n\nusing namespace std;\n\nconstexpr int N = 10;\nusing Board = array<array<int, N>, N>;\nusing Pos = pair<int, int>;\n\nvoid flush() { cout << flush; }\n\nvoid move_board(Board& board, char dir) {\n    if (dir == 'F') {\n        for (int x = 0; x < N; x++) {\n            int write = 0;\n            for (int y = 0; y < N; y++) {\n                if (board[y][x] != 0) {\n                    if (write != y) {\n                        board[write][x] = board[y][x];\n                        board[y][x] = 0;\n                    }\n                    write++;\n                }\n            }\n        }\n    } else if (dir == 'B') {\n        for (int x = 0; x < N; x++) {\n            int write = N - 1;\n            for (int y = N - 1; y >= 0; --y) {\n                if (board[y][x] != 0) {\n                    if (write != y) {\n                        board[write][x] = board[y][x];\n                        board[y][x] = 0;\n                    }\n                    write--;\n                }\n            }\n        }\n    } else if (dir == 'L') {\n        for (int y = 0; y < N; y++) {\n            int write = 0;\n            for (int x = 0; x < N; x++) {\n                if (board[y][x] != 0) {\n                    if (write != x) {\n                        board[y][write] = board[y][x];\n                        board[y][x] = 0;\n                    }\n                    write++;\n                }\n            }\n        }\n    } else if (dir == 'R') {\n        for (int y = 0; y < N; y++) {\n            int write = N - 1;\n            for (int x = N - 1; x >= 0; --x) {\n                if (board[y][x] != 0) {\n                    if (write != x) {\n                        board[y][write] = board[y][x];\n                        board[y][x] = 0;\n                    }\n                    write--;\n                }\n            }\n        }\n    }\n}\n\nvector<array<int, 2>> get_empty_cells(const Board& board) {\n    vector<array<int, 2>> res;\n    for (int y = 0; y < N; ++y)\n        for (int x = 0; x < N; ++x)\n            if (board[y][x] == 0)\n                res.push_back({y, x});\n    return res;\n}\n\nPos get_index_from_pt(const vector<array<int, 2>>& empties, int p_t) {\n    assert(p_t >= 1 && p_t <= (int)empties.size());\n    return { empties[p_t - 1][0], empties[p_t - 1][1] };\n}\n\nconstexpr int dy[4] = { 1, -1, 0, 0 };\nconstexpr int dx[4] = { 0, 0, 1, -1 };\n\nstruct ClusterResult {\n    int total_sum_sq;\n    int curr_flavor_sum_sq;\n    int largest_curr_flavor_cluster;\n};\n\nClusterResult analyze_clusters(const Board& board, int flavor) {\n    array<array<bool, N>, N> visited{};\n    int total_score = 0;\n    int curr_flavor_score = 0;\n    int largest_curr_flavor_cluster = 0;\n    for (int y = 0; y < N; y++) for (int x = 0; x < N; x++) {\n        if (board[y][x] != 0 && !visited[y][x]) {\n            int f = board[y][x];\n            int sz = 0;\n            queue<pair<int, int>> q;\n            q.push({ y, x });\n            visited[y][x] = true;\n            while (!q.empty()) {\n                auto [cy, cx] = q.front(); q.pop();\n                sz++;\n                for (int d = 0; d < 4; d++) {\n                    int ny = cy + dy[d], nx = cx + dx[d];\n                    if (ny >= 0 && ny < N && nx >= 0 && nx < N) {\n                        if (!visited[ny][nx] && board[ny][nx] == f) {\n                            visited[ny][nx] = true;\n                            q.push({ ny, nx });\n                        }\n                    }\n                }\n            }\n            total_score += sz * sz;\n            if (f == flavor) {\n                curr_flavor_score += sz * sz;\n                if (sz > largest_curr_flavor_cluster)\n                    largest_curr_flavor_cluster = sz;\n            }\n        }\n    }\n    return ClusterResult{ total_score, curr_flavor_score, largest_curr_flavor_cluster };\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<int> flavors(100);\n    for (int i = 0; i < 100; ++i) cin >> flavors[i];\n\n    Board board{};\n\n    const array<char, 4> all_dirs = { 'F','B','L','R' };\n\n    for (int step = 0; step < 100; ++step) {\n        int p_t;\n        cin >> p_t;\n        vector<array<int, 2>> empties = get_empty_cells(board);\n        Pos pos = get_index_from_pt(empties, p_t);\n        int flavor = flavors[step];\n        board[pos.first][pos.second] = flavor;\n\n        // Try all moves, pick the best per heuristic\n        int best_total = -1;\n        int best_flav_sum = -1;\n        int best_flav_cluster = -1;\n        char chosen_dir = 'F'; // default\n        for (char dir : all_dirs) {\n            Board temp = board;\n            move_board(temp, dir);\n            ClusterResult cl = analyze_clusters(temp, flavor);\n\n            if (cl.total_sum_sq > best_total ||\n               (cl.total_sum_sq == best_total && cl.curr_flavor_sum_sq > best_flav_sum) ||\n               (cl.total_sum_sq == best_total && cl.curr_flavor_sum_sq == best_flav_sum && cl.largest_curr_flavor_cluster > best_flav_cluster)\n            ) {\n                best_total = cl.total_sum_sq;\n                best_flav_sum = cl.curr_flavor_sum_sq;\n                best_flav_cluster = cl.largest_curr_flavor_cluster;\n                chosen_dir = dir;\n            }\n        }\n        move_board(board, chosen_dir);\n\n        if (step != 99) {\n            cout << chosen_dir << '\\n';\n            flush();\n        }\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\n#include <Eigen/Dense>\nusing namespace std;\nusing namespace Eigen;\n\nconst int MAX_N = 100;\nconst int EIGEN_CNT = 10; // Number of eigenvalues to keep\n\n// Helper: string edge list to Eigen adjacency\nvoid string_to_matrix(const string &s, int N, MatrixXd &adj) {\n    adj = MatrixXd::Zero(N, N);\n    int idx = 0;\n    for(int i=0;i<N;i++)for(int j=i+1;j<N;j++) {\n        if(s[idx++]=='1') {\n            adj(i,j) = adj(j,i) = 1.0;\n        }\n    }\n}\n\n// Get sorted degree sequence\nvector<int> get_degseq(const string &s, int N) {\n    vector<int> deg(N, 0);\n    int idx = 0;\n    for(int i=0;i<N;++i) for(int j=i+1;j<N;++j,++idx) {\n        if(s[idx]=='1') {\n            deg[i]++; deg[j]++;\n        }\n    }\n    sort(deg.begin(), deg.end());\n    return deg;\n}\n\n// Get quantized eigenvalues (largest positive & lowest negative EIGEN_CNT/2 each)\nvector<double> get_eigen(const string &s, int N) {\n    MatrixXd adj(N, N);\n    string_to_matrix(s, N, adj);\n    SelfAdjointEigenSolver<MatrixXd> sol(adj);\n    vector<double> eigs(N);\n    for(int i=0;i<N;++i) eigs[i] = sol.eigenvalues()(i);\n    sort(eigs.begin(), eigs.end());\n    // Take lower EIGEN_CNT/2 and upper EIGEN_CNT/2\n    int K = EIGEN_CNT/2;\n    vector<double> v;\n    for(int i=0;i<K;++i) v.push_back(eigs[i]);\n    for(int i=N-K;i<N;++i) v.push_back(eigs[i]);\n    return v;\n}\n\n// Euclidean distance for eigenvectors, and L1 for degree seqs\ndouble eigen_dist(const vector<double>& a, const vector<double>& b) {\n    double d = 0;\n    for(int i=0;i<(int)a.size();++i) d += (a[i]-b[i])*(a[i]-b[i]);\n    return sqrt(d);\n}\nint deg_dist(const vector<int>& a, const vector<int>& b) {\n    int d = 0;\n    for(int i=0;i<(int)a.size();++i) d += abs(a[i]-b[i]);\n    return d;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int M;\n    double eps;\n    cin >> M >> eps;\n\n    // Adaptive N (tuned)\n    int add = (int)(eps * 2.8 * M + 8);\n    int N = min(100, max(4, M + add));\n\n    // Random regular graph generator as before\n    mt19937 rng(1337+M+(int)(eps*10000));\n    auto random_regular_graph = [&](int N, int d) {\n        vector<int> deg(N, d);\n        vector<int> stubs;\n        for(int i=0;i<N;i++) for(int j=0;j<d;j++) stubs.push_back(i);\n        vector<vector<int>> adj(N);\n        for(int tries=0;tries<10;tries++) {\n            auto st = stubs;\n            shuffle(st.begin(), st.end(), rng);\n            vector<vector<int>> to(N);\n            bool good = true;\n            for(int i=0;i<st.size();i+=2) {\n                int u=st[i],v=st[i+1];\n                if(u==v) {good=false;break;}\n                if(find(to[u].begin(), to[u].end(), v)!=to[u].end()) {good=false;break;}\n                to[u].push_back(v);\n                to[v].push_back(u);\n            }\n            if(good) return to;\n        }\n        // Fallback: Erdos-Renyi at density 0.5\n        vector<vector<int>> adj2(N);\n        uniform_real_distribution<double> ud(0,1);\n        for(int i=0;i<N;i++) for(int j=i+1;j<N;j++) {\n            if(ud(rng)<0.5) { adj2[i].push_back(j); adj2[j].push_back(i); }\n        }\n        return adj2;\n    };\n\n    // Prepare graph codes\n    vector<string> graph_codes;\n    set<string> used_code;\n    int target_deg = min(N-1, max(2, N/2 + (int)(eps*N/3)));\n    for(int i=0;i<M;i++) {\n        string code;\n        do {\n            auto adj = random_regular_graph(N, target_deg);\n            string s(N*(N-1)/2,'0');\n            int idx=0;\n            for(int u=0;u<N;u++) for(int v=u+1;v<N;v++,idx++) {\n                if(find(adj[u].begin(), adj[u].end(), v)!=adj[u].end()) s[idx]='1';\n            }\n            code=s;\n        } while(used_code.count(code));\n        used_code.insert(code);\n        graph_codes.push_back(code);\n    }\n\n    // Output M graphs\n    cout << N << endl;\n    for(string& s:graph_codes) cout << s << '\\n';\n    cout.flush();\n\n    // Precompute features for all codes\n    vector< vector<int> > degseqs(M);\n    vector< vector<double> > eigens(M);\n    for(int i=0;i<M;i++) {\n        degseqs[i]=get_degseq(graph_codes[i], N);\n        eigens[i]=get_eigen(graph_codes[i], N);\n    }\n\n    // For each query\n    for(int q=0;q<100;q++) {\n        string query;\n        cin >> query;\n        auto q_degseq = get_degseq(query,N);\n        auto q_eigen = get_eigen(query,N);\n\n        // Find closest code\n        int best = 0;\n        double bestscore = 1e18;\n        for(int i=0;i<M;i++) {\n            int dd = deg_dist(q_degseq, degseqs[i]);\n            double ed = eigen_dist(q_eigen, eigens[i]);\n            double score = 0.11*dd + ed; // Heavy on eigen, degree helps in rare collision\n            if(score < bestscore) {\n                bestscore = score;\n                best = i;\n            }\n        }\n\n        cout << best << '\\n';\n        cout.flush();\n    }\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Random engine\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\nint randint(int a, int b) { return uniform_int_distribution<int>(a, b)(rng); }\n\nstruct Edge {\n    int u, v, w, id;\n    Edge(int u=0, int v=0, int w=0, int id=0): u(u), v(v), w(w), id(id) {}\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, D, K;\n    cin >> N >> M >> D >> K;\n\n    vector<Edge> edges;\n    vector<vector<pair<int,int>>> g(N);\n    map<pair<int,int>, int> uv2eid;\n\n    for (int i = 0; i < M; ++i) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        --u; --v;\n        edges.emplace_back(u, v, w, i);\n        g[u].emplace_back(v, w);\n        g[v].emplace_back(u, w);\n        int uu=u, vv=v; if (uu>vv) swap(uu,vv);\n        uv2eid[make_pair(uu,vv)] = i;\n    }\n\n    for (int i = 0; i < N; ++i) { int x, y; cin >> x >> y; }\n\n    // Edge importance: SPT betweenness with sample sources\n    const int SAMPLES = 16;\n    vector<int> sample_src;\n    unordered_set<int> used;\n    while ((int)sample_src.size() < SAMPLES) {\n        int s = randint(0, N-1);\n        if (!used.count(s)) sample_src.push_back(s), used.insert(s);\n    }\n\n    vector<int> e_importance(M, 0);\n    for (int si : sample_src) {\n        vector<int> dist(N, INT_MAX), from(N, -1);\n        dist[si]=0;\n        using pli=pair<int,int>;\n        priority_queue<pli,vector<pli>,greater<pli>> pq;\n        pq.emplace(0,si);\n        while (!pq.empty()) {\n            auto[d,u]=pq.top(); pq.pop();\n            if (d>dist[u]) continue;\n            for (auto &[v,w]:g[u]) {\n                if (dist[v]>d+w) {\n                    dist[v]=d+w;\n                    from[v]=u;\n                    pq.emplace(dist[v],v);\n                }\n            }\n        }\n        for (int v=0; v<N; ++v) {\n            int u = from[v];\n            if (u == -1) continue;\n            int uu=u, vv=v; if (uu>vv) swap(uu,vv);\n            int eid = uv2eid[{uu,vv}];\n            e_importance[eid] += 1;\n        }\n    }\n\n    // Sort edges by importance and weight (for tie-break)\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        if (e_importance[a]!=e_importance[b]) return e_importance[a]>e_importance[b];\n        return edges[a].w > edges[b].w;\n    });\n\n    vector<int> day_of_edge(M, -1);\n    vector<int> day_counts(D, 0);\n    vector<long long> day_damage(D, 0);\n    vector<unordered_set<int>> day_verts(D);\n\n    // 1. Assign the very top edges with maximum possible spread\n    int spreadN = min(2*D, M); // Spread top 2*D edges\n    vector<int> days_sequence;\n    for (int i=0; i<D; ++i) days_sequence.push_back(i);\n    for (int i=0; i<spreadN; ++i) {\n        int eid = order[i];\n        int u = edges[eid].u, v = edges[eid].v;\n        // Assign to (i * D/spreadN) % D, shifted randomly\n        int offset = randint(0, D-1);\n        int d = ((i * D/spreadN) + offset) % D;\n        int tries = 0, found = 0;\n        for (; tries < D; ++tries) {\n            int d2 = (d + tries) % D;\n            if (day_counts[d2] >= K) continue;\n            if (!day_verts[d2].count(u) && !day_verts[d2].count(v)) {\n                d = d2; found = 1; break;\n            }\n        }\n        if (!found) {\n            for (int d2=0; d2<D; ++d2)\n                if ((day_counts[d2]<K)) { d=d2; break; }\n        }\n        day_of_edge[eid] = d;\n        day_counts[d]++;\n        day_damage[d] += e_importance[eid];\n        day_verts[d].insert(u); day_verts[d].insert(v);\n    }\n\n    // 2. For the next batch of critical edges, anti-adjacency plus modulo days\n    int spreadM = min(6*D, M);\n    for (int idx = spreadN; idx < spreadM; ++idx) {\n        int eid = order[idx];\n        int u = edges[eid].u, v = edges[eid].v;\n        int bestd=-1, bestscore=INT_MAX;\n        int seed = randint(0, D-1);\n        // Try modulo placement first for dispersion\n        for (int tries=0; tries<D; ++tries) {\n            int d=(seed+tries)%D;\n            if(day_counts[d]>=K)continue;\n            if(day_verts[d].count(u)||day_verts[d].count(v))continue;\n            bestd = d; bestscore = day_counts[d];\n            break;\n        }\n        if (bestd == -1) {\n            // Now, allow adjacent but minimize day \"damage\"\n            long long minscore = 2e9;\n            for (int d=0; d<D; ++d) {\n                if(day_counts[d]>=K) continue;\n                long long score = day_damage[d];\n                if(day_verts[d].count(u)||day_verts[d].count(v)) score += 3000;\n                if(score<minscore) {minscore=score; bestd=d;}\n            }\n        }\n        if (bestd == -1) for(int d=0;d<D;++d) if(day_counts[d]<K){bestd=d;break;}\n        day_of_edge[eid]=bestd;\n        day_counts[bestd]++;\n        day_damage[bestd] += e_importance[eid];\n        day_verts[bestd].insert(u); day_verts[bestd].insert(v);\n    }\n\n    // 3. Assign remaining edges focusing on K cap, light balance, and soft anti-adjacency\n    for (int idx = spreadM; idx < M; ++idx) {\n        int eid = order[idx];\n        int u = edges[eid].u, v = edges[eid].v;\n        long long bestscore=1e18; int bestd=-1;\n        for (int d=0; d<D; ++d) {\n            if (day_counts[d] >= K) continue;\n            long long sc = day_damage[d];\n            if (day_verts[d].count(u) || day_verts[d].count(v)) sc += 500;\n            if (sc < bestscore) {bestscore=sc; bestd=d;}\n        }\n        if (bestd==-1) for(int d=0;d<D;++d) if(day_counts[d]<K){bestd=d;break;}\n        day_of_edge[eid] = bestd;\n        day_counts[bestd]++;\n        day_damage[bestd] += e_importance[eid];\n        day_verts[bestd].insert(u); day_verts[bestd].insert(v);\n    }\n\n    // 4. Post-processing: Try swaps between highest and lowest \"damage\" days for critical edges\n    for (int iter=0; iter<5; ++iter) {\n        int maxd = max_element(day_damage.begin(), day_damage.end())-day_damage.begin();\n        int mind = min_element(day_damage.begin(), day_damage.end())-day_damage.begin();\n        if (maxd==mind) break;\n        int be=-1, se=-1, maxe=-1, mine=-1;\n        // Find critical edge on maxd, weak edge on mind, swap if no vertex collision\n        int maxEimpThresh = e_importance[order[spreadN-1]];\n        for (int i=0;i<M;++i) if (day_of_edge[i]==maxd && e_importance[i]>=maxEimpThresh) {be=i;break;}\n        for (int j=0;j<M;++j) if (day_of_edge[j]==mind && e_importance[j]<maxEimpThresh/2) {se=j;break;}\n        if (be==-1||se==-1) break;\n        // Now check for vertex collision if swapped\n        auto check = [&](int eid, int d, int skip_eid) -> bool {\n            int u=edges[eid].u, v=edges[eid].v;\n            if (u==edges[skip_eid].u||u==edges[skip_eid].v) return false; // would collide\n            if (v==edges[skip_eid].u||v==edges[skip_eid].v) return false;\n            return true;\n        };\n        if (!check(be, mind, se) || !check(se,maxd,be)) break;\n        swap(day_of_edge[be], day_of_edge[se]);\n        // Actually update day_damage/verts for the two days\n        for (int d:{maxd,mind}) {\n            day_damage[d]=0;\n            day_counts[d]=0;\n            day_verts[d].clear();\n            for(int i=0;i<M;++i) if(day_of_edge[i]==d) {\n                day_damage[d]+=e_importance[i];\n                day_counts[d]++;\n                day_verts[d].insert(edges[i].u);\n                day_verts[d].insert(edges[i].v);\n            }\n        }\n    }\n\n    for (int i = 0; i < M; ++i) {\n        cout << (day_of_edge[i]+1) << (i+1==M ? '\\n' : ' ');\n    }\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int D;\n    cin >> D;\n    vector<vector<string>> F(2, vector<string>(D)), R(2, vector<string>(D));\n    for(int i=0; i<D; ++i) cin >> F[0][i];\n    for(int i=0; i<D; ++i) cin >> R[0][i];\n    for(int i=0; i<D; ++i) cin >> F[1][i];\n    for(int i=0; i<D; ++i) cin >> R[1][i];\n    vector<vector<int>> out(2, vector<int>(D*D*D, 0));\n    int block_id = 1;\n    for (int obj = 0; obj < 2; ++obj)\n        for (int x = 0; x < D; ++x)\n            for (int y = 0; y < D; ++y)\n                for (int z = 0; z < D; ++z)\n                    if (F[obj][z][x] == '1' && R[obj][z][y] == '1')\n                        out[obj][x*D*D + y*D + z] = block_id++;\n    cout << block_id-1 << \"\\n\";\n    for (int obj = 0; obj < 2; ++obj)\n        for (int i = 0; i < D*D*D; ++i)\n            cout << out[obj][i] << (i+1 == D*D*D ? '\\n' : ' ');\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <queue>\n#include <algorithm>\n#include <limits>\n#include <set>\n#include <cassert>\nusing namespace std;\n\nstruct Edge {\n    int u, v, idx;\n    long long w;\n    bool operator<(const Edge& o) const { return w < o.w; }\n};\n\ninline int dist(int x0,int y0,int x1,int y1) {\n    return (int)ceil(sqrt(1LL*(x0-x1)*(x0-x1) + 1LL*(y0-y1)*(y0-y1)));\n}\n\nconst int INF = 1e9+7;\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n\n    int N, M, K;\n    cin >> N >> M >> K;\n    vector<pair<int, int>> nodes(N);\n    for (int i = 0; i < N; ++i)\n        cin >> nodes[i].first >> nodes[i].second;\n    vector<Edge> edges(M);\n    vector<vector<pair<int, int>>> g(N); // (to, edge_id)\n    for (int j = 0; j < M; ++j) {\n        int u, v;\n        long long w;\n        cin >> u >> v >> w;\n        edges[j] = {u - 1, v - 1, j, w};\n        g[u - 1].emplace_back(v - 1, j);\n        g[v - 1].emplace_back(u - 1, j);\n    }\n    vector<pair<int, int>> residents(K);\n    for (int k = 0; k < K; ++k)\n        cin >> residents[k].first >> residents[k].second;\n\n    // For each node, for each resident, can node i cover k?\n    vector<vector<int>> can_cover(N); // residents node i can cover within 5000\n    for (int i = 0; i < N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            int d = dist(nodes[i].first, nodes[i].second, residents[k].first, residents[k].second);\n            if (d <= 5000) can_cover[i].push_back(k);\n        }\n    }\n\n    // Prepare all-pairs shortest paths (using Dijkstra per node) for fast edge cost queries.\n    vector<vector<long long>> sp(N, vector<long long>(N, 1e18));\n    vector<vector<int>> sp_prev(N, vector<int>(N, -1));\n    for (int s = 0; s < N; ++s) {\n        vector<long long>& d = sp[s];\n        d[s] = 0;\n        using pli = pair<long long,int>;\n        priority_queue<pli, vector<pli>, greater<pli>> pq; \n        pq.push({0, s});\n        while (!pq.empty()) {\n            auto [cost, v] = pq.top(); pq.pop();\n            if (cost > d[v]) continue;\n            for (auto &[to, eid] : g[v]) {\n                long long nc = cost + edges[eid].w;\n                if (d[to] > nc) {\n                    d[to] = nc;\n                    sp_prev[s][to] = v;\n                    pq.push({nc, to});\n                }\n            }\n        }\n    }\n\n    vector<int> Pi(N, 0);\n    set<int> covered;\n    set<int> active_nodes;\n    vector<bool> edge_on(M, false);\n\n    // Greedy set cover with edge cost\n    set<int> not_covered;\n    for (int k = 0; k < K; ++k) not_covered.insert(k);\n\n    // Root is always active\n    active_nodes.insert(0);\n\n    while (!not_covered.empty()) {\n        int best_id = -1, best_r = 0, best_nc = 0, best_new = -1;\n        long long best_score = 1e18;\n        set<int> best_residents;\n        set<int> best_path_edges;\n\n        for (int i = 0; i < N; ++i) {\n            // Residents that would be newly covered if broadcasting from node i, and minimal required radius.\n            set<int> new_residents;\n            int max_r = 0;\n            for (int k : can_cover[i]) {\n                if (not_covered.count(k)) {\n                    int d = dist(nodes[i].first, nodes[i].second, residents[k].first, residents[k].second);\n                    if (d > max_r) max_r = d;\n                    new_residents.insert(k);\n                }\n            }\n            if (new_residents.empty()) continue;\n\n            // Marginal edge cost to connect to active network\n            long long mcost = 1e18;\n            int connect_from = -1;\n            for (int j : active_nodes) {\n                if (sp[j][i] < mcost) {\n                    mcost = sp[j][i];\n                    connect_from = j;\n                }\n            }\n            // Score: (power cost + edge cost) / #newly covered (to prioritize efficiency)\n            long long sc = (1LL*max_r*max_r + mcost) * 10000LL / (long long)new_residents.size();\n            if (sc < best_score) {\n                best_score = sc;\n                best_id = i;\n                best_r = max_r;\n                best_residents = new_residents;\n                best_nc = connect_from;\n            }\n        }\n        if (best_id == -1) break;\n\n        // Activate node\n        Pi[best_id] = max(Pi[best_id], best_r);\n        active_nodes.insert(best_id);\n        for (int k : best_residents) not_covered.erase(k);\n\n        // Activate edge path\n        int v = best_id;\n        int from = best_nc;\n        // Path from 'from' to 'v'\n        vector<int> p;\n        while (v != from) {\n            int pv = sp_prev[from][v];\n            // Find eid between v and pv\n            int eid = -1;\n            for (auto &[to, e] : g[v]) if (to == pv) {eid = e; break;}\n            assert(eid != -1);\n            edge_on[eid] = true;\n            v = pv;\n        }\n    }\n\n    // Ensure all active broadcast nodes are connected to root (defensive: may be disconnected if initial root not always used)\n    for (int i = 0; i < N; ++i) if (Pi[i] > 0) {\n        // If not connected, connect\n        // Check: is there a path to root in the currently-on-edge subgraph?\n        vector<bool> v(N, false);\n        queue<int> q;\n        q.push(0); v[0]=1;\n        while (!q.empty()) {\n            int cur = q.front(); q.pop();\n            for (auto &[to, eid] : g[cur]) if (edge_on[eid] && !v[to]) { v[to]=1; q.push(to);}\n        }\n        if (!v[i]) {\n            // Find shortest path to 0\n            int vtx = i;\n            while (vtx != 0) {\n                int pv = sp_prev[0][vtx];\n                int eid = -1;\n                for (auto &[to, e] : g[vtx]) if (to == pv) {eid = e; break;}\n                assert(eid != -1);\n                edge_on[eid] = true;\n                vtx = pv;\n            }\n        }\n    }\n\n    // Power-pruning: safe Pi reductions\n    vector<bool> still_covered(K, false);\n    for (int i = 0; i < N; ++i) if (Pi[i] > 0) {\n        for (int k = 0; k < K; ++k) {\n            int d = dist(nodes[i].first, nodes[i].second, residents[k].first, residents[k].second);\n            if (d <= Pi[i]) still_covered[k] = true;\n        }\n    }\n    for (int i = 0; i < N; ++i) if (Pi[i] > 0) {\n        bool safe = true;\n        vector<int> need_cover;\n        for (int k = 0; k < K; ++k) {\n            int d = dist(nodes[i].first, nodes[i].second, residents[k].first, residents[k].second);\n            if (d <= Pi[i] && still_covered[k]) need_cover.push_back(k);\n        }\n        for (int k : need_cover) {\n            bool one_covered = false;\n            for (int j = 0; j < N; ++j) if (j != i && Pi[j] > 0) {\n                int d = dist(nodes[j].first, nodes[j].second, residents[k].first, residents[k].second);\n                if (d <= Pi[j]) { one_covered = true; break; }\n            }\n            if (!one_covered) { safe = false; break; }\n        }\n        if (safe) Pi[i] = 0;\n    }\n\n    // Output\n    for (int i = 0; i < N; ++i) cout << Pi[i] << (i+1==N ? '\\n' : ' ');\n    for (int j = 0; j < M; ++j) cout << (edge_on[j]?1:0) << (j+1==M ? '\\n' : ' ');\n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <algorithm>\n#include <queue>\n#include <cassert>\n#include <set>\nusing namespace std;\n\nconstexpr int N = 30;\nconstexpr int NN = N*(N+1)/2;\nconstexpr int MAX_MOVE = 10000;\n\nconst int dx[6] = {-1, -1, 0, 0, 1, 1};\nconst int dy[6] = {-1, 0, -1, 1, 0, 1};\n\ninline bool is_valid(int x, int y) {\n    return 0 <= x && x < N && 0 <= y && y <= x;\n}\ninline bool is_adjacent(int x1, int y1, int x2, int y2) {\n    for(int d=0; d<6; ++d)\n        if(x1+dx[d]==x2 && y1+dy[d]==y2) return true;\n    return false;\n}\ninline bool has_child(int x, int y) { return x < N-1; }\ninline pair<pair<int,int>, pair<int,int>> get_children(int x, int y) {\n    return {{x+1,y}, {x+1,y+1}};\n}\ninline pair<int,int> get_parentL(int x, int y) { return {x-1,y-1}; }\ninline pair<int,int> get_parentR(int x, int y) { return {x-1,y}; }\n\nstruct MoveRecorder {\n    vector<tuple<int,int,int,int>> moves;\n    int K = 0;\n    vector<vector<int>> &grid;\n    vector<pair<int,int>> &label_pos;\n    MoveRecorder(vector<vector<int>> &g, vector<pair<int,int>> &lp): grid(g), label_pos(lp) {}\n    void do_swap(int x1, int y1, int x2, int y2) {\n        using std::swap;\n        assert(is_adjacent(x1, y1, x2, y2));\n        swap(grid[x1][y1], grid[x2][y2]);\n        label_pos[grid[x1][y1]] = {x1, y1};\n        label_pos[grid[x2][y2]] = {x2, y2};\n        moves.emplace_back(x1, y1, x2, y2);\n        K++;\n    }\n};\n\nint count_violation(const vector<vector<int>> &grid) {\n    int res = 0;\n    for (int x = 0; x < N-1; ++x)\n        for (int y = 0; y <= x; ++y) {\n            auto [l, r] = get_children(x,y);\n            if(grid[x][y] > grid[l.first][l.second]) res++;\n            if(grid[x][y] > grid[r.first][r.second]) res++;\n        }\n    return res;\n}\n\nvector<pair<int,int>> bfs_path(const vector<vector<int>> &grid, pair<int,int> from, pair<int,int> to, int max_depth=16) {\n    // Early out\n    if(from == to) return {from};\n    queue<vector<pair<int,int>>> q;\n    set<pair<int,int>> vis;\n    q.push({from});\n    vis.insert(from);\n    while(!q.empty()) {\n        auto path = q.front(); q.pop();\n        auto [x,y] = path.back();\n        if((int)path.size() > max_depth+1) continue;\n        for(int d=0; d<6; ++d) {\n            int nx = x+dx[d], ny = y+dy[d];\n            if(is_valid(nx,ny) && !vis.count({nx,ny})) {\n                auto np = path; np.emplace_back(nx,ny);\n                if(make_pair(nx,ny)==to) return np;\n                q.push(np); vis.insert({nx,ny});\n            }\n        }\n    }\n    return {};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    vector<vector<int>> grid(N);\n    vector<pair<int,int>> label_pos(NN);\n    for(int x=0; x<N; ++x) {\n        grid[x].resize(x+1);\n        for(int y=0; y<=x; ++y){\n            cin >> grid[x][y];\n            label_pos[grid[x][y]] = {x, y};\n        }\n    }\n    MoveRecorder recorder(grid, label_pos);\n\n    // Alternate multi-directional passes\n    int max_pass = 13;\n    for(int pass = 0; pass < max_pass && recorder.K < MAX_MOVE; ++pass) {\n        bool changed = false;\n        // Top-down\n        for(int x=0; x<N-1 && recorder.K < MAX_MOVE; ++x) {\n            int sy = (pass&1?x:0), ey = (pass&1? -1:x+1), delta = (pass&1? -1:1);\n            for(int y=sy; y!=ey && recorder.K < MAX_MOVE; y+=delta) {\n                int v = grid[x][y];\n                auto [l,r] = get_children(x, y);\n                int lval = grid[l.first][l.second], rval = grid[r.first][r.second];\n                if(v > lval || v > rval) {\n                    int cx = x, cy = y;\n                    while(cx < N-1 && recorder.K < MAX_MOVE) {\n                        auto [cl,cr] = get_children(cx, cy);\n                        int clx=cl.first, cly=cl.second, crx=cr.first, cry=cr.second;\n                        int cv = grid[cx][cy], clv = grid[clx][cly], crv = grid[crx][cry];\n                        if(clv < crv && clv < cv) {\n                            recorder.do_swap(cx, cy, clx, cly);\n                            cx = clx; cy = cly; changed = true;\n                        }else if(crv < clv && crv < cv) {\n                            recorder.do_swap(cx, cy, crx, cry);\n                            cx = crx; cy = cry; changed = true;\n                        }else break;\n                    }\n                }\n            }\n        }\n        // Bottom-up\n        for(int x=N-1; x>0 && recorder.K < MAX_MOVE; --x) {\n            int sy = (pass&1?x:0), ey = (pass&1? -1:x+1), delta = (pass&1? -1:1);\n            for(int y=sy; y!=ey && recorder.K < MAX_MOVE; y+=delta) {\n                int cv = grid[x][y];\n                // left parent\n                if(y > 0) {\n                    auto [plx,ply] = get_parentL(x,y);\n                    if(is_valid(plx,ply) && grid[plx][ply] > cv) {\n                        int cx = x, cy = y;\n                        while(cx>0 && recorder.K<MAX_MOVE) {\n                            auto [plnx,plny] = get_parentL(cx,cy);\n                            if(is_valid(plnx,plny) && grid[plnx][plny] > grid[cx][cy]) {\n                                recorder.do_swap(plnx,plny,cx,cy);\n                                cx=plnx;cy=plny;changed=true;\n                            } else break;\n                        }\n                    }\n                }\n                // right parent\n                if(y < x) {\n                    auto [prx, pry] = get_parentR(x, y);\n                    if(is_valid(prx,pry) && grid[prx][pry] > cv) {\n                        int cx = x, cy = y;\n                        while(cx>0 && recorder.K<MAX_MOVE) {\n                            auto [prnx,prny] = get_parentR(cx,cy);\n                            if(is_valid(prnx,prny) && grid[prnx][prny] > grid[cx][cy]) {\n                                recorder.do_swap(prnx,prny,cx,cy);\n                                cx=prnx;cy=prny;changed=true;\n                            }else break;\n                        }\n                    }\n                }\n            }\n        }\n        if(!changed) break;\n    }\n    // Build violation list, highest first\n    vector<tuple<int,int,int,int,int>> vios; // x, y, cx, cy, tier\n    for (int x = 0; x < N-1; ++x)\n        for (int y = 0; y <= x; ++y) {\n            auto [l, r] = get_children(x,y);\n            if(grid[x][y] > grid[l.first][l.second]) vios.emplace_back(x,y, l.first,l.second, x);\n            if(grid[x][y] > grid[r.first][r.second]) vios.emplace_back(x,y, r.first,r.second, x);\n        }\n    // Sort by uppermost tier first\n    sort(vios.begin(), vios.end(), [](auto &a, auto &b){ return get<4>(a) < get<4>(b); });\n\n    int max_try = 200; // Try more BFS corrections\n    int done = 0;\n    int max_bfs_depth = 14; // High but not too high\n    for(auto &[x1,y1,x2,y2,tier]: vios) {\n        if(recorder.K >= MAX_MOVE) break;\n        if(grid[x1][y1] <= grid[x2][y2]) continue;\n        auto path = bfs_path(grid, {x2,y2}, {x1,y1}, max_bfs_depth);\n        if(!path.empty() && path.size() > 1 && (int)path.size()-1 + recorder.K < MAX_MOVE) {\n            for(int i=(int)path.size()-2; i>=0; --i)\n                recorder.do_swap(path[i+1].first,path[i+1].second,path[i].first,path[i].second);\n            done++;\n        }\n        if(done > max_try) break;\n    }\n    // Output\n    cout << recorder.K << '\\n';\n    for(const auto& [x1,y1,x2,y2]: recorder.moves)\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << \"\\n\";\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int D = 9;\nconstexpr int ENTRANCE_I = 0;\nconstexpr int ENTRANCE_J = (D-1)/2;\nconst int di[] = {-1,1,0,0}, dj[] = {0,0,-1,1};\n\nstruct Cell {\n    int i, j;\n    Cell(int i=0, int j=0):i(i),j(j){}\n    bool operator==(const Cell& o) const { return i==o.i && j==o.j; }\n    bool operator!=(const Cell& o) const { return !(*this==o); }\n};\n\nostream& operator<<(ostream& os, const Cell& c) {\n    return os << c.i << ' ' << c.j;\n}\n\nbool in_grid(int i, int j) {\n    return 0 <= i && i < D && 0 <= j && j < D;\n}\n\nvector<Cell> adj4(Cell c) {\n    vector<Cell> v;\n    for(int d=0;d<4;++d) {\n        int ni = c.i+di[d], nj = c.j+dj[d];\n        if(in_grid(ni,nj)) v.emplace_back(ni,nj);\n    }\n    return v;\n}\n\n// For quickly assigning container numbers to positions.\nstruct WarehouseSolver {\n    int N;\n    set<Cell> obstacles;\n    set<Cell> not_assignable; // entrance + 3 adjacents + obstacles\n    vector<Cell> assignable_cells; // order by BFS from entrance\n    map<Cell, int> cell_to_bfs_layer;\n\n    // Storage state\n    vector<pair<int,int>> arrivals; // (container number, arrival idx)\n    map<Cell, int> assigned_cell_to_num;\n    map<int, Cell> num_to_cell;\n\n    // Extraction ordering\n    vector<Cell> extraction_order;\n\n    WarehouseSolver() {}\n\n    void initialize() {\n        // Build not_assignable: entrance & its 3 adjacents & obstacles\n        not_assignable.insert(Cell(ENTRANCE_I, ENTRANCE_J));\n        for(int d=0;d<4;++d) {\n            int ni = ENTRANCE_I+di[d], nj = ENTRANCE_J+dj[d];\n            if(in_grid(ni,nj))\n                not_assignable.insert(Cell(ni,nj));\n        }\n        for(auto c: obstacles) not_assignable.insert(c);\n\n        // BFS from entrance to get \"ranked\" assignable cells\n        vector<vector<int>> vis(D, vector<int>(D, -1));\n        queue<Cell> q;\n        q.push(Cell(ENTRANCE_I, ENTRANCE_J));\n        vis[ENTRANCE_I][ENTRANCE_J]=0;\n        int dist = 1;\n        // Pre-mark not_assignable so we don't revisit\n        for(auto c: not_assignable) vis[c.i][c.j]=-2;\n        vis[ENTRANCE_I][ENTRANCE_J]=0; // entrance\n\n        vector<Cell> order;\n        while(!q.empty()) {\n            Cell c = q.front();q.pop();\n            for(auto d: adj4(c)) {\n                if(vis[d.i][d.j] == -1) {\n                    vis[d.i][d.j] = vis[c.i][c.j]+1;\n                    q.push(d);\n                    // If it's assignable (not in not_assignable), add to order\n                    if(not_assignable.count(d) == 0) {\n                        assignable_cells.push_back(d);\n                        cell_to_bfs_layer[d] = vis[d.i][d.j];\n                    }\n                }\n            }\n        }\n    }\n\n    void read_input() {\n        cin >> N;\n        for(int k=0;k<N;++k) {\n            int ri,rj;\n            cin >> ri >> rj;\n            obstacles.insert(Cell(ri,rj));\n        }\n        initialize();\n    }\n\n    void assign_container(int t_d, int arrival_idx) {\n        // Add to arrivals\n        arrivals.emplace_back(t_d, arrival_idx);\n        // We need to select an assignable cell for it.\n\n        // For containers arrived so far, make a sorted list\n        vector<pair<int,int>> sorted_arrivals = arrivals;\n        sort(sorted_arrivals.begin(), sorted_arrivals.end()); // by t_d\n        // Their optimal mapping: map sorted_arrivals[i] to assignable_cells[i]\n        // For current container (arrival_idx), find where it lands\n        int pos = -1;\n        for(int i=0;i<sorted_arrivals.size();++i) {\n            if(sorted_arrivals[i].second == arrival_idx) {\n                pos = i;\n                break;\n            }\n        }\n        assert(pos != -1);\n\n        // Some assignable_cells may already be assigned: must choose the first unassigned slot corresponding to pos (since in rare cases, due to obstacles, not all cells may be left)\n        vector<bool> used(assignable_cells.size(), false);\n        for(auto& kv: assigned_cell_to_num) {\n            // Mark which slots are taken\n            for(int i=0;i<assignable_cells.size();++i) {\n                if(assignable_cells[i]==kv.first) used[i]=true;\n            }\n        }\n        // Assign in sorted order: for the list of arrivals (sorting by t_d), map to available slots in assignable_cells in order, skipping used ones.\n        int assign_slot = -1, cnt = 0;\n        for(int i=0;i<assignable_cells.size();++i) {\n            if(used[i]) continue;\n            if(cnt==pos) { assign_slot=i; break; }\n            cnt++;\n        }\n        assert(assign_slot != -1);\n        Cell assign_cell = assignable_cells[assign_slot];\n\n        // Assign this cell to the container num\n        assigned_cell_to_num[assign_cell] = t_d;\n        num_to_cell[t_d] = assign_cell;\n\n        // Output assignment\n        cout << assign_cell.i << \" \" << assign_cell.j << endl;\n        cout.flush();\n    }\n\n    // After all containers are placed, plan extraction order.\n    void plan_extraction() {\n        // Build grid state: 0=empty, -1=obstacle, >0=container num+1\n        vector<vector<int>> grid(D, vector<int>(D,0));\n        for(auto c: obstacles) grid[c.i][c.j]=-1;\n        for(auto& [cell, num]: assigned_cell_to_num) grid[cell.i][cell.j]=num+1;\n\n        set<int> remaining_nums;\n        for(auto& [num, cell]: num_to_cell) remaining_nums.insert(num);\n\n        extraction_order.clear();\n\n        for(int step=0;step < num_to_cell.size(); ++step) {\n            // Find all containers (cells with grid>0) reachable from entrance\n            queue<Cell> q;\n            vector<vector<bool>> vis(D,vector<bool>(D,false));\n            q.push(Cell(ENTRANCE_I, ENTRANCE_J));\n            vis[ENTRANCE_I][ENTRANCE_J]=true;\n\n            set<Cell> reachable;\n            while(!q.empty()) {\n                Cell c = q.front();q.pop();\n                for(auto d: adj4(c)) {\n                    if(!vis[d.i][d.j]) {\n                        if(grid[d.i][d.j] == 0) {\n                            vis[d.i][d.j]=true;q.push(d);\n                        } else if(grid[d.i][d.j]>0) {\n                            // It's a container\n                            reachable.insert(d);\n                        }\n                    }\n                }\n            }\n            // From reachable, pick container with smallest num\n            int best_num = 1e9;\n            Cell best_cell;\n            for(auto c: reachable) {\n                int num = grid[c.i][c.j]-1;\n                if(num < best_num) { best_num = num; best_cell = c; }\n            }\n            extraction_order.push_back(best_cell);\n\n            // Remove this from grid\n            grid[best_cell.i][best_cell.j] = 0;\n            remaining_nums.erase(best_num);\n        }\n    }\n\n    void output_extraction_order() {\n        for(auto& c: extraction_order) {\n            cout << c.i << \" \" << c.j << endl;\n        }\n        cout.flush();\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D_input, N;\n    cin >> D_input >> N;\n    assert(D_input==D);\n\n    WarehouseSolver solver;\n    solver.N=N;\n    for(int k=0;k<N;++k) {\n        int ri,rj; cin >> ri >> rj;\n        solver.obstacles.insert(Cell(ri,rj));\n    }\n    solver.initialize(); // needs to be called after obstacles are set up\n\n    const int K = D*D-1-N;\n    for(int d=0; d<K; ++d) {\n        int t_d; cin >> t_d;\n        solver.assign_container(t_d, d);\n    }\n    // After all placements\n    solver.plan_extraction();\n    solver.output_extraction_order();\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 50, M = 100, COLORS = 101;\nint n, m;\nint c[N][N];\n\n// For each color, set of adjacent colors (including 0)\nvector<set<int>> adjacency(COLORS);\n// Whether color c touches the edge (adjacent to outside/0)\nvector<bool> touches0(COLORS);\n\n// For output\nint d[N][N];\n\n// Direction vectors\nconstexpr int di[] = {-1, 0, 1, 0};\nconstexpr int dj[] = {0, 1, 0, -1};\n\n// Compose adjacency graph for all colors from input\nvoid build_adjacency() {\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j) {\n            int col = c[i][j];\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir], nj = j + dj[dir];\n                if (ni < 0 || nj < 0 || ni >= n || nj >= n) {\n                    adjacency[col].insert(0);\n                    adjacency[0].insert(col);\n                    touches0[col] = true;\n                } else if (c[ni][nj] != col) {\n                    adjacency[col].insert(c[ni][nj]);\n                }\n            }\n        }\n}\n\n// List of wards (colors)\nvector<int> all_wards() {\n    vector<int> wards;\n    for (int i = 1; i <= m; ++i) wards.push_back(i);\n    return wards;\n}\n\n// Assign output locations for each ward (color)\n// Ensures border-wards go to boundary.\nmap<int, pair<int,int>> assign_ward_positions(const vector<int>& wards) {\n    map<int,pair<int,int>> pos;\n    set<pair<int,int>> used;\n    // 1. Lay out border-wards\n    vector<pair<int,int>> border_spots;\n    for (int i = 0; i < n; ++i) {\n        border_spots.emplace_back(0, i);\n        border_spots.emplace_back(n-1, i);\n    }\n    for (int j = 1; j < n-1; ++j) {\n        border_spots.emplace_back(j, 0);\n        border_spots.emplace_back(j, n-1);\n    }\n    int bi = 0;\n\n    // 2. Inner spots for rest\n    vector<pair<int,int>> inner_spots;\n    for (int i = 1; i < n-1; ++i)\n        for (int j = 1; j < n-1; ++j)\n            inner_spots.emplace_back(i,j);\n    int ii = 0;\n\n    // Wards sorted: priority to those with more adjacents\n    vector<int> order = wards;\n    sort(order.begin(), order.end(), [](int a, int b) {\n        return adjacency[a].size() > adjacency[b].size();\n    });\n\n    for (int ward : order) {\n        if (touches0[ward] && bi < (int)border_spots.size()) {\n            // Assign to border\n            pos[ward] = border_spots[bi++];\n            used.insert(pos[ward]);\n        } else if (ii < (int)inner_spots.size()) {\n            pos[ward] = inner_spots[ii++];\n            used.insert(pos[ward]);\n        } else {\n            // fallback (should not happen)\n            pos[ward] = make_pair(0,0);\n        }\n    }\n    return pos;\n}\n\n// Fill in the output grid according to assigned ward positions and enforce adjacency requirements.\nvoid build_output_map(const map<int, pair<int,int>>& ward_pos) {\n    // Clear to zero\n    for (int i=0;i<n;++i) for (int j=0;j<n;++j) d[i][j]=0;\n\n    // Place all the wards in their assigned cell\n    for (const auto& [ward, p] : ward_pos) {\n        d[p.first][p.second] = ward;\n    }\n\n    // Now, for each adjacency, ensure the pair is represented by a pair of adjacent cells on the grid.\n    // Try to do this with minimal area addition.\n    for (int c = 1; c <= m; ++c) {\n        for (int dcol : adjacency[c]) {\n            if (dcol < c) continue; // Each pair once (and skip dcol=0 for now, handlded by positions on boundary)\n\n            auto [ci, cj] = ward_pos.at(c);\n            auto [di_, dj_] = ward_pos.at(dcol);\n\n            // Are they adjacent in the grid?\n            if (abs(ci-di_)+abs(cj-dj_) ==1) continue;\n\n            // Otherwise, connect them along Manhattan path with their own colors\n            int curi = ci, curj = cj;\n            // Let's make a path from (ci,cj) to (di_,dj_) (no '0' along the way)\n            while (curi != di_) {\n                curi += (di_ > curi) ? 1 : -1;\n                if (d[curi][curj] == 0)\n                    d[curi][curj] = c;\n            }\n            while (curj != dj_) {\n                curj += (dj_ > curj) ? 1 : -1;\n                if (d[curi][curj] == 0)\n                    d[curi][curj] = c;\n            }\n        }\n    }\n}\n\n// Validation helpers (not used in contest submission)\n// Check all same-color cells are connected (DFS)\n// Check adjacencies\n\n// Full solution\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    n = N; m = M;\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j)\n            cin >> c[i][j];\n\n    adjacency.assign(COLORS, set<int>());\n    touches0.assign(COLORS, false);\n\n    build_adjacency();\n\n    vector<int> wards = all_wards();\n\n    auto ward_pos = assign_ward_positions(wards);\n\n    build_output_map(ward_pos);\n\n    // Output result\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cout << d[i][j] << \" \\n\"[j==n-1];\n        }\n    }\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nvoid fastio() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); }\nvoid flush() { cout.flush(); }\n\n// --------------- Definitions --------------\nint N, D, Q;  // Number, Divisions, Queries\nint query_count = 0;\n\n// Ask a balance between L and R, return -1 (L<R), 0 (=), 1 (L>R)\nint askBalance(const vector<int>& L, const vector<int>& R) {\n    assert(!L.empty() && !R.empty());\n    assert(query_count < Q);\n    cout << L.size() << \" \" << R.size() << \" \";\n    for (int x : L) cout << x << \" \";\n    for (int x : R) cout << x << \" \";\n    cout << \"\\n\";\n    flush();\n    string s; cin >> s;\n    query_count++;\n    if (s == \"<\") return -1;\n    else if (s == \"=\") return 0;\n    else if (s == \">\") return 1;\n    else {\n        cerr << \"Unknown judge response: \" << s << endl;\n        exit(1);\n    }\n}\n\n// Tournament-based win scores\nvector<int> get_win_scores(int N, int Q) {\n    vector<int> win_count(N, 0);\n    vector<vector<int>> compared(N, vector<int>(N, 0)); // 0: not yet, 1: compared\n\n    int max_pairs = Q;\n    // Enumerate all unordered pairs, random order for coverage\n    vector<pair<int,int>> pairs;\n    for (int i = 0; i < N; ++i) {\n        for (int j = i+1; j < N; ++j) {\n            pairs.emplace_back(i, j);\n        }\n    }\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    shuffle(pairs.begin(), pairs.end(), rng);\n\n    int used = 0;\n    for (auto &[i, j]: pairs) {\n        if (used >= max_pairs) break;\n        int res = askBalance({i}, {j});\n        if (res == 1) { win_count[i]++; }\n        else if (res == -1) { win_count[j]++; }\n        // in case of tie (rare), do nothing (or +0.5 to both if desired)\n        // compared[i][j] = compared[j][i] = 1;\n        used++;\n    }\n    return win_count;\n}\n\n// Assign heavy items to lightest groups, greedy stratified assign\nvector<int> assign_to_groups_by_score(const vector<int>& score) {\n    int N = score.size();\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    // Highest win_count first\n    sort(idx.begin(), idx.end(), [&](int i, int j){ return score[i] > score[j]; });\n\n    vector<long long> group_score(D, 0);\n    vector<int> assign(N, -1);\n    for (int t = 0; t < N; ++t) {\n        int i = idx[t];\n        if (t < D) {\n            assign[i] = t; // ensure each group gets at least 1 item\n            group_score[t] += score[i];\n        } else {\n            // assign to current lowest group\n            int gid = min_element(group_score.begin(), group_score.end()) - group_score.begin();\n            assign[i] = gid;\n            group_score[gid] += score[i];\n        }\n    }\n    return assign;\n}\n\nint main() {\n    fastio();\n    cin >> N >> D >> Q;\n\n    // 1. Use up to Q pairwise queries to collect win data\n    vector<int> win_score = get_win_scores(N, Q);\n\n    // 2. Assign by greedy\n    vector<int> assign = assign_to_groups_by_score(win_score);\n\n    // 3. Output\n    for (int i = 0; i < N; ++i) {\n        cout << assign[i] << (i+1 == N ? '\\n' : ' ');\n    }\n    flush();\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 200;\nconstexpr int M = 10;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int n, m;\n    cin >> n >> m;\n    assert(n == 200 && m == 10);\n\n    vector<vector<int>> stacks(m); // [stack][bottom..top]\n    vector<pair<int,int>> box_pos(n+1); // [box] -> (stack_id, pos_from_bottom)\n\n    for (int i = 0; i < m; ++i) {\n        stacks[i].resize(n/m);\n        for (int j = 0; j < n/m; ++j) {\n            cin >> stacks[i][j];\n            box_pos[stacks[i][j]] = {i, j};\n        }\n    }\n\n    vector<pair<int, int>> ops; // operations: (v, stack_id), stack_id==0 for carry out\n\n    // For each number to be carried out in order\n    vector<int> stack_pointer(m, 0); // number of boxes taken out from bottom of each stack\n\n    for (int target = 1; target <= n; ++target) {\n        // Find where the target box is\n        pair<int,int> pos = box_pos[target];\n        int s = pos.first, idx = pos.second;\n\n        // Since boxes are only removed from top, need to adjust for boxes already taken out from this stack\n        int logical_pos = idx - stack_pointer[s];\n        int stack_size = stacks[s].size();\n\n        // If it's at the top of its stack (adjusted)\n        if (logical_pos == (int)stacks[s].size() - 1) {\n            // Output: (target, 0)\n            ops.emplace_back(target, 0);\n            // Remove from stack\n            stacks[s].pop_back();\n            stack_pointer[s]++;\n        } else {\n            // Need to move [logical_pos, end] to another stack\n            vector<int> to_move;\n            for (int j = logical_pos; j < (int)stacks[s].size(); ++j) to_move.push_back(stacks[s][j]);\n            \n            // Remove from source stack\n            stacks[s].resize(logical_pos);\n\n            // Invalidate pointer for moved boxes\n            for (int box : to_move) box_pos[box] = {-1, -1};\n\n            // Select destination stack (shortest, not s)\n            int dest = -1, minsize = INT_MAX;\n            for (int i = 0; i < m; ++i) {\n                if (i == s) continue;\n                if ((int)stacks[i].size() < minsize) {\n                    minsize = (int)stacks[i].size();\n                    dest = i;\n                }\n            }\n\n            // Place chunk to target stack\n            for (int box : to_move) {\n                stacks[dest].push_back(box);\n            }\n            // Update positions for moved boxes\n            int sz = stacks[dest].size();\n            for (int j = 0; j < (int)to_move.size(); ++j) {\n                box_pos[to_move[j]] = {dest, sz - (int)to_move.size() + j};\n            }\n\n            // Output operation: (target, dest+1)\n            ops.emplace_back(target, dest+1);\n        restart: // We'll loop back as the box may need carry operation in next iteration\n            // Try again in next loop, as now it should be on top at dest stack\n            target--;\n        }\n    }\n    // Output\n    for (auto [v, i] : ops) cout << v << \" \" << i << \"\\n\";\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int di[4] = {-1, 1, 0, 0};\nconstexpr int dj[4] = {0, 0, -1, 1};\nconstexpr char DIR[4] = {'U', 'D', 'L', 'R'};\n// Utility\nstruct Position {\n    int i, j;\n    Position(int ii = 0, int jj = 0) : i(ii), j(jj) {}\n    bool operator==(const Position &r) const { return i == r.i && j == r.j; }\n};\n\nint N, maxLength = 100000;\nvector<string> hwall, vwall;\nvector<vector<int>> dirt;\nvector<vector<bool>> vis;\nvector<Position> route; // the \"path\"\nset<pair<int,int>> high_dirt_set;\nvector<Position> hi_dirt_list;\n\ninline bool in_grid(int i, int j) { return 0 <= i && i < N && 0 <= j && j < N; }\n\nbool can_move(int i, int j, int dir) {\n    int ni = i + di[dir], nj = j + dj[dir];\n    if (!in_grid(ni, nj)) return false;\n    if (dir == 0) return hwall[ni][nj] == '0'; // U\n    if (dir == 1) return hwall[i][j] == '0';   // D\n    if (dir == 2) return vwall[ni][nj] == '0'; // L\n    if (dir == 3) return vwall[i][j] == '0';   // R\n    return false;\n}\n\n// BFS shortest path (excluding first)\nvector<Position> bfs_shortest_path(int si, int sj, int ti=0, int tj=0) {\n    vector<vector<Position>> prev(N, vector<Position>(N, Position(-1,-1)));\n    queue<Position> q;\n    q.push({si,sj}); prev[si][sj]={si,sj};\n    while(!q.empty()) {\n        auto pos=q.front(); q.pop();\n        if(pos.i==ti && pos.j==tj) break;\n        for(int dir=0;dir<4;++dir){\n            int ni=pos.i+di[dir], nj=pos.j+dj[dir];\n            if(!in_grid(ni,nj)) continue;\n            if(!can_move(pos.i,pos.j,dir)) continue;\n            if(prev[ni][nj].i!=-1) continue;\n            prev[ni][nj]=pos;\n            q.push({ni,nj});\n        }\n    }\n    vector<Position> res;\n    Position cur={ti,tj};\n    if(prev[ti][tj].i==-1) return {}; // no path\n    while(!(cur.i==si && cur.j==sj)){\n        res.push_back(cur);\n        cur=prev[cur.i][cur.j];\n    }\n    reverse(res.begin(),res.end());\n    return res;\n}\n\nbool validate_path(const vector<Position>& r) {\n    for (size_t k=1; k<r.size(); ++k) {\n        int pi=r[k-1].i, pj=r[k-1].j, ni=r[k].i, nj=r[k].j;\n        bool found=false;\n        for(int dir=0;dir<4;++dir) {\n            if(pi+di[dir] == ni && pj+dj[dir] == nj) {\n                if (!can_move(pi,pj,dir)) return false;\n                found=true; break;\n            }\n        }\n        if(!found) return false;\n    }\n    return true;\n}\n\nstring route_to_moves(const vector<Position>& route) {\n    string moves;\n    for (size_t k = 1; k < route.size(); ++k) {\n        int pi = route[k-1].i, pj = route[k-1].j;\n        int ni = route[k].i, nj = route[k].j;\n        bool found = false;\n        for (int dir = 0; dir < 4; ++dir) {\n            if (pi + di[dir] == ni && pj + dj[dir] == nj) {\n                moves += DIR[dir];\n                found = true;\n                break;\n            }\n        }\n        if (!found) {\n            cerr << \"route_to_moves invalid move \" << pi << \" \" << pj << \" to \" << ni << \" \" << nj << endl;\n            assert(found);\n        }\n    }\n    return moves;\n}\n\nvoid dfs_with_detour(int i, int j, int &steps_left) {\n    if (steps_left <= 0) return;\n    vis[i][j]=true;\n    route.push_back({i,j});\n    --steps_left;\n\n    // Optionally take a detour if this is a high-dirt cell (not 0,0), and not at max length\n    if (steps_left>=2 && high_dirt_set.count({i,j}) && !(i==0 && j==0)) {\n        // Find a neighbor to loop\n        for(int dir=0;dir<4;++dir) {\n            int ni=i+di[dir], nj=j+dj[dir];\n            if(!in_grid(ni,nj)) continue;\n            if(!can_move(i,j,dir)) continue;\n            if(!vis[ni][nj]) continue; // avoid unvisited cells\n            // Move out and back\n            route.push_back({ni,nj});\n            route.push_back({i,j});\n            steps_left -=2;\n            break;\n        }\n    }\n    // Explore neighbors in decreasing dirt order\n    vector<pair<int,int>> nbrs;\n    for(int dir=0;dir<4;++dir){\n        int ni=i+di[dir], nj=j+dj[dir];\n        if(in_grid(ni,nj) && !vis[ni][nj] && can_move(i,j,dir)) {\n            nbrs.emplace_back(dirt[ni][nj], dir);\n        }\n    }\n    sort(nbrs.rbegin(), nbrs.rend());\n    for(auto &[dval,dir] : nbrs){\n        int ni=i+di[dir], nj=j+dj[dir];\n        if (steps_left <= 1) break; // always leave a step for return\n        dfs_with_detour(ni,nj,steps_left);\n        if (steps_left <= 0) return;\n        // Backtrack to parent node if time allows\n        route.push_back({i,j});\n        --steps_left;\n        if(steps_left<=0) return;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    hwall.resize(N-1); for(int i=0;i<N-1;++i) cin >> hwall[i];\n    vwall.resize(N);   for(int i=0;i<N;++i) cin >> vwall[i];\n    dirt.assign(N,vector<int>(N));\n    for(int i=0;i<N;++i) for(int j=0;j<N;++j) cin >> dirt[i][j];\n\n    // Choose high dirt cells for detour (top K)\n    vector<pair<int, Position>> dirtvec;\n    for(int i=0;i<N;++i) for(int j=0;j<N;++j)\n        dirtvec.push_back({-dirt[i][j], {i,j}});\n    sort(dirtvec.begin(), dirtvec.end(), [](const pair<int, Position>& a, const pair<int, Position>& b) {\n        return a.first < b.first;\n    });\n\n    int K = max(3,min(8, N*N/8));\n    for(int k=0;k<K && k<(int)dirtvec.size(); ++k) {\n        auto [negd,pos]=dirtvec[k];\n        if (pos.i == 0 && pos.j == 0) continue;\n        high_dirt_set.emplace(pos.i,pos.j);\n        hi_dirt_list.push_back(pos);\n    }\n\n    // DFS with limited steps, detours as we go\n    vis.assign(N,vector<bool>(N,false));\n    route.clear();\n    int steps_left = maxLength-1; // leave at least 1 for possible return\n    dfs_with_detour(0,0,steps_left);\n    // At current route.back(), append shortest path to 0,0\n    Position last = route.back();\n    auto pathback = bfs_shortest_path(last.i,last.j,0,0);\n    for(auto &p:pathback) {\n        if ((int)route.size()>=maxLength) break;\n        route.push_back(p);\n    }\n    // If not at (0,0), forcibly append more\n    if (!(route.back() == Position(0,0))) {\n        auto finalback = bfs_shortest_path(route.back().i, route.back().j, 0, 0);\n        for(auto &p:finalback) {\n            if ((int)route.size()>=maxLength) break;\n            route.push_back(p);\n            if(p.i==0 && p.j==0) break;\n        }\n    }\n    // Truncate if grossly over length\n    if ((int)route.size()>maxLength) route.resize(maxLength);\n\n    // Validate\n    assert(route[0]==Position(0,0));\n    assert(route.back()==Position(0,0));\n    assert(validate_path(route));\n\n    // Output\n    string moves = route_to_moves(route);\n    cout << moves << '\\n';\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 15;\nconst int LOOK_AHEAD = 3;\n\n// Function to find greatest overlap (suffix of a with prefix of b)\nint calc_overlap(const string &a, const string &b) {\n    int maxl = min(a.size(), b.size());\n    for (int len = maxl; len; --len)\n        if (a.substr(a.size() - len, len) == b.substr(0, len))\n            return len;\n    return 0;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int n, m, si, sj;\n    cin >> n >> m >> si >> sj;\n\n    vector<string> grid(n);\n    for (int i = 0; i < n; ++i) cin >> grid[i];\n\n    // Build position list for each letter\n    vector<pair<int, int>> letter_pos[26];\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j)\n            letter_pos[grid[i][j] - 'A'].emplace_back(i, j);\n\n    vector<string> words(m);\n    for (int i = 0; i < m; ++i) cin >> words[i];\n\n    // --- Greedy Minimum Superstring (pairwise) ---\n    vector<string> curr_words = words;\n    while (curr_words.size() > 1) {\n        int best_i = -1, best_j = -1, best_ov = -1;\n        for (int i = 0; i < int(curr_words.size()); ++i) {\n            for (int j = 0; j < int(curr_words.size()); ++j) {\n                if (i == j) continue;\n                int ov = calc_overlap(curr_words[i], curr_words[j]);\n                if (ov > best_ov) {\n                    best_ov = ov;\n                    best_i = i;\n                    best_j = j;\n                }\n            }\n        }\n        if (best_ov <= 0) best_i = 0, best_j = 1, best_ov = 0;\n        string merged = curr_words[best_i] + curr_words[best_j].substr(best_ov);\n        vector<string> new_words;\n        for (int i = 0; i < int(curr_words.size()); ++i) {\n            if (i != best_i && i != best_j)\n                new_words.push_back(curr_words[i]);\n        }\n        new_words.push_back(merged);\n        curr_words.swap(new_words);\n        if (curr_words[0].size() > 5000) break;\n    }\n    string superstring = curr_words[0];\n    if (int(superstring.size()) > 5000) superstring = superstring.substr(0, 5000);\n    int s_len = superstring.size();\n\n    // --- \"LOOK AHEAD\" MOVEMENT ROUTE --\n    vector<pair<int,int>> route(s_len);\n    int ci = si, cj = sj;\n    for (int idx = 0; idx < s_len; ) {\n        int K = min(LOOK_AHEAD, s_len - idx);\n        // Prepare index for each letter\n        vector<vector<pair<int,int>>> letters(K);\n        for (int k = 0; k < K; ++k) \n            letters[k] = letter_pos[superstring[idx + k] - 'A'];\n        // Limit: only consider first 10 positions per letter for speed\n        for (int k = 0; k < K; ++k) {\n            if (int(letters[k].size()) > 10)\n                letters[k].resize(10);\n        }\n\n        int best_cost = INT_MAX;\n        vector<int> best_chosen(K, 0);\n        vector<int> tries(K, 0);\n        // Try all possible sequences for this small window\n        while (true) {\n            int cost = abs(ci - letters[0][tries[0]].first) + abs(cj - letters[0][tries[0]].second) + 1;\n            for (int k = 1; k < K; ++k) {\n                auto &prv = letters[k-1][tries[k-1]];\n                auto &cur = letters[k][tries[k]];\n                cost += abs(prv.first - cur.first) + abs(prv.second - cur.second) + 1;\n            }\n            if (cost < best_cost) {\n                best_cost = cost;\n                best_chosen = tries;\n            }\n            // next tries\n            int step = K-1;\n            while (step >= 0) {\n                if (++tries[step] < int(letters[step].size()))\n                    break;\n                tries[step] = 0;\n                --step;\n            }\n            if (step < 0) break; // done\n        }\n        // Write out chosen sequence\n        for (int k = 0; k < K; ++k) {\n            route[idx + k] = letters[k][best_chosen[k]];\n        }\n        ci = route[idx + K - 1].first;\n        cj = route[idx + K - 1].second;\n        idx += K;\n    }\n\n    for (auto &[i, j] : route) cout << i << \" \" << j << '\\n';\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Polyomino {\n    vector<pair<int,int>> cells;\n    int h = 0, w = 0;\n    vector<vector<pair<int,int>>> placements;\n};\n\nint N, M;\ndouble eps;\nvector<Polyomino> oil_fields;\nvector<vector<int>> drillValue;\nvector<vector<int>> alivePlacements;\n\nvoid enumerate_placements() {\n    for (auto &poly : oil_fields) {\n        int min_i = 1e9, min_j = 1e9, max_i = -1e9, max_j = -1e9;\n        for (auto [x, y] : poly.cells) {\n            min_i = min(min_i, x);\n            max_i = max(max_i, x);\n            min_j = min(min_j, y);\n            max_j = max(max_j, y);\n        }\n        poly.h = max_i + 1;\n        poly.w = max_j + 1;\n        for (int base_i = 0; base_i + poly.h <= N; ++base_i) {\n            for (int base_j = 0; base_j + poly.w <= N; ++base_j) {\n                vector<pair<int,int>> placement;\n                for (auto [di, dj]: poly.cells) {\n                    placement.emplace_back(base_i + di, base_j + dj);\n                }\n                poly.placements.push_back(placement);\n            }\n        }\n    }\n}\n\nvector<vector<int>> plausible_oil_counts() {\n    vector<vector<int>> cnt(N, vector<int>(N));\n    for (int f = 0; f < M; ++f) {\n        for (int pi: alivePlacements[f]) {\n            for (auto [ci, cj]: oil_fields[f].placements[pi]) {\n                cnt[ci][cj]++;\n            }\n        }\n    }\n    return cnt;\n}\n\nvoid do_query(const string& s) {\n    cout << s << endl;\n    cout << flush;\n}\n\nbool update_alivePlacements() {\n    bool changed = false;\n    for (int f = 0; f < M; ++f) {\n        vector<int> updated;\n        for (int pi : alivePlacements[f]) {\n            const auto& placement = oil_fields[f].placements[pi];\n            bool ok = true;\n            for (auto [ci, cj]: placement) {\n                if (drillValue[ci][cj] == 0) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (!ok) continue;\n            for (auto [ci, cj]: placement) {\n                if (drillValue[ci][cj] > 0) {\n                    int possible = 1;\n                    for (int ff = 0; ff < M; ++ff) if (ff != f) {\n                        for (int pi2 : alivePlacements[ff]) {\n                            for (auto [ci2, cj2]: oil_fields[ff].placements[pi2]) {\n                                if (ci2 == ci && cj2 == cj) {\n                                    possible++;\n                                    goto donecount;\n                                }\n                            }\n                        }\n                        donecount:;\n                    }\n                    if (possible < drillValue[ci][cj]) {\n                        ok = false;\n                        break;\n                    }\n                }\n            }\n            if (ok) updated.push_back(pi);\n        }\n        if ((int)updated.size() != (int)alivePlacements[f].size()) changed = true;\n        alivePlacements[f] = move(updated);\n    }\n    return changed;\n}\n\npair<int,int> choose_next_drill() {\n    auto cnt = plausible_oil_counts();\n    int best_val = -1;\n    pair<int,int> best = {-1, -1};\n    for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j)\n        if (drillValue[i][j] == -1 && cnt[i][j] > best_val) {\n            best_val = cnt[i][j];\n            best = {i, j};\n        }\n    if (best_val == -1) {\n        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j)\n            if (drillValue[i][j] == -1) return {i, j};\n    }\n    return best;\n}\n\nbool solved(set<pair<int,int>> &result_cells) {\n    set<pair<int,int>> S;\n    for (int f=0; f<M; ++f) {\n        if (alivePlacements[f].size() != 1) return false;\n        for (auto [ci,cj]: oil_fields[f].placements[alivePlacements[f][0]]) {\n            S.emplace(ci,cj);\n        }\n    }\n    result_cells = move(S);\n    return true;\n}\n\nvoid fallback_brute(set<pair<int,int>>& answer_set, vector<pair<int,int>>& already_drilled) {\n    // Drill remaining cells\n    for (int i=0; i<N; ++i) for(int j=0; j<N; ++j)\n        if (drillValue[i][j] == -1) {\n            do_query(\"q 1 \" + to_string(i) + \" \" + to_string(j));\n            int v; cin >> v;\n            drillValue[i][j] = v;\n        }\n    // Collect oil cells\n    answer_set.clear();\n    for (int i=0; i<N; ++i) for(int j=0; j<N; ++j)\n        if (drillValue[i][j] > 0) answer_set.emplace(i,j);\n    for (auto [i,j]: already_drilled) {\n        if (drillValue[i][j] > 0) answer_set.emplace(i,j);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    cin >> N >> M >> eps;\n    oil_fields.resize(M);\n    for (int k=0; k<M; ++k) {\n        int d; cin >> d;\n        vector<pair<int,int>> cc;\n        for (int q=0; q<d; ++q) {\n            int x, y; cin >> x >> y;\n            cc.emplace_back(x, y);\n        }\n        oil_fields[k].cells = move(cc);\n    }\n\n    enumerate_placements();\n\n    alivePlacements.clear();\n    for (auto &poly : oil_fields) {\n        int K = poly.placements.size();\n        vector<int> v(K);\n        iota(v.begin(), v.end(), 0);\n        alivePlacements.push_back(move(v));\n    }\n    drillValue.assign(N, vector<int>(N, -1));\n\n    set<pair<int,int>> answer_set;\n    vector<pair<int,int>> already_drilled;\n\n    // Start (at most M) random drills\n    mt19937 rng(12345);\n    int opcnt = 0;\n    int max_trials = min(M, N*N);\n    bool found = false;\n    for (; opcnt < max_trials; ) {\n        uniform_int_distribution<int> dist(0, N-1);\n        int i = dist(rng), j = dist(rng);\n        if (drillValue[i][j] != -1) continue;\n        do_query(\"q 1 \" + to_string(i) + \" \" + to_string(j));\n        int v; cin >> v;\n        drillValue[i][j] = v;\n        already_drilled.emplace_back(i,j);\n        opcnt++;\n        update_alivePlacements();\n        if (solved(answer_set)) { found = true; break; }\n    }\n\n    int alive_total = 0;\n    for (auto& pl : alivePlacements) alive_total += pl.size();\n    // Elimination loop (if necessary)\n    while (!found && opcnt < 2 * N * N && alive_total < 1000) {\n        if (solved(answer_set)) { found = true; break;}\n        pair<int,int> drill = choose_next_drill();\n        if (drill.first == -1) break;\n        int i = drill.first, j = drill.second;\n        do_query(\"q 1 \" + to_string(i) + \" \" + to_string(j));\n        int v; cin >> v;\n        drillValue[i][j] = v;\n        already_drilled.emplace_back(i,j);\n        opcnt++;\n        update_alivePlacements();\n        alive_total = 0;\n        for (auto& pl : alivePlacements) alive_total += pl.size();\n    }\n\n    if (!found) {\n        fallback_brute(answer_set, already_drilled);\n    }\n    else {\n        // Ensure all positive drilled cells present\n        for (auto [i,j]: already_drilled) {\n            if (drillValue[i][j] > 0) answer_set.emplace(i,j);\n        }\n    }\n\n    vector<pair<int,int>> oilCells(answer_set.begin(), answer_set.end());\n    cout << \"a \" << oilCells.size();\n    for (auto [i,j]: oilCells) cout << \" \" << i << \" \" << j;\n    cout << endl << flush;\n\n    int res = 0;\n    cin >> res; // Must always read final input!\n    if (res != 1) {\n        cerr << \"# Output judged incorrect!\" << endl;\n    }\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int W = 1000;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int w, D, N;\n    cin >> w >> D >> N;\n    vector<vector<int>> a(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    for (int d = 0; d < D; ++d) {\n        int64_t total = 0;\n        for (int k = 0; k < N; ++k) total += a[d][k];\n\n        // Sort areas, get assignment order (largest gets largest slice)\n        vector<pair<int, int>> req(N);\n        for (int k = 0; k < N; ++k) req[k] = {a[d][k], k};\n        sort(req.rbegin(), req.rend());\n        vector<int> order(N);\n        for (int i = 0; i < N; ++i) order[req[i].second] = i;\n\n        // Create proportional slices\n        vector<int> widths(N), cuts(N+1, 0);\n        int used = 0;\n        for (int i = 0; i < N; ++i) {\n            if (i+1 == N) widths[i] = W - used;\n            else {\n                widths[i] = max(int64_t(1), (req[i].first * W) / max(total, int64_t(1)));\n                used += widths[i];\n            }\n        }\n        if (used + widths[N-1] > W) widths[N-1] -= used + widths[N-1] - W;\n        for (int i = 0; i < N; ++i) cuts[i+1] = cuts[i] + widths[i];\n\n        // Output by original reservation order\n        for (int k = 0; k < N; ++k) {\n            int idx = order[k];\n            int x0 = cuts[idx], x1 = cuts[idx+1];\n            cout << 0 << \" \" << x0 << \" \" << W << \" \" << x1 << \"\\n\";\n        }\n    }\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 9, M = 20, K = 81;\nconstexpr int MOD = 998244353;\nusing Board = array<array<int, N>, N>;\nusing Stamp = array<array<int, 3>, 3>;\n\nlong long modsum(const Board& board) {\n    long long sum = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            sum += board[i][j] % MOD;\n    return sum;\n}\n\n// Phase 1: Position list for a perfect 3x3 tiling of the board\nvector<pair<int,int>> perfect_tiling_positions() {\n    vector<pair<int,int>> pos;\n    for (int pi = 0; pi <= N-3; pi += 3)\n        for (int pj = 0; pj <= N-3; pj += 3)\n            pos.emplace_back(pi, pj);\n    return pos;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n\n    int n, m, k;\n    cin >> n >> m >> k;\n    Board a;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> a[i][j];\n    vector<Stamp> stamps(M);\n    for (int t = 0; t < M; ++t)\n        for (int i = 0; i < 3; ++i)\n            for (int j = 0; j < 3; ++j)\n                cin >> stamps[t][i][j];\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    long long best_score = -1;\n    vector<tuple<int, int, int>> best_ops;\n\n    int NUM_RESTART = 10; // Tune to fit within time, try 20 on faster machines\n\n    const auto initial_tiles = perfect_tiling_positions();\n\n    for (int iter = 0; iter < NUM_RESTART; ++iter) {\n        Board board = a;\n        array<array<int, N>, N> board_mod;\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                board_mod[i][j] = board[i][j] % MOD;\n        vector<tuple<int, int, int>> ops;\n\n        // Phase 1: Initial tiling (covers all cells once in the first 9 moves)\n        for (const auto& [pi, pj] : initial_tiles) {\n            int best_gain = 0;\n            vector<int> best_stamps;\n            for (int m_id = 0; m_id < M; ++m_id) {\n                int gain = 0;\n                const auto& st = stamps[m_id];\n                for (int di = 0; di < 3; ++di)\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int ni = pi + di, nj = pj + dj;\n                        int before = board_mod[ni][nj];\n                        int after = (board[ni][nj] + st[di][dj]) % MOD;\n                        gain += (after - before + MOD) % MOD;\n                    }\n                if (gain > best_gain) {\n                    best_gain = gain;\n                    best_stamps.clear();\n                    best_stamps.push_back(m_id);\n                } else if (gain == best_gain) {\n                    best_stamps.push_back(m_id);\n                }\n            }\n            // break ties randomly\n            int m_id = best_stamps[rng() % best_stamps.size()];\n            ops.emplace_back(m_id, pi, pj);\n            const auto& st = stamps[m_id];\n            for (int di = 0; di < 3; ++di)\n                for (int dj = 0; dj < 3; ++dj) {\n                    int ni = pi + di, nj = pj + dj;\n                    board[ni][nj] += st[di][dj];\n                    board_mod[ni][nj] = (board_mod[ni][nj] + st[di][dj]) % MOD;\n                }\n        }\n\n        // Phase 2: Greedy for the remaining moves, with tie-breaking on min cell touched\n        for (int step = initial_tiles.size(); step < K; ++step) {\n            int best_gain = 0;\n            int best_mincell = MOD+1;\n            vector<tuple<int, int, int>> candidates;\n            for (int m_id = 0; m_id < M; ++m_id) {\n                const auto& st = stamps[m_id];\n                for (int p = 0; p <= N - 3; ++p) {\n                    for (int q = 0; q <= N - 3; ++q) {\n                        int gain = 0;\n                        int mincell = MOD+1;\n                        for (int di = 0; di < 3; ++di)\n                            for (int dj = 0; dj < 3; ++dj) {\n                                int ni = p + di, nj = q + dj;\n                                int before = board_mod[ni][nj];\n                                int after = (board[ni][nj] + st[di][dj]) % MOD;\n                                gain += (after - before + MOD) % MOD;\n                                mincell = min(mincell, before);\n                            }\n                        if (gain > best_gain || (gain == best_gain && mincell < best_mincell)) {\n                            best_gain = gain;\n                            best_mincell = mincell;\n                            candidates.clear();\n                            candidates.emplace_back(m_id, p, q);\n                        } else if (gain == best_gain && mincell == best_mincell) {\n                            candidates.emplace_back(m_id, p, q);\n                        }\n                    }\n                }\n            }\n            if (best_gain <= 0) break;\n            shuffle(candidates.begin(), candidates.end(), rng);\n            auto [m, p, q] = candidates[0];\n            ops.emplace_back(m, p, q);\n            const auto& st = stamps[m];\n            for (int di = 0; di < 3; ++di)\n                for (int dj = 0; dj < 3; ++dj) {\n                    int ni = p + di, nj = q + dj;\n                    board[ni][nj] += st[di][dj];\n                    board_mod[ni][nj] = (board_mod[ni][nj] + st[di][dj]) % MOD;\n                }\n        }\n        long long tot = modsum(board);\n        if (tot > best_score) {\n            best_score = tot;\n            best_ops = ops;\n        }\n    }\n    cout << best_ops.size() << '\\n';\n    for (auto [m, p, q] : best_ops) {\n        cout << m << \" \" << p << \" \" << q << '\\n';\n    }\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\nconstexpr int N = 5, MAX_TURNS = 10000;\n\nstruct Crane {\n    int r, c;\n    bool large, holding;\n    int hold;\n};\nint main() {\n    ios::sync_with_stdio(0); cin.tie(0);\n    vector<vector<int>> A(N, vector<int>(N));\n    for (auto& row : A) for (int& x : row) cin >> x;\n\n    // Per-row incoming queues\n    array<queue<int>, N> arrv;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) arrv[i].push(A[i][j]);\n\n    int grid[N][N]; for(auto& r:grid)fill(begin(r),end(r),-1);\n    vector<Crane> cranes;\n    for (int i = 0; i < N; i++) cranes.push_back({i, 0, i==0, false, -1});\n    int who[N][N]; for(auto& r:who)fill(begin(r),end(r),-1);\n    for(int i=0;i<N;i++)who[i][0]=i;\n    int need[N] = {};\n    vector<string> logs(N);\n\n    int dispatched_cnt = 0;\n    int turn = 0; // track number of turns actually used\n    for (; turn < MAX_TURNS; ++turn) {\n        // ARRIVAL: deliver if possible\n        for (int i = 0; i < N; i++)\n            if (grid[i][0] == -1 && !cranes[i].holding && !arrv[i].empty())\n                grid[i][0] = arrv[i].front(), arrv[i].pop();\n\n        char acts[N]; fill(begin(acts),end(acts),'.');\n        int claim[N][N]; for(int i=0;i<N;i++)for(int j=0;j<N;j++)claim[i][j]=who[i][j];\n\n        for (int k = 0; k < N; k++) {\n            auto& cr = cranes[k];\n            int r = cr.r, c = cr.c;\n            int mygoal = N*r + need[r];\n\n            // 1. Deliver if at dispatch gate\n            if(cr.holding && cr.hold==mygoal && c==N-1 && grid[r][c]==-1) {\n                acts[k]='Q'; cr.holding=false; grid[r][c]=cr.hold; cr.hold=-1; need[r]++;\n                continue;\n            }\n            // 2. Buffer if holding wrong container at free buffer\n            if(cr.holding && cr.hold!=mygoal && c>=1 && c<=3 && grid[r][c]==-1) {\n                acts[k]='Q'; cr.holding=false; grid[r][c]=cr.hold; cr.hold=-1;\n                continue;\n            }\n            // 3. If holding, go to dispatch/buffer\n            if(cr.holding){\n                int tgt=-1;\n                if(cr.hold==mygoal) tgt=N-1;\n                else for(int pos=1;pos<=3;pos++) if(grid[r][pos]==-1){tgt=pos;break;}\n                if(tgt!=-1 && c!=tgt){\n                    int dir=(tgt>c?1:-1);\n                    if(who[r][c+dir]==-1 && (cr.large || grid[r][c+dir]==-1)){\n                        acts[k]=(dir==1?'R':'L'); who[r][c]=-1; cr.c+=dir; who[r][cr.c]=k; continue;\n                    }\n                }\n            }\n            // 4. Pick up target underfoot\n            if(!cr.holding && grid[r][c]==mygoal){\n                acts[k]='P'; cr.holding=true; cr.hold=mygoal; grid[r][c]=-1; continue;\n            }\n            // 5. Buffer wrong arrival if at rec gate\n            if(!cr.holding && c==0 && grid[r][0]!=-1 && grid[r][0]!=mygoal){\n                acts[k]='P'; cr.holding=true; cr.hold=grid[r][0]; grid[r][0]=-1; continue;\n            }\n            // 6. Move toward correct container\n            int tgt=-1, dist=10;\n            for(int pos=0;pos<=3;pos++)if(grid[r][pos]==mygoal&&abs(pos-c)<dist){tgt=pos;dist=abs(pos-c);}\n            if(tgt!=-1 && c!=tgt){\n                int dir = (tgt>c?1:-1);\n                if(who[r][c+dir]==-1){\n                    acts[k]=(dir==1?'R':'L');\n                    who[r][c]=-1; cr.c+=dir; who[r][cr.c]=k; continue;\n                }\n            }\n            // 7. Move to an empty buffer (wait for future)\n            if(!cr.holding){\n                for(int buf=1;buf<=3;buf++)\n                    if(grid[r][buf]==-1 && c!=buf && who[r][buf]==-1){\n                        int dir=(buf>c?1:-1);\n                        if(who[r][c+dir]==-1){\n                            acts[k]=(dir==1?'R':'L'); who[r][c]=-1; cr.c+=dir; who[r][cr.c]=k; break;\n                        }\n                    }\n            }\n        }\n        for (int k = 0; k < N; k++) logs[k] += acts[k];\n\n        // DISPATCH any containers delivered\n        for (int i = 0; i < N; i++) if (grid[i][N-1]!=-1) { grid[i][N-1]=-1; dispatched_cnt++; }\n\n        // --- EARLY STOP ---\n        if (dispatched_cnt == N*N) {\n            ++turn;\n            break;\n        }\n    }\n    // PAD\n    size_t mxlen=turn;\n    for(auto&s:logs) if(s.size()<mxlen) s+=string(mxlen-s.size(),'.');\n    for(auto&s:logs) cout << s << '\\n';\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 20;\nconstexpr int MAX_LOAD = 1000000;\nconstexpr int K_BEST = 3;\nconstexpr int SUPPLY_RADIUS = 2;\n\nstruct Cell {\n    int y, x, amount;\n    bool done = false;\n};\n\nvector<char> get_path(int sy, int sx, int ty, int tx) {\n    vector<char> path;\n    while (sy < ty) { path.emplace_back('D'); sy++; }\n    while (sy > ty) { path.emplace_back('U'); sy--; }\n    while (sx < tx) { path.emplace_back('R'); sx++; }\n    while (sx > tx) { path.emplace_back('L'); sx--; }\n    return path;\n}\n\n// Dirs for adj search\nconst int DY[4] = {-1,1,0,0}, DX[4] = {0,0,-1,1};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n; cin >> n;\n    vector<vector<int>> h(n, vector<int>(n));\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j) cin >> h[i][j];\n\n    vector<Cell> supplies, demands;\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j)\n            if (h[i][j] > 0) supplies.push_back({i, j, h[i][j]});\n            else if (h[i][j] < 0) demands.push_back({i, j, -h[i][j]});\n\n    vector<string> commands;\n    int cy = 0, cx = 0, load = 0;\n\n    // Nearest nonempty supply\n    auto find_nearest_supply = [&](int cy, int cx) {\n        int idx = -1, best = INT_MAX;\n        for (int i = 0; i < (int)supplies.size(); ++i)\n            if (!supplies[i].done && supplies[i].amount)\n                if (int d = abs(supplies[i].y - cy) + abs(supplies[i].x - cx); d < best)\n                    best = d, idx = i;\n        return idx;\n    };\n\n    // Multi-pickup: gather various adjacent supplies\n    auto collect_supply_batch = [&](int sy, int sx, int truck_free, vector<Cell>& supplies, vector<pair<int,int>>& batch) {\n        int n = supplies.size();\n        vector<tuple<int,int,int>> close;\n        for (int i = 0; i < n; ++i) {\n            if (supplies[i].done || supplies[i].amount == 0) continue;\n            int d = abs(supplies[i].y - sy) + abs(supplies[i].x - sx);\n            if (d == 0) continue;\n            if (d <= SUPPLY_RADIUS) close.emplace_back(d, i, supplies[i].amount);\n        }\n        sort(close.begin(), close.end());\n        int cur_y = sy, cur_x = sx, remain = truck_free;\n        for (auto& [dist, idx, amt] : close) {\n            if (remain == 0) break;\n            auto path = get_path(cur_y, cur_x, supplies[idx].y, supplies[idx].x);\n            for (char c : path) batch.push_back({0, c});\n            batch.push_back({1, idx});\n            remain -= min(remain, supplies[idx].amount);\n            cur_y = supplies[idx].y;\n            cur_x = supplies[idx].x;\n        }\n        return make_pair(cur_y, cur_x);\n    };\n\n    // \"Smart multi-drop\": deliver at adjacent demands after batch\n    auto greedy_adj_demands = [&](int& py, int& px, int& tload, vector<Cell>& demands, vector<string>& commands) {\n        bool found = 1;\n        while (tload > 0 && found) {\n            found = 0;\n            for (int d = 0; d < 4; ++d) {\n                int ny = py + DY[d], nx = px + DX[d];\n                if (ny < 0 || ny >= N || nx < 0 || nx >= N) continue;\n                for (int i = 0; i < (int)demands.size(); ++i)\n                    if (demands[i].y == ny && demands[i].x == nx && !demands[i].done && demands[i].amount > 0) {\n                        // Move to neighbor\n                        commands.push_back(string(1, \"UDLR\"[d]));\n                        py = ny, px = nx;\n                        int deliver = min(tload, demands[i].amount);\n                        if (deliver > 0) {\n                            commands.push_back(\"-\" + to_string(deliver));\n                            demands[i].amount -= deliver;\n                            tload -= deliver;\n                            if (demands[i].amount == 0) demands[i].done = true;\n                        }\n                        found = 1;\n                        break;\n                    }\n                if (found) break;\n            }\n        }\n    };\n\n    while (true) {\n        if (load == 0) {\n            int sidx = find_nearest_supply(cy, cx);\n            if (sidx == -1) break;\n            auto& cell = supplies[sidx]; int y = cell.y, x = cell.x;\n            int truck_free = MAX_LOAD;\n            auto path0 = get_path(cy, cx, y, x);\n            for (char c : path0) commands.push_back(string(1, c));\n            cy = y; cx = x;\n            int to_load = min(truck_free, cell.amount);\n            commands.push_back(\"+\" + to_string(to_load));\n            load += to_load;\n            truck_free -= to_load;\n            cell.amount -= to_load; if (cell.amount == 0) cell.done = true;\n            vector<pair<int,int>> supply_script;\n            auto [ey, ex] = collect_supply_batch(y, x, truck_free, supplies, supply_script);\n            for (auto& [kind, dat] : supply_script) {\n                if (kind == 0) {\n                    commands.push_back(string(1, (char)dat));\n                    cy = (dat=='U'?cy-1: dat=='D'?cy+1: cy);\n                    cx = (dat=='L'?cx-1: dat=='R'?cx+1: cx);\n                } else {\n                    int idx = dat;\n                    int amt = min(MAX_LOAD-load, supplies[idx].amount);\n                    if (amt > 0) {\n                        commands.push_back(\"+\"+to_string(amt));\n                        load += amt;\n                        supplies[idx].amount -= amt;\n                        if (supplies[idx].amount == 0) supplies[idx].done = true;\n                    }\n                }\n            }\n        } else {\n            vector<pair<int,int>> cand;\n            for (int i = 0; i < (int)demands.size(); ++i)\n                if (!demands[i].done && demands[i].amount > 0)\n                    cand.emplace_back(abs(demands[i].y - cy) + abs(demands[i].x - cx), i);\n            sort(cand.begin(), cand.end());\n            vector<int> dindices;\n            int tload = load;\n            for(auto& [dist, i] : cand)\n                if (tload > 0 && (int)dindices.size() < K_BEST)\n                    dindices.push_back(i), tload -= demands[i].amount;\n            if (dindices.empty()) break;\n            vector<int> bestseq;\n            long long bestcost = LLONG_MAX;\n            int dk = dindices.size();\n            vector<int> perm = dindices;\n            do {\n                int py = cy, px = cx, tload2 = load;\n                long long cost = 0;\n                int real_len = 0;\n                for (int ind = 0; ind < dk && tload2 > 0; ++ind) {\n                    int id = perm[ind];\n                    int dy = demands[id].y, dx = demands[id].x;\n                    cost += 1LL * (abs(py - dy) + abs(px - dx)) * (100 + tload2);\n                    int deliver = min(tload2, demands[id].amount);\n                    if (deliver <= 0) break;\n                    tload2 -= deliver;\n                    py = dy; px = dx;\n                    ++real_len;\n                }\n                if (cost < bestcost) {\n                    bestcost = cost;\n                    bestseq = perm;\n                    bestseq.resize(real_len);\n                }\n            } while (next_permutation(perm.begin(), perm.end()));\n            // Execute tour\n            int py = cy, px = cx, tload2 = load;\n            for (int ind = 0; ind < (int)bestseq.size() && tload2 > 0; ++ind) {\n                int id = bestseq[ind];\n                int dy = demands[id].y, dx = demands[id].x;\n                for (char c : get_path(py, px, dy, dx)) commands.push_back(string(1, c)), py+=(c=='D')-(c=='U'), px+=(c=='R')-(c=='L');\n                int deliver = min(tload2, demands[id].amount);\n                if (deliver > 0) {\n                    commands.push_back(\"-\"+to_string(deliver));\n                    demands[id].amount -= deliver;\n                    tload2 -= deliver;\n                    if (demands[id].amount == 0) demands[id].done = true;\n                }\n            }\n            // Now, multi-drop to adjacent demands as long as load > 0!\n            greedy_adj_demands(py, px, tload2, demands, commands);\n            cy = py; cx = px; load = tload2;\n        }\n    }\n    for (auto& s : commands) cout << s << '\\n';\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 6, M = 15, T = 10, SEED_COUNT = 2 * N * (N - 1), GRID_SIZE = N * N;\n\nstruct Seed {\n    vector<int> x;\n    int id, v;\n    Seed(int _id, const vector<int>& _x) : x(_x), id(_id), v(accumulate(x.begin(), x.end(), 0)) {}\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int n, m, t;\n    cin >> n >> m >> t;\n    vector<Seed> seeds;\n    for (int i = 0; i < SEED_COUNT; ++i) {\n        vector<int> x(m);\n        for (int j = 0; j < m; ++j) cin >> x[j];\n        seeds.emplace_back(i, x);\n    }\n\n    mt19937 rng(123456789);\n\n    for (int turn = 0; turn < T; ++turn) {\n        // Step 1: Find feature-wise maxima and their seed IDs\n        vector<int> feature_max(m, 0), best_seed_for_feature(m, -1);\n        for (int j = 0; j < m; ++j)\n            for (size_t i = 0; i < seeds.size(); ++i)\n                if (seeds[i].x[j] >= feature_max[j]) {\n                    feature_max[j] = seeds[i].x[j];\n                    best_seed_for_feature[j] = seeds[i].id;\n                }\n        set<int> unique_max_seeds(best_seed_for_feature.begin(), best_seed_for_feature.end());\n        unique_max_seeds.erase(-1);\n\n        // Step 2: Build a pool of elite seeds (max-feature and high-value)\n        vector<pair<int, int>> score_id; // (score, seed_idx)\n        for (size_t i = 0; i < seeds.size(); ++i) {\n            int maxcnt = 0;\n            for (int j = 0; j < m; ++j)\n                if (seeds[i].x[j] == feature_max[j])\n                    ++maxcnt;\n            int score = seeds[i].v + 80*maxcnt + uniform_int_distribution<int>(0,3)(rng);\n            score_id.emplace_back(score, i);\n        }\n        sort(score_id.rbegin(), score_id.rend());\n\n        vector<int> chosen_ids; // Seed indices to be planted\n        set<int> used;\n        // First, insert all unique max-feature seeds\n        for (int id : unique_max_seeds) {\n            chosen_ids.push_back(id);\n            used.insert(id);\n        }\n        // Then, fill up the grid with highest scoring seeds (avoiding duplicates)\n        for (auto& [score, i] : score_id) {\n            if ((int)chosen_ids.size() == GRID_SIZE) break;\n            if (used.count(seeds[i].id)) continue;\n            chosen_ids.push_back(seeds[i].id);\n            used.insert(seeds[i].id);\n        }\n        // Safety: fill in case not enough chosen\n        for (size_t i = 0; i < seeds.size() && chosen_ids.size() < GRID_SIZE; ++i)\n            if (!used.count(seeds[i].id)) chosen_ids.push_back(seeds[i].id), used.insert(seeds[i].id);\n\n        // Step 3: Assign the chosen seeds to the grid\n        vector<vector<int>> grid(n, vector<int>(n, -1));\n\n        // Place unique max-feature seeds in the central 4x4 block as much as possible (or 5x5 if more than 16)\n        int k = unique_max_seeds.size();\n        int blockSize = (k <= 16) ? 4 : ((k <= 25) ? 5 : 6);\n        int startRow = (N-blockSize)/2, startCol = (N-blockSize)/2;\n        int idx = 0;\n\n        // Place the max-feature seeds in the block, row-major\n        for (int i = 0; i < blockSize && idx < (int)unique_max_seeds.size(); ++i) {\n            for (int j = 0; j < blockSize && idx < (int)unique_max_seeds.size(); ++j) {\n                grid[startRow+i][startCol+j] = *next(unique_max_seeds.begin(), idx++);\n            }\n        }\n        // Now, fill other grid cells with other chosen seeds\n        idx = 0;\n        for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j)\n            if (grid[i][j] == -1) {\n                // Pick the next from chosen_ids not already placed\n                while (idx < (int)chosen_ids.size() && unique_max_seeds.count(chosen_ids[idx])) ++idx;\n                if (idx < (int)chosen_ids.size())\n                    grid[i][j] = chosen_ids[idx++];\n            }\n\n        // Step 4: Output the grid and read next seeds\n        for (int i = 0; i < n; ++i) {\n            for (int j = 0; j < n; ++j)\n                cout << grid[i][j] << (j + 1 < n ? ' ' : '\\n');\n        }\n        cout.flush();\n\n        // Always read 60 new seeds after output, even after last turn, for protocol\n        vector<Seed> next_seeds;\n        for (int k = 0; k < SEED_COUNT; ++k) {\n            vector<int> x(m);\n            for (int j = 0; j < m; ++j) cin >> x[j];\n            next_seeds.emplace_back(k, x);\n        }\n        seeds = move(next_seeds);\n    }\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int x, y; };\n\nvector<Pos> get_leaves(int legs, int len) {\n    vector<Pos> dirs = {{0,1}, {1,0}, {0,-1}, {-1,0}, {1,1}, {-1,1}, {1,-1}, {-1,-1}};\n    vector<Pos> res;\n    int D = dirs.size();\n    for(int i=0; i<legs; ++i){ int m=1+(i/D); res.push_back({dirs[i%D].x*len*m, dirs[i%D].y*len*m}); }\n    return res;\n}\nPos add(Pos a,Pos b){ return {a.x+b.x,a.y+b.y}; }\n\nint main() {\n    int N, M, V; cin>>N>>M>>V;\n    vector<string> s(N), t(N);\n    for(int i=0;i<N;i++) cin>>s[i];\n    for(int i=0;i<N;i++) cin>>t[i];\n    vector<Pos> pick, deliver;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n        if(s[i][j]=='1') pick.push_back({i,j});\n        if(t[i][j]=='1') deliver.push_back({i,j});\n    }\n    int V_=min(V,9), L=1;\n    cout<<V_<<\"\\n\"; for(int i=1;i<V_;i++) cout<<\"0 \"<<L<<\"\\n\"; cout<<\"0 0\\n\";\n    auto leaves = get_leaves(V_-1,L);\n    vector<bool> tip_hold(V_-1,false), picked(pick.size(),false), delivered(deliver.size(),false);\n    int root_x=0, root_y=0, d_cnt=0, T=0;\n\n    while(d_cnt<M&&T<100000){\n        // Get all tips not holding\n        vector<int> free; for(int i=0;i<V_-1;i++) if(!tip_hold[i]) free.push_back(i);\n        vector<int> todo; for(int i=0;i<(int)pick.size()&&todo.size()<free.size();i++) if(!picked[i]) todo.push_back(i);\n        int batch=min(free.size(),todo.size());\n        bool found=false; Pos root; vector<int> assign(V_-1,-1);\n        for(int rx=0;rx<N&&!found;rx++) for(int ry=0;ry<N&&!found;ry++){\n            vector<int> a(V_-1,-1); vector<bool> used(V_-1,0);\n            bool fail=0;\n            for(int b=0;b<batch;b++){\n                bool mt=0;\n                for(int ii=0;ii<(int)free.size();ii++){\n                    int f=free[ii];if(used[f])continue;\n                    auto tip=add({rx,ry},leaves[f]);\n                    if(tip.x<0||tip.y<0||tip.x>=N||tip.y>=N)continue;\n                    if(tip.x==pick[todo[b]].x&&tip.y==pick[todo[b]].y){\n                        a[f]=b;used[f]=1;mt=1;break;}\n                }\n                if(!mt){ fail=1;break;}\n            }\n            if(!fail){ assign=a; root={rx,ry}; found=1;}\n        }\n        if(!found) break;\n        while(root_x<root.x){string s(2*V_,'.');s[0]='D';cout<<s<<\"\\n\";T++;root_x++;}\n        while(root_x>root.x){string s(2*V_,'.');s[0]='U';cout<<s<<\"\\n\";T++;root_x--;}\n        while(root_y<root.y){string s(2*V_,'.');s[0]='R';cout<<s<<\"\\n\";T++;root_y++;}\n        while(root_y>root.y){string s(2*V_,'.');s[0]='L';cout<<s<<\"\\n\";T++;root_y--;}\n        string cmd(2*V_,'.');\n        for(int f=0;f<V_-1;f++) if(assign[f]!=-1){\n            int idx=todo[assign[f]];picked[idx]=1;tip_hold[f]=1;cmd[V_+f+1]='P';\n        }\n        cout<<cmd<<\"\\n\";T++;\n\n        // Now deliver for all tips now holding!\n        vector<int> fill;\n        for(int f=0;f<V_-1;f++) if(tip_hold[f]) fill.push_back(f);\n        vector<int> deldo;\n        for(int i=0;i<(int)deliver.size()&&deldo.size()<fill.size();i++) if(!delivered[i]) deldo.push_back(i);\n        batch=min(fill.size(),deldo.size());\n        found=0; assign=vector<int>(V_-1,-1);\n        for(int rx=0;rx<N&&!found;rx++) for(int ry=0;ry<N&&!found;ry++){\n            vector<int> a(V_-1,-1);vector<bool>used(V_-1,0);bool fail=0;\n            for(int b=0;b<batch;b++){\n                bool mt=0; for(int ii=0;ii<(int)fill.size();ii++){\n                    int f=fill[ii]; if(used[f])continue;\n                    auto tip=add({rx,ry},leaves[f]);\n                    if(tip.x<0||tip.y<0||tip.x>=N||tip.y>=N)continue;\n                    if(tip.x==deliver[deldo[b]].x&&tip.y==deliver[deldo[b]].y){\n                        a[f]=b;used[f]=1;mt=1;break; }\n                }\n                if(!mt){fail=1;break;}\n            }\n            if(!fail){assign=a; root={rx,ry}; found=1;}\n        }\n        if(!found) break;\n        while(root_x<root.x){string s(2*V_,'.');s[0]='D';cout<<s<<\"\\n\";T++;root_x++;}\n        while(root_x>root.x){string s(2*V_,'.');s[0]='U';cout<<s<<\"\\n\";T++;root_x--;}\n        while(root_y<root.y){string s(2*V_,'.');s[0]='R';cout<<s<<\"\\n\";T++;root_y++;}\n        while(root_y>root.y){string s(2*V_,'.');s[0]='L';cout<<s<<\"\\n\";T++;root_y--;}\n        string dcmd(2*V_,'.');\n        for(int f=0;f<V_-1;f++) if(assign[f]!=-1){\n            int idx=deldo[assign[f]];delivered[idx]=1;tip_hold[f]=0;dcmd[V_+f+1]='P';d_cnt++;}\n        cout<<dcmd<<\"\\n\";T++;\n    }\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int GRID = 200;\nconstexpr int FIELD = 100000;\nconstexpr int MAX_PERIM = 400000;\n\nstruct Rect {\n    int x0, y0, x1, y1;\n    int a, b, perim, score;\n    bool operator<(const Rect &o) const {\n        if (score != o.score) return score > o.score;\n        return perim < o.perim;\n    }\n};\n\nint full_perim(int x0, int y0, int x1, int y1, double cell_size) {\n    return 2 * (int)((x1-x0+1)*cell_size) + 2 * (int)((y1-y0+1)*cell_size); \n}\n\nvector<pair<int,int>> makeLShapePolygon(const Rect& main, const Rect& att, int attach_dir, double cell_size) {\n    // attach_dir: 0=left, 1=bottom, 2=right, 3=top\n    // Counterclockwise.\n    int x0 = int(lround(main.x0 * cell_size));\n    int x1 = int(lround((main.x1+1) * cell_size - 1));\n    int y0 = int(lround(main.y0 * cell_size));\n    int y1 = int(lround((main.y1+1) * cell_size - 1));\n    int ax0 = int(lround(att.x0 * cell_size));\n    int ax1 = int(lround((att.x1+1) * cell_size - 1));\n    int ay0 = int(lround(att.y0 * cell_size));\n    int ay1 = int(lround((att.y1+1) * cell_size - 1));\n    vector<pair<int,int>> v;\n    if (attach_dir == 0) {\n        v.push_back({ax0, ay0});\n        v.push_back({ax0, ay1});\n        v.push_back({x0, ay1});\n        v.push_back({x0, y1});\n        v.push_back({x1, y1});\n        v.push_back({x1, y0});\n        v.push_back({x0, y0});\n        v.push_back({ax0, y0});\n    } else if (attach_dir == 1) {\n        v.push_back({ax0, ay0});\n        v.push_back({ax1, ay0});\n        v.push_back({ax1, y0});\n        v.push_back({x1, y0});\n        v.push_back({x1, y1});\n        v.push_back({x0, y1});\n        v.push_back({x0, y0});\n        v.push_back({ax0, y0});\n    } else if (attach_dir == 2) {\n        v.push_back({x0, y0});\n        v.push_back({x0, y1});\n        v.push_back({x1, y1});\n        v.push_back({ax1, y1});\n        v.push_back({ax1, ay1});\n        v.push_back({ax1, ay0});\n        v.push_back({x1, ay0});\n        v.push_back({x1, y0});\n    } else if (attach_dir == 3) {\n        v.push_back({x0, y0});\n        v.push_back({x0, y1});\n        v.push_back({ax0, y1});\n        v.push_back({ax0, ay1});\n        v.push_back({ax1, ay1});\n        v.push_back({ax1, y1});\n        v.push_back({x1, y1});\n        v.push_back({x1, y0});\n    }\n    // Remove sequential duplicates (maybe not needed)\n    vector<pair<int,int>> clean;\n    for (int i=0; i<(int)v.size(); ++i) if (i==0 || v[i]!=v[i-1]) clean.push_back(v[i]);\n    if (!clean.empty() && clean[0] == clean.back()) clean.pop_back();\n    return clean;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    cin >> N;\n    vector<pair<int, int>> mackerels(N), sardines(N);\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n        mackerels[i] = {x, y};\n    }\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n        sardines[i] = {x, y};\n    }\n\n    double cell_size = (double)FIELD / GRID;\n    auto cell = [&](int x, int y) -> pair<int, int> {\n        int cx = min(GRID-1, int(x / cell_size));\n        int cy = min(GRID-1, int(y / cell_size));\n        return {cx, cy};\n    };\n\n    vector<vector<int>> mac_grid(GRID, vector<int>(GRID, 0)), sar_grid(GRID, vector<int>(GRID, 0));\n    for (auto [x,y]: mackerels) {\n        auto [cx,cy] = cell(x,y);\n        mac_grid[cx][cy] += 1;\n    }\n    for (auto [x,y]: sardines) {\n        auto [cx,cy] = cell(x,y);\n        sar_grid[cx][cy] += 1;\n    }\n    vector<vector<int>> mac_sum(GRID+1, vector<int>(GRID+1)), sar_sum(GRID+1, vector<int>(GRID+1));\n    for (int i = 0; i < GRID; ++i) for (int j = 0; j < GRID; ++j) {\n        mac_sum[i+1][j+1] = mac_grid[i][j] + mac_sum[i+1][j] + mac_sum[i][j+1] - mac_sum[i][j];\n        sar_sum[i+1][j+1] = sar_grid[i][j] + sar_sum[i+1][j] + sar_sum[i][j+1] - sar_sum[i][j];\n    }\n    auto rect_sum = [&](int x0,int y0,int x1,int y1, const auto& sum) {\n        return sum[x1+1][y1+1] - sum[x0][y1+1] - sum[x1+1][y0] + sum[x0][y0];\n    };\n\n    int rmin = 4, rmax = 20;\n    Rect main{-1,-1,-1,-1,0,0,0,0};\n    for (int dx = rmin; dx <= rmax; dx += 2) {\n        for (int dy = rmin; dy <= rmax; dy += 2) {\n            for (int x0=0; x0+dx-1<GRID; x0+=max(1,dx/3)) {\n                int x1 = x0+dx-1;\n                for (int y0=0; y0+dy-1<GRID; y0+=max(1,dy/3)) {\n                    int y1=y0+dy-1;\n                    int a = rect_sum(x0,y0,x1,y1,mac_sum);\n                    int b = rect_sum(x0,y0,x1,y1,sar_sum);\n                    int score = a-b+1;\n                    int perim = 2*(int)((x1-x0+1)*cell_size) + 2*(int)((y1-y0+1)*cell_size);\n                    if (score <= 0 || perim > MAX_PERIM) continue;\n                    Rect r = {x0,y0,x1,y1,a,b,perim,score};\n                    if (main.score < r.score || (main.score == r.score && r.perim < main.perim)) main = r;\n                }\n            }\n        }\n    }\n\n    // Greedy expansion of main rectangle\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        vector<tuple<int,int,int,int>> deltas = {\n            {-1,0,0,0},    // left\n            {0,-1,0,0},    // bottom\n            {0,0,1,0},     // right\n            {0,0,0,1}      // top\n        };\n        for (auto [dlx,dly,drx,dry] : deltas) {\n            int nx0=main.x0+dlx, ny0=main.y0+dly, nx1=main.x1+drx, ny1=main.y1+dry;\n            if(nx0<0 || ny0<0 || nx1>=GRID || ny1>=GRID || nx0>nx1 || ny0>ny1) continue;\n            int a=rect_sum(nx0,ny0,nx1,ny1,mac_sum);\n            int b=rect_sum(nx0,ny0,nx1,ny1,sar_sum);\n            int score=a-b+1;\n            int perim = 2*(int)((nx1-nx0+1)*cell_size) + 2*(int)((ny1-ny0+1)*cell_size);\n            if (score > main.score && perim <= MAX_PERIM) {\n                main = {nx0,ny0,nx1,ny1,a,b,perim,score};\n                improved = true;\n                break;\n            }\n        }\n    }\n\n    // Try to add a \"notch\" (attach rectangle) to the main rectangle for L-shape\n    Rect best_att{-1,-1,-1,-1,0,0,0,0};\n    int best_dir = -1;\n    int best_score = main.score;\n\n    // For each direction, search for best attachment\n    for (int dir=0; dir<4; ++dir) {\n        int base_x0 = main.x0, base_y0 = main.y0, base_x1 = main.x1, base_y1 = main.y1;\n        for (int span1 = 2; span1 <= 14; ++span1) {\n            for (int span2 = 2; span2 <= 14; ++span2) {\n                int ax0, ay0, ax1, ay1;\n                if (dir == 0 && main.x0 - span1 >= 0) { // left\n                    ax0 = main.x0 - span1; ax1 = main.x0 - 1;\n                    for (int ylo = base_y0; ylo <= base_y1 - span2 + 1; ++ylo) {\n                        ay0 = ylo, ay1 = ylo + span2 - 1;\n                        int a = rect_sum(ax0, ay0, ax1, ay1, mac_sum);\n                        int b = rect_sum(ax0, ay0, ax1, ay1, sar_sum);\n                        if (a==0) continue;\n                        int att_score = main.a + a - (main.b + b) + 1;\n                        int minx = min(main.x0, ax0), maxx = max(main.x1, ax1);\n                        int miny = min(main.y0, ay0), maxy = max(main.y1, ay1);\n                        int perim = full_perim(minx, miny, maxx, maxy, cell_size);\n                        if (att_score > best_score && perim <= MAX_PERIM) {\n                            best_score = att_score;\n                            best_att = {ax0, ay0, ax1, ay1, a, b, 0, att_score};\n                            best_dir = dir;\n                        }\n                    }\n                } else if (dir == 1 && main.y0 - span1 >= 0) { // bottom\n                    ay0 = main.y0 - span1; ay1 = main.y0 - 1;\n                    for (int xlo = base_x0; xlo <= base_x1 - span2 + 1; ++xlo) {\n                        ax0 = xlo, ax1 = xlo + span2 - 1;\n                        int a = rect_sum(ax0, ay0, ax1, ay1, mac_sum);\n                        int b = rect_sum(ax0, ay0, ax1, ay1, sar_sum);\n                        if(a==0) continue;\n                        int att_score = main.a + a - (main.b + b) + 1;\n                        int minx = min(main.x0, ax0), maxx = max(main.x1, ax1);\n                        int miny = min(main.y0, ay0), maxy = max(main.y1, ay1);\n                        int perim = full_perim(minx, miny, maxx, maxy, cell_size);\n                        if (att_score > best_score && perim <= MAX_PERIM) {\n                            best_score = att_score;\n                            best_att = {ax0, ay0, ax1, ay1, a, b, 0, att_score};\n                            best_dir = dir;\n                        }\n                    }\n                } else if (dir == 2 && main.x1 + span1 < GRID) { // right\n                    ax0 = main.x1 + 1; ax1 = main.x1 + span1;\n                    for (int ylo = base_y0; ylo <= base_y1 - span2 + 1; ++ylo) {\n                        ay0 = ylo, ay1 = ylo + span2 - 1;\n                        int a = rect_sum(ax0, ay0, ax1, ay1, mac_sum);\n                        int b = rect_sum(ax0, ay0, ax1, ay1, sar_sum);\n                        if(a==0) continue;\n                        int att_score = main.a + a - (main.b + b) + 1;\n                        int minx = min(main.x0, ax0), maxx = max(main.x1, ax1);\n                        int miny = min(main.y0, ay0), maxy = max(main.y1, ay1);\n                        int perim = full_perim(minx, miny, maxx, maxy, cell_size);\n                        if (att_score > best_score && perim <= MAX_PERIM) {\n                            best_score = att_score;\n                            best_att = {ax0, ay0, ax1, ay1, a, b, 0, att_score};\n                            best_dir = dir;\n                        }\n                    }\n                } else if (dir == 3 && main.y1 + span1 < GRID) { // top\n                    ay0 = main.y1 + 1; ay1 = main.y1 + span1;\n                    for (int xlo = base_x0; xlo <= base_x1 - span2 + 1; ++xlo) {\n                        ax0 = xlo, ax1 = xlo + span2 - 1;\n                        int a = rect_sum(ax0, ay0, ax1, ay1, mac_sum);\n                        int b = rect_sum(ax0, ay0, ax1, ay1, sar_sum);\n                        if(a==0) continue;\n                        int att_score = main.a + a - (main.b + b) + 1;\n                        int minx = min(main.x0, ax0), maxx = max(main.x1, ax1);\n                        int miny = min(main.y0, ay0), maxy = max(main.y1, ay1);\n                        int perim = full_perim(minx, miny, maxx, maxy, cell_size);\n                        if (att_score > best_score && perim <= MAX_PERIM) {\n                            best_score = att_score;\n                            best_att = {ax0, ay0, ax1, ay1, a, b, 0, att_score};\n                            best_dir = dir;\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    if (best_dir == -1) {\n        // Just output expanded rectangle, as before\n        int xLB = int(lround(main.x0 * cell_size));\n        int xRT = int(lround((main.x1+1) * cell_size - 1));\n        int yLB = int(lround(main.y0 * cell_size));\n        int yRT = int(lround((main.y1+1) * cell_size - 1));\n        vector<pair<int,int>> corners = {\n            {xLB, yLB},\n            {xLB, yRT},\n            {xRT, yRT},\n            {xRT, yLB}\n        };\n        cout << 4 << '\\n';\n        for(auto [x, y] : corners) cout << x << ' ' << y << '\\n';\n    } else {\n        auto poly = makeLShapePolygon(main, best_att, best_dir, cell_size);\n        cout << poly.size() << '\\n';\n        for (auto [x,y] : poly)\n            cout << x << \" \" << y << '\\n';\n    }\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect {\n    int idx;\n    int w, h;\n};\n\nstruct PlacedRect {\n    int idx, x, y, w, h;\n};\n\nstruct Placement {\n    int p, r;     // rect index, rotation\n    char d;       // direction 'U'/'L'\n    int b;        // base: -1 or one of 0..(p-1)\n    Placement(int p, int r, char d, int b) : p(p), r(r), d(d), b(b) {}\n};\n\nbool overlap(const PlacedRect& a, const PlacedRect& b) {\n    return !(a.x + a.w <= b.x || b.x + b.w <= a.x ||\n             a.y + a.h <= b.y || b.y + b.h <= a.y);\n}\n\nstruct PkgResult {\n    vector<Placement> placements;\n    int sum; // W+H+sum_{skipped}(w+h)\n    int boxw, boxh;\n    vector<int> skipped;\n};\n\nPkgResult best_blplus(const vector<Rect>& rects, const vector<int>& mask, const vector<int>& skipped, int criterion=0) {\n    // criterion: 0=perimeter (w+h), 1=area (w*h)\n    int n = mask.size();\n    vector<Placement> res;\n    vector<PlacedRect> placed;\n    int box_w = 0, box_h = 0;\n    for (int iidx = 0; iidx < n; ++iidx) {\n        int i = mask[iidx];\n        int best_r = 0, best_b = -1;\n        char best_d = 'U';\n        int best_x = -1, best_y = -1;\n        int min_score = INT_MAX, min_area = INT_MAX, min_yx = INT_MAX;\n        for (int r = 0; r < 2; ++r) {\n            int wi = (r == 0 ? rects[i].w : rects[i].h);\n            int hi = (r == 0 ? rects[i].h : rects[i].w);\n            for (char d : {'U', 'L'}) {\n                vector<int> base_idx = {-1};\n                for (int bidx = 0; bidx < (int)placed.size(); ++bidx) base_idx.push_back(bidx);\n                for (int b : base_idx) {\n                    int x=0, y=0;\n                    if (d == 'U') {\n                        x = (b==-1)?0:placed[b].x;\n                        int max_y = 0;\n                        for(const auto& rpr: placed){\n                            if (b!=-1 && rpr.idx==placed[b].idx) continue;\n                            int overlap_left = max(x, rpr.x);\n                            int overlap_right = min(x+wi, rpr.x+rpr.w);\n                            if(overlap_left < overlap_right){\n                                max_y = max(max_y, rpr.y + rpr.h);\n                            }\n                        }\n                        y = max_y;\n                    } else {\n                        y = (b==-1)?0:placed[b].y;\n                        int max_x = 0;\n                        for(const auto& rpr: placed){\n                            if (b!=-1 && rpr.idx==placed[b].idx) continue;\n                            int overlap_top = max(y, rpr.y);\n                            int overlap_bot = min(y+hi, rpr.y+rpr.h);\n                            if(overlap_top < overlap_bot){\n                                max_x = max(max_x, rpr.x + rpr.w);\n                            }\n                        }\n                        x = max_x;\n                    }\n                    if(x<0||y<0) continue;\n                    PlacedRect test = {i, x, y, wi, hi};\n                    bool ok = true;\n                    for (const auto& pr: placed){\n                        if(overlap(pr,test)){ok=false;break;}\n                    }\n                    if (!ok) continue;\n                    int max_x = x+wi, max_y = y+hi;\n                    for(auto& pr:placed){\n                        max_x = max(max_x, pr.x+pr.w);\n                        max_y = max(max_y, pr.y+pr.h);\n                    }\n                    int perim = max_x + max_y;\n                    int area = max_x * max_y;\n                    int score = criterion == 0 ? perim : area;\n                    int bl_tiebreak = y*1000000 + x;\n                    if(score < min_score\n                        || (score==min_score && area<min_area)\n                        || (score==min_score && area==min_area && bl_tiebreak<min_yx)){\n                        min_score = score;\n                        min_area = area;\n                        min_yx = bl_tiebreak;\n                        best_r = r; best_d = d; best_b = b; best_x = x; best_y = y;\n                    }\n                }\n            }\n        }\n        if (best_x==-1) { // fallback (should not happen)\n            best_r = 0; best_d = 'U'; best_b = -1; best_x = box_w; best_y = 0;\n        }\n        res.emplace_back(rects[i].idx, best_r, best_d, (best_b==-1?-1:placed[best_b].idx));\n        int wi = (best_r==0?rects[i].w:rects[i].h);\n        int hi = (best_r==0?rects[i].h:rects[i].w);\n        placed.push_back({rects[i].idx, best_x, best_y, wi, hi});\n        box_w = max(box_w, best_x+wi);\n        box_h = max(box_h, best_y+hi);\n    }\n    // Score: W+H+sum_of_skipped\n    int sum = box_w + box_h;\n    for (int i: skipped) sum += rects[i].w + rects[i].h;\n    return {res, sum, box_w, box_h, skipped};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    int N,T,sigma;\n    cin >> N >> T >> sigma;\n    vector<Rect> rects(N);\n    for (int i=0; i<N; ++i) {\n        int w,h;\n        cin >> w >> h;\n        rects[i] = {i,w,h};\n    }\n    // 1. All indices ('none skipped')\n    vector<int> allidx(N); iota(allidx.begin(), allidx.end(), 0);\n    vector<int> nullskip;\n    vector<PkgResult> soups;\n\n    // Try both perimeter and area minimization for 'none skipped'\n    for (int crit=0; crit<=1; ++crit) {\n        auto r = best_blplus(rects, allidx, nullskip, crit);\n        soups.push_back(r);\n    }\n\n    // Now skip-1\n    vector<pair<int,int>> byscore;\n    for (int i=0; i<N; ++i) {\n        vector<int> mask; for(int j=0;j<N;++j) if(j!=i) mask.push_back(j);\n        auto r = best_blplus(rects, mask, {i}, 0);\n        byscore.emplace_back(r.sum, i);\n        soups.push_back(r);\n    }\n    sort(byscore.begin(), byscore.end());\n    // Best 8 skip-1\n    int skip2tested = 0;\n    for(int k=0; k<min(8,N); ++k) {\n        int i = byscore[k].second;\n        for(int j = k+1; j<min(12,N); ++j) { // try more most-promising j\n            int jj = byscore[j].second;\n            if(i==jj) continue;\n            vector<int> mask;\n            for(int q=0;q<N;++q) if(q!=i && q!=jj) mask.push_back(q);\n            auto r = best_blplus(rects, mask, {i,jj}, 0);\n            soups.push_back(r);\n            if(++skip2tested>25) break;\n        }\n        if(skip2tested>25) break;\n    }\n\n    // Fill up to T slots, round robin over the soups\n    for(int t=0;t<T;++t){\n        auto& r = soups[t % soups.size()];\n        cout<<r.placements.size()<<'\\n';\n        for(auto& pl:r.placements) cout<<pl.p<<' '<<pl.r<<' '<<pl.d<<' '<<pl.b<<'\\n';\n        cout<<flush;\n        int W, H; cin>>W>>H;\n    }\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Calculate attractiveness score for given solution\nlong long calc_score(int N, const vector<int> &A, const vector<int> &depth) {\n    long long s = 0;\n    for(int i=0; i<N; ++i)  s += (long long)(depth[i]+1)*A[i];\n    return s;\n}\n\n// BFS or DFS expansion function (\"dfs\" flag: true for DFS, false for BFS)\nvoid expand_tree(const vector<vector<int>> &adj, const vector<int> &A, int H, bool dfs_mode,\n    vector<int> &parent, vector<int> &depth, vector<bool> &assigned,\n    int v)\n{\n    parent[v] = -1;\n    depth[v] = 0;\n    assigned[v] = true;\n    if(!dfs_mode) {\n        queue<pair<int,int>> q;\n        q.emplace(v, 0);\n        while(!q.empty()) {\n            auto [cur, d] = q.front(); q.pop();\n            if (d == H) continue;\n            vector<pair<int, int>> nbrs;\n            for(int nb: adj[cur]) if (!assigned[nb]) nbrs.emplace_back(-A[nb], nb);\n            sort(nbrs.begin(), nbrs.end());\n            for(auto& [negA, nb]: nbrs) {\n                if (assigned[nb]) continue;\n                parent[nb] = cur;\n                depth[nb] = d+1;\n                assigned[nb] = true;\n                q.emplace(nb, d+1);\n            }\n        }\n    } else {\n        stack<pair<int,int>> q;\n        q.emplace(v, 0);\n        while(!q.empty()) {\n            auto [cur, d] = q.top(); q.pop();\n            if(d == H) continue;\n            vector<pair<int,int>> nbrs;\n            for(int nb: adj[cur]) if (!assigned[nb]) nbrs.emplace_back(-A[nb], nb);\n            sort(nbrs.begin(), nbrs.end());\n            for(auto& [negA, nb]: nbrs) {\n                if (assigned[nb]) continue;\n                parent[nb] = cur;\n                depth[nb] = d+1;\n                assigned[nb] = true;\n                q.emplace(nb, d+1);\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, H;\n    cin >> N >> M >> H;\n    vector<int> A(N);\n    for(auto &x: A) cin >> x;\n\n    vector<vector<int>> adj(N);\n    for(int i=0;i<M;++i) {\n        int u, v; cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    // Skip coords\n    int dummy;\n    for(int i=0; i < N*2; ++i) cin >> dummy;\n\n    // Compute root order\n    vector<int> node_order(N);\n    iota(node_order.begin(), node_order.end(), 0);\n    sort(node_order.begin(), node_order.end(), [&](int i, int j){ return A[i] > A[j]; });\n\n    // Solution/score for BFS and DFS\n    vector<vector<int>> parents(2, vector<int>(N, -1));\n    vector<vector<int>> depths(2, vector<int>(N, -1));\n    vector<vector<bool>> assigneds(2, vector<bool>(N, false));\n    for(int kind=0; kind<2; ++kind) {\n        vector<int> &parent = parents[kind];\n        vector<int> &depth = depths[kind];\n        vector<bool> &assigned = assigneds[kind];\n        for(int idx=0; idx<N; ++idx) {\n            int v = node_order[idx];\n            if(assigned[v]) continue;\n            expand_tree(adj, A, H, kind==1, parent, depth, assigned, v);\n        }\n    }\n    // Choose best\n    long long score0 = calc_score(N, A, depths[0]);\n    long long score1 = calc_score(N, A, depths[1]);\n    vector<int> &parent = (score0 >= score1) ? parents[0] : parents[1];\n    for(int i=0;i<N;++i)\n        cout << parent[i] << (i+1==N ? '\\n' : ' ');\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\n// For each Oni, find a safe direction in the initial board and output shift sequence\n// Don't update the board as Oni are \"removed\" -- just as per the guarantee\n\nstruct Move {\n    char dir;\n    int idx;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N;\n    cin >> N;\n    vector<string> board(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> board[i];\n    }\n\n    // Save Oni positions at start\n    vector<pair<int,int>> onis;\n    for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j)\n        if (board[i][j] == 'x') onis.emplace_back(i,j);\n\n    vector<Move> moves;\n\n    // For safety, mark direction per Oni before generating commands\n    // Board is NOT mutated!\n    for (auto [i, j] : onis) {\n        // Try all 4 directions in the initial board\n        // Up (remove by shifting col up i+1 times)\n        bool upSafe = true;\n        for (int k = 0; k < i; ++k) if (board[k][j] == 'o') { upSafe = false; break; }\n\n        // Down\n        bool downSafe = true;\n        for (int k = i+1; k < N; ++k) if (board[k][j] == 'o') { downSafe = false; break; }\n\n        // Left\n        bool leftSafe = true;\n        for (int k = 0; k < j; ++k) if (board[i][k] == 'o') { leftSafe = false; break; }\n\n        // Right\n        bool rightSafe = true;\n        for (int k = j+1; k < N; ++k) if (board[i][k] == 'o') { rightSafe = false; break; }\n\n        // Remove Oni at (i,j) by safe direction and undo\n        if (upSafe) {\n            // Shift col j up i+1 times, then down i times\n            for (int t = 0; t < i+1; ++t)\n                moves.push_back({'U', j});\n            for (int t = 0; t < i; ++t)\n                moves.push_back({'D', j});\n            continue;\n        }\n        if (downSafe) {\n            // Shift col j down N-i times, then up N-i-1 times\n            for (int t = 0; t < N-i; ++t)\n                moves.push_back({'D', j});\n            for (int t = 0; t < N-i-1; ++t)\n                moves.push_back({'U', j});\n            continue;\n        }\n        if (leftSafe) {\n            // Shift row i left j+1 times, then right j times\n            for (int t = 0; t < j+1; ++t)\n                moves.push_back({'L', i});\n            for (int t = 0; t < j; ++t)\n                moves.push_back({'R', i});\n            continue;\n        }\n        if (rightSafe) {\n            // Shift row i right N-j times, then left N-j-1 times\n            for (int t = 0; t < N-j; ++t)\n                moves.push_back({'R', i});\n            for (int t = 0; t < N-j-1; ++t)\n                moves.push_back({'L', i});\n            continue;\n        }\n        // If this point is reached, the guarantee is violated (shouldn't happen)\n        cerr << \"No safe direction for Oni at (\" << i << \",\" << j << \") in initial board\\n\";\n        assert(false);\n    }\n\n    for (auto &mv : moves) {\n        cout << mv.dir << ' ' << mv.idx << '\\n';\n    }\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\n// Constants\nconstexpr int N = 100;\nconstexpr int L = 500000;\n\nint T[N];\nint a[N], b[N];\n\n// Estimate frequencies by fast simulation, possibly multiple starts to break short cycles\nvector<double> estimate_freq(const int a[N], const int b[N], int steps = 100000) {\n    vector<double> freq(N, 0.0);\n    int repeat = 3;\n    for(int starter = 0; starter < repeat; ++starter) {\n        vector<int> count(N, 0);\n        int cur = starter % N;\n        vector<int> visited(N, 0);\n        count[cur]++;\n        visited[cur]=1;\n        for(int step = 1; step < steps; ++step) {\n            int occ = count[cur];\n            int nxt = (occ % 2 == 1) ? a[cur] : b[cur];\n            cur = nxt;\n            count[cur]++;\n            visited[cur]=1;\n        }\n        // Ignore nodes never visited in this segment\n        int sm = 0;\n        for(int i=0; i<N; ++i) sm += count[i];\n        for(int i=0; i<N; ++i) freq[i] += double(count[i])/repeat;\n    }\n    // Normalize for steps\n    double tot = accumulate(freq.begin(), freq.end(), 0.0);\n    for(int i=0; i<N; ++i) freq[i] /= tot;\n    return freq;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    int n, l;\n    cin >> n >> l;\n    for(int i=0; i<N; ++i) cin >> T[i];\n\n    // STEP 1: Initial assignment, degree-proportional assignment\n    // Calculate quotas\n    vector<pair<double,int>> q;\n    for(int i=0; i<N; ++i) \n        q.emplace_back((double)T[i]/L,i);\n    sort(q.rbegin(),q.rend());\n\n    // Distribute incoming edges roughly according to quota\n    vector<int> indeg(N,0);\n    for(int i=0; i<N; ++i) {\n        set<int> pickset;\n        while(pickset.size() < 2) {\n            // Weighted selection\n            int idx = 0;\n            double sel = double(rand())/RAND_MAX;\n            double s = 0;\n            for(auto& [p,j]: q) {\n                s += p;\n                if(sel<=s && j!=i) { idx=j; break;}\n            }\n            if(idx==i || pickset.count(idx)) continue;\n            pickset.insert(idx);\n        }\n        auto it = pickset.begin();\n        a[i]=*it++;\n        b[i]=*it;\n        indeg[a[i]]++; indeg[b[i]]++;\n    }\n    \n    // Minor fix to remove self-loops\n    for(int i=0; i<N; ++i) {\n        if(a[i]==i || b[i]==i) {\n            int other = a[i]==i ? b[i] : a[i];\n            for(int j=0;j<N;++j) {\n                if(j!=i && a[j]!=i && b[j]!=i && a[j]!=b[j]) {\n                    if(a[i]==i) a[i]=j; else b[i]=j;\n                    break;\n                }\n            }\n        }\n    }\n\n    // Main tuning\n    auto start_time = chrono::steady_clock::now();\n    const double TIME_LIMIT = 1.8;\n\n    // Prepare fast random engine\n    mt19937 rng(123456);\n\n    // Run iterative rebalancing and local search\n    int loopct = 0;\n    double best_error = 1e18;\n    int best_a[N], best_b[N];\n    memcpy(best_a,a,sizeof(a));\n    memcpy(best_b,b,sizeof(b));\n    vector<double> best_freq;\n    while(true) {\n        ++loopct;\n        // Estimate freq\n        auto freq = estimate_freq(a,b,350000);\n        // Compute actual t_i\n        double score = 0;\n        for(int i=0;i<N;++i) score += abs(freq[i]*L-T[i]);\n        if(score < best_error) {\n            best_error = score;\n            memcpy(best_a,a,sizeof(a));\n            memcpy(best_b,b,sizeof(b));\n            best_freq = freq;\n        }\n        // Check time\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if(elapsed > TIME_LIMIT) break;\n\n        // Find most over/under assigned\n        int over=-1, under=-1;\n        double max_over=0, max_under=0;\n        for(int i=0;i<N;++i) {\n            double diff = freq[i]*L - T[i];\n            if(diff > max_over) { max_over = diff; over = i; }\n            if(diff < max_under) { max_under = diff; under = i; }\n        }\n        if(over == -1 || under == -1) break; // (Actually perfect)\n\n        // Try to reroute some edges from over to under\n        bool changed = false;\n        // Try changing some a_j or b_j that point to 'over'\n        vector<int> candidates;\n        for(int j=0;j<N;++j) if(a[j]==over || b[j]==over) candidates.push_back(j);\n        shuffle(candidates.begin(),candidates.end(),rng);\n        for(int cand: candidates) {\n            if(a[cand]==over && under!=cand) {\n                int old=a[cand]; a[cand]=under;\n                auto f2=estimate_freq(a,b,50000);\n                double s2 = 0;\n                for(int i=0;i<N;++i) s2 += abs(f2[i]*L-T[i]);\n                if(s2 < score) { changed=true; break;}\n                a[cand]=old;\n            }\n            if(b[cand]==over && under!=cand) {\n                int old=b[cand]; b[cand]=under;\n                auto f2=estimate_freq(a,b,50000);\n                double s2 = 0;\n                for(int i=0;i<N;++i) s2 += abs(f2[i]*L-T[i]);\n                if(s2 < score) { changed=true; break;}\n                b[cand]=old;\n            }\n        }\n        if(!changed) {\n            // As fallback, random swap for diversity\n            int i = rng()%N;\n            int pos = rng()%2;\n            int nv = rng()%N;\n            if(nv==i) continue;\n            if(pos==0) a[i]=nv; else b[i]=nv;\n        }\n    }\n    // Output\n    for(int i=0; i<N; ++i) \n        cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct City {\n    int id;\n    int lx, rx, ly, ry;\n    double cx, cy;\n};\n\nstruct UF {\n    vector<int> par;\n    UF(int n) : par(n) { iota(par.begin(), par.end(), 0); }\n    int find(int x) {\n        if (par[x] == x) return x;\n        return par[x] = find(par[x]);\n    }\n    bool unite(int x, int y) {\n        int rx = find(x), ry = find(y);\n        if (rx == ry) return false;\n        par[ry] = rx; return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, Q, L, W;\n    cin >> N >> M >> Q >> L >> W;\n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n\n    vector<City> cities(N);\n    for (int i = 0; i < N; ++i) {\n        int lx, rx, ly, ry;\n        cin >> lx >> rx >> ly >> ry;\n        cities[i] = {i, lx, rx, ly, ry, 0.5 * (lx + rx), 0.5 * (ly + ry)};\n    }\n\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int i, int j) {\n        if (abs(cities[i].cx - cities[j].cx) > 1e-6)\n            return cities[i].cx < cities[j].cx;\n        return cities[i].cy < cities[j].cy;\n    });\n\n    vector<vector<int>> groups;\n    int ofs = 0;\n    for (int i = 0; i < M; ++i) {\n        vector<int> grp;\n        for (int k = 0; k < G[i]; ++k, ++ofs)\n            grp.push_back(idx[ofs]);\n        groups.push_back(grp);\n    }\n\n    vector<vector<pair<int, int>>> all_edges(M);\n\n    int queries_used = 0;\n    for (int gi = 0; gi < M; ++gi) {\n        const auto& grp = groups[gi];\n        int sz = grp.size();\n        set<pair<int, int>> group_edges;\n\n        if (sz == 1) {\n            // No edge required for single-node group.\n        } else if (sz <= L && queries_used < Q) {\n            cout << \"? \" << sz;\n            for (int x : grp) cout << \" \" << x;\n            cout << endl; cout.flush();\n            for (int i = 0; i < sz - 1; ++i) {\n                int u, v;\n                cin >> u >> v;\n                if (u > v) swap(u, v);\n                group_edges.emplace(u, v);\n            }\n            ++queries_used;\n        } else {\n            for (int st = 0; st < sz && queries_used < Q; st += (L - 1)) {\n                int en = min(sz, st + L);\n                int actual = en - st;\n                if (actual < 2) continue;\n                vector<int> subset(grp.begin() + st, grp.begin() + en);\n                unordered_set<int> subset_set(subset.begin(), subset.end());\n                cout << \"? \" << actual;\n                for (int x : subset) cout << \" \" << x;\n                cout << endl; cout.flush();\n                for (int i = 0; i < actual - 1; ++i) {\n                    int u, v;\n                    cin >> u >> v;\n                    if (u > v) swap(u, v);\n                    // Defensive: only add if both endpoints belong to the group\n                    if (subset_set.count(u) && subset_set.count(v)) {\n                        group_edges.emplace(u, v);\n                    }\n                }\n                ++queries_used;\n            }\n        }\n\n        // Defensive group index mapping\n        int V = sz;\n        map<int, int> city_to_groupidx;\n        for (int i = 0; i < sz; ++i)\n            city_to_groupidx[grp[i]] = i;\n\n        UF uf(V);\n        for (auto [u, v] : group_edges) {\n            auto it_u = city_to_groupidx.find(u);\n            auto it_v = city_to_groupidx.find(v);\n            if (it_u != city_to_groupidx.end() && it_v != city_to_groupidx.end()) {\n                uf.unite(it_u->second, it_v->second);\n            }\n        }\n        vector<tuple<int, int, int>> center_edges;\n        for (int i = 0; i < sz; ++i) {\n            for (int j = i + 1; j < sz; ++j) {\n                int u = grp[i], v = grp[j];\n                double dx = cities[u].cx - cities[v].cx, dy = cities[u].cy - cities[v].cy;\n                int d = (int)floor(hypot(dx, dy));\n                center_edges.emplace_back(d, i, j);\n            }\n        }\n        sort(center_edges.begin(), center_edges.end());\n        UF final_uf(V);\n        set<pair<int, int>> final_edges = group_edges;\n        for (auto [u, v] : group_edges) {\n            auto it_u = city_to_groupidx.find(u);\n            auto it_v = city_to_groupidx.find(v);\n            if (it_u != city_to_groupidx.end() && it_v != city_to_groupidx.end())\n                final_uf.unite(it_u->second, it_v->second);\n        }\n        for (auto [d, i, j] : center_edges) {\n            if ((int)final_edges.size() >= sz - 1) break;\n            if (final_uf.unite(i, j)) {\n                int u = grp[i], v = grp[j];\n                if (u > v) swap(u, v);\n                final_edges.emplace(u, v);\n            }\n        }\n        all_edges[gi].assign(final_edges.begin(), final_edges.end());\n    }\n\n    cout << \"!\" << endl;\n    for (int gi = 0; gi < M; ++gi) {\n        const auto &grp = groups[gi];\n        for (int i = 0; i < (int)grp.size(); ++i) {\n            if (i) cout << \" \";\n            cout << grp[i];\n        }\n        cout << endl;\n        for (auto [u, v] : all_edges[gi])\n            cout << u << \" \" << v << endl;\n    }\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 20, M = 40;\nconstexpr int DX[4] = {-1, 1, 0, 0}; // U D L R\nconstexpr int DY[4] = { 0, 0, -1, 1};\nconstexpr char DIRC[4] = {'U', 'D', 'L', 'R'};\n\nstruct Pos {\n    int x, y;\n    bool operator==(const Pos& o) const { return x == o.x && y == o.y; }\n};\n\nbool inRange(int x, int y) { return 0 <= x && x < N && 0 <= y && y < N; }\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n, m;\n    cin >> n >> m;\n    vector<Pos> tgt(m);\n    for (int i = 0; i < m; ++i) cin >> tgt[i].x >> tgt[i].y;\n\n    vector<vector<bool>> blocked(N, vector<bool>(N, false));\n    Pos cur = tgt[0];\n\n    for (int step = 1; step < m; ++step) {\n        Pos goal = tgt[step];\n        while (!(cur == goal)) {\n            int best_d = -1, best_dist = INT_MAX;\n            for (int d = 0; d < 4; ++d) {\n                int nx = cur.x + DX[d], ny = cur.y + DY[d];\n                if (!inRange(nx, ny)) continue;\n                if (blocked[nx][ny]) continue;\n                int dist = abs(nx - goal.x) + abs(ny - goal.y);\n                if (dist < best_dist) {\n                    best_dist = dist;\n                    best_d = d;\n                }\n            }\n            if (best_d == -1) break; // No move possible (should never happen)\n            cur.x += DX[best_d];\n            cur.y += DY[best_d];\n            cout << \"M \" << DIRC[best_d] << \"\\n\";\n        }\n    }\n}"},"16":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing i64 = int64_t;\n\nstruct Rect {\n    int x1, y1, x2, y2;\n    i64 area() const { return i64(x2-x1)*i64(y2-y1); }\n    bool contains(double x, double y) const {\n        return x > x1 && x < x2 && y > y1 && y < y2;\n    }\n    bool overlap(const Rect& o) const {\n        return !(x2 <= o.x1 || x1 >= o.x2 || y2 <= o.y1 || y1 >= o.y2);\n    }\n};\nstruct PlacedRect { int idx; Rect r; };\nstruct Company {\n    int id, x, y;\n    i64 r;\n    int density;\n    Rect rect;\n};\n\nconstexpr int GRID_SIZE = 10000;\n\nbool checkOverlap(const Rect& r, const vector<PlacedRect>& placedRects, int skip=-1) {\n    for (const auto &o: placedRects)\n        if (o.idx != skip && r.overlap(o.r)) return true;\n    return false;\n}\nRect try_place(int cx, int cy, i64 ri, const vector<PlacedRect>& placedRects) {\n    int best_w=0, best_h=0, sx=0, sy=0;\n    double best_score=1e18;\n    for (int ratio = -20; ratio <= 20; ++ratio) {\n        int w = max(1,int(sqrt(double(ri))+ratio));\n        int h = max(1,int((ri+w-1)/w));\n        if (i64(w)*h < ri) continue;\n        for (int dx=-1; dx<=1; ++dx) for (int dy=-1; dy<=1; ++dy) {\n            int x1 = clamp(cx-w/2+dx, 0, GRID_SIZE-w), y1 = clamp(cy-h/2+dy, 0, GRID_SIZE-h);\n            int x2=x1+w, y2=y1+h;\n            if (!(x1<x2 && y1<y2)) continue;\n            Rect r{x1,y1,x2,y2};\n            double xx=cx+0.5, yy=cy+0.5;\n            if (xx<=x1 || xx>=x2 || yy<=y1 || yy>=y2) continue;\n            if (checkOverlap(r,placedRects)) continue;\n            double score=abs(double(r.area()-ri))+0.1*(w-h)*(w-h);\n            if (score<best_score) { best_score=score; best_w=w; best_h=h; sx=x1; sy=y1; }\n        }\n    }\n    if (best_score<1e17) return Rect{sx, sy, sx+best_w, sy+best_h};\n    return Rect{-1,-1,-1,-1};\n}\nRect emergency_fallback(int px,int py,const vector<PlacedRect>& placedRects) {\n    vector<pair<int,int>> deltas = {{0,0},{-1,0},{1,0},{0,-1},{0,1},{-1,-1},{-1,1},{1,-1},{1,1},{-2,0},{2,0},{0,-2},{0,2}};\n    for (auto [dx,dy]: deltas) {\n        int x=px+dx,y=py+dy;\n        if (x<0||x>=GRID_SIZE) continue;\n        if (y<0||y>=GRID_SIZE) continue;\n        Rect r{x,y,x+1,y+1};\n        if (!checkOverlap(r,placedRects)) return r;\n    }\n    for (int dist=1; dist<=20; ++dist)\n        for (int dx=-dist; dx<=dist; ++dx)\n            for (int dy=-dist; dy<=dist; ++dy) {\n                if (abs(dx)!=dist && abs(dy)!=dist) continue;\n                int x=px+dx, y=py+dy;\n                if (x<0||x>=GRID_SIZE||y<0||y>=GRID_SIZE) continue;\n                Rect r{x,y,x+1,y+1};\n                if (!checkOverlap(r,placedRects)) return r;\n            }\n    for (int x=0;x<GRID_SIZE;++x)for(int y=0;y<GRID_SIZE;++y){\n        Rect r{x,y,x+1,y+1};\n        if (!checkOverlap(r,placedRects)) return r;\n    }\n    return Rect{0,0,1,1};\n}\nRect expand_rect(const Rect& ini, int cx, int cy, int idx, const vector<PlacedRect>& placedRects, i64 area_limit=1e8) {\n    Rect r=ini; bool advanced=1;\n    int rounds=0;\n    while (advanced && r.area()<area_limit && rounds<200) {\n        advanced=0;\n        if (r.x1>0&&r.x1-1<=cx&&!checkOverlap(Rect{r.x1-1,r.y1,r.x2,r.y2},placedRects,idx)) {r.x1--; advanced=1;}\n        if (r.x2<GRID_SIZE&&r.x2>cx+1&&!checkOverlap(Rect{r.x1,r.y1,r.x2+1,r.y2},placedRects,idx)) {r.x2++; advanced=1;}\n        if (r.y1>0&&r.y1-1<=cy&&!checkOverlap(Rect{r.x1,r.y1-1,r.x2,r.y2},placedRects,idx)) {r.y1--; advanced=1;}\n        if (r.y2<GRID_SIZE&&r.y2>cy+1&&!checkOverlap(Rect{r.x1,r.y1,r.x2,r.y2+1},placedRects,idx)) {r.y2++; advanced=1;}\n        rounds++;\n    }\n    int dx[]={-1,0,1,0},dy[]={0,-1,0,1}; bool done=0;\n    while (!done && r.area()<area_limit && rounds<400) {\n        done=1;\n        for (int dir=0;dir<4;++dir) {\n            Rect c=r; if(dir==0&&r.x1>0)c.x1--; if(dir==1&&r.y1>0)c.y1--; if(dir==2&&r.x2<GRID_SIZE)c.x2++; if(dir==3&&r.y2<GRID_SIZE)c.y2++;\n            if (c.contains(cx+0.5,cy+0.5)&&c.area()<=area_limit&&!checkOverlap(c,placedRects,idx)) {r=c; done=0;}\n        }\n        rounds++;\n    }\n    return r;\n}\nint calc_density(const Company& a, const vector<Company>& comps, int radius=1500){\n    int c=0;\n    for(auto& b: comps) {\n        if(a.id==b.id)continue;\n        int dx=a.x-b.x,dy=a.y-b.y;\n        if(dx*dx+dy*dy<=radius*radius)++c;\n    }\n    return c;\n}\nstruct CompRectSolution { vector<Rect> rects; double sum_p; };\ndouble compute_score(const vector<Company>& companies,const vector<Rect>& rects, vector<double>* out_p=nullptr) {\n    double sum_p = 0, n=companies.size();\n    if(out_p) out_p->resize(n);\n    for (size_t i=0;i<companies.size();++i){\n        i64 req=companies[i].r;\n        i64 area=i64(rects[i].area());\n        double px=companies[i].x+0.5,py=companies[i].y+0.5;\n        double p = 0;\n        if (px > rects[i].x1 && px < rects[i].x2 && py > rects[i].y1 && py < rects[i].y2 && area > 0) {\n            double mn=min<double>(req,area), mx=max<double>(req,area);\n            p=1.0-(1.0-mn/mx)*(1.0-mn/mx);\n        }\n        if(out_p) (*out_p)[i]=p;\n        sum_p+=p;\n    }\n    return sum_p;\n}\nCompRectSolution run_solution(const vector<Company>& companies, const vector<int>& order) {\n    int n = companies.size();\n    vector<PlacedRect> placedRects;\n    vector<Rect> out_rect(n);\n    vector<Company> local_comp = companies;\n    for (int idx : order) {\n        auto& comp = local_comp[idx];\n        Rect rect;\n        i64 tr = comp.r;\n        bool placed = false;\n        int area_shrink = 0;\n        while (area_shrink < 15) {\n            i64 req_area = std::max(i64(1), tr - tr * area_shrink / 100);\n            rect = try_place(comp.x, comp.y, req_area, placedRects);\n            if (rect.x1!=-1) {placed=1;break;}\n            area_shrink += 2;\n        }\n        if (!placed) rect = emergency_fallback(comp.x, comp.y, placedRects);\n        comp.rect=rect;\n        placedRects.push_back({comp.id, rect});\n    }\n    for (int k=0;k<n;++k) {\n        int idx=local_comp[k].id;\n        Rect ini=local_comp[k].rect;\n        i64 target = local_comp[k].r;\n        Rect grown = expand_rect(ini, local_comp[k].x, local_comp[k].y, idx, placedRects, 2*target);\n        if (!checkOverlap(grown, placedRects, idx)) {\n            local_comp[k].rect = grown;\n            for (auto& pr: placedRects) if (pr.idx==idx) pr.r=grown;\n        }\n    }\n    for (int k=0;k<n;++k) out_rect[local_comp[k].id]=local_comp[k].rect;\n    double sum_p=compute_score(companies,out_rect);\n    return CompRectSolution{out_rect, sum_p};\n}\nvoid local_micro_expand(vector<Rect>& rects, const vector<Company>& companies, int passes=2) {\n    int n = companies.size();\n    vector<double> ps(n);\n    for (int iter=0; iter<passes; ++iter) {\n        compute_score(companies, rects, &ps);\n        vector<PlacedRect> placedRects(n);\n        for (int k=0;k<n;++k) placedRects[k] = {k, rects[k]};\n        vector<int> order(n);\n        iota(order.begin(),order.end(),0);\n        if (iter&1) reverse(order.begin(), order.end());\n        for (int ii=0; ii<n; ++ii) {\n            int idx = order[ii];\n            if (ps[idx] > 0.8) continue;\n            Rect best = rects[idx]; double bestp = ps[idx];\n            auto push = [&](Rect r){\n                double px = companies[idx].x+0.5, py = companies[idx].y+0.5;\n                if (!(px > r.x1 && px < r.x2 && py > r.y1 && py < r.y2)) return;\n                if (r.x1 < 0 || r.y1 < 0 || r.x2 > GRID_SIZE || r.y2 > GRID_SIZE) return;\n                if (!(r.x1 < r.x2 && r.y1 < r.y2)) return;\n                if (checkOverlap(r, placedRects, idx)) return;\n                i64 area = r.area();\n                if (area == 0) return;\n                double req = companies[idx].r;\n                double mn = min<double>(req, area), mx = max<double>(req, area);\n                double p = 1.0 - (1.0-mn/mx)*(1.0-mn/mx);\n                if (p > bestp) { best = r; bestp = p; }\n            };\n            for (int d=1; d<=3; ++d) {\n                push({rects[idx].x1-d, rects[idx].y1, rects[idx].x2-d, rects[idx].y2});\n                push({rects[idx].x1+d, rects[idx].y1, rects[idx].x2+d, rects[idx].y2});\n                push({rects[idx].x1, rects[idx].y1-d, rects[idx].x2, rects[idx].y2-d});\n                push({rects[idx].x1, rects[idx].y1+d, rects[idx].x2, rects[idx].y2+d});\n            }\n            push({rects[idx].x1-1, rects[idx].y1, rects[idx].x2, rects[idx].y2});\n            push({rects[idx].x1, rects[idx].y1-1, rects[idx].x2, rects[idx].y2});\n            push({rects[idx].x1, rects[idx].y1, rects[idx].x2+1, rects[idx].y2});\n            push({rects[idx].x1, rects[idx].y1, rects[idx].x2, rects[idx].y2+1});\n            if (bestp > ps[idx]) {\n                rects[idx]=best;\n                placedRects[idx].r=best;\n            }\n        }\n    }\n}\n// Multi-round: reinsert lowest-p_i rectangles, e.g. 16 at a time, for 5 repetitions\nvoid repeat_reinsert_poor_rects(vector<Rect>& rects, const vector<Company>& companies, int k_repair = 16, int rounds = 5) {\n    int n = companies.size();\n    mt19937 rng(4321 + chrono::steady_clock::now().time_since_epoch().count());\n    for (int rd = 0; rd < rounds; ++rd) {\n        vector<double> ps(n); compute_score(companies, rects, &ps);\n        // Find worst-off indices\n        vector<int> idxs(n); iota(idxs.begin(), idxs.end(), 0);\n        partial_sort(idxs.begin(), idxs.begin()+k_repair, idxs.end(),\n                     [&](int i,int j){return ps[i]<ps[j];});\n        vector<int> repair_ids(idxs.begin(), idxs.begin()+k_repair);\n        vector<PlacedRect> placedRects(n);\n        for (int i=0;i<n;++i) placedRects[i] = {i, rects[i]};\n        // Remove them\n        for (int rid : repair_ids) placedRects[rid].r = {-100,-100,-50,-50};\n        shuffle(repair_ids.begin(), repair_ids.end(), rng);\n        for (int rid : repair_ids) {\n            Rect rect;\n            i64 tr = companies[rid].r;\n            bool placed = false;\n            int area_shrink = 0;\n            while (area_shrink < 15) {\n                i64 req_area = std::max(i64(1), tr - tr * area_shrink / 100);\n                rect = try_place(companies[rid].x, companies[rid].y, req_area, placedRects);\n                if (rect.x1!=-1) {placed=1;break;}\n                area_shrink += 2;\n            }\n            if (!placed) rect = emergency_fallback(companies[rid].x, companies[rid].y, placedRects);\n            placedRects[rid] = {rid, rect};\n        }\n        // Expand each just in case\n        for (int rid : repair_ids) {\n            Rect ini = placedRects[rid].r;\n            Rect grown = expand_rect(ini, companies[rid].x, companies[rid].y, rid, placedRects, 2*companies[rid].r);\n            if (!checkOverlap(grown, placedRects, rid)) {\n                placedRects[rid].r = grown;\n            }\n        }\n        // Write back if improved total score\n        vector<Rect> rects2(n);\n        for (int i=0;i<n;++i) rects2[i] = placedRects[i].r;\n        double newscore = compute_score(companies, rects2);\n        double oldscore = compute_score(companies, rects);\n        if (newscore > oldscore) rects = rects2;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    mt19937 rng(12345 + chrono::steady_clock::now().time_since_epoch().count());\n    int n;\n    cin >> n;\n    vector<Company> companies(n);\n    for (int i = 0; i < n; ++i) {\n        int x, y; i64 r;\n        cin >> x >> y >> r;\n        companies[i] = Company{i, x, y, r, 0, {}};\n    }\n    for (int i = 0; i < n; ++i)\n        companies[i].density = calc_density(companies[i], companies);\n    vector<int> order_input(n), order_area(n), order_density(n);\n    iota(order_input.begin(),order_input.end(),0);\n    order_area=order_input; order_density=order_input;\n    sort(order_area.begin(),order_area.end(),[&](int a,int b){return companies[a].r > companies[b].r;});\n    sort(order_density.begin(),order_density.end(),[&](int a,int b){\n        if (companies[a].density!=companies[b].density) return companies[a].density>companies[b].density;\n        else return companies[a].r > companies[b].r;\n    });\n    vector<vector<int>> orders = {order_input, order_area, order_density};\n    for (int rs=0; rs<64; ++rs) {\n        auto ord = order_input;\n        shuffle(ord.begin(), ord.end(), rng);\n        orders.push_back(ord);\n    }\n    vector<CompRectSolution> solutions;\n    for (auto &ord : orders)\n        solutions.push_back(run_solution(companies,ord));\n    int best=0; double best_score=solutions[0].sum_p;\n    for(size_t i=1;i<solutions.size();++i)if(solutions[i].sum_p>best_score){best_score=solutions[i].sum_p;best=i;}\n    auto rects = solutions[best].rects;\n    local_micro_expand(rects, companies, 2);\n    repeat_reinsert_poor_rects(rects, companies, 16, 5); // bump best-case by repeated repairs\n    for(auto& r:rects) cout << r.x1 << ' ' << r.y1 << ' ' << r.x2 << ' ' << r.y2 << '\\n';\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 50;\nconst int di[4] = {-1, 1, 0, 0}, dj[4] = {0, 0, -1, 1};\nconst char dch[4] = {'U', 'D', 'L', 'R'};\n\nstruct Tile {\n    vector<pair<int, int>> cells;\n    set<int> adj;\n    int max_val = -1, max_cell_i = -1, max_cell_j = -1, sum_val = 0;\n};\n\nint si, sj, t[N][N], p[N][N], ntiles;\nvector<Tile> tiles;\n\nvoid preprocess() {\n    map<int, vector<pair<int,int>>> tile_cells;\n    for(int i=0;i<N;++i) for(int j=0;j<N;++j) tile_cells[t[i][j]].emplace_back(i, j);\n    ntiles = tile_cells.size();\n    tiles.assign(ntiles, Tile());\n    for(const auto &[tid, cells] : tile_cells) {\n        Tile tile;\n        tile.cells = cells;\n        int maxv=-1, maxi=-1, maxj=-1, sumv=0;\n        for(auto &[i, j]: tile.cells) {\n            sumv += p[i][j];\n            if(p[i][j]>maxv) { maxv=p[i][j]; maxi=i; maxj=j; }\n        }\n        tile.max_val = maxv;\n        tile.max_cell_i = maxi;\n        tile.max_cell_j = maxj;\n        tile.sum_val = sumv;\n        tiles[tid] = tile;\n    }\n    for(int i=0;i<N;++i) for(int j=0;j<N;++j){\n        int tid = t[i][j];\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>=N||nj>=N) continue;\n            int ntid = t[ni][nj];\n            if(ntid!=tid) tiles[tid].adj.insert(ntid);\n        }\n    }\n}\n\nstruct State {\n    int ci, cj, curr_tile, score, moves;\n    vector<bool> tile_used;\n    string path;\n    State() = default;\n    State(int _i,int _j)\n        : ci(_i), cj(_j), curr_tile(t[_i][_j]), score(p[_i][_j]), moves(0),\n          tile_used(ntiles,false), path(\"\") { tile_used[curr_tile]=true; }\n    State(int _ci,int _cj,int _curr_tile,int _score,int _moves,const vector<bool> &_tile_used,const string &_path)\n        : ci(_ci), cj(_cj), curr_tile(_curr_tile), score(_score), moves(_moves),\n          tile_used(_tile_used), path(_path) {}\n    State(int _ci,int _cj,int _curr_tile,int _score,int _moves,vector<bool> &&_tile_used,string &&_path)\n        : ci(_ci), cj(_cj), curr_tile(_curr_tile), score(_score), moves(_moves),\n          tile_used(std::move(_tile_used)), path(std::move(_path)) {}\n    bool operator<(const State& o) const {\n        if(score != o.score) return score > o.score;\n        return path.size() > o.path.size();\n    }\n};\n\nint rollout(int ci, int cj, vector<bool> tile_used, int score, mt19937& rng, int steps=16) {\n    for(int s=0;s<steps;++s){\n        vector<pair<int,int>> moves;\n        for(int d=0;d<4;++d){\n            int ni=ci+di[d], nj=cj+dj[d];\n            if(ni<0||nj<0||ni>=N||nj>=N) continue;\n            int n_tid=t[ni][nj];\n            if(tile_used[n_tid]) continue;\n            moves.emplace_back(ni,nj);\n        }\n        if(moves.empty()) break;\n        int mx_val=-1;\n        for(auto [ni,nj]:moves) mx_val=max(mx_val,p[ni][nj]);\n        vector<pair<int,int>> opts;\n        for(auto [ni,nj]:moves) if(p[ni][nj]+2>=mx_val) opts.push_back({ni,nj});\n        auto [nni,nnj]=opts[rng()%opts.size()];\n        ci=nni; cj=nnj;\n        int n_tid=t[ci][cj];\n        tile_used[n_tid]=true; score+=p[ci][cj];\n    }\n    return score;\n}\n\n// Hybrid: \u03b5-greedy with region diversity at start\npair<string,int> hybrid_ep_greedy_random_path(mt19937 &rng, int phase1_steps=5, double eps1=0.75, double eps2=0.30) {\n    int ci=si,cj=sj,score=p[ci][cj];\n    vector<bool> tile_used(ntiles,false); tile_used[t[ci][cj]]=true; string path=\"\";\n    int prev_reg = (ci/10)*5+(cj/10);\n    for(int steps = 0;; ++steps) {\n        vector<pair<int,int>> moves;\n        vector<int> move_dir;\n        vector<int> region;\n        for(int d=0;d<4;++d){\n            int ni=ci+di[d],nj=cj+dj[d];\n            if(ni<0||nj<0||ni>=N||nj>=N) continue;\n            int n_tid=t[ni][nj];\n            if(tile_used[n_tid]) continue;\n            moves.push_back({ni,nj});\n            move_dir.push_back(d);\n            region.push_back((ni/10)*5+(nj/10));\n        }\n        if(moves.empty()) break;\n        int idx = 0;\n        double epsilon = (steps < phase1_steps ? eps1 : eps2);\n        if(uniform_real_distribution<double>(0,1)(rng)<epsilon){\n            // region diversity: pick a move to a region not visited last step, if available\n            vector<int> diverse;\n            for(int z=0;z<moves.size();++z) if(region[z] != prev_reg) diverse.push_back(z);\n            if(!diverse.empty())\n                idx = diverse[rng()%diverse.size()];\n            else\n                idx = rng()%moves.size();\n        } else {\n            int best=-1, best_val=-1;\n            for(int z=0;z<moves.size();++z) if(p[moves[z].first][moves[z].second]>best_val){\n                best_val=p[moves[z].first][moves[z].second]; best=z;\n            }\n            idx = best;\n        }\n        prev_reg = region[idx];\n        ci = moves[idx].first; cj = moves[idx].second;\n        tile_used[t[ci][cj]] = true;\n        path += dch[move_dir[idx]];\n        score += p[ci][cj];\n    }\n    return {path, score};\n}\n\nstring multi_restart_beam_search() {\n    const int BEAM_WIDTH=32, MAX_TRIES=8;\n    const double TIME_LIMIT=1.95;\n    const int EARLY_MOVES=7, ROLL_EARLY=6, ROLL_LATE=2;\n    const int ROLL_STEPS_EARLY=16, ROLL_STEPS_LATE=8;\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    int best_score=0; string best_path=\"\";\n    auto start = chrono::high_resolution_clock::now();\n    int tries = 0;\n\n    while(tries<MAX_TRIES) {\n        State initial(si,sj);\n        vector<State> beam{initial};\n        int local_best_score=initial.score; string local_best_path=\"\";\n        while(!beam.empty()) {\n            vector<State> next_beam;\n            for(const auto& state: beam){\n                vector<tuple<int,int,int,int,int,int,int>> cand;\n                for(int d=0;d<4;++d){\n                    int ni=state.ci+di[d],nj=state.cj+dj[d];\n                    if(ni<0||nj<0||ni>=N||nj>=N) continue;\n                    int n_tid=t[ni][nj];\n                    if(state.tile_used[n_tid]) continue;\n                    int openness=0;\n                    vector<bool> used2=state.tile_used; used2[n_tid]=true;\n                    for(int dd=0;dd<4;++dd){\n                        int nni=ni+di[dd],nnj=nj+dj[dd];\n                        if(nni<0||nnj<0||nni>=N||nnj>=N)continue;\n                        int n2_tid = t[nni][nnj];\n                        if(used2[n2_tid])continue;\n                        openness++;\n                    }\n                    int n_rolls=(state.moves<EARLY_MOVES)?ROLL_EARLY:ROLL_LATE;\n                    int roll_steps=(state.moves<EARLY_MOVES)?ROLL_STEPS_EARLY:ROLL_STEPS_LATE;\n                    int total=0;\n                    for(int roll=0;roll<n_rolls;++roll)\n                        total+=rollout(ni,nj,used2,state.score+p[ni][nj],rng,roll_steps);\n                    int eval=total/n_rolls;\n                    int r=uniform_int_distribution<int>(0,9999)(rng);\n                    cand.emplace_back(eval,openness,r,d,ni,nj,n_tid);\n                }\n                if(cand.empty()) {\n                    if(state.score > local_best_score) {\n                        local_best_score=state.score; local_best_path=state.path;\n                    }\n                    continue;\n                }\n                sort(cand.rbegin(), cand.rend());\n                if(state.moves < EARLY_MOVES){\n                    unordered_map<long long,tuple<int,int,int,int,int,int,int>> unique_by_tile_region;\n                    for(auto &tu : cand){\n                        auto [valh, openness, rnd, d, ni, nj, n_tid]=tu;\n                        int region=(ni/10)*5+(nj/10);\n                        long long key=n_tid; key=(key<<8)|region;\n                        if(unique_by_tile_region.count(key)==0) unique_by_tile_region[key]=tu;\n                    }\n                    vector<tuple<int,int,int,int,int,int,int>> final_cand;\n                    for(auto &kv : unique_by_tile_region) final_cand.emplace_back(kv.second);\n                    sort(final_cand.rbegin(), final_cand.rend());\n                    int take = min<int>(final_cand.size(), 3);\n                    for(int kk=0;kk<take;++kk){\n                        auto [valh, openness, rnd, d, ni, nj, n_tid]=final_cand[kk];\n                        auto next_tile_used=state.tile_used; next_tile_used[n_tid]=true;\n                        string npath=state.path+dch[d];\n                        next_beam.emplace_back(ni,nj,n_tid,state.score+p[ni][nj],\n                                               state.moves+1, std::move(next_tile_used), std::move(npath));\n                    }\n                } else {\n                    unordered_map<int, tuple<int,int,int,int,int,int,int>> unique_by_tid;\n                    for(auto &tu: cand) {\n                        int tid=get<6>(tu);\n                        if(unique_by_tid.count(tid)==0) unique_by_tid[tid]=tu;\n                    }\n                    vector<tuple<int,int,int,int,int,int,int>> final_cand;\n                    for(auto &kv: unique_by_tid) final_cand.emplace_back(kv.second);\n                    sort(final_cand.rbegin(), final_cand.rend());\n                    int take = min<int>(final_cand.size(), 3);\n                    for(int kk=0;kk<take;++kk){\n                        auto [valh, openness, rnd, d, ni, nj, n_tid]=final_cand[kk];\n                        auto next_tile_used=state.tile_used; next_tile_used[n_tid]=true;\n                        string npath=state.path+dch[d];\n                        next_beam.emplace_back(ni, nj, n_tid, state.score + p[ni][nj],\n                                               state.moves+1, std::move(next_tile_used), std::move(npath));\n                    }\n                }\n            }\n            if(next_beam.empty()) break;\n            if((int)next_beam.size()>BEAM_WIDTH){\n                std::partial_sort(next_beam.begin(),next_beam.begin()+BEAM_WIDTH,next_beam.end());\n                next_beam.resize(BEAM_WIDTH);\n            }else sort(next_beam.begin(),next_beam.end());\n            beam=std::move(next_beam);\n        }\n        if(local_best_path.empty()&&!beam.empty())\n            local_best_path=beam.front().path;\n        if(local_best_score<initial.score&&!beam.empty()){\n            int ci=si, cj=sj;\n            vector<bool> used(ntiles,false);\n            int score=p[ci][cj]; used[t[ci][cj]]=true;\n            for(char ch: beam.front().path){\n                int dir=-1;\n                if(ch=='U') dir=0; else if(ch=='D') dir=1;\n                else if(ch=='L') dir=2; else if(ch=='R') dir=3;\n                ci+=di[dir]; cj+=dj[dir];\n                score += p[ci][cj];\n                used[t[ci][cj]]=true;\n            }\n            local_best_score = score;\n        }\n        if(local_best_score > best_score) {\n            best_score = local_best_score;\n            best_path = local_best_path;\n        }\n        tries++;\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now-start).count();\n        if(elapsed > TIME_LIMIT*0.8) break;\n    }\n\n    if(best_score < 13000) {\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now-start).count();\n        while(elapsed < TIME_LIMIT) {\n            auto [rpath, rscore] = hybrid_ep_greedy_random_path(rng, 6, 0.67, 0.25);\n            if(rscore > best_score) { best_score=rscore; best_path=rpath; }\n            now = chrono::high_resolution_clock::now();\n            elapsed = chrono::duration<double>(now-start).count();\n        }\n    }\n    return best_path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    cin >> si >> sj;\n    for(int i=0;i<N;++i) for(int j=0;j<N;++j) cin >> t[i][j];\n    for(int i=0;i<N;++i) for(int j=0;j<N;++j) cin >> p[i][j];\n    preprocess();\n    string path = multi_restart_beam_search();\n    cout << path << '\\n';\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Constants\nconstexpr int N = 30;\nconstexpr int Q = 1000;\nconstexpr int DIR = 4;\nconst char dir_chars[DIR] = {'U','D','L','R'};\nconst int dx[DIR] = {-1,+1,0,0}, dy[DIR] = {0,0,-1,+1};\n\n// Edge structure for statistics\nstruct EdgeInfo {\n    double est = 5000.0;\n    int count = 0;\n    double sum = 0.0;\n    bool known = false;\n    \n    void update(double val) {\n        sum += val;\n        count++;\n        est = sum / count;\n    }\n    void add_sample(double val, double smoothing=0.8) {\n        if (!known) { est = val; known=true; return; }\n        est = smoothing*est + (1-smoothing)*val;\n    }\n};\n\n// Edge model: grid of edge estimates, separate for horizontal and vertical\nEdgeInfo horiz[N][N-1]; // between (i,j) and (i,j+1)\nEdgeInfo vert[N-1][N]; // between (i,j) and (i+1,j)\n\n// For edge encoding\ninline bool in_grid(int i, int j) { return 0<=i && i<N && 0<=j && j<N; }\n\n// Returns list of moves ('U','D','L','R') for s to t using current edge estimates\nvector<char> estimate_path(pair<int,int> s, pair<int,int> t) {\n    using T = tuple<double,int,int,string>; // cost, i, j, path\n    priority_queue<T, vector<T>, greater<>> pq;\n    vector<vector<double>> dist(N, vector<double>(N, 1e18));\n    vector<vector<pair<int,int>>> prev(N, vector<pair<int,int>>(N, {-1,-1}));\n    vector<vector<int>> previdx(N, vector<int>(N, -1));\n    dist[s.first][s.second] = 0;\n    pq.emplace(0.0, s.first, s.second, \"\");\n    while (!pq.empty()) {\n        auto [cost, i, j, p] = pq.top(); pq.pop();\n        if (make_pair(i,j)==t) {\n            // reconstruct path\n            vector<char> res;\n            int x = t.first, y = t.second;\n            while (prev[x][y].first != -1) {\n                int px = prev[x][y].first, py = prev[x][y].second;\n                int d = previdx[x][y];\n                res.push_back(dir_chars[d]);\n                x=px; y=py;\n            }\n            reverse(res.begin(), res.end());\n            return res;\n        }\n        if (cost > dist[i][j]) continue;\n        for (int d=0; d<4; ++d) {\n            int ni = i+dx[d], nj = j+dy[d];\n            if (!in_grid(ni, nj)) continue;\n            double ecost;\n            if (d==0) ecost = vert[i-1][j].est; // up: between (i-1,j)-(i,j)\n            if (d==1) ecost = vert[i][j].est;   // down: between (i,j)-(i+1,j)\n            if (d==2) ecost = horiz[i][j-1].est; // left: between (i,j-1)-(i,j)\n            if (d==3) ecost = horiz[i][j].est;   // right: between (i,j)-(i,j+1)\n            if (dist[ni][nj] > dist[i][j] + ecost) {\n                dist[ni][nj] = dist[i][j]+ecost;\n                prev[ni][nj] = {i,j};\n                previdx[ni][nj] = d;\n                pq.emplace(dist[ni][nj], ni, nj, p + dir_chars[d]);\n            }\n        }\n    }\n    // never reached: should not happen\n    return {};\n}\n\n// Map moves to edges for updating\nvoid update_edges(pair<int,int> s, const vector<char>& path, double total_edge_len) {\n    vector<pair<int,int>> wayp;\n    wayp.push_back(s);\n    int x = s.first, y = s.second;\n    for (char c: path) {\n        if (c=='U') x--;\n        else if (c=='D') x++;\n        else if (c=='L') y--;\n        else if (c=='R') y++;\n        wayp.emplace_back(x,y);\n    }\n    int plen = (int)path.size();\n    if (plen==0) return;\n    double unit = total_edge_len / plen; // naive: assign equally (no better info!)\n    for (int i=0; i<plen; ++i) {\n        int x0 = wayp[i].first, y0 = wayp[i].second;\n        int x1 = wayp[i+1].first, y1 = wayp[i+1].second;\n        // edge direction\n        if (x0==x1 && y0+1==y1) {\n            horiz[x0][y0].add_sample(unit);\n        } else if (x0==x1 && y0-1==y1) {\n            horiz[x0][y1].add_sample(unit);\n        } else if (x0+1==x1 && y0==y1) {\n            vert[x0][y0].add_sample(unit);\n        } else if (x0-1==x1 && y0==y1) {\n            vert[x1][y0].add_sample(unit);\n        } else assert(false);\n    }\n}\n\n// Early in the contest, randomly explore to cover more edges\nvector<char> random_path(pair<int,int> s, pair<int,int> t, mt19937 &rng) {\n    int x = s.first, y = s.second;\n    int tx = t.first, ty = t.second;\n    vector<char> path;\n    int dx_ = tx - x, dy_ = ty - y;\n    vector<char> moves;\n    if (dx_ > 0) moves.insert(moves.end(), dx_, 'D');\n    else moves.insert(moves.end(), -dx_, 'U');\n    if (dy_ > 0) moves.insert(moves.end(), dy_, 'R');\n    else moves.insert(moves.end(), -dy_, 'L');\n    shuffle(moves.begin(), moves.end(), rng); // randomize order\n    // Create actual path via valid movement\n    for(char c : moves) path.push_back(c);\n    return path;\n}\n\n// Readline helpers\nint si, sj, ti, tj;\nvoid fast_scan() { scanf(\"%d%d%d%d\", &si, &sj, &ti, &tj); }\nint fast_int() { int x; scanf(\"%d\", &x); return x; }\n\nint main() {\n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n\n    for (int query=0; query<Q; ++query) {\n        fast_scan();\n        pair<int,int> s = {si, sj}, t = {ti, tj};\n        vector<char> path_chars;\n        if (query < 100) {\n            path_chars = random_path(s, t, rng); // randomize for first 100 queries\n        } else {\n            path_chars = estimate_path(s, t);\n            if (path_chars.size()==0) { // fallback\n                path_chars = random_path(s, t, rng);\n            }\n        }\n        // Output path\n        string out(path_chars.begin(), path_chars.end());\n        printf(\"%s\\n\", out.c_str());\n        fflush(stdout);\n\n        // Input feedback (rounded noisy cost)\n        int feedback = fast_int();\n\n        // Update edge estimates using feedback length\n        update_edges(s, path_chars, feedback);\n\n        // (optional: debug)\n        // if (query%100==99) cerr << \"[[\"<<query<<\"]]\\n\";\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\n// For random numbers\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Returns list of tuples (direction (0=row,1=col), i, shift)\nvector<tuple<int,int,int>> all_positions(int N, int len) {\n    vector<tuple<int,int,int>> positions;\n    for(int dir=0;dir<2;++dir) // 0=row,1=col\n        for(int i=0;i<N;++i)\n            for(int shift=0;shift<N;++shift)\n                positions.emplace_back(dir,i,shift);\n    return positions;\n}\n\n// Try placing s in matrix a at (dir,i,shift)\n// Return if conflict (false if conflict), and collect pos_painted (to mark for this string)\nbool can_place(const vector<string> &a, int N, const string &s,\n               int dir, int i, int shift, vector<pair<int,int>> &pos_painted) {\n    int k = s.size();\n    pos_painted.clear();\n    for(int p=0;p<k;++p){\n        int x = (dir==0)? i : (i+p)%N;\n        int y = (dir==0)? (shift+p)%N : shift;\n        if(a[x][y]=='.' || a[x][y]==s[p]) {\n            pos_painted.emplace_back(x,y);\n        } else {\n            return false;\n        }\n    }\n    return true;\n}\n\n// Place s in matrix a at given places\nvoid do_paint(vector<string> &a, const string &s, const vector<pair<int,int>> &pos_painted, int dir, int i, int shift) {\n    int k = s.size();\n    for(int p=0;p<k;++p){\n        int x = (dir==0)? i : (i+p)%a.size();\n        int y = (dir==0)? (shift+p)%a.size() : shift;\n        a[x][y] = s[p];\n    }\n}\n\n// Checks if s is covered somewhere in matrix a as row/col subsequence (using torus)\nbool is_covered(const vector<string> &a, const string &s) {\n    int N = a.size();\n    int k = s.size();\n    for(int i=0;i<N;++i){\n        for(int shift=0;shift<N;++shift){\n            // Row\n            bool ok=true;\n            for(int p=0;p<k;++p){\n                if(a[i][(shift+p)%N]!=s[p]) { ok=false; break; }\n            }\n            if(ok) return true;\n            // Col\n            ok=true;\n            for(int p=0;p<k;++p){\n                if(a[(i+p)%N][shift]!=s[p]) { ok=false; break; }\n            }\n            if(ok) return true;\n        }\n    }\n    return false;\n}\n\nint main() {\n    ios::sync_with_stdio(0); cin.tie(0);\n    int N, M;\n    cin >> N >> M;\n    vector<string> s(M);\n    for(int i=0;i<M;++i) cin >> s[i];\n\n    vector<string> best_ans;\n    int best_cover = 0;\n\n    // Try several random processings to maximize c\n    int TRIALS = 7; // You can tune this\n    for(int trial=0; trial<TRIALS; ++trial){\n        vector<string> a(N, string(N,'.'));\n        vector<int> idx(M);\n        iota(idx.begin(), idx.end(), 0);\n        shuffle(idx.begin(), idx.end(), rng);\n\n        // Record for each cell the possible frequency of candidates (for later fill)\n        vector<vector<array<int,8>>> freq(N,vector<array<int,8>>(N));\n        for(int t=0;t<M;++t){\n            const string &si = s[t];\n            int k = si.size();\n            for(int dir=0;dir<2;++dir)\n                for(int i=0;i<N;++i)\n                    for(int shift=0;shift<N;++shift){\n                        for(int p=0;p<k;++p) {\n                            int x = (dir==0)? i : (i+p)%N;\n                            int y = (dir==0)? (shift+p)%N : shift;\n                            freq[x][y][si[p]-'A']++;\n                        }\n                    }\n        }\n\n        // Main Greedy: Try to pack as many s[idx[*]] as possible\n        vector<bool> used(M, false);\n        for(int tt=0;tt<M;++tt){\n            int i_s = idx[tt];\n            const string &si = s[i_s];\n            int k = si.size();\n\n            // Find all possible placements without conflict\n            vector<tuple<int,int,int>> possible;\n            vector<pair<int,int>> buf;\n            for(int dir=0;dir<2;++dir)\n                for(int i=0;i<N;++i)\n                    for(int shift=0;shift<N;++shift)\n                        if(can_place(a,N,si,dir,i,shift,buf))\n                            possible.emplace_back(dir,i,shift);\n\n            if(possible.empty()) continue;\n\n            // Pick randomly (could pick \"minimally fills new cells\", or \"max freq\", but use random for now)\n            auto [dir,i,shift] = possible[rng()%possible.size()];\n            // Actually place it\n            do_paint(a, si, buf, dir, i, shift);\n            used[i_s] = true;\n        }\n        // Final fill-in: Remaining '.' fill with most frequent guess (from freq), or 'A'\n        for(int i=0;i<N;++i) for(int j=0;j<N;++j) if(a[i][j]=='.') {\n            int maxv = 0; char c='A';\n            for(int t=0;t<8;++t) if(freq[i][j][t]>maxv) {\n                maxv = freq[i][j][t];\n                c = 'A' + t;\n            }\n            a[i][j] = c;\n        }\n\n        // Now count how many s are matched as subsequence\n        int cover = 0;\n        for(int i=0;i<M;++i) if(is_covered(a, s[i])) cover++;\n\n        if(cover > best_cover) {\n            best_cover = cover;\n            best_ans = a;\n            if(cover == M) break; // optimal (no point in more tries)\n        }\n    }\n    // Output final matrix\n    for(int i=0;i<N;++i)\n        cout << best_ans[i] << '\\n';\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int DX[4] = {-1, 1, 0, 0}, DY[4] = {0, 0, -1, 1};\nconstexpr char DIRS[4] = {'U', 'D', 'L', 'R'};\nusing Pos = pair<int, int>;\n\nstruct FastBitSet {\n    vector<uint64_t> bs;\n    int size;\n    FastBitSet(int n) : bs((n+63)>>6), size(n) {}\n    void set(int k) { bs[k>>6] |= 1ULL<<(k&63); }\n    void reset(int k) { bs[k>>6] &= ~(1ULL<<(k&63)); }\n    bool test(int k) const { return (bs[k>>6]>>(k&63))&1; }\n    void operator|=(const FastBitSet& rhs) {\n        for (size_t i=0; i<bs.size(); ++i) bs[i] |= rhs.bs[i];\n    }\n    int count() const { int res=0; for(auto x:bs) res+=__builtin_popcountll(x); return res; }\n    bool all() const {\n        int lim = size, full = lim/64, rest=lim%64;\n        for(int i=0;i<full;++i) if(bs[i]!=~0ULL) return false;\n        if(rest) return (bs[full]&((1ULL<<rest)-1))==((1ULL<<rest)-1);\n        return true;\n    }\n};\n\nstruct RoadMapper {\n    int N;\n    vector<vector<int>> idx_of;\n    vector<Pos> pos_of;\n    int num_roads;\n    RoadMapper(int N_, const vector<string>& grid):N(N_){\n        idx_of.assign(N,vector<int>(N,-1));\n        int id=0;\n        for(int i=0;i<N;++i)for(int j=0;j<N;++j)\n            if('5'<=grid[i][j]&&grid[i][j]<='9'){idx_of[i][j]=id++;pos_of.push_back({i,j});}\n        num_roads=id;\n    }\n    int id(int i,int j) const {return (0<=i&&i<N&&0<=j&&j<N)?idx_of[i][j]:-1;}\n};\n\nstruct Visibility {\n    int N,num_roads;\n    RoadMapper& mapper;\n    vector<FastBitSet> vis;\n    Visibility(int N_,RoadMapper&m,const vector<string>&grid)\n        :N(N_),mapper(m),num_roads(m.num_roads),vis(num_roads,FastBitSet(m.num_roads)) {\n        auto& idx=mapper.idx_of;\n        for(int k=0;k<num_roads;++k){\n            auto [i,j]=mapper.pos_of[k];\n            for(int jj=j;jj>=0;--jj){ if(idx[i][jj]==-1)break; vis[k].set(idx[i][jj]); }\n            for(int jj=j+1;jj<N;++jj){ if(idx[i][jj]==-1)break; vis[k].set(idx[i][jj]); }\n            for(int ii=i;ii>=0;--ii){ if(idx[ii][j]==-1)break; vis[k].set(idx[ii][j]); }\n            for(int ii=i+1;ii<N;++ii){ if(idx[ii][j]==-1)break; vis[k].set(idx[ii][j]); }\n            vis[k].set(k);\n        }\n    }\n};\n\nvector<vector<int>> make_move_cost(const vector<string>& grid){\n    int N=grid.size();\n    vector<vector<int>> move_cost(N,vector<int>(N,-1));\n    for(int i=0;i<N;++i)for(int j=0;j<N;++j)\n        if('5'<=grid[i][j]&&grid[i][j]<='9') move_cost[i][j]=grid[i][j]-'0';\n    return move_cost;\n}\nint path_length(const vector<string>& grid, int N, Pos st, Pos gl, const vector<vector<int>>& move_cost){\n    if(st==gl)return 0;\n    priority_queue<tuple<int,int,int>,vector<tuple<int,int,int>>,greater<>> pq;\n    vector<vector<int>> dist(N,vector<int>(N,INT_MAX));\n    pq.emplace(0,st.first,st.second); dist[st.first][st.second]=0;\n    while(!pq.empty()){\n        auto [d,i,j]=pq.top();pq.pop();\n        if(make_pair(i,j)==gl) return d;\n        if(dist[i][j]<d)continue;\n        for(int dir=0;dir<4;++dir){\n            int ni=i+DX[dir],nj=j+DY[dir];\n            if(ni<0||nj<0||ni>=N||nj>=N)continue;\n            if(move_cost[ni][nj]<0)continue;\n            int nd=d+move_cost[ni][nj];\n            if(dist[ni][nj]>nd){\n                dist[ni][nj]=nd; pq.emplace(nd,ni,nj);\n            }\n        }\n    }\n    return INT_MAX;\n}\n\nvector<Pos> bfs_shortest_path(const vector<string>& grid, int N, Pos st, Pos gl) {\n    if (st == gl) return {st};\n    vector<vector<Pos>> pre(N, vector<Pos>(N, {-1,-1}));\n    queue<Pos> que; que.push(st);\n    pre[st.first][st.second]=st;\n    while(!que.empty()){\n        auto [i,j]=que.front();que.pop();\n        for(int d=0;d<4;++d){\n            int ni=i+DX[d], nj=j+DY[d];\n            if(ni<0||nj<0||ni>=N||nj>=N)continue;\n            if(!(grid[ni][nj]>='5'&&grid[ni][nj]<='9'))continue;\n            if(pre[ni][nj].first!=-1)continue;\n            pre[ni][nj]={i,j};\n            if(make_pair(ni,nj)==gl){\n                vector<Pos> ret;\n                Pos cur=gl;\n                while(cur!=st){ret.push_back(cur);cur=pre[cur.first][cur.second];}\n                ret.push_back(st);\n                reverse(ret.begin(),ret.end());\n                return ret;\n            }\n            que.push({ni,nj});\n        }\n    }\n    return {};\n}\nchar move_dir(const Pos& from, const Pos& to){\n    int di=to.first-from.first,dj=to.second-from.second;\n    for(int d=0;d<4;++d)if(di==DX[d]&&dj==DY[d])return DIRS[d];\n    return '\\0';\n}\n\n\n// key: ratio scan cover but with dijkstra cap per step\nvector<int> greedy_scan_cover(const RoadMapper& m, const Visibility& vis, int si, int sj,\n        mt19937& rng, const vector<string>& grid, const vector<vector<int>>& move_cost, int topK=4){\n    int num=m.num_roads, prev_id=m.id(si,sj);\n    FastBitSet covered(num);\n    covered|=vis.vis[prev_id];\n    vector<int> scan_pts; scan_pts.push_back(prev_id);\n    vector<bool> used(num,false); used[prev_id]=true;\n    int N = move_cost.size();\n\n    while(!covered.all()){\n        vector<tuple<double,int,int>> cand; // ratio, (-gain), id\n        vector<pair<int,int>> gainlist; // id, gain\n        for(int k=0;k<num;++k){\n            if(used[k])continue;\n            int cnt=0;\n            for(int x=0;x<num;++x)\n                if(vis.vis[k].test(x)&&!covered.test(x)) ++cnt;\n            if(cnt>0) gainlist.emplace_back(k, cnt);\n        }\n        if(gainlist.empty()) break;\n        // Find max gain\n        int max_gain = 0;\n        for(auto[x,g]:gainlist) if(g>max_gain) max_gain=g;\n        vector<int> bests;\n        for(auto[x,g]:gainlist) if(g==max_gain) bests.push_back(x);\n        // For bests only: compute path_cost. Cap check to 20 at random if needed.\n        shuffle(bests.begin(),bests.end(), rng);\n        int checklim = min((int)bests.size(), 20);\n        for(int i=0;i<checklim;i++){\n            int k = bests[i];\n            int gain = max_gain;\n            int cost = path_length(grid, N, m.pos_of[prev_id], m.pos_of[k], move_cost);\n            cand.emplace_back(-1.0*gain/(cost+1e-5), -gain, k);\n        }\n        // For rest, just use gain (approximate). Use -1 cost so sorted after ratio.\n        for(int i=checklim;i<bests.size();++i){\n            int k = bests[i];\n            int gain = max_gain;\n            cand.emplace_back(-1e6, -gain, k);\n        }\n        sort(cand.begin(), cand.end());\n        int tk=min(topK,(int)cand.size());\n        int idx=uniform_int_distribution<int>(0,tk-1)(rng);\n        int pick=get<2>(cand[idx]);\n        scan_pts.push_back(pick);\n        covered|=vis.vis[pick];\n        used[pick]=true;\n        prev_id=pick;\n    }\n    return scan_pts;\n}\n\nvoid compute_all_pairs(vector<vector<int>>& dist, const vector<int>& scan_pts, const vector<string>& grid, const RoadMapper& m, const vector<vector<int>>& move_cost){\n    int L=scan_pts.size();\n    for(int i=0;i<L;++i)for(int j=0;j<L;++j){\n        if(i==j){dist[i][j]=0; continue;}\n        int t=path_length(grid,grid.size(), m.pos_of[scan_pts[i]], m.pos_of[scan_pts[j]], move_cost);\n        dist[i][j]=t;\n    }\n}\nvector<int> nearest_neighbor_scan_order(const vector<int>& scan_pts, int start_idx, const vector<vector<int>>& dist){\n    int L=scan_pts.size();\n    vector<int> order={start_idx};\n    vector<bool> vis(L,false); vis[start_idx]=true;\n    int cur=start_idx;\n    for(int step=1;step<L;++step){\n        int nxt=-1,best=INT_MAX;\n        for(int i=0;i<L;++i)\n            if(!vis[i] && dist[cur][i]<best){best=dist[cur][i];nxt=i;}\n        order.push_back(nxt); vis[nxt]=true; cur=nxt;\n    }\n    return order;\n}\nvoid tsp2opt(vector<int>& order, const vector<vector<int>>& dist, int max_rounds=2){\n    int L=order.size();\n    for(int rep=0;rep<max_rounds;++rep){\n        bool updated = false;\n        for(int i=1;i<L-2;++i){\n            for(int j=i+1;j<L-1;++j){\n                int before = dist[order[i-1]][order[i]] + dist[order[j]][order[j+1]];\n                int after  = dist[order[i-1]][order[j]] + dist[order[i]][order[j+1]];\n                if(after < before){\n                    reverse(order.begin()+i,order.begin()+j+1);\n                    updated=true;\n                }\n            }\n        }\n        if(!updated) break;\n    }\n}\nvector<Pos> build_route(const vector<int>& scan_pts, const vector<int>& order, const RoadMapper& m, const vector<string>& grid){\n    vector<Pos> route;\n    for(int ix=0;ix<order.size();++ix){\n        int cur_pt=scan_pts[order[ix]];\n        Pos cur_pos=m.pos_of[cur_pt];\n        if(route.empty()){route.push_back(cur_pos);}\n        else{\n            auto seg=bfs_shortest_path(grid,grid.size(),route.back(),cur_pos);\n            for(int i=1;i<seg.size();++i) route.push_back(seg[i]);\n        }\n    }\n    if(route.front()!=route.back()){\n        auto seg=bfs_shortest_path(grid,grid.size(),route.back(),route.front());\n        for(int i=1;i<seg.size();++i) route.push_back(seg[i]);\n    }\n    vector<Pos> clean{route[0]};\n    for(int i=1;i<route.size();++i)\n        if(route[i]!=route[i-1]) clean.push_back(route[i]);\n    return clean;\n}\nvoid prune_scan_pts(vector<int>& scan_pts, int si, int sj, const RoadMapper& m, const Visibility& vis, int rounds=2) {\n    int num=m.num_roads, start_id = m.id(si,sj);\n    for(int iter=0; iter<rounds; ++iter){\n        for(int i=scan_pts.size()-1;i>=0;--i){\n            if(scan_pts[i]==start_id) continue;\n            vector<int> tscan = scan_pts;\n            tscan.erase(tscan.begin()+i);\n            FastBitSet covered(num);\n            for(int id:tscan) covered |= vis.vis[id];\n            if(covered.all()){\n                scan_pts = tscan;\n            }\n        }\n    }\n}\nint route_cost(const vector<Pos>& route, const vector<string>& grid){\n    int cost=0;\n    for(size_t i=1;i<route.size();++i){\n        auto [ni, nj] = route[i];\n        cost += grid[ni][nj] - '0';\n    }\n    return cost;\n}\n\nint main() {\n    ios::sync_with_stdio(0);cin.tie(0);\n    int N,si,sj; cin>>N>>si>>sj;\n    vector<string> grid(N);\n    for(int i=0;i<N;++i)cin>>grid[i];\n    RoadMapper m(N,grid);\n    Visibility vis(N,m,grid);\n\n    constexpr int MAXRAND=10, MAXPRUNE=2, SCANPT_LIMIT=80;\n    constexpr double SOFTTIME=2.1;\n    auto startclock=chrono::steady_clock::now();\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()+si*61+sj*73);\n\n    auto move_cost = make_move_cost(grid);\n    int best_cost = INT_MAX, best_scanpt = 999, nbest = 0;\n    string best_moves;\n    for(int randtry=0;randtry<MAXRAND;++randtry){\n        if(chrono::duration<double>(chrono::steady_clock::now()-startclock).count()>SOFTTIME) break;\n        int k = 4;\n        if(randtry==0||randtry==MAXRAND-1) k=8;\n        auto scan_pts=greedy_scan_cover(m,vis,si,sj,rng,grid,move_cost,k);\n        prune_scan_pts(scan_pts, si, sj, m, vis, MAXPRUNE);\n        if(scan_pts.size() > min(SCANPT_LIMIT,best_scanpt+2)) continue;\n        int start_idx=0;\n        for(int i=0;i<scan_pts.size();++i)\n            if(m.pos_of[scan_pts[i]]==Pos(si,sj)) start_idx=i;\n        int L=scan_pts.size();\n        vector<vector<int>> dist(L,vector<int>(L, 1e9));\n        compute_all_pairs(dist, scan_pts, grid, m, move_cost);\n        auto order = nearest_neighbor_scan_order(scan_pts, start_idx, dist);\n        tsp2opt(order, dist, 8);\n        auto route=build_route(scan_pts,order,m,grid);\n        int cost=route_cost(route,grid);\n        if(route.front()!=route.back()) continue;\n        string res; bool ok = true;\n        for(int i=1;i<route.size();++i){\n            char c=move_dir(route[i-1],route[i]);\n            if(c=='\\0') ok=false;\n            res+=c;\n        }\n        int ci=si,cj=sj;\n        for(char c:res){\n            int d=find(DIRS,DIRS+4,c)-DIRS;\n            if(d>=4){ok=false; break;}\n            int ni=ci+DX[d],nj=cj+DY[d];\n            if(ni<0||nj<0||ni>=N||nj>=N||!(grid[ni][nj]>='5'&&grid[ni][nj]<='9')){ok=false;break;}\n            ci=ni; cj=nj;\n        }\n        if(!ok||ci!=si||cj!=sj) continue;\n        bool better = (scan_pts.size() < best_scanpt) || (scan_pts.size()==best_scanpt && cost < best_cost);\n        if(better){\n            best_cost = cost;\n            best_moves = res;\n            best_scanpt = scan_pts.size();\n            nbest = 1;\n            if(scan_pts.size() <= 38) break; // Early finish if very promising.\n        }else if(scan_pts.size()==best_scanpt&&cost==best_cost){\n            nbest++;\n        }\n    }\n    if(best_moves.empty()) { cout<<'\\n'; return 0; }\n    cout<<best_moves<<endl;\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int MAX_K = 20, MAX_M = 20, MAX_N = 1000;\n\nint n, m, k, r;\nvector<vector<int>> d;\nvector<vector<int>> dependencies, revdeps;\nvector<int> indegree;\nvector<int> status;\n\nstruct MemberState {\n    int current_task = -1;\n    int assigned_day = -1;\n};\n\nvector<MemberState> members;\nint current_day = 1;\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nstruct ProbeInfo {\n    vector<bool> axis_probed;\n    int boot_done = 0;\n    int probes_done = 0;\n    ProbeInfo(int K = MAX_K) : axis_probed(K, false) {}\n};\nvector<ProbeInfo> probeinfo;\n\nstruct FastSkillEstimate {\n    vector<int> estimate;\n    FastSkillEstimate(int K) : estimate(K, 0) {}\n};\nvector<FastSkillEstimate> skillstats;\n\nvector<vector<pair<int,int>>> member_finished_tasks;\nvector<int> task_criticality;\n\nvoid read_input() {\n    cin >> n >> m >> k >> r;\n    d.resize(n, vector<int>(k));\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < k; ++j)\n            cin >> d[i][j];\n    dependencies.assign(n, {});\n    revdeps.assign(n, {});\n    indegree.assign(n, 0);\n    for (int i = 0; i < r; ++i) {\n        int u, v; cin >> u >> v; --u; --v;\n        dependencies[v].push_back(u);\n        revdeps[u].push_back(v);\n        indegree[v]++;\n    }\n}\n\nvector<int> compute_critical_path() {\n    vector<int> critical(n, 0);\n    vector<int> topo;\n    vector<int> indeg_tmp = indegree;\n    queue<int> q;\n    for (int i = 0; i < n; ++i) if (indeg_tmp[i] == 0) q.push(i);\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        topo.push_back(u);\n        for (int v : revdeps[u]) {\n            --indeg_tmp[v];\n            if (indeg_tmp[v] == 0) q.push(v);\n        }\n    }\n    reverse(topo.begin(), topo.end());\n    for (int u : topo)\n        for (int v : revdeps[u])\n            critical[u] = max(critical[u], critical[v] + 1);\n    return critical;\n}\n\nvoid initialize() {\n    status.assign(n, 0);\n    members.assign(m, MemberState());\n    probeinfo.assign(m, ProbeInfo(k));\n    skillstats.assign(m, FastSkillEstimate(k));\n    member_finished_tasks.assign(m, {});\n    task_criticality = compute_critical_path();\n}\n\nset<int> ready_tasks;\nvoid add_ready_tasks() {\n    for (int i = 0; i < n; ++i)\n        if (indegree[i] == 0 && status[i] == 0)\n            ready_tasks.insert(i);\n}\n\nvector<vector<double>> estimate_skills() {\n    vector<vector<double>> est(m, vector<double>(k, 0.0));\n    for (int mi = 0; mi < m; ++mi)\n        for (int dim = 0; dim < k; ++dim)\n            est[mi][dim] = max(0, skillstats[mi].estimate[dim]);\n    return est;\n}\n\nvoid assign_tasks_today(vector<pair<int, int>>& assignments) {\n    vector<int> idle_members;\n    for (int j = 0; j < m; ++j)\n        if (members[j].current_task == -1)\n            idle_members.push_back(j);\n    set<int> used_tasks;\n    auto est_sk = estimate_skills();\n\n    for (int j : idle_members) {\n        // --- EARLY BOOTSTRAP: first 3 assignments use the easiest available tasks ---\n        if (probeinfo[j].boot_done < 3) {\n            int best_t = -1, best_sum = INT_MAX, best_crit = -1;\n            for (int t : ready_tasks) if (!used_tasks.count(t)) {\n                int sum = 0;\n                for (int kk = 0; kk < k; ++kk) sum += d[t][kk];\n                int tot=(int)revdeps[t].size();\n                if (sum < best_sum || (sum == best_sum && tot > best_crit)) {\n                    best_t = t; best_sum = sum; best_crit = tot;\n                }\n            }\n            if (best_t != -1) {\n                assignments.emplace_back(j, best_t);\n                used_tasks.insert(best_t);\n                status[best_t] = 1;\n                members[j].current_task = best_t;\n                members[j].assigned_day = current_day;\n                probeinfo[j].boot_done++;\n                continue;\n            }\n        }\n        // --- STRUCTURED EXPLORATION: assign member to tasks peaking on an unprobed axis ---\n        if (probeinfo[j].probes_done < k) {\n            for (int dim = 0; dim < k; ++dim) {\n                if (!probeinfo[j].axis_probed[dim]) {\n                    int best_t = -1, best_req = INT_MAX, best_crit = -1;\n                    for (int t: ready_tasks) if (!used_tasks.count(t)) {\n                        int peakval = -1, peakd=-1;\n                        for (int kk=0;kk<k;++kk)\n                            if (d[t][kk]>peakval) {peakval=d[t][kk]; peakd=kk;}\n                        if (peakd==dim) {\n                            int tot=(int)revdeps[t].size();\n                            if (d[t][peakd] < best_req || (d[t][peakd]==best_req && tot>best_crit)) {\n                                best_t = t; best_req=d[t][peakd]; best_crit=tot;\n                            }\n                        }\n                    }\n                    if (best_t != -1) {\n                        assignments.emplace_back(j, best_t);\n                        used_tasks.insert(best_t);\n                        status[best_t] = 1;\n                        members[j].current_task = best_t;\n                        members[j].assigned_day = current_day;\n                        break;\n                    }\n                }\n            }\n            if(members[j].current_task != -1) continue;\n            // If not found, fall through to exploitation\n        }\n\n        // --- EXPLOITATION: pick best estimated match with criticality ---\n        double best_score = 1e9; int best_task = -1; int best_crit = -1;\n        vector<int> candidates;\n        for (int t : ready_tasks) if (!used_tasks.count(t)) {\n            double w = 0;\n            for (int kk = 0; kk < k; ++kk)\n                if (d[t][kk] > est_sk[j][kk])\n                    w += (d[t][kk] - est_sk[j][kk]);\n            double expect = max(1.0, w);\n            int crit = task_criticality[t];\n            double score = expect - crit * 0.2;\n            if (score < best_score-1e-8) {\n                best_score = score;\n                best_task = t;\n                best_crit = crit;\n                candidates.clear();\n                candidates.push_back(t);\n            } else if (abs(score-best_score)<1e-8) {\n                candidates.push_back(t);\n            }\n        }\n        if (!candidates.empty()) {\n            int tsel = candidates[rng()%candidates.size()];\n            assignments.emplace_back(j, tsel);\n            used_tasks.insert(tsel);\n            status[tsel] = 1;\n            members[j].current_task = tsel;\n            members[j].assigned_day = current_day;\n        }\n    }\n}\n\nvoid process_feedback(const vector<int>& finished_members) {\n    for (int member : finished_members) {\n        auto& ms = members[member];\n        int tsk = ms.current_task, t0 = ms.assigned_day, obs_days = current_day - t0 + 1;\n        status[tsk] = 2;\n        ms.current_task = -1;\n        ms.assigned_day = -1;\n        member_finished_tasks[member].emplace_back(tsk, obs_days);\n\n        // After each of the first 3 bootstraps: if t=1, lift all skills to requirement of this task\n        if(probeinfo[member].boot_done>0 && probeinfo[member].boot_done<=3){\n            if(obs_days==1)\n                for(int kk=0;kk<k;++kk)\n                    skillstats[member].estimate[kk]=max(skillstats[member].estimate[kk],d[tsk][kk]);\n        }\n        // Structured probe info update\n        int peakv=-1, peakd=-1;\n        for(int kk=0;kk<k;++kk) if(d[tsk][kk]>peakv){ peakv=d[tsk][kk]; peakd=kk;}\n        if(!probeinfo[member].axis_probed[peakd]){\n            probeinfo[member].axis_probed[peakd]=true;\n            probeinfo[member].probes_done++;\n        }\n        // As before, only ever lift skill estimates up, never down\n        for(int kk=0;kk<k;++kk){\n            int val = d[tsk][kk] - max(0, obs_days-1);\n            if(val > skillstats[member].estimate[kk])\n                skillstats[member].estimate[kk] = val;\n        }\n        for (int dv : revdeps[tsk]) {\n            --indegree[dv];\n            if (indegree[dv] == 0 && status[dv] == 0)\n                ready_tasks.insert(dv);\n        }\n    }\n}\n\nvoid print_assignments(const vector<pair<int, int>>& assignments) {\n    cout << assignments.size();\n    for (auto [member, task] : assignments)\n        cout << ' ' << (member + 1) << ' ' << (task + 1);\n    cout << '\\n';\n    cout.flush();\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    read_input();\n    initialize();\n    add_ready_tasks();\n\n    while (true) {\n        vector<pair<int, int>> assignments;\n        assign_tasks_today(assignments);\n        for (auto &p : assignments)\n            ready_tasks.erase(p.second);\n        print_assignments(assignments);\n\n        string line;\n        while (true) {\n            getline(cin, line);\n            if (cin.eof()) exit(0);\n            if (!line.empty()) break;\n        }\n        if (line==\"-1\") break;\n        istringstream iss(line);\n        int cnt; iss >> cnt;\n        if (cnt==-1) break;\n        vector<int> finished(cnt);\n        for (int i = 0; i < cnt; ++i) { int x; iss >> x; finished[i]=x-1;}\n        process_feedback(finished);\n        current_day++;\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\nmt19937 rng(42);\n\nstruct Order {\n    int id;\n    int ax, ay;\n    int cx, cy;\n    int score;\n};\n\nint manh(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\nstruct Node {\n    int x, y;\n    int ord_idx;\n    bool is_pickup;\n};\n\nstruct Result {\n    vector<int> sel_ids;\n    vector<pair<int,int>> route;\n    int route_cost;\n};\n\nResult get_route_raw(const vector<Order>& sel_orders_50, const vector<int> &order_seq) {\n    vector<Node> nodes;\n    for (int i = 0; i < 50; ++i)\n        nodes.push_back({sel_orders_50[i].ax, sel_orders_50[i].ay, i, true});\n    for (int i = 0; i < 50; ++i)\n        nodes.push_back({sel_orders_50[i].cx, sel_orders_50[i].cy, i, false});\n\n    vector<pair<int,int>> route = {{400,400}};\n    for(int idx: order_seq)\n        route.emplace_back(nodes[idx].x, nodes[idx].y);\n    route.emplace_back(400,400);\n\n    int cost=0;\n    for(int i=1;i<(int)route.size();++i)\n        cost += manh(route[i-1].first,route[i-1].second,route[i].first,route[i].second);\n\n    vector<int> sel_ids;\n    for(const auto&o:sel_orders_50)sel_ids.push_back(o.id+1);\n    return {sel_ids,route,cost};\n}\n\nResult get_route(const vector<Order>& sel_orders, int variant=0, vector<int>* ret_seq=nullptr) {\n    vector<Node> nodes;\n    for (int i = 0; i < 50; ++i)\n        nodes.push_back({sel_orders[i].ax, sel_orders[i].ay, i, true});\n    for (int i = 0; i < 50; ++i)\n        nodes.push_back({sel_orders[i].cx, sel_orders[i].cy, i, false});\n    int N = nodes.size();\n\n    vector<bool> visited(N, false);\n    vector<bool> pickup_done(50, false);\n\n    int cur_x = 400, cur_y = 400;\n    vector<int> visit_seq;\n    for (int step = 0; step < N; ++step) {\n        vector<int> avail;\n        for (int i = 0; i < N; ++i) if (!visited[i]) {\n            if (!nodes[i].is_pickup && !pickup_done[nodes[i].ord_idx]) continue;\n            avail.push_back(i);\n        }\n        int best = -1, best_dist = 1e9;\n        vector<int> candidates;\n        for (int i : avail) {\n            int dist = manh(cur_x, cur_y, nodes[i].x, nodes[i].y);\n            if (dist < best_dist) {\n                best_dist = dist;\n                candidates.clear();\n                candidates.push_back(i);\n            }\n            else if (dist == best_dist) candidates.push_back(i);\n        }\n        if(!candidates.empty()) {\n            if(variant==0) best = candidates[0];\n            else best = candidates[rng()%candidates.size()];\n        } else {\n            best = avail[rng()%avail.size()];\n        }\n        visited[best]=true;\n        if(nodes[best].is_pickup) pickup_done[nodes[best].ord_idx]=true;\n        cur_x = nodes[best].x; cur_y = nodes[best].y;\n        visit_seq.push_back(best);\n    }\n    if (ret_seq) *ret_seq = visit_seq;\n    vector<pair<int,int>> route = {{400,400}};\n    for(auto i:visit_seq) route.emplace_back(nodes[i].x, nodes[i].y);\n    route.emplace_back(400,400);\n    int cost=0;\n    for(int i=1;i<(int)route.size();++i)\n        cost += manh(route[i-1].first,route[i-1].second,route[i].first,route[i].second);\n    vector<int> sel_ids;\n    for(const auto&o:sel_orders)sel_ids.push_back(o.id+1);\n    return {sel_ids,route,cost};\n}\n\nbool sequence_feasible(const vector<int>& seq) {\n    vector<bool> pickdone(50, false);\n    for(int i:seq) {\n        if(i>=50 && !pickdone[i-50]) return false;\n        if(i<50) pickdone[i]=true;\n    }\n    return true;\n}\n\nvoid route_2swap_local(vector<Order>& sel_orders, vector<int>& best_seq, int& best_cost, int max_rounds=1) {\n    int N = best_seq.size();\n    for(int round=0;round<max_rounds;++round) {\n        bool improved=false;\n        for(int i=0;i<N-2;++i) {\n            for(int j=i+1;j<N-1;++j) {\n                if(i==j) continue;\n                vector<int> nseq = best_seq;\n                swap(nseq[i], nseq[j]);\n                if(!sequence_feasible(nseq)) continue;\n                Result tryR = get_route_raw(sel_orders, nseq);\n                if(tryR.route_cost < best_cost) {\n                    best_cost = tryR.route_cost;\n                    best_seq = nseq;\n                    improved=true;\n                }\n            }\n        }\n        if(!improved) break;\n    }\n}\n\nvoid improve_order_set(const vector<Order>& orders_all, vector<Order>& sel_orders, int imp_trials=13, int imp_nb_out=6, int imp_nb_in=8) {\n    set<int> chosen;\n    for(auto&o:sel_orders) chosen.insert(o.id);\n    vector<Order> unchosen;\n    for(const auto&o:orders_all) if(!chosen.count(o.id)) unchosen.push_back(o);\n\n    int best_cost = get_route(sel_orders, 1).route_cost;\n\n    for(int trial=0; trial<imp_trials; ++trial){\n        vector<int> idx_out;\n        for(int i=0;i<(int)sel_orders.size();++i) idx_out.push_back(i);\n        shuffle(idx_out.begin(),idx_out.end(),rng);\n        idx_out.resize(min((int)idx_out.size(),imp_nb_out));\n\n        vector<int> idx_in;\n        for(int i=0;i<(int)unchosen.size();++i) idx_in.push_back(i);\n        shuffle(idx_in.begin(),idx_in.end(),rng);\n        idx_in.resize(min((int)idx_in.size(),imp_nb_in));\n\n        bool changed = false;\n        for(int oi:idx_out) {\n            for(int ii:idx_in) {\n                Order out = sel_orders[oi];\n                Order in = unchosen[ii];\n                sel_orders[oi] = in;\n                set<int> checkset;\n                for(auto&o:sel_orders) checkset.insert(o.id);\n                if(checkset.size()<50) {\n                    sel_orders[oi] = out;\n                    continue;\n                }\n                int cost = get_route(sel_orders, 1).route_cost;\n                if(cost < best_cost) {\n                    best_cost = cost;\n                    unchosen[ii] = out;\n                    changed = true;\n                    break;\n                } else {\n                    sel_orders[oi] = out;\n                }\n            }\n            if(changed) break;\n        }\n        if(!changed) break;\n    }\n}\n\n// New: 2-out 2-in swap set improvement\nvoid improve_order_set_2swap(const vector<Order>& orders_all, vector<Order>& sel_orders, int imp_trials=4, int imp_nb_out=7, int imp_nb_in=8) {\n    set<int> chosen;\n    for(const auto&o:sel_orders) chosen.insert(o.id);\n    vector<Order> unchosen;\n    for(const auto&o:orders_all) if(!chosen.count(o.id)) unchosen.push_back(o);\n\n    int best_cost = get_route(sel_orders, 1).route_cost;\n\n    for(int trial=0; trial<imp_trials; ++trial){\n        vector<int> idx_out;\n        for(int i=0;i<(int)sel_orders.size();++i) idx_out.push_back(i);\n        shuffle(idx_out.begin(),idx_out.end(),rng);\n        idx_out.resize(min((int)idx_out.size(),imp_nb_out));\n        vector<int> idx_in;\n        for(int i=0;i<(int)unchosen.size();++i) idx_in.push_back(i);\n        shuffle(idx_in.begin(),idx_in.end(),rng);\n        idx_in.resize(min((int)idx_in.size(),imp_nb_in));\n        bool changed = false;\n        for(int i1=0;i1<(int)idx_out.size();++i1)\n        for(int i2=i1+1;i2<(int)idx_out.size();++i2) {\n            int oi1=idx_out[i1], oi2=idx_out[i2];\n            for(int j1=0;j1<(int)idx_in.size();++j1)\n            for(int j2=j1+1;j2<(int)idx_in.size();++j2) {\n                int ii1=idx_in[j1], ii2=idx_in[j2];\n                auto out1=sel_orders[oi1], out2=sel_orders[oi2];\n                auto in1=unchosen[ii1], in2=unchosen[ii2];\n                sel_orders[oi1]=in1; sel_orders[oi2]=in2;\n                set<int> checkset;\n                for(const auto&o:sel_orders) checkset.insert(o.id);\n                if((int)checkset.size()<50) { sel_orders[oi1]=out1; sel_orders[oi2]=out2; continue; }\n                int cost = get_route(sel_orders,1).route_cost;\n                if(cost < best_cost) {\n                    best_cost = cost;\n                    unchosen[ii1]=out1; unchosen[ii2]=out2;\n                    changed = true;\n                    break;\n                } else {\n                    sel_orders[oi1]=out1; sel_orders[oi2]=out2;\n                }\n            }\n            if(changed) break;\n        }\n        if(!changed) break;\n    }\n}\n\nvoid fill_to_50_smart(vector<Order>& sel, const vector<Order>& all, int nfill) {\n    set<int> curids;\n    for(auto&o:sel) curids.insert(o.id);\n\n    vector<pair<int,int>> sel_pts;\n    for(auto&o:sel) {\n        sel_pts.emplace_back(o.ax, o.ay);\n        sel_pts.emplace_back(o.cx, o.cy);\n    }\n\n    vector<pair<double,int>> can_add;\n    for(int i=0;i<(int)all.size();++i) if(!curids.count(all[i].id)) {\n        int min_dist = INT_MAX;\n        for(const auto&pt : sel_pts)\n            min_dist = min(min_dist, manh(pt.first, pt.second, all[i].ax, all[i].ay));\n        double h = all[i].score + 0.5 * min_dist;\n        can_add.push_back({h, i});\n    }\n    sort(can_add.begin(), can_add.end());\n    for(int add=0;add<nfill && add<(int)can_add.size();++add) {\n        sel.push_back(all[can_add[add].second]);\n    }\n}\n\nvoid kmeans(const vector<pair<int,int>>& pts, int K, vector<int>& belong, vector<pair<int,int>>& centers, int iters=4) {\n    int N = pts.size();\n    belong.resize(N);\n    vector<pair<int,int>> centers2;\n    centers2.push_back(pts[rng()%N]);\n    vector<int> dist(N, 1e9);\n    for (int k = 1; k < K; ++k) {\n        int S = 0;\n        for (int i = 0; i < N; ++i) {\n            int d = manh(pts[i].first, pts[i].second, centers2.back().first, centers2.back().second);\n            if(d < dist[i]) dist[i] = d;\n            S += dist[i];\n        }\n        if(S==0) break;\n        int t = rng()%S, acc=0,i=0;\n        for(;i<N&&acc<t;++i) acc+=dist[i];\n        centers2.push_back(pts[(i==N)?N-1:i]);\n    }\n    centers = centers2;\n\n    for (int it = 0; it < iters; ++it) {\n        for (int i = 0; i < N; ++i) {\n            int best = 0, best_d = manh(pts[i].first, pts[i].second, centers[0].first, centers[0].second);\n            for (int k = 1; k < K; ++k) {\n                int d = manh(pts[i].first, pts[i].second, centers[k].first, centers[k].second);\n                if (d < best_d) best_d = d, best = k;\n            }\n            belong[i] = best;\n        }\n        vector<int64_t> sx(K, 0), sy(K, 0), sn(K, 0);\n        for (int i = 0; i < N; ++i) {\n            sx[belong[i]] += pts[i].first;\n            sy[belong[i]] += pts[i].second;\n            sn[belong[i]] += 1;\n        }\n        for (int k = 0; k < K; ++k) {\n            if (sn[k]) centers[k] = {int(sx[k]/sn[k]), int(sy[k]/sn[k])};\n        }\n    }\n}\n\nvoid run_strategy(const vector<Order> &orders, const vector<int> &belong, const vector<pair<int,int>> &centers, int CLUSTER_TRY, int RUNS_PER_CLUSTER, int &best_cost, vector<int>& best_sel_ids, vector<pair<int,int>>& best_route) {\n    int K = centers.size();\n    vector<int> center_order(K);\n    iota(center_order.begin(),center_order.end(),0);\n    sort(center_order.begin(),center_order.end(),[&](int i,int j){\n        int di=manh(400,400,centers[i].first,centers[i].second);\n        int dj=manh(400,400,centers[j].first,centers[j].second);\n        return di<dj;\n    });\n\n    for(int cl=0;cl<CLUSTER_TRY;++cl){\n        int cid = center_order[cl];\n        vector<Order> cand0;\n        for(int i=0;i<orders.size();++i)if(belong[i]==cid)\n            cand0.push_back(orders[i]);\n        sort(cand0.begin(),cand0.end(),[](const Order&a,const Order&b){return a.score<b.score;});\n        int in_cluster = min((int)cand0.size(),38);\n        vector<Order> candA(cand0.begin(),cand0.begin()+in_cluster);\n        fill_to_50_smart(candA, orders, 50-in_cluster);\n        improve_order_set(orders, candA, 13, 6, 7);\n\n        for(int run=0;run<RUNS_PER_CLUSTER;++run){\n            Result res = get_route(candA, run>0?1:0);\n            if(res.route_cost < best_cost){\n                best_cost = res.route_cost;\n                best_sel_ids=res.sel_ids;\n                best_route=res.route;\n            }\n        }\n    }\n}\n\nvoid run_pair_strategy(const vector<Order> &orders, const vector<int> &belong, const vector<pair<int,int>> &centers, int PAIR_TRY, int subsize, int &best_cost, vector<int>& best_sel_ids, vector<pair<int,int>>& best_route) {\n    int K = centers.size();\n    vector<pair<int,int>> cluster_ord;\n    for(int i=0;i<K;++i)\n        cluster_ord.emplace_back(manh(400,400,centers[i].first, centers[i].second), i);\n    sort(cluster_ord.begin(),cluster_ord.end());\n    int pszs = subsize;\n    int cnt = 0;\n    for(int p1=0;p1<min(K,4);++p1) {\n        for(int p2=p1+1;p2<min(K,7);++p2) {\n            if(cnt++ > PAIR_TRY) break;\n            int c1 = cluster_ord[p1].second;\n            int c2 = cluster_ord[p2].second;\n            vector<Order> c1s, c2s;\n            for(int i=0;i<(int)orders.size();++i) if(belong[i]==c1) c1s.push_back(orders[i]);\n            for(int i=0;i<(int)orders.size();++i) if(belong[i]==c2) c2s.push_back(orders[i]);\n            sort(c1s.begin(),c1s.end(),[](const Order&a,const Order&b){return a.score<b.score;});\n            sort(c2s.begin(),c2s.end(),[](const Order&a,const Order&b){return a.score<b.score;});\n            int m1 = min(pszs, (int)c1s.size());\n            int m2 = min(pszs, (int)c2s.size());\n            set<int> ids;\n            vector<Order> cand;\n            for(int i=0; i<m1 && (int)cand.size()<50; ++i) {\n                if(!ids.count(c1s[i].id)) {\n                    ids.insert(c1s[i].id);\n                    cand.push_back(c1s[i]);\n                }\n            }\n            for(int i=0; i<m2 && (int)cand.size()<50; ++i) {\n                if(!ids.count(c2s[i].id)) {\n                    ids.insert(c2s[i].id);\n                    cand.push_back(c2s[i]);\n                }\n            }\n            fill_to_50_smart(cand, orders, 50-cand.size());\n            improve_order_set(orders, cand, 11, 5, 6);\n            Result res = get_route(cand, 1);\n            if(res.route_cost < best_cost){\n                best_cost = res.route_cost;\n                best_sel_ids=res.sel_ids;\n                best_route=res.route;\n            }\n        }\n        if(cnt > PAIR_TRY) break;\n    }\n}\n\nvoid run_random_trials(const vector<Order> &orders, int ntrial, int &best_cost, vector<int>& best_sel_ids, vector<pair<int,int>>& best_route) {\n    vector<int> perm(orders.size());\n    iota(perm.begin(),perm.end(),0);\n\n    for(int t=0;t<ntrial;++t) {\n        shuffle(perm.begin(),perm.end(),rng);\n        vector<Order> sel;\n        sel.reserve(50);\n        set<int> seen;\n        for(int i=0; i<(int)orders.size() && (int)sel.size()<50; ++i) {\n            if(!seen.count(orders[perm[i]].id)) {\n                sel.push_back(orders[perm[i]]);\n                seen.insert(orders[perm[i]].id);\n            }\n        }\n        improve_order_set(orders, sel, 10, 5, 6);\n        Result res = get_route(sel, 1);\n        if(res.route_cost < best_cost){\n            best_cost = res.route_cost;\n            best_sel_ids=res.sel_ids;\n            best_route=res.route;\n        }\n    }\n}\n\nvoid greedy_construct(const vector<Order> &orders, int &best_cost, vector<int> &best_sel_ids, vector<pair<int,int>> &best_route, int seedidx = -1) {\n    int N = orders.size();\n    vector<bool> used(N, false);\n    vector<Order> cur_orders;\n    cur_orders.reserve(50);\n\n    vector<int> rem(N); iota(rem.begin(), rem.end(), 0);\n\n    if (seedidx < 0) {\n        sort(rem.begin(), rem.end(), [&](int i, int j) { return orders[i].score < orders[j].score; });\n        seedidx = rem[0];\n    }\n\n    cur_orders.push_back(orders[seedidx]);\n    used[seedidx] = true;\n\n    for (int k = 1; k < 50; ++k) {\n        vector<int> pool;\n        int lim = min(80, (int)rem.size());\n        for (int t = 0; t < lim; ++t)\n            if (!used[rem[t]]) pool.push_back(rem[t]);\n        for (int t = 0; t < 15; ++t) {\n            int rid = rng() % N;\n            if (!used[rid])\n                pool.push_back(rid);\n        }\n        int best = -1;\n        double best_proxy = 1e18;\n        for (int idx : pool) {\n            int mind = 1e9;\n            for (const auto &sq : cur_orders)\n                mind = min(mind, manh(sq.ax, sq.ay, orders[idx].ax, orders[idx].ay));\n            double proxy = orders[idx].score + 0.8 * mind;\n            if (proxy < best_proxy) {\n                best = idx;\n                best_proxy = proxy;\n            }\n        }\n        if (best != -1) {\n            cur_orders.push_back(orders[best]);\n            used[best] = true;\n        }\n    }\n    improve_order_set(orders, cur_orders, 10, 4, 5);\n    Result res = get_route(cur_orders, 1);\n    if (res.route_cost < best_cost) {\n        best_cost = res.route_cost;\n        best_sel_ids = res.sel_ids;\n        best_route = res.route;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    vector<Order> orders(1000);\n    for (int i = 0; i < 1000; ++i) {\n        int a, b, c, d;\n        cin >> a >> b >> c >> d;\n        orders[i] = {i, a, b, c, d, 0};\n    }\n    for (auto &o : orders) {\n        o.score = manh(400, 400, o.ax, o.ay) + manh(o.ax, o.ay, o.cx, o.cy) + manh(o.cx, o.cy, 400, 400);\n    }\n\n    int best_cost = INT_MAX;\n    vector<int> best_sel_ids;\n    vector<pair<int,int>> best_route;\n    vector<int> best_seq;\n\n    int K = 10, CLUSTER_TRY = 6, RUNS_PER_CLUSTER = 4;\n    vector<pair<int, int>> pickups, deliveries;\n    for (auto &o : orders) {\n        pickups.emplace_back(o.ax, o.ay);\n        deliveries.emplace_back(o.cx, o.cy);\n    }\n    vector<int> belong_pick, belong_del;\n    vector<pair<int, int>> centers_pick, centers_del;\n    kmeans(pickups, K, belong_pick, centers_pick, 3);\n    kmeans(deliveries, K, belong_del, centers_del, 3);\n\n    run_strategy(orders, belong_pick, centers_pick, CLUSTER_TRY, RUNS_PER_CLUSTER, best_cost, best_sel_ids, best_route);\n    run_strategy(orders, belong_del, centers_del, CLUSTER_TRY, RUNS_PER_CLUSTER, best_cost, best_sel_ids, best_route);\n    run_pair_strategy(orders, belong_pick, centers_pick, 8, 26, best_cost, best_sel_ids, best_route);\n    run_pair_strategy(orders, belong_del, centers_del, 8, 26, best_cost, best_sel_ids, best_route);\n\n    sort(orders.begin(), orders.end(), [](const Order& a, const Order& b) {\n        return a.score < b.score;\n    });\n    vector<Order> top50(orders.begin(), orders.begin() + 50);\n\n    improve_order_set(orders, top50, 8, 4, 5);\n    Result res = get_route(top50, 1, &best_seq);\n    if (res.route_cost < best_cost) {\n        best_cost = res.route_cost;\n        best_sel_ids = res.sel_ids;\n        best_route = res.route;\n    } else {\n        get_route(top50, 1, &best_seq);\n    }\n\n    run_random_trials(orders, 18, best_cost, best_sel_ids, best_route);\n\n    greedy_construct(orders, best_cost, best_sel_ids, best_route, -1);\n    for (int s = 0; s < 5; ++s)\n        greedy_construct(orders, best_cost, best_sel_ids, best_route, rng() % 1000);\n\n    // 2-out 2-in improvement\n    vector<Order> chosen_orders;\n    set<int> chosen_set;\n    for(int rid : best_sel_ids) chosen_set.insert(rid-1);\n    for(const auto&o:orders) if(chosen_set.count(o.id)) chosen_orders.push_back(o);\n    improve_order_set_2swap(orders, chosen_orders, 2, 6, 8);\n\n    vector<int> seq;\n    Result rr = get_route(chosen_orders, 1, &seq);\n    best_cost = rr.route_cost;\n    best_sel_ids = rr.sel_ids;\n    best_route = rr.route;\n\n    route_2swap_local(chosen_orders, seq, best_cost, 2);\n    Result r2 = get_route_raw(chosen_orders, seq);\n    best_cost = r2.route_cost;\n    best_sel_ids = r2.sel_ids;\n    best_route = r2.route;\n\n    cout << \"50\";\n    for (int i = 0; i < 50; ++i)\n        cout << \" \" << best_sel_ids[i];\n    cout << \"\\n\";\n    cout << best_route.size();\n    for (auto &p : best_route)\n        cout << \" \" << p.first << \" \" << p.second;\n    cout << \"\\n\";\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 400, M = 1995;\n\nstruct DSU {\n    vector<int> par, sz;\n    vector<bitset<N>> members;\n    DSU(int n) : par(n), sz(n, 1), members(n) {\n        iota(par.begin(), par.end(), 0);\n        for(int i=0; i<n; ++i) members[i].set(i);\n    }\n    int find(int x) { return par[x]==x ? x : par[x]=find(par[x]); }\n    bool unite(int x, int y) {\n        x = find(x); y = find(y);\n        if(x == y) return false;\n        if(sz[x]<sz[y]) swap(x,y);\n        par[y]=x; sz[x]+=sz[y];\n        members[x] |= members[y];\n        members[y].reset();\n        return true;\n    }\n    bitset<N>& get_members(int x) { return members[find(x)]; }\n    int component_size(int x) { return sz[find(x)]; }\n};\n\nstruct Edge { int u, v, d; };\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Use a random seed (can replace with chrono for each submission/rerun)\n    mt19937 rng(time(nullptr));\n\n    vector<pair<int,int>> coords(N);\n    for(int i=0; i<N; ++i) cin >> coords[i].first >> coords[i].second;\n    vector<Edge> edges(M);\n    vector<vector<queue<int>>> pair_edge_ids(N, vector<queue<int>>(N));\n    vector<vector<int>> d_table(N, vector<int>(N, -1));\n    vector<vector<int>> rem_edge_cnt(N, vector<int>(N, 0));\n    for(int i=0; i<M; ++i) {\n        int u, v; cin >> u >> v;\n        int x1=coords[u].first, y1=coords[u].second;\n        int x2=coords[v].first, y2=coords[v].second;\n        int d = round(sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));\n        edges[i] = {u, v, d};\n        pair_edge_ids[min(u,v)][max(u,v)].push(i);\n        d_table[min(u,v)][max(u,v)] = d;\n        rem_edge_cnt[min(u,v)][max(u,v)]++;\n    }\n    DSU dsu(N);\n\n    int num_components = N;\n\n    // Tuned parameters!\n    double cheap_factor_base = 1.073;\n    double cheap_factor_final = 1.157;\n    double extra_factor_2edges = 1.12;\n    double extra_factor_1edge = 1.18;\n    // For very large components, be slightly more aggressive (risk management)\n    double bigcomp_threshold_boost = 1.01;\n\n    for(int i=0; i<M; ++i) {\n        int l_i; cin >> l_i;\n        int u = edges[i].u, v = edges[i].v, d = edges[i].d;\n        bool accepted = false;\n        int ru = dsu.find(u), rv = dsu.find(v);\n        if(ru == rv) {\n            pair_edge_ids[min(u,v)][max(u,v)].pop();\n            rem_edge_cnt[min(u,v)][max(u,v)]--;\n            cout << 0 << endl; cout << flush;\n            continue;\n        }\n        auto &q = pair_edge_ids[min(u,v)][max(u,v)];\n        q.pop();\n        rem_edge_cnt[min(u,v)][max(u,v)]--;\n\n        int remain = 0, min_d = 1e9;\n        auto &A = dsu.get_members(ru), &B = dsu.get_members(rv);\n        for(int a = A._Find_first(); a < N; a = A._Find_next(a)) {\n            for(int b = B._Find_first(); b < N; b = B._Find_next(b)) {\n                if(a == b) continue;\n                int uu=min(a,b), vv=max(a,b);\n                int cnt = rem_edge_cnt[uu][vv];\n                if(cnt) {\n                    remain += cnt;\n                    if(d_table[uu][vv]>=0) min_d = min(min_d, d_table[uu][vv]);\n                }\n            }\n        }\n\n        bool must_accept = (remain == 0);\n        int comp_sz = max(dsu.component_size(ru), dsu.component_size(rv));\n\n        double cheap_factor;\n        if (must_accept)             cheap_factor = extra_factor_1edge;\n        else if (remain == 1)        cheap_factor = extra_factor_1edge;\n        else if (remain == 2)        cheap_factor = extra_factor_2edges;\n        else if (num_components > 250) cheap_factor = 1.050;\n        else if (num_components > 100) cheap_factor = cheap_factor_base;\n        else if (num_components > 20)  cheap_factor = (cheap_factor_base + 0.5 * (cheap_factor_final - cheap_factor_base));\n        else                           cheap_factor = cheap_factor_final;\n\n        // For very large components, bump threshold up for insurance!\n        if(comp_sz >= 200) cheap_factor *= bigcomp_threshold_boost;\n\n        int hard_thres = int(cheap_factor * min_d);\n\n        if(must_accept) {\n            cout << 1 << endl; cout << flush;\n            dsu.unite(u,v); --num_components;\n            accepted = true;\n        } else if(l_i <= hard_thres) {\n            cout << 1 << endl; cout << flush;\n            dsu.unite(u,v); --num_components;\n            accepted = true;\n        } else if(l_i <= hard_thres+7) {\n            // Fuzzy random acceptance: probability decays quickly.\n            // Accept with 15% at +1, 7% +2, 5% +3, 2% +4, 1% +5, 1% +6, 0.5% +7.\n            int diff = l_i - hard_thres;\n            static const int p[] = {0,15,7,5,2,1,1,0};\n            if(p[min(diff,7)] && (rng()%100 < p[min(diff,7)])) {\n                cout << 1 << endl; cout << flush;\n                dsu.unite(u,v); --num_components;\n                accepted = true;\n            }\n        }\n        if(!accepted) {\n            cout << 0 << endl; cout << flush;\n        }\n    }\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int W = 30, H = 30;\nconstexpr int DX[4] = {-1, 1, 0, 0};\nconstexpr int DY[4] = {0, 0, -1, 1};\nconstexpr char MOVES[4] = {'U', 'D', 'L', 'R'};\nconstexpr char WALLS[4] = {'u', 'd', 'l', 'r'};\n\ninline bool ins(int x, int y) { return 0 <= x && x < H && 0 <= y && y < W; }\n\nstruct Pet { int x, y, type; };\nstruct Human { int x, y, dest_x, dest_y, band_l, band_r; };\n\nint get_dir_wall(char c) { if (c=='u')return 0; if (c=='d')return 1; if (c=='l')return 2; if (c=='r')return 3; return -1; }\nint get_dir_move(char c) { if (c=='U')return 0; if (c=='D')return 1; if (c=='L')return 2; if (c=='R')return 3; return -1; }\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n\n    int N; cin >> N;\n    vector<Pet> pets(N);\n    vector<string> grid(H, string(W, '.'));\n    for (int i = 0; i < N; i++) {\n        int x, y, t; cin >> x >> y >> t; --x; --y;\n        pets[i] = {x, y, t}; grid[x][y] = 'p';\n    }\n    int M; cin >> M;\n    vector<Human> humans(M);\n    for (int i = 0; i < M; i++) {\n        int x, y; cin >> x >> y; --x; --y;\n        humans[i].x = x; humans[i].y = y; grid[x][y] = 'h';\n    }\n    int band_size = W / M;\n    for (int i = 0; i < M; i++) {\n        int l = i * band_size, r = (i == M-1 ? W-1 : (i+1)*band_size-1);\n        humans[i].band_l=l; humans[i].band_r=r;\n        humans[i].dest_x=H/2; humans[i].dest_y=(l+r)/2;\n    }\n\n    vector<vector<int>> pet_grid(H, vector<int>(W, 0));\n    int phase_move = 12;\n    vector<vector<bool>> will_wall(H, vector<bool>(W, false));\n    for (int turn = 0; turn < 300; ++turn) {\n        string actions(M, '.');\n        for (int i = 0; i < H; ++i)\n            for (int j = 0; j < W; ++j)\n                if (grid[i][j]=='h' || grid[i][j]=='p') grid[i][j] = '.';\n        for (int i = 0; i < H; ++i) fill(pet_grid[i].begin(), pet_grid[i].end(), 0);\n        vector<vector<int>> human_grid(H, vector<int>(W, 0));\n        for (int i = 0; i < M; ++i) {\n            grid[humans[i].x][humans[i].y] = 'h';\n            human_grid[humans[i].x][humans[i].y]++;\n        }\n        for (int i = 0; i < N; ++i) {\n            grid[pets[i].x][pets[i].y] = 'p';\n            pet_grid[pets[i].x][pets[i].y]++;\n        }\n        for (int i = 0; i < H; ++i) fill(will_wall[i].begin(), will_wall[i].end(), false);\n\n        // 1. Mark all will_wall positions (plan all wall placements for this turn)\n        for (int i = 0; i < M; ++i) {\n            auto& h = humans[i];\n            int cx=h.x, cy=h.y, xl=h.band_l, xr=h.band_r;\n            if (turn < phase_move) continue;\n            for (int d = 0; d < 4; ++d) {\n                int tx=cx+DX[d], ty=cy+DY[d];\n                if (!ins(tx,ty)) continue;\n                if (!(ty == xl-1 || ty == xr+1)) continue;\n                if (grid[tx][ty]!='.') continue;\n                if (human_grid[tx][ty]!=0 || pet_grid[tx][ty]!=0) continue;\n                bool safe=true;\n                for (int d2=0; d2<4; ++d2) {\n                    int nx=tx+DX[d2], ny=ty+DY[d2];\n                    if (ins(nx,ny)&&pet_grid[nx][ny]) {safe=false; break;}\n                }\n                if (safe) will_wall[tx][ty]=true;\n            }\n        }\n\n        // 2. Now assign actions, disallowing movement into \"will_wall\" cells!\n        for (int i = 0; i < M; ++i) {\n            auto& h = humans[i];\n            int cx=h.x, cy=h.y, xl=h.band_l, xr=h.band_r;\n            if (turn < phase_move) {\n                int destx=h.dest_x, desty=h.dest_y;\n                if (cx < destx && ins(cx+1,cy) && grid[cx+1][cy]=='.' && !will_wall[cx+1][cy]) actions[i]='D';\n                else if (cx > destx && ins(cx-1,cy) && grid[cx-1][cy]=='.' && !will_wall[cx-1][cy]) actions[i]='U';\n                else if (cy < desty && ins(cx,cy+1) && grid[cx][cy+1]=='.' && !will_wall[cx][cy+1]) actions[i]='R';\n                else if (cy > desty && ins(cx,cy-1) && grid[cx][cy-1]=='.' && !will_wall[cx][cy-1]) actions[i]='L';\n                continue;\n            }\n            bool did_wall=false;\n            for (int d=0; d<4 && !did_wall; ++d) {\n                int tx=cx+DX[d], ty=cy+DY[d];\n                if (!ins(tx,ty)) continue;\n                if (!(ty == xl-1 || ty == xr+1)) continue;\n                if (grid[tx][ty]!='.') continue;\n                if (human_grid[tx][ty]!=0 || pet_grid[tx][ty]!=0) continue;\n                bool safe=true;\n                for (int d2=0; d2<4; ++d2) {\n                    int nx=tx+DX[d2], ny=ty+DY[d2];\n                    if (ins(nx,ny)&&pet_grid[nx][ny]) {safe=false; break;}\n                }\n                if (safe&&!will_wall[tx][ty]) { actions[i]=WALLS[d]; did_wall=true; }\n            }\n            if (did_wall) continue;\n            if (cy < xl && ins(cx,cy+1) && grid[cx][cy+1]=='.' && !will_wall[cx][cy+1]) actions[i]='R';\n            else if (cy > xr && ins(cx,cy-1) && grid[cx][cy-1]=='.' && !will_wall[cx][cy-1]) actions[i]='L';\n        }\n        cout << actions << '\\n' << flush;\n\n        // Wall placements\n        for (int i = 0; i < M; ++i) {\n            int dir = get_dir_wall(actions[i]);\n            if (dir >= 0) {\n                int wx=humans[i].x+DX[dir], wy=humans[i].y+DY[dir];\n                if (ins(wx,wy)) grid[wx][wy]='#';\n            }\n        }\n        vector<string> pet_moves(N);\n        for (int i = 0; i < N; ++i) cin >> pet_moves[i];\n        for (int i = 0; i < M; ++i) {\n            int dir=get_dir_move(actions[i]), nx=humans[i].x, ny=humans[i].y;\n            if (dir>=0) {\n                nx+=DX[dir], ny+=DY[dir];\n                if (ins(nx,ny)&&grid[nx][ny]=='.'&& !will_wall[nx][ny]) {humans[i].x=nx; humans[i].y=ny;}\n            }\n        }\n        for (int i = 0; i < N; ++i) for (char c : pet_moves[i]) {\n            int dir=get_dir_move(c), nx=pets[i].x, ny=pets[i].y;\n            if (dir>=0) {\n                nx+=DX[dir]; ny+=DY[dir];\n                if (ins(nx,ny)&&grid[nx][ny]!='#') pets[i].x=nx,pets[i].y=ny;\n            }\n        }\n    }\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Directions: U, D, L, R\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst char DC[] = {'U', 'D', 'L', 'R'};\n\nstruct WallMap {\n    int h[20][19]; // right wall\n    int v[19][20]; // down wall\n    bool can_move(int i, int j, int dir) const {\n        if(dir==0) { // Up\n            if(i==0) return false;\n            return v[i-1][j]==0;\n        }\n        if(dir==1) { // Down\n            if(i==19) return false;\n            return v[i][j]==0;\n        }\n        if(dir==2) { // Left\n            if(j==0) return false;\n            return h[i][j-1]==0;\n        }\n        if(dir==3) { // Right\n            if(j==19) return false;\n            return h[i][j]==0;\n        }\n        return false;\n    }\n};\n\nvector<int> bfs_shortest_path(const WallMap &wm, int si, int sj, int gi, int gj) {\n    vector<vector<int>> dist(20, vector<int>(20, -1));\n    vector<vector<pair<int,int>>> prev(20, vector<pair<int,int>>(20, {-1,-1}));\n    queue<pair<int,int>> q;\n    dist[si][sj] = 0;\n    q.push({si, sj});\n    while(!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int d=0; d<4; ++d) {\n            if(!wm.can_move(i, j, d)) continue;\n            int ni = i + di[d], nj = j + dj[d];\n            if(dist[ni][nj] == -1) {\n                dist[ni][nj] = dist[i][j] + 1;\n                prev[ni][nj] = {i, j};\n                q.push({ni, nj});\n            }\n        }\n    }\n    vector<int> path;\n    int ci = gi, cj = gj;\n    if (dist[ci][cj] == -1) return {};\n    while (!(ci == si && cj == sj)) {\n        auto [pi, pj] = prev[ci][cj];\n        for (int d=0; d<4; ++d) if(pi+di[d]==ci && pj+dj[d]==cj && wm.can_move(pi, pj, d)) {\n            path.push_back(d);\n            break;\n        }\n        tie(ci, cj) = make_pair(pi, pj);\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nstring path_repeat_each(const vector<int>& path, int k, int total_limit) {\n    string ret;\n    for(int d: path) for(int rpt=0;rpt<k;++rpt) {\n        if((int)ret.size()<total_limit) ret+=DC[d];\n    }\n    while((int)ret.size() + (int)path.size()*k <= total_limit) {\n        for(int d: path) for(int rpt=0;rpt<k;++rpt) {\n            if((int)ret.size()<total_limit) ret+=DC[d];\n        }\n    }\n    return ret;\n}\n\nstring path_repeat_full(const vector<int>& path, int total_limit) {\n    string ret;\n    while((int)ret.size() + (int)path.size() <= total_limit) {\n        for(int d: path) {\n            if((int)ret.size()<total_limit) ret += DC[d];\n        }\n    }\n    while((int)ret.size()<total_limit && !path.empty()) {\n        ret += DC[path.back()];\n    }\n    return ret;\n}\n\n// \"Snake\" path: interleaved DRDR if shortest path is mostly D+R\nstring path_snake(const vector<int>& path, int total_limit) {\n    // Count D/R\n    int cntD=0, cntR=0;\n    for(int d: path) if(d==1)cntD++; else if(d==3)cntR++;\n    string ret;\n    int cD=0, cR=0;\n    while((int)ret.size()<total_limit && (cD<cntD || cR<cntR)) {\n        if(cD<cntD) { ret+='D'; cD++;}\n        if((int)ret.size()>=total_limit)break;\n        if(cR<cntR) { ret+='R'; cR++;}\n    }\n    // Repeat to fill\n    while((int)ret.size()+cntD+cntR<=total_limit) {\n        int tD=0,tR=0;\n        while((tD<cntD || tR<cntR) && (int)ret.size()<total_limit) {\n            if(tD<cntD) { ret+='D'; tD++;}\n            if((int)ret.size()>=total_limit)break;\n            if(tR<cntR) { ret+='R'; tR++;}\n        }\n    }\n    // Pad\n    while((int)ret.size()<total_limit) ret+='D';\n    return ret;\n}\n\n// Adaptive greedy BFS plan: at each move, from current position, plan to goal, take first step, repeat\nstring greedy_bfs_plan(const WallMap& wm, int si, int sj, int gi, int gj, int total_limit) {\n    int i=si, j=sj;\n    string ret;\n    for(int step=0;step<total_limit;++step) {\n        if(i==gi && j==gj) break;\n        vector<vector<int>> dist(20, vector<int>(20, -1));\n        vector<vector<int>> firstdir(20, vector<int>(20, -1));\n        queue<pair<int,int>> q;\n        dist[i][j]=0;\n        q.push({i,j});\n        firstdir[i][j] = -1;\n        while(!q.empty()) {\n            auto [ci,cj] = q.front(); q.pop();\n            for(int d=0;d<4;++d) {\n                if(!wm.can_move(ci,cj,d)) continue;\n                int ni=ci+di[d], nj=cj+dj[d];\n                if(dist[ni][nj]!=-1) continue;\n                dist[ni][nj]=dist[ci][cj]+1;\n                firstdir[ni][nj] = (dist[ci][cj]==0 ? d : firstdir[ci][cj]);\n                q.push({ni,nj});\n            }\n        }\n        if(dist[gi][gj]==-1) break; // unreachable\n        int move = firstdir[gi][gj];\n        if(move==-1) break;\n        ret+=DC[move];\n        // Simulate move (assume not forgotten, for plan)\n        if(wm.can_move(i,j,move)) { i+=di[move]; j+=dj[move]; }\n    }\n    // Pad with last move for roundness\n    if(!ret.empty()) while((int)ret.size()<total_limit) ret+=ret.back();\n    return ret;\n}\n\ndouble simulate(const WallMap& wm, int si, int sj, int gi, int gj, double p, const string& route, int runs=1500) {\n    mt19937_64 rng(7171717); // fixed seed\n    uniform_real_distribution<> rd(0, 1);\n    double sum = 0;\n    for(int it=0;it<runs;++it) {\n        int i = si, j = sj, t=0;\n        bool reached = false;\n        for(t=1; t<=(int)route.size(); ++t) {\n            if(i==gi && j==gj) {reached=true; break;}\n            double coin = rd(rng);\n            if(coin < p) {\n                // Forget: do nothing\n            } else {\n                int d = -1;\n                for(int k=0;k<4;++k) if(route[t-1]==DC[k]){d=k;break;}\n                if(wm.can_move(i,j,d)) {\n                    i += di[d], j += dj[d];\n                }\n            }\n            if(i==gi && j==gj) {reached=true; break;}\n        }\n        if(i==gi && j==gj) {reached=true;}\n        if(reached) sum += (401 - t + (i==gi && j==gj ? 0 : 1));\n    }\n    return sum / runs;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n\n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n    WallMap wm;\n    for (int i=0;i<20;++i) for (int j=0;j<19;++j) {\n        char c; cin >> c;\n        wm.h[i][j] = c-'0';\n    }\n    for (int i=0;i<19;++i) for (int j=0;j<20;++j) {\n        char c; cin >> c;\n        wm.v[i][j] = c-'0';\n    }\n\n    auto spath = bfs_shortest_path(wm, si, sj, ti, tj);\n    int route_limit = 200;\n\n    vector<pair<double, string>> candidates;\n\n    // Candidate 1: Repeat full shortest path\n    string c1 = path_repeat_full(spath, route_limit);\n    candidates.emplace_back(simulate(wm, si, sj, ti, tj, p, c1, 1000), c1);\n\n    // Candidate 2: Repeat each move 2x\n    if(spath.size()*2 <= route_limit) {\n        string c2 = path_repeat_each(spath, 2, route_limit);\n        candidates.emplace_back(simulate(wm, si, sj, ti, tj, p, c2, 1000), c2);\n    }\n    // Candidate 3: Repeat each move 3x\n    if(spath.size()*3 <= route_limit) {\n        string c3 = path_repeat_each(spath, 3, route_limit);\n        candidates.emplace_back(simulate(wm, si, sj, ti, tj, p, c3, 1000), c3);\n    }\n    // Candidate 4: \"Snake path\" (DRDR), only for nearly axis-aligned path and short ones\n    int Ds = 0, Rs = 0, Ls = 0, Us = 0;\n    for(int d: spath) switch(d){case 0:Us++;break;case 1:Ds++;break;case 2:Ls++;break;case 3:Rs++;break;}\n    if((Us==0||Ds==0) && (Ls==0||Rs==0)) { // axis-aligned\n        string c4 = path_snake(spath, route_limit);\n        candidates.emplace_back(simulate(wm, si, sj, ti, tj, p, c4, 1000), c4);\n    }\n    // Candidate 5: Greedy BFS replanner\n    string c5 = greedy_bfs_plan(wm, si, sj, ti, tj, route_limit);\n    candidates.emplace_back(simulate(wm, si, sj, ti, tj, p, c5, 700), c5); // simulation heavier, use fewer runs\n\n    // Pick the best\n    auto [_, bestroute] = *max_element(candidates.begin(), candidates.end());\n    cout << bestroute << endl;\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 30;\nconst int di[4] = {0, -1, 0, 1}, dj[4] = {-1, 0, 1, 0};\nconst int to[8][4] = {\n    {1, 0, -1, -1}, {3, -1, -1, 0},\n    {-1, -1, 3, 2}, {-1, 2, 1, -1},\n    {1, 0, 3, 2}, {3, 2, 1, 0},\n    {2, -1, 0, -1}, {-1, 3, -1, 1}\n};\nint realType(int t, int r) {\n    if (t <= 3) return (t + r) % 4;\n    if (t == 4) return r % 2 == 0 ? 4 : 5;\n    if (t == 5) return r % 2 == 0 ? 5 : 4;\n    if (t == 6) return r % 2 == 0 ? 6 : 7;\n    return r % 2 == 0 ? 7 : 6;\n}\nvector<int> get_loops(const vector<vector<int>>& tile_types, const vector<vector<int>>& rotations) {\n    int st[N][N];\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++)\n        st[i][j] = realType(tile_types[i][j], rotations[i][j]);\n    bool visited[N][N][4] = {};\n    vector<int> loop_lengths;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) for (int d = 0; d < 4; d++) {\n        if (visited[i][j][d]) continue;\n        int ci = i, cj = j, cd = d, len = 0;\n        while (true) {\n            if (visited[ci][cj][cd]) break;\n            visited[ci][cj][cd] = true;\n            int nd = to[st[ci][cj]][cd];\n            if (nd == -1) break;\n            int ni = ci + di[nd], nj = cj + dj[nd];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) break;\n            cd = (nd + 2) % 4;\n            ci = ni; cj = nj; len++;\n            if (ci == i && cj == j && cd == d) {\n                loop_lengths.push_back(len);\n                break;\n            }\n        }\n    }\n    sort(loop_lengths.rbegin(), loop_lengths.rend());\n    return loop_lengths;\n}\nvector<vector<bool>> force_rect_border_loop(int L, int R, int T, int B, \n    const vector<vector<int>>& type, vector<vector<int>>& rot) {\n    vector<vector<bool>> used(N, vector<bool>(N, false));\n    vector<pair<int,int>> path;\n    if (R - L < 2 || B - T < 2) return used;\n    for (int j = L; j < R - 1; ++j) path.emplace_back(T, j);\n    for (int i = T; i < B - 1; ++i) path.emplace_back(i, R - 1);\n    for (int j = R - 1; j > L; --j) path.emplace_back(B - 1, j);\n    for (int i = B - 1; i > T; --i) path.emplace_back(i, L);\n    int pathlen = path.size();\n    for (int pos = 0; pos < pathlen; ++pos) {\n        auto [i, j] = path[pos];\n        used[i][j] = true;\n        auto [pi, pj] = path[(pos - 1 + pathlen) % pathlen];\n        int into_dir = -1;\n        if (pi == i - 1 && pj == j) into_dir = 1;\n        else if (pi == i + 1 && pj == j) into_dir = 3;\n        else if (pi == i && pj == j - 1) into_dir = 0;\n        else if (pi == i && pj == j + 1) into_dir = 2;\n        auto [ni, nj] = path[(pos + 1) % pathlen];\n        int out_dir = -1;\n        if (ni == i - 1 && nj == j) out_dir = 1;\n        else if (ni == i + 1 && nj == j) out_dir = 3;\n        else if (ni == i && nj == j - 1) out_dir = 0;\n        else if (ni == i && nj == j + 1) out_dir = 2;\n        int best_rot = -1;\n        for (int r = 0; r < 4; ++r) {\n            int nt = realType(type[i][j], r);\n            int t_out = to[nt][into_dir];\n            if (t_out == out_dir) { best_rot = r; break; }\n        }\n        if (best_rot == -1) {\n            for (int r = 0; r < 4; ++r) {\n                int nt = realType(type[i][j], r);\n                if (to[nt][into_dir] != -1 || to[nt][out_dir] != -1) {\n                    best_rot = r; break;\n                }\n            }\n        }\n        if (best_rot == -1) best_rot = 0;\n        rot[i][j] = best_rot;\n    }\n    return used;\n}\nvoid greedy_fit_rotations(\n    const vector<vector<int>>& type, \n    vector<vector<int>>& rot, \n    const vector<vector<bool>>& forced,\n    std::mt19937 &rng\n) {\n    for (int sweep = 0; sweep < 7; ++sweep) {\n        vector<pair<int, int>> order;\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                if (!forced[i][j]) order.emplace_back(i, j);\n        shuffle(order.begin(), order.end(), rng);\n        for (auto [i, j] : order) {\n            int best = -1, bestr = 0;\n            for (int r = 0; r < 4; ++r) {\n                int nt = realType(type[i][j], r), connect = 0;\n                for (int d = 0; d < 4; ++d) {\n                    int nd = to[nt][d];\n                    if (nd == -1) continue;\n                    int ni = i + di[nd], nj = j + dj[nd];\n                    if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                    int backdir = (nd + 2) % 4;\n                    int neighbor_type = type[ni][nj], neighbor_rot = rot[ni][nj];\n                    int neighbor_real = realType(neighbor_type, neighbor_rot);\n                    if (to[neighbor_real][backdir] != -1) connect++;\n                }\n                int tiebreak = rng();\n                if (connect > best || (connect == best && tiebreak & 1)) { best = connect; bestr = r; }\n            }\n            rot[i][j] = bestr;\n        }\n    }\n}\nvoid local_hillclimb(vector<vector<int>>& rot, const vector<vector<int>>& type, int steps = 5) {\n    auto score_func = [&](const vector<vector<int>>& rot) -> int {\n        auto loops = get_loops(type, rot);\n        if (loops.size() < 2) return 0;\n        return loops[0] * loops[1];\n    };\n    int cur_score = score_func(rot);\n    for (int sweep = 0; sweep < steps; ++sweep) {\n        bool improved = false;\n        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) {\n            int bestr = rot[i][j], bestscore = cur_score;\n            for (int r = 0; r < 4; ++r) {\n                if (r == rot[i][j]) continue;\n                int old = rot[i][j];\n                rot[i][j] = r;\n                int s = score_func(rot);\n                if (s > bestscore) {\n                    bestscore = s;\n                    bestr = r;\n                }\n                rot[i][j] = old;\n            }\n            if (bestr != rot[i][j]) {\n                rot[i][j] = bestr;\n                cur_score = bestscore;\n                improved = true;\n            }\n        }\n        if (!improved) break;\n    }\n}\nvector<vector<int>> try_partitioned_loops_full(const vector<vector<int>>& type, std::mt19937 &rng) {\n    vector<vector<int>> rot_best(N, vector<int>(N, 0));\n    int best_score = 0;\n    auto try_and_eval = [&](auto init_partition) {\n        vector<vector<int>> rot(N, vector<int>(N, 0));\n        vector<vector<bool>> forced(N, vector<bool>(N, 0));\n        init_partition(type, rot, forced);\n        greedy_fit_rotations(type, rot, forced, rng);\n        local_hillclimb(rot, type, 5);\n        auto loops = get_loops(type, rot);\n        int score = (loops.size() >= 2 ? loops[0] * loops[1] : 0);\n        if (score > best_score) {\n            best_score = score;\n            rot_best = rot;\n        }\n    };\n    try_and_eval([](const auto&type, auto&rot, auto&forced){\n        auto left_forced = force_rect_border_loop(0, N/2, 0, N, type, rot);\n        auto right_forced = force_rect_border_loop(N/2, N, 0, N, type, rot);\n        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j)\n            forced[i][j] = left_forced[i][j] || right_forced[i][j];\n    });\n    try_and_eval([](const auto&type, auto&rot, auto&forced){\n        auto top_forced = force_rect_border_loop(0, N, 0, N/2, type, rot);\n        auto bottom_forced = force_rect_border_loop(0, N, N/2, N, type, rot);\n        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j)\n            forced[i][j] = top_forced[i][j] || bottom_forced[i][j];\n    });\n    try_and_eval([](const auto&type, auto&rot, auto&forced){\n        auto outer_forced = force_rect_border_loop(0, N, 0, N, type, rot);\n        auto in1_forced = force_rect_border_loop(2, N-2, 2, N-2, type, rot);\n        auto in3_forced = force_rect_border_loop(4, N-4, 4, N-4, type, rot);\n        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j)\n            forced[i][j] = outer_forced[i][j] || in1_forced[i][j] || in3_forced[i][j];\n    });\n    try_and_eval([](const auto&type, auto&rot, auto&forced){\n        auto frame1 = force_rect_border_loop(1, N-1, 1, N-1, type, rot);\n        auto frame3 = force_rect_border_loop(3, N-3, 3, N-3, type, rot);\n        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j)\n            forced[i][j] = frame1[i][j] || frame3[i][j];\n    });\n    try_and_eval([](const auto&type, auto&rot, auto&forced){\n        auto outer_forced = force_rect_border_loop(0, N, 0, N, type, rot);\n        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j)\n            forced[i][j] = outer_forced[i][j];\n    });\n    {\n        vector<vector<int>> rot(N, vector<int>(N, 0));\n        vector<vector<bool>> forced(N, vector<bool>(N, 0));\n        greedy_fit_rotations(type, rot, forced, rng);\n        local_hillclimb(rot, type, 5);\n        auto loops = get_loops(type, rot);\n        int score = (loops.size() >= 2 ? loops[0] * loops[1] : 0);\n        if (score > best_score) {\n            best_score = score;\n            rot_best = rot;\n        }\n    }\n    return rot_best;\n}\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    using clk = chrono::steady_clock;\n    auto T0 = clk::now();\n    auto nowsec = [&](){ return chrono::duration<double>(clk::now()-T0).count(); };\n    vector<vector<int>> type(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        string s; cin >> s;\n        for (int j = 0; j < N; j++)\n            type[i][j] = s[j] - '0';\n    }\n    std::random_device dev;\n    std::mt19937 rng(dev());\n    int best_score = 0;\n    vector<vector<int>> best_rot;\n    int nruns = 2;\n    double tmax = 1.8;\n    for (int trial = 0; trial < nruns; ++trial) {\n        if (trial > 0) rng.seed(dev());\n        auto rot = try_partitioned_loops_full(type, rng);\n        auto loops = get_loops(type, rot);\n        int score = (loops.size() >= 2 ? loops[0] * loops[1] : 0);\n        if (score > best_score) {\n            best_score = score;\n            best_rot = rot;\n        }\n        if (nowsec() > tmax) break;\n    }\n    string out;\n    out.reserve(N*N);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            out += char('0' + best_rot[i][j]);\n    cout << out << endl;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nusing pii = pair<int,int>;\n\nchrono::high_resolution_clock::time_point time_start;\ndouble elapsed_sec() {\n    auto t = chrono::high_resolution_clock::now();\n    return chrono::duration<double>(t - time_start).count();\n}\n\n// Directions: UDLR\nconst int dr[] = {-1, 1, 0, 0};\nconst int dc[] = {0, 0, -1, 1};\nconst char dir_char[] = {'U','D','L','R'};\nconst int opp_dir[] = {1,0,3,2};\nconst int bit[] = {1<<1,1<<3,1<<0,1<<2}; // up,down,left,right\n\nstruct Board {\n    int N;\n    vector<vector<int>> grid;\n    pii empty; // (r,c) position of the empty cell\n\n    Board(int N_): N(N_), grid(N, vector<int>(N)) {}\n    Board(const Board &o): N(o.N), grid(o.grid), empty(o.empty) {}\n\n    void read_input() {\n        for(int i=0; i<N; ++i) {\n            string s; cin >> s;\n            for(int j=0; j<N; ++j) {\n                char ch = s[j];\n                if(ch=='0') {\n                    grid[i][j]=0;\n                    empty = {i,j};\n                } else if(isdigit(ch)) {\n                    grid[i][j] = ch-'0';\n                } else {\n                    grid[i][j] = ch-'a'+10;\n                }\n            }\n        }\n    }\n\n    // Can we move in dir d (U/D/L/R)?\n    bool can_move(int d) const {\n        int er = empty.first, ec = empty.second;\n        int nr = er + dr[d], nc = ec + dc[d];\n        return nr>=0 && nr<N && nc>=0 && nc<N;\n    }\n\n    // Do the move in dir d. Assumes move is legal.\n    void do_move(int d) {\n        int er = empty.first, ec = empty.second;\n        int nr = er + dr[d], nc = ec + dc[d];\n        swap(grid[er][ec], grid[nr][nc]);\n        empty = {nr, nc};\n    }\n\n    // For performance, do undo_move doesn't need to be tracked if not required yet.\n};\n\nstruct DSU {\n    vector<int> par, siz;\n    DSU(int n): par(n), siz(n,1) { iota(par.begin(), par.end(), 0); }\n    int find(int x) { return par[x]==x ? x : par[x]=find(par[x]); }\n    bool unite(int x,int y) {\n        x = find(x); y = find(y);\n        if(x==y) return false;\n        if(siz[x]<siz[y]) swap(x,y);\n        par[y]=x; siz[x]+=siz[y];\n        return true;\n    }\n    int size(int x) { return siz[find(x)]; }\n};\n\nstruct TreeChecker {\n    // Build a graph of non-empty tiles, with edges as problem states,\n    // Then find the largest connected component which is also acyclic\n\n    int N;\n    vector<vector<int>> grid;\n    vector<vector<int>> idmap; // for mapping (i,j) to node ids, since one cell is empty\n\n    TreeChecker(const vector<vector<int>> &g): N(g.size()), grid(g) {\n        // Build idmap: -1 for empty, else unique 0...(N*N-2)\n        idmap.assign(N, vector<int>(N,-1));\n        int id=0;\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++) {\n            if(grid[i][j]!=0) idmap[i][j]=id++;\n        }\n    }\n\n    // Returns (largest tree size)\n    int get_largest_tree_size() {\n        int nn = N*N-1;\n        vector<vector<int>> G(nn);\n        // Build undirected edge list\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++) {\n            if(grid[i][j]==0) continue;\n            int t = grid[i][j];\n            int id1 = idmap[i][j];\n            // down\n            if((t&8) && i+1<N && grid[i+1][j]!=0 && (grid[i+1][j]&2))\n                G[id1].push_back(idmap[i+1][j]);\n            // right\n            if((t&4) && j+1<N && grid[i][j+1]!=0 && (grid[i][j+1]&1))\n                G[id1].push_back(idmap[i][j+1]);\n            // (U/L can reverse edge but already covered)\n        }\n        // Find largest connected acyclic component: for each CC, check if no cycles (tree), report largest\n        int res=0;\n        vector<int> vis(nn,0);\n        for(int i=0;i<nn;i++) {\n            if(vis[i]) continue;\n            int size=0, edges=0;\n            bool is_tree=true;\n            function<void(int,int)> dfs=[&](int u, int p){\n                vis[u]=1; size++;\n                for(int v:G[u]) {\n                    if(v==p) continue;\n                    edges++;\n                    if(vis[v]) is_tree=false;\n                    else dfs(v, u);\n                }\n            };\n            dfs(i,-1);\n            if(is_tree && edges/2==size-1) res=max(res,size); // undirected: edges double-counted\n        }\n        return res;\n    }\n};\n\nint main() {\n    time_start = chrono::high_resolution_clock::now();\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T;\n    cin >> N >> T;\n    Board board(N);\n    board.read_input();\n\n    // Naive strategy: try random walks and keep the best\n    string best_moves;\n    int best_score = 0;\n    Board best_board = board;\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    int try_limit = 1500;   // Control based on validated time!\n    int walk_len = min(T, 200); // Try short walks first, might help\n\n    for(int t=0; t<try_limit; ++t) {\n        Board cur_board = board;\n        vector<int> move_hist;\n        string moves = \"\";\n        int prev_move = -1;\n        for(int k=0; k<walk_len; ++k) {\n            // Random legal move, avoid undoing previous\n            vector<int> can_moves;\n            for(int d=0; d<4; ++d) {\n                if( d != opp_dir[prev_move] && cur_board.can_move(d))\n                    can_moves.push_back(d);\n            }\n            if(can_moves.empty()) break;\n            int mv = can_moves[ rng() % can_moves.size() ];\n            cur_board.do_move(mv);\n            moves += dir_char[mv];\n            prev_move = mv;\n        }\n        // Compute score\n        TreeChecker tc(cur_board.grid);\n        int S = tc.get_largest_tree_size();\n        if(S>best_score || (S==best_score && (int)moves.size()<best_moves.size())) {\n            best_score = S;\n            best_moves = moves;\n            best_board = cur_board;\n        }\n        // Time management (1.8sec safety)\n        if(elapsed_sec() > 1.8) break;\n    }\n\n    // Output\n    cout << best_moves << \"\\n\";\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing P = pair<int, int>;\nusing ll = long long;\nconst double PI = acos(-1.0);\nconst int CAKE_RADIUS = 10000;\nconst int K = 100;\n\nstruct Strawberry {\n    int x, y;\n    int idx; // original id\n};\n\nstruct Line {\n    // Represent by ax + by + c = 0\n    // Or two points (px, py), (qx, qy)\n    int px, py, qx, qy;\n};\n\nstruct Piece {\n    vector<int> strawberry_idxs;\n};\n\nint N, K_input;\nvector<int> a; // a[1..10]\nvector<Strawberry> strawberries;\nvector<Line> cuts;\n\n// For bipartition: Given indices of strawberries, try to partition into sizes d and n-d\n// Return (success, (indices in side A, indices in side B), Line to cut by)\ntuple<bool, vector<int>, vector<int>, Line>\nbipartition(const vector<int>& idxs, int d, const vector<Strawberry>& strawbs, mt19937 &rng) {\n    int n = idxs.size();\n    if (n < d || d == 0 || d == n) return {false, {}, {}, {}};\n    vector<pair<double,int>> project(n); // (projection, index in idxs)\n    vector<double> directions;\n    const int tries = 20;\n    uniform_real_distribution<double> angle_dist(0, PI);\n    for(int attempt = 0; attempt < tries; ++attempt) {\n        double ang = angle_dist(rng);\n        double dx = cos(ang), dy = sin(ang);\n        for(int i = 0; i < n; ++i) {\n            const auto &s = strawbs[idxs[i]];\n            project[i] = {s.x*dx + s.y*dy, i};\n        }\n        sort(project.begin(), project.end());\n        // Try split after d-1 points (left: [0,d-1], right: [d,n-1])\n        double cut_left = project[d-1].first;\n        double cut_right = project[d].first;\n        double cut_proj = (cut_left + cut_right) / 2.0; // split position at midpoint\n        // Find two points on this line\n        // For simplicity, pick a point within cake in direction orthogonal to (dx,dy)\n        // e.g., normal vector (-dy, dx)\n        double nx = -dy, ny = dx;\n        // Pick p0 at (0,0) + cake_radius * (nx, ny)\n        double p0x = nx * CAKE_RADIUS, p0y = ny * CAKE_RADIUS;\n        double p1x = -nx * CAKE_RADIUS, p1y = -ny * CAKE_RADIUS;\n        // Shift line along (dx,dy) by cut_proj units: move origin along (dx,dy)\n        p0x += dx * cut_proj;\n        p0y += dy * cut_proj;\n        p1x += dx * cut_proj;\n        p1y += dy * cut_proj;\n        // Round to integer points in [-1e9,1e9]\n        auto clamp = [](double v) -> int64_t {\n            const ll M = 1000000000LL;\n            if (v > M) return M;\n            if (v < -M) return -M;\n            return static_cast<ll>(round(v));\n        };\n        ll px = clamp(p0x), py = clamp(p0y), qx = clamp(p1x), qy = clamp(p1y);\n\n        // Now assign to sides: those with projection < cut_proj on one side, others on other\n        vector<int> A, B;\n        for(int i = 0; i < n; ++i) {\n            int sidx = idxs[project[i].second];\n            if (project[i].first < cut_proj) A.push_back(sidx);\n            else if (project[i].first > cut_proj) B.push_back(sidx);\n            else {\n                // projection == cut_proj:\n                // Looks like a double point, but in practice, can assign to either cake side\n                // Just assign to B for safety (as cut_proj is mid of two projections)\n                B.push_back(sidx);\n            }\n        }\n        // If any strawberry happens to be exactly ON the line, abort this cut\n        // Check for each strawberry:\n        double eps = 1e-8;\n        bool on_cut = false;\n        for(int i = 0; i < n; ++i) {\n            if (abs(project[i].first - cut_proj) < eps) {\n                // A strawberry would be lost; try a new direction\n                on_cut = true;\n                break;\n            }\n        }\n        if (on_cut) continue;\n        // Now, can get exact d in A or B depending on ordering:\n        if (A.size() == d || B.size() == d) {\n            if (A.size() == d) {\n                return {true, A, B, Line{(int)px, (int)py, (int)qx, (int)qy}};\n            } else {\n                return {true, B, A, Line{(int)px, (int)py, (int)qx, (int)qy}};\n            }\n        }\n    }\n    // no suitable split found\n    return {false, {}, {}, {}};\n}\n\nint main(){\n    ios::sync_with_stdio(false); cin.tie(0);\n    cin >> N >> K_input;\n    a.resize(11);\n    int Ncheck = 0;\n    for(int d=1;d<=10; ++d) {\n        cin >> a[d];\n        Ncheck += d * a[d];\n    }\n    strawberries.resize(N);\n    for(int i=0;i<N;++i){\n        int x, y; cin >> x >> y;\n        strawberries[i] = {x, y, i};\n    }\n    // Bookkeeping for pieces:\n    vector<vector<int>> pieces; // each as vector of strawberry indices\n    pieces.push_back(vector<int>(N));\n    iota(pieces[0].begin(), pieces[0].end(), 0);\n\n    // For each d from 10 downto 1 (focus on large pieces first)\n    // Alternatively, weighted by number required; for now, 10..1\n    int remains[11];\n    for(int d=1;d<=10;++d) remains[d]=a[d];\n\n    mt19937 rng(123456 + chrono::steady_clock::now().time_since_epoch().count());\n\n    // For cuts\n    vector<Line> used_cuts;\n\n    // For pieces: maintain multiset by size (for quickly finding suitable ones)\n    // Actually, not necessary for up to 1000 pieces\n\n    // Map: pieces_to_process[d]: indices of pieces of size >= d, and not yet processed\n    // We'll go for greedy: for d from 10..1, try to split pieces down\n    // For now, do as explained: try to generate as many pieces of size d as a[d]\n    for(int d=10; d>=1; --d) {\n        int need = remains[d];\n        if(need == 0) continue;\n        // Look for pieces with size >= d\n        // For each round:\n        bool found;\n        int attempts = 0;\n        while(need > 0) {\n            found = false;\n            for(int pi=0; pi<pieces.size(); ++pi) {\n                vector<int> &piece = pieces[pi];\n                if ((int)piece.size() > d) {\n                    // Try bipartition this piece into d and n-d\n                    auto [ok, groupA, groupB, line] = bipartition(piece, d, strawberries, rng);\n                    if(ok) {\n                        // Accept this cut, add it to cuts\n                        used_cuts.push_back(line);\n                        // Remove piece, add groupA, groupB instead\n                        piece = move(groupA);\n                        pieces.push_back(move(groupB));\n                        // Mark found\n                        found = true;\n                        --need;\n                        break; // do next need\n                    }\n                }\n            }\n            if(!found) break; // Could not perform more for this d\n            if((int)used_cuts.size() >= K) break;\n            ++attempts;\n            if(attempts > 1000) break; // Give up (should not be needed)\n        }\n        if((int)used_cuts.size() >= K) break;\n    }\n\n    // Now, after all splits, count how many pieces of each size, up to a[d] per attendee\n    vector<int> cnt(11, 0);\n    for(const auto &piece: pieces) {\n        int sz = piece.size();\n        if(sz >= 1 && sz <= 10) cnt[sz]++;\n    }\n    int total_given = 0;\n    for(int d=1;d<=10;++d) total_given += min(a[d], cnt[d]);\n    // Output cuts\n    int k_out = used_cuts.size();\n    cout << k_out << \"\\n\";\n    for(const auto &line : used_cuts) {\n        cout << line.px << \" \" << line.py << \" \" << line.qx << \" \" << line.qy << \"\\n\";\n    }\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nusing pii = pair<int,int>;\n\nstruct Edge {\n    int x1, y1, x2, y2;\n    Edge(int a, int b, int c, int d) {\n        if (pii(a,b) < pii(c,d)) {\n            x1 = a; y1 = b; x2 = c; y2 = d;\n        } else {\n            x1 = c; y1 = d; x2 = a; y2 = b;\n        }\n    }\n    bool operator < (const Edge& o) const {\n        return tie(x1, y1, x2, y2) < tie(o.x1, o.y1, o.x2, o.y2);\n    }\n};\n\nint N, M;\nvector<vector<int>> board;\nset<pii> dots;\nset<Edge> used_edges;\nset<pii> frontier;\nvector<vector<ll>> weights;\nll S = 0;\nint CENTER;\nvector<array<int,8>> moves;\n\nbool is_valid(int x, int y) {\n    return 0 <= x && x < N && 0 <= y && y < N;\n}\n\nll quad_area(const vector<pii>& p) {\n    ll a = 0;\n    for (int i = 0; i < 4; ++i) {\n        a += 1LL * p[i].first * p[(i+1)%4].second;\n        a -= 1LL * p[i].second * p[(i+1)%4].first;\n    }\n    return abs(a);\n}\n\nvoid mark_frontier(int x, int y) {\n    static const int dx[4] = {1,-1,0,0}, dy[4]={0,0,1,-1};\n    if (!dots.count({x,y})) return;\n    for (int dir=0;dir<4;++dir) {\n        int nx=x+dx[dir], ny=y+dy[dir];\n        if (is_valid(nx,ny) && !dots.count({nx,ny})) {\n            frontier.insert({x,y});\n            return;\n        }\n    }\n    frontier.erase({x,y});\n}\n\nvoid input() {\n    cin >> N >> M;\n    board.assign(N, vector<int>(N, 0));\n    dots.clear();\n    frontier.clear();\n    for (int i = 0; i < M; ++i) {\n        int x, y;\n        cin >> x >> y;\n        board[x][y] = 2;\n        dots.emplace(x, y);\n    }\n    CENTER = (N-1)/2;\n    weights.assign(N, vector<ll>(N, 0));\n    S = 0;\n    for (int x=0;x<N;++x) for (int y=0;y<N;++y) {\n        weights[x][y] = (x-CENTER)*(x-CENTER) + (y-CENTER)*(y-CENTER) + 1;\n        S += weights[x][y];\n    }\n    for (auto &[x,y] : dots) mark_frontier(x,y);\n}\n\nbool check_valid_dots(const array<int,8>& mv) {\n    return \n        is_valid(mv[2], mv[3]) && board[mv[2]][mv[3]] > 0 &&\n        is_valid(mv[4], mv[5]) && board[mv[4]][mv[5]] > 0 &&\n        is_valid(mv[6], mv[7]) && board[mv[6]][mv[7]] > 0;\n}\n\nbool find_one_move(array<int,8> &out, chrono::time_point<chrono::steady_clock> time_limit) {\n    vector<pii> dot_list(dots.begin(), dots.end());\n    static mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n    vector<int> dot_idx(dot_list.size());\n    iota(dot_idx.begin(), dot_idx.end(), 0);\n    shuffle(dot_idx.begin(), dot_idx.end(), rng);\n\n    // Try up to MAX_TRIALS, skip if too long or out of time\n    const int MAX_TRIALS = 12000;\n    int trial = 0;\n\n    while (trial < MAX_TRIALS) {\n        ++trial;\n        if (trial % 30 == 0 &&\n            chrono::steady_clock::now() > time_limit) return false;\n        int sz = dot_list.size();\n        // Axis\n        int i = dot_idx[rng()%sz];\n        int j = dot_idx[rng()%sz];\n        if (i == j) continue;\n        auto [x1, y1] = dot_list[i];\n        auto [x2, y2] = dot_list[j];\n        if (!frontier.count({x1, y1})) continue;\n        if (x1 != x2 && y1 != y2) {\n            vector<pii> pts = {{x1, y1}, {x1, y2}, {x2, y2}, {x2, y1}};\n            set<pii> uniq(pts.begin(), pts.end());\n            if ((int)uniq.size() != 4) continue;\n            int dot_cnt=0, empty_cnt=0, empty_idx=-1;\n            for (int k=0;k<4;++k) {\n                if (dots.count(pts[k])) ++dot_cnt;\n                else { ++empty_cnt; empty_idx=k; }\n            }\n            if (!(dot_cnt==3 && empty_cnt==1)) continue;\n            int x_new=pts[empty_idx].first, y_new=pts[empty_idx].second;\n            if (!is_valid(x_new, y_new) || board[x_new][y_new]!=0) continue;\n            if (quad_area(pts)==0) continue;\n\n            array<int,8> move;\n            move[0]=x_new; move[1]=y_new;\n            for (int off=1, idx=(empty_idx+1)%4; off<=3; ++off, idx=(idx+1)%4) {\n                move[2*off]=pts[idx].first;\n                move[2*off+1]=pts[idx].second;\n            }\n            if (!check_valid_dots(move)) continue;\n            bool ok = true;\n            for (int k=0;k<4;++k) {\n                auto [xa, ya]=pts[k];\n                auto [xb, yb]=pts[(k+1)%4];\n                int ddx=xb-xa, ddy=yb-ya;\n                int steps=max(abs(ddx),abs(ddy));\n                int sdx=steps==0?0:ddx/steps, sdy=steps==0?0:ddy/steps;\n                for (int t=1;t<steps;++t) {\n                    int xm=xa+sdx*t, ym=ya+sdy*t;\n                    if (!is_valid(xm,ym)) {ok=false; break;}\n                    if (dots.count({xm,ym})) {ok=false; break;}\n                }\n                for (int t=0;t<steps;++t) {\n                    int xm1=xa + sdx*t, ym1=ya + sdy*t;\n                    int xm2=xa + sdx*(t+1), ym2=ya + sdy*(t+1);\n                    Edge e_seg(xm1, ym1, xm2, ym2);\n                    if (used_edges.count(e_seg)) { ok = false; break; }\n                }\n                if(!ok) break;\n            }\n            if (!ok) continue;\n            out = move;\n            return true;\n        } else if (x1 != x2 || y1 != y2) {\n            // Diagonal\n            int dx = x2 - x1, dy = y2 - y1;\n            if (dx == 0 || dy == 0) continue;\n            if (abs(dx) != abs(dy) || abs(dx) > 6) continue;\n            int x3 = x2 - dy, y3 = y2 + dx;\n            int x4 = x1 - dy, y4 = y1 + dx;\n            vector<pii> pts = {{x1,y1},{x2,y2},{x3,y3},{x4,y4}};\n            set<pii> uniq(pts.begin(), pts.end());\n            if ((int)uniq.size()!=4) continue;\n            bool bounds=true;\n            for (int k=0;k<4;++k) if (!is_valid(pts[k].first, pts[k].second)) bounds=false;\n            if (!bounds) continue;\n            int dot_cnt=0, empty_cnt=0, empty_idx=-1;\n            for (int k=0;k<4;++k) {\n                if (dots.count(pts[k])) ++dot_cnt;\n                else { ++empty_cnt; empty_idx=k; }\n            }\n            if (!(dot_cnt==3 && empty_cnt==1)) continue;\n            int x_new=pts[empty_idx].first, y_new=pts[empty_idx].second;\n            if (board[x_new][y_new]!=0) continue;\n            if (quad_area(pts)==0) continue;\n            array<int,8> move;\n            move[0]=x_new; move[1]=y_new;\n            for (int off=1, idx=(empty_idx+1)%4; off<=3; ++off, idx=(idx+1)%4) {\n                move[2*off]=pts[idx].first;\n                move[2*off+1]=pts[idx].second;\n            }\n            if (!check_valid_dots(move)) continue;\n            bool ok = true;\n            for (int k=0;k<4;++k) {\n                auto [xa, ya]=pts[k];\n                auto [xb, yb]=pts[(k+1)%4];\n                int ddx=xb-xa, ddy=yb-ya;\n                int steps=max(abs(ddx),abs(ddy));\n                int sdx=steps==0?0:ddx/steps, sdy=steps==0?0:ddy/steps;\n                for (int t=1;t<steps;++t) {\n                    int xm=xa+sdx*t, ym=ya+sdy*t;\n                    if (!is_valid(xm,ym)) {ok=false; break;}\n                    if (dots.count({xm,ym})) {ok=false; break;}\n                }\n                for (int t=0;t<steps;++t) {\n                    int xm1=xa + sdx*t, ym1=ya + sdy*t;\n                    int xm2=xa + sdx*(t+1), ym2=ya + sdy*(t+1);\n                    Edge e_seg(xm1, ym1, xm2, ym2);\n                    if (used_edges.count(e_seg)) { ok = false; break; }\n                }\n                if(!ok) break;\n            }\n            if (!ok) continue;\n            out = move;\n            return true;\n        }\n    }\n    return false;\n}\n\nvoid make_move(const array<int,8>& mv) {\n    int x1=mv[0], y1=mv[1];\n    int x2=mv[2], y2=mv[3];\n    int x3=mv[4], y3=mv[5];\n    int x4=mv[6], y4=mv[7];\n    assert(board[x2][y2] > 0);\n    assert(board[x3][y3] > 0);\n    assert(board[x4][y4] > 0);\n    board[x1][y1] = 1;\n    dots.emplace(x1, y1);\n    mark_frontier(x1, y1);\n    vector<pii> pts = {pii(x1,y1), pii(x2,y2), pii(x3,y3), pii(x4,y4)};\n    for (int k=1; k<=3; ++k) mark_frontier(mv[k*2], mv[k*2+1]);\n    for (int i=0; i<4; ++i) {\n        auto [xa, ya] = pts[i];\n        auto [xb, yb] = pts[(i+1)%4];\n        int ddx=xb-xa, ddy=yb-ya;\n        int steps=max(abs(ddx),abs(ddy));\n        int sdx=steps==0?0:ddx/steps, sdy=steps==0?0:ddy/steps;\n        for (int t=0;t<steps;++t) {\n            int xm1=xa + sdx*t, ym1=ya + sdy*t;\n            int xm2=xa + sdx*(t+1), ym2=ya + sdy*(t+1);\n            Edge e_seg(xm1, ym1, xm2, ym2);\n            used_edges.insert(e_seg);\n        }\n    }\n    moves.push_back(mv);\n}\n\nvoid solve() {\n    auto tstart = chrono::steady_clock::now();\n    auto time_limit = tstart + chrono::milliseconds(4800); // 4.8s\n    int move_count = 0;\n    while (true) {\n        array<int,8> mv;\n        if (!find_one_move(mv, time_limit)) break;\n        make_move(mv);\n        if ((++move_count)%30==0) {\n            if (chrono::steady_clock::now() > time_limit) break;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    input();\n    solve();\n    cout << moves.size() << \"\\n\";\n    for (const auto& mv : moves) {\n        assert(board[mv[2]][mv[3]] > 0 && board[mv[4]][mv[5]] > 0 && board[mv[6]][mv[7]] > 0); // Safety!\n        for (int i=0;i<8;++i) cout << mv[i] << \" \";\n        cout << \"\\n\";\n    }\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <array>\n#include <algorithm>\n#include <queue>\n#include <cassert>\n\nusing namespace std;\n\nconstexpr int N = 10;\nusing Board = array<array<int, N>, N>;\nusing Pos = pair<int, int>;\n\nvoid flush() { cout << flush; }\n\nvoid move_board(Board& board, char dir) {\n    if (dir == 'F') {\n        for (int x = 0; x < N; x++) {\n            int write = 0;\n            for (int y = 0; y < N; y++) {\n                if (board[y][x] != 0) {\n                    if (write != y) {\n                        board[write][x] = board[y][x];\n                        board[y][x] = 0;\n                    }\n                    write++;\n                }\n            }\n        }\n    } else if (dir == 'B') {\n        for (int x = 0; x < N; x++) {\n            int write = N - 1;\n            for (int y = N - 1; y >= 0; --y) {\n                if (board[y][x] != 0) {\n                    if (write != y) {\n                        board[write][x] = board[y][x];\n                        board[y][x] = 0;\n                    }\n                    write--;\n                }\n            }\n        }\n    } else if (dir == 'L') {\n        for (int y = 0; y < N; y++) {\n            int write = 0;\n            for (int x = 0; x < N; x++) {\n                if (board[y][x] != 0) {\n                    if (write != x) {\n                        board[y][write] = board[y][x];\n                        board[y][x] = 0;\n                    }\n                    write++;\n                }\n            }\n        }\n    } else if (dir == 'R') {\n        for (int y = 0; y < N; y++) {\n            int write = N - 1;\n            for (int x = N - 1; x >= 0; --x) {\n                if (board[y][x] != 0) {\n                    if (write != x) {\n                        board[y][write] = board[y][x];\n                        board[y][x] = 0;\n                    }\n                    write--;\n                }\n            }\n        }\n    }\n}\n\nvector<array<int, 2>> get_empty_cells(const Board& board) {\n    vector<array<int, 2>> res;\n    for (int y = 0; y < N; ++y)\n        for (int x = 0; x < N; ++x)\n            if (board[y][x] == 0)\n                res.push_back({y, x});\n    return res;\n}\n\nPos get_index_from_pt(const vector<array<int, 2>>& empties, int p_t) {\n    assert(p_t >= 1 && p_t <= (int)empties.size());\n    return { empties[p_t - 1][0], empties[p_t - 1][1] };\n}\n\nconstexpr int dy[4] = { 1, -1, 0, 0 };\nconstexpr int dx[4] = { 0, 0, 1, -1 };\n\nstruct ClusterResult {\n    int total_sum_sq;\n    int curr_flavor_sum_sq;\n    int largest_curr_flavor_cluster;\n};\n\nClusterResult analyze_clusters(const Board& board, int flavor) {\n    array<array<bool, N>, N> visited{};\n    int total_score = 0;\n    int curr_flavor_score = 0;\n    int largest_curr_flavor_cluster = 0;\n    for (int y = 0; y < N; y++) for (int x = 0; x < N; x++) {\n        if (board[y][x] != 0 && !visited[y][x]) {\n            int f = board[y][x];\n            int sz = 0;\n            queue<pair<int, int>> q;\n            q.push({ y, x });\n            visited[y][x] = true;\n            while (!q.empty()) {\n                auto [cy, cx] = q.front(); q.pop();\n                sz++;\n                for (int d = 0; d < 4; d++) {\n                    int ny = cy + dy[d], nx = cx + dx[d];\n                    if (ny >= 0 && ny < N && nx >= 0 && nx < N) {\n                        if (!visited[ny][nx] && board[ny][nx] == f) {\n                            visited[ny][nx] = true;\n                            q.push({ ny, nx });\n                        }\n                    }\n                }\n            }\n            total_score += sz * sz;\n            if (f == flavor) {\n                curr_flavor_score += sz * sz;\n                if (sz > largest_curr_flavor_cluster)\n                    largest_curr_flavor_cluster = sz;\n            }\n        }\n    }\n    return ClusterResult{ total_score, curr_flavor_score, largest_curr_flavor_cluster };\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<int> flavors(100);\n    for (int i = 0; i < 100; ++i) cin >> flavors[i];\n\n    Board board{};\n\n    const array<char, 4> all_dirs = { 'F','B','L','R' };\n\n    for (int step = 0; step < 100; ++step) {\n        int p_t;\n        cin >> p_t;\n        vector<array<int, 2>> empties = get_empty_cells(board);\n        Pos pos = get_index_from_pt(empties, p_t);\n        int flavor = flavors[step];\n        board[pos.first][pos.second] = flavor;\n\n        // Try all moves, pick the best per heuristic\n        int best_total = -1;\n        int best_flav_sum = -1;\n        int best_flav_cluster = -1;\n        char chosen_dir = 'F'; // default\n        for (char dir : all_dirs) {\n            Board temp = board;\n            move_board(temp, dir);\n            ClusterResult cl = analyze_clusters(temp, flavor);\n\n            if (cl.total_sum_sq > best_total ||\n               (cl.total_sum_sq == best_total && cl.curr_flavor_sum_sq > best_flav_sum) ||\n               (cl.total_sum_sq == best_total && cl.curr_flavor_sum_sq == best_flav_sum && cl.largest_curr_flavor_cluster > best_flav_cluster)\n            ) {\n                best_total = cl.total_sum_sq;\n                best_flav_sum = cl.curr_flavor_sum_sq;\n                best_flav_cluster = cl.largest_curr_flavor_cluster;\n                chosen_dir = dir;\n            }\n        }\n        move_board(board, chosen_dir);\n\n        if (step != 99) {\n            cout << chosen_dir << '\\n';\n            flush();\n        }\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\n#include <Eigen/Dense>\nusing namespace std;\nusing namespace Eigen;\n\nconst int MAX_N = 100;\nconst int EIGEN_CNT = 10; // Number of eigenvalues to keep\n\n// Helper: string edge list to Eigen adjacency\nvoid string_to_matrix(const string &s, int N, MatrixXd &adj) {\n    adj = MatrixXd::Zero(N, N);\n    int idx = 0;\n    for(int i=0;i<N;i++)for(int j=i+1;j<N;j++) {\n        if(s[idx++]=='1') {\n            adj(i,j) = adj(j,i) = 1.0;\n        }\n    }\n}\n\n// Get sorted degree sequence\nvector<int> get_degseq(const string &s, int N) {\n    vector<int> deg(N, 0);\n    int idx = 0;\n    for(int i=0;i<N;++i) for(int j=i+1;j<N;++j,++idx) {\n        if(s[idx]=='1') {\n            deg[i]++; deg[j]++;\n        }\n    }\n    sort(deg.begin(), deg.end());\n    return deg;\n}\n\n// Get quantized eigenvalues (largest positive & lowest negative EIGEN_CNT/2 each)\nvector<double> get_eigen(const string &s, int N) {\n    MatrixXd adj(N, N);\n    string_to_matrix(s, N, adj);\n    SelfAdjointEigenSolver<MatrixXd> sol(adj);\n    vector<double> eigs(N);\n    for(int i=0;i<N;++i) eigs[i] = sol.eigenvalues()(i);\n    sort(eigs.begin(), eigs.end());\n    // Take lower EIGEN_CNT/2 and upper EIGEN_CNT/2\n    int K = EIGEN_CNT/2;\n    vector<double> v;\n    for(int i=0;i<K;++i) v.push_back(eigs[i]);\n    for(int i=N-K;i<N;++i) v.push_back(eigs[i]);\n    return v;\n}\n\n// Euclidean distance for eigenvectors, and L1 for degree seqs\ndouble eigen_dist(const vector<double>& a, const vector<double>& b) {\n    double d = 0;\n    for(int i=0;i<(int)a.size();++i) d += (a[i]-b[i])*(a[i]-b[i]);\n    return sqrt(d);\n}\nint deg_dist(const vector<int>& a, const vector<int>& b) {\n    int d = 0;\n    for(int i=0;i<(int)a.size();++i) d += abs(a[i]-b[i]);\n    return d;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int M;\n    double eps;\n    cin >> M >> eps;\n\n    // Adaptive N (tuned)\n    int add = (int)(eps * 2.8 * M + 8);\n    int N = min(100, max(4, M + add));\n\n    // Random regular graph generator as before\n    mt19937 rng(1337+M+(int)(eps*10000));\n    auto random_regular_graph = [&](int N, int d) {\n        vector<int> deg(N, d);\n        vector<int> stubs;\n        for(int i=0;i<N;i++) for(int j=0;j<d;j++) stubs.push_back(i);\n        vector<vector<int>> adj(N);\n        for(int tries=0;tries<10;tries++) {\n            auto st = stubs;\n            shuffle(st.begin(), st.end(), rng);\n            vector<vector<int>> to(N);\n            bool good = true;\n            for(int i=0;i<st.size();i+=2) {\n                int u=st[i],v=st[i+1];\n                if(u==v) {good=false;break;}\n                if(find(to[u].begin(), to[u].end(), v)!=to[u].end()) {good=false;break;}\n                to[u].push_back(v);\n                to[v].push_back(u);\n            }\n            if(good) return to;\n        }\n        // Fallback: Erdos-Renyi at density 0.5\n        vector<vector<int>> adj2(N);\n        uniform_real_distribution<double> ud(0,1);\n        for(int i=0;i<N;i++) for(int j=i+1;j<N;j++) {\n            if(ud(rng)<0.5) { adj2[i].push_back(j); adj2[j].push_back(i); }\n        }\n        return adj2;\n    };\n\n    // Prepare graph codes\n    vector<string> graph_codes;\n    set<string> used_code;\n    int target_deg = min(N-1, max(2, N/2 + (int)(eps*N/3)));\n    for(int i=0;i<M;i++) {\n        string code;\n        do {\n            auto adj = random_regular_graph(N, target_deg);\n            string s(N*(N-1)/2,'0');\n            int idx=0;\n            for(int u=0;u<N;u++) for(int v=u+1;v<N;v++,idx++) {\n                if(find(adj[u].begin(), adj[u].end(), v)!=adj[u].end()) s[idx]='1';\n            }\n            code=s;\n        } while(used_code.count(code));\n        used_code.insert(code);\n        graph_codes.push_back(code);\n    }\n\n    // Output M graphs\n    cout << N << endl;\n    for(string& s:graph_codes) cout << s << '\\n';\n    cout.flush();\n\n    // Precompute features for all codes\n    vector< vector<int> > degseqs(M);\n    vector< vector<double> > eigens(M);\n    for(int i=0;i<M;i++) {\n        degseqs[i]=get_degseq(graph_codes[i], N);\n        eigens[i]=get_eigen(graph_codes[i], N);\n    }\n\n    // For each query\n    for(int q=0;q<100;q++) {\n        string query;\n        cin >> query;\n        auto q_degseq = get_degseq(query,N);\n        auto q_eigen = get_eigen(query,N);\n\n        // Find closest code\n        int best = 0;\n        double bestscore = 1e18;\n        for(int i=0;i<M;i++) {\n            int dd = deg_dist(q_degseq, degseqs[i]);\n            double ed = eigen_dist(q_eigen, eigens[i]);\n            double score = 0.11*dd + ed; // Heavy on eigen, degree helps in rare collision\n            if(score < bestscore) {\n                bestscore = score;\n                best = i;\n            }\n        }\n\n        cout << best << '\\n';\n        cout.flush();\n    }\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\nint randint(int a, int b) { return uniform_int_distribution<int>(a, b)(rng); }\n\nstruct Edge {\n    int u, v, w, id;\n    Edge(int u=0, int v=0, int w=0, int id=0): u(u), v(v), w(w), id(id) {}\n};\n\nint main() {\n    ios::sync_with_stdio(0); cin.tie(0);\n\n    int N, M, D, K;\n    cin >> N >> M >> D >> K;\n    vector<Edge> edges;\n    vector<vector<pair<int,int>>> g(N);\n    map<pair<int,int>, int> uv2eid;\n\n    for (int i = 0; i < M; ++i) {\n        int u, v, w; cin >> u >> v >> w; --u; --v;\n        edges.emplace_back(u, v, w, i);\n        g[u].emplace_back(v, w); g[v].emplace_back(u, w);\n        int uu=u, vv=v; if (uu > vv) swap(uu, vv);\n        uv2eid[make_pair(uu, vv)] = i;\n    }\n    for (int i = 0; i < N; ++i) { int x, y; cin >> x >> y; }\n\n    // Edge importance by SPT betweenness\n    const int SAMPLES = 48;\n    vector<int> sample_src;\n    unordered_set<int> used;\n    while ((int)sample_src.size() < SAMPLES) {\n        int s = randint(0,N-1);\n        if (!used.count(s)) sample_src.push_back(s), used.insert(s);\n    }\n    vector<int> e_importance(M, 0);\n    for (int si : sample_src) {\n        vector<int> dist(N, INT_MAX), from(N, -1);\n        dist[si]=0;\n        using pli=pair<int,int>;\n        priority_queue<pli,vector<pli>,greater<pli>> pq; pq.emplace(0,si);\n        while (!pq.empty()) {\n            auto[d,u]=pq.top(); pq.pop();\n            if (d>dist[u]) continue;\n            for (auto &[v,w]:g[u]) {\n                if (dist[v]>d+w) {\n                    dist[v]=d+w; from[v]=u; pq.emplace(dist[v],v);\n                }\n            }\n        }\n        for (int v=0; v<N; ++v) {\n            int u=from[v];\n            if (u==-1) continue;\n            int uu=u, vv=v; if (uu>vv) swap(uu,vv);\n            int eid=uv2eid[{uu,vv}];\n            e_importance[eid]++;\n        }\n    }\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b){\n        if(e_importance[a]!=e_importance[b]) return e_importance[a]>e_importance[b];\n        return edges[a].w>edges[b].w;\n    });\n\n    vector<int> day_of_edge(M, -1);\n    vector<int> day_counts(D, 0);\n    vector<long long> day_damage(D,0);\n    vector<unordered_set<int>> day_verts(D);\n\n    // 1. Supercritical D: at most 1 per day, no adjacent (D days)\n    vector<int> used_super(D, 0);\n    for (int i = 0; i < D && i < M; ++i) {\n        int eid = order[i];\n        int u=edges[eid].u, v=edges[eid].v;\n        int assign = -1; long long mindamage = LLONG_MAX;\n        for (int d = 0; d < D; ++d) {\n            int dprev=(d-1+D)%D, dnext=(d+1)%D;\n            if(day_counts[d]<K && !used_super[d] && !used_super[dprev] && !used_super[dnext] &&\n               !day_verts[d].count(u) && !day_verts[d].count(v) && day_damage[d]<mindamage)\n            { assign = d; mindamage=day_damage[d]; }\n        }\n        if(assign==-1)\n            for(int d=0;d<D;++d)\n                if(day_counts[d]<K && !used_super[d] && !day_verts[d].count(u) && !day_verts[d].count(v) && day_damage[d]<mindamage)\n                { assign = d; mindamage = day_damage[d]; }\n        if(assign==-1)\n            for(int d=0;d<D;++d)\n                if(day_counts[d]<K && day_damage[d]<mindamage)\n                { assign = d; mindamage=day_damage[d]; }\n        day_of_edge[eid]=assign;\n        day_counts[assign]++;\n        used_super[assign]=1;\n        day_damage[assign]+=e_importance[eid];\n        day_verts[assign].insert(u); day_verts[assign].insert(v);\n    }\n\n    // 2. Next D: at most 2 per day, prefer non-neighboring\n    vector<int> used_high(D,0);\n    for (int i = D; i < 2*D && i < M; ++i) {\n        int eid = order[i];\n        int u=edges[eid].u,v=edges[eid].v;\n        int assign=-1; long long mindamage=LLONG_MAX;\n        for (int d = 0; d<D; ++d) {\n            int dprev=(d-1+D)%D, dnext=(d+1)%D;\n            if(day_counts[d]<K && used_high[d]<2 && used_high[dprev]<2 && used_high[dnext]<2 &&\n                !day_verts[d].count(u) && !day_verts[d].count(v) && day_damage[d]<mindamage)\n            { assign=d; mindamage=day_damage[d]; }\n        }\n        if(assign==-1)\n            for(int d=0;d<D;++d)\n                if(day_counts[d]<K && used_high[d]<2 && !day_verts[d].count(u) && !day_verts[d].count(v) && day_damage[d]<mindamage)\n                { assign = d; mindamage=day_damage[d]; }\n        if(assign==-1)\n            for(int d=0;d<D;++d)\n                if(day_counts[d]<K && day_damage[d]<mindamage)\n                { assign = d; mindamage=day_damage[d]; }\n        day_of_edge[eid]=assign;\n        day_counts[assign]++;\n        used_high[assign]++;\n        day_damage[assign]+=e_importance[eid];\n        day_verts[assign].insert(u); day_verts[assign].insert(v);\n    }\n\n    // 3. Bulk, as before\n    for (int i=2*D; i<M; ++i) {\n        int eid=order[i];\n        int u=edges[eid].u,v=edges[eid].v;\n        long long bestsc=1e18; int bestd=-1;\n        for(int d=0; d<D; ++d) {\n            if (day_counts[d] >= K) continue;\n            long long sc = day_damage[d];\n            if(day_verts[d].count(u)||day_verts[d].count(v)) sc += 100;\n            if(sc < bestsc) {bestsc=sc; bestd=d;}\n        }\n        if (bestd==-1) for(int d=0;d<D;++d) if(day_counts[d]<K){bestd=d;break;}\n        day_of_edge[eid]=bestd;\n        day_counts[bestd]++;\n        day_damage[bestd]+=e_importance[eid];\n        day_verts[bestd].insert(u); day_verts[bestd].insert(v);\n    }\n\n    // Swap pass as before\n    int swaps = max(12, D/2);\n    for (int gap=0; gap<swaps; ++gap) {\n        int maxd = max_element(day_damage.begin(),day_damage.end())-day_damage.begin();\n        int mind = min_element(day_damage.begin(),day_damage.end())-day_damage.begin();\n        if(day_damage[maxd]<1.8*day_damage[mind]) break;\n        int be=-1, le=-1, critthresh=e_importance[order[D/2]], bulkthresh=e_importance[order[2*D-1]];\n        for (int i=0;i<M;++i) if(day_of_edge[i]==maxd && e_importance[i]>=critthresh) {be=i;break;}\n        for (int i=0;i<M;++i) if(day_of_edge[i]==mind && e_importance[i]<=bulkthresh) {le=i;break;}\n        if(be==-1||le==-1) break;\n        int ub=edges[be].u, vb=edges[be].v, ul=edges[le].u, vl=edges[le].v;\n        auto can_swap = [&](int eid1, int d, int uid2, int vid2){\n            int u=edges[eid1].u, v=edges[eid1].v;\n            if(u==uid2||u==vid2) return false;\n            if(v==uid2||v==vid2) return false;\n            return true;\n        };\n        if(can_swap(be,mind,ul,vl)&&can_swap(le,maxd,ub,vb)){\n            swap(day_of_edge[be],day_of_edge[le]);\n            for (int d:{maxd,mind}) {\n                day_damage[d]=0; day_counts[d]=0; day_verts[d].clear();\n                for (int i=0;i<M;++i) if(day_of_edge[i]==d) {\n                    day_damage[d]+=e_importance[i];\n                    day_counts[d]++;\n                    day_verts[d].insert(edges[i].u);\n                    day_verts[d].insert(edges[i].v);\n                }\n            }\n        } else break;\n    }\n\n    for(int i=0;i<M;++i)\n        cout << (day_of_edge[i]+1) << (i+1==M?'\\n':' ');\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int D;\n    cin >> D;\n    vector<vector<string>> F(2, vector<string>(D)), R(2, vector<string>(D));\n    for(int i=0; i<D; ++i) cin >> F[0][i];\n    for(int i=0; i<D; ++i) cin >> R[0][i];\n    for(int i=0; i<D; ++i) cin >> F[1][i];\n    for(int i=0; i<D; ++i) cin >> R[1][i];\n    vector<vector<int>> out(2, vector<int>(D*D*D, 0));\n    int block_id = 1;\n    for (int obj = 0; obj < 2; ++obj)\n        for (int x = 0; x < D; ++x)\n            for (int y = 0; y < D; ++y)\n                for (int z = 0; z < D; ++z)\n                    if (F[obj][z][x] == '1' && R[obj][z][y] == '1')\n                        out[obj][x*D*D + y*D + z] = block_id++;\n    cout << block_id-1 << \"\\n\";\n    for (int obj = 0; obj < 2; ++obj)\n        for (int i = 0; i < D*D*D; ++i)\n            cout << out[obj][i] << (i+1 == D*D*D ? '\\n' : ' ');\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <queue>\n#include <algorithm>\n#include <limits>\n#include <set>\n#include <cassert>\nusing namespace std;\n\nstruct Edge {\n    int u, v, idx;\n    long long w;\n    bool operator<(const Edge& o) const { return w < o.w; }\n};\n\ninline int dist(int x0,int y0,int x1,int y1) {\n    return (int)ceil(sqrt(1LL*(x0-x1)*(x0-x1) + 1LL*(y0-y1)*(y0-y1)));\n}\n\nconst int INF = 1e9+7;\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n\n    int N, M, K;\n    cin >> N >> M >> K;\n    vector<pair<int, int>> nodes(N);\n    for (int i = 0; i < N; ++i)\n        cin >> nodes[i].first >> nodes[i].second;\n    vector<Edge> edges(M);\n    vector<vector<pair<int, int>>> g(N); // (to, edge_id)\n    for (int j = 0; j < M; ++j) {\n        int u, v;\n        long long w;\n        cin >> u >> v >> w;\n        edges[j] = {u - 1, v - 1, j, w};\n        g[u - 1].emplace_back(v - 1, j);\n        g[v - 1].emplace_back(u - 1, j);\n    }\n    vector<pair<int, int>> residents(K);\n    for (int k = 0; k < K; ++k)\n        cin >> residents[k].first >> residents[k].second;\n\n    // For each node, for each resident, can node i cover k?\n    vector<vector<int>> can_cover(N); // residents node i can cover within 5000\n    for (int i = 0; i < N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            int d = dist(nodes[i].first, nodes[i].second, residents[k].first, residents[k].second);\n            if (d <= 5000) can_cover[i].push_back(k);\n        }\n    }\n\n    // Prepare all-pairs shortest paths (using Dijkstra per node) for fast edge cost queries.\n    vector<vector<long long>> sp(N, vector<long long>(N, 1e18));\n    vector<vector<int>> sp_prev(N, vector<int>(N, -1));\n    for (int s = 0; s < N; ++s) {\n        vector<long long>& d = sp[s];\n        d[s] = 0;\n        using pli = pair<long long,int>;\n        priority_queue<pli, vector<pli>, greater<pli>> pq; \n        pq.push({0, s});\n        while (!pq.empty()) {\n            auto [cost, v] = pq.top(); pq.pop();\n            if (cost > d[v]) continue;\n            for (auto &[to, eid] : g[v]) {\n                long long nc = cost + edges[eid].w;\n                if (d[to] > nc) {\n                    d[to] = nc;\n                    sp_prev[s][to] = v;\n                    pq.push({nc, to});\n                }\n            }\n        }\n    }\n\n    vector<int> Pi(N, 0);\n    set<int> covered;\n    set<int> active_nodes;\n    vector<bool> edge_on(M, false);\n\n    // Greedy set cover with edge cost\n    set<int> not_covered;\n    for (int k = 0; k < K; ++k) not_covered.insert(k);\n\n    // Root is always active\n    active_nodes.insert(0);\n\n    while (!not_covered.empty()) {\n        int best_id = -1, best_r = 0, best_nc = 0, best_new = -1;\n        long long best_score = 1e18;\n        set<int> best_residents;\n        set<int> best_path_edges;\n\n        for (int i = 0; i < N; ++i) {\n            // Residents that would be newly covered if broadcasting from node i, and minimal required radius.\n            set<int> new_residents;\n            int max_r = 0;\n            for (int k : can_cover[i]) {\n                if (not_covered.count(k)) {\n                    int d = dist(nodes[i].first, nodes[i].second, residents[k].first, residents[k].second);\n                    if (d > max_r) max_r = d;\n                    new_residents.insert(k);\n                }\n            }\n            if (new_residents.empty()) continue;\n\n            // Marginal edge cost to connect to active network\n            long long mcost = 1e18;\n            int connect_from = -1;\n            for (int j : active_nodes) {\n                if (sp[j][i] < mcost) {\n                    mcost = sp[j][i];\n                    connect_from = j;\n                }\n            }\n            // Score: (power cost + edge cost) / #newly covered (to prioritize efficiency)\n            long long sc = (1LL*max_r*max_r + mcost) * 10000LL / (long long)new_residents.size();\n            if (sc < best_score) {\n                best_score = sc;\n                best_id = i;\n                best_r = max_r;\n                best_residents = new_residents;\n                best_nc = connect_from;\n            }\n        }\n        if (best_id == -1) break;\n\n        // Activate node\n        Pi[best_id] = max(Pi[best_id], best_r);\n        active_nodes.insert(best_id);\n        for (int k : best_residents) not_covered.erase(k);\n\n        // Activate edge path\n        int v = best_id;\n        int from = best_nc;\n        // Path from 'from' to 'v'\n        vector<int> p;\n        while (v != from) {\n            int pv = sp_prev[from][v];\n            // Find eid between v and pv\n            int eid = -1;\n            for (auto &[to, e] : g[v]) if (to == pv) {eid = e; break;}\n            assert(eid != -1);\n            edge_on[eid] = true;\n            v = pv;\n        }\n    }\n\n    // Ensure all active broadcast nodes are connected to root (defensive: may be disconnected if initial root not always used)\n    for (int i = 0; i < N; ++i) if (Pi[i] > 0) {\n        // If not connected, connect\n        // Check: is there a path to root in the currently-on-edge subgraph?\n        vector<bool> v(N, false);\n        queue<int> q;\n        q.push(0); v[0]=1;\n        while (!q.empty()) {\n            int cur = q.front(); q.pop();\n            for (auto &[to, eid] : g[cur]) if (edge_on[eid] && !v[to]) { v[to]=1; q.push(to);}\n        }\n        if (!v[i]) {\n            // Find shortest path to 0\n            int vtx = i;\n            while (vtx != 0) {\n                int pv = sp_prev[0][vtx];\n                int eid = -1;\n                for (auto &[to, e] : g[vtx]) if (to == pv) {eid = e; break;}\n                assert(eid != -1);\n                edge_on[eid] = true;\n                vtx = pv;\n            }\n        }\n    }\n\n    // Power-pruning: safe Pi reductions\n    vector<bool> still_covered(K, false);\n    for (int i = 0; i < N; ++i) if (Pi[i] > 0) {\n        for (int k = 0; k < K; ++k) {\n            int d = dist(nodes[i].first, nodes[i].second, residents[k].first, residents[k].second);\n            if (d <= Pi[i]) still_covered[k] = true;\n        }\n    }\n    for (int i = 0; i < N; ++i) if (Pi[i] > 0) {\n        bool safe = true;\n        vector<int> need_cover;\n        for (int k = 0; k < K; ++k) {\n            int d = dist(nodes[i].first, nodes[i].second, residents[k].first, residents[k].second);\n            if (d <= Pi[i] && still_covered[k]) need_cover.push_back(k);\n        }\n        for (int k : need_cover) {\n            bool one_covered = false;\n            for (int j = 0; j < N; ++j) if (j != i && Pi[j] > 0) {\n                int d = dist(nodes[j].first, nodes[j].second, residents[k].first, residents[k].second);\n                if (d <= Pi[j]) { one_covered = true; break; }\n            }\n            if (!one_covered) { safe = false; break; }\n        }\n        if (safe) Pi[i] = 0;\n    }\n\n    // Output\n    for (int i = 0; i < N; ++i) cout << Pi[i] << (i+1==N ? '\\n' : ' ');\n    for (int j = 0; j < M; ++j) cout << (edge_on[j]?1:0) << (j+1==M ? '\\n' : ' ');\n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <algorithm>\n#include <queue>\n#include <cassert>\n#include <set>\nusing namespace std;\n\nconstexpr int N = 30;\nconstexpr int NN = N*(N+1)/2;\nconstexpr int MAX_MOVE = 10000;\n\nconst int dx[6] = {-1, -1, 0, 0, 1, 1};\nconst int dy[6] = {-1, 0, -1, 1, 0, 1};\n\ninline bool is_valid(int x, int y) {\n    return 0 <= x && x < N && 0 <= y && y <= x;\n}\ninline bool is_adjacent(int x1, int y1, int x2, int y2) {\n    for(int d=0; d<6; ++d)\n        if(x1+dx[d]==x2 && y1+dy[d]==y2) return true;\n    return false;\n}\ninline bool has_child(int x, int y) { return x < N-1; }\ninline pair<pair<int,int>, pair<int,int>> get_children(int x, int y) {\n    return {{x+1,y}, {x+1,y+1}};\n}\ninline pair<int,int> get_parentL(int x, int y) { return {x-1,y-1}; }\ninline pair<int,int> get_parentR(int x, int y) { return {x-1,y}; }\n\nstruct MoveRecorder {\n    vector<tuple<int,int,int,int>> moves;\n    int K = 0;\n    vector<vector<int>> &grid;\n    vector<pair<int,int>> &label_pos;\n    MoveRecorder(vector<vector<int>> &g, vector<pair<int,int>> &lp): grid(g), label_pos(lp) {}\n    void do_swap(int x1, int y1, int x2, int y2) {\n        using std::swap;\n        assert(is_adjacent(x1, y1, x2, y2));\n        swap(grid[x1][y1], grid[x2][y2]);\n        label_pos[grid[x1][y1]] = {x1, y1};\n        label_pos[grid[x2][y2]] = {x2, y2};\n        moves.emplace_back(x1, y1, x2, y2);\n        K++;\n    }\n};\n\nint count_violation(const vector<vector<int>> &grid) {\n    int res = 0;\n    for (int x = 0; x < N-1; ++x)\n        for (int y = 0; y <= x; ++y) {\n            auto [l, r] = get_children(x,y);\n            if(grid[x][y] > grid[l.first][l.second]) res++;\n            if(grid[x][y] > grid[r.first][r.second]) res++;\n        }\n    return res;\n}\n\nvector<pair<int,int>> bfs_path(const vector<vector<int>> &grid, pair<int,int> from, pair<int,int> to, int max_depth=16) {\n    // Early out\n    if(from == to) return {from};\n    queue<vector<pair<int,int>>> q;\n    set<pair<int,int>> vis;\n    q.push({from});\n    vis.insert(from);\n    while(!q.empty()) {\n        auto path = q.front(); q.pop();\n        auto [x,y] = path.back();\n        if((int)path.size() > max_depth+1) continue;\n        for(int d=0; d<6; ++d) {\n            int nx = x+dx[d], ny = y+dy[d];\n            if(is_valid(nx,ny) && !vis.count({nx,ny})) {\n                auto np = path; np.emplace_back(nx,ny);\n                if(make_pair(nx,ny)==to) return np;\n                q.push(np); vis.insert({nx,ny});\n            }\n        }\n    }\n    return {};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    vector<vector<int>> grid(N);\n    vector<pair<int,int>> label_pos(NN);\n    for(int x=0; x<N; ++x) {\n        grid[x].resize(x+1);\n        for(int y=0; y<=x; ++y){\n            cin >> grid[x][y];\n            label_pos[grid[x][y]] = {x, y};\n        }\n    }\n    MoveRecorder recorder(grid, label_pos);\n\n    // Alternate multi-directional passes\n    int max_pass = 13;\n    for(int pass = 0; pass < max_pass && recorder.K < MAX_MOVE; ++pass) {\n        bool changed = false;\n        // Top-down\n        for(int x=0; x<N-1 && recorder.K < MAX_MOVE; ++x) {\n            int sy = (pass&1?x:0), ey = (pass&1? -1:x+1), delta = (pass&1? -1:1);\n            for(int y=sy; y!=ey && recorder.K < MAX_MOVE; y+=delta) {\n                int v = grid[x][y];\n                auto [l,r] = get_children(x, y);\n                int lval = grid[l.first][l.second], rval = grid[r.first][r.second];\n                if(v > lval || v > rval) {\n                    int cx = x, cy = y;\n                    while(cx < N-1 && recorder.K < MAX_MOVE) {\n                        auto [cl,cr] = get_children(cx, cy);\n                        int clx=cl.first, cly=cl.second, crx=cr.first, cry=cr.second;\n                        int cv = grid[cx][cy], clv = grid[clx][cly], crv = grid[crx][cry];\n                        if(clv < crv && clv < cv) {\n                            recorder.do_swap(cx, cy, clx, cly);\n                            cx = clx; cy = cly; changed = true;\n                        }else if(crv < clv && crv < cv) {\n                            recorder.do_swap(cx, cy, crx, cry);\n                            cx = crx; cy = cry; changed = true;\n                        }else break;\n                    }\n                }\n            }\n        }\n        // Bottom-up\n        for(int x=N-1; x>0 && recorder.K < MAX_MOVE; --x) {\n            int sy = (pass&1?x:0), ey = (pass&1? -1:x+1), delta = (pass&1? -1:1);\n            for(int y=sy; y!=ey && recorder.K < MAX_MOVE; y+=delta) {\n                int cv = grid[x][y];\n                // left parent\n                if(y > 0) {\n                    auto [plx,ply] = get_parentL(x,y);\n                    if(is_valid(plx,ply) && grid[plx][ply] > cv) {\n                        int cx = x, cy = y;\n                        while(cx>0 && recorder.K<MAX_MOVE) {\n                            auto [plnx,plny] = get_parentL(cx,cy);\n                            if(is_valid(plnx,plny) && grid[plnx][plny] > grid[cx][cy]) {\n                                recorder.do_swap(plnx,plny,cx,cy);\n                                cx=plnx;cy=plny;changed=true;\n                            } else break;\n                        }\n                    }\n                }\n                // right parent\n                if(y < x) {\n                    auto [prx, pry] = get_parentR(x, y);\n                    if(is_valid(prx,pry) && grid[prx][pry] > cv) {\n                        int cx = x, cy = y;\n                        while(cx>0 && recorder.K<MAX_MOVE) {\n                            auto [prnx,prny] = get_parentR(cx,cy);\n                            if(is_valid(prnx,prny) && grid[prnx][prny] > grid[cx][cy]) {\n                                recorder.do_swap(prnx,prny,cx,cy);\n                                cx=prnx;cy=prny;changed=true;\n                            }else break;\n                        }\n                    }\n                }\n            }\n        }\n        if(!changed) break;\n    }\n    // Build violation list, highest first\n    vector<tuple<int,int,int,int,int>> vios; // x, y, cx, cy, tier\n    for (int x = 0; x < N-1; ++x)\n        for (int y = 0; y <= x; ++y) {\n            auto [l, r] = get_children(x,y);\n            if(grid[x][y] > grid[l.first][l.second]) vios.emplace_back(x,y, l.first,l.second, x);\n            if(grid[x][y] > grid[r.first][r.second]) vios.emplace_back(x,y, r.first,r.second, x);\n        }\n    // Sort by uppermost tier first\n    sort(vios.begin(), vios.end(), [](auto &a, auto &b){ return get<4>(a) < get<4>(b); });\n\n    int max_try = 200; // Try more BFS corrections\n    int done = 0;\n    int max_bfs_depth = 14; // High but not too high\n    for(auto &[x1,y1,x2,y2,tier]: vios) {\n        if(recorder.K >= MAX_MOVE) break;\n        if(grid[x1][y1] <= grid[x2][y2]) continue;\n        auto path = bfs_path(grid, {x2,y2}, {x1,y1}, max_bfs_depth);\n        if(!path.empty() && path.size() > 1 && (int)path.size()-1 + recorder.K < MAX_MOVE) {\n            for(int i=(int)path.size()-2; i>=0; --i)\n                recorder.do_swap(path[i+1].first,path[i+1].second,path[i].first,path[i].second);\n            done++;\n        }\n        if(done > max_try) break;\n    }\n    // Output\n    cout << recorder.K << '\\n';\n    for(const auto& [x1,y1,x2,y2]: recorder.moves)\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << \"\\n\";\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int D = 9;\nconstexpr int ENTRANCE_I = 0;\nconstexpr int ENTRANCE_J = (D-1)/2;\nconst int di[] = {-1,1,0,0}, dj[] = {0,0,-1,1};\n\nstruct Cell {\n    int i, j;\n    Cell(int i=0, int j=0):i(i),j(j){}\n    bool operator==(const Cell& o) const { return i==o.i && j==o.j; }\n    bool operator!=(const Cell& o) const { return !(*this==o); }\n};\n\nostream& operator<<(ostream& os, const Cell& c) {\n    return os << c.i << ' ' << c.j;\n}\n\nbool in_grid(int i, int j) {\n    return 0 <= i && i < D && 0 <= j && j < D;\n}\n\nvector<Cell> adj4(Cell c) {\n    vector<Cell> v;\n    for(int d=0;d<4;++d) {\n        int ni = c.i+di[d], nj = c.j+dj[d];\n        if(in_grid(ni,nj)) v.emplace_back(ni,nj);\n    }\n    return v;\n}\n\n// For quickly assigning container numbers to positions.\nstruct WarehouseSolver {\n    int N;\n    set<Cell> obstacles;\n    set<Cell> not_assignable; // entrance + 3 adjacents + obstacles\n    vector<Cell> assignable_cells; // order by BFS from entrance\n    map<Cell, int> cell_to_bfs_layer;\n\n    // Storage state\n    vector<pair<int,int>> arrivals; // (container number, arrival idx)\n    map<Cell, int> assigned_cell_to_num;\n    map<int, Cell> num_to_cell;\n\n    // Extraction ordering\n    vector<Cell> extraction_order;\n\n    WarehouseSolver() {}\n\n    void initialize() {\n        // Build not_assignable: entrance & its 3 adjacents & obstacles\n        not_assignable.insert(Cell(ENTRANCE_I, ENTRANCE_J));\n        for(int d=0;d<4;++d) {\n            int ni = ENTRANCE_I+di[d], nj = ENTRANCE_J+dj[d];\n            if(in_grid(ni,nj))\n                not_assignable.insert(Cell(ni,nj));\n        }\n        for(auto c: obstacles) not_assignable.insert(c);\n\n        // BFS from entrance to get \"ranked\" assignable cells\n        vector<vector<int>> vis(D, vector<int>(D, -1));\n        queue<Cell> q;\n        q.push(Cell(ENTRANCE_I, ENTRANCE_J));\n        vis[ENTRANCE_I][ENTRANCE_J]=0;\n        int dist = 1;\n        // Pre-mark not_assignable so we don't revisit\n        for(auto c: not_assignable) vis[c.i][c.j]=-2;\n        vis[ENTRANCE_I][ENTRANCE_J]=0; // entrance\n\n        vector<Cell> order;\n        while(!q.empty()) {\n            Cell c = q.front();q.pop();\n            for(auto d: adj4(c)) {\n                if(vis[d.i][d.j] == -1) {\n                    vis[d.i][d.j] = vis[c.i][c.j]+1;\n                    q.push(d);\n                    // If it's assignable (not in not_assignable), add to order\n                    if(not_assignable.count(d) == 0) {\n                        assignable_cells.push_back(d);\n                        cell_to_bfs_layer[d] = vis[d.i][d.j];\n                    }\n                }\n            }\n        }\n    }\n\n    void read_input() {\n        cin >> N;\n        for(int k=0;k<N;++k) {\n            int ri,rj;\n            cin >> ri >> rj;\n            obstacles.insert(Cell(ri,rj));\n        }\n        initialize();\n    }\n\n    void assign_container(int t_d, int arrival_idx) {\n        // Add to arrivals\n        arrivals.emplace_back(t_d, arrival_idx);\n        // We need to select an assignable cell for it.\n\n        // For containers arrived so far, make a sorted list\n        vector<pair<int,int>> sorted_arrivals = arrivals;\n        sort(sorted_arrivals.begin(), sorted_arrivals.end()); // by t_d\n        // Their optimal mapping: map sorted_arrivals[i] to assignable_cells[i]\n        // For current container (arrival_idx), find where it lands\n        int pos = -1;\n        for(int i=0;i<sorted_arrivals.size();++i) {\n            if(sorted_arrivals[i].second == arrival_idx) {\n                pos = i;\n                break;\n            }\n        }\n        assert(pos != -1);\n\n        // Some assignable_cells may already be assigned: must choose the first unassigned slot corresponding to pos (since in rare cases, due to obstacles, not all cells may be left)\n        vector<bool> used(assignable_cells.size(), false);\n        for(auto& kv: assigned_cell_to_num) {\n            // Mark which slots are taken\n            for(int i=0;i<assignable_cells.size();++i) {\n                if(assignable_cells[i]==kv.first) used[i]=true;\n            }\n        }\n        // Assign in sorted order: for the list of arrivals (sorting by t_d), map to available slots in assignable_cells in order, skipping used ones.\n        int assign_slot = -1, cnt = 0;\n        for(int i=0;i<assignable_cells.size();++i) {\n            if(used[i]) continue;\n            if(cnt==pos) { assign_slot=i; break; }\n            cnt++;\n        }\n        assert(assign_slot != -1);\n        Cell assign_cell = assignable_cells[assign_slot];\n\n        // Assign this cell to the container num\n        assigned_cell_to_num[assign_cell] = t_d;\n        num_to_cell[t_d] = assign_cell;\n\n        // Output assignment\n        cout << assign_cell.i << \" \" << assign_cell.j << endl;\n        cout.flush();\n    }\n\n    // After all containers are placed, plan extraction order.\n    void plan_extraction() {\n        // Build grid state: 0=empty, -1=obstacle, >0=container num+1\n        vector<vector<int>> grid(D, vector<int>(D,0));\n        for(auto c: obstacles) grid[c.i][c.j]=-1;\n        for(auto& [cell, num]: assigned_cell_to_num) grid[cell.i][cell.j]=num+1;\n\n        set<int> remaining_nums;\n        for(auto& [num, cell]: num_to_cell) remaining_nums.insert(num);\n\n        extraction_order.clear();\n\n        for(int step=0;step < num_to_cell.size(); ++step) {\n            // Find all containers (cells with grid>0) reachable from entrance\n            queue<Cell> q;\n            vector<vector<bool>> vis(D,vector<bool>(D,false));\n            q.push(Cell(ENTRANCE_I, ENTRANCE_J));\n            vis[ENTRANCE_I][ENTRANCE_J]=true;\n\n            set<Cell> reachable;\n            while(!q.empty()) {\n                Cell c = q.front();q.pop();\n                for(auto d: adj4(c)) {\n                    if(!vis[d.i][d.j]) {\n                        if(grid[d.i][d.j] == 0) {\n                            vis[d.i][d.j]=true;q.push(d);\n                        } else if(grid[d.i][d.j]>0) {\n                            // It's a container\n                            reachable.insert(d);\n                        }\n                    }\n                }\n            }\n            // From reachable, pick container with smallest num\n            int best_num = 1e9;\n            Cell best_cell;\n            for(auto c: reachable) {\n                int num = grid[c.i][c.j]-1;\n                if(num < best_num) { best_num = num; best_cell = c; }\n            }\n            extraction_order.push_back(best_cell);\n\n            // Remove this from grid\n            grid[best_cell.i][best_cell.j] = 0;\n            remaining_nums.erase(best_num);\n        }\n    }\n\n    void output_extraction_order() {\n        for(auto& c: extraction_order) {\n            cout << c.i << \" \" << c.j << endl;\n        }\n        cout.flush();\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D_input, N;\n    cin >> D_input >> N;\n    assert(D_input==D);\n\n    WarehouseSolver solver;\n    solver.N=N;\n    for(int k=0;k<N;++k) {\n        int ri,rj; cin >> ri >> rj;\n        solver.obstacles.insert(Cell(ri,rj));\n    }\n    solver.initialize(); // needs to be called after obstacles are set up\n\n    const int K = D*D-1-N;\n    for(int d=0; d<K; ++d) {\n        int t_d; cin >> t_d;\n        solver.assign_container(t_d, d);\n    }\n    // After all placements\n    solver.plan_extraction();\n    solver.output_extraction_order();\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 50, M = 100, COLORS = 101;\nint n, m;\nint c[N][N];\n\n// For each color, set of adjacent colors (including 0)\nvector<set<int>> adjacency(COLORS);\n// Whether color c touches the edge (adjacent to outside/0)\nvector<bool> touches0(COLORS);\n\n// For output\nint d[N][N];\n\n// Direction vectors\nconstexpr int di[] = {-1, 0, 1, 0};\nconstexpr int dj[] = {0, 1, 0, -1};\n\n// Compose adjacency graph for all colors from input\nvoid build_adjacency() {\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j) {\n            int col = c[i][j];\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir], nj = j + dj[dir];\n                if (ni < 0 || nj < 0 || ni >= n || nj >= n) {\n                    adjacency[col].insert(0);\n                    adjacency[0].insert(col);\n                    touches0[col] = true;\n                } else if (c[ni][nj] != col) {\n                    adjacency[col].insert(c[ni][nj]);\n                }\n            }\n        }\n}\n\n// List of wards (colors)\nvector<int> all_wards() {\n    vector<int> wards;\n    for (int i = 1; i <= m; ++i) wards.push_back(i);\n    return wards;\n}\n\n// Assign output locations for each ward (color)\n// Ensures border-wards go to boundary.\nmap<int, pair<int,int>> assign_ward_positions(const vector<int>& wards) {\n    map<int,pair<int,int>> pos;\n    set<pair<int,int>> used;\n    // 1. Lay out border-wards\n    vector<pair<int,int>> border_spots;\n    for (int i = 0; i < n; ++i) {\n        border_spots.emplace_back(0, i);\n        border_spots.emplace_back(n-1, i);\n    }\n    for (int j = 1; j < n-1; ++j) {\n        border_spots.emplace_back(j, 0);\n        border_spots.emplace_back(j, n-1);\n    }\n    int bi = 0;\n\n    // 2. Inner spots for rest\n    vector<pair<int,int>> inner_spots;\n    for (int i = 1; i < n-1; ++i)\n        for (int j = 1; j < n-1; ++j)\n            inner_spots.emplace_back(i,j);\n    int ii = 0;\n\n    // Wards sorted: priority to those with more adjacents\n    vector<int> order = wards;\n    sort(order.begin(), order.end(), [](int a, int b) {\n        return adjacency[a].size() > adjacency[b].size();\n    });\n\n    for (int ward : order) {\n        if (touches0[ward] && bi < (int)border_spots.size()) {\n            // Assign to border\n            pos[ward] = border_spots[bi++];\n            used.insert(pos[ward]);\n        } else if (ii < (int)inner_spots.size()) {\n            pos[ward] = inner_spots[ii++];\n            used.insert(pos[ward]);\n        } else {\n            // fallback (should not happen)\n            pos[ward] = make_pair(0,0);\n        }\n    }\n    return pos;\n}\n\n// Fill in the output grid according to assigned ward positions and enforce adjacency requirements.\nvoid build_output_map(const map<int, pair<int,int>>& ward_pos) {\n    // Clear to zero\n    for (int i=0;i<n;++i) for (int j=0;j<n;++j) d[i][j]=0;\n\n    // Place all the wards in their assigned cell\n    for (const auto& [ward, p] : ward_pos) {\n        d[p.first][p.second] = ward;\n    }\n\n    // Now, for each adjacency, ensure the pair is represented by a pair of adjacent cells on the grid.\n    // Try to do this with minimal area addition.\n    for (int c = 1; c <= m; ++c) {\n        for (int dcol : adjacency[c]) {\n            if (dcol < c) continue; // Each pair once (and skip dcol=0 for now, handlded by positions on boundary)\n\n            auto [ci, cj] = ward_pos.at(c);\n            auto [di_, dj_] = ward_pos.at(dcol);\n\n            // Are they adjacent in the grid?\n            if (abs(ci-di_)+abs(cj-dj_) ==1) continue;\n\n            // Otherwise, connect them along Manhattan path with their own colors\n            int curi = ci, curj = cj;\n            // Let's make a path from (ci,cj) to (di_,dj_) (no '0' along the way)\n            while (curi != di_) {\n                curi += (di_ > curi) ? 1 : -1;\n                if (d[curi][curj] == 0)\n                    d[curi][curj] = c;\n            }\n            while (curj != dj_) {\n                curj += (dj_ > curj) ? 1 : -1;\n                if (d[curi][curj] == 0)\n                    d[curi][curj] = c;\n            }\n        }\n    }\n}\n\n// Validation helpers (not used in contest submission)\n// Check all same-color cells are connected (DFS)\n// Check adjacencies\n\n// Full solution\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    n = N; m = M;\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j)\n            cin >> c[i][j];\n\n    adjacency.assign(COLORS, set<int>());\n    touches0.assign(COLORS, false);\n\n    build_adjacency();\n\n    vector<int> wards = all_wards();\n\n    auto ward_pos = assign_ward_positions(wards);\n\n    build_output_map(ward_pos);\n\n    // Output result\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cout << d[i][j] << \" \\n\"[j==n-1];\n        }\n    }\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nvoid fastio() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); }\nvoid flush() { cout.flush(); }\n\n// --------------- Definitions --------------\nint N, D, Q;  // Number, Divisions, Queries\nint query_count = 0;\n\n// Ask a balance between L and R, return -1 (L<R), 0 (=), 1 (L>R)\nint askBalance(const vector<int>& L, const vector<int>& R) {\n    assert(!L.empty() && !R.empty());\n    assert(query_count < Q);\n    cout << L.size() << \" \" << R.size() << \" \";\n    for (int x : L) cout << x << \" \";\n    for (int x : R) cout << x << \" \";\n    cout << \"\\n\";\n    flush();\n    string s; cin >> s;\n    query_count++;\n    if (s == \"<\") return -1;\n    else if (s == \"=\") return 0;\n    else if (s == \">\") return 1;\n    else {\n        cerr << \"Unknown judge response: \" << s << endl;\n        exit(1);\n    }\n}\n\n// Tournament-based win scores\nvector<int> get_win_scores(int N, int Q) {\n    vector<int> win_count(N, 0);\n    vector<vector<int>> compared(N, vector<int>(N, 0)); // 0: not yet, 1: compared\n\n    int max_pairs = Q;\n    // Enumerate all unordered pairs, random order for coverage\n    vector<pair<int,int>> pairs;\n    for (int i = 0; i < N; ++i) {\n        for (int j = i+1; j < N; ++j) {\n            pairs.emplace_back(i, j);\n        }\n    }\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    shuffle(pairs.begin(), pairs.end(), rng);\n\n    int used = 0;\n    for (auto &[i, j]: pairs) {\n        if (used >= max_pairs) break;\n        int res = askBalance({i}, {j});\n        if (res == 1) { win_count[i]++; }\n        else if (res == -1) { win_count[j]++; }\n        // in case of tie (rare), do nothing (or +0.5 to both if desired)\n        // compared[i][j] = compared[j][i] = 1;\n        used++;\n    }\n    return win_count;\n}\n\n// Assign heavy items to lightest groups, greedy stratified assign\nvector<int> assign_to_groups_by_score(const vector<int>& score) {\n    int N = score.size();\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    // Highest win_count first\n    sort(idx.begin(), idx.end(), [&](int i, int j){ return score[i] > score[j]; });\n\n    vector<long long> group_score(D, 0);\n    vector<int> assign(N, -1);\n    for (int t = 0; t < N; ++t) {\n        int i = idx[t];\n        if (t < D) {\n            assign[i] = t; // ensure each group gets at least 1 item\n            group_score[t] += score[i];\n        } else {\n            // assign to current lowest group\n            int gid = min_element(group_score.begin(), group_score.end()) - group_score.begin();\n            assign[i] = gid;\n            group_score[gid] += score[i];\n        }\n    }\n    return assign;\n}\n\nint main() {\n    fastio();\n    cin >> N >> D >> Q;\n\n    // 1. Use up to Q pairwise queries to collect win data\n    vector<int> win_score = get_win_scores(N, Q);\n\n    // 2. Assign by greedy\n    vector<int> assign = assign_to_groups_by_score(win_score);\n\n    // 3. Output\n    for (int i = 0; i < N; ++i) {\n        cout << assign[i] << (i+1 == N ? '\\n' : ' ');\n    }\n    flush();\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 200;\nconstexpr int M = 10;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int n, m;\n    cin >> n >> m;\n    assert(n == 200 && m == 10);\n\n    vector<vector<int>> stacks(m); // [stack][bottom..top]\n    vector<pair<int,int>> box_pos(n+1); // [box] -> (stack_id, pos_from_bottom)\n\n    for (int i = 0; i < m; ++i) {\n        stacks[i].resize(n/m);\n        for (int j = 0; j < n/m; ++j) {\n            cin >> stacks[i][j];\n            box_pos[stacks[i][j]] = {i, j};\n        }\n    }\n\n    vector<pair<int, int>> ops; // operations: (v, stack_id), stack_id==0 for carry out\n\n    // For each number to be carried out in order\n    vector<int> stack_pointer(m, 0); // number of boxes taken out from bottom of each stack\n\n    for (int target = 1; target <= n; ++target) {\n        // Find where the target box is\n        pair<int,int> pos = box_pos[target];\n        int s = pos.first, idx = pos.second;\n\n        // Since boxes are only removed from top, need to adjust for boxes already taken out from this stack\n        int logical_pos = idx - stack_pointer[s];\n        int stack_size = stacks[s].size();\n\n        // If it's at the top of its stack (adjusted)\n        if (logical_pos == (int)stacks[s].size() - 1) {\n            // Output: (target, 0)\n            ops.emplace_back(target, 0);\n            // Remove from stack\n            stacks[s].pop_back();\n            stack_pointer[s]++;\n        } else {\n            // Need to move [logical_pos, end] to another stack\n            vector<int> to_move;\n            for (int j = logical_pos; j < (int)stacks[s].size(); ++j) to_move.push_back(stacks[s][j]);\n            \n            // Remove from source stack\n            stacks[s].resize(logical_pos);\n\n            // Invalidate pointer for moved boxes\n            for (int box : to_move) box_pos[box] = {-1, -1};\n\n            // Select destination stack (shortest, not s)\n            int dest = -1, minsize = INT_MAX;\n            for (int i = 0; i < m; ++i) {\n                if (i == s) continue;\n                if ((int)stacks[i].size() < minsize) {\n                    minsize = (int)stacks[i].size();\n                    dest = i;\n                }\n            }\n\n            // Place chunk to target stack\n            for (int box : to_move) {\n                stacks[dest].push_back(box);\n            }\n            // Update positions for moved boxes\n            int sz = stacks[dest].size();\n            for (int j = 0; j < (int)to_move.size(); ++j) {\n                box_pos[to_move[j]] = {dest, sz - (int)to_move.size() + j};\n            }\n\n            // Output operation: (target, dest+1)\n            ops.emplace_back(target, dest+1);\n        restart: // We'll loop back as the box may need carry operation in next iteration\n            // Try again in next loop, as now it should be on top at dest stack\n            target--;\n        }\n    }\n    // Output\n    for (auto [v, i] : ops) cout << v << \" \" << i << \"\\n\";\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int di[4] = {-1, 1, 0, 0};\nconstexpr int dj[4] = {0, 0, -1, 1};\nconstexpr char DIR[4] = {'U', 'D', 'L', 'R'};\n// Utility\nstruct Position {\n    int i, j;\n    Position(int ii = 0, int jj = 0) : i(ii), j(jj) {}\n    bool operator==(const Position &r) const { return i == r.i && j == r.j; }\n};\n\nint N, maxLength = 100000;\nvector<string> hwall, vwall;\nvector<vector<int>> dirt;\nvector<vector<bool>> vis;\nvector<Position> route; // the \"path\"\nset<pair<int,int>> high_dirt_set;\nvector<Position> hi_dirt_list;\n\ninline bool in_grid(int i, int j) { return 0 <= i && i < N && 0 <= j && j < N; }\n\nbool can_move(int i, int j, int dir) {\n    int ni = i + di[dir], nj = j + dj[dir];\n    if (!in_grid(ni, nj)) return false;\n    if (dir == 0) return hwall[ni][nj] == '0'; // U\n    if (dir == 1) return hwall[i][j] == '0';   // D\n    if (dir == 2) return vwall[ni][nj] == '0'; // L\n    if (dir == 3) return vwall[i][j] == '0';   // R\n    return false;\n}\n\n// BFS shortest path (excluding first)\nvector<Position> bfs_shortest_path(int si, int sj, int ti=0, int tj=0) {\n    vector<vector<Position>> prev(N, vector<Position>(N, Position(-1,-1)));\n    queue<Position> q;\n    q.push({si,sj}); prev[si][sj]={si,sj};\n    while(!q.empty()) {\n        auto pos=q.front(); q.pop();\n        if(pos.i==ti && pos.j==tj) break;\n        for(int dir=0;dir<4;++dir){\n            int ni=pos.i+di[dir], nj=pos.j+dj[dir];\n            if(!in_grid(ni,nj)) continue;\n            if(!can_move(pos.i,pos.j,dir)) continue;\n            if(prev[ni][nj].i!=-1) continue;\n            prev[ni][nj]=pos;\n            q.push({ni,nj});\n        }\n    }\n    vector<Position> res;\n    Position cur={ti,tj};\n    if(prev[ti][tj].i==-1) return {}; // no path\n    while(!(cur.i==si && cur.j==sj)){\n        res.push_back(cur);\n        cur=prev[cur.i][cur.j];\n    }\n    reverse(res.begin(),res.end());\n    return res;\n}\n\nbool validate_path(const vector<Position>& r) {\n    for (size_t k=1; k<r.size(); ++k) {\n        int pi=r[k-1].i, pj=r[k-1].j, ni=r[k].i, nj=r[k].j;\n        bool found=false;\n        for(int dir=0;dir<4;++dir) {\n            if(pi+di[dir] == ni && pj+dj[dir] == nj) {\n                if (!can_move(pi,pj,dir)) return false;\n                found=true; break;\n            }\n        }\n        if(!found) return false;\n    }\n    return true;\n}\n\nstring route_to_moves(const vector<Position>& route) {\n    string moves;\n    for (size_t k = 1; k < route.size(); ++k) {\n        int pi = route[k-1].i, pj = route[k-1].j;\n        int ni = route[k].i, nj = route[k].j;\n        bool found = false;\n        for (int dir = 0; dir < 4; ++dir) {\n            if (pi + di[dir] == ni && pj + dj[dir] == nj) {\n                moves += DIR[dir];\n                found = true;\n                break;\n            }\n        }\n        if (!found) {\n            cerr << \"route_to_moves invalid move \" << pi << \" \" << pj << \" to \" << ni << \" \" << nj << endl;\n            assert(found);\n        }\n    }\n    return moves;\n}\n\nvoid dfs_with_detour(int i, int j, int &steps_left) {\n    if (steps_left <= 0) return;\n    vis[i][j]=true;\n    route.push_back({i,j});\n    --steps_left;\n\n    // Optionally take a detour if this is a high-dirt cell (not 0,0), and not at max length\n    if (steps_left>=2 && high_dirt_set.count({i,j}) && !(i==0 && j==0)) {\n        // Find a neighbor to loop\n        for(int dir=0;dir<4;++dir) {\n            int ni=i+di[dir], nj=j+dj[dir];\n            if(!in_grid(ni,nj)) continue;\n            if(!can_move(i,j,dir)) continue;\n            if(!vis[ni][nj]) continue; // avoid unvisited cells\n            // Move out and back\n            route.push_back({ni,nj});\n            route.push_back({i,j});\n            steps_left -=2;\n            break;\n        }\n    }\n    // Explore neighbors in decreasing dirt order\n    vector<pair<int,int>> nbrs;\n    for(int dir=0;dir<4;++dir){\n        int ni=i+di[dir], nj=j+dj[dir];\n        if(in_grid(ni,nj) && !vis[ni][nj] && can_move(i,j,dir)) {\n            nbrs.emplace_back(dirt[ni][nj], dir);\n        }\n    }\n    sort(nbrs.rbegin(), nbrs.rend());\n    for(auto &[dval,dir] : nbrs){\n        int ni=i+di[dir], nj=j+dj[dir];\n        if (steps_left <= 1) break; // always leave a step for return\n        dfs_with_detour(ni,nj,steps_left);\n        if (steps_left <= 0) return;\n        // Backtrack to parent node if time allows\n        route.push_back({i,j});\n        --steps_left;\n        if(steps_left<=0) return;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    hwall.resize(N-1); for(int i=0;i<N-1;++i) cin >> hwall[i];\n    vwall.resize(N);   for(int i=0;i<N;++i) cin >> vwall[i];\n    dirt.assign(N,vector<int>(N));\n    for(int i=0;i<N;++i) for(int j=0;j<N;++j) cin >> dirt[i][j];\n\n    // Choose high dirt cells for detour (top K)\n    vector<pair<int, Position>> dirtvec;\n    for(int i=0;i<N;++i) for(int j=0;j<N;++j)\n        dirtvec.push_back({-dirt[i][j], {i,j}});\n    sort(dirtvec.begin(), dirtvec.end(), [](const pair<int, Position>& a, const pair<int, Position>& b) {\n        return a.first < b.first;\n    });\n\n    int K = max(3,min(8, N*N/8));\n    for(int k=0;k<K && k<(int)dirtvec.size(); ++k) {\n        auto [negd,pos]=dirtvec[k];\n        if (pos.i == 0 && pos.j == 0) continue;\n        high_dirt_set.emplace(pos.i,pos.j);\n        hi_dirt_list.push_back(pos);\n    }\n\n    // DFS with limited steps, detours as we go\n    vis.assign(N,vector<bool>(N,false));\n    route.clear();\n    int steps_left = maxLength-1; // leave at least 1 for possible return\n    dfs_with_detour(0,0,steps_left);\n    // At current route.back(), append shortest path to 0,0\n    Position last = route.back();\n    auto pathback = bfs_shortest_path(last.i,last.j,0,0);\n    for(auto &p:pathback) {\n        if ((int)route.size()>=maxLength) break;\n        route.push_back(p);\n    }\n    // If not at (0,0), forcibly append more\n    if (!(route.back() == Position(0,0))) {\n        auto finalback = bfs_shortest_path(route.back().i, route.back().j, 0, 0);\n        for(auto &p:finalback) {\n            if ((int)route.size()>=maxLength) break;\n            route.push_back(p);\n            if(p.i==0 && p.j==0) break;\n        }\n    }\n    // Truncate if grossly over length\n    if ((int)route.size()>maxLength) route.resize(maxLength);\n\n    // Validate\n    assert(route[0]==Position(0,0));\n    assert(route.back()==Position(0,0));\n    assert(validate_path(route));\n\n    // Output\n    string moves = route_to_moves(route);\n    cout << moves << '\\n';\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 15;\nconst int DEFAULT_LOOK_AHEAD = 3;\nconst double TIME_LIMIT = 1.7;\n\ntuple<int, int, int, int> overlap_and_move(\n    const string &suffix, int ci, int cj,\n    const string &word, const vector<pair<int,int>> letter_pos[26])\n{\n    int best_ov = 0, best_cost = INT_MAX, best_ni = ci, best_nj = cj;\n    for (int ov = min((int)suffix.size(), (int)word.size()); ov >= 0; --ov) {\n        if (suffix.size() < ov || word.size() < ov) continue;\n        if (suffix.substr(suffix.size()-ov, ov) != word.substr(0, ov)) continue;\n        string to_type = word.substr(ov);\n        if (to_type.empty()) {\n            if (0 < best_cost) {\n                best_ov = ov, best_cost = 0;\n                best_ni = ci, best_nj = cj;\n            }\n            continue;\n        }\n        int li = ci, lj = cj, total = 0;\n        for (char ch : to_type) {\n            int mincost = INT_MAX, ni = -1, nj = -1;\n            int c = ch - 'A';\n            for (auto [pi, pj] : letter_pos[c]) {\n                int cost = abs(li-pi) + abs(lj-pj);\n                if (cost < mincost) {\n                    mincost = cost, ni = pi, nj = pj;\n                }\n            }\n            total += mincost + 1;\n            li = ni, lj = nj;\n        }\n        if (total < best_cost) {\n            best_ov = ov, best_cost = total;\n            best_ni = li, best_nj = lj;\n        }\n    }\n    return make_tuple(best_ov, best_cost, best_ni, best_nj);\n}\n\nint compute_cost(const vector<pair<int, int>> &route, int si, int sj) {\n    int ci = si, cj = sj, total = 0;\n    for (auto [ni, nj] : route) {\n        total += abs(ci - ni) + abs(cj - nj) + 1;\n        ci = ni, cj = nj;\n    }\n    return total;\n}\n\n// Adjacent 2-opt swap for best order (fast)\nvoid try_greedy_adjacent_2opt(vector<int> &cur_order,\n                     const vector<string> &words,\n                     const vector<pair<int,int>> letter_pos[26],\n                     int si, int sj, string &best_superstring,\n                     vector<pair<int,int>> &best_route, int &best_total_cost)\n{\n    int m = words.size();\n    for (int iter = 0; iter < 1; ++iter) {\n        bool improved = false;\n        for (int i = 1; i + 1 < m; ++i) {\n            swap(cur_order[i], cur_order[i+1]);\n            string superstring = words[cur_order[0]];\n            int ci = si, cj = sj;\n            for (char ch : superstring) {\n                int c = ch - 'A';\n                auto &lst = letter_pos[c];\n                int best = 0, bestcost = abs(ci-lst[0].first)+abs(cj-lst[0].second);\n                for (int l=1; l<(int)lst.size(); ++l) {\n                    int cost = abs(ci-lst[l].first)+abs(cj-lst[l].second);\n                    if (cost < bestcost) bestcost = cost, best = l;\n                }\n                ci = lst[best].first;\n                cj = lst[best].second;\n            }\n            for (int order_idx = 1; order_idx < m; ++order_idx) {\n                int tail_len = min(6, (int)superstring.size());\n                string tail = superstring.substr(superstring.size() - tail_len, tail_len);\n                auto [ov, cost, newci, newcj] = overlap_and_move(\n                    tail, ci, cj, words[cur_order[order_idx]], letter_pos\n                );\n                superstring += words[cur_order[order_idx]].substr(ov);\n                string add = words[cur_order[order_idx]].substr(ov);\n                for (char ch : add) {\n                    int c = ch - 'A';\n                    auto &lst = letter_pos[c];\n                    int best = 0, bestcost = abs(ci-lst[0].first)+abs(cj-lst[0].second);\n                    for (int l=1; l<(int)lst.size(); ++l) {\n                        int cost = abs(ci-lst[l].first)+abs(cj-lst[l].second);\n                        if (cost < bestcost) bestcost = cost, best = l;\n                    }\n                    ci = lst[best].first; cj = lst[best].second;\n                }\n            }\n            if ((int)superstring.size() > 5000) { swap(cur_order[i], cur_order[i+1]); continue; }\n            // Compute routing\n            int s_len = superstring.size();\n            vector<pair<int,int>> route(s_len);\n            ci = si, cj = sj;\n            for (int idx = 0; idx < s_len;) {\n                int K = min(DEFAULT_LOOK_AHEAD, s_len - idx);\n                vector<vector<pair<int,int>>> letters(K);\n                for (int k = 0; k < K; ++k)\n                    letters[k] = letter_pos[superstring[idx + k] - 'A'];\n                for (int k = 0; k < K; ++k) {\n                    if (int(letters[k].size()) > 10)\n                        letters[k].resize(10);\n                }\n                int best_cost = INT_MAX;\n                vector<int> best_chosen(K, 0);\n                vector<int> tries2(K, 0);\n                while (true) {\n                    int cost = abs(ci - letters[0][tries2[0]].first) + abs(cj - letters[0][tries2[0]].second) + 1;\n                    for (int k = 1; k < K; ++k) {\n                        auto &prv = letters[k-1][tries2[k-1]];\n                        auto &cur = letters[k][tries2[k]];\n                        cost += abs(prv.first - cur.first) + abs(prv.second - cur.second) + 1;\n                    }\n                    if (cost < best_cost) {\n                        best_cost = cost;\n                        best_chosen = tries2;\n                    }\n                    int step = K-1;\n                    while (step >= 0) {\n                        if (++tries2[step] < int(letters[step].size()))\n                            break;\n                        tries2[step] = 0;\n                        --step;\n                    }\n                    if (step < 0) break;\n                }\n                for (int k = 0; k < K; ++k) {\n                    route[idx + k] = letters[k][best_chosen[k]];\n                }\n                ci = route[idx + K - 1].first;\n                cj = route[idx + K - 1].second;\n                idx += K;\n            }\n            int total_cost = compute_cost(route, si, sj);\n            if (total_cost < best_total_cost) {\n                best_total_cost = total_cost;\n                best_superstring = superstring;\n                best_route = route;\n                improved = true;\n            } else {\n                swap(cur_order[i], cur_order[i+1]);\n            }\n        }\n        if (!improved) break;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int n, m, si, sj;\n    cin >> n >> m >> si >> sj;\n\n    vector<string> grid(n);\n    for (int i = 0; i < n; ++i) cin >> grid[i];\n\n    vector<pair<int, int>> letter_pos[26];\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j)\n            letter_pos[grid[i][j] - 'A'].emplace_back(i, j);\n\n    vector<string> words(m);\n    for (int i = 0; i < m; ++i) cin >> words[i];\n\n    random_device rd;\n    mt19937 rng(rd());\n\n    int best_total_cost = INT_MAX;\n    vector<pair<int,int>> best_route;\n    string best_superstring;\n    vector<int> best_order;\n\n    auto time_start = chrono::steady_clock::now();\n    int tries = 0;\n    for (; ; ++tries) {\n        auto t_now = chrono::steady_clock::now();\n        double elapsed = chrono::duration_cast<chrono::duration<double>>(t_now - time_start).count();\n        if (elapsed >= TIME_LIMIT) break;\n\n        vector<int> order(m);\n        iota(order.begin(), order.end(), 0);\n        if (tries > 0) shuffle(order.begin(), order.end(), rng);\n\n        int weight_cost = 10 + rng()%2;\n        int weight_ov = 2 + rng()%3;\n\n        vector<bool> used(m, false);\n        string superstring = words[order[0]];\n        used[order[0]] = true;\n        int used_count = 1;\n        int ci = si, cj = sj;\n        for (char ch : superstring) {\n            int c = ch - 'A';\n            auto &lst = letter_pos[c];\n            int best = 0, bestcost = abs(ci-lst[0].first)+abs(cj-lst[0].second);\n            for (int l=1; l<(int)lst.size(); ++l) {\n                int cost = abs(ci-lst[l].first)+abs(cj-lst[l].second);\n                if (cost < bestcost) bestcost = cost, best = l;\n            }\n            ci = lst[best].first;\n            cj = lst[best].second;\n        }\n        vector<int> merge_seq = {order[0]};\n        while (used_count < m) {\n            int bestidx = -1, bestscore = INT_MAX, bestov = 0, best_newci = 0, best_newcj = 0;\n            int tail_len = min(6, (int)superstring.size());\n            string tail = superstring.substr(superstring.size() - tail_len, tail_len);\n            for (int ti = 0; ti < m; ++ti) {\n                if (used[ti]) continue;\n                auto [ov, cost, newci, newcj] = overlap_and_move(tail, ci, cj, words[ti], letter_pos);\n                int score = cost*weight_cost - ov*weight_ov;\n                if (score < bestscore) {\n                    bestidx = ti; bestscore = score; bestov = ov;\n                    best_newci = newci; best_newcj = newcj;\n                }\n            }\n            superstring += words[bestidx].substr(bestov);\n            string add = words[bestidx].substr(bestov);\n            for (char ch : add) {\n                int c = ch - 'A';\n                auto &lst = letter_pos[c];\n                int best = 0, bestcost = abs(ci-lst[0].first)+abs(cj-lst[0].second);\n                for (int l=1; l<(int)lst.size(); ++l) {\n                    int cost = abs(ci-lst[l].first)+abs(cj-lst[l].second);\n                    if (cost < bestcost) bestcost = cost, best = l;\n                }\n                ci = lst[best].first; cj = lst[best].second;\n            }\n            used[bestidx] = true;\n            used_count++;\n            merge_seq.push_back(bestidx);\n            if ((int)superstring.size() > 5000) break;\n        }\n        if ((int)superstring.size() > 5000) continue;\n\n        int s_len = superstring.size();\n        vector<pair<int,int>> route(s_len);\n        ci = si, cj = sj;\n        for (int idx = 0; idx < s_len; ) {\n            int K = min(DEFAULT_LOOK_AHEAD, s_len - idx);\n            vector<vector<pair<int,int>>> letters(K);\n            for (int k = 0; k < K; ++k)\n                letters[k] = letter_pos[superstring[idx + k] - 'A'];\n            for (int k = 0; k < K; ++k) {\n                if (int(letters[k].size()) > 10)\n                    letters[k].resize(10);\n            }\n            int best_cost = INT_MAX;\n            vector<int> best_chosen(K, 0);\n            vector<int> tries2(K, 0);\n            while (true) {\n                int cost = abs(ci - letters[0][tries2[0]].first) + abs(cj - letters[0][tries2[0]].second) + 1;\n                for (int k = 1; k < K; ++k) {\n                    auto &prv = letters[k-1][tries2[k-1]];\n                    auto &cur = letters[k][tries2[k]];\n                    cost += abs(prv.first - cur.first) + abs(prv.second - cur.second) + 1;\n                }\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_chosen = tries2;\n                }\n                int step = K-1;\n                while (step >= 0) {\n                    if (++tries2[step] < int(letters[step].size()))\n                        break;\n                    tries2[step] = 0;\n                    --step;\n                }\n                if (step < 0) break;\n            }\n            for (int k = 0; k < K; ++k) {\n                route[idx + k] = letters[k][best_chosen[k]];\n            }\n            ci = route[idx + K - 1].first;\n            cj = route[idx + K - 1].second;\n            idx += K;\n        }\n        int total_cost = compute_cost(route, si, sj);\n        if (total_cost < best_total_cost) {\n            best_total_cost = total_cost;\n            best_route = route;\n            best_superstring = superstring;\n            best_order = merge_seq;\n        }\n    }\n\n    try_greedy_adjacent_2opt(best_order, words, letter_pos, si, sj, best_superstring, best_route, best_total_cost);\n\n    for (auto &[i, j] : best_route) cout << i << \" \" << j << '\\n';\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Polyomino {\n    vector<pair<int,int>> cells;\n    int h = 0, w = 0;\n    vector<vector<pair<int,int>>> placements;\n};\n\nint N, M;\ndouble eps;\nvector<Polyomino> oil_fields;\nvector<vector<int>> drillValue;\nvector<vector<int>> alivePlacements;\n\nvoid enumerate_placements() {\n    for (auto &poly : oil_fields) {\n        int min_i = 1e9, min_j = 1e9, max_i = -1e9, max_j = -1e9;\n        for (auto [x, y] : poly.cells) {\n            min_i = min(min_i, x);\n            max_i = max(max_i, x);\n            min_j = min(min_j, y);\n            max_j = max(max_j, y);\n        }\n        poly.h = max_i + 1;\n        poly.w = max_j + 1;\n        for (int base_i = 0; base_i + poly.h <= N; ++base_i) {\n            for (int base_j = 0; base_j + poly.w <= N; ++base_j) {\n                vector<pair<int,int>> placement;\n                for (auto [di, dj]: poly.cells) {\n                    placement.emplace_back(base_i + di, base_j + dj);\n                }\n                poly.placements.push_back(placement);\n            }\n        }\n    }\n}\n\nvector<vector<int>> plausible_oil_counts() {\n    vector<vector<int>> cnt(N, vector<int>(N));\n    for (int f = 0; f < M; ++f) {\n        for (int pi: alivePlacements[f]) {\n            for (auto [ci, cj]: oil_fields[f].placements[pi]) {\n                cnt[ci][cj]++;\n            }\n        }\n    }\n    return cnt;\n}\n\nvoid do_query(const string& s) {\n    cout << s << endl;\n    cout << flush;\n}\n\nbool update_alivePlacements() {\n    bool changed = false;\n    for (int f = 0; f < M; ++f) {\n        vector<int> updated;\n        for (int pi : alivePlacements[f]) {\n            const auto& placement = oil_fields[f].placements[pi];\n            bool ok = true;\n            for (auto [ci, cj]: placement) {\n                if (drillValue[ci][cj] == 0) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (!ok) continue;\n            for (auto [ci, cj]: placement) {\n                if (drillValue[ci][cj] > 0) {\n                    int possible = 1;\n                    for (int ff = 0; ff < M; ++ff) if (ff != f) {\n                        for (int pi2 : alivePlacements[ff]) {\n                            for (auto [ci2, cj2]: oil_fields[ff].placements[pi2]) {\n                                if (ci2 == ci && cj2 == cj) {\n                                    possible++;\n                                    goto donecount;\n                                }\n                            }\n                        }\n                        donecount:;\n                    }\n                    if (possible < drillValue[ci][cj]) {\n                        ok = false;\n                        break;\n                    }\n                }\n            }\n            if (ok) updated.push_back(pi);\n        }\n        if ((int)updated.size() != (int)alivePlacements[f].size()) changed = true;\n        alivePlacements[f] = move(updated);\n    }\n    return changed;\n}\n\npair<int,int> choose_next_drill() {\n    auto cnt = plausible_oil_counts();\n    int best_val = -1;\n    pair<int,int> best = {-1, -1};\n    for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j)\n        if (drillValue[i][j] == -1 && cnt[i][j] > best_val) {\n            best_val = cnt[i][j];\n            best = {i, j};\n        }\n    if (best_val == -1) {\n        for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j)\n            if (drillValue[i][j] == -1) return {i, j};\n    }\n    return best;\n}\n\nbool solved(set<pair<int,int>> &result_cells) {\n    set<pair<int,int>> S;\n    for (int f=0; f<M; ++f) {\n        if (alivePlacements[f].size() != 1) return false;\n        for (auto [ci,cj]: oil_fields[f].placements[alivePlacements[f][0]]) {\n            S.emplace(ci,cj);\n        }\n    }\n    result_cells = move(S);\n    return true;\n}\n\nvoid fallback_brute(set<pair<int,int>>& answer_set, vector<pair<int,int>>& already_drilled) {\n    // Drill remaining cells\n    for (int i=0; i<N; ++i) for(int j=0; j<N; ++j)\n        if (drillValue[i][j] == -1) {\n            do_query(\"q 1 \" + to_string(i) + \" \" + to_string(j));\n            int v; cin >> v;\n            drillValue[i][j] = v;\n        }\n    // Collect oil cells\n    answer_set.clear();\n    for (int i=0; i<N; ++i) for(int j=0; j<N; ++j)\n        if (drillValue[i][j] > 0) answer_set.emplace(i,j);\n    for (auto [i,j]: already_drilled) {\n        if (drillValue[i][j] > 0) answer_set.emplace(i,j);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    cin >> N >> M >> eps;\n    oil_fields.resize(M);\n    for (int k=0; k<M; ++k) {\n        int d; cin >> d;\n        vector<pair<int,int>> cc;\n        for (int q=0; q<d; ++q) {\n            int x, y; cin >> x >> y;\n            cc.emplace_back(x, y);\n        }\n        oil_fields[k].cells = move(cc);\n    }\n\n    enumerate_placements();\n\n    alivePlacements.clear();\n    for (auto &poly : oil_fields) {\n        int K = poly.placements.size();\n        vector<int> v(K);\n        iota(v.begin(), v.end(), 0);\n        alivePlacements.push_back(move(v));\n    }\n    drillValue.assign(N, vector<int>(N, -1));\n\n    set<pair<int,int>> answer_set;\n    vector<pair<int,int>> already_drilled;\n\n    // Start (at most M) random drills\n    mt19937 rng(12345);\n    int opcnt = 0;\n    int max_trials = min(M, N*N);\n    bool found = false;\n    for (; opcnt < max_trials; ) {\n        uniform_int_distribution<int> dist(0, N-1);\n        int i = dist(rng), j = dist(rng);\n        if (drillValue[i][j] != -1) continue;\n        do_query(\"q 1 \" + to_string(i) + \" \" + to_string(j));\n        int v; cin >> v;\n        drillValue[i][j] = v;\n        already_drilled.emplace_back(i,j);\n        opcnt++;\n        update_alivePlacements();\n        if (solved(answer_set)) { found = true; break; }\n    }\n\n    int alive_total = 0;\n    for (auto& pl : alivePlacements) alive_total += pl.size();\n    // Elimination loop (if necessary)\n    while (!found && opcnt < 2 * N * N && alive_total < 1000) {\n        if (solved(answer_set)) { found = true; break;}\n        pair<int,int> drill = choose_next_drill();\n        if (drill.first == -1) break;\n        int i = drill.first, j = drill.second;\n        do_query(\"q 1 \" + to_string(i) + \" \" + to_string(j));\n        int v; cin >> v;\n        drillValue[i][j] = v;\n        already_drilled.emplace_back(i,j);\n        opcnt++;\n        update_alivePlacements();\n        alive_total = 0;\n        for (auto& pl : alivePlacements) alive_total += pl.size();\n    }\n\n    if (!found) {\n        fallback_brute(answer_set, already_drilled);\n    }\n    else {\n        // Ensure all positive drilled cells present\n        for (auto [i,j]: already_drilled) {\n            if (drillValue[i][j] > 0) answer_set.emplace(i,j);\n        }\n    }\n\n    vector<pair<int,int>> oilCells(answer_set.begin(), answer_set.end());\n    cout << \"a \" << oilCells.size();\n    for (auto [i,j]: oilCells) cout << \" \" << i << \" \" << j;\n    cout << endl << flush;\n\n    int res = 0;\n    cin >> res; // Must always read final input!\n    if (res != 1) {\n        cerr << \"# Output judged incorrect!\" << endl;\n    }\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int W = 1000;\n\nusing RectList = vector<tuple<int,int,int,int>>;\n\n// Local + global greedy fix to ensure all stripes meet area in the correct subregion\nvoid ensure_enough(const vector<int>& areas, vector<int>& cuts, int D) {\n    int N = areas.size();\n    vector<int> width(N), need(N);\n    for(int i=0;i<N;++i) width[i]=cuts[i+1]-cuts[i];\n    for(int i=0;i<N;++i) need[i]=(areas[i]+D-1)/D;\n    bool changed = true;\n    while(changed) {\n        changed = false;\n        for(int i=0;i<N;++i) {\n            if (width[i] < need[i]) {\n                int j = -1;\n                if (i>0 && width[i-1]>need[i-1] && width[i-1]>1) j = i-1;\n                else if(i+1<N && width[i+1]>need[i+1] && width[i+1]>1) j = i+1;\n                else for(int k=0;k<N;++k) if(k!=i && width[k]>need[k] && width[k]>1) {j=k; break;}\n                if(j==-1) continue;\n                if(j<i) {\n                    for(int k=j+1;k<=i;++k) cuts[k]--;\n                } else {\n                    for(int k=i+1;k<=j;++k) cuts[k]++;\n                }\n                for(int k=0;k<N;++k) width[k]=cuts[k+1]-cuts[k];\n                changed = true;\n            }\n        }\n    }\n    cuts[0]=0; cuts[N]=D;\n    for(int i=1;i<N;++i) cuts[i]=min(D-1, max(cuts[i], cuts[i-1]+1));\n}\n\n// Generalized: stripe a subregion [y0,y1)x[x0,x1)\nint64_t assign_stripes_sub(const vector<int>& areas, RectList& rects, int y0, int x0, int y1, int x1, bool vertical) {\n    int H = y1 - y0, Wd = x1 - x0, N = areas.size();\n    int64_t total = accumulate(areas.begin(), areas.end(), int64_t(0));\n    vector<pair<int,int>> req(N);\n    for(int i=0;i<N;++i) req[i]={areas[i],i};\n    sort(req.rbegin(), req.rend());\n    vector<int> order(N); for(int i=0;i<N;++i) order[req[i].second] = i;\n    vector<int> widths(N), cuts(N+1, 0);\n    int used=0, DIM = (vertical?Wd:H);\n    for(int i=0;i<N;++i) {\n        if(i+1==N) widths[i]=DIM-used;\n        else {\n            widths[i]=max(int64_t(1), req[i].first * DIM / max(total, int64_t(1)));\n            used += widths[i];\n        }\n    }\n    if(used + widths[N-1] > DIM) widths[N-1] -= used + widths[N-1] - DIM;\n    for(int i=0;i<N;++i) cuts[i+1] = cuts[i] + widths[i];\n    // Local and global fix\n    vector<int> fixed_areas(N); for(int i=0;i<N;++i) fixed_areas[i]=req[i].first;\n    ensure_enough(fixed_areas, cuts, DIM);\n\n    int64_t penalty = 0;\n    rects.resize(N);\n    for(int i=0;i<N;++i) {\n        int idx = order[i];\n        int sx0 = x0, sx1 = x1, sy0 = y0, sy1 = y1;\n        if(vertical) {\n            sx0 = x0 + cuts[idx];\n            sx1 = x0 + cuts[idx+1];\n        } else {\n            sy0 = y0 + cuts[idx];\n            sy1 = y0 + cuts[idx+1];\n        }\n        sx0 = max(0, min(W-1, sx0));\n        sx1 = max(sx0+1, min(W, sx1));\n        sy0 = max(0, min(W-1, sy0));\n        sy1 = max(sy0+1, min(W, sy1));\n        int b = (sx1-sx0)*(sy1-sy0);\n        if(b < areas[i]) penalty += 100LL*(areas[i]-b);\n        rects[i] = {sy0, sx0, sy1, sx1};\n    }\n    return penalty;\n}\n\n// Standard full-grid stripes call\nint64_t assign_stripes(const vector<int>& areas, RectList& rects, bool vertical) {\n    return assign_stripes_sub(areas, rects, 0, 0, W, W, vertical);\n}\n\nint64_t assign_2d(const vector<int>& areas, RectList& rects) {\n    int N = areas.size();\n    int max_idx = max_element(areas.begin(),areas.end())-areas.begin();\n    int64_t best_pen = LLONG_MAX;\n    RectList best_rects;\n\n    int64_t need = areas[max_idx];\n    for(int top=0;top<=1;++top) for(int left=0;left<=1;++left) {\n        int h = sqrt(need);\n        int w = (need+h-1)/h;\n        if(h > W) h = W;\n        if(w > W) w = W;\n        if(h*w<need) h = (need+w-1)/w;\n        if(h>w && h<=W) swap(h,w);\n        if(h<=0||w<=0||h>W||w>W) continue;\n        int y0=top?W-h:0, y1=y0+h, x0=left?W-w:0, x1=x0+w;\n        vector<int> rest_areas; vector<int> rest_ids;\n        for(int i=0;i<N;++i) if(i!=max_idx) {rest_areas.push_back(areas[i]); rest_ids.push_back(i);}\n        RectList rr, rr2;\n        \n        // Vert stripes in remaining region to the right ([y0,y1)x[x1,W))\n        int64_t min_pen = LLONG_MAX;\n        RectList curr(N);\n\n        if(x1 < W && int(rest_areas.size())>0) {\n            int64_t p = assign_stripes_sub(rest_areas, rr, y0, x1, y1, W, true);\n            for(size_t i=0;i<rr.size();++i) curr[rest_ids[i]] = rr[i];\n            curr[max_idx] = {y0,x0,y1,x1};\n            int area = (y1-y0)*(x1-x0);\n            int penalty = (area<areas[max_idx])?100LL*(areas[max_idx]-area):0;\n            for(size_t i=0;i<rr.size();++i) {\n                int area_rest = (get<2>(rr[i])-get<0>(rr[i]))*(get<3>(rr[i])-get<1>(rr[i]));\n                if(area_rest<rest_areas[i]) penalty+=100LL*(rest_areas[i]-area_rest);\n            }\n            if(penalty<min_pen) {min_pen=penalty; best_rects=curr;}\n        }\n        // Horiz stripes in remaining region below ([y1,W)x[x0,x1))\n        if(y1 < W && int(rest_areas.size())>0){\n            int64_t p = assign_stripes_sub(rest_areas, rr2, y1, x0, W, x1, false);\n            for(size_t i=0;i<rr2.size();++i) curr[rest_ids[i]] = rr2[i];\n            curr[max_idx] = {y0,x0,y1,x1};\n            int area = (y1-y0)*(x1-x0);\n            int penalty = (area<areas[max_idx])?100LL*(areas[max_idx]-area):0;\n            for(size_t i=0;i<rr2.size();++i) {\n                int area_rest = (get<2>(rr2[i])-get<0>(rr2[i]))*(get<3>(rr2[i])-get<1>(rr2[i]));\n                if(area_rest<rest_areas[i]) penalty+=100LL*(rest_areas[i]-area_rest);\n            }\n            if(penalty<min_pen) {min_pen=penalty; best_rects=curr;}\n        }\n        // Stripe the whole remaining region (L-shape is more complex, so skip for now)\n        // If single group left, just assign all the rest!\n        if(int(rest_areas.size())==1) {\n            RectList temp(1); temp[0]={y0,x1,W,x1+W-x1};\n            curr[rest_ids[0]] = temp[0];\n            curr[max_idx] = {y0,x0,y1,x1};\n            int area = (y1-y0)*(x1-x0);\n            int penalty = (area<areas[max_idx])?100LL*(areas[max_idx]-area):0;\n            int area_rest = (get<2>(temp[0])-get<0>(temp[0]))*(get<3>(temp[0])-get<1>(temp[0]));\n            if(area_rest<rest_areas[0]) penalty+=100LL*(rest_areas[0]-area_rest);\n            if(penalty<min_pen) {min_pen=penalty; best_rects=curr;}\n        }\n    }\n    rects = best_rects;\n    return best_pen;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    int w,D,N;\n    cin >> w >> D >> N;\n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; ++d)\n        for (int k = 0; k < N; ++k)\n            cin >> a[d][k];\n\n    for (int d=0; d<D; ++d) {\n        int64_t maxreq = *max_element(a[d].begin(), a[d].end());\n        bool try2d = (maxreq >= W*W/3);\n        RectList rects;\n        int64_t pen2d = LLONG_MAX, pen1 = LLONG_MAX, pen2 = LLONG_MAX;\n        if (try2d) { pen2d = assign_2d(a[d], rects); }\n        RectList vrects, hrects;\n        pen1 = assign_stripes(a[d], vrects, true);\n        pen2 = assign_stripes(a[d], hrects, false);\n        int64_t best_pen = pen1, which=1;\n        RectList* best_rects = &vrects;\n        if(pen2<best_pen){best_pen=pen2;best_rects=&hrects;which=2;}\n        if(pen2d<best_pen){best_pen=pen2d;best_rects=&rects;which=3;}\n        for(auto [y0,x0,y1,x1]:*best_rects)\n            cout << y0 << \" \" << x0 << \" \" << y1 << \" \" << x1 << \"\\n\";\n    }\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 9, M = 20, K = 81;\nconstexpr int MOD = 998244353;\nusing Board = array<array<int, N>, N>;\nusing Stamp = array<array<int, 3>, 3>;\n\nlong long modsum(const Board& board) {\n    long long sum = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            sum += board[i][j] % MOD;\n    return sum;\n}\n\n// Phase 1: Position list for a perfect 3x3 tiling of the board\nvector<pair<int,int>> perfect_tiling_positions() {\n    vector<pair<int,int>> pos;\n    for (int pi = 0; pi <= N-3; pi += 3)\n        for (int pj = 0; pj <= N-3; pj += 3)\n            pos.emplace_back(pi, pj);\n    return pos;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n\n    int n, m, k;\n    cin >> n >> m >> k;\n    Board a;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> a[i][j];\n    vector<Stamp> stamps(M);\n    for (int t = 0; t < M; ++t)\n        for (int i = 0; i < 3; ++i)\n            for (int j = 0; j < 3; ++j)\n                cin >> stamps[t][i][j];\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    long long best_score = -1;\n    vector<tuple<int, int, int>> best_ops;\n\n    int NUM_RESTART = 10; // Tune to fit within time, try 20 on faster machines\n\n    const auto initial_tiles = perfect_tiling_positions();\n\n    for (int iter = 0; iter < NUM_RESTART; ++iter) {\n        Board board = a;\n        array<array<int, N>, N> board_mod;\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                board_mod[i][j] = board[i][j] % MOD;\n        vector<tuple<int, int, int>> ops;\n\n        // Phase 1: Initial tiling (covers all cells once in the first 9 moves)\n        for (const auto& [pi, pj] : initial_tiles) {\n            int best_gain = 0;\n            vector<int> best_stamps;\n            for (int m_id = 0; m_id < M; ++m_id) {\n                int gain = 0;\n                const auto& st = stamps[m_id];\n                for (int di = 0; di < 3; ++di)\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int ni = pi + di, nj = pj + dj;\n                        int before = board_mod[ni][nj];\n                        int after = (board[ni][nj] + st[di][dj]) % MOD;\n                        gain += (after - before + MOD) % MOD;\n                    }\n                if (gain > best_gain) {\n                    best_gain = gain;\n                    best_stamps.clear();\n                    best_stamps.push_back(m_id);\n                } else if (gain == best_gain) {\n                    best_stamps.push_back(m_id);\n                }\n            }\n            // break ties randomly\n            int m_id = best_stamps[rng() % best_stamps.size()];\n            ops.emplace_back(m_id, pi, pj);\n            const auto& st = stamps[m_id];\n            for (int di = 0; di < 3; ++di)\n                for (int dj = 0; dj < 3; ++dj) {\n                    int ni = pi + di, nj = pj + dj;\n                    board[ni][nj] += st[di][dj];\n                    board_mod[ni][nj] = (board_mod[ni][nj] + st[di][dj]) % MOD;\n                }\n        }\n\n        // Phase 2: Greedy for the remaining moves, with tie-breaking on min cell touched\n        for (int step = initial_tiles.size(); step < K; ++step) {\n            int best_gain = 0;\n            int best_mincell = MOD+1;\n            vector<tuple<int, int, int>> candidates;\n            for (int m_id = 0; m_id < M; ++m_id) {\n                const auto& st = stamps[m_id];\n                for (int p = 0; p <= N - 3; ++p) {\n                    for (int q = 0; q <= N - 3; ++q) {\n                        int gain = 0;\n                        int mincell = MOD+1;\n                        for (int di = 0; di < 3; ++di)\n                            for (int dj = 0; dj < 3; ++dj) {\n                                int ni = p + di, nj = q + dj;\n                                int before = board_mod[ni][nj];\n                                int after = (board[ni][nj] + st[di][dj]) % MOD;\n                                gain += (after - before + MOD) % MOD;\n                                mincell = min(mincell, before);\n                            }\n                        if (gain > best_gain || (gain == best_gain && mincell < best_mincell)) {\n                            best_gain = gain;\n                            best_mincell = mincell;\n                            candidates.clear();\n                            candidates.emplace_back(m_id, p, q);\n                        } else if (gain == best_gain && mincell == best_mincell) {\n                            candidates.emplace_back(m_id, p, q);\n                        }\n                    }\n                }\n            }\n            if (best_gain <= 0) break;\n            shuffle(candidates.begin(), candidates.end(), rng);\n            auto [m, p, q] = candidates[0];\n            ops.emplace_back(m, p, q);\n            const auto& st = stamps[m];\n            for (int di = 0; di < 3; ++di)\n                for (int dj = 0; dj < 3; ++dj) {\n                    int ni = p + di, nj = q + dj;\n                    board[ni][nj] += st[di][dj];\n                    board_mod[ni][nj] = (board_mod[ni][nj] + st[di][dj]) % MOD;\n                }\n        }\n        long long tot = modsum(board);\n        if (tot > best_score) {\n            best_score = tot;\n            best_ops = ops;\n        }\n    }\n    cout << best_ops.size() << '\\n';\n    for (auto [m, p, q] : best_ops) {\n        cout << m << \" \" << p << \" \" << q << '\\n';\n    }\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\nconstexpr int N = 5, MAX_TURNS = 10000;\n\nstruct Crane {\n    int r, c;\n    bool large, holding;\n    int hold;\n};\nint main() {\n    ios::sync_with_stdio(0); cin.tie(0);\n    vector<vector<int>> A(N, vector<int>(N));\n    for (auto& row : A) for (int& x : row) cin >> x;\n\n    // Per-row incoming queues\n    array<queue<int>, N> arrv;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) arrv[i].push(A[i][j]);\n\n    int grid[N][N]; for(auto& r:grid)fill(begin(r),end(r),-1);\n    vector<Crane> cranes;\n    for (int i = 0; i < N; i++) cranes.push_back({i, 0, i==0, false, -1});\n    int who[N][N]; for(auto& r:who)fill(begin(r),end(r),-1);\n    for(int i=0;i<N;i++)who[i][0]=i;\n    int need[N] = {};\n    vector<string> logs(N);\n\n    int dispatched_cnt = 0;\n    int turn = 0; // track number of turns actually used\n    for (; turn < MAX_TURNS; ++turn) {\n        // ARRIVAL: deliver if possible\n        for (int i = 0; i < N; i++)\n            if (grid[i][0] == -1 && !cranes[i].holding && !arrv[i].empty())\n                grid[i][0] = arrv[i].front(), arrv[i].pop();\n\n        char acts[N]; fill(begin(acts),end(acts),'.');\n        int claim[N][N]; for(int i=0;i<N;i++)for(int j=0;j<N;j++)claim[i][j]=who[i][j];\n\n        for (int k = 0; k < N; k++) {\n            auto& cr = cranes[k];\n            int r = cr.r, c = cr.c;\n            int mygoal = N*r + need[r];\n\n            // 1. Deliver if at dispatch gate\n            if(cr.holding && cr.hold==mygoal && c==N-1 && grid[r][c]==-1) {\n                acts[k]='Q'; cr.holding=false; grid[r][c]=cr.hold; cr.hold=-1; need[r]++;\n                continue;\n            }\n            // 2. Buffer if holding wrong container at free buffer\n            if(cr.holding && cr.hold!=mygoal && c>=1 && c<=3 && grid[r][c]==-1) {\n                acts[k]='Q'; cr.holding=false; grid[r][c]=cr.hold; cr.hold=-1;\n                continue;\n            }\n            // 3. If holding, go to dispatch/buffer\n            if(cr.holding){\n                int tgt=-1;\n                if(cr.hold==mygoal) tgt=N-1;\n                else for(int pos=1;pos<=3;pos++) if(grid[r][pos]==-1){tgt=pos;break;}\n                if(tgt!=-1 && c!=tgt){\n                    int dir=(tgt>c?1:-1);\n                    if(who[r][c+dir]==-1 && (cr.large || grid[r][c+dir]==-1)){\n                        acts[k]=(dir==1?'R':'L'); who[r][c]=-1; cr.c+=dir; who[r][cr.c]=k; continue;\n                    }\n                }\n            }\n            // 4. Pick up target underfoot\n            if(!cr.holding && grid[r][c]==mygoal){\n                acts[k]='P'; cr.holding=true; cr.hold=mygoal; grid[r][c]=-1; continue;\n            }\n            // 5. Buffer wrong arrival if at rec gate\n            if(!cr.holding && c==0 && grid[r][0]!=-1 && grid[r][0]!=mygoal){\n                acts[k]='P'; cr.holding=true; cr.hold=grid[r][0]; grid[r][0]=-1; continue;\n            }\n            // 6. Move toward correct container\n            int tgt=-1, dist=10;\n            for(int pos=0;pos<=3;pos++)if(grid[r][pos]==mygoal&&abs(pos-c)<dist){tgt=pos;dist=abs(pos-c);}\n            if(tgt!=-1 && c!=tgt){\n                int dir = (tgt>c?1:-1);\n                if(who[r][c+dir]==-1){\n                    acts[k]=(dir==1?'R':'L');\n                    who[r][c]=-1; cr.c+=dir; who[r][cr.c]=k; continue;\n                }\n            }\n            // 7. Move to an empty buffer (wait for future)\n            if(!cr.holding){\n                for(int buf=1;buf<=3;buf++)\n                    if(grid[r][buf]==-1 && c!=buf && who[r][buf]==-1){\n                        int dir=(buf>c?1:-1);\n                        if(who[r][c+dir]==-1){\n                            acts[k]=(dir==1?'R':'L'); who[r][c]=-1; cr.c+=dir; who[r][cr.c]=k; break;\n                        }\n                    }\n            }\n        }\n        for (int k = 0; k < N; k++) logs[k] += acts[k];\n\n        // DISPATCH any containers delivered\n        for (int i = 0; i < N; i++) if (grid[i][N-1]!=-1) { grid[i][N-1]=-1; dispatched_cnt++; }\n\n        // --- EARLY STOP ---\n        if (dispatched_cnt == N*N) {\n            ++turn;\n            break;\n        }\n    }\n    // PAD\n    size_t mxlen=turn;\n    for(auto&s:logs) if(s.size()<mxlen) s+=string(mxlen-s.size(),'.');\n    for(auto&s:logs) cout << s << '\\n';\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 20;\nconstexpr int MAX_LOAD = 1000000;\nconstexpr int SUPPLY_RADIUS = 2;\nconstexpr int DEMAND_CHAIN_MAX_DIST = 4;\n\nstruct Cell {\n    int y, x, amount;\n    bool done = false;\n};\n\nvector<char> get_path(int sy, int sx, int ty, int tx) {\n    vector<char> path;\n    while (sy < ty) { path.emplace_back('D'); sy++; }\n    while (sy > ty) { path.emplace_back('U'); sy--; }\n    while (sx < tx) { path.emplace_back('R'); sx++; }\n    while (sx > tx) { path.emplace_back('L'); sx--; }\n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n; cin >> n;\n    vector<vector<int>> h(n, vector<int>(n));\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j) cin >> h[i][j];\n\n    vector<Cell> supplies, demands;\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j)\n            if (h[i][j] > 0)\n                supplies.push_back({i, j, h[i][j]});\n            else if (h[i][j] < 0)\n                demands.push_back({i, j, -h[i][j]});\n\n    vector<string> commands;\n    int cy = 0, cx = 0, load = 0;\n\n    auto find_nearest_supply = [&](int cy, int cx) -> int {\n        int idx = -1, best = INT_MAX;\n        for (int i = 0; i < (int)supplies.size(); ++i)\n            if (!supplies[i].done && supplies[i].amount)\n                if (int d = abs(supplies[i].y - cy) + abs(supplies[i].x - cx); d < best)\n                    best = d, idx = i;\n        return idx;\n    };\n\n    auto collect_supply_batch = [&](int sy, int sx, int truck_free, vector<Cell>& supplies, vector<pair<int,int>>& batch) {\n        int n = supplies.size();\n        vector<tuple<int,int,int>> close;\n        for (int i = 0; i < n; ++i) {\n            if (supplies[i].done || supplies[i].amount == 0) continue;\n            int d = abs(supplies[i].y - sy) + abs(supplies[i].x - sx);\n            if (d == 0) continue;\n            if (d <= SUPPLY_RADIUS) close.emplace_back(d, i, supplies[i].amount);\n        }\n        sort(close.begin(), close.end());\n        int cur_y = sy, cur_x = sx, remain = truck_free;\n        for (auto& [dist, idx, amt] : close) {\n            if (remain == 0) break;\n            auto path = get_path(cur_y, cur_x, supplies[idx].y, supplies[idx].x);\n            for (char c : path) batch.push_back({0, c});\n            batch.push_back({1, idx});\n            remain -= min(remain, supplies[idx].amount);\n            cur_y = supplies[idx].y, cur_x = supplies[idx].x;\n        }\n        return make_pair(cur_y, cur_x);\n    };\n\n    auto greedy_chain_demands = [&](int& py, int& px, int& tload, vector<Cell>& demands, vector<string>& commands) {\n        while (tload > 0) {\n            int best_i = -1, best_dist = INT_MAX;\n            for (int i = 0; i < (int)demands.size(); ++i) {\n                if (!demands[i].done && demands[i].amount > 0) {\n                    int d = abs(py-demands[i].y) + abs(px-demands[i].x);\n                    if (d && d <= DEMAND_CHAIN_MAX_DIST) {\n                        if (d < best_dist) best_dist = d, best_i = i;\n                    }\n                }\n            }\n            if (best_i == -1) break;\n            int dy = demands[best_i].y, dx = demands[best_i].x;\n            auto path = get_path(py, px, dy, dx);\n            for (char c : path) commands.push_back(string(1, c));\n            py = dy; px = dx;\n            int deliver = min(tload, demands[best_i].amount);\n            if (deliver > 0) {\n                commands.push_back(\"-\" + to_string(deliver));\n                demands[best_i].amount -= deliver;\n                tload -= deliver;\n                if (demands[best_i].amount == 0) demands[best_i].done = true;\n            }\n        }\n    };\n\n    while (true) {\n        if (load == 0) {\n            // Small enhancement: If a demand is adjacent and there is an adjacent supply, do micro supply-demand loop\n            bool found_fast = false;\n            for (int d = 0; d < 4 && !found_fast; ++d) {\n                int ny = cy + (d == 0 ? -1 : d == 1 ? 1 : 0);\n                int nx = cx + (d == 2 ? -1 : d == 3 ? 1 : 0);\n                for (int s = 0; s < (int)supplies.size(); ++s) {\n                    if (!supplies[s].done && supplies[s].amount > 0\n                        && abs(supplies[s].y - ny) + abs(supplies[s].x - nx) == 0) {\n                        // move to supply, load, and then try to deliver immediately if possible\n                        commands.push_back(string(1, \"UDLR\"[d]));\n                        cy = ny; cx = nx;\n                        int amt = min(supplies[s].amount, MAX_LOAD);\n                        commands.push_back(\"+\" + to_string(amt));\n                        load += amt;\n                        supplies[s].amount -= amt;\n                        if (supplies[s].amount == 0) supplies[s].done = true;\n                        found_fast = true;\n                        break;\n                    }\n                }\n            }\n            if(found_fast) continue;\n\n            int sidx = find_nearest_supply(cy, cx);\n            if (sidx == -1) break;\n            auto& cell = supplies[sidx];\n            int y = cell.y, x = cell.x, truck_free = MAX_LOAD;\n            auto path0 = get_path(cy, cx, y, x);\n            for (char c : path0) commands.push_back(string(1, c));\n            cy = y; cx = x;\n            int to_load = min(truck_free, cell.amount);\n            commands.push_back(\"+\" + to_string(to_load));\n            load += to_load;\n            truck_free -= to_load;\n            cell.amount -= to_load;\n            if (cell.amount == 0) cell.done = true;\n            vector<pair<int,int>> supply_script;\n            auto [ey, ex] = collect_supply_batch(y, x, truck_free, supplies, supply_script);\n            for (auto& [kind, dat] : supply_script) {\n                if (kind == 0) {\n                    commands.push_back(string(1, (char)dat));\n                    cy = (dat=='U'?cy-1: dat=='D'?cy+1: cy);\n                    cx = (dat=='L'?cx-1: dat=='R'?cx+1: cx);\n                } else {\n                    int idx = dat;\n                    int amt = min(MAX_LOAD-load, supplies[idx].amount);\n                    if (amt > 0) {\n                        commands.push_back(\"+\"+to_string(amt));\n                        load += amt;\n                        supplies[idx].amount -= amt;\n                        if (supplies[idx].amount == 0) supplies[idx].done = true;\n                    }\n                }\n            }\n        } else {\n            int K_BEST = (load > 500 ? 5 : (load > 250 ? 4 : 3));\n            vector<pair<int,int>> cand;\n            for (int i = 0; i < (int)demands.size(); ++i)\n                if (!demands[i].done && demands[i].amount > 0)\n                    cand.emplace_back(abs(demands[i].y - cy) + abs(demands[i].x - cx), i);\n            sort(cand.begin(), cand.end());\n            vector<int> dindices;\n            int tload = load;\n            for(auto& [dist, i] : cand)\n                if (tload > 0 && (int)dindices.size() < K_BEST)\n                    dindices.push_back(i), tload -= demands[i].amount;\n            if (dindices.empty()) break;\n            vector<int> bestseq;\n            long long bestcost = LLONG_MAX;\n            int dk = dindices.size();\n            vector<int> perm = dindices;\n            do {\n                int py = cy, px = cx, tload2 = load;\n                long long cost = 0;\n                int real_len = 0;\n                for (int ind = 0; ind < dk && tload2 > 0; ++ind) {\n                    int id = perm[ind];\n                    int dy = demands[id].y, dx = demands[id].x;\n                    cost += 1LL * (abs(py - dy) + abs(px - dx)) * (100 + tload2);\n                    int deliver = min(tload2, demands[id].amount);\n                    if (deliver <= 0) break;\n                    tload2 -= deliver;\n                    py = dy; px = dx;\n                    ++real_len;\n                }\n                if (cost < bestcost) {\n                    bestcost = cost;\n                    bestseq = perm;\n                    bestseq.resize(real_len);\n                }\n            } while (next_permutation(perm.begin(), perm.end()));\n            int py = cy, px = cx, tload2 = load;\n            for (int ind = 0; ind < (int)bestseq.size() && tload2 > 0; ++ind) {\n                int id = bestseq[ind];\n                int dy = demands[id].y, dx = demands[id].x;\n                for (char c : get_path(py, px, dy, dx)) commands.push_back(string(1, c)), py+=(c=='D')-(c=='U'), px+=(c=='R')-(c=='L');\n                int deliver = min(tload2, demands[id].amount);\n                if (deliver > 0) {\n                    commands.push_back(\"-\"+to_string(deliver));\n                    demands[id].amount -= deliver;\n                    tload2 -= deliver;\n                    if (demands[id].amount == 0) demands[id].done = true;\n                }\n            }\n            greedy_chain_demands(py, px, tload2, demands, commands);\n            cy = py; cx = px; load = tload2;\n        }\n    }\n    for (size_t i = 0; i < commands.size(); ++i) {\n        cout << commands[i] << '\\n';\n    }\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 6, M = 15, T = 10, SEED_COUNT = 2 * N * (N - 1), GRID_SIZE = N * N;\n\nstruct Seed {\n    vector<int> x;\n    int id;\n    int value;\n    int max_feat;\n    Seed(int _id, const vector<int>& _x) : x(_x), id(_id) {\n        value = accumulate(x.begin(), x.end(), 0);\n        max_feat = 0;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int n, m, t;\n    cin >> n >> m >> t;\n    vector<Seed> seeds;\n    for (int i = 0; i < SEED_COUNT; ++i) {\n        vector<int> x(m);\n        for (int j = 0; j < m; ++j) cin >> x[j];\n        seeds.emplace_back(i, x);\n    }\n    mt19937 rng(123456789);\n\n    for (int turn = 0; turn < T; ++turn) {\n        // Feature max computation\n        vector<int> feat_max(m, 0);\n        for (int j = 0; j < m; ++j)\n            for (const auto& s : seeds)\n                feat_max[j] = max(feat_max[j], s.x[j]);\n\n        for (auto& s : seeds) {\n            s.max_feat = 0;\n            for (int j = 0; j < m; ++j)\n                if (s.x[j] == feat_max[j]) ++s.max_feat;\n        }\n\n        // ------ Step 1: Assemble exactly 36 unique seed IDs ------\n        vector<int> selected_ids;\n        set<int> used; // IDs\n\n        if (turn < 3) {\n            // Collect unique per-feature-max seeds (by set)\n            set<int> featmax_seeds;\n            for (int j = 0; j < m; ++j)\n                for (int i = 0; i < SEED_COUNT; ++i)\n                    if (seeds[i].x[j] == feat_max[j])\n                        featmax_seeds.insert(seeds[i].id);\n            // Add these first\n            for (int id : featmax_seeds) {\n                selected_ids.push_back(id);\n                used.insert(id);\n            }\n            // Score all seeds (skip those already picked)\n            vector<pair<int, int>> scorelist;\n            for (int i = 0; i < SEED_COUNT; ++i) {\n                if (!used.count(seeds[i].id))\n                    scorelist.emplace_back(seeds[i].value + seeds[i].max_feat * 40, seeds[i].id);\n            }\n            sort(scorelist.rbegin(), scorelist.rend());\n            // Fill up to 36 with best available unused seeds\n            for (auto& [score, id] : scorelist) {\n                if ((int)selected_ids.size() == 36) break;\n                selected_ids.push_back(id);\n                used.insert(id);\n            }\n            // Fallback: if still not 36, fill from any unused IDs\n            for (int i = 0; (int)selected_ids.size() < 36 && i < SEED_COUNT; ++i) {\n                if (!used.count(seeds[i].id)) {\n                    selected_ids.push_back(seeds[i].id);\n                    used.insert(seeds[i].id);\n                }\n            }\n        } else {\n            // After round 2: propagate superseeds, then fill with best unused seeds\n            int max_mf = 0;\n            for (auto& s : seeds) max_mf = max(max_mf, s.max_feat);\n            vector<int> superseeds;\n            for (auto& s : seeds)\n                if (s.max_feat == max_mf) superseeds.push_back(s.id);\n            shuffle(superseeds.begin(), superseeds.end(), rng);\n            sort(superseeds.begin(), superseeds.end(), [&](int a, int b) {\n                return seeds[a].value > seeds[b].value;\n            });\n            // Take up to 8 superseeds first\n            for (int i = 0; i < (int)superseeds.size() && (int)selected_ids.size() < 8; ++i) {\n                selected_ids.push_back(superseeds[i]);\n                used.insert(superseeds[i]);\n            }\n            // Now fill the rest (to 36) with highest valued remaining seeds\n            vector<pair<int, int>> scorelist;\n            for (int i = 0; i < SEED_COUNT; ++i) {\n                if (!used.count(seeds[i].id))\n                    scorelist.emplace_back(seeds[i].value + seeds[i].max_feat * 40, seeds[i].id);\n            }\n            sort(scorelist.rbegin(), scorelist.rend());\n            for (auto& [score, id] : scorelist) {\n                if ((int)selected_ids.size() == 36) break;\n                selected_ids.push_back(id);\n                used.insert(id);\n            }\n            // Fallback: if still not 36\n            for (int i = 0; (int)selected_ids.size() < 36 && i < SEED_COUNT; ++i) {\n                if (!used.count(seeds[i].id)) {\n                    selected_ids.push_back(seeds[i].id);\n                    used.insert(seeds[i].id);\n                }\n            }\n        }\n        // Now guaranteed: selected_ids.size() == 36, all unique.\n\n        // ------ Step 2: Assign to grid cells ------\n        vector<pair<int, int>> cell_order;\n        if (turn < 3) {\n            // Central 4x4 first, then periphery (row-major order)\n            for (int i = 1; i <= 4; ++i)\n                for (int j = 1; j <= 4; ++j)\n                    cell_order.emplace_back(i, j);\n            for (int i = 0; i < n; ++i)\n                for (int j = 0; j < n; ++j)\n                    if (i < 1 || i > 4 || j < 1 || j > 4)\n                        cell_order.emplace_back(i, j);\n        } else {\n            // Center/cross, then others\n            vector<pair<int,int>> special_cells = { {2,2},{2,3},{3,2},{3,3},{1,2},{2,1},{3,4},{4,3} };\n            for (auto p : special_cells) cell_order.push_back(p);\n            for (int i = 0; i < n; ++i)\n                for (int j = 0; j < n; ++j) {\n                    bool already = false;\n                    for (auto& sc : special_cells)\n                        if (sc.first == i && sc.second == j) already = true;\n                    if (!already)\n                        cell_order.emplace_back(i, j);\n                }\n        }\n        // assign seeds to grid in determined order\n        vector<vector<int>> grid(n, vector<int>(n, -1));\n        for (int k = 0; k < 36; ++k) {\n            auto [i, j] = cell_order[k];\n            grid[i][j] = selected_ids[k];\n        }\n\n        // ------ Step 3: Output ------\n        for (int i = 0; i < n; ++i) {\n            for (int j = 0; j < n; ++j)\n                cout << grid[i][j] << (j + 1 < n ? ' ' : '\\n');\n        }\n        cout.flush();\n\n        // ------ Step 4: Input next seeds ------\n        vector<Seed> next_seeds;\n        for (int k = 0; k < SEED_COUNT; ++k) {\n            vector<int> x(m);\n            for (int j = 0; j < m; ++j) cin >> x[j];\n            next_seeds.emplace_back(k, x);\n        }\n        seeds = move(next_seeds);\n    }\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int x, y; };\n\nvector<Pos> get_leaves(int legs, int len) {\n    vector<Pos> dirs = {{0,1}, {1,0}, {0,-1}, {-1,0}, {1,1}, {-1,1}, {1,-1}, {-1,-1}};\n    vector<Pos> res;\n    int D = dirs.size();\n    for(int i=0; i<legs; ++i){ int m=1+(i/D); res.push_back({dirs[i%D].x*len*m, dirs[i%D].y*len*m}); }\n    return res;\n}\nPos add(Pos a,Pos b){ return {a.x+b.x,a.y+b.y}; }\n\nint main() {\n    int N, M, V; cin>>N>>M>>V;\n    vector<string> s(N), t(N);\n    for(int i=0;i<N;i++) cin>>s[i];\n    for(int i=0;i<N;i++) cin>>t[i];\n    vector<Pos> pick, deliver;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n        if(s[i][j]=='1') pick.push_back({i,j});\n        if(t[i][j]=='1') deliver.push_back({i,j});\n    }\n    int V_=min(V,9), L=1;\n    cout<<V_<<\"\\n\"; for(int i=1;i<V_;i++) cout<<\"0 \"<<L<<\"\\n\"; cout<<\"0 0\\n\";\n    auto leaves = get_leaves(V_-1,L);\n    vector<bool> tip_hold(V_-1,false), picked(pick.size(),false), delivered(deliver.size(),false);\n    int root_x=0, root_y=0, d_cnt=0, T=0;\n\n    while(d_cnt<M&&T<100000){\n        // Get all tips not holding\n        vector<int> free; for(int i=0;i<V_-1;i++) if(!tip_hold[i]) free.push_back(i);\n        vector<int> todo; for(int i=0;i<(int)pick.size()&&todo.size()<free.size();i++) if(!picked[i]) todo.push_back(i);\n        int batch=min(free.size(),todo.size());\n        bool found=false; Pos root; vector<int> assign(V_-1,-1);\n        for(int rx=0;rx<N&&!found;rx++) for(int ry=0;ry<N&&!found;ry++){\n            vector<int> a(V_-1,-1); vector<bool> used(V_-1,0);\n            bool fail=0;\n            for(int b=0;b<batch;b++){\n                bool mt=0;\n                for(int ii=0;ii<(int)free.size();ii++){\n                    int f=free[ii];if(used[f])continue;\n                    auto tip=add({rx,ry},leaves[f]);\n                    if(tip.x<0||tip.y<0||tip.x>=N||tip.y>=N)continue;\n                    if(tip.x==pick[todo[b]].x&&tip.y==pick[todo[b]].y){\n                        a[f]=b;used[f]=1;mt=1;break;}\n                }\n                if(!mt){ fail=1;break;}\n            }\n            if(!fail){ assign=a; root={rx,ry}; found=1;}\n        }\n        if(!found) break;\n        while(root_x<root.x){string s(2*V_,'.');s[0]='D';cout<<s<<\"\\n\";T++;root_x++;}\n        while(root_x>root.x){string s(2*V_,'.');s[0]='U';cout<<s<<\"\\n\";T++;root_x--;}\n        while(root_y<root.y){string s(2*V_,'.');s[0]='R';cout<<s<<\"\\n\";T++;root_y++;}\n        while(root_y>root.y){string s(2*V_,'.');s[0]='L';cout<<s<<\"\\n\";T++;root_y--;}\n        string cmd(2*V_,'.');\n        for(int f=0;f<V_-1;f++) if(assign[f]!=-1){\n            int idx=todo[assign[f]];picked[idx]=1;tip_hold[f]=1;cmd[V_+f+1]='P';\n        }\n        cout<<cmd<<\"\\n\";T++;\n\n        // Now deliver for all tips now holding!\n        vector<int> fill;\n        for(int f=0;f<V_-1;f++) if(tip_hold[f]) fill.push_back(f);\n        vector<int> deldo;\n        for(int i=0;i<(int)deliver.size()&&deldo.size()<fill.size();i++) if(!delivered[i]) deldo.push_back(i);\n        batch=min(fill.size(),deldo.size());\n        found=0; assign=vector<int>(V_-1,-1);\n        for(int rx=0;rx<N&&!found;rx++) for(int ry=0;ry<N&&!found;ry++){\n            vector<int> a(V_-1,-1);vector<bool>used(V_-1,0);bool fail=0;\n            for(int b=0;b<batch;b++){\n                bool mt=0; for(int ii=0;ii<(int)fill.size();ii++){\n                    int f=fill[ii]; if(used[f])continue;\n                    auto tip=add({rx,ry},leaves[f]);\n                    if(tip.x<0||tip.y<0||tip.x>=N||tip.y>=N)continue;\n                    if(tip.x==deliver[deldo[b]].x&&tip.y==deliver[deldo[b]].y){\n                        a[f]=b;used[f]=1;mt=1;break; }\n                }\n                if(!mt){fail=1;break;}\n            }\n            if(!fail){assign=a; root={rx,ry}; found=1;}\n        }\n        if(!found) break;\n        while(root_x<root.x){string s(2*V_,'.');s[0]='D';cout<<s<<\"\\n\";T++;root_x++;}\n        while(root_x>root.x){string s(2*V_,'.');s[0]='U';cout<<s<<\"\\n\";T++;root_x--;}\n        while(root_y<root.y){string s(2*V_,'.');s[0]='R';cout<<s<<\"\\n\";T++;root_y++;}\n        while(root_y>root.y){string s(2*V_,'.');s[0]='L';cout<<s<<\"\\n\";T++;root_y--;}\n        string dcmd(2*V_,'.');\n        for(int f=0;f<V_-1;f++) if(assign[f]!=-1){\n            int idx=deldo[assign[f]];delivered[idx]=1;tip_hold[f]=0;dcmd[V_+f+1]='P';d_cnt++;}\n        cout<<dcmd<<\"\\n\";T++;\n    }\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int GRID = 200;\nconstexpr int FIELD = 100000;\nconstexpr int MAX_PERIM = 400000;\n\nstruct Rect {\n    int x0, y0, x1, y1;\n    int a, b, perim, score;\n    bool operator<(const Rect &o) const {\n        if (score != o.score) return score > o.score;\n        return perim < o.perim;\n    }\n};\n\nint full_perim(int x0, int y0, int x1, int y1, double cell_size) {\n    return 2 * (int)((x1-x0+1)*cell_size) + 2 * (int)((y1-y0+1)*cell_size); \n}\n\nvector<pair<int,int>> makeLShapePolygon(const Rect& main, const Rect& att, int attach_dir, double cell_size) {\n    // attach_dir: 0=left, 1=bottom, 2=right, 3=top\n    // Counterclockwise.\n    int x0 = int(lround(main.x0 * cell_size));\n    int x1 = int(lround((main.x1+1) * cell_size - 1));\n    int y0 = int(lround(main.y0 * cell_size));\n    int y1 = int(lround((main.y1+1) * cell_size - 1));\n    int ax0 = int(lround(att.x0 * cell_size));\n    int ax1 = int(lround((att.x1+1) * cell_size - 1));\n    int ay0 = int(lround(att.y0 * cell_size));\n    int ay1 = int(lround((att.y1+1) * cell_size - 1));\n    vector<pair<int,int>> v;\n    if (attach_dir == 0) {\n        v.push_back({ax0, ay0});\n        v.push_back({ax0, ay1});\n        v.push_back({x0, ay1});\n        v.push_back({x0, y1});\n        v.push_back({x1, y1});\n        v.push_back({x1, y0});\n        v.push_back({x0, y0});\n        v.push_back({ax0, y0});\n    } else if (attach_dir == 1) {\n        v.push_back({ax0, ay0});\n        v.push_back({ax1, ay0});\n        v.push_back({ax1, y0});\n        v.push_back({x1, y0});\n        v.push_back({x1, y1});\n        v.push_back({x0, y1});\n        v.push_back({x0, y0});\n        v.push_back({ax0, y0});\n    } else if (attach_dir == 2) {\n        v.push_back({x0, y0});\n        v.push_back({x0, y1});\n        v.push_back({x1, y1});\n        v.push_back({ax1, y1});\n        v.push_back({ax1, ay1});\n        v.push_back({ax1, ay0});\n        v.push_back({x1, ay0});\n        v.push_back({x1, y0});\n    } else if (attach_dir == 3) {\n        v.push_back({x0, y0});\n        v.push_back({x0, y1});\n        v.push_back({ax0, y1});\n        v.push_back({ax0, ay1});\n        v.push_back({ax1, ay1});\n        v.push_back({ax1, y1});\n        v.push_back({x1, y1});\n        v.push_back({x1, y0});\n    }\n    // Remove sequential duplicates (maybe not needed)\n    vector<pair<int,int>> clean;\n    for (int i=0; i<(int)v.size(); ++i) if (i==0 || v[i]!=v[i-1]) clean.push_back(v[i]);\n    if (!clean.empty() && clean[0] == clean.back()) clean.pop_back();\n    return clean;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    cin >> N;\n    vector<pair<int, int>> mackerels(N), sardines(N);\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n        mackerels[i] = {x, y};\n    }\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n        sardines[i] = {x, y};\n    }\n\n    double cell_size = (double)FIELD / GRID;\n    auto cell = [&](int x, int y) -> pair<int, int> {\n        int cx = min(GRID-1, int(x / cell_size));\n        int cy = min(GRID-1, int(y / cell_size));\n        return {cx, cy};\n    };\n\n    vector<vector<int>> mac_grid(GRID, vector<int>(GRID, 0)), sar_grid(GRID, vector<int>(GRID, 0));\n    for (auto [x,y]: mackerels) {\n        auto [cx,cy] = cell(x,y);\n        mac_grid[cx][cy] += 1;\n    }\n    for (auto [x,y]: sardines) {\n        auto [cx,cy] = cell(x,y);\n        sar_grid[cx][cy] += 1;\n    }\n    vector<vector<int>> mac_sum(GRID+1, vector<int>(GRID+1)), sar_sum(GRID+1, vector<int>(GRID+1));\n    for (int i = 0; i < GRID; ++i) for (int j = 0; j < GRID; ++j) {\n        mac_sum[i+1][j+1] = mac_grid[i][j] + mac_sum[i+1][j] + mac_sum[i][j+1] - mac_sum[i][j];\n        sar_sum[i+1][j+1] = sar_grid[i][j] + sar_sum[i+1][j] + sar_sum[i][j+1] - sar_sum[i][j];\n    }\n    auto rect_sum = [&](int x0,int y0,int x1,int y1, const auto& sum) {\n        return sum[x1+1][y1+1] - sum[x0][y1+1] - sum[x1+1][y0] + sum[x0][y0];\n    };\n\n    int rmin = 4, rmax = 20;\n    Rect main{-1,-1,-1,-1,0,0,0,0};\n    for (int dx = rmin; dx <= rmax; dx += 2) {\n        for (int dy = rmin; dy <= rmax; dy += 2) {\n            for (int x0=0; x0+dx-1<GRID; x0+=max(1,dx/3)) {\n                int x1 = x0+dx-1;\n                for (int y0=0; y0+dy-1<GRID; y0+=max(1,dy/3)) {\n                    int y1=y0+dy-1;\n                    int a = rect_sum(x0,y0,x1,y1,mac_sum);\n                    int b = rect_sum(x0,y0,x1,y1,sar_sum);\n                    int score = a-b+1;\n                    int perim = 2*(int)((x1-x0+1)*cell_size) + 2*(int)((y1-y0+1)*cell_size);\n                    if (score <= 0 || perim > MAX_PERIM) continue;\n                    Rect r = {x0,y0,x1,y1,a,b,perim,score};\n                    if (main.score < r.score || (main.score == r.score && r.perim < main.perim)) main = r;\n                }\n            }\n        }\n    }\n\n    // Greedy expansion of main rectangle\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        vector<tuple<int,int,int,int>> deltas = {\n            {-1,0,0,0},    // left\n            {0,-1,0,0},    // bottom\n            {0,0,1,0},     // right\n            {0,0,0,1}      // top\n        };\n        for (auto [dlx,dly,drx,dry] : deltas) {\n            int nx0=main.x0+dlx, ny0=main.y0+dly, nx1=main.x1+drx, ny1=main.y1+dry;\n            if(nx0<0 || ny0<0 || nx1>=GRID || ny1>=GRID || nx0>nx1 || ny0>ny1) continue;\n            int a=rect_sum(nx0,ny0,nx1,ny1,mac_sum);\n            int b=rect_sum(nx0,ny0,nx1,ny1,sar_sum);\n            int score=a-b+1;\n            int perim = 2*(int)((nx1-nx0+1)*cell_size) + 2*(int)((ny1-ny0+1)*cell_size);\n            if (score > main.score && perim <= MAX_PERIM) {\n                main = {nx0,ny0,nx1,ny1,a,b,perim,score};\n                improved = true;\n                break;\n            }\n        }\n    }\n\n    // Try to add a \"notch\" (attach rectangle) to the main rectangle for L-shape\n    Rect best_att{-1,-1,-1,-1,0,0,0,0};\n    int best_dir = -1;\n    int best_score = main.score;\n\n    // For each direction, search for best attachment\n    for (int dir=0; dir<4; ++dir) {\n        int base_x0 = main.x0, base_y0 = main.y0, base_x1 = main.x1, base_y1 = main.y1;\n        for (int span1 = 2; span1 <= 14; ++span1) {\n            for (int span2 = 2; span2 <= 14; ++span2) {\n                int ax0, ay0, ax1, ay1;\n                if (dir == 0 && main.x0 - span1 >= 0) { // left\n                    ax0 = main.x0 - span1; ax1 = main.x0 - 1;\n                    for (int ylo = base_y0; ylo <= base_y1 - span2 + 1; ++ylo) {\n                        ay0 = ylo, ay1 = ylo + span2 - 1;\n                        int a = rect_sum(ax0, ay0, ax1, ay1, mac_sum);\n                        int b = rect_sum(ax0, ay0, ax1, ay1, sar_sum);\n                        if (a==0) continue;\n                        int att_score = main.a + a - (main.b + b) + 1;\n                        int minx = min(main.x0, ax0), maxx = max(main.x1, ax1);\n                        int miny = min(main.y0, ay0), maxy = max(main.y1, ay1);\n                        int perim = full_perim(minx, miny, maxx, maxy, cell_size);\n                        if (att_score > best_score && perim <= MAX_PERIM) {\n                            best_score = att_score;\n                            best_att = {ax0, ay0, ax1, ay1, a, b, 0, att_score};\n                            best_dir = dir;\n                        }\n                    }\n                } else if (dir == 1 && main.y0 - span1 >= 0) { // bottom\n                    ay0 = main.y0 - span1; ay1 = main.y0 - 1;\n                    for (int xlo = base_x0; xlo <= base_x1 - span2 + 1; ++xlo) {\n                        ax0 = xlo, ax1 = xlo + span2 - 1;\n                        int a = rect_sum(ax0, ay0, ax1, ay1, mac_sum);\n                        int b = rect_sum(ax0, ay0, ax1, ay1, sar_sum);\n                        if(a==0) continue;\n                        int att_score = main.a + a - (main.b + b) + 1;\n                        int minx = min(main.x0, ax0), maxx = max(main.x1, ax1);\n                        int miny = min(main.y0, ay0), maxy = max(main.y1, ay1);\n                        int perim = full_perim(minx, miny, maxx, maxy, cell_size);\n                        if (att_score > best_score && perim <= MAX_PERIM) {\n                            best_score = att_score;\n                            best_att = {ax0, ay0, ax1, ay1, a, b, 0, att_score};\n                            best_dir = dir;\n                        }\n                    }\n                } else if (dir == 2 && main.x1 + span1 < GRID) { // right\n                    ax0 = main.x1 + 1; ax1 = main.x1 + span1;\n                    for (int ylo = base_y0; ylo <= base_y1 - span2 + 1; ++ylo) {\n                        ay0 = ylo, ay1 = ylo + span2 - 1;\n                        int a = rect_sum(ax0, ay0, ax1, ay1, mac_sum);\n                        int b = rect_sum(ax0, ay0, ax1, ay1, sar_sum);\n                        if(a==0) continue;\n                        int att_score = main.a + a - (main.b + b) + 1;\n                        int minx = min(main.x0, ax0), maxx = max(main.x1, ax1);\n                        int miny = min(main.y0, ay0), maxy = max(main.y1, ay1);\n                        int perim = full_perim(minx, miny, maxx, maxy, cell_size);\n                        if (att_score > best_score && perim <= MAX_PERIM) {\n                            best_score = att_score;\n                            best_att = {ax0, ay0, ax1, ay1, a, b, 0, att_score};\n                            best_dir = dir;\n                        }\n                    }\n                } else if (dir == 3 && main.y1 + span1 < GRID) { // top\n                    ay0 = main.y1 + 1; ay1 = main.y1 + span1;\n                    for (int xlo = base_x0; xlo <= base_x1 - span2 + 1; ++xlo) {\n                        ax0 = xlo, ax1 = xlo + span2 - 1;\n                        int a = rect_sum(ax0, ay0, ax1, ay1, mac_sum);\n                        int b = rect_sum(ax0, ay0, ax1, ay1, sar_sum);\n                        if(a==0) continue;\n                        int att_score = main.a + a - (main.b + b) + 1;\n                        int minx = min(main.x0, ax0), maxx = max(main.x1, ax1);\n                        int miny = min(main.y0, ay0), maxy = max(main.y1, ay1);\n                        int perim = full_perim(minx, miny, maxx, maxy, cell_size);\n                        if (att_score > best_score && perim <= MAX_PERIM) {\n                            best_score = att_score;\n                            best_att = {ax0, ay0, ax1, ay1, a, b, 0, att_score};\n                            best_dir = dir;\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    if (best_dir == -1) {\n        // Just output expanded rectangle, as before\n        int xLB = int(lround(main.x0 * cell_size));\n        int xRT = int(lround((main.x1+1) * cell_size - 1));\n        int yLB = int(lround(main.y0 * cell_size));\n        int yRT = int(lround((main.y1+1) * cell_size - 1));\n        vector<pair<int,int>> corners = {\n            {xLB, yLB},\n            {xLB, yRT},\n            {xRT, yRT},\n            {xRT, yLB}\n        };\n        cout << 4 << '\\n';\n        for(auto [x, y] : corners) cout << x << ' ' << y << '\\n';\n    } else {\n        auto poly = makeLShapePolygon(main, best_att, best_dir, cell_size);\n        cout << poly.size() << '\\n';\n        for (auto [x,y] : poly)\n            cout << x << \" \" << y << '\\n';\n    }\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\nstruct Timer { chrono::steady_clock::time_point st;\n    Timer() : st(chrono::steady_clock::now()) {}\n    double elapsed() const { return chrono::duration<double>(chrono::steady_clock::now()-st).count(); }\n};\nstruct Rect { int idx, w, h; };\nstruct Placement { int p,r; char d; int b; Placement(int p,int r,char d,int b):p(p),r(r),d(d),b(b){} };\nstruct PlacedRect { int idx,x,y,w,h; };\nbool overlap(const PlacedRect &a,const PlacedRect &b){\n    return !(a.x+a.w<=b.x || b.x+b.w<=a.x || a.y+a.h<=b.y || b.y+b.h<=a.y);\n}\nstruct PkgResult { vector<Placement>sol; int score; vector<int>skipped; int boxw, boxh; };\n\nPkgResult best_bl_rotK(const vector<Rect>& rects, const vector<int>& mask, const vector<int>& skipped, int mode=0, int meanArea=0, int K=3) {\n    // Try all 2^K rotation patterns for first K rectangles (default: K=3)\n    int n=mask.size();\n    int best_total=INT_MAX;\n    vector<Placement>bestres;\n    int bestw=0, besth=0;\n    vector<int>tmp_mask(mask);\n\n    int limit = min(K, n);\n    for(int rot=0; rot<(1<<limit); ++rot){\n        vector<Placement>res; vector<PlacedRect>placed;\n        int box_w=0, box_h=0;\n        for(int iidx=0; iidx<n; ++iidx){\n            int i=mask[iidx], best_r=0, best_b=-1; char best_d='U'; int best_x=-1, best_y=-1; long long min_score=LLONG_MAX;\n            int rstart = (iidx<limit ? ((rot>>iidx)&1) : -1);\n            for(int r=0; r<2; ++r){\n                if(rstart!=-1 && r!=rstart) continue;\n                int wi = (r==0?rects[i].w:rects[i].h), hi = (r==0?rects[i].h:rects[i].w);\n                for(char d:{'U','L'}){\n                    vector<int>baseidx={-1}; for(int b=0;b<(int)placed.size();++b)baseidx.push_back(b);\n                    for(int b:baseidx){\n                        int x=0,y=0;\n                        if(d=='U'){ x=(b==-1)?0:placed[b].x; int my=0;\n                            for(auto&rpr:placed){\n                                if(b!=-1&&rpr.idx==placed[b].idx)continue;\n                                int l=max(x,rpr.x), rht=min(x+wi,rpr.x+rpr.w);\n                                if(l<rht)my=max(my,rpr.y+rpr.h);} y=my;\n                        }else{ y=(b==-1)?0:placed[b].y; int mx=0;\n                            for(auto&rpr:placed){\n                                if(b!=-1&&rpr.idx==placed[b].idx)continue;\n                                int t=max(y,rpr.y),bt=min(y+hi,rpr.y+rpr.h);\n                                if(t<bt)mx=max(mx,rpr.x+rpr.w);} x=mx;\n                        }\n                        if(x<0||y<0)continue; PlacedRect test{i,x,y,wi,hi}; bool ok=1;\n                        for(auto&pr:placed)if(overlap(pr,test)){ok=0;break;}\n                        if(!ok)continue;\n                        int bxw=max(box_w,x+wi), bxh=max(box_h,y+hi);\n                        long long score;\n                        if(mode==0) score = bxw+bxh;\n                        else if(mode==1) score = 1LL*bxw*bxh;\n                        else score = bxw+bxh + 1LL*bxw*bxh/(rects.size()?rects.size():(int)1);\n                        long long tie = (long long)y*1000000 + x;\n                        if(score<min_score || (score==min_score && tie<(long long)best_y*1000000+best_x)){\n                            min_score=score; best_r=r; best_d=d; best_b=b; best_x=x; best_y=y;\n                        }\n                    }\n                }\n            }\n            if(best_x==-1)best_r=0,best_d='U',best_b=-1,best_x=box_w,best_y=0;\n            res.emplace_back(rects[i].idx,best_r,best_d,(best_b==-1?-1:placed[best_b].idx));\n            int wi=(best_r==0?rects[i].w:rects[i].h), hi=(best_r==0?rects[i].h:rects[i].w);\n            placed.push_back({rects[i].idx,best_x,best_y,wi,hi});\n            box_w=max(box_w,best_x+wi); box_h=max(box_h,best_y+hi);\n        }\n        int total=box_w+box_h; for(int i:skipped) total+=rects[i].w+rects[i].h;\n        if(total<best_total){ best_total=total; bestres=res; bestw=box_w; besth=box_h; }\n    }\n    return {bestres,best_total,skipped,bestw,besth};\n}\n\nint main(){\n    ios::sync_with_stdio(0); cin.tie(0);\n    int N,T,sigma; cin>>N>>T>>sigma;\n    vector<Rect>rects(N); for(int i=0;i<N;++i){int w,h; cin>>w>>h; rects[i]={i,w,h};}\n    Timer timer;\n    int meanArea = 1;\n    vector<int>all(N); iota(all.begin(),all.end(),0);\n    vector<PkgResult>soups;\n    for(int m=0;m<2;++m) soups.push_back(best_bl_rotK(rects, all, {}, m, meanArea, 3));\n    vector<pair<int,int>>skip1_scores;\n    int base0 = soups[0].score;\n    for(int i=0;i<N;++i){\n        vector<int>mask; for(int j=0;j<N;++j) if(i!=j)mask.push_back(j);\n        auto r=best_bl_rotK(rects,mask,{i},0,meanArea,3);\n        skip1_scores.emplace_back(base0-r.score,i); soups.push_back(r);\n        if(timer.elapsed()>2.0)break;\n    }\n    sort(skip1_scores.begin(),skip1_scores.end(),greater<>());\n    for(int k=0;k<min(4,N);++k){\n        int i=skip1_scores[k].second;\n        vector<int>mask; for(int j=0;j<N;++j) if(i!=j)mask.push_back(j);\n        soups.push_back(best_bl_rotK(rects,mask,{i},1,meanArea,3));\n        if(timer.elapsed()>2.13)break;\n    }\n    int skip2_max=(N>50?3:7), tried2=0;\n    vector<tuple<int,int,int>>beam_candidates;\n    for(int a=0;a<min(7,(int)skip1_scores.size());++a){\n        int i=skip1_scores[a].second;\n        for(int b=a+1;b<min(12,(int)skip1_scores.size());++b){\n            int j=skip1_scores[b].second;\n            if(i==j)continue;\n            vector<int>mask; for(int q=0;q<N;++q) if(q!=i&&q!=j)mask.push_back(q);\n            auto ret=best_bl_rotK(rects,mask,{i,j},0,meanArea,3);\n            soups.push_back(ret);\n            beam_candidates.push_back({ret.score,i,j});\n            if(++tried2>=skip2_max||timer.elapsed()>2.27)break;\n        }\n        if(timer.elapsed()>2.27)break;\n    }\n    if(N<=35 && timer.elapsed()<2.3){\n        sort(beam_candidates.begin(),beam_candidates.end());\n        int beam=0,beam_max=3;\n        for(auto& tpl: beam_candidates){\n            int i=get<1>(tpl),j=get<2>(tpl);\n            for(int k=0;k<N;++k) if(k!=i&&k!=j) {\n                vector<int>mask; for(int q=0;q<N;++q) if(q!=i&&q!=j&&q!=k)mask.push_back(q);\n                soups.push_back(best_bl_rotK(rects,mask,{i,j,k},0,meanArea,3));\n                if(++beam>=beam_max||timer.elapsed()>2.43)break;\n            }\n            if(timer.elapsed()>2.43)break;\n        }\n    }\n    mt19937 rng(1234+N*5555);\n    for(int st=0;st<min(6,N/2);++st){\n        int i=rng()%N, j=rng()%N; while(j==i)j=rng()%N;\n        vector<int>mask; for(int q=0;q<N;++q) if(q!=i&&q!=j)mask.push_back(q);\n        soups.push_back(best_bl_rotK(rects,mask,{i,j},0,meanArea,3));\n        if(timer.elapsed()>2.6)break;\n    }\n    int T_prep = min((int)soups.size(),T), besti=0, bestv=INT_MAX;\n    for(int i=0;i<T_prep;++i)if(soups[i].score<bestv){bestv=soups[i].score;besti=i;}\n    for(int t=0;t<T;++t){\n        int use = t<T_prep?t:besti;\n        auto&r=soups[use];\n        cout<<r.sol.size()<<'\\n';\n        for(auto&pl:r.sol)cout<<pl.p<<' '<<pl.r<<' '<<pl.d<<' '<<pl.b<<'\\n';\n        cout<<flush;\n        int W,H;cin>>W>>H;\n    }\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Calculate per-node \"potential\" (sum of A within 2 hops)\nvector<int> compute_potential(const vector<vector<int>>& adj, const vector<int>& A) {\n    int N = A.size();\n    vector<int> pot(N, 0);\n    for(int v=0; v<N; ++v) {\n        set<int> seen = {v};\n        int cur_sum = A[v];\n        for(int nb: adj[v]) {\n            seen.insert(nb); cur_sum += A[nb];\n        }\n        for(int nb: adj[v]) for(int nb2: adj[nb]) if (seen.insert(nb2).second) cur_sum += A[nb2];\n        pot[v] = cur_sum;\n    }\n    return pot;\n}\n\nvoid expand_tree(const vector<vector<int>>& adj, const vector<int>& A, int H, bool dfs_mode,\n    vector<int>& parent, vector<int>& depth, vector<bool>& assigned, int v, mt19937& rng)\n{\n    parent[v] = -1;\n    depth[v] = 0;\n    assigned[v] = true;\n    if (!dfs_mode) {\n        queue<pair<int, int>> q;\n        q.emplace(v, 0);\n        while (!q.empty()) {\n            auto [cur, d] = q.front(); q.pop();\n            if (d == H) continue;\n            vector<pair<int, int>> nbrs;\n            for (int nb : adj[cur]) if (!assigned[nb]) nbrs.emplace_back(A[nb], nb); // by beauty\n            shuffle(nbrs.begin(), nbrs.end(), rng); // tiebreak\n            sort(nbrs.rbegin(), nbrs.rend());\n            for (auto& [aval, nb] : nbrs) if (!assigned[nb]) {\n                parent[nb] = cur;\n                depth[nb] = d + 1;\n                assigned[nb] = true;\n                q.emplace(nb, d + 1);\n            }\n        }\n    } else {\n        stack<pair<int, int>> q;\n        q.emplace(v, 0);\n        while (!q.empty()) {\n            auto [cur, d] = q.top(); q.pop();\n            if (d == H) continue;\n            vector<pair<int, int>> nbrs;\n            for (int nb : adj[cur]) if (!assigned[nb]) nbrs.emplace_back(A[nb], nb);\n            shuffle(nbrs.begin(), nbrs.end(), rng);\n            sort(nbrs.rbegin(), nbrs.rend());\n            for (auto& [aval, nb] : nbrs) if (!assigned[nb]) {\n                parent[nb] = cur;\n                depth[nb] = d + 1;\n                assigned[nb] = true;\n                q.emplace(nb, d + 1);\n            }\n        }\n    }\n}\n\nlong long calc_score(const vector<int>& A, const vector<int>& depth) {\n    long long s = 0;\n    for(size_t i = 0; i < A.size(); ++i) s += 1LL * (depth[i] + 1) * A[i];\n    return s;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, H;\n    cin >> N >> M >> H;\n    vector<int> A(N);\n    int A_xor = 0;\n    for (auto& x : A) { cin >> x; A_xor ^= x; }\n    vector<vector<int>> adj(N);\n    int coord_xor = 0;\n    for (int i = 0; i < M; ++i) {\n        int u, v; cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n        coord_xor ^= u * 137 + v * 271;\n    }\n    int coord_sum = 0;\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n        coord_sum += x + y;\n    }\n    // Per-test seed for deterministic behavior per testcase\n    mt19937 rng(7919LL * A_xor + 3571LL * coord_xor + 11939LL * coord_sum);\n\n    // Prepare root orders\n    vector<vector<int>> root_orders;\n\n    // 1. Descending A\n    vector<int> by_A(N);\n    iota(by_A.begin(), by_A.end(), 0);\n    sort(by_A.begin(), by_A.end(), [&](int i, int j){ return A[i] > A[j]; });\n    root_orders.push_back(by_A);\n\n    // 2. Ascending A\n    vector<int> by_Ar = by_A; reverse(by_Ar.begin(), by_Ar.end());\n    root_orders.push_back(by_Ar);\n\n    // 3. k random orders\n    int k_rand_roots = 16; // Increase for CPU allowance\n    for (int r = 0; r < k_rand_roots; ++r) {\n        vector<int> ord = by_A;\n        shuffle(ord.begin(), ord.end(), rng);\n        root_orders.push_back(ord);\n    }\n\n    // 4. Potential-based orderings (sum of beauty in 2 hops)\n    vector<int> pot = compute_potential(adj, A);\n    vector<int> by_pot(N);\n    iota(by_pot.begin(), by_pot.end(), 0);\n    sort(by_pot.begin(), by_pot.end(), [&](int i, int j){ return pot[i] > pot[j]; });\n    root_orders.push_back(by_pot);\n    vector<int> by_potr = by_pot; reverse(by_potr.begin(), by_potr.end());\n    root_orders.push_back(by_potr);\n\n    // Try each, BFS & DFS + shuffled tie breaks, keep best\n    long long best_score = -1;\n    vector<int> best_parent(N, -1);\n\n    for (auto& cur_order : root_orders) {\n        for (int dfs = 0; dfs <= 1; ++dfs) {\n            vector<int> parent(N, -1), depth(N, -1);\n            vector<bool> assigned(N, false);\n            for (int idx = 0; idx < N; ++idx) {\n                int v = cur_order[idx];\n                if (!assigned[v]) expand_tree(adj, A, H, dfs, parent, depth, assigned, v, rng);\n            }\n            long long sc = calc_score(A, depth);\n            if (sc > best_score) {\n                best_score = sc;\n                best_parent = parent;\n            }\n        }\n    }\n    for (int i = 0; i < N; ++i)\n        cout << best_parent[i] << (i + 1 == N ? '\\n' : ' ');\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\n// For each Oni, find a safe direction in the initial board and output shift sequence\n// Don't update the board as Oni are \"removed\" -- just as per the guarantee\n\nstruct Move {\n    char dir;\n    int idx;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N;\n    cin >> N;\n    vector<string> board(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> board[i];\n    }\n\n    // Save Oni positions at start\n    vector<pair<int,int>> onis;\n    for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j)\n        if (board[i][j] == 'x') onis.emplace_back(i,j);\n\n    vector<Move> moves;\n\n    // For safety, mark direction per Oni before generating commands\n    // Board is NOT mutated!\n    for (auto [i, j] : onis) {\n        // Try all 4 directions in the initial board\n        // Up (remove by shifting col up i+1 times)\n        bool upSafe = true;\n        for (int k = 0; k < i; ++k) if (board[k][j] == 'o') { upSafe = false; break; }\n\n        // Down\n        bool downSafe = true;\n        for (int k = i+1; k < N; ++k) if (board[k][j] == 'o') { downSafe = false; break; }\n\n        // Left\n        bool leftSafe = true;\n        for (int k = 0; k < j; ++k) if (board[i][k] == 'o') { leftSafe = false; break; }\n\n        // Right\n        bool rightSafe = true;\n        for (int k = j+1; k < N; ++k) if (board[i][k] == 'o') { rightSafe = false; break; }\n\n        // Remove Oni at (i,j) by safe direction and undo\n        if (upSafe) {\n            // Shift col j up i+1 times, then down i times\n            for (int t = 0; t < i+1; ++t)\n                moves.push_back({'U', j});\n            for (int t = 0; t < i; ++t)\n                moves.push_back({'D', j});\n            continue;\n        }\n        if (downSafe) {\n            // Shift col j down N-i times, then up N-i-1 times\n            for (int t = 0; t < N-i; ++t)\n                moves.push_back({'D', j});\n            for (int t = 0; t < N-i-1; ++t)\n                moves.push_back({'U', j});\n            continue;\n        }\n        if (leftSafe) {\n            // Shift row i left j+1 times, then right j times\n            for (int t = 0; t < j+1; ++t)\n                moves.push_back({'L', i});\n            for (int t = 0; t < j; ++t)\n                moves.push_back({'R', i});\n            continue;\n        }\n        if (rightSafe) {\n            // Shift row i right N-j times, then left N-j-1 times\n            for (int t = 0; t < N-j; ++t)\n                moves.push_back({'R', i});\n            for (int t = 0; t < N-j-1; ++t)\n                moves.push_back({'L', i});\n            continue;\n        }\n        // If this point is reached, the guarantee is violated (shouldn't happen)\n        cerr << \"No safe direction for Oni at (\" << i << \",\" << j << \") in initial board\\n\";\n        assert(false);\n    }\n\n    for (auto &mv : moves) {\n        cout << mv.dir << ' ' << mv.idx << '\\n';\n    }\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\n// Constants\nconstexpr int N = 100;\nconstexpr int L = 500000;\n\nint T[N];\nint a[N], b[N];\n\n// Estimate frequencies by fast simulation, possibly multiple starts to break short cycles\nvector<double> estimate_freq(const int a[N], const int b[N], int steps = 100000) {\n    vector<double> freq(N, 0.0);\n    int repeat = 3;\n    for(int starter = 0; starter < repeat; ++starter) {\n        vector<int> count(N, 0);\n        int cur = starter % N;\n        vector<int> visited(N, 0);\n        count[cur]++;\n        visited[cur]=1;\n        for(int step = 1; step < steps; ++step) {\n            int occ = count[cur];\n            int nxt = (occ % 2 == 1) ? a[cur] : b[cur];\n            cur = nxt;\n            count[cur]++;\n            visited[cur]=1;\n        }\n        // Ignore nodes never visited in this segment\n        int sm = 0;\n        for(int i=0; i<N; ++i) sm += count[i];\n        for(int i=0; i<N; ++i) freq[i] += double(count[i])/repeat;\n    }\n    // Normalize for steps\n    double tot = accumulate(freq.begin(), freq.end(), 0.0);\n    for(int i=0; i<N; ++i) freq[i] /= tot;\n    return freq;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    int n, l;\n    cin >> n >> l;\n    for(int i=0; i<N; ++i) cin >> T[i];\n\n    // STEP 1: Initial assignment, degree-proportional assignment\n    // Calculate quotas\n    vector<pair<double,int>> q;\n    for(int i=0; i<N; ++i) \n        q.emplace_back((double)T[i]/L,i);\n    sort(q.rbegin(),q.rend());\n\n    // Distribute incoming edges roughly according to quota\n    vector<int> indeg(N,0);\n    for(int i=0; i<N; ++i) {\n        set<int> pickset;\n        while(pickset.size() < 2) {\n            // Weighted selection\n            int idx = 0;\n            double sel = double(rand())/RAND_MAX;\n            double s = 0;\n            for(auto& [p,j]: q) {\n                s += p;\n                if(sel<=s && j!=i) { idx=j; break;}\n            }\n            if(idx==i || pickset.count(idx)) continue;\n            pickset.insert(idx);\n        }\n        auto it = pickset.begin();\n        a[i]=*it++;\n        b[i]=*it;\n        indeg[a[i]]++; indeg[b[i]]++;\n    }\n    \n    // Minor fix to remove self-loops\n    for(int i=0; i<N; ++i) {\n        if(a[i]==i || b[i]==i) {\n            int other = a[i]==i ? b[i] : a[i];\n            for(int j=0;j<N;++j) {\n                if(j!=i && a[j]!=i && b[j]!=i && a[j]!=b[j]) {\n                    if(a[i]==i) a[i]=j; else b[i]=j;\n                    break;\n                }\n            }\n        }\n    }\n\n    // Main tuning\n    auto start_time = chrono::steady_clock::now();\n    const double TIME_LIMIT = 1.8;\n\n    // Prepare fast random engine\n    mt19937 rng(123456);\n\n    // Run iterative rebalancing and local search\n    int loopct = 0;\n    double best_error = 1e18;\n    int best_a[N], best_b[N];\n    memcpy(best_a,a,sizeof(a));\n    memcpy(best_b,b,sizeof(b));\n    vector<double> best_freq;\n    while(true) {\n        ++loopct;\n        // Estimate freq\n        auto freq = estimate_freq(a,b,350000);\n        // Compute actual t_i\n        double score = 0;\n        for(int i=0;i<N;++i) score += abs(freq[i]*L-T[i]);\n        if(score < best_error) {\n            best_error = score;\n            memcpy(best_a,a,sizeof(a));\n            memcpy(best_b,b,sizeof(b));\n            best_freq = freq;\n        }\n        // Check time\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if(elapsed > TIME_LIMIT) break;\n\n        // Find most over/under assigned\n        int over=-1, under=-1;\n        double max_over=0, max_under=0;\n        for(int i=0;i<N;++i) {\n            double diff = freq[i]*L - T[i];\n            if(diff > max_over) { max_over = diff; over = i; }\n            if(diff < max_under) { max_under = diff; under = i; }\n        }\n        if(over == -1 || under == -1) break; // (Actually perfect)\n\n        // Try to reroute some edges from over to under\n        bool changed = false;\n        // Try changing some a_j or b_j that point to 'over'\n        vector<int> candidates;\n        for(int j=0;j<N;++j) if(a[j]==over || b[j]==over) candidates.push_back(j);\n        shuffle(candidates.begin(),candidates.end(),rng);\n        for(int cand: candidates) {\n            if(a[cand]==over && under!=cand) {\n                int old=a[cand]; a[cand]=under;\n                auto f2=estimate_freq(a,b,50000);\n                double s2 = 0;\n                for(int i=0;i<N;++i) s2 += abs(f2[i]*L-T[i]);\n                if(s2 < score) { changed=true; break;}\n                a[cand]=old;\n            }\n            if(b[cand]==over && under!=cand) {\n                int old=b[cand]; b[cand]=under;\n                auto f2=estimate_freq(a,b,50000);\n                double s2 = 0;\n                for(int i=0;i<N;++i) s2 += abs(f2[i]*L-T[i]);\n                if(s2 < score) { changed=true; break;}\n                b[cand]=old;\n            }\n        }\n        if(!changed) {\n            // As fallback, random swap for diversity\n            int i = rng()%N;\n            int pos = rng()%2;\n            int nv = rng()%N;\n            if(nv==i) continue;\n            if(pos==0) a[i]=nv; else b[i]=nv;\n        }\n    }\n    // Output\n    for(int i=0; i<N; ++i) \n        cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct City {\n    int id;\n    int lx, rx, ly, ry;\n    double cx, cy;\n};\n\nstruct UF {\n    vector<int> par;\n    UF(int n) : par(n) { iota(par.begin(), par.end(), 0); }\n    int find(int x) {\n        if (par[x] == x) return x;\n        return par[x] = find(par[x]);\n    }\n    bool unite(int x, int y) {\n        int rx = find(x), ry = find(y);\n        if (rx == ry) return false;\n        par[ry] = rx; return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, Q, L, W;\n    cin >> N >> M >> Q >> L >> W;\n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n\n    vector<City> cities(N);\n    for (int i = 0; i < N; ++i) {\n        int lx, rx, ly, ry;\n        cin >> lx >> rx >> ly >> ry;\n        cities[i] = {i, lx, rx, ly, ry, 0.5 * (lx + rx), 0.5 * (ly + ry)};\n    }\n\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int i, int j) {\n        if (abs(cities[i].cx - cities[j].cx) > 1e-6)\n            return cities[i].cx < cities[j].cx;\n        return cities[i].cy < cities[j].cy;\n    });\n\n    vector<vector<int>> groups;\n    int ofs = 0;\n    for (int i = 0; i < M; ++i) {\n        vector<int> grp;\n        for (int k = 0; k < G[i]; ++k, ++ofs)\n            grp.push_back(idx[ofs]);\n        groups.push_back(grp);\n    }\n\n    vector<vector<pair<int, int>>> all_edges(M);\n\n    int queries_used = 0;\n    for (int gi = 0; gi < M; ++gi) {\n        const auto& grp = groups[gi];\n        int sz = grp.size();\n        set<pair<int, int>> group_edges;\n\n        if (sz == 1) {\n            // No edge required for single-node group.\n        } else if (sz <= L && queries_used < Q) {\n            cout << \"? \" << sz;\n            for (int x : grp) cout << \" \" << x;\n            cout << endl; cout.flush();\n            for (int i = 0; i < sz - 1; ++i) {\n                int u, v;\n                cin >> u >> v;\n                if (u > v) swap(u, v);\n                group_edges.emplace(u, v);\n            }\n            ++queries_used;\n        } else {\n            for (int st = 0; st < sz && queries_used < Q; st += (L - 1)) {\n                int en = min(sz, st + L);\n                int actual = en - st;\n                if (actual < 2) continue;\n                vector<int> subset(grp.begin() + st, grp.begin() + en);\n                unordered_set<int> subset_set(subset.begin(), subset.end());\n                cout << \"? \" << actual;\n                for (int x : subset) cout << \" \" << x;\n                cout << endl; cout.flush();\n                for (int i = 0; i < actual - 1; ++i) {\n                    int u, v;\n                    cin >> u >> v;\n                    if (u > v) swap(u, v);\n                    // Defensive: only add if both endpoints belong to the group\n                    if (subset_set.count(u) && subset_set.count(v)) {\n                        group_edges.emplace(u, v);\n                    }\n                }\n                ++queries_used;\n            }\n        }\n\n        // Defensive group index mapping\n        int V = sz;\n        map<int, int> city_to_groupidx;\n        for (int i = 0; i < sz; ++i)\n            city_to_groupidx[grp[i]] = i;\n\n        UF uf(V);\n        for (auto [u, v] : group_edges) {\n            auto it_u = city_to_groupidx.find(u);\n            auto it_v = city_to_groupidx.find(v);\n            if (it_u != city_to_groupidx.end() && it_v != city_to_groupidx.end()) {\n                uf.unite(it_u->second, it_v->second);\n            }\n        }\n        vector<tuple<int, int, int>> center_edges;\n        for (int i = 0; i < sz; ++i) {\n            for (int j = i + 1; j < sz; ++j) {\n                int u = grp[i], v = grp[j];\n                double dx = cities[u].cx - cities[v].cx, dy = cities[u].cy - cities[v].cy;\n                int d = (int)floor(hypot(dx, dy));\n                center_edges.emplace_back(d, i, j);\n            }\n        }\n        sort(center_edges.begin(), center_edges.end());\n        UF final_uf(V);\n        set<pair<int, int>> final_edges = group_edges;\n        for (auto [u, v] : group_edges) {\n            auto it_u = city_to_groupidx.find(u);\n            auto it_v = city_to_groupidx.find(v);\n            if (it_u != city_to_groupidx.end() && it_v != city_to_groupidx.end())\n                final_uf.unite(it_u->second, it_v->second);\n        }\n        for (auto [d, i, j] : center_edges) {\n            if ((int)final_edges.size() >= sz - 1) break;\n            if (final_uf.unite(i, j)) {\n                int u = grp[i], v = grp[j];\n                if (u > v) swap(u, v);\n                final_edges.emplace(u, v);\n            }\n        }\n        all_edges[gi].assign(final_edges.begin(), final_edges.end());\n    }\n\n    cout << \"!\" << endl;\n    for (int gi = 0; gi < M; ++gi) {\n        const auto &grp = groups[gi];\n        for (int i = 0; i < (int)grp.size(); ++i) {\n            if (i) cout << \" \";\n            cout << grp[i];\n        }\n        cout << endl;\n        for (auto [u, v] : all_edges[gi])\n            cout << u << \" \" << v << endl;\n    }\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 20, M = 40;\nconstexpr int DX[4] = {-1, 1, 0, 0}; // U D L R\nconstexpr int DY[4] = { 0, 0, -1, 1};\nconstexpr char DIRC[4] = {'U', 'D', 'L', 'R'};\n\nstruct Pos {\n    int x, y;\n    bool operator==(const Pos& o) const { return x == o.x && y == o.y; }\n};\n\nbool inRange(int x, int y) { return 0 <= x && x < N && 0 <= y && y < N; }\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n, m;\n    cin >> n >> m;\n    vector<Pos> tgt(m);\n    for (int i = 0; i < m; ++i) cin >> tgt[i].x >> tgt[i].y;\n\n    vector<vector<bool>> blocked(N, vector<bool>(N, false));\n    Pos cur = tgt[0];\n\n    for (int step = 1; step < m; ++step) {\n        Pos goal = tgt[step];\n\n        // Try greedy Slide if in the same row/col\n        bool slid = false;\n        for (int d = 0; d < 4; ++d) {\n            int dx = DX[d], dy = DY[d];\n\n            if ((dx && cur.y == goal.y && ((dx > 0 && goal.x > cur.x) || (dx < 0 && goal.x < cur.x))) ||\n                (dy && cur.x == goal.x && ((dy > 0 && goal.y > cur.y) || (dy < 0 && goal.y < cur.y)))) \n            {\n                int x = cur.x, y = cur.y;\n                bool ok = true;\n                while (x != goal.x || y != goal.y) {\n                    x += dx; y += dy;\n                    if (!inRange(x, y) || blocked[x][y]) {\n                        ok = false;\n                        break;\n                    }\n                }\n                // The cell after the goal\n                int nx = goal.x + dx, ny = goal.y + dy;\n                if (ok && (!inRange(nx, ny) || blocked[nx][ny])) {\n                    // Can slide!\n                    cout << \"S \" << DIRC[d] << \"\\n\";\n                    cur = goal;\n                    slid = true;\n                    break;\n                }\n            }\n        }\n        if (slid) continue;\n\n        // Else, fall back to step-by-step move\n        while (!(cur == goal)) {\n            int best_d = -1, best_dist = INT_MAX;\n            for (int d = 0; d < 4; ++d) {\n                int nx = cur.x + DX[d], ny = cur.y + DY[d];\n                if (!inRange(nx, ny)) continue;\n                if (blocked[nx][ny]) continue;\n                int dist = abs(nx - goal.x) + abs(ny - goal.y);\n                if (dist < best_dist) {\n                    best_dist = dist;\n                    best_d = d;\n                }\n            }\n            if (best_d == -1) break; // Should never happen\n            cur.x += DX[best_d];\n            cur.y += DY[best_d];\n            cout << \"M \" << DIRC[best_d] << \"\\n\";\n        }\n    }\n}"}}}