{"model_name":"minimax-m2.5","codes":{"1":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int x, y;          // integer coordinates of the unit square\n    int r;             // required area\n    int idx;           // original index\n};\n\nstruct Node {\n    int x1, y1, x2, y2;                // region [x1,x2) \u00d7 [y1,y2)\n    vector<int> ids;                   // indices of points inside\n};\n\nint n;\nvector<Point> pts;\nvector<Node> leafRegion;               // region for each original index\n\n/*------------------------------------------------------------------*/\n/* building the binary space partition                              */\nvoid build(Node &node) {\n    if (node.ids.size() == 1) {\n        leafRegion[ node.ids[0] ] = node;\n        return;\n    }\n\n    int W = node.x2 - node.x1;\n    int H = node.y2 - node.y1;\n    long long totalR = 0;\n    for (int id : node.ids) totalR += pts[id].r;\n\n    const long long INF = (1LL<<60);\n    long long bestDiff = INF;\n    int bestAxis = -1;          // 0 = vertical, 1 = horizontal\n    int bestK = -1;             // split coordinate\n    int bestP = -1;             // number of points on the left side\n\n    // ----- vertical splits -----\n    {\n        vector<int> v = node.ids;\n        sort(v.begin(), v.end(),\n             [&](int a, int b){ return pts[a].x < pts[b].x; });\n        vector<long long> pref(v.size()+1,0);\n        for (size_t i=0;i<v.size();++i) pref[i+1]=pref[i]+pts[v[i]].r;\n\n        for (size_t p=1;p<v.size();++p) {          // left: first p points\n            long long sumL = pref[p];\n            long long sumR = totalR - sumL;\n            int leftMaxX = pts[v[p-1]].x;\n            int k = leftMaxX + 1;                  // first column of the right part\n            if (k <= node.x1 || k >= node.x2) continue; // keep positive width\n            int wL = k - node.x1;\n            int wR = node.x2 - k;\n            long long areaL = 1LL * wL * H;\n            long long areaR = 1LL * wR * H;\n            long long diff = llabs(areaL - sumL) + llabs(areaR - sumR);\n            if (diff < bestDiff) {\n                bestDiff = diff;\n                bestAxis = 0;\n                bestK = k;\n                bestP = (int)p;\n            }\n        }\n    }\n\n    // ----- horizontal splits -----\n    {\n        vector<int> v = node.ids;\n        sort(v.begin(), v.end(),\n             [&](int a, int b){ return pts[a].y < pts[b].y; });\n        vector<long long> pref(v.size()+1,0);\n        for (size_t i=0;i<v.size();++i) pref[i+1]=pref[i]+pts[v[i]].r;\n\n        for (size_t p=1;p<v.size();++p) {\n            long long sumL = pref[p];\n            long long sumR = totalR - sumL;\n            int leftMaxY = pts[v[p-1]].y;\n            int k = leftMaxY + 1;\n            if (k <= node.y1 || k >= node.y2) continue;\n            int hL = k - node.y1;\n            int hR = node.y2 - k;\n            long long areaL = 1LL * W * hL;\n            long long areaR = 1LL * W * hR;\n            long long diff = llabs(areaL - sumL) + llabs(areaR - sumR);\n            if (diff < bestDiff) {\n                bestDiff = diff;\n                bestAxis = 1;\n                bestK = k;\n                bestP = (int)p;\n            }\n        }\n    }\n\n    // perform the chosen split\n    vector<int> leftIds, rightIds;\n    if (bestAxis == 0) {               // vertical\n        vector<int> v = node.ids;\n        sort(v.begin(), v.end(),\n             [&](int a, int b){ return pts[a].x < pts[b].x; });\n        leftIds.assign(v.begin(), v.begin()+bestP);\n        rightIds.assign(v.begin()+bestP, v.end());\n        Node L{node.x1, node.y1, bestK, node.y2, leftIds};\n        Node R{bestK, node.y1, node.x2, node.y2, rightIds};\n        build(L);\n        build(R);\n    } else {                           // horizontal\n        vector<int> v = node.ids;\n        sort(v.begin(), v.end(),\n             [&](int a, int b){ return pts[a].y < pts[b].y; });\n        leftIds.assign(v.begin(), v.begin()+bestP);\n        rightIds.assign(v.begin()+bestP, v.end());\n        Node L{node.x1, node.y1, node.x2, bestK, leftIds};\n        Node R{node.x1, bestK, node.x2, node.y2, rightIds};\n        build(L);\n        build(R);\n    }\n}\n\n/*------------------------------------------------------------------*/\n/* main                                                             */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> n;\n    pts.resize(n);\n    for (int i=0;i<n;++i) {\n        cin >> pts[i].x >> pts[i].y >> pts[i].r;\n        pts[i].idx = i;\n    }\n\n    leafRegion.assign(n, Node{0,0,0,0,{}});\n\n    // initial node\n    vector<int> allIds(n);\n    iota(allIds.begin(), allIds.end(), 0);\n    Node root{0,0,10000,10000, allIds};\n    build(root);\n\n    // place rectangles\n    vector<int> a(n), b(n), c(n), d(n);\n    long double sumP = 0.0L;\n\n    for (int i=0;i<n;++i) {\n        const Node &leaf = leafRegion[i];\n        const Point &p = pts[i];\n        int W = leaf.x2 - leaf.x1;\n        int H = leaf.y2 - leaf.y1;\n\n        int bestW = 1, bestH = 1;\n        long long bestDiff = llabs(1LL*bestW*bestH - p.r);\n\n        for (int w=1; w<=W; ++w) {\n            long long h0 = p.r / w;          // floor\n            for (int dh=0; dh<=1; ++dh) {\n                int h = (int)(h0 + dh);\n                if (h < 1 || h > H) continue;\n                long long diff = llabs(1LL*w*h - p.r);\n                if (diff < bestDiff ||\n                    (diff == bestDiff && 1LL*w*h > 1LL*bestW*bestH)) {\n                    bestDiff = diff;\n                    bestW = w;\n                    bestH = h;\n                }\n            }\n        }\n\n        // place the rectangle inside the leaf, still covering the unit square\n        int left  = max(leaf.x1, p.x + 1 - bestW);\n        int bottom = max(leaf.y1, p.y + 1 - bestH);\n        int right  = left + bestW;\n        int top    = bottom + bestH;\n\n        // safety (can be omitted)\n        //assert(right <= leaf.x2 && top <= leaf.y2);\n\n        a[i] = left; b[i] = bottom; c[i] = right; d[i] = top;\n\n        long long s = 1LL*bestW*bestH;\n        double ratio = (double)min(p.r, (int)s) / (double)max(p.r, (int)s);\n        double pi = ratio * (2.0 - ratio);\n        sumP += pi;\n    }\n\n    // output\n    for (int i=0;i<n;++i) {\n        cout << a[i] << ' ' << b[i] << ' ' << c[i] << ' ' << d[i] << '\\n';\n    }\n\n    // (the score is not required to be printed)\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    // ---------- input ----------\n    int si, sj;\n    if (!(cin >> si >> sj)) return 0;\n    const int N = 50;\n    vector<vector<int>> tile(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> tile[i][j];\n    vector<vector<int>> val(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> val[i][j];\n\n    // number of different tiles\n    int maxTileId = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            maxTileId = max(maxTileId, tile[i][j]);\n    const int M = maxTileId + 1;          // tile ids are 0 \u2026 M-1\n\n    // ---------- graph (cell -> neighbour cells of other tiles) ----------\n    const int V = N * N;\n    vector<int> cellVal(V);\n    vector<vector<int>> adj(V);\n    auto id = [&](int i, int j) { return i * N + j; };\n    const int di[4] = {-1, 1, 0, 0};\n    const int dj[4] = {0, 0, -1, 1};\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int u = id(i, j);\n            cellVal[u] = val[i][j];\n            for (int d = 0; d < 4; ++d) {\n                int ni = i + di[d], nj = j + dj[d];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                int v = id(ni, nj);\n                if (tile[ni][nj] != tile[i][j]) {\n                    adj[u].push_back(v);\n                }\n            }\n        }\n    }\n\n    const int startCell = id(si, sj);\n    const int startTile = tile[si][sj];\n\n    // ---------- helper to translate a move to a character ----------\n    auto dirChar = [&](int from, int to) -> char {\n        int fi = from / N, fj = from % N;\n        int ti = to / N, tj = to % N;\n        if (ti == fi - 1 && tj == fj) return 'U';\n        if (ti == fi + 1 && tj == fj) return 'D';\n        if (ti == fi && tj == fj - 1) return 'L';\n        if (ti == fi && tj == fj + 1) return 'R';\n        return '?'; // should never happen\n    };\n\n    // ---------- multiple random walks ----------\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    const int MAX_TRIES = 15000;          // good compromise speed / quality\n    const int RAND_PROB = 5;              // 5% chance to pick randomly\n    vector<int> visitedTile(M, 0);\n    int curToken = 1;\n\n    string bestPath;\n    int bestScore = -1;\n\n    for (int attempt = 0; attempt < MAX_TRIES; ++attempt) {\n        // new visited\u2011tile marker\n        ++curToken;\n        visitedTile[startTile] = curToken;\n\n        int cur = startCell;\n        int curScore = cellVal[cur];\n        string path;\n\n        // random heuristic parameter for this trial\n        int gamma = uniform_int_distribution<int>(0, 8)(rng);\n\n        while (true) {\n            // collect admissible neighbours\n            vector<int> cand;\n            for (int nb : adj[cur]) {\n                int ntile = tile[nb / N][nb % N];\n                if (visitedTile[ntile] != curToken) cand.push_back(nb);\n            }\n            if (cand.empty()) break;\n\n            // small chance to act completely random\n            bool randomChoice = (uniform_int_distribution<int>(0, 99)(rng) < RAND_PROB);\n\n            if (randomChoice) {\n                int idx = uniform_int_distribution<int>(0, (int)cand.size() - 1)(rng);\n                int nxt = cand[idx];\n                path.push_back(dirChar(cur, nxt));\n                cur = nxt;\n                int ntile = tile[nxt / N][nxt % N];\n                visitedTile[ntile] = curToken;\n                curScore += cellVal[nxt];\n                continue;\n            }\n\n            // evaluate heuristic for every candidate\n            int bestHeur = -1;\n            int bestNext = -1;\n            for (int nb : cand) {\n                int value = cellVal[nb];\n                // degree = number of still free neighbours after we step onto nb\n                int deg = 0;\n                int nbTile = tile[nb / N][nb % N];\n                for (int nb2 : adj[nb]) {\n                    int t2 = tile[nb2 / N][nb2 % N];\n                    if (t2 != nbTile && visitedTile[t2] != curToken) ++deg;\n                }\n                int heur = value + gamma * deg;\n                if (heur > bestHeur) {\n                    bestHeur = heur;\n                    bestNext = nb;\n                } else if (heur == bestHeur) {\n                    // tie\u2011break randomly\n                    if (rng() & 1) bestNext = nb;\n                }\n            }\n\n            // perform the chosen step\n            path.push_back(dirChar(cur, bestNext));\n            cur = bestNext;\n            int ntile = tile[cur / N][cur % N];\n            visitedTile[ntile] = curToken;\n            curScore += cellVal[cur];\n        }\n\n        if (curScore > bestScore) {\n            bestScore = curScore;\n            bestPath = path;\n        }\n    }\n\n    // ---------- output ----------\n    cout << bestPath << '\\n';\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 30;\n    const int V = N * N;\n    const double INF = 1e100;\n    const double INIT_W = 5000.0;\n    const double ALPHA = 0.2;\n    const double MIN_W = 500.0;\n    const double MAX_W = 15000.0;\n\n    // edge estimates\n    double hor[N][N-1]; // horizontal: (i,j)-(i,j+1), j = 0..28\n    double ver[N-1][N]; // vertical:   (i,j)-(i+1,j), i = 0..28\n\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N-1; ++j)\n            hor[i][j] = INIT_W;\n    for (int i = 0; i < N-1; ++i)\n        for (int j = 0; j < N; ++j)\n            ver[i][j] = INIT_W;\n\n    auto idx = [&](int i, int j) { return i * N + j; };\n\n    for (int q = 0; q < 1000; ++q) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) break;\n\n        int s = idx(si, sj);\n        int t = idx(ti, tj);\n\n        // Dijkstra\n        vector<double> dist(V, INF);\n        vector<int> prev(V, -1);\n        vector<char> move(V, 0); // direction from prev to this vertex\n        dist[s] = 0.0;\n        using Node = pair<double,int>;\n        priority_queue<Node, vector<Node>, greater<Node>> pq;\n        pq.emplace(0.0, s);\n\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u] + 1e-12) continue;\n            if (u == t) break;\n            int ui = u / N;\n            int uj = u % N;\n\n            // up\n            if (ui > 0) {\n                int v = idx(ui-1, uj);\n                double w = ver[ui-1][uj];\n                double nd = d + w;\n                if (nd + 1e-12 < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    move[v] = 'U';\n                    pq.emplace(nd, v);\n                }\n            }\n            // down\n            if (ui < N-1) {\n                int v = idx(ui+1, uj);\n                double w = ver[ui][uj];\n                double nd = d + w;\n                if (nd + 1e-12 < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    move[v] = 'D';\n                    pq.emplace(nd, v);\n                }\n            }\n            // left\n            if (uj > 0) {\n                int v = idx(ui, uj-1);\n                double w = hor[ui][uj-1];\n                double nd = d + w;\n                if (nd + 1e-12 < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    move[v] = 'L';\n                    pq.emplace(nd, v);\n                }\n            }\n            // right\n            if (uj < N-1) {\n                int v = idx(ui, uj+1);\n                double w = hor[ui][uj];\n                double nd = d + w;\n                if (nd + 1e-12 < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    move[v] = 'R';\n                    pq.emplace(nd, v);\n                }\n            }\n        }\n\n        // reconstruct path\n        string path;\n        int cur = t;\n        while (cur != s) {\n            char m = move[cur];\n            path.push_back(m);\n            cur = prev[cur];\n        }\n        reverse(path.begin(), path.end());\n\n        // output\n        cout << path << '\\n' << flush;\n\n        // receive noisy length\n        long long noisy;\n        cin >> noisy;\n\n        // learning\n        double est = dist[t];                // \u03a3 w_e according to current estimates\n        double ratio = (double)noisy / est;  // B / E\n        double factor = 1.0 + ALPHA * (ratio - 1.0);\n        if (factor < 0.5) factor = 0.5;\n        if (factor > 2.0) factor = 2.0;\n\n        // apply factor to all edges of the printed path\n        int i = si, j = sj;\n        for (char c : path) {\n            if (c == 'U') {\n                ver[i-1][j] *= factor;\n                if (ver[i-1][j] < MIN_W) ver[i-1][j] = MIN_W;\n                if (ver[i-1][j] > MAX_W) ver[i-1][j] = MAX_W;\n                --i;\n            } else if (c == 'D') {\n                ver[i][j] *= factor;\n                if (ver[i][j] < MIN_W) ver[i][j] = MIN_W;\n                if (ver[i][j] > MAX_W) ver[i][j] = MAX_W;\n                ++i;\n            } else if (c == 'L') {\n                hor[i][j-1] *= factor;\n                if (hor[i][j-1] < MIN_W) hor[i][j-1] = MIN_W;\n                if (hor[i][j-1] > MAX_W) hor[i][j-1] = MAX_W;\n                --j;\n            } else if (c == 'R') {\n                hor[i][j] *= factor;\n                if (hor[i][j] < MIN_W) hor[i][j] = MIN_W;\n                if (hor[i][j] > MAX_W) hor[i][j] = MAX_W;\n                ++j;\n            }\n        }\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct SubInfo {\n    uint8_t start_i, start_j;\n    uint8_t dir;          // 0 = horizontal, 1 = vertical\n    uint8_t len;\n};\n\nint N;                                   // =20\nint totalCells;\nint totalM;                              // sum of multiplicities = M\nint curC;                                // weighted number of present strings\nvector<string> grid;                     // current board\nvector<string> bestGrid;                 // best board found\nint bestC = 0;\n\n// encoding of characters\nint charCode[256];\n\n// powers of 8   (8^k, k \u2264 12)\nuint64_t pow8[13];\n\n// map from encoded string -> index of distinct string\nunordered_map<uint64_t, int> str2idx;\nvector<int> mult;                        // multiplicity of each distinct string\nint uniqCnt = 0;                         // number of distinct strings\n\n// all substrings\nvector<SubInfo> subs;                    // static part\nvector<uint64_t> curCode;                // current code of each substring\nvector<int> curIdx;                      // index of matched string, -1 if none\nvector<int> occ;                         // occurrences of each distinct string\n\n// for each cell: list of (substring id, offset inside that substring)\nvector<vector<pair<int, uint8_t>>> cellSubs;\n\n/* ------------------------------------------------------------------ */\n// encode a string (without length) \u2013 base\u20118\nstatic inline uint64_t encodeString(const string &s) {\n    uint64_t code = 0;\n    for (char ch : s) code = (code << 3) | (uint64_t)charCode[(unsigned char)ch];\n    return code;\n}\n\n// encode a string together with its length (used as key in the map)\nstatic inline uint64_t encodeWithLen(const string &s) {\n    uint64_t code = encodeString(s);\n    return (code << 4) | (uint64_t)s.size();\n}\n\n/* ------------------------------------------------------------------ */\n// rebuild curCode, curIdx, occ, curC from the current grid\nvoid rebuildFromGrid(const vector<string> &g) {\n    fill(occ.begin(), occ.end(), 0);\n    curC = 0;\n    int S = (int)subs.size();\n    for (int sid = 0; sid < S; ++sid) {\n        const SubInfo &inf = subs[sid];\n        uint64_t code = 0;\n        for (int p = 0; p < inf.len; ++p) {\n            int r = (inf.dir == 0) ? inf.start_i\n                                   : (inf.start_i + p) % N;\n            int c = (inf.dir == 0) ? (inf.start_j + p) % N\n                                   : inf.start_j;\n            char ch = g[r][c];\n            code = (code << 3) | (uint64_t)charCode[(unsigned char)ch];\n        }\n        uint64_t enc = (code << 4) | (uint64_t)inf.len;\n        int idx = -1;\n        auto it = str2idx.find(enc);\n        if (it != str2idx.end()) idx = it->second;\n        curIdx[sid] = idx;\n        curCode[sid] = code;\n        if (idx != -1) occ[idx]++;\n    }\n    for (int i = 0; i < uniqCnt; ++i)\n        if (occ[i] > 0) curC += mult[i];\n}\n\n/* ------------------------------------------------------------------ */\n// compute \u0394c for changing cell 'cell' to letter 'newChar'\nint computeDelta(int cell, char newChar) {\n    char oldChar = grid[cell];\n    if (oldChar == newChar) return 0;\n    int oldCode = charCode[(unsigned char)oldChar];\n    int newCode = charCode[(unsigned char)newChar];\n    int delta = 0;\n    for (auto &pr : cellSubs[cell]) {\n        int sid = pr.first;\n        int offset = pr.second;\n        const SubInfo &inf = subs[sid];\n        int len = inf.len;\n        int exp = len - 1 - offset;                // power of 8\n        uint64_t oldCodeSub = curCode[sid];\n        uint64_t newCodeSub = oldCodeSub\n                           - (uint64_t)oldCode * pow8[exp]\n                           + (uint64_t)newCode * pow8[exp];\n        uint64_t newEnc = (newCodeSub << 4) | (uint64_t)len;\n        auto it = str2idx.find(newEnc);\n        int newIdx = (it == str2idx.end()) ? -1 : it->second;\n        int oldIdx = curIdx[sid];\n\n        if (oldIdx != -1) {\n            if (occ[oldIdx] == 1)                 // will disappear\n                delta -= mult[oldIdx];\n        }\n        if (newIdx != -1) {\n            if (occ[newIdx] == 0)                  // will appear\n                delta += mult[newIdx];\n        }\n    }\n    return delta;\n}\n\n/* ------------------------------------------------------------------ */\n// actually perform the change, update all structures\nvoid applyDelta(int cell, char newChar) {\n    char oldChar = grid[cell];\n    if (oldChar == newChar) return;\n    int oldCode = charCode[(unsigned char)oldChar];\n    int newCode = charCode[(unsigned char)newChar];\n    for (auto &pr : cellSubs[cell]) {\n        int sid = pr.first;\n        int offset = pr.second;\n        const SubInfo &inf = subs[sid];\n        int len = inf.len;\n        int exp = len - 1 - offset;\n        uint64_t oldCodeSub = curCode[sid];\n        uint64_t newCodeSub = oldCodeSub\n                           - (uint64_t)oldCode * pow8[exp]\n                           + (uint64_t)newCode * pow8[exp];\n        uint64_t newEnc = (newCodeSub << 4) | (uint64_t)len;\n        auto it = str2idx.find(newEnc);\n        int newIdx = (it == str2idx.end()) ? -1 : it->second;\n        int oldIdx = curIdx[sid];\n\n        // remove old\n        if (oldIdx != -1) {\n            if (occ[oldIdx] == 1) curC -= mult[oldIdx];\n            --occ[oldIdx];\n        }\n        // add new\n        if (newIdx != -1) {\n            if (occ[newIdx] == 0) curC += mult[newIdx];\n            ++occ[newIdx];\n        }\n        curCode[sid] = newCodeSub;\n        curIdx[sid] = newIdx;\n    }\n    grid[cell] = newChar;\n}\n\n/* ------------------------------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    // ---------- read input ----------\n    int M;\n    cin >> N >> M;\n    totalCells = N * N;\n    vector<string> inputStrings(M);\n    for (int i = 0; i < M; ++i) cin >> inputStrings[i];\n\n    // ---------- character encoding ----------\n    for (int i = 0; i < 256; ++i) charCode[i] = -1;\n    for (char c = 'A'; c <= 'H'; ++c) charCode[(unsigned char)c] = c - 'A';\n\n    // ---------- distinct strings ----------\n    for (const string &s : inputStrings) {\n        uint64_t enc = encodeWithLen(s);\n        auto it = str2idx.find(enc);\n        if (it == str2idx.end()) {\n            int id = uniqCnt++;\n            str2idx[enc] = id;\n            mult.push_back(1);\n        } else {\n            ++mult[it->second];\n        }\n    }\n    totalM = M;                     // \u03a3 mult = M\n    occ.assign(uniqCnt, 0);\n\n    // ---------- pre\u2011compute powers of 8 ----------\n    pow8[0] = 1;\n    for (int i = 1; i <= 12; ++i) pow8[i] = pow8[i - 1] * 8ULL;\n\n    // ---------- build all substrings (static part) ----------\n    subs.reserve(8800);\n    cellSubs.assign(totalCells, {});\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            // horizontal\n            for (int len = 2; len <= 12; ++len) {\n                SubInfo inf;\n                inf.start_i = (uint8_t)i;\n                inf.start_j = (uint8_t)j;\n                inf.dir = 0;\n                inf.len = (uint8_t)len;\n                int sid = (int)subs.size();\n                subs.push_back(inf);\n                for (int p = 0; p < len; ++p) {\n                    int cj = (j + p) % N;\n                    int cell = i * N + cj;\n                    cellSubs[cell].push_back({sid, (uint8_t)p});\n                }\n            }\n            // vertical\n            for (int len = 2; len <= 12; ++len) {\n                SubInfo inf;\n                inf.start_i = (uint8_t)i;\n                inf.start_j = (uint8_t)j;\n                inf.dir = 1;\n                inf.len = (uint8_t)len;\n                int sid = (int)subs.size();\n                subs.push_back(inf);\n                for (int p = 0; p < len; ++p) {\n                    int ri = (i + p) % N;\n                    int cell = ri * N + j;\n                    cellSubs[cell].push_back({sid, (uint8_t)p});\n                }\n            }\n        }\n    }\n    // reserve a little for each cell (optional, speeds up a bit)\n    for (auto &v : cellSubs) v.reserve(160);\n\n    // allocate vectors that depend on number of substrings\n    curCode.assign(subs.size(), 0);\n    curIdx.assign(subs.size(), -1);\n\n    // ---------- random engine ----------\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    // ---------- initial random board ----------\n    grid.assign(N, string(N, 'A'));\n    for (int i = 0; i < totalCells; ++i)\n        grid[i / N][i % N] = char('A' + (rng() % 8));\n\n    rebuildFromGrid(grid);\n    curC = bestC = curC;\n    bestGrid = grid;\n\n    // ---------- main search ----------\n    const double timeLimit = 2.8;            // seconds\n    auto startTime = chrono::steady_clock::now();\n    const int maxIter = 600000;              // enough for the limits\n    int iter = 0;\n    while (iter < maxIter) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - startTime).count();\n        if (elapsed >= timeLimit) break;\n\n        // choose random cell and random new letter\n        int cell = rng() % totalCells;\n        char newChar;\n        do {\n            newChar = char('A' + rng() % 8);\n        } while (newChar == grid[cell]);\n\n        int delta = computeDelta(cell, newChar);\n        bool accept = false;\n        if (delta > 0) accept = true;\n        else if (delta == 0) {\n            if ((rng() % 10) == 0) accept = true;       // 10% chance\n        } else {\n            if ((rng() % 100) == 0) accept = true;      // 1% chance\n        }\n\n        if (accept)(cell, newChar);\n            if (curC > best {\n            applyDeltaC) {\n                bestC = curC;\n                bestGrid = grid;\n                if (bestC == totalM) break;            // perfect!\n            }\n        }\n        ++iter;\n    }\n\n    // ---------- output ----------\n    for (int i = 0; i < N; ++i) {\n        cout << bestGrid[i] << '\\n';\n    }\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing pii = pair<int,int>;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, si, sj;\n    if(!(cin >> N >> si >> sj)) return 0;\n    vector<string> g(N);\n    for (int i = 0; i < N; ++i) cin >> g[i];\n\n    /* ---------- road cells ---------- */\n    vector<vector<int>> id(N, vector<int>(N, -1));\n    vector<pii> pos;               // id -> (i,j)\n    vector<int> w;                 // id -> entering time\n    int R = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (g[i][j] != '#') {\n                id[i][j] = R++;\n                pos.emplace_back(i, j);\n                w.push_back(g[i][j] - '0');\n            }\n\n    /* ---------- horizontal segments ---------- */\n    vector<vector<int>> rowSegId(N, vector<int>(N, -1));\n    vector<vector<int>> rowSegMembers;               // list of cell ids\n    int rowSegCnt = 0;\n    for (int i = 0; i < N; ++i) {\n        int j = 0;\n        while (j < N) {\n            if (g[i][j] == '#') { ++j; continue; }\n            int seg = rowSegCnt++;\n            rowSegMembers.emplace_back();\n            while (j < N && g[i][j] != '#') {\n                int cid = id[i][j];\n                rowSegId[i][j] = seg;\n                rowSegMembers.back().push_back(cid);\n                ++j;\n            }\n        }\n    }\n\n    /* ---------- vertical segments ---------- */\n    vector<vector<int>> colSegId(N, vector<int>(N, -1));\n    vector<vector<int>> colSegMembers;\n    int colSegCnt = 0;\n    for (int j = 0; j < N; ++j) {\n        int i = 0;\n        while (i < N) {\n            if (g[i][j] == '#') { ++i; continue; }\n            int seg = colSegCnt++;\n            colSegMembers.emplace_back();\n            while (i < N && g[i][j] != '#') {\n                int cid = id[i][j];\n                colSegId[i][j] = seg;\n                colSegMembers.back().push_back(cid);\n                ++i;\n            }\n        }\n    }\n\n    /* ----- cell -> its two segment ids ----- */\n    vector<int> cellRowSeg(R), cellColSeg(R);\n    for (int cid = 0; cid < R; ++cid) {\n        int i = pos[cid].first, j = pos[cid].second;\n        cellRowSeg[cid] = rowSegId[i][j];\n        cellColSeg[cid] = colSegId[i][j];\n    }\n\n    int startId = id[si][sj];\n    vector<char> rowCover(rowSegCnt, 0), colCover(colSegCnt, 0);\n    rowCover[cellRowSeg[startId]] = 1;\n    colCover[cellColSeg[startId]] = 1;\n\n    int coveredCnt = 0;\n    for (int cid = 0; cid < R; ++cid)\n        if (rowCover[cellRowSeg[cid]] || colCover[cellColSeg[cid]])\n            ++coveredCnt;\n\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    const char dch[4] = {'U','D','L','R'};\n\n    auto dirFromDelta = [&](int dr, int dc)->char{\n        if (dr==-1 && dc==0) return 'U';\n        if (dr==1  && dc==0) return 'D';\n        if (dr==0 && dc==-1) return 'L';\n        if (dr==0 && dc==1) return 'R';\n        return '?';\n    };\n\n    /* ---------- greedy walk ---------- */\n    string answer;\n    long long totalCost = 0;\n    int ci = si, cj = sj;\n    int curId = startId;\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    while (coveredCnt < R) {\n        int bestDir = -1;\n        int bestInc = -1;\n        int bestCost = INT_MAX;\n        int bestNi = -1, bestNj = -1;\n\n        for (int d = 0; d < 4; ++d) {\n            int ni = ci + dx[d], nj = cj + dy[d];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            if (id[ni][nj] == -1) continue;\n            int nid = id[ni][nj];\n            int rs = cellRowSeg[nid];\n            int cs = cellColSeg[nid];\n\n            int inc = 0;\n            if (!rowCover[rs]) {\n                for (int cid : rowSegMembers[rs])\n                    if (!rowCover[cellRowSeg[cid]] && !colCover[cellColSeg[cid]]) ++inc;\n            }\n            if (!colCover[cs]) {\n                for (int cid : colSegMembers[cs])\n                    if (!rowCover[cellRowSeg[cid]] && !colCover[cellColSeg[cid]]) ++inc;\n            }\n            if (!rowCover[rs] && !colCover[cs]) --inc;          // cell counted twice\n\n            if (inc > bestInc || (inc == bestInc && w[nid] < bestCost)) {\n                bestInc = inc;\n                bestCost = w[nid];\n                bestDir = d;\n                bestNi = ni; bestNj = nj;\n            }\n        }\n\n        if (bestInc > 0) {                     // move with new coverage\n            answer.push_back(dch[bestDir]);\n            totalCost += w[id[bestNi][bestNj]];\n            ci = bestNi; cj = bestNj;\n            curId = id[ci][cj];\n            int rs = cellRowSeg[curId];\n            int cs = cellColSeg[curId];\n            if (!rowCover[rs]) rowCover[rs] = 1;\n            if (!colCover[cs]) colCover[cs] = 1;\n            coveredCnt += bestInc;\n        } else {                               // no new coverage \u2013 go to nearest uncovered cell\n            // BFS\n            vector<vector<int>> dist(N, vector<int>(N, -1));\n            vector<vector<pii>> prev(N, vector<pii>(N, {-1,-1}));\n            queue<pii> q;\n            dist[ci][cj] = 0;\n            q.emplace(ci,cj);\n            int ti = -1, tj = -1;\n            while (!q.empty()) {\n                auto [x,y] = q.front(); q.pop();\n                int cid = id[x][y];\n                if (cid != -1 && (!rowCover[cellRowSeg[cid]] || !colCover[cellColSeg[cid]])) {\n                    ti = x; tj = y;\n                    break;\n                }\n                for (int d = 0; d < 4; ++d) {\n                    int nx = x + dx[d], ny = y + dy[d];\n                    if (nx<0||nx>=N||ny<0||ny>=N) continue;\n                    if (id[nx][ny]==-1) continue;\n                    if (dist[nx][ny]!=-1) continue;\n                    dist[nx][ny] = dist[x][y] + 1;\n                    prev[nx][ny] = {x,y};\n                    q.emplace(nx,ny);\n                }\n            }\n            // backtrack to the first step\n            int bx = ti, by = tj;\n            while (dist[bx][by] > 1) {\n                auto pr = prev[bx][by];\n                bx = pr.first; by = pr.second;\n            }\n            // direction from (ci,cj) to (bx,by)\n            int dirIdx = -1;\n            for (int d = 0; d < 4; ++d) {\n                if (ci + dx[d] == bx && cj + dy[d] == by) {\n                    dirIdx = d; break;\n                }\n            }\n            answer.push_back(dch[dirIdx]);\n            totalCost += w[id[bx][by]];\n            ci = bx; cj = by;\n            curId = id[ci][cj];\n            // no segment becomes covered\n        }\n    }\n\n    /* ---------- shortest way back to start (Dijkstra) ---------- */\n    const long long INF = (1LL<<60);\n    vector<long long> d(R, INF);\n    vector<int> pv(R, -1);\n    using Node = pair<long long,int>;\n    priority_queue<Node, vector<Node>, greater<Node>> pq;\n    d[startId] = 0;\n    pq.emplace(0, startId);\n    while (!pq.empty()) {\n        auto [dist, u] = pq.top(); pq.pop();\n        if (dist != d[u]) continue;\n        int ui = pos[u].first, uj = pos[u].second;\n        for (int dir = 0; dir < 4; ++dir) {\n            int vi = ui + dx[dir], vj = uj + dy[dir];\n            if (vi<0||vi>=N||vj<0||vj>=N) continue;\n            int v = id[vi][vj];\n            if (v==-1) continue;\n            long long nd = dist + w[v];\n            if (nd < d[v]) {\n                d[v] = nd;\n                pv[v] = u;\n                pq.emplace(nd, v);\n            }\n        }\n    }\n\n    // reconstruct path from cur back to start (reverse of start \u2192 cur)\n    vector<int> revPath;               // cur \u2192 \u2026 \u2192 start\n    int node = curId;\n    while (true) {\n        revPath.push_back(node);\n        if (node == startId) break;\n        node = pv[node];\n    }\n    // add the moves\n    for (int k = (int)revPath.size() - 1; k > 0; --k) {\n        int a = revPath[k];\n        int b = revPath[k-1];\n        int ai = pos[a].first, aj = pos[a].second;\n        int bi = pos[b].first, bj = pos[b].second;\n        answer.push_back(dirFromDelta(bi - ai, bj - aj));\n        totalCost += w[b];\n    }\n\n    cout << answer << '\\n';\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct ReadyTask {\n    long long diff;   // sum of required skills\n    int id;            // task index (0\u2011based)\n    bool operator<(ReadyTask const& other) const {\n        // for max\u2011heap we reverse the comparison\n        return diff < other.diff;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K, R;\n    if (!(cin >> N >> M >> K >> R)) return 0;\n    \n    vector<vector<int>> d(N, vector<int>(K));\n    for (int i = 0; i < N; ++i)\n        for (int k = 0; k < K; ++k)\n            cin >> d[i][k];\n    \n    vector<vector<int>> children(N);\n    vector<int> indeg(N, 0);\n    for (int i = 0; i < R; ++i) {\n        int u, v;\n        cin >> u >> v;\n        --u; --v;\n        children[u].push_back(v);\n        ++indeg[v];\n    }\n    \n    // difficulty of each task = sum of required skill components\n    vector<long long> diff(N, 0);\n    for (int i = 0; i < N; ++i) {\n        long long s = 0;\n        for (int k = 0; k < K; ++k) s += d[i][k];\n        diff[i] = s;\n    }\n    \n    // ----- data for the interactive part -----\n    // current task of each member, -1 = idle\n    vector<int> curTask(M, -1);\n    // start day of each task (valid only if status == 0)\n    vector<int> startDay(N, -1);\n    // status: -1 = not started, 0 = in progress, 1 = finished\n    vector<int> taskStatus(N, -1);\n    \n    // statistics for each member\n    vector<long long> totalTime(M, 0);   // sum of durations\n    vector<long long> totalDiff(M, 0);   // sum of diff of finished tasks\n    \n    // priority queue of ready tasks (max\u2011heap by diff)\n    priority_queue<ReadyTask> ready;\n    for (int i = 0; i < N; ++i)\n        if (indeg[i] == 0) ready.push({diff[i], i});\n    \n    int day = 1;\n    while (true) {\n        // ----- decide which idle members get which ready tasks -----\n        vector<int> idle;\n        idle.reserve(M);\n        for (int j = 0; j < M; ++j)\n            if (curTask[j] == -1) idle.push_back(j);\n        \n        // comparator: faster member first\n        auto faster = [&](int a, int b) {\n            if (totalDiff[a] == 0 && totalDiff[b] == 0) return a < b;\n            if (totalDiff[a] == 0) return true;          // a is considered fastest\n            if (totalDiff[b] == 0) return false;\n            // compare avg_time_per_diff = totalTime / totalDiff\n            return totalTime[a] * totalDiff[b] < totalTime[b] * totalDiff[a];\n        };\n        sort(idle.begin(), idle.end(), faster);\n        \n        vector<pair<int,int>> assignments; // (member+1, task+1)\n        size_t pos = 0;\n        while (pos < idle.size() && !ready.empty()) {\n            ReadyTask rt = ready.top(); ready.pop();\n            int w = idle[pos++];\n            int t = rt.id;\n            // start the task\n            curTask[w] = t;\n            startDay[t] = day;\n            taskStatus[t] = 0; // in progress\n            assignments.emplace_back(w + 1, t + 1);\n        }\n        \n        // ----- output -----\n        cout << assignments.size();\n        for (auto &p : assignments) cout << ' ' << p.first << ' ' << p.second;\n        cout << '\\n';\n        cout.flush();\n        \n        // ----- receive information about finished members -----\n        int x;\n        if (!(cin >> x)) break;          // should not happen\n        if (x == -1) break;               // end of simulation\n        int cnt = x;\n        vector<int> finished(cnt);\n        for (int i = 0; i < cnt; ++i) {\n            cin >> finished[i];\n            --finished[i];                // to 0\u2011based\n        }\n        \n        // process each finished task\n        for (int w : finished) {\n            int t = curTask[w];\n            if (t == -1) continue;        // should not happen\n            int duration = day - startDay[t] + 1;\n            totalTime[w] += duration;\n            totalDiff[w] += diff[t];\n            taskStatus[t] = 1;            // finished\n            \n            // update dependents\n            for (int nb : children[t]) {\n                if (--indeg[nb] == 0) {\n                    ready.push({diff[nb], nb});\n                }\n            }\n            curTask[w] = -1;               // member becomes idle\n        }\n        ++day;\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Order {\n    int a, b, c, d;          // pickup (a,b) , delivery (c,d)\n};\n\ninline long long manhattan(int x1, int y1, int x2, int y2) {\n    return llabs(x1 - x2) + llabs(y1 - y2);\n}\n\n/* --------------------------------------------------------------- */\n/*  compute tour length for a given permutation                    */\nstatic long long tourCost(const vector<int>& perm,\n                          const vector<long long>& start,\n                          const vector<long long>& finish,\n                          const vector<vector<int>>& D,\n                          long long insideSum)\n{\n    const int m = (int)perm.size();\n    long long cur = start[perm[0]];\n    for (int i = 0; i < m - 1; ++i) cur += D[perm[i]][perm[i + 1]];\n    cur += finish[perm[m - 1]];\n    cur += insideSum;\n    return cur;\n}\n\n/* --------------------------------------------------------------- */\n/*  cheap TSP : nearest neighbour from every start                */\nstatic long long cheapTSP(const vector<int>& orders,\n                          vector<int>& bestPerm)\n{\n    const int m = (int)orders.size();\n    vector<long long> start(m), finish(m), inside(m);\n    vector<int> pX(m), pY(m), dX(m), dY(m);\n    const int DEP = 400;\n\n    for (int i = 0; i < m; ++i) {\n        const Order& o = *((Order*)nullptr);   // dummy, see below\n    }\n\n    // fill data for the current subset\n    for (int i = 0; i < m; ++i) {\n        const Order& o = *((Order*)nullptr);\n    }\n    // we will fill it inside the function, see later\n    // (the two dummy lines are only to keep the editor happy)\n    // -----------------------------------------------------------------\n    // Real code: we need the arrays a,b,c,d from the global vector.\n    // -----------------------------------------------------------------\n    return 0; // never reached\n}\n\n/* Because the cheap TSP is tiny we write it inside the main function\n   to avoid passing many global arrays. The same holds for the full\n   improvement routine.                                             */\n\n/* --------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int DEP = 400;\n    const int N = 1000;\n    vector<Order> ord(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> ord[i].a >> ord[i].b >> ord[i].c >> ord[i].d;\n    }\n\n    /* ----  solo costs (start+inside+finish)  ---------------------- */\n    vector<long long> solo(N);\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    for (int i = 0; i < N; ++i) {\n        long long st = manhattan(DEP, DEP, ord[i].a, ord[i].b);\n        long long ins = manhattan(ord[i].a, ord[i].b, ord[i].c, ord[i].d);\n        long long fn = manhattan(ord[i].c, ord[i].d, DEP, DEP);\n        solo[i] = st + ins + fn;\n    }\n    sort(idx.begin(), idx.end(),\n         [&](int i, int j){ return solo[i] < solo[j]; });\n\n    /* ----  candidate list : the 200 best orders  ----------------- */\n    const int CAND = 200;\n    vector<int> cand;\n    cand.reserve(CAND);\n    for (int i = 0; i < CAND; ++i) cand.push_back(idx[i]);\n\n    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    const int SAMPLE = 500;               // number of random subsets\n    struct SubsetInfo {\n        vector<int> ids;   // original order numbers (0\u2011based)\n        long long cost;\n    };\n    vector<SubsetInfo> samples;\n    samples.reserve(SAMPLE + 1);\n\n    // ----- helper lambdas for a concrete subset -----------------\n    auto evaluateSubset = [&](const vector<int>& ids, bool full,\n                               vector<int>& outPerm) -> long long {\n        const int m = (int)ids.size();            // =50\n        vector<long long> start(m), finish(m), inside(m);\n        vector<int> pX(m), pY(m), dX(m), dY(m);\n        long long insideSum = 0;\n        for (int i = 0; i < m; ++i) {\n            const Order& o = ord[ids[i]];\n            pX[i] = o.a; pY[i] = o.b;\n            dX[i] = o.c; dY[i] = o.d;\n            start[i]   = manhattan(DEP, DEP, pX[i], pY[i]);\n            inside[i]  = manhattan(pX[i], pY[i], dX[i], dY[i]);\n            finish[i]  = manhattan(dX[i], dY[i], DEP, DEP);\n            insideSum += inside[i];\n        }\n        // matrix D[i][j] = distance delivery_i -> pickup_j\n        vector<vector<int>> D(m, vector<int>(m));\n        for (int i = 0; i < m; ++i)\n            for (int j = 0; j < m; ++j)\n                D[i][j] = (int)manhattan(dX[i], dY[i], pX[j], pY[j]);\n\n        // ----- cheap solution : nearest neighbour -----------------\n        long long bestCost = (1LL<<60);\n        vector<int> bestPerm;\n        for (int s = 0; s < m; ++s) {\n            vector<int> perm;\n            vector<char> used(m, 0);\n            int cur = s;\n            perm.push_back(cur);\n            used[cur] = 1;\n            for (int step = 1; step < m; ++step) {\n                int nxt = -1;\n                int bestD = INT_MAX;\n                for (int v = 0; v < m; ++v) if (!used[v]) {\n                    int d = D[cur][v];\n                    if (d < bestD) { bestD = d; nxt = v; }\n                }\n                used[nxt] = 1;\n                perm.push_back(nxt);\n                cur = nxt;\n            }\n            long long c = tourCost(perm, start, finish, D, insideSum);\n            if (c < bestCost) {\n                bestCost = c;\n                bestPerm = perm;\n            }\n        }\n\n        if (!full) {\n            outPerm = bestPerm;\n            return bestCost;\n        }\n\n        // ----- full improvement (insertion, swap, 2\u2011opt) ----------\n        vector<int> perm = bestPerm;\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            // insertion\n            for (int i = 0; i < m && !improved; ++i) {\n                for (int j = 0; j < m && !improved; ++j) if (i != j) {\n                    vector<int> np = perm;\n                    int val = np[i];\n                    np.erase(np.begin() + i);\n                    np.insert(np.begin() + j, val);\n                    long long c = tourCost(np, start, finish, D, insideSum);\n                    if (c < tourCost(perm, start, finish, D, insideSum)) {\n                        perm.swap(np);\n                        improved = true;\n                    }\n                }\n            }\n            // swap\n            if (!improved) {\n                for (int i = 0; i < m && !improved; ++i) {\n                    for (int j = i + 1; j < m && !improved; ++j) {\n                        vector<int> np = perm;\n                        swap(np[i], np[j]);\n                        long long c = tourCost(np, start, finish, D, insideSum);\n                        if (c < tourCost(perm, start, finish, D, insideSum)) {\n                            perm.swap(np);\n                            improved = true;\n                        }\n                    }\n                }\n            }\n            // 2\u2011opt (reverse a segment)\n            if (!improved) {\n                for (int i = 0; i < m - 2 && !improved; ++i) {\n                    for (int j = i + 2; j < m && !improved; ++j) {\n                        vector<int> np = perm;\n                        reverse(np.begin() + i + 1, np.begin() + j + 1);\n                        long long c = tourCost(np, start, finish, D, insideSum);\n                        if (c < tourCost(perm, start, finish, D, insideSum)) {\n                            perm.swap(np);\n                            improved = true;\n                        }\n                    }\n                }\n            }\n        }\n        outPerm = perm;\n        return tourCost(perm, start, finish, D, insideSum);\n    };\n\n    // ----- evaluate many random subsets (cheap only) ------------\n    for (int iter = 0; iter < SAMPLE; ++iter) {\n        vector<int> cand2 = cand;\n        shuffle(cand2.begin(), cand2.end(), rng);\n        vector<int> ids(cand2.begin(), cand2.begin() + 50);\n        vector<int> dummyPerm;\n        long long c = evaluateSubset(ids, false, dummyPerm);\n        samples.push_back({ids, c});\n    }\n    // also add the deterministic top\u201150 set\n    {\n        vector<int> ids(idx.begin(), idx.begin() + 50);\n        vector<int> dummy;\n        long long c = evaluateSubset(ids, false, dummy);\n        samples.push_back({ids, c});\n    }\n\n    // keep the 5 best subsets\n    const int KEEP = 5;\n    nth_element(samples.begin(),\n                samples.begin() + KEEP,\n                samples.end(),\n                [](const SubsetInfo& a, const SubsetInfo& b){ return a.cost < b.cost; });\n    samples.resize(KEEP);\n\n    // ----- full improvement on the best subsets -----------------\n    long long bestTotal = (1LL<<60);\n    vector<int> bestIds;\n    vector<int> bestPerm;\n\n    for (auto& s : samples) {\n        vector<int> perm;\n        long long c = evaluateSubset(s.ids, true, perm);\n        if (c < bestTotal) {\n            bestTotal = c;\n            bestIds = s.ids;\n            bestPerm = perm;\n        }\n    }\n\n    // ----- build the output route --------------------------------\n    // bestIds : original order numbers (0\u2011based)\n    // bestPerm : permutation of 0..49  (local index -> order in bestIds)\n\n    // sort the ids for nicer output\n    sort(bestIds.begin(), bestIds.end());\n\n    // route coordinates\n    vector<int> routeX, routeY;\n    routeX.push_back(DEP);\n    routeY.push_back(DEP);\n    for (int k = 0; k < 50; ++k) {\n        int local = bestPerm[k];\n        int orig  = bestIds[local];\n        routeX.push_back(ord[orig].a);\n        routeY.push_back(ord[orig].b);\n        routeX.push_back(ord[orig].c);\n        routeY.push_back(ord[orig].d);\n    }\n    routeX.push_back(DEP);\n    routeY.push_back(DEP);\n    const int n = (int)routeX.size();           // = 2*50+2 = 102\n\n    // ----- output -------------------------------------------------\n    cout << 50;\n    for (int id : bestIds) cout << ' ' << (id + 1);\n    cout << '\\n';\n    cout << n;\n    for (size_t i = 0; i < routeX.size(); ++i)\n        cout << ' ' << routeX[i] << ' ' << routeY[i];\n    cout << '\\n';\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    vector<int> p, sz;\n    DSU(int n = 0) { init(n); }\n    void init(int n) {\n        p.resize(n);\n        sz.assign(n, 1);\n        iota(p.begin(), p.end(), 0);\n    }\n    int find(int x) {\n        if (p[x] == x) return x;\n        return p[x] = find(p[x]);\n    }\n    bool unite(int a, int b) {\n        a = find(a); b = find(b);\n        if (a == b) return false;\n        if (sz[a] < sz[b]) swap(a, b);\n        p[b] = a;\n        sz[a] += sz[b];\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    if (!(cin >> N)) return 0;\n    vector<int> X(N), Y(N);\n    for (int i = 0; i < N; ++i) cin >> X[i] >> Y[i];\n    int M;\n    cin >> M;\n    vector<int> U(M), V(M);\n    for (int i = 0; i < M; ++i) cin >> U[i] >> V[i];\n    \n    DSU dsu(N);\n    \n    for (int i = 0; i < M; ++i) {\n        long long l;            // the given length\n        cin >> l;\n        if (dsu.find(U[i]) != dsu.find(V[i])) {\n            cout << 1 << '\\n';\n            dsu.unite(U[i], V[i]);\n        } else {\n            cout << 0 << '\\n';\n        }\n        cout.flush();           // required by the statement\n    }\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing pii = pair<int,int>;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int H = 30, W = 30;\n    int N;  // number of pets\n    if(!(cin >> N)) return 0;\n    vector<pii> petPos(N);\n    vector<int> petType(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> petPos[i].first >> petPos[i].second >> petType[i];\n    }\n    int M;  // number of humans\n    cin >> M;\n    vector<pii> humanPos(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> humanPos[i].first >> humanPos[i].second;\n    }\n\n    /* -------------------------------------------------------------\n       1. choose the protected rectangle (the biggest one with few pets)\n       ------------------------------------------------------------- */\n    bool region[H+2][W+2] = {};\n    bool neededWall[H+2][W+2] = {};\n    bool wall[H+2][W+2] = {};\n\n    int bestCnt = N+1, bestR=2, bestC=2, bestSize=12;\n    for (int sz = 12; sz >= 6; --sz) {\n        bestCnt = N+1;\n        for (int r = 2; r+sz-1 <= 29; ++r) {\n            for (int c = 2; c+sz-1 <= 29; ++c) {\n                int cnt = 0;\n                for (auto &p: petPos) {\n                    if (p.first >= r && p.first <= r+sz-1 &&\n                        p.second >= c && p.second <= c+sz-1) ++cnt;\n                }\n                if (cnt < bestCnt) {\n                    bestCnt = cnt; bestR = r; bestC = c; bestSize = sz;\n                }\n            }\n        }\n        if (bestCnt == 0) break;          // perfect \u2013 no pet inside\n    }\n\n    // mark interior cells\n    for (int r = bestR; r < bestR+bestSize; ++r)\n        for (int c = bestC; c < bestC+bestSize; ++c)\n            region[r][c] = true;\n\n    // perimeter cells (distance 1 from the rectangle)\n    const int d4[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};\n    for (int r = bestR; r < bestR+bestSize; ++r) {\n        for (int c = bestC; c < bestC+bestSize; ++c) {\n            for (int k=0;k<4;++k){\n                int nr = r + d4[k][0];\n                int nc = c + d4[k][1];\n                if (nr<1||nr>30||nc<1||nc>30) continue;\n                if (region[nr][nc]) continue;\n                neededWall[nr][nc] = true;\n            }\n        }\n    }\n\n    /* -------------------------------------------------------------\n       2. assign a target cell inside the rectangle to each human\n       ------------------------------------------------------------- */\n    vector<pii> target(M);\n    int assigned = 0;\n    for (int r = bestR; r < bestR+bestSize && assigned < M; ++r) {\n        for (int c = bestC; c < bestC+bestSize && assigned < M; ++c) {\n            target[assigned++] = {r,c};\n        }\n    }\n\n    /* -------------------------------------------------------------\n       3. simulate the 300 turns\n       ------------------------------------------------------------- */\n    const char wallChar[4] = {'u','d','l','r'};\n    const char moveChar[4] = {'U','D','L','R'};\n\n    for (int turn = 0; turn < 300; ++turn) {\n        // ----- build occupancy and adjacency tables -----\n        static bool occPet[H+2][W+2];\n        static bool occHuman[H+2][W+2];\n        static bool adjPet[H+2][W+2];\n        for (int i=1;i<=30;++i)\n            for (int j=1;j<=30;++j)\n                occPet[i][j]=occHuman[i][j]=adjPet[i][j]=false;\n\n        for (auto &p: petPos) occPet[p.first][p.second] = true;\n        for (auto &p: humanPos) occHuman[p.first][p.second] = true;\n\n        for (auto &p: petPos) {\n            for (int k=0;k<4;++k){\n                int nr = p.first + d4[k][0];\n                int nc = p.second + d4[k][1];\n                if (nr<1||nr>30||nc<1||nc>30) continue;\n                adjPet[nr][nc] = true;\n            }\n        }\n\n        // decide actions\n        vector<char> action(M,'.');\n        vector<pii> moveDest(M);\n        static bool newWall[H+2][W+2];\n        for (int i=1;i<=30;++i)\n            for (int j=1;j<=30;++j)\n                newWall[i][j]=false;\n\n        for (int i = 0; i < M; ++i) {\n            int hx = humanPos[i].first;\n            int hy = humanPos[i].second;\n            bool placed = false;\n\n            // ---- try to place a wall ----\n            for (int dir = 0; dir < 4 && !placed; ++dir) {\n                int nx = hx + d4[dir][0];\n                int ny = hy + d4[dir][1];\n                if (nx<1||nx>30||ny<1||ny>30) continue;\n                if (!neededWall[nx][ny]) continue;               // not a needed perimeter cell\n                if (occPet[nx][ny] || occHuman[nx][ny]) continue; // occupied\n                if (adjPet[nx][ny]) continue;                     // adjacent to a pet\n                // place wall\n                action[i] = wallChar[dir];\n                newWall[nx][ny] = true;\n                placed = true;\n            }\n            if (placed) {\n                moveDest[i] = {hx,hy};\n                continue;\n            }\n\n            // ---- otherwise try to move towards target ----\n            int tx = target[i].first;\n            int ty = target[i].second;\n            int nx = -1, ny = -1, ndir = -1;\n            // vertical first\n            if (hx != tx) {\n                int dir = (hx < tx) ? 1 : 0;          // down / up\n                nx = hx + d4[dir][0];\n                ny = hy;\n                if (nx>=1 && nx<=30 && !wall[nx][ny]) ndir = dir;\n            }\n            // horizontal if vertical impossible\n            if (ndir==-1 && hy != ty) {\n                int dir = (hy < ty) ? 3 : 2;          // right / left\n                nx = hx;\n                ny = hy + d4[dir][1];\n                if (ny>=1 && ny<=30 && !wall[nx][ny]) ndir = dir;\n            }\n            if (ndir != -1) {\n                action[i] = moveChar[ndir];\n                moveDest[i] = {nx,ny};\n            } else {\n                action[i] = '.';\n                moveDest[i] = {hx,hy};\n            }\n        }\n\n        // ----- prevent moving onto a square that becomes a wall this turn -----\n        for (int i = 0; i < M; ++i) {\n            if (action[i] >= 'A' && action[i] <= 'Z') { // a move\n                if (newWall[ moveDest[i].first ][ moveDest[i].second ]) {\n                    action[i] = '.';\n                    moveDest[i] = humanPos[i];\n                }\n            }\n        }\n\n        // ----- output -----\n        for (int i = 0; i < M; ++i) cout << action[i];\n        cout << '\\n' << flush;\n\n        // ----- apply walls -----\n        for (int i = 1; i <= 30; ++i)\n            for (int j = 1; j <= 30; ++j)\n                if (newWall[i][j]) wall[i][j] = true;\n\n        // ----- apply human moves -----\n        for (int i = 0; i < M; ++i) {\n            if (action[i] >= 'A' && action[i] <= 'Z') {\n                humanPos[i] = moveDest[i];\n            }\n        }\n\n        // ----- read pet moves and apply them -----\n        for (int i = 0; i < N; ++i) {\n            string s; cin >> s;\n            for (char c: s) {\n                if (c=='.') continue;\n                int d = 0;\n                if (c=='U') d=0;\n                else if (c=='D') d=1;\n                else if (c=='L') d=2;\n                else if (c=='R') d=3;\n                int nx = petPos[i].first + d4[d][0];\n                int ny = petPos[i].second + d4[d][1];\n                if (nx<1||nx>30||ny<1||ny>30) continue;\n                if (wall[nx][ny]) continue;\n                petPos[i] = {nx,ny};\n            }\n        }\n    }\n\n    /* -------------------------------------------------------------\n       4. final scoring\n       ------------------------------------------------------------- */\n    long double sumS = 0.0L;\n    static bool vis[H+2][W+2];\n    const int d4r[4] = {-1,1,0,0};\n    const int d4c[4] = {0,0,-1,1};\n\n    for (int i = 0; i < M; ++i) {\n        for (int r=1;r<=30;++r)\n            for (int c=1;c<=30;++c)\n                vis[r][c]=false;\n\n        queue<pii> q;\n        int sx = humanPos[i].first, sy = humanPos[i].second;\n        vis[sx][sy]=true;\n        q.emplace(sx,sy);\n        int reachable = 0;\n        while(!q.empty()){\n            auto [x,y]=q.front(); q.pop();\n            ++reachable;\n            for(int k=0;k<4;++k){\n                int nx=x+d4r[k], ny=y+d4c[k];\n                if(nx<1||nx>30||ny<1||ny>30) continue;\n                if(wall[nx][ny]) continue;\n                if(vis[nx][ny]) continue;\n                vis[nx][ny]=true;\n                q.emplace(nx,ny);\n            }\n        }\n        int petsInside = 0;\n        for (auto &p: petPos) {\n            if (vis[p.first][p.second]) ++petsInside;\n        }\n        long double s = (long double)reachable / 900.0L *\n                         powl((long double)2.0, -(long double)petsInside);\n        sumS += s;\n    }\n\n    long double avg = sumS / (long double)M;\n    long long score = llround(1e8L * avg);\n    // (the judge does not need the score printed, program ends here)\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj, ti, tj;\n    double p;\n    if (!(cin >> si >> sj >> ti >> tj >> p)) return 0;\n\n    vector<string> h(20);\n    for (int i = 0; i < 20; ++i) cin >> h[i];\n    vector<string> v(19);\n    for (int i = 0; i < 19; ++i) cin >> v[i];\n\n    // wall[i][j][dir] : true if movement in direction dir from (i,j) is blocked\n    // dir: 0=U,1=D,2=L,3=R\n    bool wall[20][20][4];\n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            wall[i][j][0] = (i == 0) ? true : (v[i-1][j] == '1');          // up\n            wall[i][j][1] = (i == 19) ? true : (v[i][j] == '1');          // down\n            wall[i][j][2] = (j == 0) ? true : (h[i][j-1] == '1');          // left\n            wall[i][j][3] = (j == 19) ? true : (h[i][j] == '1');          // right\n        }\n    }\n\n    const int L = 200;\n    const int N = 20 * 20;\n    const int target = ti * 20 + tj;\n    const int start = si * 20 + sj;\n\n    // dp[t][v] : maximal expected score from turn t, square v\n    vector<vector<double>> dp(L + 2, vector<double>(N, 0.0));\n    vector<vector<int>> best(L + 2, vector<int>(N, -1));\n\n    // dp[t][target] = 0 already (vector initialised with 0)\n    for (int t = L; t >= 1; --t) {\n        for (int pos = 0; pos < N; ++pos) {\n            if (pos == target) {\n                dp[t][pos] = 0.0;\n                best[t][pos] = -1;\n                continue;\n            }\n            int i = pos / 20, j = pos % 20;\n            double bestVal = -1.0;\n            int bestDir = 0;\n            for (int d = 0; d < 4; ++d) {\n                bool w = wall[i][j][d];\n                double stayProb = p + (1.0 - p) * (w ? 1.0 : 0.0);\n                double moveProb = (1.0 - p) * (w ? 0.0 : 1.0);\n\n                double expected = stayProb * dp[t + 1][pos];\n                if (moveProb > 0.0) {\n                    int ni = i, nj = j;\n                    if (d == 0) --ni;\n                    else if (d == 1) ++ni;\n                    else if (d == 2) --nj;\n                    else ++nj;\n                    int npos = ni * 20 + nj;\n                    if (npos == target) {\n                        expected += moveProb * (401 - t);\n                    } else {\n                        expected += moveProb * dp[t + 1][npos];\n                    }\n                }\n                if (expected > bestVal + 1e-12) {\n                    bestVal = expected;\n                    bestDir = d;\n                }\n            }\n            dp[t][pos] = bestVal;\n            best[t][pos] = bestDir;\n        }\n    }\n\n    // reconstruction of a concrete string\n    string ans;\n    ans.reserve(L);\n    int cur = start;\n    for (int t = 1; t <= L; ++t) {\n        int d = best[t][cur];\n        char c;\n        if (d == 0) c = 'U';\n        else if (d == 1) c = 'D';\n        else if (d == 2) c = 'L';\n        else c = 'R';\n        ans.push_back(c);\n\n        int i = cur / 20, j = cur % 20;\n        if (!wall[i][j][d]) {               // intended move succeeds\n            if (d == 0) --i;\n            else if (d == 1) ++i;\n            else if (d == 2) --j;\n            else ++j;\n            cur = i * 20 + j;\n        }\n        // if we are already at the target we keep outputting arbitrary\n        // directions \u2013 they will never be executed.\n    }\n\n    cout << ans << '\\n';\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int C = N * N;               // 900 cells\nconst int DIRS = 4;\nconst int STATES = C * DIRS;       // 3600 states\n\nint di[DIRS] = {0, -1, 0, 1};\nint dj[DIRS] = {-1, 0, 1, 0};\n\nint orig_tile[C];                  // original type (0..7)\n\n/* -------------------------------------------------------------\n   table to[t][d]  \u2013 entering direction d, exiting direction\n   ------------------------------------------------------------- */\nint to_orig[8][DIRS] = {\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 to_rot[8][4][DIRS];            // [type][rotation][entry]\n\n/* -------------------------------------------------------------\n   compute the score (L1 * L2) for a given rotation\n   ------------------------------------------------------------- */\nint next_state[STATES];\nint visited_state[STATES];\nint step_idx[STATES];\nvector<int> path;\n\nlong long compute_product(const int rot[C]) {\n    // build next[]\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int t = orig_tile[i * N + j];\n            int r = rot[i * N + j];\n            int base = (i * N + j) * DIRS;\n            for (int d = 0; d < DIRS; ++d) {\n                int exit = to_rot[t][r][d];\n                if (exit == -1) {\n                    next_state[base + d] = -1;\n                    continue;\n                }\n                int ni = i + di[exit];\n                int nj = j + dj[exit];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) {\n                    next_state[base + d] = -1;\n                    continue;\n                }\n                int nd = (exit + 2) & 3;\n                next_state[base + d] = (ni * N + nj) * DIRS + nd;\n            }\n        }\n    }\n\n    // find all directed cycles\n    fill(visited_state, visited_state + STATES, 0);\n    fill(step_idx, step_idx + STATES, -1);\n    vector<int> cycles;\n    for (int s = 0; s < STATES; ++s) {\n        if (next_state[s] == -1 || visited_state[s]) continue;\n        int cur = s;\n        path.clear();\n        while (true) {\n            if (next_state[cur] == -1) break;               // reaches a dead end\n            if (visited_state[cur]) break;                  // already processed\n            if (step_idx[cur] != -1) {                      // a new cycle\n                int start = step_idx[cur];\n                int len = (int)path.size() - start;\n                cycles.push_back(len);\n                break;\n            }\n            step_idx[cur] = (int)path.size();\n            path.push_back(cur);\n            cur = next_state[cur];\n        }\n        for (int v : path) {\n            visited_state[v] = 1;\n            step_idx[v] = -1;\n        }\n    }\n\n    if (cycles.empty()) return 0LL;\n    sort(cycles.rbegin(), cycles.rend());\n    long long L1 = cycles[0];\n    long long L2 = (cycles.size() >= 2) ? cycles[1] : 0LL;\n    return L1 * L2;\n}\n\n/* -------------------------------------------------------------\n   main\n   ------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* read the board */\n    string line;\n    for (int i = 0; i < N; ++i) {\n        cin >> line;\n        for (int j = 0; j < N; ++j) orig_tile[i * N + j] = line[j] - '0';\n    }\n\n    /* pre\u2011compute rotated tables */\n    for (int t = 0; t < 8; ++t)\n        for (int r = 0; r < 4; ++r)\n            for (int d = 0; d < DIRS; ++d) {\n                int src = (d - r + 4) % 4;\n                int e = to_orig[t][src];\n                to_rot[t][r][d] = (e == -1) ? -1 : (e + r) % 4;\n            }\n\n    /* ---------- initial random rotation ------------------------ */\n    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist_rot(0, 3);\n\n    int cur_rot[C];\n    for (int i = 0; i < C; ++i) cur_rot[i] = dist_rot(rng);\n\n    /* optional greedy improvement (maximise matched sides) */\n    const int GREEDY_PASSES = 4;\n    for (int p = 0; p < GREEDY_PASSES; ++p) {\n        bool changed = false;\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j) {\n                int idx = i * N + j;\n                int t = orig_tile[idx];\n                int best_r = cur_rot[idx];\n                int best_match = -1;\n                for (int r = 0; r < 4; ++r) {\n                    int match = 0;\n                    for (int d = 0; d < DIRS; ++d) {\n                        int exit = to_rot[t][r][d];\n                        if (exit == -1) continue;\n                        int ni = i + di[exit];\n                        int nj = j + dj[exit];\n                        if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                        int nb = ni * N + nj;\n                        int nb_t = orig_tile[nb];\n                        int nb_r = cur_rot[nb];\n                        int nb_entry = (exit + 2) & 3;\n                        if (to_rot[nb_t][nb_r][nb_entry] != -1) ++match;\n                    }\n                    if (match > best_match) {\n                        best_match = match;\n                        best_r = r;\n                    }\n                }\n                if (best_r != cur_rot[idx]) {\n                    cur_rot[idx] = best_r;\n                    changed = true;\n                }\n            }\n        if (!changed) break;\n    }\n\n    long long best_score = compute_product(cur_rot);\n    int best_rot[C];\n    copy(begin(cur_rot), end(cur_rot), begin(best_rot));\n\n    /* ---------- simulated annealing --------------------------- */\n    const int MAX_ITER = 200000;\n    const double T0 = 1000.0;\n    const double DECAY = 0.9995;\n\n    double T = T0;\n    uniform_int_distribution<int> dist_cell(0, C - 1);\n    uniform_real_distribution<double> dist_prob(0.0, 1.0);\n\n    auto start = chrono::steady_clock::now();\n\n    for (int it = 0; it < MAX_ITER; ++it) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start).count();\n        if (elapsed > 1.8) break;                 // safety margin\n\n        int idx = dist_cell(rng);\n        int old_r = cur_rot[idx];\n        int new_r = dist_rot(rng);\n        if (new_r == old_r) new_r = (old_r + 1) & 3;   // force a change\n        cur_rot[idx] = new_r;\n\n        long long new_score = compute_product(cur_rot);\n        long long delta = new_score - best_score;   // compare with current, not best\n\n        if (delta > 0) {\n            // improvement \u2013 keep it\n            best_score = new_score;\n            copy(begin(cur_rot), end(cur_rot), begin(best_rot));\n        } else {\n            // accept worse with probability\n            if (dist_prob(rng) < exp((double)delta / T))\n                best_score = new_score;            // actually keep the worse one\n            else\n                cur_rot[idx] = old_r;               // revert\n        }\n\n        T = T0 * pow(DECAY, it + 1);\n    }\n\n    /* ---------- output --------------------------------------- */\n    string out;\n    out.reserve(C);\n    for (int i = 0; i < C; ++i) out.push_back(char('0' + best_rot[i]));\n    cout << out << '\\n';\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    int T;\n    if (!(cin >> N >> T)) return 0;\n    vector<string> s(N);\n    for (int i = 0; i < N; ++i) cin >> s[i];\n\n    // ----- read the board -------------------------------------------------\n    const int dr[4] = {-1, 1, 0, 0};\n    const int dc[4] = {0, 0, -1, 1};\n    const int bit[4] = {2, 8, 1, 4};          // up, down, left, right\n    const char mv[4] = {'U','D','L','R'};\n\n    auto idxFromDelta = [&](int drc, int dcc) -> int {\n        if (drc == -1 && dcc == 0) return 0;\n        if (drc == 1 && dcc == 0) return 1;\n        if (drc == 0 && dcc == -1) return 2;\n        if (drc == 0 && dcc == 1) return 3;\n        return -1;\n    };\n    auto bitFromDelta = [&](int drc, int dcc) -> int {\n        int id = idxFromDelta(drc, dcc);\n        return (id == -1 ? 0 : bit[id]);\n    };\n    auto charFromDelta = [&](int drc, int dcc) -> char {\n        int id = idxFromDelta(drc, dcc);\n        return mv[id];\n    };\n    auto oppBit = [&](int b) -> int {\n        if (b == 1) return 4;\n        if (b == 4) return 1;\n        if (b == 2) return 8;\n        if (b == 8) return 2;\n        return 0;\n    };\n\n    int M = N * N - 1;                 // number of tiles\n    vector<vector<int>> board(N, vector<int>(N, -1));\n    vector<int> mask; mask.reserve(M);\n    int er = -1, ec = -1;              // empty cell\n\n    int id = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            char c = s[i][j];\n            if (c == '0') {\n                er = i; ec = j;\n                board[i][j] = -1;\n            } else {\n                int v;\n                if ('0' <= c && c <= '9') v = c - '0';\n                else v = 10 + (c - 'a');\n                board[i][j] = id;\n                mask.push_back(v);\n                ++id;\n            }\n        }\n    }\n    // current masks (bits that are still free)\n    vector<int> curMask = mask;\n    vector<char> inComponent(M, 0);\n    string answer;\n    answer.reserve(T);\n\n    // ---------------------------------------------------------------------\n    // Step 0 : place the first tile (the root)\n    bool placedRoot = false;\n    for (int d = 0; d < 4 && !placedRoot; ++d) {\n        int nr = er + dr[d], nc = ec + dc[d];\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n        int tid = board[nr][nc];\n        if (tid == -1) continue;\n        int dir = bitFromDelta(dr[d], dc[d]);          // direction from empty to neighbour\n        if (mask[tid] & dir) {                         // it points to the empty square\n            char ch = charFromDelta(-dr[d], -dc[d]);   // slide the tile into the empty square\n            answer.push_back(ch);\n            board[er][ec] = tid;\n            board[nr][nc] = -1;\n            er = nr; ec = nc;\n            inComponent[tid] = 1;\n            placedRoot = true;\n            break;\n        }\n    }\n    if (!placedRoot) {                                 // fallback: any neighbour\n        for (int d = 0; d < 4 && !placedRoot; ++d) {\n            int nr = er + dr[d], nc = ec + dc[d];\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n            int tid = board[nr][nc];\n            if (tid == -1) continue;\n            char ch = charFromDelta(-dr[d], -dc[d]);\n            answer.push_back(ch);\n            board[er][ec] = tid;\n            board[nr][nc] = -1;\n            er = nr; ec = nc;\n            inComponent[tid] = 1;\n            placedRoot = true;\n            break;\n        }\n    }\n    int placedCnt = 1;          // we have one tile in the component\n\n    // ---------------------------------------------------------------------\n    // Main loop\n    while (placedCnt < M && (int)answer.size() < T) {\n        bool progress = false;\n\n        // ---- try to add a new vertex (Step 1) ---------------------------\n        for (int d = 0; d < 4 && !progress; ++d) {\n            int pr = er + dr[d], pc = ec + dc[d];\n            if (pr < 0 || pr >= N || pc < 0 || pc >= N) continue;\n            int parent = board[pr][pc];\n            if (parent == -1) continue;\n            if (!inComponent[parent]) continue;\n\n            int dirParent = bitFromDelta(dr[d], dc[d]);          // direction from parent to empty\n            if ((curMask[parent] & dirParent) == 0) continue;   // already used\n\n            int cr = er - dr[d], cc = ec - dc[d];\n            if (cr < 0 || cr >= N || cc < 0 || cc >= N) continue;\n            int child = board[cr][cc];\n            if (child == -1) continue;\n            if (inComponent[child]) continue;\n\n            int dirChild = oppBit(dirParent);                    // direction from child to parent\n            if ((curMask[child] & dirChild) == 0) continue;      // no opposite line\n\n            // perform the slide\n            char ch = charFromDelta(dr[d], dc[d]);               // child moves into empty\n            answer.push_back(ch);\n            board[er][ec] = child;\n            board[cr][cc] = -1;\n            er = cr; ec = cc;\n\n            // remove used bits\n            curMask[parent] &= ~dirParent;\n            curMask[child]  &= ~dirChild;\n            inComponent[child] = 1;\n            ++placedCnt;\n            progress = true;\n        }\n        if (progress) continue;\n\n        // ---- no possible edge, move the empty square (Step 2) ----------\n        bool moved = false;\n        for (int d = 0; d < 4 && !moved; ++d) {\n            int nr = er + dr[d], nc = ec + dc[d];\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n            int tid = board[nr][nc];\n            if (tid == -1) continue;\n            if (inComponent[tid]) continue;          // we prefer an unplaced tile\n            char ch = charFromDelta(-dr[d], -dc[d]); // slide it into the empty square\n            answer.push_back(ch);\n            board[er][ec] = tid;\n            board[nr][nc] = -1;\n            er = nr; ec = nc;\n            moved = true;\n        }\n        if (!moved) {                                 // should happen only when finished\n            // all neighbours are already in the component -> we are done\n            break;\n        }\n    }\n\n    cout << answer << '\\n';\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nusing ull = unsigned long long;\n\nstruct Line {\n    ll px, py, qx, qy;\n};\n\nstruct PairHash {\n    size_t operator()(const pair<ull, ull>& p) const noexcept {\n        return p.first ^ (p.second << 1);\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, K;\n    if (!(cin >> N >> K)) return 0;\n    vector<int> a(11);\n    for (int d = 1; d <= 10; ++d) cin >> a[d];\n    vector<ll> xs(N), ys(N);\n    for (int i = 0; i < N; ++i) cin >> xs[i] >> ys[i];\n\n    int sumA = 0;\n    for (int d = 1; d <= 10; ++d) sumA += a[d];\n\n    /* ---------- random generators ---------- */\n    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    // random integer inside the cake (radius 10000)\n    uniform_int_distribution<int> distInt(-10000, 10000);\n    auto randInside = [&]() -> pair<ll, ll> {\n        while (true) {\n            ll x = distInt(rng);\n            ll y = distInt(rng);\n            if (x * x + y * y < 100000000LL)   // 10^8\n                return {x, y};\n        }\n    };\n\n    // try to create a line that does not pass through any strawberry\n    auto generateLine = [&](int tries) -> optional<Line> {\n        for (int t = 0; t < tries; ++t) {\n            auto p = randInside();\n            auto q = randInside();\n            if (p == q) continue;\n            Line L{p.first, p.second, q.first, q.second};\n            ll dx = L.qx - L.px;\n            ll dy = L.qy - L.py;\n            bool ok = true;\n            for (int i = 0; i < N; ++i) {\n                ll cross = dx * (ys[i] - L.py) - dy * (xs[i] - L.px);\n                if (cross == 0) { ok = false; break; }\n            }\n            if (ok) return L;\n        }\n        return nullopt;\n    };\n\n    const int MAX_ATTEMPTS = 200;          // number of complete tries\n    int bestScore = -1;\n    vector<Line> bestLines;\n\n    for (int attempt = 0; attempt < MAX_ATTEMPTS; ++attempt) {\n        /* ----- create K random lines ----- */\n        vector<Line> lines;\n        lines.reserve(K);\n        for (int i = 0; i < K; ++i) {\n            auto L = generateLine(100);\n            if (!L) {                         // fallback \u2013 a line far away\n                lines.push_back({0, 20000, 1, 20000});\n            } else {\n                lines.push_back(*L);\n            }\n        }\n\n        /* ----- evaluate the partition ----- */\n        vector<ull> hi(N, 0), lo(N, 0);       // signature bits\n        for (int idx = 0; idx < K; ++idx) {\n            const Line& L = lines[idx];\n            ll dx = L.qx - L.px;\n            ll dy = L.qy - L.py;\n            for (int i = 0; i < N; ++i) {\n                ll cross = dx * (ys[i] - L.py) - dy * (xs[i] - L.px);\n                bool right = cross > 0;       // cross is never zero here\n                if (right) {\n                    if (idx < 64) lo[i] |= (1ULL << idx);\n                    else          hi[i] |= (1ULL << (idx - 64));\n                }\n            }\n        }\n\n        unordered_map<pair<ull, ull>, int, PairHash> mp;\n        mp.reserve(N * 2);\n        for (int i = 0; i < N; ++i) {\n            ++mp[{hi[i], lo[i]}];\n        }\n\n        vector<int> b(11, 0);\n        for (auto &kv : mp) {\n            int sz = kv.second;\n            if (1 <= sz && sz <= 10) ++b[sz];\n        }\n\n        int distributed = 0;\n        for (int d = 1; d <= 10; ++d)\n            distributed += min(a[d], b[d]);\n\n        if (distributed > bestScore) {\n            bestScore = distributed;\n            bestLines = lines;\n            if (distributed == sumA) break;   // perfect, stop early\n        }\n    }\n\n    /* ----- output ----- */\n    cout << bestLines.size() << '\\n';\n    for (const auto& L : bestLines)\n        cout << L.px << ' ' << L.py << ' ' << L.qx << ' ' << L.qy << '\\n';\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Candidate {\n    int mx, my;                       // missing corner\n    array<pair<int,int>,3> others;    // the three existing corners\n};\n\nint N, M;\nint center_;\nbool hasDot[61][61];\n\n// data structures for dot queries\nvector< set<int> > dotX, dotY;                     // 0 \u2026 N-1\nunordered_map<int, set<int> > dotD, dotS;        // d = x-y , s = x+y\n\n// data structures for generating candidates\nvector< vector<pair<int,int>> > dotsAtS;               // s -> list of points\nunordered_map<int, vector<pair<int,int>> > dotsAtD;   // d -> list of points\n\n// edges already drawn\nunordered_map<int, set<pair<int,int>>> edgeHor;   // y -> intervals of x\nunordered_map<int, set<pair<int,int>>> edgeVer;   // x -> intervals of y\nunordered_map<int, set<pair<int,int>>> edgeDiagP; // d -> intervals of x\nunordered_map<int, set<pair<int,int>>> edgeDiagM; // s -> intervals of x\n\ninline int weight(int x, int y) {\n    int dx = x - center_;\n    int dy = y - center_;\n    return dx*dx + dy*dy + 1;\n}\n\n// ---------- helpers for edges ----------\n\nbool adj(const pair<int,int>& a, const pair<int,int>& b) {\n    return (a.first == b.first) ||\n           (a.second == b.second) ||\n           (a.first - a.second == b.first - b.second) ||\n           (a.first + a.second == b.first + b.second);\n}\n\n// overlap test for one line\nbool hasOverlapOnLine(const unordered_map<int, set<pair<int,int>>>& mp,\n                      int line, int l, int r) {\n    auto it = mp.find(line);\n    if (it == mp.end()) return false;\n    const auto& st = it->second;\n    auto itr = st.lower_bound({l, INT_MIN});\n    if (itr != st.end()) {\n        int l2 = itr->first, r2 = itr->second;\n        if (max(l, l2) <= min(r, r2) - 1) return true;\n    }\n    if (itr != st.begin()) {\n        --itr;\n        int l2 = itr->first, r2 = itr->second;\n        if (max(l, l2) <= min(r, r2) - 1) return true;\n    }\n    return false;\n}\n\n// check whether the side (a,b) overlaps an existing edge\nbool edgeOverlap(const pair<int,int>& a, const pair<int,int>& b) {\n    if (a.first == b.first) {                     // vertical\n        int x = a.first;\n        int l = min(a.second, b.second);\n        int r = max(a.second, b.second);\n        return hasOverlapOnLine(edgeVer, x, l, r);\n    } else if (a.second == b.second) {           // horizontal\n        int y = a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        return hasOverlapOnLine(edgeHor, y, l, r);\n    } else if (a.first - a.second == b.first - b.second) { // diag +1\n        int d = a.first - a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        return hasOverlapOnLine(edgeDiagP, d, l, r);\n    } else {                                      // diag -1\n        int s = a.first + a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        return hasOverlapOnLine(edgeDiagM, s, l, r);\n    }\n}\n\n// insert an edge into the stored sets\nvoid addEdgeToSet(const pair<int,int>& a, const pair<int,int>& b) {\n    if (a.first == b.first) {\n        int x = a.first;\n        int l = min(a.second, b.second);\n        int r = max(a.second, b.second);\n        edgeVer[x].insert({l, r});\n    } else if (a.second == b.second) {\n        int y = a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        edgeHor[y].insert({l, r});\n    } else if (a.first - a.second == b.first - b.second) {\n        int d = a.first - a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        edgeDiagP[d].insert({l, r});\n    } else {\n        int s = a.first + a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        edgeDiagM[s].insert({l, r});\n    }\n}\n\n// does any dot lie on the open interval of the side ?\nbool dotOnEdgeOpen(const pair<int,int>& a, const pair<int,int>& b) {\n    if (a.first == b.first) {                 // vertical\n        int x = a.first;\n        int lo = min(a.second, b.second);\n        int hi = max(a.second, b.second);\n        const auto& st = dotX[x];\n        auto it = st.lower_bound(lo + 1);\n        if (it != st.end() && *it <= hi - 1) return true;\n        return false;\n    } else if (a.second == b.second) {       // horizontal\n        int y = a.second;\n        int lo = min(a.first, b.first);\n        int hi = max(a.first, b.first);\n        const auto& st = dotY[y];\n        auto it = st.lower_bound(lo + 1);\n        if (it != st.end() && *it <= hi - 1) return true;\n        return false;\n    } else if (a.first - a.second == b.first - b.second) { // diag +1\n        int d = a.first - a.second;\n        int lo = min(a.first, b.first);\n        int hi = max(a.first, b.first);\n        const auto& st = dotD[d];\n        auto it = st.lower_bound(lo + 1);\n        if (it != st.end() && *it <= hi - 1) return true;\n        return false;\n    } else {                                   // diag -1\n        int s = a.first + a.second;\n        int lo = min(a.first, b.first);\n        int hi = max(a.first, b.first);\n        const auto& st = dotS[s];\n        auto it = st.lower_bound(lo + 1);\n        if (it != st.end() && *it <= hi - 1) return true;\n        return false;\n    }\n}\n\n// ---------- test a candidate ----------\nbool isValidMove(const Candidate& cand) {\n    array<pair<int,int>,4> pts;\n    pts[0] = {cand.mx, cand.my};\n    pts[1] = cand.others[0];\n    pts[2] = cand.others[1];\n    pts[3] = cand.others[2];\n\n    // collect the four sides\n    vector<pair<pair<int,int>, pair<int,int>>> sides;\n    for (int i = 0; i < 4; ++i)\n        for (int j = i+1; j < 4; ++j)\n            if (adj(pts[i], pts[j]))\n                sides.push_back({pts[i], pts[j]});\n\n    if (sides.size() != 4) return false;   // should not happen\n\n    for (auto &e : sides) {\n        if (edgeOverlap(e.first, e.second)) return false;\n        if (dotOnEdgeOpen(e.first, e.second)) return false;\n    }\n    return true;\n}\n\n// ---------- add a new dot ----------\nvoid addDot(int x, int y) {\n    hasDot[x][y] = true;\n    dotX[x].insert(y);\n    dotY[y].insert(x);\n    int d = x - y;\n    int s = x + y;\n    dotD[d].insert(x);\n    dotS[s].insert(x);\n\n    dotsAtS[s].push_back({x, y});\n    dotsAtD[d].push_back({x, y});\n}\n\n// ---------- ordering for output ----------\nvector<pair<int,int>> order4(const Candidate& cand) {\n    array<pair<int,int>,4> pts;\n    pts[0] = {cand.mx, cand.my};\n    pts[1] = cand.others[0];\n    pts[2] = cand.others[1];\n    pts[3] = cand.others[2];\n\n    vector<pair<int,int>> adj;\n    int oppIdx = -1;\n    for (int i = 1; i < 4; ++i) {\n        if (adj(pts[0], pts[i])) adj.push_back(pts[i]);\n        else oppIdx = i;\n    }\n    // safety \u2013 should never happen for a legal rectangle\n    if (adj.size() != 2 || oppIdx == -1)\n        return {pts[0], pts[1], pts[2], pts[3]};\n\n    vector<pair<int,int>> res;\n    res.push_back(pts[0]);               // the new dot\n    res.push_back(adj[0]);               // one neighbour\n    res.push_back(pts[oppIdx]);          // opposite corner\n    res.push_back(adj[1]);               // the other neighbour\n    return res;\n}\n\n// ---------------------------------------------------------------\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> M;\n    center_ = (N - 1) / 2;\n\n    dotX.assign(N, {});\n    dotY.assign(N, {});\n    dotsAtS.assign(2*N-1, {});\n\n    for (int i = 0; i < M; ++i) {\n        int x, y; cin >> x >> y;\n        addDot(x, y);\n    }\n\n    long long sumW = 0;\n    for (int x = 0; x < N; ++x)\n        for (int y = 0; y < N; ++y)\n            if (hasDot[x][y]) sumW += weight(x, y);\n\n    vector< array<int,8> > operations;\n\n    // -----------------------------------------------------------\n    // main greedy loop\n    while (true) {\n        vector<Candidate> cand;\n        cand.reserve(80000);\n\n        // ----- axis\u2011parallel rectangles -----\n        for (int x = 0; x < N; ++x) {\n            const auto& ys = dotX[x];\n            vector<int> yvec(ys.begin(), ys.end());\n            int sz = (int)yvec.size();\n            for (int i = 0; i < sz; ++i) {\n                int y1 = yvec[i];\n                for (int j = i+1; j < sz; ++j) {\n                    int y2 = yvec[j];\n                    for (int x2 = 0; x2 < N; ++x2) if (x2 != x) {\n                        bool has1 = hasDot[x2][y1];\n                        bool has2 = hasDot[x2][y2];\n                        if (has1 && !has2) {                // missing (x2 , y2)\n                            if (!hasDot[x2][y2]) {\n                                Candidate c;\n                                c.mx = x2; c.my = y2;\n                                c.others[0] = {x, y1};\n                                c.others[1] = {x, y2};\n                                c.others[2] = {x2, y1};\n                                cand.push_back(c);\n                            }\n                        } else if (!has1 && has2) {        // missing (x2 , y1)\n                            if (!hasDot[x2][y1]) {\n                                Candidate c;\n                                c.mx = x2; c.my = y1;\n                                c.others[0] = {x, y1};\n                                c.others[1] = {x, y2};\n                                c.others[2] = {x2, y2};\n                                cand.push_back(c);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        // ----- 45\u00b0 squares -----\n        for (int s = 0; s < 2*N-1; ++s) {\n            const auto &vec = dotsAtS[s];\n            int sz = (int)vec.size();\n            for (int i = 0; i < sz; ++i) {\n                auto A = vec[i];\n                for (int j = i+1; j < sz; ++j) {\n                    auto B = vec[j];\n                    int dA = A.first - A.second;\n                    int dB = B.first - B.second;\n\n                    // C with d = dA\n                    auto itA = dotsAtD.find(dA);\n                    if (itA != dotsAtD.end()) {\n                        for (auto C : itA->second) {\n                            if (C.first + C.second == s) continue; // same s\n                            int s2 = C.first + C.second;\n                            int xm = (s2 + dB) / 2;\n                            int ym = (s2 - dB) / 2;\n                            if (xm < 0 || xm >= N || ym < 0 || ym >= N) continue;\n                            if (hasDot[xm][ym]) continue;\n                            Candidate c;\n                            c.mx = xm; c.my = ym;\n                            c.others[0] = A;\n                            c.others[1] = B;\n                            c.others[2] = C;\n                            cand.push_back(c);\n                        }\n                    }\n                    // C with d = dB\n                    auto itB = dotsAtD.find(dB);\n                    if (itB != dotsAtD.end()) {\n                        for (auto C : itB->second) {\n                            if (C.first + C.second == s) continue;\n                            int s2 = C.first + C.second;\n                            int xm = (s2 + dA) / 2;\n                            int ym = (s2 - dA) / 2;\n                            if (xm < 0 || xm >= N || ym < 0 || ym >= N) continue;\n                            if (hasDot[xm][ym]) continue;\n                            Candidate c;\n                            c.mx = xm; c.my = ym;\n                            c.others[0] = A;\n                            c.others[1] = B;\n                            c.others[2] = C;\n                            cand.push_back(c);\n                        }\n                    }\n                }\n            }\n        }\n\n        // ----- choose best -----\n        int bestIdx = -1;\n        int bestW = -1;\n        for (int i = 0; i < (int)cand.size(); ++i) {\n            if (!isValidMove(cand[i])) continue;\n            int w = weight(cand[i].mx, cand[i].my);\n            if (w > bestW) {\n                bestW = w;\n                bestIdx = i;\n            }\n        }\n        if (bestIdx == -1) break;            // no more moves\n\n        const Candidate &chosen = cand[bestIdx];\n        // add the dot\n        addDot(chosen.mx, chosen.my);\n        sumW += bestW;\n\n        // add the four edges\n        array<pair<int,int>,4> pts;\n        pts[0] = {chosen.mx, chosen.my};\n        pts[1] = chosen.others[0];\n        pts[2] = chosen.others[1];\n        pts[3] = chosen.others[2];\n        for (int i = 0; i < 4; ++i)\n            for (int j = i+1; j < 4; ++j)\n                if (adj(pts[i], pts[j]))\n                    addEdgeToSet(pts[i], pts[j]);\n\n        // store operation in required order\n        vector<pair<int,int>> order = order4(chosen);\n        array<int,8> op;\n        for (int k = 0; k < 4; ++k) {\n            op[2*k]   = order[k].first;\n            op[2*k+1] = order[k].second;\n        }\n        operations.push_back(op);\n    }\n\n    // ----- output -----\n    cout << operations.size() << '\\n';\n    for (auto &op : operations) {\n        for (int i = 0; i < 8; ++i) {\n            if (i) cout << ' ';\n            cout << op[i];\n        }\n        cout << '\\n';\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int SZ = 10;\n\n/* apply one tilt direction (in place) */\nvoid tilt(int a[SZ][SZ], char dir) {\n    if (dir == 'F') {                 // forward -> top\n        for (int c = 0; c < SZ; ++c) {\n            int wr = 0;\n            for (int r = 0; r < SZ; ++r) {\n                if (a[r][c] != 0) {\n                    if (wr != r) {\n                        a[wr][c] = a[r][c];\n                        a[r][c] = 0;\n                    }\n                    ++wr;\n                }\n            }\n        }\n    } else if (dir == 'B') {          // backward -> bottom\n        for (int c = 0; c < SZ; ++c) {\n            int wr = SZ - 1;\n            for (int r = SZ - 1; r >= 0; --r) {\n                if (a[r][c] != 0) {\n                    a[wr][c] = a[r][c];\n                    if (wr != r) a[r][c] = 0;\n                    --wr;\n                }\n            }\n        }\n    } else if (dir == 'L') {          // left\n        for (int r = 0; r < SZ; ++r) {\n            int wc = 0;\n            for (int c = 0; c < SZ; ++c) {\n                if (a[r][c] != 0) {\n                    a[r][wc] = a[r][c];\n                    if (wc != c) a[r][c] = 0;\n                    ++wc;\n                }\n            }\n        }\n    } else if (dir == 'R') {          // right\n        for (int r = 0; r < SZ; ++r) {\n            int wc = SZ - 1;\n            for (int c = SZ - 1; c >= 0; --c) {\n                if (a[r][c] != 0) {\n                    a[r][wc] = a[r][c];\n                    if (wc != c) a[r][c] = 0;\n                    --wc;\n                }\n            }\n        }\n    }\n}\n\n/* sum of squares of component sizes */\nlong long sumSquares(const int a[SZ][SZ]) {\n    bool vis[SZ][SZ] = {};\n    const int dr[4] = {-1, 1, 0, 0};\n    const int dc[4] = {0, 0, -1, 1};\n    long long sum = 0;\n    for (int r = 0; r < SZ; ++r) {\n        for (int c = 0; c < SZ; ++c) {\n            if (a[r][c] == 0 || vis[r][c]) continue;\n            int flavour = a[r][c];\n            int sz = 0;\n            queue<pair<int,int>> q;\n            q.emplace(r,c);\n            vis[r][c] = true;\n            while (!q.empty()) {\n                auto [cr, cc] = q.front(); q.pop();\n                ++sz;\n                for (int k = 0; k < 4; ++k) {\n                    int nr = cr + dr[k];\n                    int nc = cc + dc[k];\n                    if (0 <= nr && nr < SZ && 0 <= nc && nc < SZ &&\n                        !vis[nr][nc] && a[nr][nc] == flavour) {\n                        vis[nr][nc] = true;\n                        q.emplace(nr,nc);\n                    }\n                }\n            }\n            sum += 1LL * sz * sz;\n        }\n    }\n    return sum;\n}\n\n/* find the p-th empty cell (1\u2011based) */\npair<int,int> findEmptyCell(const int a[SZ][SZ], int p) {\n    for (int r = 0; r < SZ; ++r)\n        for (int c = 0; c < SZ; ++c)\n            if (a[r][c] == 0) {\n                --p;\n                if (p == 0) return {r, c};\n            }\n    return { -1, -1 }; // never reached\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int TOTAL = 100;\n    vector<int> flavour(TOTAL + 1);\n    for (int i = 1; i <= TOTAL; ++i) cin >> flavour[i];\n\n    int board[SZ][SZ];\n    for (int r = 0; r < SZ; ++r)\n        for (int c = 0; c < SZ; ++c)\n            board[r][c] = 0;\n\n    const array<char,4> dirs = {'F','B','L','R'};\n\n    for (int step = 1; step <= TOTAL; ++step) {\n        int p;               // which empty cell receives the new candy\n        cin >> p;\n        auto [r, c] = findEmptyCell(board, p);\n        board[r][c] = flavour[step];\n\n        char bestDir = 'F';\n        long long bestVal = -1;\n\n        for (char d : dirs) {\n            int tmp[SZ][SZ];\n            for (int i = 0; i < SZ; ++i)\n                for (int j = 0; j < SZ; ++j)\n                    tmp[i][j] = board[i][j];\n            tilt(tmp, d);\n            long long val = sumSquares(tmp);\n            if (val > bestVal) {\n                bestVal = val;\n                bestDir = d;\n            }\n        }\n\n        cout << bestDir << '\\n';\n        cout.flush();\n\n        tilt(board, bestDir);          // apply the chosen tilt\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int M;\n    double eps;\n    if (!(cin >> M >> eps)) return 0;\n\n    /* ---------- choose N ---------- */\n    int N = max(4, min(100, M + 5));\n    while (N * (N - 1) / 2 < M) ++N;          // safety\n    \n    const int L = N * (N - 1) / 2;           // number of edges\n    \n    /* ---------- list of edges in lexicographic order ---------- */\n    vector<pair<int,int>> edge;\n    edge.reserve(L);\n    for (int i = 0; i < N; ++i)\n        for (int j = i + 1; j < N; ++j)\n            edge.emplace_back(i, j);\n    \n    /* ---------- generate the M graphs ---------- */\n    vector<string> graphStr;\n    graphStr.reserve(M);\n    vector<vector<int>> degSorted;           // sorted degree sequences\n    degSorted.reserve(M);\n    \n    for (int idx = 0; idx < M; ++idx) {\n        string s(L, '0');\n        // deterministic random order of edges\n        vector<int> ord(L);\n        iota(ord.begin(), ord.end(), 0);\n        mt19937_64 rng(idx + 123456);         // fixed seed\n        shuffle(ord.begin(), ord.end(), rng);\n        for (int e = 0; e < idx; ++e) s[ord[e]] = '1';\n        graphStr.push_back(s);\n        \n        // degree vector\n        vector<int> deg(N, 0);\n        for (int e = 0; e < L; ++e)\n            if (s[e] == '1') {\n                ++deg[edge[e].first];\n                ++deg[edge[e].second];\n            }\n        vector<int> d = deg;\n        sort(d.begin(), d.end(), greater<int>());\n        degSorted.push_back(d);\n    }\n\n    /* ---------- output the description ---------- */\n    cout << N << '\\n';\n    for (const string& g : graphStr) cout << g << '\\n';\n    cout.flush();\n\n    /* ---------- pre\u2011compute log factorials ---------- */\n    vector<double> lfac(N + 1);\n    lfac[0] = 0.0;\n    for (int i = 1; i <= N; ++i) lfac[i] = lfac[i - 1] + log((double)i);\n\n    const bool zeroNoise = fabs(eps) < 1e-12;    // \u03b5 = 0 ?\n    const int n = N - 1;                        // number of incident edges\n\n    /* ---------- answer the 100 queries ---------- */\n    for (int q = 0; q < 100; ++q) {\n        string h;  cin >> h;\n        \n        // observed degrees\n        vector<int> degObs(N, 0);\n        for (int e = 0; e < L; ++e)\n            if (h[e] == '1') {\n                ++degObs[edge[e].first];\n                ++degObs[edge[e].second];\n            }\n        vector<int> dobs = degObs;\n        sort(dobs.begin(), dobs.end(), greater<int>());\n\n        int bestIdx = 0;\n        double bestScore = -1e300;              // -\u221e\n\n        for (int idx = 0; idx < M; ++idx) {\n            const vector<int>& dref = degSorted[idx];\n            double cur = 0.0;\n            bool possible = true;\n\n            for (int v = 0; v < N; ++v) {\n                int d0 = dref[v];               // original degree\n                int k  = dobs[v];               // observed degree\n\n                if (zeroNoise) {                // exact match\n                    if (k != d0) { possible = false; break; }\n                    continue;\n                }\n\n                // success probability of a single edge (formula (2))\n                double p = eps + (1.0 - 2.0 * eps) * (double)d0 / n;\n                if (p <= 0.0) {\n                    if (k != 0) { possible = false; break; }\n                    // probability = 1\n                } else if (p >= 1.0) {\n                    if (k != n) { possible = false; break; }\n                } else {\n                    double logC = lfac[n] - lfac[k] - lfac[n - k];\n                    double logp = log(p);\n                    double log1mp = log(1.0 - p);\n                    cur += logC + k * logp + (n - k) * log1mp;\n                }\n            }\n            if (!possible) continue;\n            if (cur > bestScore) {\n                bestScore = cur;\n                bestIdx = idx;\n            }\n        }\n        cout << bestIdx << '\\n';\n        cout.flush();\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v;\n    int w;\n    long long cost;          // cnt * w\n};\n\nstruct AdjEdge {\n    int to;\n    int w;\n    int id;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n    vector<Edge> edges(M);\n    vector<vector<AdjEdge>> adj(N + 1);\n    for (int i = 0; i < M; ++i) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        edges[i] = {u, v, w, 0};\n        adj[u].push_back({v, w, i});\n        adj[v].push_back({u, w, i});\n    }\n    // read and ignore coordinates\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    const long long INF = (1LL << 60);\n\n    // ---------- 1. compute cnt[e] ----------\n    vector<long long> cnt(M, 0);\n    vector<long long> dist(N + 1);\n    vector<int> parent_edge(N + 1, -1);\n    using P = pair<long long, int>;\n\n    for (int src = 1; src <= N; ++src) {\n        fill(dist.begin(), dist.end(), INF);\n        fill(parent_edge.begin(), parent_edge.end(), -1);\n        priority_queue<P, vector<P>, greater<P>> pq;\n        dist[src] = 0;\n        pq.emplace(0LL, src);\n        while (!pq.empty()) {\n            auto [du, u] = pq.top(); pq.pop();\n            if (du != dist[u]) continue;\n            for (const auto &e : adj[u]) {\n                int v = e.to;\n                long long nd = du + e.w;\n                if (nd < dist[v]) {\n                    dist[v] = nd;\n                    parent_edge[v] = e.id;\n                    pq.emplace(nd, v);\n                }\n            }\n        }\n        for (int v = 1; v <= N; ++v) {\n            if (v == src) continue;\n            int eid = parent_edge[v];\n            if (eid != -1) cnt[eid]++;          // directed pair (src , v)\n        }\n    }\n\n    // ---------- 2. compute cost = cnt * w ----------\n    for (int i = 0; i < M; ++i) {\n        edges[i].cost = cnt[i] * (long long)edges[i].w;\n    }\n\n    // ---------- 3. allocate edges to days ----------\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    // sort by decreasing cost\n    sort(order.begin(), order.end(),\n         [&](int a, int b) {\n             return edges[a].cost > edges[b].cost;\n         });\n\n    vector<int> dayCnt(D, 0);\n    vector<long long> dayLoad(D, 0);\n    vector<int> assign(M, -1);          // final answer: day 0..D-1\n\n    // random generator for tie breaking\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    for (int idx : order) {\n        long long bestLoad = LLONG_MAX;\n        vector<int> cand;\n        for (int d = 0; d < D; ++d) {\n            if (dayCnt[d] < K) {\n                if (dayLoad[d] < bestLoad) {\n                    bestLoad = dayLoad[d];\n                    cand.clear();\n                    cand.push_back(d);\n                } else if (dayLoad[d] == bestLoad) {\n                    cand.push_back(d);\n                }\n            }\n        }\n        // there is always at least one candidate\n        int chosen = cand.empty() ? 0 : cand[uniform_int_distribution<int>(0, (int)cand.size() - 1)(rng)];\n        assign[idx] = chosen;\n        ++dayCnt[chosen];\n        dayLoad[chosen] += edges[idx].cost;\n    }\n\n    // ---------- 4. output ----------\n    for (int i = 0; i < M; ++i) {\n        if (i) cout << ' ';\n        cout << (assign[i] + 1);      // days are 1\u2011based in output\n    }\n    cout << '\\n';\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D;\n    if (!(cin >> D)) return 0;\n    vector<string> f1(D), r1(D), f2(D), r2(D);\n    for (int z = 0; z < D; ++z) cin >> f1[z];\n    for (int z = 0; z < D; ++z) cin >> r1[z];\n    for (int z = 0; z < D; ++z) cin >> f2[z];\n    for (int z = 0; z < D; ++z) cin >> r2[z];\n\n    const int N = D * D * D;\n    auto idx = [&](int x, int y, int z) { return x * D * D + y * D + z; };\n\n    vector<char> allowed1(N, 0), allowed2(N, 0), inter(N, 0);\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                int id = idx(x, y, z);\n                allowed1[id] = (f1[z][x] == '1' && r1[z][y] == '1');\n                allowed2[id] = (f2[z][x] == '1' && r2[z][y] == '1');\n                inter[id] = allowed1[id] & allowed2[id];\n            }\n\n    /* ---------- connected components of intersection ---------- */\n    vector<int> comp(N, -1);\n    vector<int> compVolume;\n    vector<vector<int>> comps;\n    const int dx[6] = {1,-1,0,0,0,0};\n    const int dy[6] = {0,0,1,-1,0,0};\n    const int dz[6] = {0,0,0,0,1,-1};\n\n    for (int id = 0; id < N; ++id) if (inter[id] && comp[id] == -1) {\n        queue<int> q;\n        q.push(id);\n        comp[id] = (int)comps.size();\n        vector<int> cells;\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            cells.push_back(v);\n            int x = v / (D * D);\n            int rem = v % (D * D);\n            int y = rem / D;\n            int z = rem % D;\n            for (int dir = 0; dir < 6; ++dir) {\n                int nx = x + dx[dir], ny = y + dy[dir], nz = z + dz[dir];\n                if (nx < 0 || nx >= D || ny < 0 || ny >= D || nz < 0 || nz >= D) continue;\n                int nid = idx(nx, ny, nz);\n                if (inter[nid] && comp[nid] == -1) {\n                    comp[nid] = (int)comps.size();\n                    q.push(nid);\n                }\n            }\n        }\n        comps.push_back(move(cells));\n    }\n\n    int nShared = (int)comps.size();\n    vector<int> blockVol(nShared);\n    for (int i = 0; i < nShared; ++i) blockVol[i] = (int)comps[i].size();\n\n    /* ---------- output arrays ---------- */\n    vector<int> out1(N, 0), out2(N, 0);\n    for (int ci = 0; ci < nShared; ++ci) {\n        int bid = ci + 1;                       // block numbers start with 1\n        for (int v : comps[ci]) {\n            out1[v] = bid;\n            out2[v] = bid;\n        }\n    }\n\n    /* ---------- helper data ---------- */\n    bool frontCovered[2][14][14] = {}, rightCovered[2][14][14] = {};\n    for (int id = 0; id < N; ++id) if (inter[id]) {\n        int x = id / (D * D);\n        int rem = id % (D * D);\n        int y = rem / D;\n        int z = rem % D;\n        // object 0 (first pair)\n        frontCovered[0][z][x] = true;\n        rightCovered[0][z][y] = true;\n        // object 1 (second pair)\n        frontCovered[1][z][x] = true;\n        rightCovered[1][z][y] = true;\n    }\n\n    const vector<string>* f[2] = {&f1, &f2};\n    const vector<string>* r[2] = {&r1, &r2};\n    const vector<char>* allowed[2] = {&allowed1, &allowed2};\n\n    int nextBlock = nShared + 1;\n\n    /* ---------- exclusive blocks ---------- */\n    for (int obj = 0; obj < 2; ++obj) {\n        const vector<string>& fobj = *f[obj];\n        const vector<string>& robj = *r[obj];\n        const vector<char>& allow = *allowed[obj];\n        vector<int>& out = (obj == 0 ? out1 : out2);\n\n        for (int z = 0; z < D; ++z) {\n            // uncovered columns\n            vector<int> X, Y;\n            for (int x = 0; x < D; ++x)\n                if (fobj[z][x] == '1' && !frontCovered[obj][z][x]) X.push_back(x);\n            for (int y = 0; y < D; ++y)\n                if (robj[z][y] == '1' && !rightCovered[obj][z][y]) Y.push_back(y);\n            if (X.empty() && Y.empty()) continue;\n\n            int L = (int)X.size();\n            int R = (int)Y.size();\n\n            // adjacency from left (X) to right (Y)\n            vector<vector<int>> adj(L);\n            for (int li = 0; li < L; ++li) {\n                int x = X[li];\n                for (int rj = 0; rj < R; ++rj) {\n                    int y = Y[rj];\n                    int id = idx(x, y, z);\n                    if (allow[id] && !inter[id]) adj[li].push_back(rj);\n                }\n            }\n\n            // maximum matching (simple DFS augment)\n            vector<int> matchR(R, -1);\n            function<bool(int, vector<char>&)> dfs = [&](int v, vector<char>& seen) {\n                for (int to : adj[v]) {\n                    if (seen[to]) continue;\n                    seen[to] = true;\n                    if (matchR[to] == -1 || dfs(matchR[to], seen)) {\n                        matchR[to] = v;\n                        return true;\n                    }\n                }\n                return false;\n            };\n            int matchSize = 0;\n            for (int v = 0; v < L; ++v) {\n                vector<char> seen(R, false);\n                if (dfs(v, seen)) ++matchSize;\n            }\n\n            // edge cover\n            vector<char> coverL(L, 0), coverR(R, 0);\n            vector<pair<int,int>> edges; // (left index , right index)\n\n            // matched edges\n            for (int rj = 0; rj < R; ++rj) {\n                int li = matchR[rj];\n                if (li != -1) {\n                    edges.emplace_back(li, rj);\n                    coverL[li] = coverR[rj] = 1;\n                }\n            }\n\n            // uncovered left vertices\n            for (int li = 0; li < L; ++li) if (!coverL[li]) {\n                int x = X[li];\n                int y = -1;\n                for (int yy = 0; yy < D; ++yy) {\n                    int id = idx(x, yy, z);\n                    if (allow[id] && !inter[id]) { y = yy; break; }\n                }\n                // y must exist\n                // find its index in Y (may be -1 if it is a covered right column)\n                int rj = -1;\n                for (int jj = 0; jj < R; ++jj) if (Y[jj] == y) { rj = jj; break; }\n                edges.emplace_back(li, rj); // rj may be -1, handle later\n                coverL[li] = 1;\n            }\n\n            // uncovered right vertices\n            for (int rj = 0; rj < R; ++rj) if (!coverR[rj]) {\n                int y = Y[rj];\n                int x = -1;\n                for (int xx = 0; xx < D; ++xx) {\n                    int id = idx(xx, y, z);\n                    if (allow[id] && !inter[id]) { x = xx; break; }\n                }\n                // x must exist\n                int li = -1;\n                for (int ii = 0; ii < L; ++ii) if (X[ii] == x) { li = ii; break; }\n                edges.emplace_back(li, rj);\n                coverR[rj] = 1;\n            }\n\n            // avoid duplicate cells inside this layer\n            vector<vector<char>> used(D, vector<char>(D, 0));\n\n            for (auto [li, rj] : edges) {\n                int x = X[li];\n                int y;\n                if (rj >= 0) y = Y[rj];\n                else {\n                    // we stored a fallback edge with rj == -1, take the y we already found\n                    // (the previous step already found a suitable y)\n                    // recover y from the earlier search \u2013 we stored it when handling this left vertex\n                    // Let's redo the fallback in a simpler way:\n                    // we already added the edge when handling uncovered left, so we can just continue\n                    continue;\n                }\n                if (used[x][y]) continue;\n                used[x][y] = 1;\n                int id = idx(x, y, z);\n                out[id] = nextBlock++;\n            }\n        }\n    }\n\n    int totalBlocks = nextBlock - 1;\n    cout << totalBlocks << \"\\n\";\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << out1[i];\n    }\n    cout << \"\\n\";\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << out2[i];\n    }\n    cout << \"\\n\";\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nconst ll INF = (1LL << 60);\n\n/* ---------- global data ---------- */\nint N, M, K;\n\nvector<int> X, Y;                     // vertex coordinates\nvector<int> A, B;                     // resident coordinates\n\nstruct Edge {\n    int u, v;\n    int w;\n};\nvector<Edge> edges;                   // edges (1\u2011based index)\nvector<vector<pair<int,int>>> adj;    // (neighbour, edge index)\n\nvector<vector<ll>> dist2;              // squared distance vertex \u2192 resident\nvector<vector<ll>> wgt;               // weight matrix\nvector<vector<int>> edgeIdx;          // edge index matrix, -1 if none\n\n/* ---------- integer square root (ceil) ---------- */\nint ceil_sqrt_ll(ll x) {\n    if (x <= 0) return 0;\n    ll r = (ll)std::sqrt((double)x);\n    while (r * r < x) ++r;\n    while (r > 0 && (r-1)*(r-1) >= x) --r;\n    return (int)r;\n}\n\n/* ---------- evaluate a vertex set ---------- */\nvoid evaluate(const vector<int>& S,\n              bool& feasible,\n              ll& totalCost,\n              vector<int>& radius,\n              vector<int>& usedEdgeIdx)\n{\n    int nS = (int)S.size();\n    // ----- radius for each vertex -----\n    vector<ll> maxDist2(N + 1, 0);          // only used for vertices in S\n    // assign each resident to nearest vertex in S\n    for (int k = 0; k < K; ++k) {\n        ll bestDist = INF;\n        int bestVert = -1;\n        for (int v : S) {\n            ll d = dist2[v][k];\n            if (d < bestDist) {\n                bestDist = d;\n                bestVert = v;\n            }\n        }\n        if (bestVert != -1) {\n            if (bestDist > maxDist2[bestVert]) maxDist2[bestVert] = bestDist;\n        }\n    }\n    // compute radii\n    radius.assign(N + 1, 0);\n    feasible = true;\n    ll sumSq = 0;\n    for (int v : S) {\n        ll md2 = maxDist2[v];\n        int r = 0;\n        if (md2 > 0) r = ceil_sqrt_ll(md2);\n        if (r > 5000) { feasible = false; return; }\n        radius[v] = r;\n        sumSq += 1LL * r * r;\n    }\n\n    // ----- minimum spanning tree of S (Prim) -----\n    vector<char> inS(N + 1, 0);\n    for (int v : S) inS[v] = 1;\n\n    vector<ll> minEdge(N + 1, INF);\n    vector<int> parent(N + 1, -1);\n    vector<int> parentEdge(N + 1, -1);\n    vector<char> visited(N + 1, 0);\n\n    visited[1] = 1;                         // source is always in S\n    for (int u = 1; u <= N; ++u) {\n        if (!inS[u] || u == 1) continue;\n        if (edgeIdx[1][u] != -1) {\n            minEdge[u] = wgt[1][u];\n            parent[u] = 1;\n            parentEdge[u] = edgeIdx[1][u];\n        }\n    }\n\n    usedEdgeIdx.clear();\n    ll edgeCost = 0;\n    for (int it = 0; it < nS - 1; ++it) {\n        int v = -1;\n        ll best = INF;\n        for (int u = 1; u <= N; ++u) {\n            if (inS[u] && !visited[u] && minEdge[u] < best) {\n                best = minEdge[u];\n                v = u;\n            }\n        }\n        if (v == -1) {          // not connected\n            feasible = false;\n            return;\n        }\n        visited[v] = 1;\n        edgeCost += best;\n        usedEdgeIdx.push_back(parentEdge[v]);\n\n        // relax edges from v\n        for (int u = 1; u <= N; ++u) {\n            if (inS[u] && !visited[u] && edgeIdx[v][u] != -1) {\n                ll w = wgt[v][u];\n                if (w < minEdge[u]) {\n                    minEdge[u] = w;\n                    parent[u] = v;\n                    parentEdge[u] = edgeIdx[v][u];\n                }\n            }\n        }\n    }\n\n    totalCost = sumSq + edgeCost;\n}\n\n/* ---------- main ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    /* ----- input ----- */\n    cin >> N >> M >> K;\n    X.resize(N + 1);\n    Y.resize(N + 1);\n    for (int i = 1; i <= N; ++i) cin >> X[i] >> Y[i];\n\n    edges.resize(M + 1);                 // 1\u2011based\n    adj.assign(N + 1, {});\n    wgt.assign(N + 1, vector<ll>(N + 1, INF));\n    edgeIdx.assign(N + 1, vector<int>(N + 1, -1));\n\n    for (int j = 1; j <= M; ++j) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        edges[j] = {u, v, w};\n        adj[u].push_back({v, j});\n        adj[v].push_back({u, j});\n        if (w < wgt[u][v]) {\n            wgt[u][v] = wgt[v][u] = w;\n            edgeIdx[u][v] = edgeIdx[v][u] = j;\n        }\n    }\n\n    A.resize(K);\n    B.resize(K);\n    for (int k = 0; k < K; ++k) cin >> A[k] >> B[k];\n\n    /* ----- pre\u2011compute squared distances ----- */\n    dist2.assign(N + 1, vector<ll>(K));\n    for (int i = 1; i <= N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            ll dx = X[i] - A[k];\n            ll dy = Y[i] - B[k];\n            dist2[i][k] = dx * dx + dy * dy;\n        }\n    }\n\n    /* ----- start with vertex 1 only ----- */\n    vector<int> curS = {1};\n    vector<char> inS(N + 1, 0);\n    inS[1] = 1;\n\n    bool feasible = false;\n    ll curCost = 0;\n    vector<int> curRadius;\n    vector<int> curEdges;\n\n    evaluate(curS, feasible, curCost, curRadius, curEdges);\n    if (feasible) {\n        // best solution already\n    } else {\n        /* ---- greedy expansion until feasible ---- */\n        while (true) {\n            // find candidates \u2013 vertices adjacent to current S\n            vector<int> cand;\n            vector<char> candFlag(N + 1, 0);\n            for (int e = 1; e <= M; ++e) {\n                int u = edges[e].u, v = edges[e].v;\n                if (inS[u] ^ inS[v]) {\n                    int x = inS[u] ? v : u;\n                    if (!candFlag[x]) {\n                        candFlag[x] = 1;\n                        cand.push_back(x);\n                    }\n                }\n            }\n            // try every candidate\n            ll bestCost = INF;\n            int bestCand = -1;\n            bool bestFeas = false;\n            vector<int> bestRadiusTmp;\n            vector<int> bestEdgesTmp;\n            for (int v : cand) {\n                vector<int> ns = curS;\n                ns.push_back(v);\n                bool f; ll c; vector<int> rad; vector<int> ed;\n                evaluate(ns, f, c, rad, ed);\n                if (!f) continue;\n                if (c < bestCost) {\n                    bestCost = c;\n                    bestCand = v;\n                    bestFeas = f;\n                    bestRadiusTmp = rad;\n                    bestEdgesTmp = ed;\n                }\n            }\n            if (bestCand == -1) {\n                // should not happen \u2013 we can always add more vertices\n                // fallback: add any remaining vertex\n                for (int v = 1; v <= N; ++v) if (!inS[v]) {\n                    vector<int> ns = curS; ns.push_back(v);\n                    bool f; ll c; vector<int> rad; vector<int> ed;\n                    evaluate(ns, f, c, rad, ed);\n                    if (f) { bestCand = v; bestCost = c; bestFeas = f;\n                            bestRadiusTmp = rad; bestEdgesTmp = ed; }\n                    break;\n                }\n                if (bestCand == -1) break;   // safety\n            }\n            // apply best addition\n            inS[bestCand] = 1;\n            curS.push_back(bestCand);\n            evaluate(curS, feasible, curCost, curRadius, curEdges);\n            if (feasible) break;\n        }\n    }\n\n    /* ----- store best solution ----- */\n    ll bestCost = curCost;\n    vector<int> bestS = curS;\n    vector<int> bestRadius = curRadius;\n    vector<int> bestEdges = curEdges;\n\n    /* ----- improvement: removal + addition ----- */\n    bool changed = true;\n    while (changed) {\n        changed = false;\n        /* removal */\n        for (size_t i = 0; i < bestS.size(); ++i) {\n            int v = bestS[i];\n            if (v == 1) continue;               // cannot remove the source\n            vector<int> ns = bestS;\n            ns.erase(ns.begin() + i);\n            bool f; ll c; vector<int> rad; vector<int> ed;\n            evaluate(ns, f, c, rad, ed);\n            if (f && c < bestCost - 1) {\n                bestCost = c;\n                bestS = ns;\n                inS[v] = 0;\n                bestRadius = rad;\n                bestEdges = ed;\n                changed = true;\n                break;                           // restart\n            }\n        }\n        if (changed) continue;\n\n        /* addition of a neighbour that improves the cost */\n        // collect neighbours of current set\n        vector<int> cand;\n        vector<char> candFlag(N + 1, 0);\n        for (int e = 1; e <= M; ++e) {\n            int u = edges[e].u, v = edges[e].v;\n            if (inS[u] ^ inS[v]) {\n                int x = inS[u] ? v : u;\n                if (!candFlag[x]) {\n                    candFlag[x] = 1;\n                    cand.push_back(x);\n                }\n            }\n        }\n        for (int v : cand) {\n            vector<int> ns = bestS;\n            ns.push_back(v);\n            bool f; ll c; vector<int> rad; vector<int> ed;\n            evaluate(ns, f, c, rad, ed);\n            if (f && c < bestCost - 1) {\n                bestCost = c;\n                bestS = ns;\n                inS[v] = 1;\n                bestRadius = rad;\n                bestEdges = ed;\n                changed = true;\n                break;\n            }\n        }\n    }\n\n    /* ----- prepare output ----- */\n    vector<int> P(N + 1, 0);\n    for (int i = 1; i <= N; ++i) {\n        if (i < (int)bestRadius.size())\n            P[i] = bestRadius[i];          // zero for all other vertices\n    }\n\n    vector<int> B(M + 1, 0);\n    for (int id : bestEdges) B[id] = 1;\n\n    /* ----- print ----- */\n    for (int i = 1; i <= N; ++i) {\n        if (i > 1) cout << ' ';\n        cout << P[i];\n    }\n    cout << '\\n';\n    for (int j = 1; j <= M; ++j) {\n        if (j > 1) cout << ' ';\n        cout << B[j];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int N = 30;\n    const int M = N * (N + 1) / 2;          // 465\n\n    // index of each coordinate\n    vector<vector<int>> idx(N, vector<int>(N, -1));\n    int curIdx = 0;\n    for (int x = 0; x < N; ++x) {\n        for (int y = 0; y <= x; ++y) {\n            idx[x][y] = curIdx++;\n        }\n    }\n\n    // read the permutation\n    vector<int> value(M);\n    for (int x = 0; x < N; ++x) {\n        for (int y = 0; y <= x; ++y) {\n            int v;\n            if (!(cin >> v)) return 0;\n            value[idx[x][y]] = v;\n        }\n    }\n\n    struct Swap {\n        int x1, y1, x2, y2;\n    };\n    vector<Swap> ops;\n\n    // heapify: process nodes from last non\u2011leaf level up to root\n    for (int x = N - 2; x >= 0; --x) {\n        for (int y = 0; y <= x; ++y) {\n            int curX = x, curY = y;\n            while (curX < N - 1) {\n                int cur = idx[curX][curY];\n                int childX = curX + 1;\n                int leftY  = curY;\n                int rightY = curY + 1;\n\n                int left  = idx[childX][leftY];\n                int right = idx[childX][rightY];\n\n                // find the smaller child that violates the heap property\n                int child = -1;\n                int childX2 = -1, childY2 = -1;\n                if (value[cur] > value[left]) {\n                    child = left;\n                    childX2 = childX; childY2 = leftY;\n                }\n                if (value[cur] > value[right]) {\n                    if (child == -1 || value[right] < value[child]) {\n                        child = right;\n                        childX2 = childX; childY2 = rightY;\n                    }\n                }\n                if (child == -1) break;          // heap property satisfied\n\n                // perform the swap\n                ops.push_back({curX, curY, childX2, childY2});\n                swap(value[cur], value[child]);\n\n                // continue sifting the moved ball downwards\n                curX = childX2;\n                curY = childY2;\n            }\n        }\n    }\n\n    // output\n    cout << ops.size() << '\\n';\n    for (auto &s : ops) {\n        cout << s.x1 << ' ' << s.y1 << ' ' << s.x2 << ' ' << s.y2 << '\\n';\n    }\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int D = 9;\nconst int dr[4] = {-1, 1, 0, 0};\nconst int dc[4] = {0, 0, -1, 1};\nconst int INF = 1e9;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> D >> N)) return 0;\n    vector<vector<bool>> obstacle(D, vector<bool>(D, false));\n    for (int k = 0; k < N; ++k) {\n        int ri, rj;\n        cin >> ri >> rj;\n        obstacle[ri][rj] = true;\n    }\n\n    const int R = 0;\n    const int C = (D - 1) / 2;          // entrance (0,4)\n\n    // ---------- depth (BFS) ----------\n    vector<vector<int>> depth(D, vector<int>(D, -1));\n    queue<pair<int,int>> q;\n    depth[R][C] = 0;\n    q.emplace(R, C);\n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        for (int dir = 0; dir < 4; ++dir) {\n            int nr = r + dr[dir], nc = c + dc[dir];\n            if (nr < 0 || nr >= D || nc < 0 || nc >= D) continue;\n            if (obstacle[nr][nc]) continue;\n            if (depth[nr][nc] != -1) continue;\n            depth[nr][nc] = depth[r][c] + 1;\n            q.emplace(nr, nc);\n        }\n    }\n\n    const int M = D * D - 1 - N;               // number of containers\n\n    // containers are numbered 0 .. M-1\n    vector<int> pos_x(M, -1), pos_y(M, -1);\n    vector<vector<int>> number_at(D, vector<int>(D, -1));   // container number stored here\n\n    vector<vector<bool>> occupied(D, vector<bool>(D, false));\n    // entrance is never occupied\n\n    // -----------------------------------------------------------------\n    //  storing phase\n    // -----------------------------------------------------------------\n    for (int step = 0; step < M; ++step) {\n        int t;  // container number arriving now\n        cin >> t;\n\n        // build current empty graph and find articulation points\n        vector<vector<bool>> empty(D, vector<bool>(D, false));\n        for (int i = 0; i < D; ++i)\n            for (int j = 0; j < D; ++j)\n                if (!obstacle[i][j] && !occupied[i][j])\n                    empty[i][j] = true;\n\n        // Tarjan articulation points\n        vector<vector<int>> disc(D, vector<int>(D, 0));\n        vector<vector<int>> low(D, vector<int>(D, 0));\n        vector<vector<bool>> visited(D, vector<bool>(D, false));\n        vector<vector<bool>> isArt(D, vector<bool>(D, false));\n        int timer = 0;\n        function<void(int,int,int,int)> dfs = [&](int r, int c, int parent_r, int parent_c) {\n            visited[r][c] = true;\n            disc[r][c] = low[r][c] = ++timer;\n            int child = 0;\n            for (int d = 0; d < 4; ++d) {\n                int nr = r + dr[d], nc = c + dc[d];\n                if (nr < 0 || nr >= D || nc < 0 || nc >= D) continue;\n                if (!empty[nr][nc]) continue;\n                if (nr == parent_r && nc == parent_c) continue;\n                if (!visited[nr][nc]) {\n                    ++child;\n                    dfs(nr, nc, r, c);\n                    low[r][c] = min(low[r][c], low[nr][nc]);\n                    if (parent_r == -1 && child > 1) isArt[r][c] = true;\n                    if (parent_r != -1 && low[nr][nc] >= disc[r][c]) isArt[r][c] = true;\n                } else {\n                    low[r][c] = min(low[r][c], disc[nr][nc]);\n                }\n            }\n        };\n        dfs(R, C, -1, -1);\n\n        // choose the best empty non\u2011articulation square with minimal depth\n        int best_r = -1, best_c = -1, bestDepth = INF;\n        for (int i = 0; i < D; ++i) {\n            for (int j = 0; j < D; ++j) {\n                if (i == R && j == C) continue;          // entrance cannot be used\n                if (!empty[i][j]) continue;\n                if (isArt[i][j]) continue;                // cannot use a cut vertex\n                if (depth[i][j] < bestDepth) {\n                    bestDepth = depth[i][j];\n                    best_r = i; best_c = j;\n                }\n            }\n        }\n        // (by Lemma 3 such a cell always exists)\n        // store the container\n        occupied[best_r][best_c] = true;\n        number_at[best_r][best_c] = t;\n        pos_x[t] = best_r;\n        pos_y[t] = best_c;\n\n        cout << best_r << ' ' << best_c << '\\n';\n        cout.flush();\n    }\n\n    // -----------------------------------------------------------------\n    //  retrieval phase \u2013 output squares in non\u2011decreasing depth\n    // -----------------------------------------------------------------\n    vector<pair<int,int>> order; // (depth, container number)\n    for (int num = 0; num < M; ++num) {\n        int r = pos_x[num];\n        int c = pos_y[num];\n        order.emplace_back(depth[r][c], num);\n    }\n    sort(order.begin(), order.end(),\n         [](const pair<int,int>& a, const pair<int,int>& b){\n             if (a.first != b.first) return a.first < b.first;\n             return a.second < b.second;\n         });\n\n    for (auto &p : order) {\n        int num = p.second;\n        cout << pos_x[num] << ' ' << pos_y[num] << '\\n';\n    }\n    cout.flush();\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\nint n, m;\nconst int MAXC = 100 + 5;            // colours 0 \u2026 m\nint a[55][55];                       // current colours\nint total[MAXC];                     // number of squares of each colour\nint adjCnt[MAXC][MAXC];              // current number of adjacency edges\nbool need[MAXC][MAXC];               // adjacency existed in the original map\n\nint dx[4] = {-1, 1, 0, 0};\nint dy[4] = {0, 0, -1, 1};\n\nint vis[55][55];\nint bfsStamp = 0;\n\n/* --------------------------------------------------------------- */\n// check whether the square (x,y) can be turned into 0\nbool canDelete(int x, int y) {\n    int c = a[x][y];\n    if (c == 0) return false;\n    if (total[c] <= 1) return false;                // colour must survive\n\n    // 1) adjacent to zero (or outside)\n    bool adjZero = false;\n    for (int dir = 0; dir < 4; ++dir) {\n        int nx = x + dx[dir], ny = y + dy[dir];\n        if (nx < 0 || nx >= n || ny < 0 || ny >= n) { adjZero = true; break; }\n        if (a[nx][ny] == 0) { adjZero = true; break; }\n    }\n    if (!adjZero) return false;\n\n    // collect neighbour colours (including 0 for outside)\n    int nbCol[4];\n    bool nbOut[4];\n    for (int dir = 0; dir < 4; ++dir) {\n        int nx = x + dx[dir], ny = y + dy[dir];\n        if (nx < 0 || nx >= n || ny < 0 || ny >= n) {\n            nbCol[dir] = 0;\n            nbOut[dir] = true;\n        } else {\n            nbCol[dir] = a[nx][ny];\n            nbOut[dir] = false;\n        }\n    }\n\n    // 2) no illegal new adjacency 0\u2011d\n    for (int dir = 0; dir < 4; ++dir) {\n        int d = nbCol[dir];\n        if (d == c) continue;\n        if (d != 0 && !need[0][d]) return false;      // would create forbidden 0\u2011d\n    }\n\n    // 3) keep at least one adjacency for every required pair\n    for (int dir = 0; dir < 4; ++dir) {\n        int d = nbCol[dir];\n        if (d == c) continue;\n        if (need[c][d] && adjCnt[c][d] <= 1) return false;\n    }\n\n    // 4) connectivity of the colour after removal\n    // find a start cell of colour c different from (x,y)\n    int sx = -1, sy = -1;\n    for (int dir = 0; dir < 4; ++dir) {\n        int nx = x + dx[dir], ny = y + dy[dir];\n        if (0 <= nx && nx < n && 0 <= ny && ny < n && a[nx][ny] == c) {\n            sx = nx; sy = ny;\n            break;\n        }\n    }\n    if (sx == -1) return false;          // no other cell of this colour\n\n    ++bfsStamp;\n    queue<pair<int,int>> q;\n    q.emplace(sx, sy);\n    vis[sx][sy] = bfsStamp;\n    int cnt = 0;\n    while (!q.empty()) {\n        auto [cx, cy] = q.front(); q.pop();\n        ++cnt;\n        for (int dir = 0; dir < 4; ++dir) {\n            int nx = cx + dx[dir], ny = cy + dy[dir];\n            if (nx < 0 || nx >= n || ny < 0 || ny >= n) continue;\n            if (a[nx][ny] != c) continue;\n            if (nx == x && ny == y) continue;          // the removed cell\n            if (vis[nx][ny] == bfsStamp) continue;\n            vis[nx][ny] = bfsStamp;\n            q.emplace(nx, ny);\n        }\n    }\n    if (cnt != total[c] - 1) return false;            // would disconnect\n\n    return true;\n}\n\n/* --------------------------------------------------------------- */\n// really delete the square (x,y)\nvoid doDelete(int x, int y) {\n    int c = a[x][y];\n    a[x][y] = 0;\n    --total[c];\n\n    for (int dir = 0; dir < 4; ++dir) {\n        int nx = x + dx[dir], ny = y + dy[dir];\n        int nd;\n        bool outside = false;\n        if (nx < 0 || nx >= n || ny < 0 || ny >= n) {\n            nd = 0;\n            outside = true;\n        } else {\n            nd = a[nx][ny];\n        }\n        if (nd == c) continue;                 // same colour, irrelevant\n\n        // remove adjacency c \u2013 nd\n        --adjCnt[c][nd];\n        --adjCnt[nd][c];\n\n        // create new adjacency 0 \u2013 nd (if nd is inside the board)\n        if (!outside && nd != 0) {\n            ++adjCnt[0][nd];\n            ++adjCnt[nd][0];\n        }\n    }\n\n    // neighbours become candidates (they may have a zero neighbour now)\n    for (int dir = 0; dir < 4; ++dir) {\n        int nx = x + dx[dir], ny = y + dy[dir];\n        if (0 <= nx && nx < n && 0 <= ny && ny < n && a[nx][ny] > 0) {\n            // will be pushed into the global queue later\n            q.emplace(nx, ny);\n        }\n    }\n}\n\n/* --------------------------------------------------------------- */\nqueue<pair<int,int>> q;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> n >> m;\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j)\n            cin >> a[i][j];\n\n    /* ----- initial adjacency counting ----- */\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            int c = a[i][j];\n            ++total[c];\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + dx[dir], nj = j + dy[dir];\n                if (ni < 0 || ni >= n || nj < 0 || nj >= n) {\n                    ++adjCnt[c][0];\n                    ++adjCnt[0][c];\n                } else {\n                    int d = a[ni][nj];\n                    if (d != c) {\n                        ++adjCnt[c][d];\n                        ++adjCnt[d][c];\n                    }\n                }\n            }\n        }\n    }\n\n    /* ----- which adjacencies exist in the original map ----- */\n    for (int c = 0; c <= m; ++c)\n        for (int d = 0; d <= m; ++d)\n            need[c][d] = (adjCnt[c][d] > 0);\n\n    /* ----- initialise candidate queue (border squares) ----- */\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) if (a[i][j] > 0) {\n            bool adjZero = false;\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + dx[dir], nj = j + dy[dir];\n                if (ni < 0 || ni >= n || nj < 0 || nj >= n) { adjZero = true; break; }\n                if (a[ni][nj] == 0) { adjZero = true; break; }\n            }\n            if (adjZero) q.emplace(i, j);\n        }\n    }\n\n    /* ----- main loop ----- */\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        if (a[x][y] == 0) continue;               // already deleted\n        if (canDelete(x, y))\n            doDelete(x, y);\n    }\n\n    /* ----- output ----- */\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            if (j) cout << ' ';\n            cout << a[i][j];\n        }\n        cout << '\\n';\n    }\n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, D, Q;\n    if (!(cin >> N >> D >> Q)) return 0;\n    \n    // win[i] \u2013 times item i was heavier, tie[i] \u2013 times equal\n    vector<int> win(N, 0), tie(N, 0);\n    int performed = 0;\n    \n    // ------------------------------------------------------------\n    // 1) forced consecutive pairs (every item appears at least once)\n    for (int i = 0; i + 1 < N && performed < Q; ++i) {\n        int a = i, b = i + 1;\n        cout << \"1 1 \" << a << ' ' << b << \"\\n\";\n        cout.flush();\n        ++performed;\n        string res; cin >> res;\n        if (res == \">\") {\n            ++win[a];\n        } else if (res == \"<\") {\n            ++win[b];\n        } else { // \"=\"\n            ++tie[a];\n            ++tie[b];\n        }\n    }\n    // ------------------------------------------------------------\n    // 2) random pairs until we have performed exactly Q queries\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    while (performed < Q) {\n        int a = rng() % N;\n        int b = rng() % N;\n        if (a == b) continue;\n        if (a > b) swap(a, b);\n        cout << \"1 1 \" << a << ' ' << b << \"\\n\";\n        cout.flush();\n        ++performed;\n        string res; cin >> res;\n        if (res == \">\") {\n            ++win[a];\n        } else if (res == \"<\") {\n            ++win[b];\n        } else { // \"=\"\n            ++tie[a];\n            ++tie[b];\n        }\n    }\n    \n    // ------------------------------------------------------------\n    // 3) compute rough weight estimates and sort items\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    vector<double> score(N);\n    for (int i = 0; i < N; ++i) score[i] = win[i] + 0.5 * tie[i];\n    stable_sort(idx.begin(), idx.end(),\n                [&](int a, int b) { return score[a] > score[b]; });\n    \n    // ------------------------------------------------------------\n    // 4) LPT (Longest Processing Time) assignment to D groups\n    vector<double> groupSum(D, 0.0);\n    vector<int> groupOf(N, -1);\n    for (int pos = 0; pos < N; ++pos) {\n        int it = idx[pos];\n        // find group with minimal current sum\n        int best = 0;\n        for (int g = 1; g < D; ++g) {\n            if (groupSum[g] < groupSum[best]) best = g;\n        }\n        groupOf[it] = best;\n        groupSum[best] += score[it];\n    }\n    \n    // ------------------------------------------------------------\n    // 5) output the final partition\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << groupOf[i];\n    }\n    cout << \"\\n\";\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    const int per = n / m;                // 20\n    vector<vector<int>> st(m);            // bottom = index 0, top = back()\n    vector<int> where(n + 1, -1);          // current stack of each box (0\u2011based)\n\n    for (int i = 0; i < m; ++i) {\n        st[i].reserve(per);\n        for (int j = 0; j < per; ++j) {\n            int v; cin >> v;\n            st[i].push_back(v);\n            where[v] = i;\n        }\n    }\n\n    vector<pair<int,int>> ops;            // (box, destination)  destination = 0 \u2192 carry out\n\n    for (int v = 1; v <= n; ++v) {\n        int src = where[v];                // stack that currently contains v\n        // while v is not the top of its stack, move the boxes above it\n        while (!st[src].empty() && st[src].back() != v) {\n            int curTop = st[src].back();   // the box that will be moved now\n            int dest = -1;\n\n            // 1) look for a stack whose top is larger than curTop\n            int bestTop = -1;\n            for (int i = 0; i < m; ++i) {\n                if (i == src) continue;\n                if (!st[i].empty() && st[i].back() > curTop) {\n                    if (st[i].back() > bestTop) {\n                        bestTop = st[i].back();\n                        dest = i;\n                    }\n                }\n            }\n            // 2) if not found, try to use an empty stack\n            if (dest == -1) {\n                for (int i = 0; i < m; ++i) {\n                    if (i == src) continue;\n                    if (st[i].empty()) {\n                        dest = i;\n                        break;\n                    }\n                }\n            }\n            // 3) otherwise take any other stack (the order may become temporarily non\u2011decreasing)\n            if (dest == -1) {\n                for (int i = 0; i < m; ++i) {\n                    if (i == src) continue;\n                    dest = i;\n                    break;\n                }\n            }\n\n            // ----- perform operation 1 -----\n            ops.emplace_back(curTop, dest + 1);   // destination is 1\u2011based in output\n            // move the single box\n            st[src].pop_back();\n            st[dest].push_back(curTop);\n            where[curTop] = dest;\n        }\n\n        // now v is on the top \u2013 carry it out (operation 2)\n        ops.emplace_back(v, 0);\n        int src = where[v];\n        st[src].pop_back();\n        where[v] = -1;                     // mark as removed\n    }\n\n    // output\n    cout << ops.size() << '\\n';\n    for (auto [box, dst] : ops) {\n        cout << box << ' ' << dst << '\\n';\n    }\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing pii = pair<int,int>;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if(!(cin>>N)) return 0;\n    vector<string> h(N-1);\n    for (int i=0;i<N-1;i++) cin>>h[i];\n    vector<string> v(N);\n    for (int i=0;i<N;i++) cin>>v[i];\n    vector<vector<int>> d(N, vector<int>(N));\n    for (int i=0;i<N;i++)\n        for (int j=0;j<N;j++) cin>>d[i][j];\n\n    const int V = N*N;\n    auto id = [&](int i,int j){ return i*N + j; };\n\n    // adjacency of the board (no walls)\n    vector<vector<int>> adj(V);\n    const int di[4] = {0,1,0,-1};\n    const int dj[4] = {1,0,-1,0};\n    const char dc[4] = {'R','D','L','U'};\n    for (int i=0;i<N;i++) for (int j=0;j<N;j++) {\n        int u = id(i,j);\n        // right\n        if (j+1<N && v[i][j]=='0') adj[u].push_back(id(i,j+1));\n        // left\n        if (j-1>=0 && v[i][j-1]=='0') adj[u].push_back(id(i,j-1));\n        // down\n        if (i+1<N && h[i][j]=='0') adj[u].push_back(id(i+1,j));\n        // up\n        if (i-1>=0 && h[i-1][j]=='0') adj[u].push_back(id(i-1,j));\n    }\n\n    /* ------------------------------------------------------------\n       1.  base DFS walk \u2013 visits every cell, returns to (0,0)\n       ------------------------------------------------------------ */\n    vector<vector<char>> dirChar(4, vector<char>(4));\n    for (int k=0;k<4;k++) {\n        int ni = di[k], nj = dj[k];\n        // reverse direction\n        int rev = (k+2)%4;\n        dirChar[k][rev] = dc[k];\n        dirChar[rev][k] = dc[rev];\n    }\n\n    vector<vector<int>> visited(N, vector<int>(N,0));\n    string baseMoves;\n    function<void(int,int)> dfs = [&](int i,int j){\n        visited[i][j]=1;\n        for (int dir=0; dir<4; ++dir){\n            int ni=i+di[dir], nj=j+dj[dir];\n            if (ni<0||ni>=N||nj<0||nj>=N) continue;\n            if (visited[ni][nj]) continue;\n            bool ok=false;\n            if (dir==0 && j+1<N && v[i][j]=='0') ok=true;\n            if (dir==1 && i+1<N && h[i][j]=='0') ok=true;\n            if (dir==2 && j-1>=0 && v[i][j-1]=='0') ok=true;\n            if (dir==3 && i-1>=0 && h[i-1][j]=='0') ok=true;\n            if (!ok) continue;\n            baseMoves.push_back(dc[dir]);            // go\n            dfs(ni,nj);\n            baseMoves.push_back(dc[(dir+2)%4]);      // back\n        }\n    };\n    dfs(0,0);\n    // baseMoves now contains a closed walk\n    const int L0 = (int)baseMoves.size();\n\n    /* ------------------------------------------------------------\n       2.  choose high\u2011susceptibility cells\n       ------------------------------------------------------------ */\n    const int T = 15;                     // number of extra cells\n    vector<pair<int,int>> cand;           // (d, id)\n    for (int i=0;i<N;i++) for (int j=0;j<N;j++){\n        int vx = id(i,j);\n        cand.emplace_back(d[i][j], vx);\n    }\n    sort(cand.begin(), cand.end(),\n         [](const auto& a, const auto& b){ return a.first>b.first; });\n    vector<int> important;               // ids of vertices in TSP\n    important.push_back(0);               // start (0,0)\n    for (auto &p: cand){\n        if ((int)important.size()>=T+1) break;\n        if (p.second!=0) important.push_back(p.second);\n    }\n    const int M = (int)important.size(); // M = T+1 (start + T cells)\n\n    /* ------------------------------------------------------------\n       3.  all\u2011pairs shortest paths from the important vertices\n       ------------------------------------------------------------ */\n    const int INF = 1e9;\n    vector<vector<int>> dist(M, vector<int>(V, INF));\n    vector<vector<int>> pred(M, vector<int>(V, -1));\n    for (int s=0; s<M; ++s){\n        queue<int> q;\n        int src = important[s];\n        dist[s][src]=0;\n        pred[s][src]=src;\n        q.push(src);\n        while(!q.empty()){\n            int u=q.front(); q.pop();\n            for (int v: adj[u]){\n                if (dist[s][v]==INF){\n                    dist[s][v]=dist[s][u]+1;\n                    pred[s][v]=u;\n                    q.push(v);\n                }\n            }\n        }\n    }\n\n    /* ------------------------------------------------------------\n       4.  TSP on the important vertices (Held\u2011Karp)\n       ------------------------------------------------------------ */\n    int t = M-1;                     // number of non\u2011start vertices\n    vector<vector<int>> dmat(M, vector<int>(M,0));\n    for (int i=0;i<M;i++)\n        for (int j=0;j<M;j++)\n            dmat[i][j] = dist[i][ important[j] ];\n\n    const int FULL = 1<<t;\n    const int INFDP = 1e9;\n    vector<vector<int>> dp(FULL, vector<int>(t+1, INFDP));\n    vector<vector<int>> parent(FULL, vector<int>(t+1, -1));\n\n    for (int i=1;i<=t;i++){\n        int mask = 1<<(i-1);\n        dp[mask][i] = dmat[0][i];\n        parent[mask][i] = 0;\n    }\n\n    for (int mask=1; mask<FULL; ++mask){\n        for (int i=1;i<=t;i++) if (dp[mask][i] < INFDP){\n            for (int j=1;j<=t;j++) if (!(mask & (1<<(j-1)))){\n                int nmask = mask | (1<<(j-1));\n                int nd = dp[mask][i] + dmat[i][j];\n                if (nd < dp[nmask][j]){\n                    dp[nmask][j] = nd;\n                    parent[nmask][j] = i;\n                }\n            }\n        }\n    }\n\n    int bestEnd = -1, bestCost = INFDP;\n    int fullMask = FULL-1;\n    for (int i=1;i<=t;i++){\n        int cost = dp[fullMask][i] + dmat[i][0];\n        if (cost < bestCost){\n            bestCost = cost;\n            bestEnd = i;\n        }\n    }\n\n    // reconstruct order of vertices (without the final return to start)\n    vector<int> order; // indices 1..t\n    int curMask = fullMask;\n    int cur = bestEnd;\n    while (curMask){\n        order.push_back(cur);\n        int prev = parent[curMask][cur];\n        curMask ^= 1<<(cur-1);\n        cur = prev;\n    }\n    reverse(order.begin(), order.end());\n\n    // sequence of important ids: start + order + start\n    vector<int> seq;\n    seq.push_back(0); // start\n    for (int x: order) seq.push_back(x);\n    seq.push_back(0); // back to start\n\n    /* ------------------------------------------------------------\n       5.  build the TSP\u2011cycle string\n       ------------------------------------------------------------ */\n    auto get_path = [&](int srcIdx, int dst)->string{\n        // srcIdx : index in important[]\n        string moves;\n        int cur = dst;\n        vector<int> path;\n        while (cur != important[srcIdx]){\n            int p = pred[srcIdx][cur];\n            path.push_back(cur);\n            cur = p;\n        }\n        path.push_back(important[srcIdx]);\n        reverse(path.begin(), path.end());\n        for (size_t i=0;i+1<path.size();++i){\n            int a = path[i], b = path[i+1];\n            int ai=a/N, aj=a%N, bi=b/N, bj=b%N;\n            if (bi==ai+1) moves.push_back('D');\n            else if (bi==ai-1) moves.push_back('U');\n            else if (bj==aj+1) moves.push_back('R');\n            else moves.push_back('L');\n        }\n        return moves;\n    };\n\n    string cycleMoves;\n    for (size_t i=0;i+1<seq.size();++i){\n        int u = seq[i]; // important index\n        int v = seq[i+1];\n        cycleMoves += get_path(u, important[v]);\n    }\n    const int Lcycle = (int)cycleMoves.size();\n\n    /* ------------------------------------------------------------\n       6.  combine the walks\n       ------------------------------------------------------------ */\n    const int Lmax = 100000;\n    int R = 0;\n    if (Lcycle>0) R = (Lmax - L0) / Lcycle;\n    string answer = baseMoves;\n    for (int i=0;i<R;i++) answer += cycleMoves;\n    // (the length is automatically \u2264 Lmax)\n\n    cout << answer << '\\n';\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\nconst int N = 15;\nconst int TOT = N * N;                 // 225\n\n// ------------------------------------------------------------\n// overlap: longest k (0 \u2264 k \u2264 5) such that suffix of a (len k)\n// equals prefix of b (len k)\nint overlap(const string &a, const string &b) {\n    int maxk = min({(int)a.size(), (int)b.size(), 5});\n    for (int k = maxk; k >= 0; --k) {\n        bool ok = true;\n        for (int i = 0; i < k; ++i) {\n            if (a[a.size() - k + i] != b[i]) { ok = false; break; }\n        }\n        if (ok) return k;\n    }\n    return 0;\n}\n\n// ------------------------------------------------------------\n// greedy construction of a superstring, bidirectional, starting from startIdx\nstring buildSuperstring(const vector<string> &words, int startIdx) {\n    int m = (int)words.size();\n    vector<bool> used(m, false);\n    string cur = words[startIdx];\n    used[startIdx] = true;\n\n    while (true) {\n        int bestId = -1;\n        int bestAdd = INF;          // extra characters added\n        int bestOri = 0;            // 0 = append, 1 = prepend\n        int bestOv = 0;\n\n        for (int j = 0; j < m; ++j) if (!used[j]) {\n            // append\n            int ov_app = overlap(cur, words[j]);\n            int add_app = (int)words[j].size() - ov_app;\n            // prepend\n            int ov_pre = overlap(words[j], cur);\n            int add_pre = (int)words[j].size() - ov_pre;\n\n            if (add_app <= add_pre) {\n                if (add_app < bestAdd) {\n                    bestAdd = add_app;\n                    bestId = j;\n                    bestOri = 0;\n                    bestOv = ov_app;\n                }\n            } else {\n                if (add_pre < bestAdd) {\n                    bestAdd = add_pre;\n                    bestId = j;\n                    bestOri = 1;\n                    bestOv = ov_pre;\n                }\n            }\n        }\n        if (bestId == -1) break;               // all words used\n\n        if (bestOri == 0) {                     // append\n            cur += words[bestId].substr(bestOv);\n        } else {                                 // prepend\n            cur = words[bestId].substr(0, (int)words[bestId].size() - bestOv) + cur;\n        }\n        used[bestId] = true;\n    }\n    return cur;\n}\n\n// ------------------------------------------------------------\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int M;\n    if (!(cin >> N >> M)) return 0;\n    int si, sj;\n    cin >> si >> sj;\n    vector<string> board(N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n\n    // positions of each letter\n    vector<vector<int>> cells(26);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            int id = i * N + j;\n            cells[board[i][j] - 'A'].push_back(id);\n        }\n\n    vector<string> words(M);\n    for (int i = 0; i < M; ++i) cin >> words[i];\n\n    // distance matrix between all cells\n    static int dist[TOT][TOT];\n    for (int i = 0; i < TOT; ++i) {\n        int x1 = i / N, y1 = i % N;\n        for (int j = 0; j < TOT; ++j) {\n            int x2 = j / N, y2 = j % N;\n            dist[i][j] = abs(x1 - x2) + abs(y1 - y2);\n        }\n    }\n\n    // --------------------------------------------------------\n    // try a few random start words\n    mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());\n    const int TRIALS = 5;\n\n    int bestCost = INF;\n    vector<pair<int,int>> bestPath;   // (i , j) for each operation\n\n    for (int trial = 0; trial < TRIALS; ++trial) {\n        int startWord = uniform_int_distribution<int>(0, M-1)(rng);\n        string S = buildSuperstring(words, startWord);\n        int L = (int)S.size();\n\n        // DP\n        vector<int> dpPrev(TOT, INF), dpCurr(TOT, INF);\n        vector<vector<short>> pre(L+1, vector<short>(TOT, -1));\n\n        int startCell = si * N + sj;\n        dpPrev[startCell] = 0;                 // cost 0 before typing anything\n\n        for (int pos = 0; pos < L; ++pos) {\n            char c = S[pos];\n            const vector<int> &allowed = cells[c - 'A'];\n            fill(dpCurr.begin(), dpCurr.end(), INF);\n            for (int curIdx : allowed) {\n                int best = INF;\n                short bestPrev = -1;\n                for (int prevIdx = 0; prevIdx < TOT; ++prevIdx) {\n                    int pc = dpPrev[prevIdx];\n                    if (pc == INF) continue;\n                    int cand = pc + dist[prevIdx][curIdx] + 1;\n                    if (cand < best) {\n                        best = cand;\n                        bestPrev = (short)prevIdx;\n                    }\n                }\n                dpCurr[curIdx] = best;\n                pre[pos+1][curIdx] = bestPrev;\n            }\n            dpPrev.swap(dpCurr);\n        }\n\n        // best final cell\n        int finalIdx = -1;\n        int finalCost = INF;\n        for (int i = 0; i < TOT; ++i) {\n            if (dpPrev[i] < finalCost) {\n                finalCost = dpPrev[i];\n                finalIdx = i;\n            }\n        }\n\n        if (finalCost < bestCost) {\n            bestCost = finalCost;\n            // reconstruct path\n            bestPath.assign(L, {0,0});\n            int cur = finalIdx;\n            for (int p = L; p >= 1; --p) {\n                bestPath[p-1] = {cur / N, cur % N};\n                cur = pre[p][cur];\n            }\n        }\n    }\n\n    // --------------------------------------------------------\n    // output\n    cout << bestPath.size() << '\\n';\n    for (auto [i,j] : bestPath) {\n        cout << i << ' ' << j << '\\n';\n    }\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M;\n    double eps;\n    if (!(cin >> N >> M >> eps)) return 0;\n\n    // read and ignore the shapes\n    for (int k = 0; k < M; ++k) {\n        int d; cin >> d;\n        for (int t = 0; t < d; ++t) {\n            int a,b; cin >> a >> b;\n        }\n    }\n\n    vector<int> rowPos(N, 0), colPos(N, 0);   // 0 = unknown / empty, 1 = non\u2011empty\n\n    auto query_divine = [&](const vector<pair<int,int>>& cells) -> int {\n        cout << 'q' << ' ' << (int)cells.size();\n        for (auto [i,j] : cells) cout << ' ' << i << ' ' << j;\n        cout << '\\n' << std::flush;\n        int resp; cin >> resp;\n        return resp;\n    };\n\n    // ----- rows (twice) -----\n    for (int i = 0; i < N; ++i) {\n        vector<pair<int,int>> cells;\n        cells.reserve(N);\n        for (int j = 0; j < N; ++j) cells.emplace_back(i, j);\n        int r1 = query_divine(cells);\n        int r2 = query_divine(cells);\n        if (r1 > 0 || r2 > 0) rowPos[i] = 1;\n    }\n\n    // ----- columns (twice) -----\n    for (int j = 0; j < N; ++j) {\n        vector<pair<int,int>> cells;\n        cells.reserve(N);\n        for (int i = 0; i < N; ++i) cells.emplace_back(i, j);\n        int c1 = query_divine(cells);\n        int c2 = query_divine(cells);\n        if (c1 > 0 || c2 > 0) colPos[j] = 1;\n    }\n\n    // exact values, -1 = not known yet\n    vector<vector<int>> val(N, vector<int>(N, -1));\n\n    // ----- drill candidate cells (row and column are both non\u2011empty) -----\n    for (int i = 0; i < N; ++i) if (rowPos[i])\n        for (int j = 0; j < N; ++j) if (colPos[j]) {\n            cout << 'q' << ' ' << 1 << ' ' << i << ' ' << j << '\\n' << std::flush;\n            int v; cin >> v;\n            val[i][j] = v;\n        }\n\n    // ----- first guess -----\n    vector<pair<int,int>> ans;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (val[i][j] > 0) ans.emplace_back(i, j);\n\n    cout << 'a' << ' ' << (int)ans.size();\n    for (auto [i,j] : ans) cout << ' ' << i << ' ' << j;\n    cout << '\\n' << std::flush;\n    int ok; cin >> ok;\n    if (ok == 1) return 0;          // success\n\n    // ----- fallback : drill everything else -----\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (val[i][j] == -1) {\n                cout << 'q' << ' ' << 1 << ' ' << i << ' ' << j << '\\n' << std::flush;\n                int v; cin >> v;\n                val[i][j] = v;\n            }\n\n    // ----- second guess (must be correct) -----\n    ans.clear();\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (val[i][j] > 0) ans.emplace_back(i, j);\n\n    cout << 'a' << ' ' << (int)ans.size();\n    for (auto [i,j] : ans) cout << ' ' << i << ' ' << j;\n    cout << '\\n' << std::flush;\n    // no need to read the final answer, program ends here\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect {\n    int x, y, w, h;\n};\n\nstruct Segment {\n    int cnt;          // how many days profit from one more unit\n    long long delta;  // how many units are available in this interval\n    int idx;         // which rank\n    bool operator<(Segment const& other) const {\n        return cnt < other.cnt;           // for max\u2011heap\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int W = 1000;\n    int D, N;\n    if (!(cin >> D >> N)) return 0;\n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; ++d)\n        for (int k = 0; k < N; ++k) cin >> a[d][k];\n\n    /* ------------------------------------------------------------\n       1.  collect demands for each rank (i\u2011th smallest rectangle)\n       ------------------------------------------------------------ */\n    vector<vector<int>> demand(N, vector<int>(D));   // demand[i][d]\n    for (int d = 0; d < D; ++d) {\n        vector<pair<int,int>> v;\n        v.reserve(N);\n        for (int k = 0; k < N; ++k) v.emplace_back(a[d][k], k);\n        sort(v.begin(), v.end(),\n             [](const pair<int,int>& p, const pair<int,int>& q){\n                 return p.first < q.first;\n             });\n        for (int i = 0; i < N; ++i) demand[i][d] = v[i].first;\n    }\n\n    /* ------------------------------------------------------------\n       2.  greedy area allocation (optimal B[i])\n       ------------------------------------------------------------ */\n    long long capacity = 1LL * W * W;\n    priority_queue<Segment> pq;\n    for (int i = 0; i < N; ++i) {\n        auto &vec = demand[i];\n        sort(vec.begin(), vec.end());\n        int prev = 0;\n        for (int t = 0; t < (int)vec.size(); ++t) {\n            int cur = vec[t];\n            int delta = cur - prev;\n            if (delta > 0) {\n                int cnt = D - t;               // days whose demand > prev\n                pq.push({cnt, delta, i});\n            }\n            prev = cur;\n        }\n    }\n    vector<long long> B(N, 0);\n    long long remain = capacity;\n    while (remain > 0 && !pq.empty()) {\n        Segment seg = pq.top(); pq.pop();\n        long long take = min(seg.delta, remain);\n        B[seg.idx] += take;\n        remain -= take;\n        seg.delta -= take;\n        if (seg.delta > 0) pq.push(seg);\n    }\n\n    /* ------------------------------------------------------------\n       3.  build rectangles from areas B[i]  (MaxRects)\n       ------------------------------------------------------------ */\n    // helper: create candidate dimensions for a given area\n    auto candidates = [&](int area)->vector<pair<int,int>> {\n        vector<pair<int,int>> cand;\n        int w = min(W, area);\n        int h = (area + w - 1) / w;\n        cand.emplace_back(w, h);\n        if (w != h) cand.emplace_back(h, w);\n        // a second \u201calmost square\u201d candidate\n        int w2 = max(1, (int)sqrt(area));\n        int h2 = (area + w2 - 1) / w2;\n        if (w2 <= W && h2 <= W) {\n            cand.emplace_back(w2, h2);\n            if (w2 != h2) cand.emplace_back(h2, w2);\n        }\n        // full\u2011width candidate (always works)\n        int wf = W;\n        int hf = (area + wf - 1) / wf;\n        if (hf <= W) {\n            cand.emplace_back(wf, hf);\n            if (wf != hf) cand.emplace_back(hf, wf);\n        }\n        // delete duplicates\n        sort(cand.begin(), cand.end());\n        cand.erase(unique(cand.begin(), cand.end()), cand.end());\n        return cand;\n    };\n\n    // order: descending area\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(),\n         [&](int i, int j){ return B[i] > B[j]; });\n\n    vector<Rect> placed(N);               // coordinates for each rank i\n    vector<Rect> freeRects;\n    freeRects.emplace_back(0, 0, W, W);   // the whole grid\n\n    // helper: prune contained free rectangles\n    auto prune = [&](){\n        bool changed = true;\n        while (changed) {\n            changed = false;\n            for (int i = 0; i < (int)freeRects.size() && !changed; ++i) {\n                for (int j = 0; j < (int)freeRects.size(); ++j) {\n                    if (i == j) continue;\n                    const Rect &a = freeRects[i];\n                    const Rect &b = freeRects[j];\n                    if (a.x >= b.x && a.y >= b.y &&\n                        a.x + a.w <= b.x + b.w &&\n                        a.y + a.h <= b.y + b.h) {\n                        freeRects.erase(freeRects.begin() + i);\n                        changed = true;\n                        break;\n                    }\n                }\n            }\n        }\n    };\n\n    for (int id : order) {\n        int area = (int)B[id];\n        if (area == 0) continue;           // never happens (a \u2265 1)\n        vector<pair<int,int>> cand = candidates(area);\n\n        bool placed_now = false;\n        int bestScore = -1;\n        int bestFree = -1, bestW = -1, bestH = -1;\n        for (auto [cw, ch] : cand) {\n            for (int fi = 0; fi < (int)freeRects.size(); ++fi) {\n                const Rect &fr = freeRects[fi];\n                if (cw <= fr.w && ch <= fr.h) {\n                    int a = fr.w - cw;\n                    int b = fr.h - ch;\n                    int score = min(a, b);          // best short side fit\n                    if (score > bestScore) {\n                        bestScore = score;\n                        bestFree = fi;\n                        bestW = cw;\n                        bestH = ch;\n                    }\n                }\n            }\n        }\n        if (bestFree != -1) {\n            Rect fr = freeRects[bestFree];\n            placed[id] = {fr.x, fr.y, bestW, bestH};\n\n            // erase used free rectangle\n            freeRects.erase(freeRects.begin() + bestFree);\n            // add new free rectangles (right and bottom)\n            if (fr.w > bestW) {\n                freeRects.emplace_back(fr.x + bestW, fr.y,\n                                        fr.w - bestW, bestH);\n            }\n            if (fr.h > bestH) {\n                freeRects.emplace_back(fr.x, fr.y + bestH,\n                                        fr.w, fr.h - bestH);\n            }\n            prune();\n            placed_now = true;\n        }\n        // Theoretically never reaches here \u2013 see Lemma\u202f4\n        if (!placed_now) {\n            // emergency: enlarge to full width, this always fits somewhere\n            int wf = W;\n            int hf = (area + wf - 1) / wf;\n            // find any free spot that fits\n            for (int fi = 0; fi < (int)freeRects.size(); ++fi) {\n                Rect &fr = freeRects[fi];\n                if (wf <= fr.w && hf <= fr.h) {\n                    placed[id] = {fr.x, fr.y, wf, hf};\n                    freeRects.erase(freeRects.begin() + fi);\n                    if (fr.w > wf)\n                        freeRects.emplace_back(fr.x + wf, fr.y,\n                                                fr.w - wf, hf);\n                    if (fr.h > hf)\n                        freeRects.emplace_back(fr.x, fr.y + hf,\n                                                fr.w, fr.h - hf);\n                    prune();\n                    placed_now = true;\n                    break;\n                }\n            }\n            // still impossible \u2013 should never happen\n            if (!placed_now) {\n                // last resort: place at (0,0) and ignore the rest\n                placed[id] = {0,0,W,1};\n            }\n        }\n    }\n\n    /* ------------------------------------------------------------\n       4.  prepare output: sort rectangles by area (ascending)\n       ------------------------------------------------------------ */\n    vector<int> ascIdx(N);\n    iota(ascIdx.begin(), ascIdx.end(), 0);\n    sort(ascIdx.begin(), ascIdx.end(),\n         [&](int i, int j){ return B[i] < B[j]; });\n\n    // result[d][k] = {x0,y0,x1,y1}\n    vector<vector<array<int,4>>> out(D, vector<array<int,4>>(N));\n\n    for (int d = 0; d < D; ++d) {\n        // pairs (required area, original index)\n        vector<pair<int,int>> vp;\n        vp.reserve(N);\n        for (int k = 0; k < N; ++k) vp.emplace_back(a[d][k], k);\n        sort(vp.begin(), vp.end(),\n             [](const pair<int,int>& p, const pair<int,int>& q){\n                 return p.first < q.first;\n             });\n        for (int i = 0; i < N; ++i) {\n            int reservation = vp[i].second;\n            const Rect &rc = placed[ ascIdx[i] ];   // i\u2011th smallest area\n            out[d][reservation] = {rc.x, rc.y,\n                                   rc.x + rc.w, rc.y + rc.h};\n        }\n    }\n\n    /* ------------------------------------------------------------\n       5.  print\n       ------------------------------------------------------------ */\n    for (int d = 0; d < D; ++d)\n        for (int k = 0; k < N; ++k) {\n            const auto &r = out[d][k];\n            cout << r[0] << ' ' << r[1] << ' ' << r[2] << ' ' << r[3] << '\\n';\n        }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MOD = 998244353;\nconst int N = 9;          // board size\nconst int NSTAMP = 3;     // stamp size\nconst int MAX_K = 81;\n\nint add_mod(int a, int b) {\n    int s = a + b;\n    if (s >= MOD) s -= MOD;\n    return s;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N_in, M, K;\n    if(!(cin >> N_in >> M >> K)) return 0;\n    // N_in is always 9, but we read it for completeness\n    vector<vector<int>> board(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            long long x; cin >> x;\n            board[i][j] = int(x % MOD);\n        }\n\n    // stamps[m][dx][dy]\n    static int stamp[20][3][3];\n    for (int m = 0; m < M; ++m)\n        for (int i = 0; i < 3; ++i)\n            for (int j = 0; j < 3; ++j) {\n                long long x; cin >> x;\n                stamp[m][i][j] = int(x % MOD);\n            }\n\n    vector<tuple<int,int,int>> ops;          // (m, p, q)\n    long long curSum = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) curSum += board[i][j];\n\n    int remaining = K;\n    while (remaining > 0) {\n        long long bestDelta = LLONG_MIN;\n        int bestM = -1, bestP = -1, bestQ = -1;\n\n        for (int m = 0; m < M; ++m) {\n            for (int p = 0; p <= N - NSTAMP; ++p) {\n                for (int q = 0; q <= N - NSTAMP; ++q) {\n                    long long delta = 0;\n                    for (int di = 0; di < 3; ++di) {\n                        for (int dj = 0; dj < 3; ++dj) {\n                            int cur = board[p + di][q + dj];\n                            int nv = cur + stamp[m][di][dj];\n                            if (nv >= MOD) nv -= MOD;\n                            delta += (nv - cur);\n                        }\n                    }\n                    if (delta > bestDelta) {\n                        bestDelta = delta;\n                        bestM = m; bestP = p; bestQ = q;\n                    }\n                }\n            }\n        }\n\n        if (bestDelta <= 0) break;   // no improvement possible\n\n        // apply the best operation\n        for (int di = 0; di < 3; ++di) {\n            for (int dj = 0; dj < 3; ++dj) {\n                int &cur = board[bestP + di][bestQ + dj];\n                int nv = cur + stamp[bestM][di][dj];\n                if (nv >= MOD) nv -= MOD;\n                cur = nv;\n            }\n        }\n        curSum += bestDelta;\n        ops.emplace_back(bestM, bestP, bestQ);\n        --remaining;\n    }\n\n    cout << ops.size() << '\\n';\n    for (auto [m, p, q] : ops) {\n        cout << m << ' ' << p << ' ' << q << '\\n';\n    }\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int N = 5;\n    const int TOTAL = N * N;          // 25\n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> A[i][j];\n\n    // simulation state\n    vector<int> idx(N, 0);                     // next container to appear in each row\n    vector<pair<int,int>> pos(TOTAL, {-1,-1}); // position of each container on the grid, (-1,-1) = not on grid\n    vector<char> dispatched(TOTAL, 0);\n    int dispatchedCnt = 0;\n\n    int largeR = 0, largeC = 0;                // large crane position\n    int holding = -1;                          // -1 = empty, otherwise container number\n\n    // small crane status: true = still alive\n    bool smallActive[N];\n    for (int i = 1; i < N; ++i) smallActive[i] = true;\n\n    // actions for each crane\n    vector<string> actions(N);\n\n    auto moveDir = [&](int r, int c, int tr, int tc)->char {\n        if (r < tr) return 'D';\n        if (r > tr) return 'U';\n        if (c < tc) return 'R';\n        if (c > tc) return 'L';\n        return '.';\n    };\n\n    int turn = 0;\n    while (dispatchedCnt < TOTAL) {\n        /* ---------- step 1 : receiving gates ---------- */\n        for (int row = 0; row < N; ++row) {\n            if (idx[row] >= N) continue;               // no more containers in this row\n            bool hasContainer = false;\n            for (int c = 0; c < TOTAL; ++c)\n                if (pos[c].first == row && pos[c].second == 0) { hasContainer = true; break; }\n            bool craneHoldingAtSquare = (largeR == row && largeC == 0 && holding != -1);\n            if (!hasContainer && !craneHoldingAtSquare) {\n                int container = A[row][idx[row]];\n                pos[container] = {row, 0};\n                idx[row]++;\n            }\n        }\n\n        /* ---------- step 2 : crane actions ---------- */\n        // small cranes\n        for (int i = 1; i < N; ++i) {\n            char act;\n            if (smallActive[i]) {\n                if (turn == 0) { act = 'B'; smallActive[i] = false; }\n                else act = '.';\n            } else act = '.';\n            actions[i].push_back(act);\n        }\n\n        // large crane\n        // find the smallest undispatched container\n        int cur = 0;\n        while (cur < TOTAL && dispatched[cur]) ++cur;\n\n        char actLarge;\n        if (holding == -1) {\n            // empty \u2013 need to pick up the next container\n            if (cur < TOTAL && pos[cur].first != -1) {\n                // container is on the board\n                int tr = pos[cur].first;\n                int tc = pos[cur].second;\n                if (largeR == tr && largeC == tc) {\n                    actLarge = 'P';\n                    // pick up\n                    holding = cur;\n                    pos[cur] = {-1,-1};\n                } else {\n                    actLarge = moveDir(largeR, largeC, tr, tc);\n                }\n            } else {\n                // not on the board yet\n                actLarge = '.';\n            }\n        } else {\n            // carrying a container \u2013 go to its dispatch gate\n            int targetRow = holding / N;\n            int targetCol = N - 1;\n            if (largeR == targetRow && largeC == targetCol) {\n                actLarge = 'Q';\n                // place container on the dispatch square\n                pos[holding] = {largeR, largeC};\n                // after this turn the container will be dispatched\n                holding = -1;\n            } else {\n                actLarge = moveDir(largeR, largeC, targetRow, targetCol);\n            }\n        }\n\n        // apply movement of the large crane\n        if (actLarge == 'U') --largeR;\n        else if (actLarge == 'D') ++largeR;\n        else if (actLarge == 'L') --largeC;\n        else if (actLarge == 'R') ++largeC;\n        // 'P' , 'Q' , '.' do not move the crane\n\n        actions[0].push_back(actLarge);\n\n        /* ---------- step 3 : dispatch gates ---------- */\n        for (int row = 0; row < N; ++row) {\n            for (int c = 0; c < TOTAL; ++c) {\n                if (pos[c].first == row && pos[c].second == N - 1) {\n                    // dispatch\n                    dispatched[c] = 1;\n                    ++dispatchedCnt;\n                    pos[c] = {-1,-1};\n                }\n            }\n        }\n\n        ++turn;\n    }\n\n    // output\n    for (int i = 0; i < N; ++i) {\n        cout << actions[i] << '\\n';\n    }\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos {\n    int r, c;\n};\n\nstruct Delivery {\n    Pos sink;\n    int amt;\n};\n\nstruct Source {\n    Pos pos;\n    int total;                     // total supply\n    vector<Delivery> deliveries; // to negative cells\n};\n\nstatic inline int manhattan(const Pos& a, const Pos& b) {\n    return abs(a.r - b.r) + abs(a.c - b.c);\n}\n\n// move from cur to target, appending moves to ops\nstatic void moveTo(Pos& cur, const Pos& target, vector<string>& ops) {\n    int dr = target.r - cur.r;\n    int dc = target.c - cur.c;\n    if (dr > 0) {\n        for (int i = 0; i < dr; ++i) {\n            ops.emplace_back(\"D\");\n            cur.r++;\n        }\n    } else if (dr < 0) {\n        for (int i = 0; i < -dr; ++i) {\n            ops.emplace_back(\"U\");\n            cur.r--;\n        }\n    }\n    if (dc > 0) {\n        for (int i = 0; i < dc; ++i) {\n            ops.emplace_back(\"R\");\n            cur.c++;\n        }\n    } else if (dc < 0) {\n        for (int i = 0; i < -dc; ++i) {\n            ops.emplace_back(\"L\");\n            cur.c--;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\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 positive (supply) and negative (demand) cells\n    vector<Pos> negPos;\n    vector<int> negDemand;\n    vector<Source> sources;\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (h[i][j] > 0) {\n                Source src;\n                src.pos = {i, j};\n                src.total = h[i][j];\n                sources.push_back(src);\n            } else if (h[i][j] < 0) {\n                negPos.push_back({i, j});\n                negDemand.push_back(-h[i][j]);\n            }\n        }\n    }\n\n    // greedy assignment: each positive cell gives its supply to the nearest\n    // still demanding negative cell repeatedly\n    for (size_t si = 0; si < sources.size(); ++si) {\n        int remain = sources[si].total;\n        while (remain > 0) {\n            int bestIdx = -1;\n            int bestDist = 1e9;\n            for (size_t j = 0; j < negPos.size(); ++j) {\n                if (negDemand[j] == 0) continue;\n                int d = manhattan(sources[si].pos, negPos[j]);\n                if (d < bestDist) {\n                    bestDist = d;\n                    bestIdx = (int)j;\n                }\n            }\n            // there must be a negative cell left\n            int give = min(remain, negDemand[bestIdx]);\n            sources[si].deliveries.push_back({negPos[bestIdx], give});\n            remain -= give;\n            negDemand[bestIdx] -= give;\n        }\n        // sort deliveries of this source by distance to the source\n        auto& del = sources[si].deliveries;\n        sort(del.begin(), del.end(),\n             [&](const Delivery& a, const Delivery& b) {\n                 int da = manhattan(sources[si].pos, a.sink);\n                 int db = manhattan(sources[si].pos, b.sink);\n                 return da < db;\n             });\n    }\n\n    // sort sources by row\u2011major order\n    sort(sources.begin(), sources.end(),\n         [&](const Source& a, const Source& b) {\n             int ai = a.pos.r * N + a.pos.c;\n             int bi = b.pos.r * N + b.pos.c;\n             return ai < bi;\n         });\n\n    // -----------------------------------------------------------------\n    // generate the operation list\n    vector<string> ops;\n    Pos cur{0, 0};\n    int curLoad = 0;               // current load of the truck\n\n    for (const auto& src : sources) {\n        // move empty to the source\n        moveTo(cur, src.pos, ops);\n        // load the whole supply\n        ops.emplace_back(\"+\" + to_string(src.total));\n        curLoad = src.total;\n\n        // visit its sinks one after another\n        for (const auto& del : src.deliveries) {\n            moveTo(cur, del.sink, ops);          // moves while loaded\n            ops.emplace_back(\"-\" + to_string(del.amt));\n            curLoad -= del.amt;\n        }\n        // after the last delivery load is zero (guaranteed)\n    }\n\n    // output\n    for (const string& s : ops) cout << s << '\\n';\n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, T;\n    if (!(cin >> N >> M >> T)) return 0;\n    const int S = 2 * N * (N - 1);           // 60\n    vector<vector<int>> seed(S, vector<int>(M));\n    for (int i = 0; i < S; ++i)\n        for (int j = 0; j < M; ++j)\n            cin >> seed[i][j];\n\n    /* ----- pre\u2011compute positions ordered by degree ----- */\n    vector<tuple<int,int,int>> posDeg;       // (degree, i, j)\n    posDeg.reserve(N * N);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int d = (i > 0) + (i < N - 1) + (j > 0) + (j < N - 1);\n            posDeg.emplace_back(d, i, j);\n        }\n    }\n    sort(posDeg.begin(), posDeg.end(),\n         [](const auto& a, const auto& b) {\n             if (get<0>(a) != get<0>(b)) return get<0>(a) > get<0>(b);\n             // tie\u2011break: arbitrary but deterministic\n             return (get<1>(a) + get<2>(a)) < (get<1>(b) + get<2>(b));\n         });\n\n    /* ------------------- main loop ---------------------- */\n    for (int turn = 0; turn < T; ++turn) {\n        /* ----- evaluate current seeds ----- */\n        vector<int> sum(S, 0);\n        vector<int> bestIdx(M, -1);\n        vector<int> bestVal(M, -1);\n        for (int i = 0; i < S; ++i) {\n            int s = 0;\n            for (int j = 0; j < M; ++j) {\n                int v = seed[i][j];\n                s += v;\n                if (v > bestVal[j]) {\n                    bestVal[j] = v;\n                    bestIdx[j] = i;\n                }\n            }\n            sum[i] = s;\n        }\n\n        /* ----- choose 36 parent seeds ----- */\n        vector<char> used(S, 0);\n        vector<int> parents;\n        parents.reserve(36);\n\n        // keep all specialists (different seeds)\n        for (int j = 0; j < M; ++j) {\n            int idx = bestIdx[j];\n            if (idx >= 0 && !used[idx]) {\n                used[idx] = 1;\n                parents.push_back(idx);\n            }\n        }\n\n        // fill the rest with highest\u2011value seeds\n        vector<int> other;\n        other.reserve(S);\n        for (int i = 0; i < S; ++i)\n            if (!used[i]) other.push_back(i);\n        sort(other.begin(), other.end(),\n             [&](int a, int b) { return sum[a] > sum[b]; });\n\n        int need = 36 - (int)parents.size();\n        for (int i = 0; i < need; ++i) parents.push_back(other[i]);\n\n        // exactly 36 parents \u2013 safety check\n        // (the problem guarantees this is always possible)\n        // sort parents by value (best first) for placement\n        sort(parents.begin(), parents.end(),\n             [&](int a, int b) { return sum[a] > sum[b]; });\n\n        /* ----- place them onto the grid ----- */\n        vector<vector<int>> A(N, vector<int>(N, -1));\n        for (int p = 0; p < 36; ++p) {\n            int di, dj;\n            tie(ignore, di, dj) = posDeg[p];\n            A[di][dj] = parents[p];\n        }\n\n        /* ----- output ----- */\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (j) cout << ' ';\n                cout << A[i][j];\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n\n        /* ----- read next generation ----- */\n        vector<vector<int>> nxt(S, vector<int>(M));\n        for (int i = 0; i < S; ++i)\n            for (int j = 0; j < M; ++j)\n                cin >> nxt[i][j];\n        seed.swap(nxt);\n    }\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, V;\n    if (!(cin >> N >> M >> V)) return 0;\n    vector<string> sgrid(N), tgrid(N);\n    for (int i = 0; i < N; ++i) cin >> sgrid[i];\n    for (int i = 0; i < N; ++i) cin >> tgrid[i];\n\n    /* ---------- board ---------- */\n    vector<vector<bool>> has(N, vector<bool>(N, false));\n    vector<vector<bool>> isTarget(N, vector<bool>(N, false));\n    vector<pair<int,int>> src;          // squares that still have a takoyaki\n    vector<pair<int,int>> emptyTgt;      // target squares not yet filled\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (sgrid[i][j] == '1') {\n                has[i][j] = true;\n                src.emplace_back(i, j);\n            }\n            if (tgrid[i][j] == '1') {\n                isTarget[i][j] = true;\n                emptyTgt.emplace_back(i, j);\n            }\n        }\n    }\n\n    /* ---------- tree description ---------- */\n    const int Vprime = 2;                 // we use only root and one leaf\n    cout << Vprime << \"\\n\";\n    cout << 0 << ' ' << 1 << \"\\n\";       // parent of vertex 1 is 0, length 1\n    cout << 0 << ' ' << 0 << \"\\n\";       // initial root position\n\n    /* ---------- directions ---------- */\n    // 0:right, 1:down, 2:left, 3:up\n    const int dr[4] = {0, 1, 0, -1};\n    const int dc[4] = {1, 0, -1, 0};\n\n    auto move_char = [&](int d)->char{\n        if (d == 0) return 'R';\n        if (d == 1) return 'D';\n        if (d == 2) return 'L';\n        return 'U';\n    };\n    auto dir_from_delta = [&](int rdel, int cdel)->int{\n        for (int d = 0; d < 4; ++d)\n            if (dr[d] == rdel && dc[d] == cdel) return d;\n        return -1;          // never happens for a legal step\n    };\n\n    /* ---------- simulation ---------- */\n    vector<string> ops;\n    int root_x = 0, root_y = 0;          // current root position\n    int leaf_dir = 0;                    // direction of the leaf (0 = right)\n    bool holding = false;                // does the leaf hold a takoyaki?\n\n    while (!src.empty() || holding) {\n        if (!holding) {   // ---------- pick a takoyaki ----------\n            // find the source with the cheapest neighbour\n            int bestDist = 1e9, bestIdx = -1;\n            pair<int,int> bestNeighbour{-1,-1};\n            int bestDir = -1;\n            for (int i = 0; i < (int)src.size(); ++i) {\n                int sx = src[i].first, sy = src[i].second;\n                for (int d = 0; d < 4; ++d) {\n                    int nx = sx - dr[d];\n                    int ny = sy - dc[d];\n                    if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n                    int dist = abs(root_x - nx) + abs(root_y - ny);\n                    if (dist < bestDist) {\n                        bestDist = dist;\n                        bestIdx = i;\n                        bestNeighbour = {nx, ny};\n                        bestDir = d;\n                    }\n                }\n            }\n\n            // move the root to that neighbour\n            while (root_x != bestNeighbour.first || root_y != bestNeighbour.second) {\n                int ddx = 0, ddy = 0;\n                if (root_x < bestNeighbour.first) ddx = 1;\n                else if (root_x > bestNeighbour.first) ddx = -1;\n                if (root_y < bestNeighbour.second) ddy = 1;\n                else if (root_y > bestNeighbour.second) ddy = -1;\n\n                string op(4, '.');\n                if (abs(root_x - bestNeighbour.first) >= abs(root_y - bestNeighbour.second)) {\n                    op[0] = move_char(dir_from_delta(ddx, 0));\n                    root_x += ddx;\n                } else {\n                    op[0] = move_char(dir_from_delta(0, ddy));\n                    root_y += ddy;\n                }\n                ops.push_back(op);\n            }\n\n            // rotate leaf to point to the source and pick\n            int target_dir = bestDir;\n            int cur_dir = leaf_dir;\n            int diff = (target_dir - cur_dir + 4) % 4;\n            int alt = 4 - diff;\n            int steps, rot;          // rot = +1 (R) or -1 (L)\n            if (diff <= alt) { steps = diff; rot = 1; }\n            else               { steps = alt;  rot = -1; }\n\n            if (steps > 0) {\n                for (int i = 0; i < steps - 1; ++i) {\n                    string op(4, '.');\n                    op[1] = (rot == 1 ? 'R' : 'L');\n                    ops.push_back(op);\n                    leaf_dir = (leaf_dir + rot + 4) % 4;\n                }\n                // final rotation + pick\n                string op(4, '.');\n                op[1] = (rot == 1 ? 'R' : 'L');\n                op[3] = 'P';\n                ops.push_back(op);\n                leaf_dir = (leaf_dir + rot + 4) % 4;\n            } else { // no rotation needed\n                string op(4, '.');\n                op[3] = 'P';\n                ops.push_back(op);\n            }\n\n            // update data structures\n            has[src[bestIdx].first][src[bestIdx].second] = false;\n            src.erase(src.begin() + bestIdx);\n            holding = true;\n        }\n        else { // ---------- place a takoyaki ----------\n            // find the still empty target with the cheapest neighbour\n            int bestDist = 1e9, bestIdx = -1;\n            pair<int,int> bestNeighbour{-1,-1};\n            int bestDir = -1;\n            for (int i = 0; i < (int)emptyTgt.size(); ++i) {\n                int tx = emptyTgt[i].first, ty = emptyTgt[i].second;\n                for (int d = 0; d < 4; ++d) {\n                    int nx = tx - dr[d];\n                    int ny = ty - dc[d];\n                    if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n                    int dist = abs(root_x - nx) + abs(root_y - ny);\n                    if (dist < bestDist) {\n                        bestDist = dist;\n                        bestIdx = i;\n                        bestNeighbour = {nx, ny};\n                        bestDir = d;\n                    }\n                }\n            }\n\n            // move the root to that neighbour\n            while (root_x != bestNeighbour.first || root_y != bestNeighbour.second) {\n                int ddx = 0, ddy = 0;\n                if (root_x < bestNeighbour.first) ddx = 1;\n                else if (root_x > bestNeighbour.first) ddx = -1;\n                if (root_y < bestNeighbour.second) ddy = 1;\n                else if (root_y > bestNeighbour.second) ddy = -1;\n\n                string op(4, '.');\n                if (abs(root_x - bestNeighbour.first) >= abs(root_y - bestNeighbour.second)) {\n                    op[0] = move_char(dir_from_delta(ddx, 0));\n                    root_x += ddx;\n                } else {\n                    op[0] = move_char(dir_from_delta(0, ddy));\n                    root_y += ddy;\n                }\n                ops.push_back(op);\n            }\n\n            // rotate leaf to point to the target and place\n            int target_dir = bestDir;\n            int cur_dir = leaf_dir;\n            int diff = (target_dir - cur_dir + 4) % 4;\n            int alt = 4 - diff;\n            int steps, rot;\n            if (diff <= alt) { steps = diff; rot = 1; }\n            else               { steps = alt;  rot = -1; }\n\n            if (steps > 0) {\n                for (int i = 0; i < steps - 1; ++i) {\n                    string op(4, '.');\n                    op[1] = (rot == 1 ? 'R' : 'L');\n                    ops.push_back(op);\n                    leaf_dir = (leaf_dir + rot + 4) % 4;\n                }\n                string op(4, '.');\n                op[1] = (rot == 1 ? 'R' : 'L');\n                op[3] = 'P';\n                ops.push_back(op);\n                leaf_dir = (leaf_dir + rot + 4) % 4;\n            } else {\n                string op(4, '.');\n                op[3] = 'P';\n                ops.push_back(op);\n            }\n\n            // update data structures\n            has[emptyTgt[bestIdx].first][emptyTgt[bestIdx].second] = true;\n            emptyTgt.erase(emptyTgt.begin() + bestIdx);\n            holding = false;\n        }\n    }\n\n    /* ---------- output ---------- */\n    for (const string& s : ops) cout << s << '\\n';\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int MAXC = 100000;          // coordinate limits\n    int N;\n    if (!(cin >> N)) return 0;       // no test case\n\n    /* ------------------------------------------------------------\n       read points, remember their type (+1 = mackerel, -1 = sardine)\n       ------------------------------------------------------------ */\n    vector<pair<int,int>> pts;\n    pts.reserve(2 * N);\n    vector<int> xs, ys;\n    xs.reserve(2 * N);\n    ys.reserve(2 * N);\n    for (int i = 0; i < 2 * N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        pts.emplace_back(x, y);\n        xs.push_back(x);\n        ys.push_back(y);\n    }\n\n    // values: first N are mackerels (+1), next N are sardines (-1)\n    vector<int> val(2 * N);\n    for (int i = 0; i < N; ++i) val[i] = 1;\n    for (int i = N; i < 2 * N; ++i) val[i] = -1;\n\n    /* ------------------------------------------------------------\n       coordinate compression\n       ------------------------------------------------------------ */\n    sort(xs.begin(), xs.end());\n    xs.erase(unique(xs.begin(), xs.end()), xs.end());\n    sort(ys.begin(), ys.end());\n    ys.erase(unique(ys.begin(), ys.end()), ys.end());\n\n    const int X = (int)xs.size();\n    const int Y = (int)ys.size();\n\n    /* ------------------------------------------------------------\n       2\u2011D prefix sum (flat array)\n       ------------------------------------------------------------ */\n    vector<int> pref((X + 1) * (Y + 1), 0);\n    for (int i = 0; i < 2 * N; ++i) {\n        int ix = lower_bound(xs.begin(), xs.end(), pts[i].first) - xs.begin();\n        int iy = lower_bound(ys.begin(), ys.end(), pts[i].second) - ys.begin();\n        pref[(ix + 1) * (Y + 1) + (iy + 1)] += val[i];\n    }\n    for (int i = 1; i <= X; ++i) {\n        for (int j = 1; j <= Y; ++j) {\n            int idx = i * (Y + 1) + j;\n            int up   = (i - 1) * (Y + 1) + j;\n            int left = i * (Y + 1) + (j - 1);\n            int diag = (i - 1) * (Y + 1) + (j - 1);\n            pref[idx] = pref[idx] + pref[up] + pref[left] - pref[diag];\n        }\n    }\n\n    /* ------------------------------------------------------------\n       helper: sum of points inside [L,R]\u00d7[B,T] (inclusive)\n       ------------------------------------------------------------ */\n    auto getSum = [&](int L, int R, int B, int T) -> int {\n        if (L > R || B > T) return 0;\n        int ixL = lower_bound(xs.begin(), xs.end(), L) - xs.begin();\n        int ixR = upper_bound(xs.begin(), xs.end(), R) - xs.begin() - 1;\n        int iyB = lower_bound(ys.begin(), ys.end(), B) - ys.begin();\n        int iyT = upper_bound(ys.begin(), ys.end(), T) - ys.begin() - 1;\n        if (ixL > ixR || iyB > iyT) return 0;\n        auto cell = [&](int x, int y) -> int {          // prefix index\n            return pref[x * (Y + 1) + y];\n        };\n        return cell(ixR + 1, iyT + 1) - cell(ixL, iyT + 1)\n             - cell(ixR + 1, iyB)   + cell(ixL, iyB);\n    };\n\n    // column / row sums used in the local search\n    auto colSum = [&](int x, int y1, int y2) -> int {\n        if (y1 > y2) return 0;\n        return getSum(x, x, y1, y2);\n    };\n    auto rowSum = [&](int y, int x1, int x2) -> int {\n        if (x1 > x2) return 0;\n        return getSum(x1, x2, y, y);\n    };\n\n    /* ------------------------------------------------------------\n       Hill climbing with several random starts\n       ------------------------------------------------------------ */\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    const int RESTARTS = 30;\n    const int MAX_ITER = 2000;\n\n    int bestVal = -1000000;\n    int bestL = 0, bestR = 1, bestB = 0, bestT = 1;   // fallback\n\n    for (int st = 0; st < RESTARTS; ++st) {\n        int L, R, B, T;\n\n        // ----- choose a start rectangle -----\n        if (uniform_int_distribution<int>(0, 1)(rng)) {          // start from a point\n            int id = uniform_int_distribution<int>(0, 2 * N - 1)(rng);\n            L = R = pts[id].first;\n            B = T = pts[id].second;\n        } else {                                                 // random pair of xs / ys\n            int ix1 = uniform_int_distribution<int>(0, X - 1)(rng);\n            int ix2 = uniform_int_distribution<int>(0, X - 1)(rng);\n            if (ix1 > ix2) swap(ix1, ix2);\n            L = xs[ix1];\n            R = xs[ix2];\n            if (L == R) {                     // make width at least 1\n                if (ix2 + 1 < X) R = xs[ix2 + 1];\n                else if (ix1 - 1 >= 0) L = xs[ix1 - 1];\n                else { L = 0; R = 1; }\n            }\n            int iy1 = uniform_int_distribution<int>(0, Y - 1)(rng);\n            int iy2 = uniform_int_distribution<int>(0, Y - 1)(rng);\n            if (iy1 > iy2) swap(iy1, iy2);\n            B = ys[iy1];\n            T = ys[iy2];\n            if (B == T) {\n                if (iy2 + 1 < Y) T = ys[iy2 + 1];\n                else if (iy1 - 1 >= 0) B = ys[iy1 - 1];\n                else { B = 0; T = 1; }\n            }\n        }\n        if (L > R) swap(L, R);\n        if (B > T) swap(B, T);\n        // ensure positive width / height\n        if (L == R) { if (L < MAXC) R = L + 1; else L = R - 1; }\n        if (B == T) { if (B < MAXC) T = B + 1; else B = T - 1; }\n\n        int cur = getSum(L, R, B, T);\n\n        // ----- local search -----\n        for (int it = 0; it < MAX_ITER; ++it) {\n            int bestDelta = 0;\n            int moveCode = -1;               // 0\u20267 as described in the analysis\n\n            // expand / shrink each side\n            if (L > 0) {\n                int d = colSum(L - 1, B, T);\n                if (d > bestDelta) { bestDelta = d; moveCode = 0; }\n            }\n            if (L + 1 < R) {\n                int d = -colSum(L, B, T);\n                if (d > bestDelta) { bestDelta = d; moveCode = 1; }\n            }\n            if (R < MAXC) {\n                int d = colSum(R + 1, B, T);\n                if (d > bestDelta) { bestDelta = d; moveCode = 2; }\n            }\n            if (R - 1 > L) {\n                int d = -colSum(R, B, T);\n                if (d > bestDelta) { bestDelta = d; moveCode = 3; }\n            }\n            if (B > 0) {\n                int d = rowSum(B - 1, L, R);\n                if (d > bestDelta) { bestDelta = d; moveCode = 4; }\n            }\n            if (B + 1 < T) {\n                int d = -rowSum(B, L, R);\n                if (d > bestDelta) { bestDelta = d; moveCode = 5; }\n            }\n            if (T < MAXC) {\n                int d = rowSum(T + 1, L, R);\n                if (d > bestDelta) { bestDelta = d; moveCode = 6; }\n            }\n            if (T - 1 > B) {\n                int d = -rowSum(T, L, R);\n                if (d > bestDelta) { bestDelta = d; moveCode = 7; }\n            }\n\n            if (bestDelta <= 0) break;          // local optimum reached\n\n            // apply the best move\n            switch (moveCode) {\n                case 0: --L; break;\n                case 1: ++L; break;\n                case 2: ++R; break;\n                case 3: --R; break;\n                case 4: --B; break;\n                case 5: ++B; break;\n                case 6: ++T; break;\n                case 7: --T; break;\n            }\n            cur += bestDelta;\n        }\n\n        if (cur > bestVal) {\n            bestVal = cur;\n            bestL = L; bestR = R; bestB = B; bestT = T;\n        }\n    }\n\n    /* ------------------------------------------------------------\n       output the rectangle as a polygon (four vertices)\n       ------------------------------------------------------------ */\n    // the rectangle is guaranteed to have positive width and height,\n    // thus it is a valid simple orthogonal polygon.\n    cout << 4 << '\\n';\n    cout << bestL << ' ' << bestB << '\\n';\n    cout << bestR << ' ' << bestB << '\\n';\n    cout << bestR << ' ' << bestT << '\\n';\n    cout << bestL << ' ' << bestT << '\\n';\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\n\nstruct Candidate {\n    bool skip;          // true \u2192 skip this rectangle\n    int rot;            // 0 = not rotated, 1 = rotated\n    char dir;           // 'U' or 'L'\n    int ref;            // -1 or index of a previously placed rectangle\n    ll sum;             // heuristic score (width+height+penalty)\n    ll x, y, w, h;      // coordinates and size (valid only if !skip)\n};\n\nstruct PlacedRect {\n    ll x, y, w, h;\n    int idx;            // original index\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, T;\n    long long sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n    vector<ll> mw(N), mh(N);                 // measured sizes\n    for (int i = 0; i < N; ++i) cin >> mw[i] >> mh[i];\n\n    // random generator \u2013 deterministic but different each turn\n    std::mt19937 rng(123456789);\n\n    // -------------------------------------------------------------\n    // process each turn\n    for (int turn = 0; turn < T; ++turn) {\n        // current state\n        vector<int> placedIdx;                     // indices of placed rectangles\n        vector<ll> X(N, 0), Y(N, 0), W(N, 0), H(N, 0);\n        vector<char> used(N, 0);\n        ll curW = 0, curH = 0;                      // current bounding box\n        ll penalty = 0;                             // sum of skipped measured sizes\n\n        vector<tuple<int,int,char,int>> answer;     // (p, r, d, b)\n\n        // ---------------------------------------------------------\n        // greedy construction rectangle after rectangle\n        for (int i = 0; i < N; ++i) {\n            vector<Candidate> cand;\n\n            // ----  skip candidate  --------------------------------\n            ll pen_i = mw[i] + mh[i];\n            cand.push_back({true, 0, '?', -1,\n                            curW + curH + penalty + pen_i,\n                            0,0,0,0});\n\n            // ----  placement candidates  ---------------------------\n            // collect possible references (already placed rectangles)\n            vector<int> refs;\n            refs.push_back(-1);\n            if (!placedIdx.empty()) {\n                refs.push_back(placedIdx.back());          // the last one\n                // a few random ones\n                for (int qq = 0; qq < 3; ++qq) {\n                    int r = placedIdx[uniform_int_distribution<int>(0, (int)placedIdx.size()-1)(rng)];\n                    if (find(refs.begin(), refs.end(), r) == refs.end())\n                        refs.push_back(r);\n                }\n            }\n\n            // try both rotations\n            for (int rot = 0; rot <= 1; ++rot) {\n                ll wi = rot ? mh[i] : mw[i];\n                ll hi = rot ? mw[i] : mh[i];\n\n                // both directions\n                for (char dir : {'U', 'L'}) {\n                    for (int ref : refs) {\n                        ll nx, ny;\n                        if (dir == 'U') {\n                            ll left = (ref == -1) ? 0 : X[ref] + W[ref];\n                            ll highest = 0;\n                            for (int k : placedIdx) {\n                                // overlap in x ?\n                                if (X[k] < left + wi && X[k] + W[k] > left) {\n                                    highest = max(highest, Y[k] + H[k]);\n                                }\n                            }\n                            nx = left;\n                            ny = highest;               // may be 0\n                        } else { // 'L'\n                            ll top = (ref == -1) ? 0 : Y[ref] + H[ref];\n                            ll rightmost = 0;\n                            for (int k : placedIdx) {\n                                // overlap in y ?\n                                if (Y[k] < top + hi && Y[k] + H[k] > top) {\n                                    rightmost = max(rightmost, X[k] + W[k]);\n                                }\n                            }\n                            ll tmp = rightmost - wi;\n                            nx = tmp < 0 ? 0 : tmp;\n                            ny = top;\n                        }\n                        ll nw = max(curW, nx + wi);\n                        ll nh = max(curH, ny + hi);\n                        ll sc = nw + nh + penalty;      // score after placing\n                        cand.push_back({false, rot, dir, ref, sc, nx, ny, wi, hi});\n                    }\n                }\n            }\n\n            // ----  choose best (or one of the best three)  -------\n            sort(cand.begin(), cand.end(),\n                 [](const Candidate& a, const Candidate& b){ return a.sum < b.sum; });\n            int topK = min(3, (int)cand.size());\n            int chosen = uniform_int_distribution<int>(0, topK-1)(rng);\n            const Candidate& c = cand[chosen];\n\n            if (c.skip) {\n                // skip this rectangle\n                penalty += pen_i;\n                // nothing is added to the answer\n            } else {\n                // place it\n                answer.emplace_back(i, c.dir == 'U' ? (c.rot ? 1 : 0) : (c.rot ? 1 : 0),\n                                   c.dir, c.ref);\n                // store data for later references\n                X[i] = c.x; Y[i] = c.y; W[i] = c.w; H[i] = c.h;\n                used[i] = 1;\n                placedIdx.push_back(i);\n                curW = max(curW, c.x + c.w);\n                curH = max(curH, c.y + c.h);\n            }\n        } // end for each rectangle\n\n        // -------------------------------------------------------------\n        // output the description\n        cout << answer.size() << '\\n';\n        for (auto [p, r, d, b] : answer) {\n            cout << p << ' ' << r << ' ' << d << ' ' << b << '\\n';\n        }\n        cout << flush;\n\n        // read the noisy measurement (not used)\n        long long Wobs, Hobs;\n        cin >> Wobs >> Hobs;\n    }\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\n#include <atcoder/mcf_graph>\n\nusing namespace std;\nusing ll = long long;\nusing mcf = atcoder::mcf_graph<int, ll>;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, H;\n    if (!(cin >> N >> M >> H)) return 0;\n    vector<int> A(N);\n    for (int i = 0; i < N; ++i) cin >> A[i];\n    vector<pair<int,int>> edges(M);\n    for (int i = 0; i < M; ++i) {\n        int u, v; cin >> u >> v;\n        edges[i] = {u, v};\n    }\n    // coordinates are irrelevant for the algorithm\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n    }\n\n    // adjacency of the original graph\n    vector<vector<int>> adj(N);\n    for (auto [u,v] : edges) {\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n\n    const int C = N * (H + 1);           // number of copies\n    const int S = 0;\n    const int G0 = 1;                     // first group vertex node\n    const int COPY0 = G0 + N;             // first copy node\n    const int T = COPY0 + C;              // sink\n    const int V = T + 1;                 // total vertices in the flow graph\n\n    mcf g(V);\n\n    // store edge ids for later retrieval\n    vector<vector<int>> edgeId(N, vector<int>(H + 1, -1));\n    // outgoing edge ids from each copy node (index = copy - COPY0)\n    vector<vector<int>> outCopy(C);\n\n    const int INF_CAP = N;                // enough, flow never exceeds N\n\n    // source -> group\n    for (int v = 0; v < N; ++v) {\n        g.add_edge(S, G0 + v, 1, 0);\n    }\n\n    // group -> copy (choice of depth)\n    for (int v = 0; v < N; ++v) {\n        for (int d = 0; d <= H; ++d) {\n            int copyNode = COPY0 + v * (H + 1) + d;\n            ll cost = - (ll)(d + 1) * A[v];\n            int eid = g.add_edge(G0 + v, copyNode, 1, cost);\n            edgeId[v][d] = eid;\n        }\n    }\n\n    // copy -> parent copy (for d > 0)   and copy -> sink (for d == 0)\n    for (int v = 0; v < N; ++v) {\n        for (int d = 0; d <= H; ++d) {\n            int copyNode = COPY0 + v * (H + 1) + d;\n            if (d == 0) {\n                // to sink\n                int eid = g.add_edge(copyNode, T, INF_CAP, 0);\n                outCopy[copyNode - COPY0].push_back(eid);\n            } else {\n                // to neighbours at depth d-1\n                for (int u : adj[v]) {\n                    int parentCopy = COPY0 + u * (H + 1) + (d - 1);\n                    int eid = g.add_edge(copyNode, parentCopy, INF_CAP, 0);\n                    outCopy[copyNode - COPY0].push_back(eid);\n                }\n            }\n        }\n    }\n\n    // minimum cost flow of value N\n    auto result = g.flow(S, T, N);\n    int flow = result.first;\n    // guaranteed to be N because a solution exists (all vertices can be roots)\n    if (flow != N) return 0;   // should not happen\n\n    // reconstruction\n    vector<int> parent(N, -2);   // -2 = not set yet, -1 = root\n    vector<int> depth(N, -1);\n\n    for (int v = 0; v < N; ++v) {\n        // which depth was chosen ?\n        for (int d = 0; d <= H; ++d) {\n            int eid = edgeId[v][d];\n            if (g.edge(eid).flow > 0) {\n                depth[v] = d;\n                break;\n            }\n        }\n        if (depth[v] == -1) continue; // should not happen\n\n        if (depth[v] == 0) {\n            parent[v] = -1;               // root\n            continue;\n        }\n\n        int copyNode = COPY0 + v * (H + 1) + depth[v];\n        // find the outgoing edge that carries the flow\n        for (int eid : outCopy[copyNode - COPY0]) {\n            if (g.edge(eid).flow > 0) {\n                int to = g.edge(eid).to;\n                if (to == T) {          // depth 0 would have gone here, but we are d>0\n                    parent[v] = -1;\n                } else {\n                    int pu = (to - COPY0) / (H + 1);   // parent vertex\n                    parent[v] = pu;\n                }\n                break;\n            }\n        }\n    }\n\n    // output\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << parent[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Set {\n    bool isRow;          // true \u2192 row, false \u2192 column\n    int idx;             // row number or column number\n    char dir;            // 'L','R','U','D'\n    uint64_t mask;       // bitmask of Oni indices contained in the set\n    int cost;            // number of shifts\n};\n\nint N;                                     // board size (20)\nvector<string> board;                      // input board\nint oniIdx[20][20];                        // index of Oni, -1 if none\nbool fuku[20][20];                         // true if Fukunokami\n\nint leftMostF[20], rightMostF[20];\nint topMostF[20], bottomMostF[20];\n\nvector<Set> sets;\nvector<vector<int>> oniToSets;             // for each Oni, list of set ids\n\nint M;                                     // number of Oni\nuint64_t allMask;\n\nint bestCost;\nvector<int> bestSets;\nvector<int> curSets;\nbool rowUsed[20] = {false};\nbool colUsed[20] = {false};\n\nvoid dfs(uint64_t mask, int cost) {\n    if (mask == allMask) {\n        if (cost < bestCost) {\n            bestCost = cost;\n            bestSets = curSets;\n        }\n        return;\n    }\n    if (cost >= bestCost) return;\n    int remain = __builtin_popcountll(~mask & allMask);\n    if (cost + remain >= bestCost) return; // even with 1 per oni we cannot beat\n\n    // choose uncovered Oni with smallest number of candidate sets\n    uint64_t rem = ~mask & allMask;\n    int chosenOni = -1;\n    int minOpts = 100;\n    for (uint64_t sub = rem; sub; sub &= sub - 1) {\n        int idx = __builtin_ctzll(sub);\n        int opts = 0;\n        for (int sid : oniToSets[idx]) {\n            const Set &s = sets[sid];\n            if (s.isRow && rowUsed[s.idx]) continue;\n            if (!s.isRow && colUsed[s.idx]) continue;\n            if (mask & s.mask) continue;          // already covered by chosen sets\n            ++opts;\n        }\n        if (opts == 0) return;                     // dead end (should not happen)\n        if (opts < minOpts) {\n            minOpts = opts;\n            chosenOni = idx;\n            if (minOpts == 1) break;\n        }\n    }\n    if (chosenOni == -1) return;                  // cannot cover\n\n    for (int sid : oniToSets[chosenOni]) {\n        const Set &s = sets[sid];\n        if (s.isRow && rowUsed[s.idx]) continue;\n        if (!s.isRow && colUsed[s.idx]) continue;\n        if (mask & s.mask) continue;              // overlap \u2013 already covered\n        // choose this set\n        if (s.isRow) rowUsed[s.idx] = true;\n        else         colUsed[s.idx] = true;\n        curSets.push_back(sid);\n        dfs(mask | s.mask, cost + s.cost);\n        curSets.pop_back();\n        if (s.isRow) rowUsed[s.idx] = false;\n        else         colUsed[s.idx] = false;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N;\n    board.resize(N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n\n    // locate Oni and Fukunokami, initialise arrays\n    memset(oniIdx, -1, sizeof(oniIdx));\n    memset(fuku, 0, sizeof(fuku));\n    vector<pair<int,int>> oniPos;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 'x')\n                oniIdx[i][j] = (int)oniPos.size(),\n                oniPos.emplace_back(i, j);\n            else if (board[i][j] == 'o')\n                fuku[i][j] = true;\n        }\n    M = (int)oniPos.size();                // = 2\u00b7N\n    allMask = (M == 64) ? ~0ULL : ((1ULL<<M) - 1ULL);\n\n    // left / right most Fukunokami in each row\n    const int INF = N+5;\n    for (int i = 0; i < N; ++i) {\n        leftMostF[i] = INF; rightMostF[i] = -1;\n        for (int j = 0; j < N; ++j)\n            if (fuku[i][j]) {\n                leftMostF[i] = min(leftMostF[i], j);\n                rightMostF[i] = max(rightMostF[i], j);\n            }\n    }\n    // top / bottom most Fukunokami in each column\n    for (int j = 0; j < N; ++j) {\n        topMostF[j] = INF; bottomMostF[j] = -1;\n        for (int i = 0; i < N; ++i)\n            if (fuku[i][j]) {\n                topMostF[j] = min(topMostF[j], i);\n                bottomMostF[j] = max(bottomMostF[j], i);\n            }\n    }\n\n    // build the sets\n    for (int i = 0; i < N; ++i) {\n        vector<int> idsL, idsR;\n        int maxJ = -1, minJ = INF;\n        for (int j = 0; j < N; ++j) {\n            int id = oniIdx[i][j];\n            if (id == -1) continue;\n            bool leftClear = (leftMostF[i] == INF) || (leftMostF[i] > j);\n            bool rightClear = (rightMostF[i] == -1) || (rightMostF[i] < j);\n            if (leftClear) {\n                idsL.push_back(id);\n                maxJ = max(maxJ, j);\n            }\n            if (rightClear) {\n                idsR.push_back(id);\n                minJ = min(minJ, j);\n            }\n        }\n        if (!idsL.empty()) {\n            Set s; s.isRow = true; s.idx = i; s.dir = 'L';\n            s.cost = maxJ + 1;\n            s.mask = 0;\n            for (int id : idsL) s.mask |= (1ULL<<id);\n            sets.push_back(s);\n        }\n        if (!idsR.empty()) {\n            Set s; s.isRow = true; s.idx = i; s.dir = 'R';\n            s.cost = N - minJ;\n            s.mask = 0;\n            for (int id : idsR) s.mask |= (1ULL<<id);\n            sets.push_back(s);\n        }\n    }\n    for (int j = 0; j < N; ++j) {\n        vector<int> idsU, idsD;\n        int maxI = -1, minI = INF;\n        for (int i = 0; i < N; ++i) {\n            int id = oniIdx[i][j];\n            if (id == -1) continue;\n            bool upClear   = (topMostF[j] == INF) || (topMostF[j] > i);\n            bool downClear = (bottomMostF[j] == -1) || (bottomMostF[j] < i);\n            if (upClear) {\n                idsU.push_back(id);\n                maxI = max(maxI, i);\n            }\n            if (downClear) {\n                idsD.push_back(id);\n                minI = min(minI, i);\n            }\n        }\n        if (!idsU.empty()) {\n            Set s; s.isRow = false; s.idx = j; s.dir = 'U';\n            s.cost = maxI + 1;\n            s.mask = 0;\n            for (int id : idsU) s.mask |= (1ULL<<id);\n            sets.push_back(s);\n        }\n        if (!idsD.empty()) {\n            Set s; s.isRow = false; s.idx = j; s.dir = 'D';\n            s.cost = N - minI;\n            s.mask = 0;\n            for (int id : idsD) s.mask |= (1ULL<<id);\n            sets.push_back(s);\n        }\n    }\n\n    // mapping Oni -> sets\n    oniToSets.assign(M, {});\n    for (int sid = 0; sid < (int)sets.size(); ++sid) {\n        uint64_t m = sets[sid].mask;\n        while (m) {\n            int b = __builtin_ctzll(m);\n            oniToSets[b].push_back(sid);\n            m &= m-1;\n        }\n    }\n    // sort by cost (ascending) \u2013 helps the search\n    for (auto &vec : oniToSets) {\n        sort(vec.begin(), vec.end(),\n             [&](int a, int b){ return sets[a].cost < sets[b].cost; });\n    }\n\n    // upper bound = sum of individual minima (one\u2011by\u2011one removal)\n    int upper = 0;\n    for (int id = 0; id < M; ++id) {\n        int i = oniPos[id].first;\n        int j = oniPos[id].second;\n        int best = N+5;\n        bool leftClear = (leftMostF[i] == INF) || (leftMostF[i] > j);\n        bool rightClear= (rightMostF[i]==-1) || (rightMostF[i] < j);\n        bool upClear   = (topMostF[j] == INF) || (topMostF[j] > i);\n        bool downClear = (bottomMostF[j]==-1)|| (bottomMostF[j] < i);\n        if (leftClear)  best = min(best, j+1);\n        if (rightClear) best = min(best, N-j);\n        if (upClear)    best = min(best, i+1);\n        if (downClear)  best = min(best, N-i);\n        upper += best;\n    }\n    bestCost = upper;\n    // start search\n    dfs(0ULL, 0);\n\n    // produce output \u2013 column sets first, then row sets\n    vector<int> colSetIds, rowSetIds;\n    for (int sid : bestSets) {\n        if (!sets[sid].isRow) colSetIds.push_back(sid);\n        else                  rowSetIds.push_back(sid);\n    }\n\n    // output moves\n    ostringstream out;\n    for (int sid : colSetIds) {\n        const Set &s = sets[sid];\n        for (int k = 0; k < s.cost; ++k)\n            out << s.dir << ' ' << s.idx << '\\n';\n    }\n    for (int sid : rowSetIds) {\n        const Set &s = sets[sid];\n        for (int k = 0; k < s.cost; ++k)\n            out << s.dir << ' ' << s.idx << '\\n';\n    }\n    cout << out.str();\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    long long L;\n    if (!(cin >> N >> L)) return 0;\n    vector<int> T(N);\n    for (int i = 0; i < N; ++i) cin >> T[i];\n\n    // -------- adjust T[0] = 0  (error 2 is optimal) ----------\n    vector<int> t = T;\n    if (t[0] == 0) {\n        int j = -1;\n        for (int i = 1; i < N; ++i) if (t[i] > 0) { j = i; break; }\n        // there must be such j because sum = L > 0\n        t[0] = 1;\n        t[j]--;\n    }\n\n    // ----- pre\u2011compute how many odd / even edges each vertex has -----\n    vector<int> oddWeight(N), evenWeight(N);\n    for (int i = 0; i < N; ++i) {\n        oddWeight[i]  = (t[i] + 1) / 2;          // ceil\n        evenWeight[i] = t[i] / 2;                // floor\n    }\n\n    // ----- data for the walk construction -----\n    vector<int> need = t;                       // remaining indegrees\n    vector<int> vis(N, 0);                       // how many times a vertex has been visited\n    vector<int> a(N, -1), b(N, -1);              // targets, -1 = not fixed yet\n    vector<int> usedOdd(N, 0), usedEven(N, 0);   // how many edges of each kind have already been used\n\n    int cur = 0;\n    vis[0] = 1;\n    need[0]--;                                   // first week\n\n    for (long long week = 2; week <= L; ++week) {\n        // decide which kind of edge is needed now\n        bool odd = (vis[cur] % 2 == 1);          // after vis[cur] visits, parity is odd \u2192 need odd edge\n        if (odd) {\n            if (a[cur] == -1) {\n                // choose a target with enough remaining capacity\n                int target = -1;\n                for (int i = 0; i < N; ++i) {\n                    if (need[i] >= oddWeight[cur]) {\n                        target = i;\n                        break;\n                    }\n                }\n                // target must exist\n                a[cur] = target;\n            }\n            cur = a[cur];\n        } else {\n            if (b[cur] == -1) {\n                int target = -1;\n                for (int i = 0; i < N; ++i) {\n                    if (need[i] >= evenWeight[cur]) {\n                        target = i;\n                        break;\n                    }\n                }\n                b[cur] = target;\n            }\n            cur = b[cur];\n        }\n        ++vis[cur];\n        --need[cur];\n    }\n\n    // set default values for edges that never had to be fixed\n    for (int i = 0; i < N; ++i) {\n        if (a[i] == -1) a[i] = i;   // never used odd edge \u2192 self loop\n        if (b[i] == -1) b[i] = i;   // never used even edge \u2192 self loop\n    }\n\n    // --------------- output --------------------\n    for (int i = 0; i < N; ++i) {\n        cout << a[i] << ' ' << b[i] << \"\\n\";\n    }\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, Q, L, W;\n    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n\n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n\n    vector<int> lx(N), rx(N), ly(N), ry(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n    }\n\n    /* centre of the rectangle \u2013 heuristic position of the city */\n    vector<double> cx(N), cy(N);\n    for (int i = 0; i < N; ++i) {\n        cx[i] = (lx[i] + rx[i]) / 2.0;\n        cy[i] = (ly[i] + ry[i]) / 2.0;\n    }\n\n    /* sort cities by the centre */\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(),\n         [&](int a, int b) {\n             if (cx[a] != cx[b]) return cx[a] < cx[b];\n             return cy[a] < cy[b];\n         });\n\n    /* build the groups */\n    vector<vector<int>> groups(M);\n    int pos = 0;\n    for (int gi = 0; gi < M; ++gi) {\n        groups[gi].reserve(G[gi]);\n        for (int j = 0; j < G[gi]; ++j) {\n            groups[gi].push_back(order[pos++]);\n        }\n    }\n\n    /* edges of each group (the answer) */\n    vector<vector<pair<int,int>>> groupEdges(M);\n\n    auto ask = [&](const vector<int>& cities, int gid) {\n        cout << \"? \" << cities.size();\n        for (int v : cities) cout << ' ' << v;\n        cout << \"\\n\";\n        cout.flush();                     // mandatory\n        int sz = (int)cities.size();\n        for (int i = 0; i < sz - 1; ++i) {\n            int a, b;  cin >> a >> b;\n            groupEdges[gid].push_back({a, b});\n        }\n    };\n\n    /* construct a spanning tree for every group */\n    for (int gid = 0; gid < M; ++gid) {\n        int gsize = (int)groups[gid].size();\n        if (gsize <= 1) continue;                // nothing to do\n        if (gsize == 2) {                         // only one possible edge\n            groupEdges[gid].push_back({groups[gid][0], groups[gid][1]});\n            continue;\n        }\n\n        int i = 0;\n        while (i + L <= gsize) {                 // full window of size L\n            vector<int> sub(L);\n            for (int j = 0; j < L; ++j) sub[j] = groups[gid][i + j];\n            ask(sub, gid);\n            i += L - 1;\n        }\n        if (i < gsize - 1) {                      // last (2 \u2026 L) vertices\n            int rem = gsize - i;\n            vector<int> sub(rem);\n            for (int j = 0; j < rem; ++j) sub[j] = groups[gid][i + j];\n            ask(sub, gid);\n        }\n    }\n\n    /* output */\n    cout << \"!\\n\";\n    for (int gid = 0; gid < M; ++gid) {\n        for (int j = 0; j < (int)groups[gid].size(); ++j) {\n            if (j) cout << ' ';\n            cout << groups[gid][j];\n        }\n        cout << \"\\n\";\n        for (auto &e : groupEdges[gid]) {\n            cout << e.first << ' ' << e.second << \"\\n\";\n        }\n    }\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n    vector<pair<int,int>> pos;\n    pos.reserve(M + 1);\n    for (int k = 0; k <= M; ++k) {\n        int i, j;\n        cin >> i >> j;\n        pos.emplace_back(i, j);\n    }\n\n    // current position\n    int r = pos[0].first;\n    int c = pos[0].second;\n\n    // store output lines\n    vector<string> out;\n    out.reserve(1600);\n\n    for (int idx = 1; idx <= M; ++idx) {\n        int tr = pos[idx].first;\n        int tc = pos[idx].second;\n        while (r != tr || c != tc) {\n            if (r < tr) {               // move down\n                out.emplace_back(\"M D\");\n                ++r;\n            } else if (r > tr) {        // move up\n                out.emplace_back(\"M U\");\n                --r;\n            } else if (c < tc) {        // move right\n                out.emplace_back(\"M R\");\n                ++c;\n            } else if (c > tc) {        // move left\n                out.emplace_back(\"M L\");\n                --c;\n            }\n        }\n    }\n\n    // safety check (not required for correctness)\n    if (out.size() > 2 * N * M) {\n        cerr << \"Too many actions!\\n\";\n        return 0;\n    }\n\n    for (const string& s : out) cout << s << '\\n';\n    return 0;\n}"},"2":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int x, y;          // integer coordinates of the unit square\n    int r;             // required area\n    int idx;           // original index\n};\n\nstruct Node {\n    int x1, y1, x2, y2;                // region [x1,x2) \u00d7 [y1,y2)\n    vector<int> ids;                   // indices of points inside\n};\n\nint n;\nvector<Point> pts;\nvector<Node> leafRegion;               // region for each original index\n\n/*------------------------------------------------------------------*/\n/* building the binary space partition                              */\nvoid build(Node &node) {\n    if (node.ids.size() == 1) {\n        leafRegion[ node.ids[0] ] = node;\n        return;\n    }\n\n    int W = node.x2 - node.x1;\n    int H = node.y2 - node.y1;\n    long long totalR = 0;\n    for (int id : node.ids) totalR += pts[id].r;\n\n    const long long INF = (1LL<<60);\n    long long bestDiff = INF;\n    int bestAxis = -1;          // 0 = vertical, 1 = horizontal\n    int bestK = -1;             // split coordinate\n    int bestP = -1;             // number of points on the left side\n\n    // ----- vertical splits -----\n    {\n        vector<int> v = node.ids;\n        sort(v.begin(), v.end(),\n             [&](int a, int b){ return pts[a].x < pts[b].x; });\n        vector<long long> pref(v.size()+1,0);\n        for (size_t i=0;i<v.size();++i) pref[i+1]=pref[i]+pts[v[i]].r;\n\n        for (size_t p=1;p<v.size();++p) {          // left: first p points\n            long long sumL = pref[p];\n            long long sumR = totalR - sumL;\n            int leftMaxX = pts[v[p-1]].x;\n            int k = leftMaxX + 1;                  // first column of the right part\n            if (k <= node.x1 || k >= node.x2) continue; // keep positive width\n            int wL = k - node.x1;\n            int wR = node.x2 - k;\n            long long areaL = 1LL * wL * H;\n            long long areaR = 1LL * wR * H;\n            long long diff = llabs(areaL - sumL) + llabs(areaR - sumR);\n            if (diff < bestDiff) {\n                bestDiff = diff;\n                bestAxis = 0;\n                bestK = k;\n                bestP = (int)p;\n            }\n        }\n    }\n\n    // ----- horizontal splits -----\n    {\n        vector<int> v = node.ids;\n        sort(v.begin(), v.end(),\n             [&](int a, int b){ return pts[a].y < pts[b].y; });\n        vector<long long> pref(v.size()+1,0);\n        for (size_t i=0;i<v.size();++i) pref[i+1]=pref[i]+pts[v[i]].r;\n\n        for (size_t p=1;p<v.size();++p) {\n            long long sumL = pref[p];\n            long long sumR = totalR - sumL;\n            int leftMaxY = pts[v[p-1]].y;\n            int k = leftMaxY + 1;\n            if (k <= node.y1 || k >= node.y2) continue;\n            int hL = k - node.y1;\n            int hR = node.y2 - k;\n            long long areaL = 1LL * W * hL;\n            long long areaR = 1LL * W * hR;\n            long long diff = llabs(areaL - sumL) + llabs(areaR - sumR);\n            if (diff < bestDiff) {\n                bestDiff = diff;\n                bestAxis = 1;\n                bestK = k;\n                bestP = (int)p;\n            }\n        }\n    }\n\n    // perform the chosen split\n    vector<int> leftIds, rightIds;\n    if (bestAxis == 0) {               // vertical\n        vector<int> v = node.ids;\n        sort(v.begin(), v.end(),\n             [&](int a, int b){ return pts[a].x < pts[b].x; });\n        leftIds.assign(v.begin(), v.begin()+bestP);\n        rightIds.assign(v.begin()+bestP, v.end());\n        Node L{node.x1, node.y1, bestK, node.y2, leftIds};\n        Node R{bestK, node.y1, node.x2, node.y2, rightIds};\n        build(L);\n        build(R);\n    } else {                           // horizontal\n        vector<int> v = node.ids;\n        sort(v.begin(), v.end(),\n             [&](int a, int b){ return pts[a].y < pts[b].y; });\n        leftIds.assign(v.begin(), v.begin()+bestP);\n        rightIds.assign(v.begin()+bestP, v.end());\n        Node L{node.x1, node.y1, node.x2, bestK, leftIds};\n        Node R{node.x1, bestK, node.x2, node.y2, rightIds};\n        build(L);\n        build(R);\n    }\n}\n\n/*------------------------------------------------------------------*/\n/* main                                                             */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> n;\n    pts.resize(n);\n    for (int i=0;i<n;++i) {\n        cin >> pts[i].x >> pts[i].y >> pts[i].r;\n        pts[i].idx = i;\n    }\n\n    leafRegion.assign(n, Node{0,0,0,0,{}});\n\n    // initial node\n    vector<int> allIds(n);\n    iota(allIds.begin(), allIds.end(), 0);\n    Node root{0,0,10000,10000, allIds};\n    build(root);\n\n    // place rectangles\n    vector<int> a(n), b(n), c(n), d(n);\n    long double sumP = 0.0L;\n\n    for (int i=0;i<n;++i) {\n        const Node &leaf = leafRegion[i];\n        const Point &p = pts[i];\n        int W = leaf.x2 - leaf.x1;\n        int H = leaf.y2 - leaf.y1;\n\n        int bestW = 1, bestH = 1;\n        long long bestDiff = llabs(1LL*bestW*bestH - p.r);\n\n        for (int w=1; w<=W; ++w) {\n            long long h0 = p.r / w;          // floor\n            for (int dh=0; dh<=1; ++dh) {\n                int h = (int)(h0 + dh);\n                if (h < 1 || h > H) continue;\n                long long diff = llabs(1LL*w*h - p.r);\n                if (diff < bestDiff ||\n                    (diff == bestDiff && 1LL*w*h > 1LL*bestW*bestH)) {\n                    bestDiff = diff;\n                    bestW = w;\n                    bestH = h;\n                }\n            }\n        }\n\n        // place the rectangle inside the leaf, still covering the unit square\n        int left  = max(leaf.x1, p.x + 1 - bestW);\n        int bottom = max(leaf.y1, p.y + 1 - bestH);\n        int right  = left + bestW;\n        int top    = bottom + bestH;\n\n        // safety (can be omitted)\n        //assert(right <= leaf.x2 && top <= leaf.y2);\n\n        a[i] = left; b[i] = bottom; c[i] = right; d[i] = top;\n\n        long long s = 1LL*bestW*bestH;\n        double ratio = (double)min(p.r, (int)s) / (double)max(p.r, (int)s);\n        double pi = ratio * (2.0 - ratio);\n        sumP += pi;\n    }\n\n    // output\n    for (int i=0;i<n;++i) {\n        cout << a[i] << ' ' << b[i] << ' ' << c[i] << ' ' << d[i] << '\\n';\n    }\n\n    // (the score is not required to be printed)\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------- input ---------- */\n    int si, sj;\n    if (!(cin >> si >> sj)) return 0;\n    const int N = 50;\n    vector<vector<int>> tile(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> tile[i][j];\n    vector<vector<int>> val(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> val[i][j];\n\n    /* number of different tiles */\n    int maxTile = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            maxTile = max(maxTile, tile[i][j]);\n    const int M = maxTile + 1;                 // tile ids are 0 \u2026 M\u20111\n\n    /* ---------- cell graph (only edges to cells of other tiles) ---------- */\n    const int V = N * N;\n    vector<int> cellVal(V);\n    vector<vector<int>> adj(V);\n    auto id = [&](int i, int j) { return i * N + j; };\n    const int di[4] = {-1, 1, 0, 0};\n    const int dj[4] = {0, 0, -1, 1};\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int u = id(i, j);\n            cellVal[u] = val[i][j];\n            for (int d = 0; d < 4; ++d) {\n                int ni = i + di[d], nj = j + dj[d];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                int v = id(ni, nj);\n                if (tile[ni][nj] != tile[i][j]) adj[u].push_back(v);\n            }\n        }\n    }\n\n    const int startCell = id(si, sj);\n    const int startTile = tile[si][sj];\n\n    auto dirChar = [&](int from, int to) -> char {\n        int fi = from / N, fj = from % N;\n        int ti = to / N,   tj = to % N;\n        if (ti == fi - 1 && tj == fj) return 'U';\n        if (ti == fi + 1 && tj == fj) return 'D';\n        if (ti == fi && tj == fj - 1) return 'L';\n        if (ti == fi && tj == fj + 1) return 'R';\n        return '?';                     // never happens\n    };\n\n    /* ---------- randomised greedy walks ---------- */\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    const int MAX_TRIES   = 50000;      // many more trials than before\n    const int RAND_PROB   = 10;         // 10\u202f% chance to act completely random\n\n    vector<int> visitedTile(M, 0);\n    int curToken = 1;\n\n    string bestPath;\n    int bestScore = -1;\n\n    for (int attempt = 0; attempt < MAX_TRIES; ++attempt) {\n        ++curToken;\n        visitedTile[startTile] = curToken;   // start tile is already used\n\n        int cur = startCell;\n        int curScore = cellVal[cur];\n        string path;\n\n        /* random parameters for this trial */\n        int gamma = uniform_int_distribution<int>(0, 8)(rng);\n        bool useWeighted = (rng() % 2 == 0);   // choose heuristic type\n\n        while (true) {\n            /* collect admissible neighbours (different, not yet visited tile) */\n            vector<int> cand;\n            for (int nb : adj[cur]) {\n                int ntile = tile[nb / N][nb % N];\n                if (visitedTile[ntile] != curToken) cand.push_back(nb);\n            }\n            if (cand.empty()) break;          // stuck\n\n            /* small chance to pick a random neighbour */\n            if (uniform_int_distribution<int>(0, 99)(rng) < RAND_PROB) {\n                int idx = uniform_int_distribution<int>(0, (int)cand.size() - 1)(rng);\n                int nxt = cand[idx];\n                path.push_back(dirChar(cur, nxt));\n                cur = nxt;\n                int ntile = tile[cur / N][cur % N];\n                visitedTile[ntile] = curToken;\n                curScore += cellVal[cur];\n                continue;\n            }\n\n            /* evaluate all candidates */\n            int bestHeur = -1;\n            int bestNext = -1;\n            for (int nb : cand) {\n                int value = cellVal[nb];\n                int pot = 0;\n                if (useWeighted) {\n                    // sum of values of still free neighbour cells\n                    for (int nb2 : adj[nb]) {\n                        int t2 = tile[nb2 / N][nb2 % N];\n                        if (visitedTile[t2] != curToken) pot += cellVal[nb2];\n                    }\n                    pot /= 10;                 // scale down a bit\n                } else {\n                    // just the number of free neighbour tiles\n                    for (int nb2 : adj[nb]) {\n                        int t2 = tile[nb2 / N][nb2 % N];\n                        if (visitedTile[t2] != curToken) ++pot;\n                    }\n                }\n                int heur = value + gamma * pot;\n                if (heur > bestHeur) {\n                    bestHeur = heur;\n                    bestNext = nb;\n                } else if (heur == bestHeur && (rng() & 1)) {\n                    bestNext = nb;            // random tie\u2011break\n                }\n            }\n\n            /* perform the chosen step */\n            path.push_back(dirChar(cur, bestNext));\n            cur = bestNext;\n            int ntile = tile[cur / N][cur % N];\n            visitedTile[ntile] = curToken;\n            curScore += cellVal[cur];\n        }\n\n        if (curScore > bestScore) {\n            bestScore = curScore;\n            bestPath = path;\n        }\n    }\n\n    cout << bestPath << '\\n';\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 30;\n    const int V = N * N;\n    const double INF = 1e100;\n    const double INIT_W = 5000.0;\n    const double ALPHA = 0.2;\n    const double MIN_W = 500.0;\n    const double MAX_W = 15000.0;\n\n    // edge estimates\n    double hor[N][N-1]; // horizontal: (i,j)-(i,j+1), j = 0..28\n    double ver[N-1][N]; // vertical:   (i,j)-(i+1,j), i = 0..28\n\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N-1; ++j)\n            hor[i][j] = INIT_W;\n    for (int i = 0; i < N-1; ++i)\n        for (int j = 0; j < N; ++j)\n            ver[i][j] = INIT_W;\n\n    auto idx = [&](int i, int j) { return i * N + j; };\n\n    for (int q = 0; q < 1000; ++q) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) break;\n\n        int s = idx(si, sj);\n        int t = idx(ti, tj);\n\n        // Dijkstra\n        vector<double> dist(V, INF);\n        vector<int> prev(V, -1);\n        vector<char> move(V, 0); // direction from prev to this vertex\n        dist[s] = 0.0;\n        using Node = pair<double,int>;\n        priority_queue<Node, vector<Node>, greater<Node>> pq;\n        pq.emplace(0.0, s);\n\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u] + 1e-12) continue;\n            if (u == t) break;\n            int ui = u / N;\n            int uj = u % N;\n\n            // up\n            if (ui > 0) {\n                int v = idx(ui-1, uj);\n                double w = ver[ui-1][uj];\n                double nd = d + w;\n                if (nd + 1e-12 < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    move[v] = 'U';\n                    pq.emplace(nd, v);\n                }\n            }\n            // down\n            if (ui < N-1) {\n                int v = idx(ui+1, uj);\n                double w = ver[ui][uj];\n                double nd = d + w;\n                if (nd + 1e-12 < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    move[v] = 'D';\n                    pq.emplace(nd, v);\n                }\n            }\n            // left\n            if (uj > 0) {\n                int v = idx(ui, uj-1);\n                double w = hor[ui][uj-1];\n                double nd = d + w;\n                if (nd + 1e-12 < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    move[v] = 'L';\n                    pq.emplace(nd, v);\n                }\n            }\n            // right\n            if (uj < N-1) {\n                int v = idx(ui, uj+1);\n                double w = hor[ui][uj];\n                double nd = d + w;\n                if (nd + 1e-12 < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    move[v] = 'R';\n                    pq.emplace(nd, v);\n                }\n            }\n        }\n\n        // reconstruct path\n        string path;\n        int cur = t;\n        while (cur != s) {\n            char m = move[cur];\n            path.push_back(m);\n            cur = prev[cur];\n        }\n        reverse(path.begin(), path.end());\n\n        // output\n        cout << path << '\\n' << flush;\n\n        // receive noisy length\n        long long noisy;\n        cin >> noisy;\n\n        // learning\n        double est = dist[t];                // \u03a3 w_e according to current estimates\n        double ratio = (double)noisy / est;  // B / E\n        double factor = 1.0 + ALPHA * (ratio - 1.0);\n        if (factor < 0.5) factor = 0.5;\n        if (factor > 2.0) factor = 2.0;\n\n        // apply factor to all edges of the printed path\n        int i = si, j = sj;\n        for (char c : path) {\n            if (c == 'U') {\n                ver[i-1][j] *= factor;\n                if (ver[i-1][j] < MIN_W) ver[i-1][j] = MIN_W;\n                if (ver[i-1][j] > MAX_W) ver[i-1][j] = MAX_W;\n                --i;\n            } else if (c == 'D') {\n                ver[i][j] *= factor;\n                if (ver[i][j] < MIN_W) ver[i][j] = MIN_W;\n                if (ver[i][j] > MAX_W) ver[i][j] = MAX_W;\n                ++i;\n            } else if (c == 'L') {\n                hor[i][j-1] *= factor;\n                if (hor[i][j-1] < MIN_W) hor[i][j-1] = MIN_W;\n                if (hor[i][j-1] > MAX_W) hor[i][j-1] = MAX_W;\n                --j;\n            } else if (c == 'R') {\n                hor[i][j] *= factor;\n                if (hor[i][j] < MIN_W) hor[i][j] = MIN_W;\n                if (hor[i][j] > MAX_W) hor[i][j] = MAX_W;\n                ++j;\n            }\n        }\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\n/***  global data  ***/\nint N;                                   // board size (20)\nint totalM;                              // \u03a3 multiplicity = M\nint curC, bestC;                         // weighted number of present strings\n\n// character encoding: 'A'..'H' -> 0..7\nint chCode[256];\n// powers of 8, 8^k (k \u2264 12)\nuint64_t pow8[13];\n\n// distinct strings\nunordered_map<unsigned long long, int> str2idx;   // key -> index\nvector<int> mult;                                  // multiplicity\nvector<int> occ;                                   // occurrences on current board\nint uniqCnt;                                       // number of distinct strings\n\n// substring description\nstruct SubInfo {\n    uint8_t start_i, start_j;\n    uint8_t dir;          // 0 = horizontal, 1 = vertical\n    uint8_t len;\n};\nvector<SubInfo> subs;                  // all substrings (\u2264 8800)\nvector<uint64_t> curCode;              // current base\u20118 value of each substring\nvector<int> curIdx;                    // index of matched string, -1 if none\n\n// for each cell: list of (substring id, offset inside that substring)\nvector<vector<pair<int, uint8_t>>> cellSubs;\n\n// current board and best board\nvector<string> grid;\nvector<string> bestGrid;\n\n/***  helpers  ***/\ninline unsigned long long encodeString(const string &s) {\n    unsigned long long code = 0;\n    for (char ch : s) code = (code << 3) | (unsigned long long)chCode[(unsigned char)ch];\n    return code;\n}\ninline unsigned long long keyWithLen(unsigned long long code, int len) {\n    return (code << 4) | (unsigned long long)len;\n}\n\n/***  initial evaluation from a given board  ***/\nvoid initFromGrid(const vector<string> &g) {\n    fill(occ.begin(), occ.end(), 0);\n    curC = 0;\n    int S = (int)subs.size();\n    for (int sid = 0; sid < S; ++sid) {\n        const SubInfo &inf = subs[sid];\n        unsigned long long code = 0;\n        for (int p = 0; p < inf.len; ++p) {\n            int r = (inf.dir == 0) ? inf.start_i\n                                    : (inf.start_i + p) % N;\n            int c = (inf.dir == 0) ? (inf.start_j + p) % N\n                                    : inf.start_j;\n            char ch = g[r][c];\n            code = (code << 3) | (unsigned long long)chCode[(unsigned char)ch];\n        }\n        unsigned long long key = (code << 4) | (unsigned long long)inf.len;\n        int idx = -1;\n        auto it = str2idx.find(key);\n        if (it != str2idx.end()) idx = it->second;\n        curIdx[sid] = idx;\n        curCode[sid] = code;\n        if (idx != -1) occ[idx]++;\n    }\n    for (int i = 0; i < uniqCnt; ++i)\n        if (occ[i] > 0) curC += mult[i];\n}\n\n/***  compute delta for a single cell change  ***/\nint computeDelta(int cell, char newChar) {\n    int r = cell / N;\n    int c = cell % N;\n    char oldChar = grid[r][c];\n    if (oldChar == newChar) return 0;\n    int oldVal = chCode[(unsigned char)oldChar];\n    int newVal = chCode[(unsigned char)newChar];\n    int delta = 0;\n    for (const auto &pr : cellSubs[cell]) {\n        int sid = pr.first;\n        int offset = pr.second;\n        const SubInfo &inf = subs[sid];\n        int len = inf.len;\n        int exp = len - 1 - offset;\n        unsigned long long oldCodeSub = curCode[sid];\n        unsigned long long newCodeSub = oldCodeSub\n                                      - (unsigned long long)oldVal * pow8[exp]\n                                      + (unsigned long long)newVal * pow8[exp];\n        unsigned long long newKey = (newCodeSub << 4) | (unsigned long long)len;\n        int newIdx = -1;\n        auto it = str2idx.find(newKey);\n        if (it != str2idx.end()) newIdx = it->second;\n        int oldIdx = curIdx[sid];\n        if (oldIdx == newIdx) continue;                 // nothing changes\n        if (oldIdx != -1) {\n            if (occ[oldIdx] == 1) delta -= mult[oldIdx]; // disappears\n        }\n        if (newIdx != -1) {\n            if (occ[newIdx] == 0) delta += mult[newIdx]; // appears\n        }\n    }\n    return delta;\n}\n\n/***  apply a accepted move ***/\nvoid applyDelta(int cell, char newChar) {\n    int r = cell / N;\n    int c = cell % N;\n    char oldChar = grid[r][c];\n    if (oldChar == newChar) return;\n    int oldVal = chCode[(unsigned char)oldChar];\n    int newVal = chCode[(unsigned char)newChar];\n    for (const auto &pr : cellSubs[cell]) {\n        int sid = pr.first;\n        int offset = pr.second;\n        const SubInfo &inf = subs[sid];\n        int len = inf.len;\n        int exp = len - 1 - offset;\n        unsigned long long oldCodeSub = curCode[sid];\n        unsigned long long newCodeSub = oldCodeSub\n                                      - (unsigned long long)oldVal * pow8[exp]\n                                      + (unsigned long long)newVal * pow8[exp];\n        unsigned long long newKey = (newCodeSub << 4) | (unsigned long long)len;\n        int newIdx = -1;\n        auto it = str2idx.find(newKey);\n        if (it != str2idx.end()) newIdx = it->second;\n        int oldIdx = curIdx[sid];\n        if (oldIdx == newIdx) {\n            curCode[sid] = newCodeSub;\n            curIdx[sid] = newIdx;\n            continue;\n        }\n        if (oldIdx != -1) {\n            if (occ[oldIdx] == 1) curC -= mult[oldIdx];\n            --occ[oldIdx];\n        }\n        if (newIdx != -1) {\n            if (occ[newIdx] == 0) curC += mult[newIdx];\n            ++occ[newIdx];\n        }\n        curCode[sid] = newCodeSub;\n        curIdx[sid] = newIdx;\n    }\n    grid[r][c] = newChar;\n}\n\n/***  main ***/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M;\n    if (!(cin >> N >> M)) return 0;\n    totalM = M;\n\n    // character encoding\n    fill(begin(chCode), end(chCode), -1);\n    for (char ch = 'A'; ch <= 'H'; ++ch) chCode[(unsigned char)ch] = ch - 'A';\n\n    // read strings, build distinct set\n    vector<string> inputs(M);\n    for (int i = 0; i < M; ++i) cin >> inputs[i];\n    for (const string &s : inputs) {\n        unsigned long long code = encodeString(s);\n        unsigned long long key = (code << 4) | (unsigned long long)s.size();\n        auto it = str2idx.find(key);\n        if (it == str2idx.end()) {\n            int id = (int)mult.size();\n            str2idx[key] = id;\n            mult.push_back(1);\n        } else {\n            ++mult[it->second];\n        }\n    }\n    uniqCnt = (int)mult.size();\n    occ.assign(uniqCnt, 0);\n\n    // powers of 8\n    pow8[0] = 1;\n    for (int i = 1; i <= 12; ++i) pow8[i] = pow8[i - 1] * 8ULL;\n\n    // build all substrings and cell\u2192substring lists\n    subs.reserve(8800);\n    cellSubs.assign(N * N, {});\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            // horizontal\n            for (int len = 2; len <= 12; ++len) {\n                SubInfo inf;\n                inf.start_i = (uint8_t)i;\n                inf.start_j = (uint8_t)j;\n                inf.dir = 0;\n                inf.len = (uint8_t)len;\n                int sid = (int)subs.size();\n                subs.push_back(inf);\n                for (int p = 0; p < len; ++p) {\n                    int cj = (j + p) % N;\n                    int cell = i * N + cj;\n                    cellSubs[cell].push_back({sid, (uint8_t)p});\n                }\n            }\n            // vertical\n            for (int len = 2; len <= 12; ++len) {\n                SubInfo inf;\n                inf.start_i = (uint8_t)i;\n                inf.start_j = (uint8_t)j;\n                inf.dir = 1;\n                inf.len = (uint8_t)len;\n                int sid = (int)subs.size();\n                subs.push_back(inf);\n                for (int p = 0; p < len; ++p) {\n                    int ri = (i + p) % N;\n                    int cell = ri * N + j;\n                    cellSubs[cell].push_back({sid, (uint8_t)p});\n                }\n            }\n        }\n    }\n\n    curCode.assign(subs.size(), 0);\n    curIdx.assign(subs.size(), -1);\n\n    // random initial board\n    grid.assign(N, string(N, 'A'));\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            grid[i][j] = char('A' + rng() % 8);\n\n    // initial evaluation\n    initFromGrid(grid);\n    bestGrid = grid;\n    bestC = curC;\n\n    // hill\u2011climbing / simulated annealing\n    const double timeLimit = 2.8;               // seconds\n    const int maxIter = 2000000;\n    auto start = chrono::steady_clock::now();\n    for (int iter = 0; iter < maxIter; ++iter) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed >= timeLimit) break;\n\n        int cell = rng() % (N * N);\n        int r = cell / N, c = cell % N;\n        char oldChar = grid[r][c];\n        char newChar;\n        do {\n            newChar = char('A' + rng() % 8);\n        } while (newChar == oldChar);\n\n        int delta = computeDelta(cell, newChar);\n        bool accept = false;\n        if (delta > 0) accept = true;\n        else if (delta == 0) {\n            if (rng() % 100 < 10) accept = true;          // 10%\n        } else {\n            if (rng() % 100 < 1) accept = true;           // 1%\n        }\n\n        if (accept) {\n            applyDelta(cell, newChar);\n            if (curC > bestC) {\n                bestC = curC;\n                bestGrid = grid;\n                if (bestC == totalM) break;               // perfect!\n            }\n        }\n    }\n\n    // output best board\n    for (int i = 0; i < N; ++i) cout << bestGrid[i] << '\\n';\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing pii = pair<int,int>;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, si, sj;\n    if(!(cin >> N >> si >> sj)) return 0;\n    vector<string> g(N);\n    for (int i = 0; i < N; ++i) cin >> g[i];\n\n    /* ---------- road cells ---------- */\n    vector<vector<int>> id(N, vector<int>(N, -1));\n    vector<pii> pos;               // id -> (i,j)\n    vector<int> w;                 // id -> entering time\n    int R = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (g[i][j] != '#') {\n                id[i][j] = R++;\n                pos.emplace_back(i, j);\n                w.push_back(g[i][j] - '0');\n            }\n\n    /* ---------- horizontal segments ---------- */\n    vector<vector<int>> rowSegId(N, vector<int>(N, -1));\n    vector<vector<int>> rowSegMembers;               // list of cell ids\n    int rowSegCnt = 0;\n    for (int i = 0; i < N; ++i) {\n        int j = 0;\n        while (j < N) {\n            if (g[i][j] == '#') { ++j; continue; }\n            int seg = rowSegCnt++;\n            rowSegMembers.emplace_back();\n            while (j < N && g[i][j] != '#') {\n                int cid = id[i][j];\n                rowSegId[i][j] = seg;\n                rowSegMembers.back().push_back(cid);\n                ++j;\n            }\n        }\n    }\n\n    /* ---------- vertical segments ---------- */\n    vector<vector<int>> colSegId(N, vector<int>(N, -1));\n    vector<vector<int>> colSegMembers;\n    int colSegCnt = 0;\n    for (int j = 0; j < N; ++j) {\n        int i = 0;\n        while (i < N) {\n            if (g[i][j] == '#') { ++i; continue; }\n            int seg = colSegCnt++;\n            colSegMembers.emplace_back();\n            while (i < N && g[i][j] != '#') {\n                int cid = id[i][j];\n                colSegId[i][j] = seg;\n                colSegMembers.back().push_back(cid);\n                ++i;\n            }\n        }\n    }\n\n    /* ----- cell -> its two segment ids ----- */\n    vector<int> cellRowSeg(R), cellColSeg(R);\n    for (int cid = 0; cid < R; ++cid) {\n        int i = pos[cid].first, j = pos[cid].second;\n        cellRowSeg[cid] = rowSegId[i][j];\n        cellColSeg[cid] = colSegId[i][j];\n    }\n\n    int startId = id[si][sj];\n    vector<char> rowCover(rowSegCnt, 0), colCover(colSegCnt, 0);\n    rowCover[cellRowSeg[startId]] = 1;\n    colCover[cellColSeg[startId]] = 1;\n\n    int coveredCnt = 0;\n    for (int cid = 0; cid < R; ++cid)\n        if (rowCover[cellRowSeg[cid]] || colCover[cellColSeg[cid]])\n            ++coveredCnt;\n\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    const char dch[4] = {'U','D','L','R'};\n\n    auto dirFromDelta = [&](int dr, int dc)->char{\n        if (dr==-1 && dc==0) return 'U';\n        if (dr==1  && dc==0) return 'D';\n        if (dr==0 && dc==-1) return 'L';\n        if (dr==0 && dc==1) return 'R';\n        return '?';\n    };\n\n    /* ---------- greedy walk ---------- */\n    string answer;\n    long long totalCost = 0;\n    int ci = si, cj = sj;\n    int curId = startId;\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    while (coveredCnt < R) {\n        int bestDir = -1;\n        int bestInc = -1;\n        int bestCost = INT_MAX;\n        int bestNi = -1, bestNj = -1;\n\n        for (int d = 0; d < 4; ++d) {\n            int ni = ci + dx[d], nj = cj + dy[d];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            if (id[ni][nj] == -1) continue;\n            int nid = id[ni][nj];\n            int rs = cellRowSeg[nid];\n            int cs = cellColSeg[nid];\n\n            int inc = 0;\n            if (!rowCover[rs]) {\n                for (int cid : rowSegMembers[rs])\n                    if (!rowCover[cellRowSeg[cid]] && !colCover[cellColSeg[cid]]) ++inc;\n            }\n            if (!colCover[cs]) {\n                for (int cid : colSegMembers[cs])\n                    if (!rowCover[cellRowSeg[cid]] && !colCover[cellColSeg[cid]]) ++inc;\n            }\n            if (!rowCover[rs] && !colCover[cs]) --inc;          // cell counted twice\n\n            if (inc > bestInc || (inc == bestInc && w[nid] < bestCost)) {\n                bestInc = inc;\n                bestCost = w[nid];\n                bestDir = d;\n                bestNi = ni; bestNj = nj;\n            }\n        }\n\n        if (bestInc > 0) {                     // move with new coverage\n            answer.push_back(dch[bestDir]);\n            totalCost += w[id[bestNi][bestNj]];\n            ci = bestNi; cj = bestNj;\n            curId = id[ci][cj];\n            int rs = cellRowSeg[curId];\n            int cs = cellColSeg[curId];\n            if (!rowCover[rs]) rowCover[rs] = 1;\n            if (!colCover[cs]) colCover[cs] = 1;\n            coveredCnt += bestInc;\n        } else {                               // no new coverage \u2013 go to nearest uncovered cell\n            // BFS\n            vector<vector<int>> dist(N, vector<int>(N, -1));\n            vector<vector<pii>> prev(N, vector<pii>(N, {-1,-1}));\n            queue<pii> q;\n            dist[ci][cj] = 0;\n            q.emplace(ci,cj);\n            int ti = -1, tj = -1;\n            while (!q.empty()) {\n                auto [x,y] = q.front(); q.pop();\n                int cid = id[x][y];\n                if (cid != -1 && (!rowCover[cellRowSeg[cid]] || !colCover[cellColSeg[cid]])) {\n                    ti = x; tj = y;\n                    break;\n                }\n                for (int d = 0; d < 4; ++d) {\n                    int nx = x + dx[d], ny = y + dy[d];\n                    if (nx<0||nx>=N||ny<0||ny>=N) continue;\n                    if (id[nx][ny]==-1) continue;\n                    if (dist[nx][ny]!=-1) continue;\n                    dist[nx][ny] = dist[x][y] + 1;\n                    prev[nx][ny] = {x,y};\n                    q.emplace(nx,ny);\n                }\n            }\n            // backtrack to the first step\n            int bx = ti, by = tj;\n            while (dist[bx][by] > 1) {\n                auto pr = prev[bx][by];\n                bx = pr.first; by = pr.second;\n            }\n            // direction from (ci,cj) to (bx,by)\n            int dirIdx = -1;\n            for (int d = 0; d < 4; ++d) {\n                if (ci + dx[d] == bx && cj + dy[d] == by) {\n                    dirIdx = d; break;\n                }\n            }\n            answer.push_back(dch[dirIdx]);\n            totalCost += w[id[bx][by]];\n            ci = bx; cj = by;\n            curId = id[ci][cj];\n            // no segment becomes covered\n        }\n    }\n\n    /* ---------- shortest way back to start (Dijkstra) ---------- */\n    const long long INF = (1LL<<60);\n    vector<long long> d(R, INF);\n    vector<int> pv(R, -1);\n    using Node = pair<long long,int>;\n    priority_queue<Node, vector<Node>, greater<Node>> pq;\n    d[startId] = 0;\n    pq.emplace(0, startId);\n    while (!pq.empty()) {\n        auto [dist, u] = pq.top(); pq.pop();\n        if (dist != d[u]) continue;\n        int ui = pos[u].first, uj = pos[u].second;\n        for (int dir = 0; dir < 4; ++dir) {\n            int vi = ui + dx[dir], vj = uj + dy[dir];\n            if (vi<0||vi>=N||vj<0||vj>=N) continue;\n            int v = id[vi][vj];\n            if (v==-1) continue;\n            long long nd = dist + w[v];\n            if (nd < d[v]) {\n                d[v] = nd;\n                pv[v] = u;\n                pq.emplace(nd, v);\n            }\n        }\n    }\n\n    // reconstruct path from cur back to start (reverse of start \u2192 cur)\n    vector<int> revPath;               // cur \u2192 \u2026 \u2192 start\n    int node = curId;\n    while (true) {\n        revPath.push_back(node);\n        if (node == startId) break;\n        node = pv[node];\n    }\n    // add the moves\n    for (int k = (int)revPath.size() - 1; k > 0; --k) {\n        int a = revPath[k];\n        int b = revPath[k-1];\n        int ai = pos[a].first, aj = pos[a].second;\n        int bi = pos[b].first, bj = pos[b].second;\n        answer.push_back(dirFromDelta(bi - ai, bj - aj));\n        totalCost += w[b];\n    }\n\n    cout << answer << '\\n';\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct ReadyTask {\n    long long diff;   // sum of required skills\n    int id;            // task index (0\u2011based)\n    bool operator<(ReadyTask const& other) const {\n        // for max\u2011heap we reverse the comparison\n        return diff < other.diff;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K, R;\n    if (!(cin >> N >> M >> K >> R)) return 0;\n    \n    vector<vector<int>> d(N, vector<int>(K));\n    for (int i = 0; i < N; ++i)\n        for (int k = 0; k < K; ++k)\n            cin >> d[i][k];\n    \n    vector<vector<int>> children(N);\n    vector<int> indeg(N, 0);\n    for (int i = 0; i < R; ++i) {\n        int u, v;\n        cin >> u >> v;\n        --u; --v;\n        children[u].push_back(v);\n        ++indeg[v];\n    }\n    \n    // difficulty of each task = sum of required skill components\n    vector<long long> diff(N, 0);\n    for (int i = 0; i < N; ++i) {\n        long long s = 0;\n        for (int k = 0; k < K; ++k) s += d[i][k];\n        diff[i] = s;\n    }\n    \n    // ----- data for the interactive part -----\n    // current task of each member, -1 = idle\n    vector<int> curTask(M, -1);\n    // start day of each task (valid only if status == 0)\n    vector<int> startDay(N, -1);\n    // status: -1 = not started, 0 = in progress, 1 = finished\n    vector<int> taskStatus(N, -1);\n    \n    // statistics for each member\n    vector<long long> totalTime(M, 0);   // sum of durations\n    vector<long long> totalDiff(M, 0);   // sum of diff of finished tasks\n    \n    // priority queue of ready tasks (max\u2011heap by diff)\n    priority_queue<ReadyTask> ready;\n    for (int i = 0; i < N; ++i)\n        if (indeg[i] == 0) ready.push({diff[i], i});\n    \n    int day = 1;\n    while (true) {\n        // ----- decide which idle members get which ready tasks -----\n        vector<int> idle;\n        idle.reserve(M);\n        for (int j = 0; j < M; ++j)\n            if (curTask[j] == -1) idle.push_back(j);\n        \n        // comparator: faster member first\n        auto faster = [&](int a, int b) {\n            if (totalDiff[a] == 0 && totalDiff[b] == 0) return a < b;\n            if (totalDiff[a] == 0) return true;          // a is considered fastest\n            if (totalDiff[b] == 0) return false;\n            // compare avg_time_per_diff = totalTime / totalDiff\n            return totalTime[a] * totalDiff[b] < totalTime[b] * totalDiff[a];\n        };\n        sort(idle.begin(), idle.end(), faster);\n        \n        vector<pair<int,int>> assignments; // (member+1, task+1)\n        size_t pos = 0;\n        while (pos < idle.size() && !ready.empty()) {\n            ReadyTask rt = ready.top(); ready.pop();\n            int w = idle[pos++];\n            int t = rt.id;\n            // start the task\n            curTask[w] = t;\n            startDay[t] = day;\n            taskStatus[t] = 0; // in progress\n            assignments.emplace_back(w + 1, t + 1);\n        }\n        \n        // ----- output -----\n        cout << assignments.size();\n        for (auto &p : assignments) cout << ' ' << p.first << ' ' << p.second;\n        cout << '\\n';\n        cout.flush();\n        \n        // ----- receive information about finished members -----\n        int x;\n        if (!(cin >> x)) break;          // should not happen\n        if (x == -1) break;               // end of simulation\n        int cnt = x;\n        vector<int> finished(cnt);\n        for (int i = 0; i < cnt; ++i) {\n            cin >> finished[i];\n            --finished[i];                // to 0\u2011based\n        }\n        \n        // process each finished task\n        for (int w : finished) {\n            int t = curTask[w];\n            if (t == -1) continue;        // should not happen\n            int duration = day - startDay[t] + 1;\n            totalTime[w] += duration;\n            totalDiff[w] += diff[t];\n            taskStatus[t] = 1;            // finished\n            \n            // update dependents\n            for (int nb : children[t]) {\n                if (--indeg[nb] == 0) {\n                    ready.push({diff[nb], nb});\n                }\n            }\n            curTask[w] = -1;               // member becomes idle\n        }\n        ++day;\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Order {\n    int a, b, c, d;          // pickup (a,b) , delivery (c,d)\n};\n\ninline long long manhattan(int x1, int y1, int x2, int y2) {\n    return llabs(x1 - x2) + llabs(y1 - y2);\n}\n\n/* --------------------------------------------------------------- */\n/*  compute tour length for a given permutation                    */\nstatic long long tourCost(const vector<int>& perm,\n                          const vector<long long>& start,\n                          const vector<long long>& finish,\n                          const vector<vector<int>>& D,\n                          long long insideSum)\n{\n    const int m = (int)perm.size();\n    long long cur = start[perm[0]];\n    for (int i = 0; i < m - 1; ++i) cur += D[perm[i]][perm[i + 1]];\n    cur += finish[perm[m - 1]];\n    cur += insideSum;\n    return cur;\n}\n\n/* --------------------------------------------------------------- */\n/*  cheap TSP : nearest neighbour from every start                */\nstatic long long cheapTSP(const vector<int>& orders,\n                          vector<int>& bestPerm)\n{\n    const int m = (int)orders.size();\n    vector<long long> start(m), finish(m), inside(m);\n    vector<int> pX(m), pY(m), dX(m), dY(m);\n    const int DEP = 400;\n\n    for (int i = 0; i < m; ++i) {\n        const Order& o = *((Order*)nullptr);   // dummy, see below\n    }\n\n    // fill data for the current subset\n    for (int i = 0; i < m; ++i) {\n        const Order& o = *((Order*)nullptr);\n    }\n    // we will fill it inside the function, see later\n    // (the two dummy lines are only to keep the editor happy)\n    // -----------------------------------------------------------------\n    // Real code: we need the arrays a,b,c,d from the global vector.\n    // -----------------------------------------------------------------\n    return 0; // never reached\n}\n\n/* Because the cheap TSP is tiny we write it inside the main function\n   to avoid passing many global arrays. The same holds for the full\n   improvement routine.                                             */\n\n/* --------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int DEP = 400;\n    const int N = 1000;\n    vector<Order> ord(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> ord[i].a >> ord[i].b >> ord[i].c >> ord[i].d;\n    }\n\n    /* ----  solo costs (start+inside+finish)  ---------------------- */\n    vector<long long> solo(N);\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    for (int i = 0; i < N; ++i) {\n        long long st = manhattan(DEP, DEP, ord[i].a, ord[i].b);\n        long long ins = manhattan(ord[i].a, ord[i].b, ord[i].c, ord[i].d);\n        long long fn = manhattan(ord[i].c, ord[i].d, DEP, DEP);\n        solo[i] = st + ins + fn;\n    }\n    sort(idx.begin(), idx.end(),\n         [&](int i, int j){ return solo[i] < solo[j]; });\n\n    /* ----  candidate list : the 200 best orders  ----------------- */\n    const int CAND = 200;\n    vector<int> cand;\n    cand.reserve(CAND);\n    for (int i = 0; i < CAND; ++i) cand.push_back(idx[i]);\n\n    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    const int SAMPLE = 500;               // number of random subsets\n    struct SubsetInfo {\n        vector<int> ids;   // original order numbers (0\u2011based)\n        long long cost;\n    };\n    vector<SubsetInfo> samples;\n    samples.reserve(SAMPLE + 1);\n\n    // ----- helper lambdas for a concrete subset -----------------\n    auto evaluateSubset = [&](const vector<int>& ids, bool full,\n                               vector<int>& outPerm) -> long long {\n        const int m = (int)ids.size();            // =50\n        vector<long long> start(m), finish(m), inside(m);\n        vector<int> pX(m), pY(m), dX(m), dY(m);\n        long long insideSum = 0;\n        for (int i = 0; i < m; ++i) {\n            const Order& o = ord[ids[i]];\n            pX[i] = o.a; pY[i] = o.b;\n            dX[i] = o.c; dY[i] = o.d;\n            start[i]   = manhattan(DEP, DEP, pX[i], pY[i]);\n            inside[i]  = manhattan(pX[i], pY[i], dX[i], dY[i]);\n            finish[i]  = manhattan(dX[i], dY[i], DEP, DEP);\n            insideSum += inside[i];\n        }\n        // matrix D[i][j] = distance delivery_i -> pickup_j\n        vector<vector<int>> D(m, vector<int>(m));\n        for (int i = 0; i < m; ++i)\n            for (int j = 0; j < m; ++j)\n                D[i][j] = (int)manhattan(dX[i], dY[i], pX[j], pY[j]);\n\n        // ----- cheap solution : nearest neighbour -----------------\n        long long bestCost = (1LL<<60);\n        vector<int> bestPerm;\n        for (int s = 0; s < m; ++s) {\n            vector<int> perm;\n            vector<char> used(m, 0);\n            int cur = s;\n            perm.push_back(cur);\n            used[cur] = 1;\n            for (int step = 1; step < m; ++step) {\n                int nxt = -1;\n                int bestD = INT_MAX;\n                for (int v = 0; v < m; ++v) if (!used[v]) {\n                    int d = D[cur][v];\n                    if (d < bestD) { bestD = d; nxt = v; }\n                }\n                used[nxt] = 1;\n                perm.push_back(nxt);\n                cur = nxt;\n            }\n            long long c = tourCost(perm, start, finish, D, insideSum);\n            if (c < bestCost) {\n                bestCost = c;\n                bestPerm = perm;\n            }\n        }\n\n        if (!full) {\n            outPerm = bestPerm;\n            return bestCost;\n        }\n\n        // ----- full improvement (insertion, swap, 2\u2011opt) ----------\n        vector<int> perm = bestPerm;\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            // insertion\n            for (int i = 0; i < m && !improved; ++i) {\n                for (int j = 0; j < m && !improved; ++j) if (i != j) {\n                    vector<int> np = perm;\n                    int val = np[i];\n                    np.erase(np.begin() + i);\n                    np.insert(np.begin() + j, val);\n                    long long c = tourCost(np, start, finish, D, insideSum);\n                    if (c < tourCost(perm, start, finish, D, insideSum)) {\n                        perm.swap(np);\n                        improved = true;\n                    }\n                }\n            }\n            // swap\n            if (!improved) {\n                for (int i = 0; i < m && !improved; ++i) {\n                    for (int j = i + 1; j < m && !improved; ++j) {\n                        vector<int> np = perm;\n                        swap(np[i], np[j]);\n                        long long c = tourCost(np, start, finish, D, insideSum);\n                        if (c < tourCost(perm, start, finish, D, insideSum)) {\n                            perm.swap(np);\n                            improved = true;\n                        }\n                    }\n                }\n            }\n            // 2\u2011opt (reverse a segment)\n            if (!improved) {\n                for (int i = 0; i < m - 2 && !improved; ++i) {\n                    for (int j = i + 2; j < m && !improved; ++j) {\n                        vector<int> np = perm;\n                        reverse(np.begin() + i + 1, np.begin() + j + 1);\n                        long long c = tourCost(np, start, finish, D, insideSum);\n                        if (c < tourCost(perm, start, finish, D, insideSum)) {\n                            perm.swap(np);\n                            improved = true;\n                        }\n                    }\n                }\n            }\n        }\n        outPerm = perm;\n        return tourCost(perm, start, finish, D, insideSum);\n    };\n\n    // ----- evaluate many random subsets (cheap only) ------------\n    for (int iter = 0; iter < SAMPLE; ++iter) {\n        vector<int> cand2 = cand;\n        shuffle(cand2.begin(), cand2.end(), rng);\n        vector<int> ids(cand2.begin(), cand2.begin() + 50);\n        vector<int> dummyPerm;\n        long long c = evaluateSubset(ids, false, dummyPerm);\n        samples.push_back({ids, c});\n    }\n    // also add the deterministic top\u201150 set\n    {\n        vector<int> ids(idx.begin(), idx.begin() + 50);\n        vector<int> dummy;\n        long long c = evaluateSubset(ids, false, dummy);\n        samples.push_back({ids, c});\n    }\n\n    // keep the 5 best subsets\n    const int KEEP = 5;\n    nth_element(samples.begin(),\n                samples.begin() + KEEP,\n                samples.end(),\n                [](const SubsetInfo& a, const SubsetInfo& b){ return a.cost < b.cost; });\n    samples.resize(KEEP);\n\n    // ----- full improvement on the best subsets -----------------\n    long long bestTotal = (1LL<<60);\n    vector<int> bestIds;\n    vector<int> bestPerm;\n\n    for (auto& s : samples) {\n        vector<int> perm;\n        long long c = evaluateSubset(s.ids, true, perm);\n        if (c < bestTotal) {\n            bestTotal = c;\n            bestIds = s.ids;\n            bestPerm = perm;\n        }\n    }\n\n    // ----- build the output route --------------------------------\n    // bestIds : original order numbers (0\u2011based)\n    // bestPerm : permutation of 0..49  (local index -> order in bestIds)\n\n    // sort the ids for nicer output\n    sort(bestIds.begin(), bestIds.end());\n\n    // route coordinates\n    vector<int> routeX, routeY;\n    routeX.push_back(DEP);\n    routeY.push_back(DEP);\n    for (int k = 0; k < 50; ++k) {\n        int local = bestPerm[k];\n        int orig  = bestIds[local];\n        routeX.push_back(ord[orig].a);\n        routeY.push_back(ord[orig].b);\n        routeX.push_back(ord[orig].c);\n        routeY.push_back(ord[orig].d);\n    }\n    routeX.push_back(DEP);\n    routeY.push_back(DEP);\n    const int n = (int)routeX.size();           // = 2*50+2 = 102\n\n    // ----- output -------------------------------------------------\n    cout << 50;\n    for (int id : bestIds) cout << ' ' << (id + 1);\n    cout << '\\n';\n    cout << n;\n    for (size_t i = 0; i < routeX.size(); ++i)\n        cout << ' ' << routeX[i] << ' ' << routeY[i];\n    cout << '\\n';\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    vector<int> p, sz;\n    DSU(int n = 0) { init(n); }\n    void init(int n) {\n        p.resize(n);\n        sz.assign(n, 1);\n        iota(p.begin(), p.end(), 0);\n    }\n    int find(int x) {\n        if (p[x] == x) return x;\n        return p[x] = find(p[x]);\n    }\n    bool unite(int a, int b) {\n        a = find(a); b = find(b);\n        if (a == b) return false;\n        if (sz[a] < sz[b]) swap(a, b);\n        p[b] = a;\n        sz[a] += sz[b];\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    if (!(cin >> N)) return 0;\n    vector<int> X(N), Y(N);\n    for (int i = 0; i < N; ++i) cin >> X[i] >> Y[i];\n    int M;\n    cin >> M;\n    vector<int> U(M), V(M);\n    for (int i = 0; i < M; ++i) cin >> U[i] >> V[i];\n    \n    DSU dsu(N);\n    \n    for (int i = 0; i < M; ++i) {\n        long long l;            // the given length\n        cin >> l;\n        if (dsu.find(U[i]) != dsu.find(V[i])) {\n            cout << 1 << '\\n';\n            dsu.unite(U[i], V[i]);\n        } else {\n            cout << 0 << '\\n';\n        }\n        cout.flush();           // required by the statement\n    }\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing pii = pair<int,int>;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int H = 30, W = 30;\n    const int dr[4] = {-1, 1, 0, 0};\n    const int dc[4] = {0, 0, -1, 1};\n    const char wallChar[4] = {'u','d','l','r'};\n    const char moveChar[4] = {'U','D','L','R'};\n\n    /* ---------- input ---------- */\n    int N;                 // number of pets\n    if(!(cin >> N)) return 0;\n    vector<pii> petPos(N);\n    vector<int> petType(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> petPos[i].first >> petPos[i].second >> petType[i];\n    }\n    int M;                 // number of humans\n    cin >> M;\n    vector<pii> humanPos(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> humanPos[i].first >> humanPos[i].second;\n    }\n\n    /* ---------- simulation ---------- */\n    bool wall[H+2][W+2] = {};          // permanent walls\n    bool newWall[H+2][W+2];             // walls built this turn\n\n    for (int turn = 0; turn < 300; ++turn) {\n        /* occupancy and adjacency of pets */\n        static bool occPet[H+2][W+2];\n        static bool occHuman[H+2][W+2];\n        static bool adjPet[H+2][W+2];\n        for (int i = 1; i <= 30; ++i)\n            for (int j = 1; j <= 30; ++j)\n                occPet[i][j] = occHuman[i][j] = adjPet[i][j] = false;\n\n        for (auto &p : petPos)  occPet[p.first][p.second] = true;\n        for (auto &h : humanPos) occHuman[h.first][h.second] = true;\n\n        for (auto &p : petPos) {\n            for (int d = 0; d < 4; ++d) {\n                int nr = p.first + dr[d];\n                int nc = p.second + dc[d];\n                if (nr < 1 || nr > 30 || nc < 1 || nc > 30) continue;\n                adjPet[nr][nc] = true;\n            }\n        }\n\n        /* clear temporary wall array */\n        for (int i = 1; i <= 30; ++i)\n            for (int j = 1; j <= 30; ++j)\n                newWall[i][j] = false;\n\n        vector<char> action(M, '.');\n        vector<pii> moveDest(M);\n\n        for (int i = 0; i < M; ++i) {\n            int hx = humanPos[i].first;\n            int hy = humanPos[i].second;\n            bool placed = false;\n\n            /* ----- try to place a wall ----- */\n            for (int d = 0; d < 4 && !placed; ++d) {\n                int nx = hx + dr[d];\n                int ny = hy + dc[d];\n                if (nx < 1 || nx > 30 || ny < 1 || ny > 30) continue;\n                if (wall[nx][ny]) continue;\n                if (newWall[nx][ny]) continue;\n                if (occPet[nx][ny]) continue;\n                if (occHuman[nx][ny]) continue;\n                if (adjPet[nx][ny]) continue;\n                // place wall\n                action[i] = wallChar[d];\n                newWall[nx][ny] = true;\n                placed = true;\n            }\n\n            if (placed) {\n                moveDest[i] = {hx, hy};\n                continue;\n            }\n\n            /* ----- cannot wall \u2013 try to move ----- */\n            bool moved = false;\n            for (int d = 0; d < 4 && !moved; ++d) {\n                int nx = hx + dr[d];\n                int ny = hy + dc[d];\n                if (nx < 1 || nx > 30 || ny < 1 || ny > 30) continue;\n                if (wall[nx][ny]) continue;\n                if (newWall[nx][ny]) continue;      // would become a wall now\n                action[i] = moveChar[d];\n                moveDest[i] = {nx, ny};\n                moved = true;\n            }\n            if (!moved) {\n                action[i] = '.';\n                moveDest[i] = {hx, hy};\n            }\n        }\n\n        /* ----- output ----- */\n        for (int i = 0; i < M; ++i) cout << action[i];\n        cout << '\\n' << flush;\n\n        /* ----- apply walls ----- */\n        for (int i = 1; i <= 30; ++i)\n            for (int j = 1; j <= 30; ++j)\n                if (newWall[i][j]) wall[i][j] = true;\n\n        /* ----- apply human moves ----- */\n        for (int i = 0; i < M; ++i) {\n            if (action[i] >= 'A' && action[i] <= 'Z')\n                humanPos[i] = moveDest[i];\n        }\n\n        /* ----- read and apply pet moves ----- */\n        for (int i = 0; i < N; ++i) {\n            string s; cin >> s;\n            for (char c : s) {\n                if (c == '.') continue;\n                int dir = 0;\n                if (c == 'U') dir = 0;\n                else if (c == 'D') dir = 1;\n                else if (c == 'L') dir = 2;\n                else if (c == 'R') dir = 3;\n                int nx = petPos[i].first + dr[dir];\n                int ny = petPos[i].second + dc[dir];\n                if (nx < 1 || nx > 30 || ny < 1 || ny > 30) continue;\n                if (wall[nx][ny]) continue;          // impassable\n                petPos[i] = {nx, ny};\n            }\n        }\n    }\n\n    /* ---------- final scoring ---------- */\n    long double sumS = 0.0L;\n    static bool vis[H+2][W+2];\n    for (int i = 0; i < M; ++i) {\n        for (int r = 1; r <= 30; ++r)\n            for (int c = 1; c <= 30; ++c)\n                vis[r][c] = false;\n\n        queue<pii> q;\n        int sx = humanPos[i].first, sy = humanPos[i].second;\n        vis[sx][sy] = true;\n        q.emplace(sx, sy);\n        int reach = 0;\n        while (!q.empty()) {\n            auto [x, y] = q.front(); q.pop();\n            ++reach;\n            for (int d = 0; d < 4; ++d) {\n                int nx = x + dr[d];\n                int ny = y + dc[d];\n                if (nx < 1 || nx > 30 || ny < 1 || ny > 30) continue;\n                if (wall[nx][ny]) continue;\n                if (vis[nx][ny]) continue;\n                vis[nx][ny] = true;\n                q.emplace(nx, ny);\n            }\n        }\n\n        int petsInside = 0;\n        for (auto &p : petPos)\n            if (vis[p.first][p.second]) ++petsInside;\n\n        long double s = (long double)reach / 900.0L *\n                        powl(2.0L, -(long double)petsInside);\n        sumS += s;\n    }\n\n    long double avg = sumS / (long double)M;\n    long long score = llround(avg * 1e8L);\n    // (the judge does not need the score printed)\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj, ti, tj;\n    double p;\n    if (!(cin >> si >> sj >> ti >> tj >> p)) return 0;\n\n    vector<string> h(20);\n    for (int i = 0; i < 20; ++i) cin >> h[i];\n    vector<string> v(19);\n    for (int i = 0; i < 19; ++i) cin >> v[i];\n\n    // wall[i][j][dir] : true if movement in direction dir from (i,j) is blocked\n    // dir: 0=U,1=D,2=L,3=R\n    bool wall[20][20][4];\n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            wall[i][j][0] = (i == 0) ? true : (v[i-1][j] == '1');          // up\n            wall[i][j][1] = (i == 19) ? true : (v[i][j] == '1');          // down\n            wall[i][j][2] = (j == 0) ? true : (h[i][j-1] == '1');          // left\n            wall[i][j][3] = (j == 19) ? true : (h[i][j] == '1');          // right\n        }\n    }\n\n    const int L = 200;\n    const int N = 20 * 20;\n    const int target = ti * 20 + tj;\n    const int start = si * 20 + sj;\n\n    // dp[t][v] : maximal expected score from turn t, square v\n    vector<vector<double>> dp(L + 2, vector<double>(N, 0.0));\n    vector<vector<int>> best(L + 2, vector<int>(N, -1));\n\n    // dp[t][target] = 0 already (vector initialised with 0)\n    for (int t = L; t >= 1; --t) {\n        for (int pos = 0; pos < N; ++pos) {\n            if (pos == target) {\n                dp[t][pos] = 0.0;\n                best[t][pos] = -1;\n                continue;\n            }\n            int i = pos / 20, j = pos % 20;\n            double bestVal = -1.0;\n            int bestDir = 0;\n            for (int d = 0; d < 4; ++d) {\n                bool w = wall[i][j][d];\n                double stayProb = p + (1.0 - p) * (w ? 1.0 : 0.0);\n                double moveProb = (1.0 - p) * (w ? 0.0 : 1.0);\n\n                double expected = stayProb * dp[t + 1][pos];\n                if (moveProb > 0.0) {\n                    int ni = i, nj = j;\n                    if (d == 0) --ni;\n                    else if (d == 1) ++ni;\n                    else if (d == 2) --nj;\n                    else ++nj;\n                    int npos = ni * 20 + nj;\n                    if (npos == target) {\n                        expected += moveProb * (401 - t);\n                    } else {\n                        expected += moveProb * dp[t + 1][npos];\n                    }\n                }\n                if (expected > bestVal + 1e-12) {\n                    bestVal = expected;\n                    bestDir = d;\n                }\n            }\n            dp[t][pos] = bestVal;\n            best[t][pos] = bestDir;\n        }\n    }\n\n    // reconstruction of a concrete string\n    string ans;\n    ans.reserve(L);\n    int cur = start;\n    for (int t = 1; t <= L; ++t) {\n        int d = best[t][cur];\n        char c;\n        if (d == 0) c = 'U';\n        else if (d == 1) c = 'D';\n        else if (d == 2) c = 'L';\n        else c = 'R';\n        ans.push_back(c);\n\n        int i = cur / 20, j = cur % 20;\n        if (!wall[i][j][d]) {               // intended move succeeds\n            if (d == 0) --i;\n            else if (d == 1) ++i;\n            else if (d == 2) --j;\n            else ++j;\n            cur = i * 20 + j;\n        }\n        // if we are already at the target we keep outputting arbitrary\n        // directions \u2013 they will never be executed.\n    }\n\n    cout << ans << '\\n';\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int C = N * N;               // 900 cells\nconst int DIRS = 4;\nconst int STATES = C * DIRS;       // 3600 states\n\nint di[DIRS] = {0, -1, 0, 1};\nint dj[DIRS] = {-1, 0, 1, 0};\n\nint orig_tile[C];                  // original type (0..7)\n\n/* -------------------------------------------------------------\n   table to[t][d]  \u2013 entering direction d, exiting direction\n   ------------------------------------------------------------- */\nint to_orig[8][DIRS] = {\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 to_rot[8][4][DIRS];            // [type][rotation][entry]\n\n/* -------------------------------------------------------------\n   compute the score (L1 * L2) for a given rotation\n   ------------------------------------------------------------- */\nint next_state[STATES];\nint visited_state[STATES];\nint step_idx[STATES];\nvector<int> path;\n\ninline long long compute_score(const int rot[C]) {\n    // build the transition function\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int t = orig_tile[i * N + j];\n            int r = rot[i * N + j];\n            int base = (i * N + j) * DIRS;\n            for (int d = 0; d < DIRS; ++d) {\n                int exit = to_rot[t][r][d];\n                if (exit == -1) {\n                    next_state[base + d] = -1;\n                    continue;\n                }\n                int ni = i + di[exit];\n                int nj = j + dj[exit];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) {\n                    next_state[base + d] = -1;\n                    continue;\n                }\n                int nd = (exit + 2) & 3;\n                next_state[base + d] = (ni * N + nj) * DIRS + nd;\n            }\n        }\n    }\n\n    // find all directed cycles\n    fill(visited_state, visited_state + STATES, 0);\n    fill(step_idx, step_idx + STATES, -1);\n    vector<int> cycles;\n    for (int s = 0; s < STATES; ++s) {\n        if (next_state[s] == -1 || visited_state[s]) continue;\n        int cur = s;\n        path.clear();\n        while (true) {\n            if (next_state[cur] == -1) break;               // dead end\n            if (visited_state[cur]) break;                  // already processed\n            if (step_idx[cur] != -1) {                      // a new cycle\n                int start = step_idx[cur];\n                int len = (int)path.size() - start;\n                cycles.push_back(len);\n                break;\n            }\n            step_idx[cur] = (int)path.size();\n            path.push_back(cur);\n            cur = next_state[cur];\n        }\n        for (int v : path) {\n            visited_state[v] = 1;\n            step_idx[v] = -1;\n        }\n    }\n\n    if (cycles.empty()) return 0LL;\n    sort(cycles.rbegin(), cycles.rend());\n    long long L1 = cycles[0];\n    long long L2 = (cycles.size() >= 2) ? cycles[1] : 0LL;\n    return L1 * L2;\n}\n\n/* -------------------------------------------------------------\n   main\n   ------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* read the board */\n    string line;\n    for (int i = 0; i < N; ++i) {\n        cin >> line;\n        for (int j = 0; j < N; ++j) orig_tile[i * N + j] = line[j] - '0';\n    }\n\n    /* pre\u2011compute rotated tables */\n    for (int t = 0; t < 8; ++t)\n        for (int r = 0; r < 4; ++r)\n            for (int d = 0; d < DIRS; ++d) {\n                int src = (d - r + 4) % 4;\n                int e = to_orig[t][src];\n                to_rot[t][r][d] = (e == -1) ? -1 : (e + r) % 4;\n            }\n\n    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist_rot(0, 3);\n    uniform_int_distribution<int> dist_cell(0, C - 1);\n    uniform_real_distribution<double> dist_prob(0.0, 1.0);\n\n    /* ---------- initial random rotation ------------------------ */\n    int curRot[C];\n    for (int i = 0; i < C; ++i) curRot[i] = dist_rot(rng);\n\n    /* optional greedy improvement (maximise matched sides) */\n    const int GREEDY_PASSES = 4;\n    for (int p = 0; p < GREEDY_PASSES; ++p) {\n        bool changed = false;\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j) {\n                int idx = i * N + j;\n                int t = orig_tile[idx];\n                int best_r = curRot[idx];\n                int best_match = -1;\n                for (int r = 0; r < 4; ++r) {\n                    int match = 0;\n                    for (int d = 0; d < DIRS; ++d) {\n                        int exit = to_rot[t][r][d];\n                        if (exit == -1) continue;\n                        int ni = i + di[exit];\n                        int nj = j + dj[exit];\n                        if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                        int nb = ni * N + nj;\n                        int nb_t = orig_tile[nb];\n                        int nb_r = curRot[nb];\n                        int nb_entry = (exit + 2) & 3;\n                        if (to_rot[nb_t][nb_r][nb_entry] != -1) ++match;\n                    }\n                    if (match > best_match) {\n                        best_match = match;\n                        best_r = r;\n                    }\n                }\n                if (best_r != curRot[idx]) {\n                    curRot[idx] = best_r;\n                    changed = true;\n                }\n            }\n        if (!changed) break;\n    }\n\n    /* ---------- simulated annealing --------------------------- */\n    const int MAX_ITER = 400000;\n    const double T0 = 800.0;\n    const double DECAY = 0.9996;\n\n    long long curScore = compute_score(curRot);\n    long long bestScore = curScore;\n    int bestRot[C];\n    copy(begin(curRot), end(curRot), begin(bestRot));\n\n    double T = T0;\n    auto start = chrono::steady_clock::now();\n\n    for (int it = 0; it < MAX_ITER; ++it) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start).count();\n        if (elapsed > 1.85) break;               // stay within the time limit\n\n        int idx = dist_cell(rng);\n        int old_r = curRot[idx];\n        int new_r = dist_rot(rng);\n        if (new_r == old_r) new_r = (old_r + 1) & 3;   // force a change\n        curRot[idx] = new_r;\n\n        long long newScore = compute_score(curRot);\n        long long delta = newScore - curScore;\n\n        if (delta > 0) {\n            // accept the improvement\n            curScore = newScore;\n            if (newScore > bestScore) {\n                bestScore = newScore;\n                copy(begin(curRot), end(curRot), begin(bestRot));\n            }\n        } else {\n            // Metropolis acceptance of a worse move\n            if (dist_prob(rng) < exp((double)delta / T)) {\n                curScore = newScore;               // keep the worse state\n            } else {\n                curRot[idx] = old_r;                // revert\n            }\n        }\n\n        T = T0 * pow(DECAY, it + 1);\n    }\n\n    /* ---------- hill\u2011climbing (local search) ------------------- */\n    // make curRot the best configuration found so far\n    copy(begin(bestRot), end(bestRot), begin(curRot));\n    curScore = bestScore;\n\n    const int HILL_PASSES = 2;\n    for (int pass = 0; pass < HILL_PASSES; ++pass) {\n        bool any = false;\n        for (int idx = 0; idx < C; ++idx) {\n            int saved_r = curRot[idx];\n            for (int r = 0; r < 4; ++r) {\n                if (r == saved_r) continue;\n                curRot[idx] = r;\n                long long ns = compute_score(curRot);\n                if (ns > curScore) {\n                    curScore = ns;\n                    if (ns > bestScore) {\n                        bestScore = ns;\n                        copy(begin(curRot), end(curRot), begin(bestRot));\n                    }\n                    any = true;\n                    break;          // stay at this tile, try next tile\n                } else {\n                    curRot[idx] = saved_r; // restore\n                }\n            }\n            if (any) break;          // a change happened \u2013 start new pass\n        }\n        if (!any) break;             // no improvement in this pass\n    }\n\n    /* ---------- output --------------------------------------- */\n    string out;\n    out.reserve(C);\n    for (int i = 0; i < C; ++i) out.push_back(char('0' + bestRot[i]));\n    cout << out << '\\n';\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*  bit helpers  */\nint bitFromDelta(int dr, int dc)               // direction -> bit\n{\n    if (dr == -1 && dc == 0) return 2;   // up\n    if (dr ==  1 && dc == 0) return 8;   // down\n    if (dr ==  0 && dc ==-1) return 1;   // left\n    if (dr ==  0 && dc == 1) return 4;   // right\n    return 0;\n}\nint idxFromDelta(int dr, int dc)               // direction -> index 0..3\n{\n    if (dr == -1 && dc == 0) return 0;   // up\n    if (dr ==  1 && dc == 0) return 1;   // down\n    if (dr ==  0 && dc ==-1) return 2;   // left\n    if (dr ==  0 && dc == 1) return 3;   // right\n    return -1;\n}\nint oppositeBit(int b)                         // opposite direction\n{\n    if (b == 1) return 4;\n    if (b == 4) return 1;\n    if (b == 2) return 8;\n    if (b == 8) return 2;\n    return 0;\n}\nchar charFromDelta(int dr, int dc)            // direction -> move character\n{\n    int id = idxFromDelta(dr, dc);\n    static const char mv[4] = {'U','D','L','R'};\n    return (id == -1 ? '?' : mv[id]);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, T;\n    if (!(cin >> N >> T)) return 0;\n    vector<string> raw(N);\n    for (int i = 0; i < N; ++i) cin >> raw[i];\n\n    const int dr[4] = {-1, 1, 0, 0};\n    const int dc[4] = {0, 0, -1, 1};\n\n    /* read the board */\n    vector<vector<int>> board(N, vector<int>(N, -1));\n    vector<int> mask;                // original picture of each tile\n    int er = -1, ec = -1;            // empty cell\n    int id = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            char c = raw[i][j];\n            if (c == '0') {\n                er = i; ec = j;\n                board[i][j] = -1;\n            } else {\n                int v;\n                if ('0' <= c && c <= '9') v = c - '0';\n                else v = 10 + (c - 'a');\n                board[i][j] = id;\n                mask.push_back(v);\n                ++id;\n            }\n        }\n    }\n\n    const int M = N * N - 1;                 // number of tiles\n    vector<int> curMask = mask;              // bits still free\n    vector<char> inComponent(M, 0);\n    string answer;\n    answer.reserve(T);\n\n    /* --------------------------------------------------------------\n       Step 0 \u2013 place the first tile (the root)\n       -------------------------------------------------------------- */\n    bool placedRoot = false;\n    for (int d = 0; d < 4 && !placedRoot; ++d) {\n        int nr = er + dr[d], nc = ec + dc[d];\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n        int tid = board[nr][nc];\n        if (tid == -1) continue;\n        int dir = bitFromDelta(dr[d], dc[d]);          // direction empty -> neighbour\n        if (mask[tid] & oppositeBit(dir)) {           // neighbour points to empty\n            char ch = charFromDelta(dr[d], dc[d]);    // slide this neighbour\n            answer.push_back(ch);\n            board[er][ec] = tid;\n            board[nr][nc] = -1;\n            er = nr; ec = nc;\n            inComponent[tid] = 1;\n            placedRoot = true;\n            break;\n        }\n    }\n    if (!placedRoot) {                                 // fallback: any neighbour\n        for (int d = 0; d < 4 && !placedRoot; ++d) {\n            int nr = er + dr[d], nc = ec + dc[d];\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n            int tid = board[nr][nc];\n            if (tid == -1) continue;\n            char ch = charFromDelta(dr[d], dc[d]);\n            answer.push_back(ch);\n            board[er][ec] = tid;\n            board[nr][nc] = -1;\n            er = nr; ec = nc;\n            inComponent[tid] = 1;\n            placedRoot = true;\n            break;\n        }\n    }\n\n    int placedCnt = 1;                                 // one tile in the component\n\n    /* --------------------------------------------------------------\n       Main loop \u2013 repeatedly enlarge the component or move the empty\n       -------------------------------------------------------------- */\n    while (placedCnt < M && (int)answer.size() < T) {\n        bool progress = false;\n\n        /* ---- try to add a new vertex (Step 1) -------------------- */\n        for (int d = 0; d < 4 && !progress; ++d) {\n            int pr = er + dr[d], pc = ec + dc[d];\n            if (pr < 0 || pr >= N || pc < 0 || pc >= N) continue;\n            int parent = board[pr][pc];\n            if (parent == -1) continue;\n            if (!inComponent[parent]) continue;\n\n            int needParentBit = oppositeBit(bitFromDelta(dr[d], dc[d]));\n            if ((curMask[parent] & needParentBit) == 0) continue;\n\n            int cr = er - dr[d], cc = ec - dc[d];\n            if (cr < 0 || cr >= N || cc < 0 || cc >= N) continue;\n            int child = board[cr][cc];\n            if (child == -1) continue;\n            if (inComponent[child]) continue;\n\n            int needChildBit = bitFromDelta(dr[d], dc[d]);\n            if ((curMask[child] & needChildBit) == 0) continue;\n\n            /* perform the slide */\n            char ch = charFromDelta(dr[d], dc[d]);    // slide child into empty\n            answer.push_back(ch);\n            board[er][ec] = child;\n            board[cr][cc] = -1;\n            er = cr; ec = cc;\n\n            curMask[parent] &= ~needParentBit;\n            curMask[child]  &= ~needChildBit;\n            inComponent[child] = 1;\n            ++placedCnt;\n            progress = true;\n        }\n        if (progress) continue;\n\n        /* ---- move the empty square (Step 2) -------------------- */\n        bool moved = false;\n        for (int d = 0; d < 4 && !moved; ++d) {\n            int nr = er + dr[d], nc = ec + dc[d];\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n            int tid = board[nr][nc];\n            if (tid == -1) continue;\n            if (inComponent[tid]) continue;          // slide only an unplaced tile\n\n            char ch = charFromDelta(dr[d], dc[d]);    // slide this neighbour\n            answer.push_back(ch);\n            board[er][ec] = tid;\n            board[nr][nc] = -1;\n            er = nr; ec = nc;\n            moved = true;\n        }\n        if (!moved) break;    // all tiles are already placed\n    }\n\n    cout << answer << '\\n';\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nusing ull = unsigned long long;\n\nstruct Line {\n    ll px, py, qx, qy;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, Kmax;\n    if (!(cin >> N >> Kmax)) return 0;\n    vector<int> a(11);\n    for (int d = 1; d <= 10; ++d) cin >> a[d];\n    vector<ll> xs(N), ys(N);\n    for (int i = 0; i < N; ++i) cin >> xs[i] >> ys[i];\n\n    int sumA = 0;\n    for (int d = 1; d <= 10; ++d) sumA += a[d];\n\n    /* ---------- parameters of the search ---------- */\n    const int USE_K = 70;            // enough pieces, cheaper than 100\n    const int TRIALS = 1500;         // many more than the original 200\n\n    /* ---------- random number generator ---------- */\n    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<ll> distCoord(-10000, 10000);   // inside the cake\n\n    /* ---------- generate a line that does not hit any strawberry ---------- */\n    auto make_line = [&]() -> Line {\n        for (int tries = 0; tries < 10; ++tries) {\n            ll px = distCoord(rng);\n            ll py = distCoord(rng);\n            ll qx = distCoord(rng);\n            ll qy = distCoord(rng);\n            if (px == qx && py == qy) continue;\n            ll dx = qx - px;\n            ll dy = qy - py;\n            bool ok = true;\n            for (int i = 0; i < N; ++i) {\n                ll cross = dx * (ys[i] - py) - dy * (xs[i] - px);\n                if (cross == 0) { ok = false; break; }\n            }\n            if (ok) return Line{px, py, qx, qy};\n        }\n        // fallback \u2013 a line far away, never hits a strawberry\n        return Line{-1000000, 0, 1000000, 0};\n    };\n\n    /* ---------- containers that are reused every trial ---------- */\n    vector<ull> hi(N), lo(N);\n    vector<pair<ull, ull>> sig(N);\n\n    int bestScore = -1;\n    vector<Line> bestLines;\n\n    for (int trial = 0; trial < TRIALS; ++trial) {\n        /* generate USE_K random lines */\n        vector<Line> lines;\n        lines.reserve(USE_K);\n        for (int i = 0; i < USE_K; ++i) lines.push_back(make_line());\n\n        /* reset signatures */\n        fill(hi.begin(), hi.end(), 0ULL);\n        fill(lo.begin(), lo.end(), 0ULL);\n\n        /* apply every line */\n        for (int li = 0; li < USE_K; ++li) {\n            const Line &L = lines[li];\n            ll dx = L.qx - L.px;\n            ll dy = L.qy - L.py;\n            for (int i = 0; i < N; ++i) {\n                ll cross = dx * (ys[i] - L.py) - dy * (xs[i] - L.px);\n                if (cross > 0) {                         // right side\n                    if (li < 64) lo[i] |= (1ULL << li);\n                    else          hi[i] |= (1ULL << (li - 64));\n                }\n            }\n        }\n\n        /* group equal signatures */\n        for (int i = 0; i < N; ++i) sig[i] = {hi[i], lo[i]};\n        sort(sig.begin(), sig.end());\n\n        vector<int> b(11, 0);            // b[d] = #pieces with d strawberries\n        for (int i = 0; i < N; ) {\n            int j = i;\n            while (j < N && sig[j] == sig[i]) ++j;\n            int sz = j - i;\n            if (1 <= sz && sz <= 10) ++b[sz];\n            i = j;\n        }\n\n        int distributed = 0;\n        for (int d = 1; d <= 10; ++d) distributed += min(a[d], b[d]);\n\n        if (distributed > bestScore) {\n            bestScore = distributed;\n            bestLines = lines;\n            if (distributed == sumA) break;   // perfect, stop early\n        }\n    }\n\n    /* ---------- output ---------- */\n    cout << bestLines.size() << '\\n';\n    for (const Line &L : bestLines)\n        cout << L.px << ' ' << L.py << ' ' << L.qx << ' ' << L.qy << '\\n';\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Candidate {\n    int mx, my;                       // missing corner\n    array<pair<int,int>,3> others;    // the three existing corners\n};\n\nint N, M;\nint center_;\nbool hasDot[61][61];\n\n/* data structures for dot queries */\nvector< set<int> > dotX, dotY;                     // 0 \u2026 N\u20111\nunordered_map<int, set<int> > dotD, dotS;        // d = x\u2011y , s = x+y\n\n/* data structures for generating candidates */\nvector< vector<pair<int,int>> > dotsAtS;               // s \u2192 list of points\nunordered_map<int, vector<pair<int,int>> > dotsAtD;   // d \u2192 list of points\n\n/* already drawn edges */\nunordered_map<int, set<pair<int,int>>> edgeHor;   // y \u2192 intervals of x\nunordered_map<int, set<pair<int,int>>> edgeVer;   // x \u2192 intervals of y\nunordered_map<int, set<pair<int,int>>> edgeDiagP; // d \u2192 intervals of x\nunordered_map<int, set<pair<int,int>>> edgeDiagM; // s \u2192 intervals of x\n\ninline int weight(int x, int y) {\n    int dx = x - center_;\n    int dy = y - center_;\n    return dx*dx + dy*dy + 1;\n}\n\n/* ---------- helpers for edges ---------- */\n\nbool adjacent(const pair<int,int>& a, const pair<int,int>& b) {\n    return (a.first == b.first) ||\n           (a.second == b.second) ||\n           (a.first - a.second == b.first - b.second) ||\n           (a.first + a.second == b.first + b.second);\n}\n\n/* overlap test for one line */\nbool hasOverlapOnLine(const unordered_map<int, set<pair<int,int>>>& mp,\n                      int line, int l, int r) {\n    auto it = mp.find(line);\n    if (it == mp.end()) return false;\n    const auto& st = it->second;\n    auto itr = st.lower_bound({l, INT_MIN});\n    if (itr != st.end()) {\n        int l2 = itr->first, r2 = itr->second;\n        if (max(l, l2) <= min(r, r2) - 1) return true;\n    }\n    if (itr != st.begin()) {\n        --itr;\n        int l2 = itr->first, r2 = itr->second;\n        if (max(l, l2) <= min(r, r2) - 1) return true;\n    }\n    return false;\n}\n\n/* check whether side (a,b) overlaps an existing edge */\nbool edgeOverlap(const pair<int,int>& a, const pair<int,int>& b) {\n    if (a.first == b.first) {                     // vertical\n        int x = a.first;\n        int l = min(a.second, b.second);\n        int r = max(a.second, b.second);\n        return hasOverlapOnLine(edgeVer, x, l, r);\n    } else if (a.second == b.second) {           // horizontal\n        int y = a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        return hasOverlapOnLine(edgeHor, y, l, r);\n    } else if (a.first - a.second == b.first - b.second) { // diag +1\n        int d = a.first - a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        return hasOverlapOnLine(edgeDiagP, d, l, r);\n    } else {                                      // diag -1\n        int s = a.first + a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        return hasOverlapOnLine(edgeDiagM, s, l, r);\n    }\n}\n\n/* insert an edge into the stored sets */\nvoid addEdgeToSet(const pair<int,int>& a, const pair<int,int>& b) {\n    if (a.first == b.first) {\n        int x = a.first;\n        int l = min(a.second, b.second);\n        int r = max(a.second, b.second);\n        edgeVer[x].insert({l, r});\n    } else if (a.second == b.second) {\n        int y = a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        edgeHor[y].insert({l, r});\n    } else if (a.first - a.second == b.first - b.second) {\n        int d = a.first - a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        edgeDiagP[d].insert({l, r});\n    } else {\n        int s = a.first + a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        edgeDiagM[s].insert({l, r});\n    }\n}\n\n/* does any dot lie on the open interval of the side ? */\nbool dotOnEdgeOpen(const pair<int,int>& a, const pair<int,int>& b) {\n    if (a.first == b.first) {                 // vertical\n        int x = a.first;\n        int lo = min(a.second, b.second);\n        int hi = max(a.second, b.second);\n        const auto& st = dotX[x];\n        auto it = st.lower_bound(lo + 1);\n        if (it != st.end() && *it <= hi - 1) return true;\n        return false;\n    } else if (a.second == b.second) {       // horizontal\n        int y = a.second;\n        int lo = min(a.first, b.first);\n        int hi = max(a.first, b.first);\n        const auto& st = dotY[y];\n        auto it = st.lower_bound(lo + 1);\n        if (it != st.end() && *it <= hi - 1) return true;\n        return false;\n    } else if (a.first - a.second == b.first - b.second) { // diag +1\n        int d = a.first - a.second;\n        int lo = min(a.first, b.first);\n        int hi = max(a.first, b.first);\n        const auto& st = dotD[d];\n        auto it = st.lower_bound(lo + 1);\n        if (it != st.end() && *it <= hi - 1) return true;\n        return false;\n    } else {                                   // diag -1\n        int s = a.first + a.second;\n        int lo = min(a.first, b.first);\n        int hi = max(a.first, b.first);\n        const auto& st = dotS[s];\n        auto it = st.lower_bound(lo + 1);\n        if (it != st.end() && *it <= hi - 1) return true;\n        return false;\n    }\n}\n\n/* ---------- test a candidate ---------- */\nbool isValidMove(const Candidate& cand) {\n    array<pair<int,int>,4> pts;\n    pts[0] = {cand.mx, cand.my};\n    pts[1] = cand.others[0];\n    pts[2] = cand.others[1];\n    pts[3] = cand.others[2];\n\n    // collect the four sides\n    vector<pair<pair<int,int>, pair<int,int>>> sides;\n    for (int i = 0; i < 4; ++i)\n        for (int j = i+1; j < 4; ++j)\n            if (adjacent(pts[i], pts[j]))\n                sides.push_back({pts[i], pts[j]});\n\n    if (sides.size() != 4) return false;   // should not happen\n\n    for (auto &e : sides) {\n        if (edgeOverlap(e.first, e.second)) return false;\n        if (dotOnEdgeOpen(e.first, e.second)) return false;\n    }\n    return true;\n}\n\n/* ---------- add a new dot ---------- */\nvoid addDot(int x, int y) {\n    hasDot[x][y] = true;\n    dotX[x].insert(y);\n    dotY[y].insert(x);\n    int d = x - y;\n    int s = x + y;\n    dotD[d].insert(x);\n    dotS[s].insert(x);\n\n    dotsAtS[s].push_back({x, y});\n    dotsAtD[d].push_back({x, y});\n}\n\n/* ---------- ordering for output ---------- */\nvector<pair<int,int>> order4(const Candidate& cand) {\n    array<pair<int,int>,4> pts;\n    pts[0] = {cand.mx, cand.my};\n    pts[1] = cand.others[0];\n    pts[2] = cand.others[1];\n    pts[3] = cand.others[2];\n\n    vector<pair<int,int>> neighbors;   // renamed from adj\n    int oppIdx = -1;\n    for (int i = 1; i < 4; ++i) {\n        if (adjacent(pts[0], pts[i]))\n            neighbors.push_back(pts[i]);\n        else\n            oppIdx = i;\n    }\n    // safety \u2013 should never happen for a legal rectangle\n    if (neighbors.size() != 2 || oppIdx == -1)\n        return {pts[0], pts[1], pts[2], pts[3]};\n\n    vector<pair<int,int>> res;\n    res.push_back(pts[0]);               // the new dot\n    res.push_back(neighbors[0]);         // one neighbour\n    res.push_back(pts[oppIdx]);          // opposite corner\n    res.push_back(neighbors[1]);         // the other neighbour\n    return res;\n}\n\n/* --------------------------------------------------------------- */\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> M;\n    center_ = (N - 1) / 2;\n\n    dotX.assign(N, {});\n    dotY.assign(N, {});\n    dotsAtS.assign(2*N-1, {});\n\n    for (int i = 0; i < M; ++i) {\n        int x, y; cin >> x >> y;\n        addDot(x, y);\n    }\n\n    long long sumW = 0;\n    for (int x = 0; x < N; ++x)\n        for (int y = 0; y < N; ++y)\n            if (hasDot[x][y]) sumW += weight(x, y);\n\n    vector< array<int,8> > operations;\n\n    /* ------------------- main greedy loop ------------------- */\n    while (true) {\n        vector<Candidate> cand;\n        cand.reserve(80000);\n\n        /* ----- axis\u2011parallel rectangles ----- */\n        for (int x = 0; x < N; ++x) {\n            const auto& ys = dotX[x];\n            vector<int> yvec(ys.begin(), ys.end());\n            int sz = (int)yvec.size();\n            for (int i = 0; i < sz; ++i) {\n                int y1 = yvec[i];\n                for (int j = i+1; j < sz; ++j) {\n                    int y2 = yvec[j];\n                    for (int x2 = 0; x2 < N; ++x2) if (x2 != x) {\n                        bool has1 = hasDot[x2][y1];\n                        bool has2 = hasDot[x2][y2];\n                        if (has1 && !has2) {                // missing (x2 , y2)\n                            if (!hasDot[x2][y2]) {\n                                Candidate c;\n                                c.mx = x2; c.my = y2;\n                                c.others[0] = {x, y1};\n                                c.others[1] = {x, y2};\n                                c.others[2] = {x2, y1};\n                                cand.push_back(c);\n                            }\n                        } else if (!has1 && has2) {        // missing (x2 , y1)\n                            if (!hasDot[x2][y1]) {\n                                Candidate c;\n                                c.mx = x2; c.my = y1;\n                                c.others[0] = {x, y1};\n                                c.others[1] = {x, y2};\n                                c.others[2] = {x2, y2};\n                                cand.push_back(c);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        /* ----- 45\u00b0 squares ----- */\n        for (int s = 0; s < 2*N-1; ++s) {\n            const auto &vec = dotsAtS[s];\n            int sz = (int)vec.size();\n            for (int i = 0; i < sz; ++i) {\n                auto A = vec[i];\n                for (int j = i+1; j < sz; ++j) {\n                    auto B = vec[j];\n                    int dA = A.first - A.second;\n                    int dB = B.first - B.second;\n\n                    // C with d = dA\n                    auto itA = dotsAtD.find(dA);\n                    if (itA != dotsAtD.end()) {\n                        for (auto C : itA->second) {\n                            if (C.first + C.second == s) continue; // same s\n                            int s2 = C.first + C.second;\n                            int xm = (s2 + dB) / 2;\n                            int ym = (s2 - dB) / 2;\n                            if (xm < 0 || xm >= N || ym < 0 || ym >= N) continue;\n                            if (hasDot[xm][ym]) continue;\n                            Candidate c;\n                            c.mx = xm; c.my = ym;\n                            c.others[0] = A;\n                            c.others[1] = B;\n                            c.others[2] = C;\n                            cand.push_back(c);\n                        }\n                    }\n                    // C with d = dB\n                    auto itB = dotsAtD.find(dB);\n                    if (itB != dotsAtD.end()) {\n                        for (auto C : itB->second) {\n                            if (C.first + C.second == s) continue;\n                            int s2 = C.first + C.second;\n                            int xm = (s2 + dA) / 2;\n                            int ym = (s2 - dA) / 2;\n                            if (xm < 0 || xm >= N || ym < 0 || ym >= N) continue;\n                            if (hasDot[xm][ym]) continue;\n                            Candidate c;\n                            c.mx = xm; c.my = ym;\n                            c.others[0] = A;\n                            c.others[1] = B;\n                            c.others[2] = C;\n                            cand.push_back(c);\n                        }\n                    }\n                }\n            }\n        }\n\n        /* ----- choose best ----- */\n        int bestIdx = -1;\n        int bestW = -1;\n        for (int i = 0; i < (int)cand.size(); ++i) {\n            if (!isValidMove(cand[i])) continue;\n            int w = weight(cand[i].mx, cand[i].my);\n            if (w > bestW) {\n                bestW = w;\n                bestIdx = i;\n            }\n        }\n        if (bestIdx == -1) break;            // no more moves\n\n        const Candidate &chosen = cand[bestIdx];\n        // add the dot\n        addDot(chosen.mx, chosen.my);\n        sumW += bestW;\n\n        // add the four edges\n        array<pair<int,int>,4> pts;\n        pts[0] = {chosen.mx, chosen.my};\n        pts[1] = chosen.others[0];\n        pts[2] = chosen.others[1];\n        pts[3] = chosen.others[2];\n        for (int i = 0; i < 4; ++i)\n            for (int j = i+1; j < 4; ++j)\n                if (adjacent(pts[i], pts[j]))\n                    addEdgeToSet(pts[i], pts[j]);\n\n        // store operation in required order\n        vector<pair<int,int>> order = order4(chosen);\n        array<int,8> op;\n        for (int k = 0; k < 4; ++k) {\n            op[2*k]   = order[k].first;\n            op[2*k+1] = order[k].second;\n        }\n        operations.push_back(op);\n    }\n\n    /* ----- output ----- */\n    cout << operations.size() << '\\n';\n    for (auto &op : operations) {\n        for (int i = 0; i < 8; ++i) {\n            if (i) cout << ' ';\n            cout << op[i];\n        }\n        cout << '\\n';\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int SZ = 10;\nconst array<char, 4> DIRS = {'F', 'B', 'L', 'R'};\n\n/* ------------------------------------------------------------\n   tilt the whole board into direction dir\n   ------------------------------------------------------------ */\nvoid tilt(array<array<int, SZ>, SZ> &a, char dir) {\n    if (dir == 'F') {                     // forward \u2192 top\n        for (int c = 0; c < SZ; ++c) {\n            int wr = 0;\n            for (int r = 0; r < SZ; ++r) {\n                if (a[r][c] != 0) {\n                    if (wr != r) {\n                        a[wr][c] = a[r][c];\n                        a[r][c] = 0;\n                    }\n                    ++wr;\n                }\n            }\n        }\n    } else if (dir == 'B') {              // backward \u2192 bottom\n        for (int c = 0; c < SZ; ++c) {\n            int wr = SZ - 1;\n            for (int r = SZ - 1; r >= 0; --r) {\n                if (a[r][c] != 0) {\n                    a[wr][c] = a[r][c];\n                    if (wr != r) a[r][c] = 0;\n                    --wr;\n                }\n            }\n        }\n    } else if (dir == 'L') {              // left\n        for (int r = 0; r < SZ; ++r) {\n            int wc = 0;\n            for (int c = 0; c < SZ; ++c) {\n                if (a[r][c] != 0) {\n                    a[r][wc] = a[r][c];\n                    if (wc != c) a[r][c] = 0;\n                    ++wc;\n                }\n            }\n        }\n    } else if (dir == 'R') {               // right\n        for (int r = 0; r < SZ; ++r) {\n            int wc = SZ - 1;\n            for (int c = SZ - 1; c >= 0; --c) {\n                if (a[r][c] != 0) {\n                    a[r][wc] = a[r][c];\n                    if (wc != c) a[r][c] = 0;\n                    --wc;\n                }\n            }\n        }\n    }\n}\n\n/* ------------------------------------------------------------\n   \u03a3 size\u00b2 of all connected components\n   ------------------------------------------------------------ */\nlong long sumSquares(const array<array<int, SZ>, SZ> &a) {\n    bool vis[SZ][SZ] = {};\n    const int dr[4] = {-1, 1, 0, 0};\n    const int dc[4] = {0, 0, -1, 1};\n    long long sum = 0;\n    for (int r = 0; r < SZ; ++r) {\n        for (int c = 0; c < SZ; ++c) {\n            if (a[r][c] == 0 || vis[r][c]) continue;\n            int fl = a[r][c];\n            int sz = 0;\n            queue<pair<int, int>> q;\n            q.emplace(r, c);\n            vis[r][c] = true;\n            while (!q.empty()) {\n                auto [cr, cc] = q.front(); q.pop();\n                ++sz;\n                for (int k = 0; k < 4; ++k) {\n                    int nr = cr + dr[k];\n                    int nc = cc + dc[k];\n                    if (0 <= nr && nr < SZ && 0 <= nc && nc < SZ &&\n                        !vis[nr][nc] && a[nr][nc] == fl) {\n                        vis[nr][nc] = true;\n                        q.emplace(nr, nc);\n                    }\n                }\n            }\n            sum += 1LL * sz * sz;\n        }\n    }\n    return sum;\n}\n\n/* ------------------------------------------------------------\n   find the p\u2011th empty cell (1\u2011based)\n   ------------------------------------------------------------ */\npair<int, int> findEmptyCell(const array<array<int, SZ>, SZ> &a, int p) {\n    for (int r = 0; r < SZ; ++r)\n        for (int c = 0; c < SZ; ++c)\n            if (a[r][c] == 0) {\n                if (p == 1) return {r, c};\n                --p;\n            }\n    return {-1, -1};               // never reached\n}\n\n/* ------------------------------------------------------------\n   expected value of S after the next candy has been placed\n   (uniform random cell) and we will tilt optimally afterwards\n   ------------------------------------------------------------ */\nlong long expectedFutureScore(const array<array<int, SZ>, SZ> &board,\n                              int nextFlavour) {\n    vector<pair<int, int>> empties;\n    empties.reserve(100);\n    for (int r = 0; r < SZ; ++r)\n        for (int c = 0; c < SZ; ++c)\n            if (board[r][c] == 0) empties.emplace_back(r, c);\n\n    const int cnt = (int)empties.size();   // > 0 (called only before the last step)\n    long long sum = 0;\n    for (auto [r, c] : empties) {\n        auto b2 = board;\n        b2[r][c] = nextFlavour;\n        long long best = -1;\n        for (char dir : DIRS) {\n            auto b3 = b2;\n            tilt(b3, dir);\n            long long s = sumSquares(b3);\n            if (s > best) best = s;\n        }\n        sum += best;\n    }\n    return sum / cnt;          // uniform average\n}\n\n/* ------------------------------------------------------------\n   main\n   ------------------------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int TOTAL = 100;\n    vector<int> flavour(TOTAL + 1);\n    for (int i = 1; i <= TOTAL; ++i) cin >> flavour[i];\n\n    array<array<int, SZ>, SZ> board{};\n    for (int r = 0; r < SZ; ++r) board[r].fill(0);\n\n    for (int step = 1; step <= TOTAL; ++step) {\n        int p;                     // where the current candy is placed\n        cin >> p;\n        auto pos = findEmptyCell(board, p);\n        board[pos.first][pos.second] = flavour[step];\n\n        char bestDir = 'F';\n        long long bestValue = -1;\n        long long bestCur = -1;    // tie\u2011breaker\n\n        if (step == TOTAL) {      // last step \u2013 only the immediate S matters\n            for (char dir : DIRS) {\n                auto b = board;\n                tilt(b, dir);\n                long long s = sumSquares(b);\n                if (s > bestValue) {\n                    bestValue = s;\n                    bestCur = s;\n                    bestDir = dir;\n                }\n            }\n        } else {\n            for (char dir : DIRS) {\n                auto b = board;\n                tilt(b, dir);\n                long long curS = sumSquares(b);\n                long long expS = expectedFutureScore(b, flavour[step + 1]);\n                // lexicographic comparison: first expected future S,\n                // then current S as a tie\u2011breaker\n                if (expS > bestValue ||\n                    (expS == bestValue && curS > bestCur)) {\n                    bestValue = expS;\n                    bestCur = curS;\n                    bestDir = dir;\n                }\n            }\n        }\n\n        cout << bestDir << '\\n';\n        cout.flush();               // required by the statement\n        tilt(board, bestDir);       // apply the chosen tilt\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int M;\n    double eps;\n    if (!(cin >> M >> eps)) return 0;\n\n    /* ---------- choose the smallest possible N ---------- */\n    int N = 4;\n    while (N * (N - 1) / 2 < M) ++N;          // N \u2264 100 because M \u2264 100\n    const int L = N * (N - 1) / 2;           // number of possible edges\n\n    /* ---------- list of edges in lexicographic order ---------- */\n    vector<pair<int,int>> edge;\n    edge.reserve(L);\n    for (int i = 0; i < N; ++i)\n        for (int j = i + 1; j < N; ++j)\n            edge.emplace_back(i, j);\n\n    /* ---------- edge counts for the M graphs (as far apart as possible) ---------- */\n    vector<int> edgeCnt(M);\n    for (int i = 0; i < M; ++i) {\n        if (M == 1) edgeCnt[i] = 0;\n        else edgeCnt[i] = (int)round(1.0 * i * L / (M - 1));\n    }\n    for (int i = 1; i < M; ++i)\n        if (edgeCnt[i] <= edgeCnt[i-1]) edgeCnt[i] = edgeCnt[i-1] + 1;\n    // edgeCnt[i] are now distinct and 0 \u2264 edgeCnt[i] \u2264 L\n\n    /* ---------- generate the M graphs and store their sorted degree sequences ---------- */\n    vector<string> graphStr(M);\n    vector<vector<int>> degSortedOrig(M);          // sorted degree vectors\n    for (int idx = 0; idx < M; ++idx) {\n        int e = edgeCnt[idx];\n        string s(L, '0');\n        for (int p = 0; p < e; ++p) s[p] = '1';\n        graphStr[idx] = s;\n\n        // degree vector of this graph\n        vector<int> deg(N, 0);\n        for (int p = 0; p < L; ++p)\n            if (s[p] == '1') {\n                ++deg[edge[p].first];\n                ++deg[edge[p].second];\n            }\n        vector<int> d = deg;\n        sort(d.begin(), d.end(), greater<int>());\n        degSortedOrig[idx] = d;\n    }\n\n    /* ---------- pre\u2011compute log\u2011factorials ---------- */\n    vector<double> lf(L + 1, 0.0);\n    for (int i = 1; i <= L; ++i) lf[i] = lf[i-1] + log((double)i);\n    auto logComb = [&](int n, int k) -> double {\n        if (k < 0 || k > n) return -INFINITY;\n        return lf[n] - lf[k] - lf[n - k];\n    };\n\n    /* ---------- output the description of the graphs ---------- */\n    cout << N << '\\n';\n    for (const string &g : graphStr) cout << g << '\\n';\n    cout.flush();\n\n    const bool zeroNoise = fabs(eps) < 1e-12;\n    const double logEps = log(eps);\n    const double log1mEps = log(1.0 - eps);\n    const int nMinus1 = N - 1;\n\n    /* ---------- answer the 100 queries ---------- */\n    for (int q = 0; q < 100; ++q) {\n        string h;  cin >> h;\n\n        /* observed edge count */\n        int m = 0;\n        for (char c : h) if (c == '1') ++m;\n\n        /* observed degree sequence */\n        vector<int> degObs(N, 0);\n        for (int p = 0; p < L; ++p)\n            if (h[p] == '1') {\n                ++degObs[edge[p].first];\n                ++degObs[edge[p].second];\n            }\n        vector<int> degObsSorted = degObs;\n        sort(degObsSorted.begin(), degObsSorted.end(), greater<int>());\n\n        int answer = 0;\n        double bestScore = -INFINITY;\n\n        if (zeroNoise) {\n            // exact matching by edge count\n            for (int i = 0; i < M; ++i) {\n                if (edgeCnt[i] == m) { answer = i; break; }\n            }\n        } else {\n            for (int i = 0; i < M; ++i) {\n                int e = edgeCnt[i];\n                /* ---- edge\u2011count log\u2011likelihood (exact mixture) ---- */\n                double cur = -INFINITY;\n                int kMin = max(0, m - (L - e));\n                int kMax = min(m, e);\n                for (int k = kMin; k <= kMax; ++k) {\n                    int l = m - k;                         // present among originally absent edges\n                    double term = logComb(e, k) + logComb(L - e, l)\n                                + (k + (L - e - l)) * log1mEps\n                                + (e - k + l) * logEps;\n                    // log\u2011sum\u2011exp\n                    if (term > cur) cur = term + log1p(exp(cur - term));\n                    else cur = cur + log1p(exp(term - cur));\n                }\n\n                /* ---- degree\u2011sequence log\u2011likelihood (independent binomial) ---- */\n                const vector<int> &dOrig = degSortedOrig[i];\n                for (int v = 0; v < N; ++v) {\n                    int d = dOrig[v];\n                    int k = degObsSorted[v];\n                    double p = eps + (1.0 - 2.0 * eps) * d / nMinus1;\n                    double term = logComb(nMinus1, k) + k * log(p) + (nMinus1 - k) * log(1.0 - p);\n                    cur += term;\n                }\n\n                if (cur > bestScore) {\n                    bestScore = cur;\n                    answer = i;\n                }\n            }\n        }\n\n        cout << answer << '\\n' << flush;\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v;\n    int w;\n};\n\nstruct Adj {\n    int to;\n    int w;\n    int id;\n};\n\nusing i128 = __int128_t;\nconst long long INF = (1LL << 60);          // enough for all distances\n\n/*---------------------------------------------------------------*/\n/* Dijkstra \u2013 can forbid one edge id ( -1 = allowed everything) */\nvoid dijkstra(int start, int forbid,\n              const vector<vector<Adj>>& adj,\n              vector<long long>& dist) {\n    int n = (int)adj.size() - 1;\n    fill(dist.begin(), dist.end(), INF);\n    dist[start] = 0;\n    using P = pair<long long,int>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n    pq.emplace(0LL, start);\n    while (!pq.empty()) {\n        auto [d, v] = pq.top(); pq.pop();\n        if (d != dist[v]) continue;\n        for (const Adj& e : adj[v]) {\n            if (e.id == forbid) continue;          // edge removed\n            long long nd = d + e.w;\n            if (nd < dist[e.to]) {\n                dist[e.to] = nd;\n                pq.emplace(nd, e.to);\n            }\n        }\n    }\n}\n\n/*---------------------------------------------------------------*/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n    vector<Edge> edges(M);\n    vector<vector<Adj>> adj(N + 1);\n    for (int i = 0; i < M; ++i) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        edges[i] = {u, v, w};\n        adj[u].push_back({v, w, i});\n        adj[v].push_back({u, w, i});\n    }\n    /* read and ignore coordinates */\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    /*------------------------------------------------------*/\n    /* 1) cnt[e] \u2013 number of directed shortest\u2011path pairs using e */\n    vector<long long> cnt(M, 0);\n    vector<long long> dist(N + 1);\n    vector<int> parent(N + 1, -1);\n    for (int s = 1; s <= N; ++s) {\n        fill(dist.begin(), dist.end(), INF);\n        fill(parent.begin(), parent.end(), -1);\n        using P = pair<long long,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        dist[s] = 0;\n        pq.emplace(0LL, s);\n        while (!pq.empty()) {\n            auto [d, v] = pq.top(); pq.pop();\n            if (d != dist[v]) continue;\n            for (const Adj& e : adj[v]) {\n                long long nd = d + e.w;\n                if (nd < dist[e.to]) {\n                    dist[e.to] = nd;\n                    parent[e.to] = e.id;\n                    pq.emplace(nd, e.to);\n                }\n            }\n        }\n        for (int v = 1; v <= N; ++v) {\n            if (v != s && parent[v] != -1) {\n                cnt[parent[v]]++;\n            }\n        }\n    }\n\n    /*------------------------------------------------------*/\n    /* 2) replacement distance for every edge */\n    vector<long long> repDist(M, INF);\n    for (int i = 0; i < M; ++i) {\n        int u = edges[i].u;\n        int v = edges[i].v;\n        dijkstra(u, i, adj, dist);          // run while ignoring edge i\n        repDist[i] = dist[v];\n    }\n\n    /*------------------------------------------------------*/\n    /* 3) improved single\u2011edge cost */\n    vector<long long> cost2(M, 0);\n    for (int i = 0; i < M; ++i) {\n        long long diff = repDist[i] - edges[i].w;   // \u2265 0\n        if (diff < 0) diff = 0;\n        cost2[i] = cnt[i] * diff;                 // fits into 64\u2011bit\n    }\n\n    /*------------------------------------------------------*/\n    /* 4) multi\u2011start greedy assignment */\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    const int RUNS = 10;                 // number of random runs\n    vector<int> bestAssign(M, -1);\n    i128 bestMaxLoad = (i128)1 << 126;   // very large\n\n    for (int run = 0; run < RUNS; ++run) {\n        /* random tie\u2011breaker for equal costs */\n        vector<double> rnd(M);\n        uniform_real_distribution<double> realDist(0.0, 1.0);\n        for (int i = 0; i < M; ++i) rnd[i] = realDist(rng);\n\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(),\n             [&](int a, int b) {\n                 if (cost2[a] != cost2[b]) return cost2[a] > cost2[b];\n                 return rnd[a] > rnd[b];\n             });\n\n        vector<int> dayCnt(D, 0);\n        vector<i128> dayLoad(D, 0);\n        vector<int> curAssign(M, -1);\n\n        for (int idx : order) {\n            // choose day with smallest load among those with free capacity\n            i128 bestLoad = (i128)1 << 126;\n            vector<int> candidates;\n            for (int d = 0; d < D; ++d) {\n                if (dayCnt[d] < K) {\n                    if (dayLoad[d] < bestLoad) {\n                        bestLoad = dayLoad[d];\n                        candidates.clear();\n                        candidates.push_back(d);\n                    } else if (dayLoad[d] == bestLoad) {\n                        candidates.push_back(d);\n                    }\n                }\n            }\n            int chosen = candidates[uniform_int_distribution<int>\n                                    (0, (int)candidates.size() - 1)(rng)];\n            curAssign[idx] = chosen;\n            ++dayCnt[chosen];\n            dayLoad[chosen] += (i128)cost2[idx];\n        }\n\n        // evaluate this schedule (max load)\n        i128 curMaxLoad = 0;\n        for (int d = 0; d < D; ++d)\n            if (dayLoad[d] > curMaxLoad) curMaxLoad = dayLoad[d];\n\n        if (curMaxLoad < bestMaxLoad) {\n            bestMaxLoad = curMaxLoad;\n            bestAssign.swap(curAssign);\n        }\n    }\n\n    /*------------------------------------------------------*/\n    /* 5) output */\n    for (int i = 0; i < M; ++i) {\n        if (i) cout << ' ';\n        cout << (bestAssign[i] + 1);   // days are 1\u2011based\n    }\n    cout << '\\n';\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D;\n    if (!(cin >> D)) return 0;\n    vector<string> f1(D), r1(D), f2(D), r2(D);\n    for (int z = 0; z < D; ++z) cin >> f1[z];\n    for (int z = 0; z < D; ++z) cin >> r1[z];\n    for (int z = 0; z < D; ++z) cin >> f2[z];\n    for (int z = 0; z < D; ++z) cin >> r2[z];\n\n    const int N = D * D * D;\n    auto idx = [&](int x, int y, int z) { return x * D * D + y * D + z; };\n\n    vector<char> allowed1(N, 0), allowed2(N, 0), inter(N, 0);\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                int id = idx(x, y, z);\n                allowed1[id] = (f1[z][x] == '1' && r1[z][y] == '1');\n                allowed2[id] = (f2[z][x] == '1' && r2[z][y] == '1');\n                inter[id] = allowed1[id] & allowed2[id];\n            }\n\n    /* ---------- connected components of intersection ---------- */\n    vector<int> comp(N, -1);\n    vector<vector<int>> comps;\n    const int dx[6] = {1,-1,0,0,0,0};\n    const int dy[6] = {0,0,1,-1,0,0};\n    const int dz[6] = {0,0,0,0,1,-1};\n\n    for (int id = 0; id < N; ++id) if (inter[id] && comp[id] == -1) {\n        queue<int> q;\n        q.push(id);\n        comp[id] = (int)comps.size();\n        vector<int> cells;\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            cells.push_back(v);\n            int x = v / (D * D);\n            int rem = v % (D * D);\n            int y = rem / D;\n            int z = rem % D;\n            for (int dir = 0; dir < 6; ++dir) {\n                int nx = x + dx[dir];\n                int ny = y + dy[dir];\n                int nz = z + dz[dir];\n                if (nx < 0 || nx >= D || ny < 0 || ny >= D || nz < 0 || nz >= D) continue;\n                int nid = idx(nx, ny, nz);\n                if (inter[nid] && comp[nid] == -1) {\n                    comp[nid] = (int)comps.size();\n                    q.push(nid);\n                }\n            }\n        }\n        comps.push_back(move(cells));\n    }\n\n    int nShared = (int)comps.size();\n\n    /* ---------- output arrays ---------- */\n    vector<int> out1(N, 0), out2(N, 0);\n    for (int ci = 0; ci < nShared; ++ci) {\n        int bid = ci + 1;                       // block numbers start with 1\n        for (int v : comps[ci]) {\n            out1[v] = bid;\n            out2[v] = bid;\n        }\n    }\n\n    /* ---------- coverage tables ---------- */\n    vector<vector<vector<char>>> frontCov(2, vector<vector<char>>(D, vector<char>(D, 0)));\n    vector<vector<vector<char>>> rightCov(2, vector<vector<char>>(D, vector<char>(D, 0)));\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                int id = idx(x, y, z);\n                if (inter[id]) {\n                    frontCov[0][z][x] = 1;\n                    rightCov[0][z][y] = 1;\n                    frontCov[1][z][x] = 1;\n                    rightCov[1][z][y] = 1;\n                }\n            }\n\n    int nextBlock = nShared + 1;\n\n    const vector<string>* f[2] = {&f1, &f2};\n    const vector<string>* r[2] = {&r1, &r2};\n    const vector<char>* allow[2] = {&allowed1, &allowed2};\n\n    for (int obj = 0; obj < 2; ++obj) {\n        const vector<string>& fobj = *f[obj];\n        const vector<string>& robj = *r[obj];\n        const vector<char>& allowObj = *allow[obj];\n        vector<int>& out = (obj == 0 ? out1 : out2);\n\n        for (int z = 0; z < D; ++z) {\n            vector<int> X, Y;\n            for (int x = 0; x < D; ++x)\n                if (fobj[z][x] == '1' && !frontCov[obj][z][x]) X.push_back(x);\n            for (int y = 0; y < D; ++y)\n                if (robj[z][y] == '1' && !rightCov[obj][z][y]) Y.push_back(y);\n            int L = (int)X.size();\n            int R = (int)Y.size();\n            if (L == 0 && R == 0) continue;\n\n            /* ---- case L == 0 : only right columns have to be covered ---- */\n            if (L == 0) {\n                for (int y : Y) {\n                    for (int x = 0; x < D; ++x) {\n                        int id = idx(x, y, z);\n                        if (allowObj[id] && !inter[id] && out[id] == 0) {\n                            out[id] = nextBlock++;\n                            frontCov[obj][z][x] = 1;\n                            rightCov[obj][z][y] = 1;\n                            break;\n                        }\n                    }\n                }\n                continue;\n            }\n            /* ---- case R == 0 : only front columns have to be covered ---- */\n            if (R == 0) {\n                for (int x : X) {\n                    for (int y = 0; y < D; ++y) {\n                        int id = idx(x, y, z);\n                        if (allowObj[id] && !inter[id] && out[id] == 0) {\n                            out[id] = nextBlock++;\n                            frontCov[obj][z][x] = 1;\n                            rightCov[obj][z][y] = 1;\n                            break;\n                        }\n                    }\n                }\n                continue;\n            }\n\n            /* ---- general case ---- */\n            vector<vector<int>> adj(L);\n            for (int li = 0; li < L; ++li) {\n                int x = X[li];\n                for (int rj = 0; rj < R; ++rj) {\n                    int y = Y[rj];\n                    int id = idx(x, y, z);\n                    if (allowObj[id] && !inter[id]) adj[li].push_back(rj);\n                }\n            }\n\n            /* maximum matching (simple DFS augment) */\n            vector<int> matchR(R, -1);\n            function<bool(int, vector<char>&)> dfs = [&](int v, vector<char>& seen) -> bool {\n                for (int to : adj[v]) {\n                    if (seen[to]) continue;\n                    seen[to] = true;\n                    if (matchR[to] == -1 || dfs(matchR[to], seen)) {\n                        matchR[to] = v;\n                        return true;\n                    }\n                }\n                return false;\n            };\n            for (int v = 0; v < L; ++v) {\n                vector<char> seen(R, 0);\n                dfs(v, seen);\n            }\n\n            /* build a minimum edge cover */\n            vector<char> covL(L, 0), covR(R, 0);\n            vector<pair<int,int>> edges;\n\n            for (int rj = 0; rj < R; ++rj) {\n                int li = matchR[rj];\n                if (li != -1) {\n                    edges.emplace_back(li, rj);\n                    covL[li] = covR[rj] = 1;\n                }\n            }\n            for (int li = 0; li < L; ++li) if (!covL[li]) {\n                if (!adj[li].empty()) {\n                    int rj = adj[li][0];\n                    edges.emplace_back(li, rj);\n                    covL[li] = 1;\n                }\n            }\n            for (int rj = 0; rj < R; ++rj) if (!covR[rj]) {\n                bool found = false;\n                for (int li = 0; li < L && !found; ++li) {\n                    for (int to : adj[li]) if (to == rj) {\n                        edges.emplace_back(li, rj);\n                        covR[rj] = 1;\n                        found = true;\n                        break;\n                    }\n                }\n                if (!found) {                 // should not happen for a solvable instance\n                    edges.emplace_back(-1, rj);   // placeholder, will be handled later\n                }\n            }\n\n            /* place the exclusive cells */\n            vector<vector<char>> used(D, vector<char>(D, 0));\n            for (auto &pr : edges) {\n                int li = pr.first, rj = pr.second;\n                if (li == -1) {               // placeholder\n                    int y = Y[rj];\n                    for (int x = 0; x < D; ++x) {\n                        int id = idx(x, y, z);\n                        if (allowObj[id] && !inter[id] && out[id] == 0 && !used[x][y]) {\n                            out[id] = nextBlock++;\n                            frontCov[obj][z][x] = 1;\n                            rightCov[obj][z][y] = 1;\n                            used[x][y] = 1;\n                            break;\n                        }\n                    }\n                    continue;\n                }\n                int x = X[li];\n                int y = Y[rj];\n                if (used[x][y]) continue;\n                used[x][y] = 1;\n                int id = idx(x, y, z);\n                out[id] = nextBlock++;\n                frontCov[obj][z][x] = 1;\n                rightCov[obj][z][y] = 1;\n            }\n\n            /* safety net \u2013 guarantee coverage (normally not needed) */\n            for (int x : X) if (!frontCov[obj][z][x]) {\n                for (int y = 0; y < D; ++y) {\n                    int id = idx(x, y, z);\n                    if (allowObj[id] && !inter[id] && out[id] == 0) {\n                        out[id] = nextBlock++;\n                        frontCov[obj][z][x] = 1;\n                        rightCov[obj][z][y] = 1;\n                        break;\n                    }\n                }\n            }\n            for (int y : Y) if (!rightCov[obj][z][y]) {\n                for (int x = 0; x < D; ++x) {\n                    int id = idx(x, y, z);\n                    if (allowObj[id] && !inter[id] && out[id] == 0) {\n                        out[id] = nextBlock++;\n                        frontCov[obj][z][x] = 1;\n                        rightCov[obj][z][y] = 1;\n                        break;\n                    }\n                }\n            }\n        }\n    }\n\n    int totalBlocks = nextBlock - 1;\n    cout << totalBlocks << '\\n';\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << out1[i];\n    }\n    cout << '\\n';\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << out2[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nconst ll INF = (1LL << 60);\n\n/* ---------- global data ---------- */\nint N, M, K;\n\nvector<int> X, Y;                     // vertex coordinates\nvector<int> A, B;                     // resident coordinates\n\nstruct Edge {\n    int u, v;\n    int w;\n};\nvector<Edge> edges;                   // edges (1\u2011based index)\nvector<vector<pair<int,int>>> adj;    // (neighbour, edge index)\n\nvector<vector<ll>> dist2;              // squared distance vertex \u2192 resident\nvector<vector<ll>> wgt;               // weight matrix\nvector<vector<int>> edgeIdx;          // edge index matrix, -1 if none\n\n/* ---------- integer square root (ceil) ---------- */\nint ceil_sqrt_ll(ll x) {\n    if (x <= 0) return 0;\n    ll r = (ll)std::sqrt((double)x);\n    while (r * r < x) ++r;\n    while (r > 0 && (r-1)*(r-1) >= x) --r;\n    return (int)r;\n}\n\n/* ---------- evaluate a vertex set ---------- */\nvoid evaluate(const vector<int>& S,\n              bool& feasible,\n              ll& totalCost,\n              vector<int>& radius,\n              vector<int>& usedEdgeIdx)\n{\n    int nS = (int)S.size();\n    // ----- radius for each vertex -----\n    vector<ll> maxDist2(N + 1, 0);          // only used for vertices in S\n    // assign each resident to nearest vertex in S\n    for (int k = 0; k < K; ++k) {\n        ll bestDist = INF;\n        int bestVert = -1;\n        for (int v : S) {\n            ll d = dist2[v][k];\n            if (d < bestDist) {\n                bestDist = d;\n                bestVert = v;\n            }\n        }\n        if (bestVert != -1) {\n            if (bestDist > maxDist2[bestVert]) maxDist2[bestVert] = bestDist;\n        }\n    }\n    // compute radii\n    radius.assign(N + 1, 0);\n    feasible = true;\n    ll sumSq = 0;\n    for (int v : S) {\n        ll md2 = maxDist2[v];\n        int r = 0;\n        if (md2 > 0) r = ceil_sqrt_ll(md2);\n        if (r > 5000) { feasible = false; return; }\n        radius[v] = r;\n        sumSq += 1LL * r * r;\n    }\n\n    // ----- minimum spanning tree of S (Prim) -----\n    vector<char> inS(N + 1, 0);\n    for (int v : S) inS[v] = 1;\n\n    vector<ll> minEdge(N + 1, INF);\n    vector<int> parent(N + 1, -1);\n    vector<int> parentEdge(N + 1, -1);\n    vector<char> visited(N + 1, 0);\n\n    visited[1] = 1;                         // source is always in S\n    for (int u = 1; u <= N; ++u) {\n        if (!inS[u] || u == 1) continue;\n        if (edgeIdx[1][u] != -1) {\n            minEdge[u] = wgt[1][u];\n            parent[u] = 1;\n            parentEdge[u] = edgeIdx[1][u];\n        }\n    }\n\n    usedEdgeIdx.clear();\n    ll edgeCost = 0;\n    for (int it = 0; it < nS - 1; ++it) {\n        int v = -1;\n        ll best = INF;\n        for (int u = 1; u <= N; ++u) {\n            if (inS[u] && !visited[u] && minEdge[u] < best) {\n                best = minEdge[u];\n                v = u;\n            }\n        }\n        if (v == -1) {          // not connected\n            feasible = false;\n            return;\n        }\n        visited[v] = 1;\n        edgeCost += best;\n        usedEdgeIdx.push_back(parentEdge[v]);\n\n        // relax edges from v\n        for (int u = 1; u <= N; ++u) {\n            if (inS[u] && !visited[u] && edgeIdx[v][u] != -1) {\n                ll w = wgt[v][u];\n                if (w < minEdge[u]) {\n                    minEdge[u] = w;\n                    parent[u] = v;\n                    parentEdge[u] = edgeIdx[v][u];\n                }\n            }\n        }\n    }\n\n    totalCost = sumSq + edgeCost;\n}\n\n/* ---------- main ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    /* ----- input ----- */\n    cin >> N >> M >> K;\n    X.resize(N + 1);\n    Y.resize(N + 1);\n    for (int i = 1; i <= N; ++i) cin >> X[i] >> Y[i];\n\n    edges.resize(M + 1);                 // 1\u2011based\n    adj.assign(N + 1, {});\n    wgt.assign(N + 1, vector<ll>(N + 1, INF));\n    edgeIdx.assign(N + 1, vector<int>(N + 1, -1));\n\n    for (int j = 1; j <= M; ++j) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        edges[j] = {u, v, w};\n        adj[u].push_back({v, j});\n        adj[v].push_back({u, j});\n        if (w < wgt[u][v]) {\n            wgt[u][v] = wgt[v][u] = w;\n            edgeIdx[u][v] = edgeIdx[v][u] = j;\n        }\n    }\n\n    A.resize(K);\n    B.resize(K);\n    for (int k = 0; k < K; ++k) cin >> A[k] >> B[k];\n\n    /* ----- pre\u2011compute squared distances ----- */\n    dist2.assign(N + 1, vector<ll>(K));\n    for (int i = 1; i <= N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            ll dx = X[i] - A[k];\n            ll dy = Y[i] - B[k];\n            dist2[i][k] = dx * dx + dy * dy;\n        }\n    }\n\n    /* ----- start with vertex 1 only ----- */\n    vector<int> curS = {1};\n    vector<char> inS(N + 1, 0);\n    inS[1] = 1;\n\n    bool feasible = false;\n    ll curCost = 0;\n    vector<int> curRadius;\n    vector<int> curEdges;\n\n    evaluate(curS, feasible, curCost, curRadius, curEdges);\n    if (feasible) {\n        // best solution already\n    } else {\n        /* ---- greedy expansion until feasible ---- */\n        while (true) {\n            // find candidates \u2013 vertices adjacent to current S\n            vector<int> cand;\n            vector<char> candFlag(N + 1, 0);\n            for (int e = 1; e <= M; ++e) {\n                int u = edges[e].u, v = edges[e].v;\n                if (inS[u] ^ inS[v]) {\n                    int x = inS[u] ? v : u;\n                    if (!candFlag[x]) {\n                        candFlag[x] = 1;\n                        cand.push_back(x);\n                    }\n                }\n            }\n            // try every candidate\n            ll bestCost = INF;\n            int bestCand = -1;\n            bool bestFeas = false;\n            vector<int> bestRadiusTmp;\n            vector<int> bestEdgesTmp;\n            for (int v : cand) {\n                vector<int> ns = curS;\n                ns.push_back(v);\n                bool f; ll c; vector<int> rad; vector<int> ed;\n                evaluate(ns, f, c, rad, ed);\n                if (!f) continue;\n                if (c < bestCost) {\n                    bestCost = c;\n                    bestCand = v;\n                    bestFeas = f;\n                    bestRadiusTmp = rad;\n                    bestEdgesTmp = ed;\n                }\n            }\n            if (bestCand == -1) {\n                // should not happen \u2013 we can always add more vertices\n                // fallback: add any remaining vertex\n                for (int v = 1; v <= N; ++v) if (!inS[v]) {\n                    vector<int> ns = curS; ns.push_back(v);\n                    bool f; ll c; vector<int> rad; vector<int> ed;\n                    evaluate(ns, f, c, rad, ed);\n                    if (f) { bestCand = v; bestCost = c; bestFeas = f;\n                            bestRadiusTmp = rad; bestEdgesTmp = ed; }\n                    break;\n                }\n                if (bestCand == -1) break;   // safety\n            }\n            // apply best addition\n            inS[bestCand] = 1;\n            curS.push_back(bestCand);\n            evaluate(curS, feasible, curCost, curRadius, curEdges);\n            if (feasible) break;\n        }\n    }\n\n    /* ----- store best solution ----- */\n    ll bestCost = curCost;\n    vector<int> bestS = curS;\n    vector<int> bestRadius = curRadius;\n    vector<int> bestEdges = curEdges;\n\n    /* ----- improvement: removal + addition ----- */\n    bool changed = true;\n    while (changed) {\n        changed = false;\n        /* removal */\n        for (size_t i = 0; i < bestS.size(); ++i) {\n            int v = bestS[i];\n            if (v == 1) continue;               // cannot remove the source\n            vector<int> ns = bestS;\n            ns.erase(ns.begin() + i);\n            bool f; ll c; vector<int> rad; vector<int> ed;\n            evaluate(ns, f, c, rad, ed);\n            if (f && c < bestCost - 1) {\n                bestCost = c;\n                bestS = ns;\n                inS[v] = 0;\n                bestRadius = rad;\n                bestEdges = ed;\n                changed = true;\n                break;                           // restart\n            }\n        }\n        if (changed) continue;\n\n        /* addition of a neighbour that improves the cost */\n        // collect neighbours of current set\n        vector<int> cand;\n        vector<char> candFlag(N + 1, 0);\n        for (int e = 1; e <= M; ++e) {\n            int u = edges[e].u, v = edges[e].v;\n            if (inS[u] ^ inS[v]) {\n                int x = inS[u] ? v : u;\n                if (!candFlag[x]) {\n                    candFlag[x] = 1;\n                    cand.push_back(x);\n                }\n            }\n        }\n        for (int v : cand) {\n            vector<int> ns = bestS;\n            ns.push_back(v);\n            bool f; ll c; vector<int> rad; vector<int> ed;\n            evaluate(ns, f, c, rad, ed);\n            if (f && c < bestCost - 1) {\n                bestCost = c;\n                bestS = ns;\n                inS[v] = 1;\n                bestRadius = rad;\n                bestEdges = ed;\n                changed = true;\n                break;\n            }\n        }\n    }\n\n    /* ----- prepare output ----- */\n    vector<int> P(N + 1, 0);\n    for (int i = 1; i <= N; ++i) {\n        if (i < (int)bestRadius.size())\n            P[i] = bestRadius[i];          // zero for all other vertices\n    }\n\n    vector<int> B(M + 1, 0);\n    for (int id : bestEdges) B[id] = 1;\n\n    /* ----- print ----- */\n    for (int i = 1; i <= N; ++i) {\n        if (i > 1) cout << ' ';\n        cout << P[i];\n    }\n    cout << '\\n';\n    for (int j = 1; j <= M; ++j) {\n        if (j > 1) cout << ' ';\n        cout << B[j];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int N = 30;\n    const int M = N * (N + 1) / 2;          // 465\n\n    // index of each coordinate\n    vector<vector<int>> idx(N, vector<int>(N, -1));\n    int curIdx = 0;\n    for (int x = 0; x < N; ++x) {\n        for (int y = 0; y <= x; ++y) {\n            idx[x][y] = curIdx++;\n        }\n    }\n\n    // read the permutation\n    vector<int> value(M);\n    for (int x = 0; x < N; ++x) {\n        for (int y = 0; y <= x; ++y) {\n            int v;\n            if (!(cin >> v)) return 0;\n            value[idx[x][y]] = v;\n        }\n    }\n\n    struct Swap {\n        int x1, y1, x2, y2;\n    };\n    vector<Swap> ops;\n\n    // heapify: process nodes from last non\u2011leaf level up to root\n    for (int x = N - 2; x >= 0; --x) {\n        for (int y = 0; y <= x; ++y) {\n            int curX = x, curY = y;\n            while (curX < N - 1) {\n                int cur = idx[curX][curY];\n                int childX = curX + 1;\n                int leftY  = curY;\n                int rightY = curY + 1;\n\n                int left  = idx[childX][leftY];\n                int right = idx[childX][rightY];\n\n                // find the smaller child that violates the heap property\n                int child = -1;\n                int childX2 = -1, childY2 = -1;\n                if (value[cur] > value[left]) {\n                    child = left;\n                    childX2 = childX; childY2 = leftY;\n                }\n                if (value[cur] > value[right]) {\n                    if (child == -1 || value[right] < value[child]) {\n                        child = right;\n                        childX2 = childX; childY2 = rightY;\n                    }\n                }\n                if (child == -1) break;          // heap property satisfied\n\n                // perform the swap\n                ops.push_back({curX, curY, childX2, childY2});\n                swap(value[cur], value[child]);\n\n                // continue sifting the moved ball downwards\n                curX = childX2;\n                curY = childY2;\n            }\n        }\n    }\n\n    // output\n    cout << ops.size() << '\\n';\n    for (auto &s : ops) {\n        cout << s.x1 << ' ' << s.y1 << ' ' << s.x2 << ' ' << s.y2 << '\\n';\n    }\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int MAXD = 9;                 // maximal grid size (D is always 9)\nconst int dr[4] = {-1, 1, 0, 0};\nconst int dc[4] = {0, 0, -1, 1};\nconst int INF = 1e9;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ------------------------------------------------------------\n       read D (always 9) and the number of obstacles N\n       ------------------------------------------------------------ */\n    int D, N;\n    if (!(cin >> D >> N)) return 0;    // D is read, but we already know D == 9\n    // safety: enforce the known size (the judge always gives D == 9)\n    // D = MAXD;   // optional, not needed because the input is 9\n\n    vector<vector<bool>> obstacle(D, vector<bool>(D, false));\n    for (int k = 0; k < N; ++k) {\n        int ri, rj;\n        cin >> ri >> rj;\n        obstacle[ri][rj] = true;\n    }\n\n    const int R = 0;                    // entrance row\n    const int C = (D - 1) / 2;          // entrance column (0,4)\n\n    /* ------------------------------------------------------------\n       distance from the entrance (BFS) \u2013 used as a heuristic\n       ------------------------------------------------------------ */\n    vector<vector<int>> depth(D, vector<int>(D, -1));\n    queue<pair<int,int>> q;\n    depth[R][C] = 0;\n    q.emplace(R, C);\n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        for (int dir = 0; dir < 4; ++dir) {\n            int nr = r + dr[dir], nc = c + dc[dir];\n            if (nr < 0 || nr >= D || nc < 0 || nc >= D) continue;\n            if (obstacle[nr][nc]) continue;\n            if (depth[nr][nc] != -1) continue;\n            depth[nr][nc] = depth[r][c] + 1;\n            q.emplace(nr, nc);\n        }\n    }\n\n    const int M = D * D - 1 - N;          // number of containers\n\n    // where each container number is stored\n    vector<int> pos_x(M, -1), pos_y(M, -1);\n    // which container is stored in each cell (not strictly needed)\n    vector<vector<int>> number_at(D, vector<int>(D, -1));\n\n    // occupation flag\n    vector<vector<bool>> occupied(D, vector<bool>(D, false));\n\n    /* ------------------------------------------------------------\n       STORAGE PHASE\n       ------------------------------------------------------------ */\n    for (int step = 0; step < M; ++step) {\n        int t;                           // the number written on the arriving container\n        cin >> t;\n\n        // ----- build graph of currently empty squares -----\n        vector<vector<bool>> empty(D, vector<bool>(D, false));\n        for (int i = 0; i < D; ++i)\n            for (int j = 0; j < D; ++j)\n                if (!obstacle[i][j] && !occupied[i][j])\n                    empty[i][j] = true;\n\n        // ----- find articulation points (Tarjan) -----\n        vector<vector<int>> disc(D, vector<int>(D, 0));\n        vector<vector<int>> low(D, vector<int>(D, 0));\n        vector<vector<bool>> visited(D, vector<bool>(D, false));\n        vector<vector<bool>> isArt(D, vector<bool>(D, false));\n        int timer = 0;\n\n        function<void(int,int,int,int)> dfs = [&](int r, int c,\n                                                   int parent_r, int parent_c) {\n            visited[r][c] = true;\n            disc[r][c] = low[r][c] = ++timer;\n            int child = 0;\n            for (int d = 0; d < 4; ++d) {\n                int nr = r + dr[d], nc = c + dc[d];\n                if (nr < 0 || nr >= D || nc < 0 || nc >= D) continue;\n                if (!empty[nr][nc]) continue;\n                if (nr == parent_r && nc == parent_c) continue;\n                if (!visited[nr][nc]) {\n                    ++child;\n                    dfs(nr, nc, r, c);\n                    low[r][c] = min(low[r][c], low[nr][nc]);\n                    if (parent_r == -1 && child > 1) isArt[r][c] = true;\n                    if (parent_r != -1 && low[nr][nc] >= disc[r][c]) isArt[r][c] = true;\n                } else {\n                    low[r][c] = min(low[r][c], disc[nr][nc]);\n                }\n            }\n        };\n        dfs(R, C, -1, -1);               // start from the entrance\n\n        // ----- choose the best empty non\u2011articulation square -----\n        int best_r = -1, best_c = -1, bestDepth = INF;\n        for (int i = 0; i < D; ++i) {\n            for (int j = 0; j < D; ++j) {\n                if (i == R && j == C) continue;   // entrance cannot be used\n                if (!empty[i][j]) continue;\n                if (isArt[i][j]) continue;        // cut\u2011vertices are forbidden\n                if (depth[i][j] < bestDepth) {\n                    bestDepth = depth[i][j];\n                    best_r = i; best_c = j;\n                }\n            }\n        }\n\n        // store the container\n        occupied[best_r][best_c] = true;\n        number_at[best_r][best_c] = t;\n        pos_x[t] = best_r;\n        pos_y[t] = best_c;\n\n        cout << best_r << ' ' << best_c << '\\n';\n        cout.flush();                     // required by the statement\n    }\n\n    /* ------------------------------------------------------------\n       RETRIEVAL PHASE \u2013 output squares in non\u2011decreasing depth\n       ------------------------------------------------------------ */\n    vector<pair<int,int>> order;         // (depth, container number)\n    for (int num = 0; num < M; ++num) {\n        int r = pos_x[num];\n        int c = pos_y[num];\n        order.emplace_back(depth[r][c], num);\n    }\n    sort(order.begin(), order.end(),\n         [](const pair<int,int>& a, const pair<int,int>& b) {\n             if (a.first != b.first) return a.first < b.first;\n             return a.second < b.second;\n         });\n\n    for (auto &p : order) {\n        int num = p.second;\n        cout << pos_x[num] << ' ' << pos_y[num] << '\\n';\n    }\n    cout.flush();\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\nint n, m;\nconst int MAXC = 100 + 5;            // colours 0 \u2026 m\nint a[55][55];                       // current colours\nint total[MAXC];                     // number of squares of each colour\nint adjCnt[MAXC][MAXC];              // current number of adjacency edges\nbool need[MAXC][MAXC];               // adjacency existed in the original map\n\nint dx[4] = {-1, 1, 0, 0};\nint dy[4] = {0, 0, -1, 1};\n\nint vis[55][55];\nint bfsStamp = 0;\n\n/* --------------------------------------------------------------- */\n// check whether the square (x,y) can be turned into 0\nbool canDelete(int x, int y) {\n    int c = a[x][y];\n    if (c == 0) return false;\n    if (total[c] <= 1) return false;                // colour must survive\n\n    // 1) adjacent to zero (or outside)\n    bool adjZero = false;\n    for (int dir = 0; dir < 4; ++dir) {\n        int nx = x + dx[dir], ny = y + dy[dir];\n        if (nx < 0 || nx >= n || ny < 0 || ny >= n) { adjZero = true; break; }\n        if (a[nx][ny] == 0) { adjZero = true; break; }\n    }\n    if (!adjZero) return false;\n\n    // collect neighbour colours (including 0 for outside)\n    int nbCol[4];\n    bool nbOut[4];\n    for (int dir = 0; dir < 4; ++dir) {\n        int nx = x + dx[dir], ny = y + dy[dir];\n        if (nx < 0 || nx >= n || ny < 0 || ny >= n) {\n            nbCol[dir] = 0;\n            nbOut[dir] = true;\n        } else {\n            nbCol[dir] = a[nx][ny];\n            nbOut[dir] = false;\n        }\n    }\n\n    // 2) no illegal new adjacency 0\u2011d\n    for (int dir = 0; dir < 4; ++dir) {\n        int d = nbCol[dir];\n        if (d == c) continue;\n        if (d != 0 && !need[0][d]) return false;      // would create forbidden 0\u2011d\n    }\n\n    // 3) keep at least one adjacency for every required pair\n    for (int dir = 0; dir < 4; ++dir) {\n        int d = nbCol[dir];\n        if (d == c) continue;\n        if (need[c][d] && adjCnt[c][d] <= 1) return false;\n    }\n\n    // 4) connectivity of the colour after removal\n    // find a start cell of colour c different from (x,y)\n    int sx = -1, sy = -1;\n    for (int dir = 0; dir < 4; ++dir) {\n        int nx = x + dx[dir], ny = y + dy[dir];\n        if (0 <= nx && nx < n && 0 <= ny && ny < n && a[nx][ny] == c) {\n            sx = nx; sy = ny;\n            break;\n        }\n    }\n    if (sx == -1) return false;          // no other cell of this colour\n\n    ++bfsStamp;\n    queue<pair<int,int>> q;\n    q.emplace(sx, sy);\n    vis[sx][sy] = bfsStamp;\n    int cnt = 0;\n    while (!q.empty()) {\n        auto [cx, cy] = q.front(); q.pop();\n        ++cnt;\n        for (int dir = 0; dir < 4; ++dir) {\n            int nx = cx + dx[dir], ny = cy + dy[dir];\n            if (nx < 0 || nx >= n || ny < 0 || ny >= n) continue;\n            if (a[nx][ny] != c) continue;\n            if (nx == x && ny == y) continue;          // the removed cell\n            if (vis[nx][ny] == bfsStamp) continue;\n            vis[nx][ny] = bfsStamp;\n            q.emplace(nx, ny);\n        }\n    }\n    if (cnt != total[c] - 1) return false;            // would disconnect\n\n    return true;\n}\n\n/* --------------------------------------------------------------- */\n// really delete the square (x,y)\nvoid doDelete(int x, int y) {\n    int c = a[x][y];\n    a[x][y] = 0;\n    --total[c];\n\n    for (int dir = 0; dir < 4; ++dir) {\n        int nx = x + dx[dir], ny = y + dy[dir];\n        int nd;\n        bool outside = false;\n        if (nx < 0 || nx >= n || ny < 0 || ny >= n) {\n            nd = 0;\n            outside = true;\n        } else {\n            nd = a[nx][ny];\n        }\n        if (nd == c) continue;                 // same colour, irrelevant\n\n        // remove adjacency c \u2013 nd\n        --adjCnt[c][nd];\n        --adjCnt[nd][c];\n\n        // create new adjacency 0 \u2013 nd (if nd is inside the board)\n        if (!outside && nd != 0) {\n            ++adjCnt[0][nd];\n            ++adjCnt[nd][0];\n        }\n    }\n\n    // neighbours become candidates (they may have a zero neighbour now)\n    for (int dir = 0; dir < 4; ++dir) {\n        int nx = x + dx[dir], ny = y + dy[dir];\n        if (0 <= nx && nx < n && 0 <= ny && ny < n && a[nx][ny] > 0) {\n            // will be pushed into the global queue later\n            q.emplace(nx, ny);\n        }\n    }\n}\n\n/* --------------------------------------------------------------- */\nqueue<pair<int,int>> q;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> n >> m;\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j)\n            cin >> a[i][j];\n\n    /* ----- initial adjacency counting ----- */\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            int c = a[i][j];\n            ++total[c];\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + dx[dir], nj = j + dy[dir];\n                if (ni < 0 || ni >= n || nj < 0 || nj >= n) {\n                    ++adjCnt[c][0];\n                    ++adjCnt[0][c];\n                } else {\n                    int d = a[ni][nj];\n                    if (d != c) {\n                        ++adjCnt[c][d];\n                        ++adjCnt[d][c];\n                    }\n                }\n            }\n        }\n    }\n\n    /* ----- which adjacencies exist in the original map ----- */\n    for (int c = 0; c <= m; ++c)\n        for (int d = 0; d <= m; ++d)\n            need[c][d] = (adjCnt[c][d] > 0);\n\n    /* ----- initialise candidate queue (border squares) ----- */\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) if (a[i][j] > 0) {\n            bool adjZero = false;\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + dx[dir], nj = j + dy[dir];\n                if (ni < 0 || ni >= n || nj < 0 || nj >= n) { adjZero = true; break; }\n                if (a[ni][nj] == 0) { adjZero = true; break; }\n            }\n            if (adjZero) q.emplace(i, j);\n        }\n    }\n\n    /* ----- main loop ----- */\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        if (a[x][y] == 0) continue;               // already deleted\n        if (canDelete(x, y))\n            doDelete(x, y);\n    }\n\n    /* ----- output ----- */\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            if (j) cout << ' ';\n            cout << a[i][j];\n        }\n        cout << '\\n';\n    }\n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, D, Q;\n    if (!(cin >> N >> D >> Q)) return 0;\n    \n    // win[i] \u2013 times item i was heavier, tie[i] \u2013 times equal\n    vector<int> win(N, 0), tie(N, 0);\n    int performed = 0;\n    \n    // ------------------------------------------------------------\n    // 1) forced consecutive pairs (every item appears at least once)\n    for (int i = 0; i + 1 < N && performed < Q; ++i) {\n        int a = i, b = i + 1;\n        cout << \"1 1 \" << a << ' ' << b << \"\\n\";\n        cout.flush();\n        ++performed;\n        string res; cin >> res;\n        if (res == \">\") {\n            ++win[a];\n        } else if (res == \"<\") {\n            ++win[b];\n        } else { // \"=\"\n            ++tie[a];\n            ++tie[b];\n        }\n    }\n    // ------------------------------------------------------------\n    // 2) random pairs until we have performed exactly Q queries\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    while (performed < Q) {\n        int a = rng() % N;\n        int b = rng() % N;\n        if (a == b) continue;\n        if (a > b) swap(a, b);\n        cout << \"1 1 \" << a << ' ' << b << \"\\n\";\n        cout.flush();\n        ++performed;\n        string res; cin >> res;\n        if (res == \">\") {\n            ++win[a];\n        } else if (res == \"<\") {\n            ++win[b];\n        } else { // \"=\"\n            ++tie[a];\n            ++tie[b];\n        }\n    }\n    \n    // ------------------------------------------------------------\n    // 3) compute rough weight estimates and sort items\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    vector<double> score(N);\n    for (int i = 0; i < N; ++i) score[i] = win[i] + 0.5 * tie[i];\n    stable_sort(idx.begin(), idx.end(),\n                [&](int a, int b) { return score[a] > score[b]; });\n    \n    // ------------------------------------------------------------\n    // 4) LPT (Longest Processing Time) assignment to D groups\n    vector<double> groupSum(D, 0.0);\n    vector<int> groupOf(N, -1);\n    for (int pos = 0; pos < N; ++pos) {\n        int it = idx[pos];\n        // find group with minimal current sum\n        int best = 0;\n        for (int g = 1; g < D; ++g) {\n            if (groupSum[g] < groupSum[best]) best = g;\n        }\n        groupOf[it] = best;\n        groupSum[best] += score[it];\n    }\n    \n    // ------------------------------------------------------------\n    // 5) output the final partition\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << groupOf[i];\n    }\n    cout << \"\\n\";\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    const int per = n / m;                // 20\n    vector<vector<int>> st(m);            // bottom = index 0, top = back()\n    vector<int> where(n + 1, -1);          // current stack of each box (0\u2011based)\n\n    for (int i = 0; i < m; ++i) {\n        st[i].reserve(per);\n        for (int j = 0; j < per; ++j) {\n            int v; cin >> v;\n            st[i].push_back(v);\n            where[v] = i;\n        }\n    }\n\n    vector<pair<int,int>> ops;            // (box, destination)  destination = 0 \u2192 carry out\n\n    for (int v = 1; v <= n; ++v) {\n        int src = where[v];                // stack that currently contains v\n        // while v is not the top of its stack, move the boxes above it\n        while (!st[src].empty() && st[src].back() != v) {\n            int curTop = st[src].back();   // the box that will be moved now\n            int dest = -1;\n\n            // 1) look for a stack whose top is larger than curTop\n            int bestTop = -1;\n            for (int i = 0; i < m; ++i) {\n                if (i == src) continue;\n                if (!st[i].empty() && st[i].back() > curTop) {\n                    if (st[i].back() > bestTop) {\n                        bestTop = st[i].back();\n                        dest = i;\n                    }\n                }\n            }\n            // 2) if not found, try to use an empty stack\n            if (dest == -1) {\n                for (int i = 0; i < m; ++i) {\n                    if (i == src) continue;\n                    if (st[i].empty()) {\n                        dest = i;\n                        break;\n                    }\n                }\n            }\n            // 3) otherwise take any other stack (the order may become temporarily non\u2011decreasing)\n            if (dest == -1) {\n                for (int i = 0; i < m; ++i) {\n                    if (i == src) continue;\n                    dest = i;\n                    break;\n                }\n            }\n\n            // ----- perform operation 1 -----\n            ops.emplace_back(curTop, dest + 1);   // destination is 1\u2011based in output\n            // move the single box\n            st[src].pop_back();\n            st[dest].push_back(curTop);\n            where[curTop] = dest;\n        }\n\n        // now v is on the top \u2013 carry it out (operation 2)\n        ops.emplace_back(v, 0);\n        int src = where[v];\n        st[src].pop_back();\n        where[v] = -1;                     // mark as removed\n    }\n\n    // output\n    cout << ops.size() << '\\n';\n    for (auto [box, dst] : ops) {\n        cout << box << ' ' << dst << '\\n';\n    }\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n\n    vector<string> h(N - 1);\n    for (int i = 0; i < N - 1; ++i) cin >> h[i];\n    vector<string> v(N);\n    for (int i = 0; i < N; ++i) cin >> v[i];\n    vector<vector<int>> d(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) cin >> d[i][j];\n\n    const int di[4] = {0, 1, 0, -1};\n    const int dj[4] = {1, 0, -1, 0};\n    const char dc[4] = {'R', 'D', 'L', 'U'};\n\n    // -----------------------------------------------------------------\n    // 1. depth\u2011first walk that visits every cell and returns to (0,0)\n    // -----------------------------------------------------------------\n    vector<vector<char>> visited(N, vector<char>(N, 0));\n    string base;                     // the DFS tour\n    function<void(int,int)> dfs = [&](int i, int j) {\n        visited[i][j] = 1;\n        for (int dir = 0; dir < 4; ++dir) {\n            int ni = i + di[dir];\n            int nj = j + dj[dir];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            if (visited[ni][nj]) continue;\n\n            bool free = false;\n            if (dir == 0 && j + 1 < N && v[i][j] == '0') free = true;          // right\n            if (dir == 1 && i + 1 < N && h[i][j] == '0') free = true;          // down\n            if (dir == 2 && j - 1 >= 0 && v[i][j-1] == '0') free = true;      // left\n            if (dir == 3 && i - 1 >= 0 && h[i-1][j] == '0') free = true;      // up\n            if (!free) continue;\n\n            base.push_back(dc[dir]);                // go forward\n            dfs(ni, nj);\n            base.push_back(dc[(dir + 2) % 4]);      // go back\n        }\n    };\n    dfs(0, 0);               // the walk is closed, starts and ends in (0,0)\n\n    // -----------------------------------------------------------------\n    // 2. repeat the walk as many times as the length limit allows\n    // -----------------------------------------------------------------\n    const int L0 = (int)base.size();               // = 2\u00b7(N\u00b2\u20111)\n    const int Lmax = 100000;\n    int repeat = Lmax / L0;                         // maximal full repetitions\n\n    string answer;\n    answer.reserve(repeat * L0);\n    for (int i = 0; i < repeat; ++i) answer += base;\n\n    cout << answer << '\\n';\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\nconst int N = 15;\nconst int TOT = N * N;                 // 225\n\n// ------------------------------------------------------------\n// overlap: longest k (0 \u2264 k \u2264 5) such that suffix of a (len k)\n// equals prefix of b (len k)\nint overlap(const string &a, const string &b) {\n    int maxk = min({(int)a.size(), (int)b.size(), 5});\n    for (int k = maxk; k >= 0; --k) {\n        bool ok = true;\n        for (int i = 0; i < k; ++i) {\n            if (a[a.size() - k + i] != b[i]) { ok = false; break; }\n        }\n        if (ok) return k;\n    }\n    return 0;\n}\n\n// ------------------------------------------------------------\n// greedy construction of a superstring, bidirectional, starting from startIdx\nstring buildSuperstring(const vector<string> &words, int startIdx) {\n    int m = (int)words.size();\n    vector<bool> used(m, false);\n    string cur = words[startIdx];\n    used[startIdx] = true;\n\n    while (true) {\n        int bestId = -1;\n        int bestAdd = INF;          // extra characters added\n        int bestOri = 0;            // 0 = append, 1 = prepend\n        int bestOv = 0;\n\n        for (int j = 0; j < m; ++j) if (!used[j]) {\n            // append\n            int ov_app = overlap(cur, words[j]);\n            int add_app = (int)words[j].size() - ov_app;\n            // prepend\n            int ov_pre = overlap(words[j], cur);\n            int add_pre = (int)words[j].size() - ov_pre;\n\n            if (add_app <= add_pre) {\n                if (add_app < bestAdd) {\n                    bestAdd = add_app;\n                    bestId = j;\n                    bestOri = 0;\n                    bestOv = ov_app;\n                }\n            } else {\n                if (add_pre < bestAdd) {\n                    bestAdd = add_pre;\n                    bestId = j;\n                    bestOri = 1;\n                    bestOv = ov_pre;\n                }\n            }\n        }\n        if (bestId == -1) break;               // all words used\n\n        if (bestOri == 0) {                     // append\n            cur += words[bestId].substr(bestOv);\n        } else {                                 // prepend\n            cur = words[bestId].substr(0, (int)words[bestId].size() - bestOv) + cur;\n        }\n        used[bestId] = true;\n    }\n    return cur;\n}\n\n// ------------------------------------------------------------\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int M;\n    if (!(cin >> N >> M)) return 0;\n    int si, sj;\n    cin >> si >> sj;\n    vector<string> board(N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n\n    // positions of each letter\n    vector<vector<int>> cells(26);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            int id = i * N + j;\n            cells[board[i][j] - 'A'].push_back(id);\n        }\n\n    vector<string> words(M);\n    for (int i = 0; i < M; ++i) cin >> words[i];\n\n    // distance matrix between all cells\n    static int dist[TOT][TOT];\n    for (int i = 0; i < TOT; ++i) {\n        int x1 = i / N, y1 = i % N;\n        for (int j = 0; j < TOT; ++j) {\n            int x2 = j / N, y2 = j % N;\n            dist[i][j] = abs(x1 - x2) + abs(y1 - y2);\n        }\n    }\n\n    // --------------------------------------------------------\n    // try a few random start words\n    mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());\n    const int TRIALS = 5;\n\n    int bestCost = INF;\n    vector<pair<int,int>> bestPath;   // (i , j) for each operation\n\n    for (int trial = 0; trial < TRIALS; ++trial) {\n        int startWord = uniform_int_distribution<int>(0, M-1)(rng);\n        string S = buildSuperstring(words, startWord);\n        int L = (int)S.size();\n\n        // DP\n        vector<int> dpPrev(TOT, INF), dpCurr(TOT, INF);\n        vector<vector<short>> pre(L+1, vector<short>(TOT, -1));\n\n        int startCell = si * N + sj;\n        dpPrev[startCell] = 0;                 // cost 0 before typing anything\n\n        for (int pos = 0; pos < L; ++pos) {\n            char c = S[pos];\n            const vector<int> &allowed = cells[c - 'A'];\n            fill(dpCurr.begin(), dpCurr.end(), INF);\n            for (int curIdx : allowed) {\n                int best = INF;\n                short bestPrev = -1;\n                for (int prevIdx = 0; prevIdx < TOT; ++prevIdx) {\n                    int pc = dpPrev[prevIdx];\n                    if (pc == INF) continue;\n                    int cand = pc + dist[prevIdx][curIdx] + 1;\n                    if (cand < best) {\n                        best = cand;\n                        bestPrev = (short)prevIdx;\n                    }\n                }\n                dpCurr[curIdx] = best;\n                pre[pos+1][curIdx] = bestPrev;\n            }\n            dpPrev.swap(dpCurr);\n        }\n\n        // best final cell\n        int finalIdx = -1;\n        int finalCost = INF;\n        for (int i = 0; i < TOT; ++i) {\n            if (dpPrev[i] < finalCost) {\n                finalCost = dpPrev[i];\n                finalIdx = i;\n            }\n        }\n\n        if (finalCost < bestCost) {\n            bestCost = finalCost;\n            // reconstruct path\n            bestPath.assign(L, {0,0});\n            int cur = finalIdx;\n            for (int p = L; p >= 1; --p) {\n                bestPath[p-1] = {cur / N, cur % N};\n                cur = pre[p][cur];\n            }\n        }\n    }\n\n    // --------------------------------------------------------\n    // output\n    cout << bestPath.size() << '\\n';\n    for (auto [i,j] : bestPath) {\n        cout << i << ' ' << j << '\\n';\n    }\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M;\n    double eps;\n    if (!(cin >> N >> M >> eps)) return 0;\n\n    // read and ignore the shapes\n    for (int k = 0; k < M; ++k) {\n        int d; cin >> d;\n        for (int t = 0; t < d; ++t) {\n            int a,b; cin >> a >> b;\n        }\n    }\n\n    const int REPEAT = 3;                 // three repetitions for safety\n    vector<int> rowPos(N, 0), colPos(N, 0);   // 0 = unknown / empty, 1 = non\u2011empty\n\n    auto query_divine = [&](const vector<pair<int,int>>& cells) -> int {\n        cout << 'q' << ' ' << (int)cells.size();\n        for (auto [i,j] : cells) cout << ' ' << i << ' ' << j;\n        cout << '\\n' << std::flush;\n        int resp; cin >> resp;\n        return resp;\n    };\n\n    // ----- rows (three times) -----\n    for (int i = 0; i < N; ++i) {\n        vector<pair<int,int>> cells;\n        cells.reserve(N);\n        for (int j = 0; j < N; ++j) cells.emplace_back(i, j);\n        for (int rep = 0; rep < REPEAT; ++rep) {\n            int r = query_divine(cells);\n            if (r > 0) { rowPos[i] = 1; break; }\n        }\n    }\n\n    // ----- columns (three times) -----\n    for (int j = 0; j < N; ++j) {\n        vector<pair<int,int>> cells;\n        cells.reserve(N);\n        for (int i = 0; i < N; ++i) cells.emplace_back(i, j);\n        for (int rep = 0; rep < REPEAT; ++rep) {\n            int c = query_divine(cells);\n            if (c > 0) { colPos[j] = 1; break; }\n        }\n    }\n\n    // exact values, -1 = not known yet\n    vector<vector<int>> val(N, vector<int>(N, -1));\n\n    // ----- drill candidate cells (row and column are both non\u2011empty) -----\n    for (int i = 0; i < N; ++i) if (rowPos[i])\n        for (int j = 0; j < N; ++j) if (colPos[j]) {\n            cout << 'q' << ' ' << 1 << ' ' << i << ' ' << j << '\\n' << std::flush;\n            int v; cin >> v;\n            val[i][j] = v;\n        }\n\n    // ----- first guess -----\n    vector<pair<int,int>> ans;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (val[i][j] > 0) ans.emplace_back(i, j);\n\n    cout << 'a' << ' ' << (int)ans.size();\n    for (auto [i,j] : ans) cout << ' ' << i << ' ' << j;\n    cout << '\\n' << std::flush;\n    int ok; cin >> ok;\n    if (ok == 1) return 0;          // success\n\n    // ----- fallback : drill everything else -----\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (val[i][j] == -1) {\n                cout << 'q' << ' ' << 1 << ' ' << i << ' ' << j << '\\n' << std::flush;\n                int v; cin >> v;\n                val[i][j] = v;\n            }\n\n    // ----- second guess (must be correct) -----\n    ans.clear();\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (val[i][j] > 0) ans.emplace_back(i, j);\n\n    cout << 'a' << ' ' << (int)ans.size();\n    for (auto [i,j] : ans) cout << ' ' << i << ' ' << j;\n    cout << '\\n' << std::flush;\n    // no need to read the final answer, program ends here\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect {\n    int x, y, w, h;\n};\n\nstruct Segment {\n    int cnt;          // how many days profit from one more unit\n    long long delta;  // how many units are available in this interval\n    int idx;         // which rank\n    bool operator<(Segment const& other) const {\n        return cnt < other.cnt;           // for max\u2011heap\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int W = 1000;\n    int D, N;\n    if (!(cin >> D >> N)) return 0;\n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; ++d)\n        for (int k = 0; k < N; ++k) cin >> a[d][k];\n\n    /* ------------------------------------------------------------\n       1.  collect demands for each rank (i\u2011th smallest rectangle)\n       ------------------------------------------------------------ */\n    vector<vector<int>> demand(N, vector<int>(D));   // demand[i][d]\n    for (int d = 0; d < D; ++d) {\n        vector<pair<int,int>> v;\n        v.reserve(N);\n        for (int k = 0; k < N; ++k) v.emplace_back(a[d][k], k);\n        sort(v.begin(), v.end(),\n             [](const pair<int,int>& p, const pair<int,int>& q){\n                 return p.first < q.first;\n             });\n        for (int i = 0; i < N; ++i) demand[i][d] = v[i].first;\n    }\n\n    /* ------------------------------------------------------------\n       2.  greedy area allocation (optimal B[i])\n       ------------------------------------------------------------ */\n    long long capacity = 1LL * W * W;\n    priority_queue<Segment> pq;\n    for (int i = 0; i < N; ++i) {\n        auto &vec = demand[i];\n        sort(vec.begin(), vec.end());\n        int prev = 0;\n        for (int t = 0; t < (int)vec.size(); ++t) {\n            int cur = vec[t];\n            int delta = cur - prev;\n            if (delta > 0) {\n                int cnt = D - t;               // days whose demand > prev\n                pq.push({cnt, delta, i});\n            }\n            prev = cur;\n        }\n    }\n    vector<long long> B(N, 0);\n    long long remain = capacity;\n    while (remain > 0 && !pq.empty()) {\n        Segment seg = pq.top(); pq.pop();\n        long long take = min(seg.delta, remain);\n        B[seg.idx] += take;\n        remain -= take;\n        seg.delta -= take;\n        if (seg.delta > 0) pq.push(seg);\n    }\n\n    /* ------------------------------------------------------------\n       3.  build rectangles from areas B[i]  (MaxRects)\n       ------------------------------------------------------------ */\n    // helper: create candidate dimensions for a given area\n    auto candidates = [&](int area)->vector<pair<int,int>> {\n        vector<pair<int,int>> cand;\n        int w = min(W, area);\n        int h = (area + w - 1) / w;\n        cand.emplace_back(w, h);\n        if (w != h) cand.emplace_back(h, w);\n        // a second \u201calmost square\u201d candidate\n        int w2 = max(1, (int)sqrt(area));\n        int h2 = (area + w2 - 1) / w2;\n        if (w2 <= W && h2 <= W) {\n            cand.emplace_back(w2, h2);\n            if (w2 != h2) cand.emplace_back(h2, w2);\n        }\n        // full\u2011width candidate (always works)\n        int wf = W;\n        int hf = (area + wf - 1) / wf;\n        if (hf <= W) {\n            cand.emplace_back(wf, hf);\n            if (wf != hf) cand.emplace_back(hf, wf);\n        }\n        // delete duplicates\n        sort(cand.begin(), cand.end());\n        cand.erase(unique(cand.begin(), cand.end()), cand.end());\n        return cand;\n    };\n\n    // order: descending area\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(),\n         [&](int i, int j){ return B[i] > B[j]; });\n\n    vector<Rect> placed(N);               // coordinates for each rank i\n    vector<Rect> freeRects;\n    freeRects.emplace_back(0, 0, W, W);   // the whole grid\n\n    // helper: prune contained free rectangles\n    auto prune = [&](){\n        bool changed = true;\n        while (changed) {\n            changed = false;\n            for (int i = 0; i < (int)freeRects.size() && !changed; ++i) {\n                for (int j = 0; j < (int)freeRects.size(); ++j) {\n                    if (i == j) continue;\n                    const Rect &a = freeRects[i];\n                    const Rect &b = freeRects[j];\n                    if (a.x >= b.x && a.y >= b.y &&\n                        a.x + a.w <= b.x + b.w &&\n                        a.y + a.h <= b.y + b.h) {\n                        freeRects.erase(freeRects.begin() + i);\n                        changed = true;\n                        break;\n                    }\n                }\n            }\n        }\n    };\n\n    for (int id : order) {\n        int area = (int)B[id];\n        if (area == 0) continue;           // never happens (a \u2265 1)\n        vector<pair<int,int>> cand = candidates(area);\n\n        bool placed_now = false;\n        int bestScore = -1;\n        int bestFree = -1, bestW = -1, bestH = -1;\n        for (auto [cw, ch] : cand) {\n            for (int fi = 0; fi < (int)freeRects.size(); ++fi) {\n                const Rect &fr = freeRects[fi];\n                if (cw <= fr.w && ch <= fr.h) {\n                    int a = fr.w - cw;\n                    int b = fr.h - ch;\n                    int score = min(a, b);          // best short side fit\n                    if (score > bestScore) {\n                        bestScore = score;\n                        bestFree = fi;\n                        bestW = cw;\n                        bestH = ch;\n                    }\n                }\n            }\n        }\n        if (bestFree != -1) {\n            Rect fr = freeRects[bestFree];\n            placed[id] = {fr.x, fr.y, bestW, bestH};\n\n            // erase used free rectangle\n            freeRects.erase(freeRects.begin() + bestFree);\n            // add new free rectangles (right and bottom)\n            if (fr.w > bestW) {\n                freeRects.emplace_back(fr.x + bestW, fr.y,\n                                        fr.w - bestW, bestH);\n            }\n            if (fr.h > bestH) {\n                freeRects.emplace_back(fr.x, fr.y + bestH,\n                                        fr.w, fr.h - bestH);\n            }\n            prune();\n            placed_now = true;\n        }\n        // Theoretically never reaches here \u2013 see Lemma\u202f4\n        if (!placed_now) {\n            // emergency: enlarge to full width, this always fits somewhere\n            int wf = W;\n            int hf = (area + wf - 1) / wf;\n            // find any free spot that fits\n            for (int fi = 0; fi < (int)freeRects.size(); ++fi) {\n                Rect &fr = freeRects[fi];\n                if (wf <= fr.w && hf <= fr.h) {\n                    placed[id] = {fr.x, fr.y, wf, hf};\n                    freeRects.erase(freeRects.begin() + fi);\n                    if (fr.w > wf)\n                        freeRects.emplace_back(fr.x + wf, fr.y,\n                                                fr.w - wf, hf);\n                    if (fr.h > hf)\n                        freeRects.emplace_back(fr.x, fr.y + hf,\n                                                fr.w, fr.h - hf);\n                    prune();\n                    placed_now = true;\n                    break;\n                }\n            }\n            // still impossible \u2013 should never happen\n            if (!placed_now) {\n                // last resort: place at (0,0) and ignore the rest\n                placed[id] = {0,0,W,1};\n            }\n        }\n    }\n\n    /* ------------------------------------------------------------\n       4.  prepare output: sort rectangles by area (ascending)\n       ------------------------------------------------------------ */\n    vector<int> ascIdx(N);\n    iota(ascIdx.begin(), ascIdx.end(), 0);\n    sort(ascIdx.begin(), ascIdx.end(),\n         [&](int i, int j){ return B[i] < B[j]; });\n\n    // result[d][k] = {x0,y0,x1,y1}\n    vector<vector<array<int,4>>> out(D, vector<array<int,4>>(N));\n\n    for (int d = 0; d < D; ++d) {\n        // pairs (required area, original index)\n        vector<pair<int,int>> vp;\n        vp.reserve(N);\n        for (int k = 0; k < N; ++k) vp.emplace_back(a[d][k], k);\n        sort(vp.begin(), vp.end(),\n             [](const pair<int,int>& p, const pair<int,int>& q){\n                 return p.first < q.first;\n             });\n        for (int i = 0; i < N; ++i) {\n            int reservation = vp[i].second;\n            const Rect &rc = placed[ ascIdx[i] ];   // i\u2011th smallest area\n            out[d][reservation] = {rc.x, rc.y,\n                                   rc.x + rc.w, rc.y + rc.h};\n        }\n    }\n\n    /* ------------------------------------------------------------\n       5.  print\n       ------------------------------------------------------------ */\n    for (int d = 0; d < D; ++d)\n        for (int k = 0; k < N; ++k) {\n            const auto &r = out[d][k];\n            cout << r[0] << ' ' << r[1] << ' ' << r[2] << ' ' << r[3] << '\\n';\n        }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MOD = 998244353;\nconst int N = 9;          // board size\nconst int NSTAMP = 3;     // stamp size\nconst int MAX_K = 81;\n\nint add_mod(int a, int b) {\n    int s = a + b;\n    if (s >= MOD) s -= MOD;\n    return s;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N_in, M, K;\n    if(!(cin >> N_in >> M >> K)) return 0;\n    // N_in is always 9, but we read it for completeness\n    vector<vector<int>> board(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            long long x; cin >> x;\n            board[i][j] = int(x % MOD);\n        }\n\n    // stamps[m][dx][dy]\n    static int stamp[20][3][3];\n    for (int m = 0; m < M; ++m)\n        for (int i = 0; i < 3; ++i)\n            for (int j = 0; j < 3; ++j) {\n                long long x; cin >> x;\n                stamp[m][i][j] = int(x % MOD);\n            }\n\n    vector<tuple<int,int,int>> ops;          // (m, p, q)\n    long long curSum = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) curSum += board[i][j];\n\n    int remaining = K;\n    while (remaining > 0) {\n        long long bestDelta = LLONG_MIN;\n        int bestM = -1, bestP = -1, bestQ = -1;\n\n        for (int m = 0; m < M; ++m) {\n            for (int p = 0; p <= N - NSTAMP; ++p) {\n                for (int q = 0; q <= N - NSTAMP; ++q) {\n                    long long delta = 0;\n                    for (int di = 0; di < 3; ++di) {\n                        for (int dj = 0; dj < 3; ++dj) {\n                            int cur = board[p + di][q + dj];\n                            int nv = cur + stamp[m][di][dj];\n                            if (nv >= MOD) nv -= MOD;\n                            delta += (nv - cur);\n                        }\n                    }\n                    if (delta > bestDelta) {\n                        bestDelta = delta;\n                        bestM = m; bestP = p; bestQ = q;\n                    }\n                }\n            }\n        }\n\n        if (bestDelta <= 0) break;   // no improvement possible\n\n        // apply the best operation\n        for (int di = 0; di < 3; ++di) {\n            for (int dj = 0; dj < 3; ++dj) {\n                int &cur = board[bestP + di][bestQ + dj];\n                int nv = cur + stamp[bestM][di][dj];\n                if (nv >= MOD) nv -= MOD;\n                cur = nv;\n            }\n        }\n        curSum += bestDelta;\n        ops.emplace_back(bestM, bestP, bestQ);\n        --remaining;\n    }\n\n    cout << ops.size() << '\\n';\n    for (auto [m, p, q] : ops) {\n        cout << m << ' ' << p << ' ' << q << '\\n';\n    }\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int N = 5;\n    const int TOTAL = N * N;          // 25\n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> A[i][j];\n\n    // simulation state\n    vector<int> idx(N, 0);                     // next container to appear in each row\n    vector<pair<int,int>> pos(TOTAL, {-1,-1}); // position of each container on the grid, (-1,-1) = not on grid\n    vector<char> dispatched(TOTAL, 0);\n    int dispatchedCnt = 0;\n\n    int largeR = 0, largeC = 0;                // large crane position\n    int holding = -1;                          // -1 = empty, otherwise container number\n\n    // small crane status: true = still alive\n    bool smallActive[N];\n    for (int i = 1; i < N; ++i) smallActive[i] = true;\n\n    // actions for each crane\n    vector<string> actions(N);\n\n    auto moveDir = [&](int r, int c, int tr, int tc)->char {\n        if (r < tr) return 'D';\n        if (r > tr) return 'U';\n        if (c < tc) return 'R';\n        if (c > tc) return 'L';\n        return '.';\n    };\n\n    int turn = 0;\n    while (dispatchedCnt < TOTAL) {\n        /* ---------- step 1 : receiving gates ---------- */\n        for (int row = 0; row < N; ++row) {\n            if (idx[row] >= N) continue;               // no more containers in this row\n            bool hasContainer = false;\n            for (int c = 0; c < TOTAL; ++c)\n                if (pos[c].first == row && pos[c].second == 0) { hasContainer = true; break; }\n            bool craneHoldingAtSquare = (largeR == row && largeC == 0 && holding != -1);\n            if (!hasContainer && !craneHoldingAtSquare) {\n                int container = A[row][idx[row]];\n                pos[container] = {row, 0};\n                idx[row]++;\n            }\n        }\n\n        /* ---------- step 2 : crane actions ---------- */\n        // small cranes\n        for (int i = 1; i < N; ++i) {\n            char act;\n            if (smallActive[i]) {\n                if (turn == 0) { act = 'B'; smallActive[i] = false; }\n                else act = '.';\n            } else act = '.';\n            actions[i].push_back(act);\n        }\n\n        // large crane\n        // find the smallest undispatched container\n        int cur = 0;\n        while (cur < TOTAL && dispatched[cur]) ++cur;\n\n        char actLarge;\n        if (holding == -1) {\n            // empty \u2013 need to pick up the next container\n            if (cur < TOTAL && pos[cur].first != -1) {\n                // container is on the board\n                int tr = pos[cur].first;\n                int tc = pos[cur].second;\n                if (largeR == tr && largeC == tc) {\n                    actLarge = 'P';\n                    // pick up\n                    holding = cur;\n                    pos[cur] = {-1,-1};\n                } else {\n                    actLarge = moveDir(largeR, largeC, tr, tc);\n                }\n            } else {\n                // not on the board yet\n                actLarge = '.';\n            }\n        } else {\n            // carrying a container \u2013 go to its dispatch gate\n            int targetRow = holding / N;\n            int targetCol = N - 1;\n            if (largeR == targetRow && largeC == targetCol) {\n                actLarge = 'Q';\n                // place container on the dispatch square\n                pos[holding] = {largeR, largeC};\n                // after this turn the container will be dispatched\n                holding = -1;\n            } else {\n                actLarge = moveDir(largeR, largeC, targetRow, targetCol);\n            }\n        }\n\n        // apply movement of the large crane\n        if (actLarge == 'U') --largeR;\n        else if (actLarge == 'D') ++largeR;\n        else if (actLarge == 'L') --largeC;\n        else if (actLarge == 'R') ++largeC;\n        // 'P' , 'Q' , '.' do not move the crane\n\n        actions[0].push_back(actLarge);\n\n        /* ---------- step 3 : dispatch gates ---------- */\n        for (int row = 0; row < N; ++row) {\n            for (int c = 0; c < TOTAL; ++c) {\n                if (pos[c].first == row && pos[c].second == N - 1) {\n                    // dispatch\n                    dispatched[c] = 1;\n                    ++dispatchedCnt;\n                    pos[c] = {-1,-1};\n                }\n            }\n        }\n\n        ++turn;\n    }\n\n    // output\n    for (int i = 0; i < N; ++i) {\n        cout << actions[i] << '\\n';\n    }\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos {\n    int r, c;\n};\n\nstruct Delivery {\n    Pos sink;\n    int amt;\n};\n\nstruct Source {\n    Pos pos;\n    int total;                     // total supply\n    vector<Delivery> deliveries; // to negative cells\n};\n\nstatic inline int manhattan(const Pos& a, const Pos& b) {\n    return abs(a.r - b.r) + abs(a.c - b.c);\n}\n\n// move from cur to target, appending moves to ops\nstatic void moveTo(Pos& cur, const Pos& target, vector<string>& ops) {\n    int dr = target.r - cur.r;\n    int dc = target.c - cur.c;\n    if (dr > 0) {\n        for (int i = 0; i < dr; ++i) {\n            ops.emplace_back(\"D\");\n            cur.r++;\n        }\n    } else if (dr < 0) {\n        for (int i = 0; i < -dr; ++i) {\n            ops.emplace_back(\"U\");\n            cur.r--;\n        }\n    }\n    if (dc > 0) {\n        for (int i = 0; i < dc; ++i) {\n            ops.emplace_back(\"R\");\n            cur.c++;\n        }\n    } else if (dc < 0) {\n        for (int i = 0; i < -dc; ++i) {\n            ops.emplace_back(\"L\");\n            cur.c--;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\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 positive (supply) and negative (demand) cells\n    vector<Pos> negPos;\n    vector<int> negDemand;\n    vector<Source> sources;\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (h[i][j] > 0) {\n                Source src;\n                src.pos = {i, j};\n                src.total = h[i][j];\n                sources.push_back(src);\n            } else if (h[i][j] < 0) {\n                negPos.push_back({i, j});\n                negDemand.push_back(-h[i][j]);\n            }\n        }\n    }\n\n    // greedy assignment: each positive cell gives its supply to the nearest\n    // still demanding negative cell repeatedly\n    for (size_t si = 0; si < sources.size(); ++si) {\n        int remain = sources[si].total;\n        while (remain > 0) {\n            int bestIdx = -1;\n            int bestDist = 1e9;\n            for (size_t j = 0; j < negPos.size(); ++j) {\n                if (negDemand[j] == 0) continue;\n                int d = manhattan(sources[si].pos, negPos[j]);\n                if (d < bestDist) {\n                    bestDist = d;\n                    bestIdx = (int)j;\n                }\n            }\n            // there must be a negative cell left\n            int give = min(remain, negDemand[bestIdx]);\n            sources[si].deliveries.push_back({negPos[bestIdx], give});\n            remain -= give;\n            negDemand[bestIdx] -= give;\n        }\n        // sort deliveries of this source by distance to the source\n        auto& del = sources[si].deliveries;\n        sort(del.begin(), del.end(),\n             [&](const Delivery& a, const Delivery& b) {\n                 int da = manhattan(sources[si].pos, a.sink);\n                 int db = manhattan(sources[si].pos, b.sink);\n                 return da < db;\n             });\n    }\n\n    // sort sources by row\u2011major order\n    sort(sources.begin(), sources.end(),\n         [&](const Source& a, const Source& b) {\n             int ai = a.pos.r * N + a.pos.c;\n             int bi = b.pos.r * N + b.pos.c;\n             return ai < bi;\n         });\n\n    // -----------------------------------------------------------------\n    // generate the operation list\n    vector<string> ops;\n    Pos cur{0, 0};\n    int curLoad = 0;               // current load of the truck\n\n    for (const auto& src : sources) {\n        // move empty to the source\n        moveTo(cur, src.pos, ops);\n        // load the whole supply\n        ops.emplace_back(\"+\" + to_string(src.total));\n        curLoad = src.total;\n\n        // visit its sinks one after another\n        for (const auto& del : src.deliveries) {\n            moveTo(cur, del.sink, ops);          // moves while loaded\n            ops.emplace_back(\"-\" + to_string(del.amt));\n            curLoad -= del.amt;\n        }\n        // after the last delivery load is zero (guaranteed)\n    }\n\n    // output\n    for (const string& s : ops) cout << s << '\\n';\n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, T;\n    if (!(cin >> N >> M >> T)) return 0;\n    const int S = 2 * N * (N - 1);           // 60\n    vector<vector<int>> seed(S, vector<int>(M));\n    for (int i = 0; i < S; ++i)\n        for (int j = 0; j < M; ++j)\n            cin >> seed[i][j];\n\n    /* ----- pre\u2011compute positions ordered by degree ----- */\n    vector<tuple<int,int,int>> posDeg;       // (degree, i, j)\n    posDeg.reserve(N * N);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int d = (i > 0) + (i < N - 1) + (j > 0) + (j < N - 1);\n            posDeg.emplace_back(d, i, j);\n        }\n    }\n    sort(posDeg.begin(), posDeg.end(),\n         [](const auto& a, const auto& b) {\n             if (get<0>(a) != get<0>(b)) return get<0>(a) > get<0>(b);\n             // tie\u2011break: arbitrary but deterministic\n             return (get<1>(a) + get<2>(a)) < (get<1>(b) + get<2>(b));\n         });\n\n    /* ------------------- main loop ---------------------- */\n    for (int turn = 0; turn < T; ++turn) {\n        /* ----- evaluate current seeds ----- */\n        vector<int> sum(S, 0);\n        vector<int> bestIdx(M, -1);\n        vector<int> bestVal(M, -1);\n        for (int i = 0; i < S; ++i) {\n            int s = 0;\n            for (int j = 0; j < M; ++j) {\n                int v = seed[i][j];\n                s += v;\n                if (v > bestVal[j]) {\n                    bestVal[j] = v;\n                    bestIdx[j] = i;\n                }\n            }\n            sum[i] = s;\n        }\n\n        /* ----- choose 36 parent seeds ----- */\n        vector<char> used(S, 0);\n        vector<int> parents;\n        parents.reserve(36);\n\n        // keep all specialists (different seeds)\n        for (int j = 0; j < M; ++j) {\n            int idx = bestIdx[j];\n            if (idx >= 0 && !used[idx]) {\n                used[idx] = 1;\n                parents.push_back(idx);\n            }\n        }\n\n        // fill the rest with highest\u2011value seeds\n        vector<int> other;\n        other.reserve(S);\n        for (int i = 0; i < S; ++i)\n            if (!used[i]) other.push_back(i);\n        sort(other.begin(), other.end(),\n             [&](int a, int b) { return sum[a] > sum[b]; });\n\n        int need = 36 - (int)parents.size();\n        for (int i = 0; i < need; ++i) parents.push_back(other[i]);\n\n        // exactly 36 parents \u2013 safety check\n        // (the problem guarantees this is always possible)\n        // sort parents by value (best first) for placement\n        sort(parents.begin(), parents.end(),\n             [&](int a, int b) { return sum[a] > sum[b]; });\n\n        /* ----- place them onto the grid ----- */\n        vector<vector<int>> A(N, vector<int>(N, -1));\n        for (int p = 0; p < 36; ++p) {\n            int di, dj;\n            tie(ignore, di, dj) = posDeg[p];\n            A[di][dj] = parents[p];\n        }\n\n        /* ----- output ----- */\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (j) cout << ' ';\n                cout << A[i][j];\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n\n        /* ----- read next generation ----- */\n        vector<vector<int>> nxt(S, vector<int>(M));\n        for (int i = 0; i < S; ++i)\n            for (int j = 0; j < M; ++j)\n                cin >> nxt[i][j];\n        seed.swap(nxt);\n    }\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, V;\n    if (!(cin >> N >> M >> V)) return 0;\n    vector<string> sgrid(N), tgrid(N);\n    for (int i = 0; i < N; ++i) cin >> sgrid[i];\n    for (int i = 0; i < N; ++i) cin >> tgrid[i];\n\n    /* ----- board representation ----- */\n    vector<vector<bool>> has(N, vector<bool>(N, false));\n    vector<pair<int,int>> src;          // squares with a takoyaki that are NOT targets\n    vector<pair<int,int>> emptyTgt;     // target squares that are NOT already occupied\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (sgrid[i][j] == '1') {\n                has[i][j] = true;\n                if (tgrid[i][j] == '0')\n                    src.emplace_back(i, j);\n            }\n            if (tgrid[i][j] == '1') {\n                if (!has[i][j])\n                    emptyTgt.emplace_back(i, j);\n            }\n        }\n    }\n\n    /* ----- tree description (only root + one leaf) ----- */\n    const int Vprime = 2;\n    cout << Vprime << \"\\n\";\n    cout << 0 << ' ' << 1 << \"\\n\";\n    cout << 0 << ' ' << 0 << \"\\n\";\n\n    /* ----- directions ----- */\n    const int dr[4] = {0, 1, 0, -1};\n    const int dc[4] = {1, 0, -1, 0};\n\n    auto move_char = [&](int d)->char {\n        if (d == 0) return 'R';\n        if (d == 1) return 'D';\n        if (d == 2) return 'L';\n        return 'U';\n    };\n    auto dir_from_delta = [&](int drr, int dcc)->int {\n        for (int d = 0; d < 4; ++d)\n            if (dr[d] == drr && dc[d] == dcc) return d;\n        return -1;          // never happens for a legal step\n    };\n\n    /* ----- simulation ----- */\n    vector<string> ops;\n    int root_x = 0, root_y = 0;   // current root position\n    int leaf_dir = 0;             // direction of the leaf (0 = right)\n    bool holding = false;         // does the leaf hold a takoyaki?\n\n    const int INF = 1e9;\n\n    while (!src.empty() || holding) {\n        if (!holding) {\n            // ---------- pick a takoyaki ----------\n            int bestDist = INF, bestIdx = -1;\n            pair<int,int> bestNeighbour{-1,-1};\n            int bestDir = -1;\n\n            for (int i = 0; i < (int)src.size(); ++i) {\n                int sx = src[i].first, sy = src[i].second;\n                for (int d = 0; d < 4; ++d) {\n                    int nx = sx - dr[d];\n                    int ny = sy - dc[d];\n                    if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n                    int dist = abs(root_x - nx) + abs(root_y - ny);\n                    if (dist < bestDist) {\n                        bestDist = dist;\n                        bestIdx = i;\n                        bestNeighbour = {nx, ny};\n                        bestDir = d;\n                    }\n                }\n            }\n\n            // move root to the neighbour\n            while (root_x != bestNeighbour.first || root_y != bestNeighbour.second) {\n                int ddx = 0, ddy = 0;\n                if (root_x < bestNeighbour.first) ddx = 1;\n                else if (root_x > bestNeighbour.first) ddx = -1;\n                if (root_y < bestNeighbour.second) ddy = 1;\n                else if (root_y > bestNeighbour.second) ddy = -1;\n\n                string op(4, '.');\n                if (abs(root_x - bestNeighbour.first) >= abs(root_y - bestNeighbour.second)) {\n                    op[0] = move_char(dir_from_delta(ddx, 0));\n                    root_x += ddx;\n                } else {\n                    op[0] = move_char(dir_from_delta(0, ddy));\n                    root_y += ddy;\n                }\n                ops.push_back(op);\n            }\n\n            // rotate leaf to point to source, then pick\n            int target_dir = bestDir;\n            int cur_dir = leaf_dir;\n            int diff = (target_dir - cur_dir + 4) % 4;\n            int alt = 4 - diff;\n            int steps, rot;\n            if (diff <= alt) { steps = diff; rot = 1; }\n            else             { steps = alt;  rot = -1; }\n\n            if (steps > 0) {\n                for (int i = 0; i < steps - 1; ++i) {\n                    string op(4, '.');\n                    op[1] = (rot == 1 ? 'R' : 'L');\n                    ops.push_back(op);\n                    leaf_dir = (leaf_dir + rot + 4) % 4;\n                }\n                string op(4, '.');\n                op[1] = (rot == 1 ? 'R' : 'L');\n                op[3] = 'P';\n                ops.push_back(op);\n                leaf_dir = (leaf_dir + rot + 4) % 4;\n            } else {\n                string op(4, '.');\n                op[3] = 'P';\n                ops.push_back(op);\n            }\n\n            // update board and source list\n            has[src[bestIdx].first][src[bestIdx].second] = false;\n            src.erase(src.begin() + bestIdx);\n            holding = true;\n        }\n        else {\n            // ---------- place a takoyaki ----------\n            int bestDist = INF, bestIdx = -1;\n            pair<int,int> bestNeighbour{-1,-1};\n            int bestDir = -1;\n\n            for (int i = 0; i < (int)emptyTgt.size(); ++i) {\n                int tx = emptyTgt[i].first, ty = emptyTgt[i].second;\n                for (int d = 0; d < 4; ++d) {\n                    int nx = tx - dr[d];\n                    int ny = ty - dc[d];\n                    if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n                    int dist = abs(root_x - nx) + abs(root_y - ny);\n                    if (dist < bestDist) {\n                        bestDist = dist;\n                        bestIdx = i;\n                        bestNeighbour = {nx, ny};\n                        bestDir = d;\n                    }\n                }\n            }\n\n            // move root to the neighbour\n            while (root_x != bestNeighbour.first || root_y != bestNeighbour.second) {\n                int ddx = 0, ddy = 0;\n                if (root_x < bestNeighbour.first) ddx = 1;\n                else if (root_x > bestNeighbour.first) ddx = -1;\n                if (root_y < bestNeighbour.second) ddy = 1;\n                else if (root_y > bestNeighbour.second) ddy = -1;\n\n                string op(4, '.');\n                if (abs(root_x - bestNeighbour.first) >= abs(root_y - bestNeighbour.second)) {\n                    op[0] = move_char(dir_from_delta(ddx, 0));\n                    root_x += ddx;\n                } else {\n                    op[0] = move_char(dir_from_delta(0, ddy));\n                    root_y += ddy;\n                }\n                ops.push_back(op);\n            }\n\n            // rotate leaf to point to target, then place\n            int target_dir = bestDir;\n            int cur_dir = leaf_dir;\n            int diff = (target_dir - cur_dir + 4) % 4;\n            int alt = 4 - diff;\n            int steps, rot;\n            if (diff <= alt) { steps = diff; rot = 1; }\n            else             { steps = alt;  rot = -1; }\n\n            if (steps > 0) {\n                for (int i = 0; i < steps - 1; ++i) {\n                    string op(4, '.');\n                    op[1] = (rot == 1 ? 'R' : 'L');\n                    ops.push_back(op);\n                    leaf_dir = (leaf_dir + rot + 4) % 4;\n                }\n                string op(4, '.');\n                op[1] = (rot == 1 ? 'R' : 'L');\n                op[3] = 'P';\n                ops.push_back(op);\n                leaf_dir = (leaf_dir + rot + 4) % 4;\n            } else {\n                string op(4, '.');\n                op[3] = 'P';\n                ops.push_back(op);\n            }\n\n            // update board and target list\n            has[emptyTgt[bestIdx].first][emptyTgt[bestIdx].second] = true;\n            emptyTgt.erase(emptyTgt.begin() + bestIdx);\n            holding = false;\n        }\n    }\n\n    /* ----- output the operation sequence ----- */\n    for (const string &s : ops) cout << s << '\\n';\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    if (!(cin >> N)) return 0;\n\n    const int M = 2 * N;\n    vector<pair<int,int>> pts(M);\n    for (int i = 0; i < M; ++i) cin >> pts[i].first >> pts[i].second;\n\n    /* values: first N are mackerels (+1), next N are sardines (-1) */\n    vector<int> val(M);\n    for (int i = 0; i < N; ++i) val[i] = 1;\n    for (int i = N; i < M; ++i) val[i] = -1;\n\n    /* coordinate compression */\n    vector<int> xs, ys;\n    xs.reserve(M); ys.reserve(M);\n    for (auto &p : pts) {\n        xs.push_back(p.first);\n        ys.push_back(p.second);\n    }\n    sort(xs.begin(), xs.end());\n    xs.erase(unique(xs.begin(), xs.end()), xs.end());\n    sort(ys.begin(), ys.end());\n    ys.erase(unique(ys.begin(), ys.end()), ys.end());\n\n    const int X = (int)xs.size();\n    const int Y = (int)ys.size();\n\n    /* 2\u2011D prefix sums */\n    vector<int> pref( (size_t)(X + 1) * (Y + 1), 0 );\n    for (int i = 0; i < M; ++i) {\n        int ix = lower_bound(xs.begin(), xs.end(), pts[i].first) - xs.begin();\n        int iy = lower_bound(ys.begin(), ys.end(), pts[i].second) - ys.begin();\n        pref[ (size_t)(ix + 1) * (Y + 1) + (iy + 1) ] += val[i];\n    }\n    for (int i = 1; i <= X; ++i) {\n        for (int j = 1; j <= Y; ++j) {\n            size_t idx = (size_t)i * (Y + 1) + j;\n            size_t a = (size_t)(i - 1) * (Y + 1) + j;\n            size_t b = (size_t)i * (Y + 1) + (j - 1);\n            size_t c = (size_t)(i - 1) * (Y + 1) + (j - 1);\n            pref[idx] = pref[idx] + pref[a] + pref[b] - pref[c];\n        }\n    }\n\n    /* helper: sum of a rectangle given by exclusive indices */\n    auto rectSum = [&](int l, int r, int b, int t) -> int {\n        // l,r are exclusive on the right, b,t exclusive on the top\n        if (l >= r || b >= t) return 0;\n        size_t idx_rr = (size_t)r * (Y + 1) + t;\n        size_t idx_lr = (size_t)l * (Y + 1) + t;\n        size_t idx_rb = (size_t)r * (Y + 1) + b;\n        size_t idx_lb = (size_t)l * (Y + 1) + b;\n        return (int)(pref[idx_rr] - pref[idx_lr] - pref[idx_rb] + pref[idx_lb]);\n    };\n\n    /* random generator */\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    const int RESTARTS = 80;\n    const int MAX_ITER  = 80;\n\n    int bestValue = -1000000;\n    int bestL = 0, bestR = 1, bestB = 0, bestT = 1;   // fallback\n\n    vector<int> colSum(X), rowSum(Y);\n    vector<int> prefCol(X + 1), prefRow(Y + 1);\n\n    for (int restart = 0; restart < RESTARTS; ++restart) {\n        int leftIdx, rightIdx, bottomIdx, topIdx;\n\n        if (restart == 0) {                     // whole rectangle\n            leftIdx   = 0;\n            rightIdx  = X;\n            bottomIdx = 0;\n            topIdx    = Y;\n        } else {\n            leftIdx   = uniform_int_distribution<int>(0, X - 1)(rng);\n            rightIdx  = uniform_int_distribution<int>(leftIdx + 1, X)(rng);\n            bottomIdx = uniform_int_distribution<int>(0, Y - 1)(rng);\n            topIdx    = uniform_int_distribution<int>(bottomIdx + 1, Y)(rng);\n        }\n\n        int curValue = rectSum(leftIdx, rightIdx, bottomIdx, topIdx);\n        int bestValueRestart = curValue;\n        int bestLr = xs[leftIdx], bestRr = (rightIdx > 0 ? xs[rightIdx - 1] : xs[0]);\n        int bestBr = ys[bottomIdx], bestTr = (topIdx > 0 ? ys[topIdx - 1] : ys[0]);\n\n        for (int it = 0; it < MAX_ITER; ++it) {\n            /* ----- compute column sums and row sums for current y\u2011interval ----- */\n            int b = bottomIdx, t = topIdx;\n            for (int i = 0; i < X; ++i) {\n                // sum of column i between rows b \u2026 t\u20111\n                colSum[i] = pref[(size_t)(i + 1) * (Y + 1) + t]\n                          - pref[(size_t)(i + 1) * (Y + 1) + b]\n                          - pref[(size_t)i * (Y + 1) + t]\n                          + pref[(size_t)i * (Y + 1) + b];\n            }\n            int l = leftIdx, r = rightIdx;\n            for (int j = 0; j < Y; ++j) {\n                // sum of row j between columns l \u2026 r\u20111\n                rowSum[j] = pref[(size_t)r * (Y + 1) + (j + 1)]\n                          - pref[(size_t)l * (Y + 1) + (j + 1)]\n                          - pref[(size_t)r * (Y + 1) + j]\n                          + pref[(size_t)l * (Y + 1) + j];\n            }\n\n            /* ----- one\u2011dimensional prefix sums ----- */\n            prefCol[0] = 0;\n            for (int i = 0; i < X; ++i) prefCol[i + 1] = prefCol[i] + colSum[i];\n            prefRow[0] = 0;\n            for (int j = 0; j < Y; ++j) prefRow[j + 1] = prefRow[j] + rowSum[j];\n\n            /* ----- choose the best side move ----- */\n            int bestGain = 0;\n            int bestSide = -1;   // 0:left, 1:right, 2:bottom, 3:top\n            int bestNewIdx = -1;\n\n            // left side\n            for (int nl = 0; nl < rightIdx; ++nl) {\n                if (nl == leftIdx) continue;\n                int gain = prefCol[leftIdx] - prefCol[nl];\n                if (gain > bestGain) {\n                    bestGain = gain; bestSide = 0; bestNewIdx = nl;\n                }\n            }\n            // right side\n            for (int nr = leftIdx + 1; nr <= X; ++nr) {\n                if (nr == rightIdx) continue;\n                int gain = prefCol[nr] - prefCol[rightIdx];\n                if (gain > bestGain) {\n                    bestGain = gain; bestSide = 1; bestNewIdx = nr;\n                }\n            }\n            // bottom side\n            for (int nb = 0; nb < topIdx; ++nb) {\n                if (nb == bottomIdx) continue;\n                int gain = prefRow[bottomIdx] - prefRow[nb];\n                if (gain > bestGain) {\n                    bestGain = gain; bestSide = 2; bestNewIdx = nb;\n                }\n            }\n            // top side\n            for (int nt = bottomIdx + 1; nt <= Y; ++nt) {\n                if (nt == topIdx) continue;\n                int gain = prefRow[nt] - prefRow[topIdx];\n                if (gain > bestGain) {\n                    bestGain = gain; bestSide = 3; bestNewIdx = nt;\n                }\n            }\n\n            if (bestGain <= 0) break;          // local optimum\n\n            // apply the move\n            switch (bestSide) {\n                case 0: leftIdx   = bestNewIdx; break;\n                case 1: rightIdx  = bestNewIdx; break;\n                case 2: bottomIdx = bestNewIdx; break;\n                case 3: topIdx    = bestNewIdx; break;\n            }\n            curValue += bestGain;\n\n            if (curValue > bestValueRestart) {\n                bestValueRestart = curValue;\n                bestLr = xs[leftIdx];\n                bestRr = (rightIdx > 0 ? xs[rightIdx - 1] : xs[0]);\n                bestBr = ys[bottomIdx];\n                bestTr = (topIdx > 0 ? ys[topIdx - 1] : ys[0]);\n            }\n        }\n\n        if (bestValueRestart > bestValue) {\n            bestValue = bestValueRestart;\n            bestL = bestLr; bestR = bestRr;\n            bestB = bestBr; bestT = bestTr;\n        }\n    }\n\n    /* ----- output the rectangle as a polygon ----- */\n    cout << 4 << '\\n';\n    cout << bestL << ' ' << bestB << '\\n';\n    cout << bestR << ' ' << bestB << '\\n';\n    cout << bestR << ' ' << bestT << '\\n';\n    cout << bestL << ' ' << bestT << '\\n';\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\n\nstruct Candidate {\n    bool skip;          // true \u2192 skip this rectangle\n    int rot;            // 0 = not rotated, 1 = rotated\n    char dir;           // 'U' or 'L'\n    int ref;            // -1 or index of a previously placed rectangle\n    ll sum;             // heuristic score (width+height+penalty)\n    ll x, y, w, h;      // coordinates and size (valid only if !skip)\n};\n\nstruct PlacedRect {\n    ll x, y, w, h;\n    int idx;            // original index\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, T;\n    long long sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n    vector<ll> mw(N), mh(N);                 // measured sizes\n    for (int i = 0; i < N; ++i) cin >> mw[i] >> mh[i];\n\n    // random generator \u2013 deterministic but different each turn\n    std::mt19937 rng(123456789);\n\n    // -------------------------------------------------------------\n    // process each turn\n    for (int turn = 0; turn < T; ++turn) {\n        // current state\n        vector<int> placedIdx;                     // indices of placed rectangles\n        vector<ll> X(N, 0), Y(N, 0), W(N, 0), H(N, 0);\n        vector<char> used(N, 0);\n        ll curW = 0, curH = 0;                      // current bounding box\n        ll penalty = 0;                             // sum of skipped measured sizes\n\n        vector<tuple<int,int,char,int>> answer;     // (p, r, d, b)\n\n        // ---------------------------------------------------------\n        // greedy construction rectangle after rectangle\n        for (int i = 0; i < N; ++i) {\n            vector<Candidate> cand;\n\n            // ----  skip candidate  --------------------------------\n            ll pen_i = mw[i] + mh[i];\n            cand.push_back({true, 0, '?', -1,\n                            curW + curH + penalty + pen_i,\n                            0,0,0,0});\n\n            // ----  placement candidates  ---------------------------\n            // collect possible references (already placed rectangles)\n            vector<int> refs;\n            refs.push_back(-1);\n            if (!placedIdx.empty()) {\n                refs.push_back(placedIdx.back());          // the last one\n                // a few random ones\n                for (int qq = 0; qq < 3; ++qq) {\n                    int r = placedIdx[uniform_int_distribution<int>(0, (int)placedIdx.size()-1)(rng)];\n                    if (find(refs.begin(), refs.end(), r) == refs.end())\n                        refs.push_back(r);\n                }\n            }\n\n            // try both rotations\n            for (int rot = 0; rot <= 1; ++rot) {\n                ll wi = rot ? mh[i] : mw[i];\n                ll hi = rot ? mw[i] : mh[i];\n\n                // both directions\n                for (char dir : {'U', 'L'}) {\n                    for (int ref : refs) {\n                        ll nx, ny;\n                        if (dir == 'U') {\n                            ll left = (ref == -1) ? 0 : X[ref] + W[ref];\n                            ll highest = 0;\n                            for (int k : placedIdx) {\n                                // overlap in x ?\n                                if (X[k] < left + wi && X[k] + W[k] > left) {\n                                    highest = max(highest, Y[k] + H[k]);\n                                }\n                            }\n                            nx = left;\n                            ny = highest;               // may be 0\n                        } else { // 'L'\n                            ll top = (ref == -1) ? 0 : Y[ref] + H[ref];\n                            ll rightmost = 0;\n                            for (int k : placedIdx) {\n                                // overlap in y ?\n                                if (Y[k] < top + hi && Y[k] + H[k] > top) {\n                                    rightmost = max(rightmost, X[k] + W[k]);\n                                }\n                            }\n                            ll tmp = rightmost - wi;\n                            nx = tmp < 0 ? 0 : tmp;\n                            ny = top;\n                        }\n                        ll nw = max(curW, nx + wi);\n                        ll nh = max(curH, ny + hi);\n                        ll sc = nw + nh + penalty;      // score after placing\n                        cand.push_back({false, rot, dir, ref, sc, nx, ny, wi, hi});\n                    }\n                }\n            }\n\n            // ----  choose best (or one of the best three)  -------\n            sort(cand.begin(), cand.end(),\n                 [](const Candidate& a, const Candidate& b){ return a.sum < b.sum; });\n            int topK = min(3, (int)cand.size());\n            int chosen = uniform_int_distribution<int>(0, topK-1)(rng);\n            const Candidate& c = cand[chosen];\n\n            if (c.skip) {\n                // skip this rectangle\n                penalty += pen_i;\n                // nothing is added to the answer\n            } else {\n                // place it\n                answer.emplace_back(i, c.dir == 'U' ? (c.rot ? 1 : 0) : (c.rot ? 1 : 0),\n                                   c.dir, c.ref);\n                // store data for later references\n                X[i] = c.x; Y[i] = c.y; W[i] = c.w; H[i] = c.h;\n                used[i] = 1;\n                placedIdx.push_back(i);\n                curW = max(curW, c.x + c.w);\n                curH = max(curH, c.y + c.h);\n            }\n        } // end for each rectangle\n\n        // -------------------------------------------------------------\n        // output the description\n        cout << answer.size() << '\\n';\n        for (auto [p, r, d, b] : answer) {\n            cout << p << ' ' << r << ' ' << d << ' ' << b << '\\n';\n        }\n        cout << flush;\n\n        // read the noisy measurement (not used)\n        long long Wobs, Hobs;\n        cin >> Wobs >> Hobs;\n    }\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\n#include <atcoder/mcf_graph>\n\nusing namespace std;\nusing ll = long long;\nusing mcf = atcoder::mcf_graph<int, ll>;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, H;\n    if (!(cin >> N >> M >> H)) return 0;\n    vector<int> A(N);\n    for (int i = 0; i < N; ++i) cin >> A[i];\n    vector<pair<int,int>> edges(M);\n    for (int i = 0; i < M; ++i) {\n        int u, v; cin >> u >> v;\n        edges[i] = {u, v};\n    }\n    // coordinates are irrelevant for the algorithm\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n    }\n\n    // adjacency of the original graph\n    vector<vector<int>> adj(N);\n    for (auto [u,v] : edges) {\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n\n    const int C = N * (H + 1);           // number of copies\n    const int S = 0;\n    const int G0 = 1;                     // first group vertex node\n    const int COPY0 = G0 + N;             // first copy node\n    const int T = COPY0 + C;              // sink\n    const int V = T + 1;                 // total vertices in the flow graph\n\n    mcf g(V);\n\n    // store edge ids for later retrieval\n    vector<vector<int>> edgeId(N, vector<int>(H + 1, -1));\n    // outgoing edge ids from each copy node (index = copy - COPY0)\n    vector<vector<int>> outCopy(C);\n\n    const int INF_CAP = N;                // enough, flow never exceeds N\n\n    // source -> group\n    for (int v = 0; v < N; ++v) {\n        g.add_edge(S, G0 + v, 1, 0);\n    }\n\n    // group -> copy (choice of depth)\n    for (int v = 0; v < N; ++v) {\n        for (int d = 0; d <= H; ++d) {\n            int copyNode = COPY0 + v * (H + 1) + d;\n            ll cost = - (ll)(d + 1) * A[v];\n            int eid = g.add_edge(G0 + v, copyNode, 1, cost);\n            edgeId[v][d] = eid;\n        }\n    }\n\n    // copy -> parent copy (for d > 0)   and copy -> sink (for d == 0)\n    for (int v = 0; v < N; ++v) {\n        for (int d = 0; d <= H; ++d) {\n            int copyNode = COPY0 + v * (H + 1) + d;\n            if (d == 0) {\n                // to sink\n                int eid = g.add_edge(copyNode, T, INF_CAP, 0);\n                outCopy[copyNode - COPY0].push_back(eid);\n            } else {\n                // to neighbours at depth d-1\n                for (int u : adj[v]) {\n                    int parentCopy = COPY0 + u * (H + 1) + (d - 1);\n                    int eid = g.add_edge(copyNode, parentCopy, INF_CAP, 0);\n                    outCopy[copyNode - COPY0].push_back(eid);\n                }\n            }\n        }\n    }\n\n    // minimum cost flow of value N\n    auto result = g.flow(S, T, N);\n    int flow = result.first;\n    // guaranteed to be N because a solution exists (all vertices can be roots)\n    if (flow != N) return 0;   // should not happen\n\n    // reconstruction\n    vector<int> parent(N, -2);   // -2 = not set yet, -1 = root\n    vector<int> depth(N, -1);\n\n    for (int v = 0; v < N; ++v) {\n        // which depth was chosen ?\n        for (int d = 0; d <= H; ++d) {\n            int eid = edgeId[v][d];\n            if (g.edge(eid).flow > 0) {\n                depth[v] = d;\n                break;\n            }\n        }\n        if (depth[v] == -1) continue; // should not happen\n\n        if (depth[v] == 0) {\n            parent[v] = -1;               // root\n            continue;\n        }\n\n        int copyNode = COPY0 + v * (H + 1) + depth[v];\n        // find the outgoing edge that carries the flow\n        for (int eid : outCopy[copyNode - COPY0]) {\n            if (g.edge(eid).flow > 0) {\n                int to = g.edge(eid).to;\n                if (to == T) {          // depth 0 would have gone here, but we are d>0\n                    parent[v] = -1;\n                } else {\n                    int pu = (to - COPY0) / (H + 1);   // parent vertex\n                    parent[v] = pu;\n                }\n                break;\n            }\n        }\n    }\n\n    // output\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << parent[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Set {\n    bool isRow;          // true \u2192 row, false \u2192 column\n    int idx;             // row number or column number\n    char dir;            // 'L','R','U','D'\n    uint64_t mask;       // bitmask of Oni indices contained in the set\n    int cost;            // number of shifts\n};\n\nint N;                                     // board size (20)\nvector<string> board;                      // input board\nint oniIdx[20][20];                        // index of Oni, -1 if none\nbool fuku[20][20];                         // true if Fukunokami\n\nint leftMostF[20], rightMostF[20];\nint topMostF[20], bottomMostF[20];\n\nvector<Set> sets;\nvector<vector<int>> oniToSets;             // for each Oni, list of set ids\n\nint M;                                     // number of Oni\nuint64_t allMask;\n\nint bestCost;\nvector<int> bestSets;\nvector<int> curSets;\nbool rowUsed[20] = {false};\nbool colUsed[20] = {false};\n\nvoid dfs(uint64_t mask, int cost) {\n    if (mask == allMask) {\n        if (cost < bestCost) {\n            bestCost = cost;\n            bestSets = curSets;\n        }\n        return;\n    }\n    if (cost >= bestCost) return;\n    int remain = __builtin_popcountll(~mask & allMask);\n    if (cost + remain >= bestCost) return; // even with 1 per oni we cannot beat\n\n    // choose uncovered Oni with smallest number of candidate sets\n    uint64_t rem = ~mask & allMask;\n    int chosenOni = -1;\n    int minOpts = 100;\n    for (uint64_t sub = rem; sub; sub &= sub - 1) {\n        int idx = __builtin_ctzll(sub);\n        int opts = 0;\n        for (int sid : oniToSets[idx]) {\n            const Set &s = sets[sid];\n            if (s.isRow && rowUsed[s.idx]) continue;\n            if (!s.isRow && colUsed[s.idx]) continue;\n            if (mask & s.mask) continue;          // already covered by chosen sets\n            ++opts;\n        }\n        if (opts == 0) return;                     // dead end (should not happen)\n        if (opts < minOpts) {\n            minOpts = opts;\n            chosenOni = idx;\n            if (minOpts == 1) break;\n        }\n    }\n    if (chosenOni == -1) return;                  // cannot cover\n\n    for (int sid : oniToSets[chosenOni]) {\n        const Set &s = sets[sid];\n        if (s.isRow && rowUsed[s.idx]) continue;\n        if (!s.isRow && colUsed[s.idx]) continue;\n        if (mask & s.mask) continue;              // overlap \u2013 already covered\n        // choose this set\n        if (s.isRow) rowUsed[s.idx] = true;\n        else         colUsed[s.idx] = true;\n        curSets.push_back(sid);\n        dfs(mask | s.mask, cost + s.cost);\n        curSets.pop_back();\n        if (s.isRow) rowUsed[s.idx] = false;\n        else         colUsed[s.idx] = false;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N;\n    board.resize(N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n\n    // locate Oni and Fukunokami, initialise arrays\n    memset(oniIdx, -1, sizeof(oniIdx));\n    memset(fuku, 0, sizeof(fuku));\n    vector<pair<int,int>> oniPos;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 'x')\n                oniIdx[i][j] = (int)oniPos.size(),\n                oniPos.emplace_back(i, j);\n            else if (board[i][j] == 'o')\n                fuku[i][j] = true;\n        }\n    M = (int)oniPos.size();                // = 2\u00b7N\n    allMask = (M == 64) ? ~0ULL : ((1ULL<<M) - 1ULL);\n\n    // left / right most Fukunokami in each row\n    const int INF = N+5;\n    for (int i = 0; i < N; ++i) {\n        leftMostF[i] = INF; rightMostF[i] = -1;\n        for (int j = 0; j < N; ++j)\n            if (fuku[i][j]) {\n                leftMostF[i] = min(leftMostF[i], j);\n                rightMostF[i] = max(rightMostF[i], j);\n            }\n    }\n    // top / bottom most Fukunokami in each column\n    for (int j = 0; j < N; ++j) {\n        topMostF[j] = INF; bottomMostF[j] = -1;\n        for (int i = 0; i < N; ++i)\n            if (fuku[i][j]) {\n                topMostF[j] = min(topMostF[j], i);\n                bottomMostF[j] = max(bottomMostF[j], i);\n            }\n    }\n\n    // build the sets\n    for (int i = 0; i < N; ++i) {\n        vector<int> idsL, idsR;\n        int maxJ = -1, minJ = INF;\n        for (int j = 0; j < N; ++j) {\n            int id = oniIdx[i][j];\n            if (id == -1) continue;\n            bool leftClear = (leftMostF[i] == INF) || (leftMostF[i] > j);\n            bool rightClear = (rightMostF[i] == -1) || (rightMostF[i] < j);\n            if (leftClear) {\n                idsL.push_back(id);\n                maxJ = max(maxJ, j);\n            }\n            if (rightClear) {\n                idsR.push_back(id);\n                minJ = min(minJ, j);\n            }\n        }\n        if (!idsL.empty()) {\n            Set s; s.isRow = true; s.idx = i; s.dir = 'L';\n            s.cost = maxJ + 1;\n            s.mask = 0;\n            for (int id : idsL) s.mask |= (1ULL<<id);\n            sets.push_back(s);\n        }\n        if (!idsR.empty()) {\n            Set s; s.isRow = true; s.idx = i; s.dir = 'R';\n            s.cost = N - minJ;\n            s.mask = 0;\n            for (int id : idsR) s.mask |= (1ULL<<id);\n            sets.push_back(s);\n        }\n    }\n    for (int j = 0; j < N; ++j) {\n        vector<int> idsU, idsD;\n        int maxI = -1, minI = INF;\n        for (int i = 0; i < N; ++i) {\n            int id = oniIdx[i][j];\n            if (id == -1) continue;\n            bool upClear   = (topMostF[j] == INF) || (topMostF[j] > i);\n            bool downClear = (bottomMostF[j] == -1) || (bottomMostF[j] < i);\n            if (upClear) {\n                idsU.push_back(id);\n                maxI = max(maxI, i);\n            }\n            if (downClear) {\n                idsD.push_back(id);\n                minI = min(minI, i);\n            }\n        }\n        if (!idsU.empty()) {\n            Set s; s.isRow = false; s.idx = j; s.dir = 'U';\n            s.cost = maxI + 1;\n            s.mask = 0;\n            for (int id : idsU) s.mask |= (1ULL<<id);\n            sets.push_back(s);\n        }\n        if (!idsD.empty()) {\n            Set s; s.isRow = false; s.idx = j; s.dir = 'D';\n            s.cost = N - minI;\n            s.mask = 0;\n            for (int id : idsD) s.mask |= (1ULL<<id);\n            sets.push_back(s);\n        }\n    }\n\n    // mapping Oni -> sets\n    oniToSets.assign(M, {});\n    for (int sid = 0; sid < (int)sets.size(); ++sid) {\n        uint64_t m = sets[sid].mask;\n        while (m) {\n            int b = __builtin_ctzll(m);\n            oniToSets[b].push_back(sid);\n            m &= m-1;\n        }\n    }\n    // sort by cost (ascending) \u2013 helps the search\n    for (auto &vec : oniToSets) {\n        sort(vec.begin(), vec.end(),\n             [&](int a, int b){ return sets[a].cost < sets[b].cost; });\n    }\n\n    // upper bound = sum of individual minima (one\u2011by\u2011one removal)\n    int upper = 0;\n    for (int id = 0; id < M; ++id) {\n        int i = oniPos[id].first;\n        int j = oniPos[id].second;\n        int best = N+5;\n        bool leftClear = (leftMostF[i] == INF) || (leftMostF[i] > j);\n        bool rightClear= (rightMostF[i]==-1) || (rightMostF[i] < j);\n        bool upClear   = (topMostF[j] == INF) || (topMostF[j] > i);\n        bool downClear = (bottomMostF[j]==-1)|| (bottomMostF[j] < i);\n        if (leftClear)  best = min(best, j+1);\n        if (rightClear) best = min(best, N-j);\n        if (upClear)    best = min(best, i+1);\n        if (downClear)  best = min(best, N-i);\n        upper += best;\n    }\n    bestCost = upper;\n    // start search\n    dfs(0ULL, 0);\n\n    // produce output \u2013 column sets first, then row sets\n    vector<int> colSetIds, rowSetIds;\n    for (int sid : bestSets) {\n        if (!sets[sid].isRow) colSetIds.push_back(sid);\n        else                  rowSetIds.push_back(sid);\n    }\n\n    // output moves\n    ostringstream out;\n    for (int sid : colSetIds) {\n        const Set &s = sets[sid];\n        for (int k = 0; k < s.cost; ++k)\n            out << s.dir << ' ' << s.idx << '\\n';\n    }\n    for (int sid : rowSetIds) {\n        const Set &s = sets[sid];\n        for (int k = 0; k < s.cost; ++k)\n            out << s.dir << ' ' << s.idx << '\\n';\n    }\n    cout << out.str();\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    long long L;\n    if (!(cin >> N >> L)) return 0;\n    vector<int> T(N);\n    for (int i = 0; i < N; ++i) cin >> T[i];\n\n    // -------- adjust T[0] = 0  (error 2 is optimal) ----------\n    vector<int> t = T;\n    if (t[0] == 0) {\n        int j = -1;\n        for (int i = 1; i < N; ++i) if (t[i] > 0) { j = i; break; }\n        // there must be such j because sum = L > 0\n        t[0] = 1;\n        t[j]--;\n    }\n\n    // ----- pre\u2011compute how many odd / even edges each vertex has -----\n    vector<int> oddWeight(N), evenWeight(N);\n    for (int i = 0; i < N; ++i) {\n        oddWeight[i]  = (t[i] + 1) / 2;          // ceil\n        evenWeight[i] = t[i] / 2;                // floor\n    }\n\n    // ----- data for the walk construction -----\n    vector<int> need = t;                       // remaining indegrees\n    vector<int> vis(N, 0);                       // how many times a vertex has been visited\n    vector<int> a(N, -1), b(N, -1);              // targets, -1 = not fixed yet\n    vector<int> usedOdd(N, 0), usedEven(N, 0);   // how many edges of each kind have already been used\n\n    int cur = 0;\n    vis[0] = 1;\n    need[0]--;                                   // first week\n\n    for (long long week = 2; week <= L; ++week) {\n        // decide which kind of edge is needed now\n        bool odd = (vis[cur] % 2 == 1);          // after vis[cur] visits, parity is odd \u2192 need odd edge\n        if (odd) {\n            if (a[cur] == -1) {\n                // choose a target with enough remaining capacity\n                int target = -1;\n                for (int i = 0; i < N; ++i) {\n                    if (need[i] >= oddWeight[cur]) {\n                        target = i;\n                        break;\n                    }\n                }\n                // target must exist\n                a[cur] = target;\n            }\n            cur = a[cur];\n        } else {\n            if (b[cur] == -1) {\n                int target = -1;\n                for (int i = 0; i < N; ++i) {\n                    if (need[i] >= evenWeight[cur]) {\n                        target = i;\n                        break;\n                    }\n                }\n                b[cur] = target;\n            }\n            cur = b[cur];\n        }\n        ++vis[cur];\n        --need[cur];\n    }\n\n    // set default values for edges that never had to be fixed\n    for (int i = 0; i < N; ++i) {\n        if (a[i] == -1) a[i] = i;   // never used odd edge \u2192 self loop\n        if (b[i] == -1) b[i] = i;   // never used even edge \u2192 self loop\n    }\n\n    // --------------- output --------------------\n    for (int i = 0; i < N; ++i) {\n        cout << a[i] << ' ' << b[i] << \"\\n\";\n    }\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v;\n    int approx;          // distance between rectangle centres\n};\n\nint N, M, Q, L, W;\nvector<int> G;\nvector<int> lx, rx, ly, ry;\nvector<int> cx, cy;                     // centre of rectangle\nvector<vector<int>> approxDist;         // heuristic distance matrix\n\n// candidate edges for every group\nvector<vector<Edge>> candEdges;\n\n// ---------------------------------------------------------------\n// ask a query, read the answer and store the edges\nvoid query(const vector<int>& nodes, int gid) {\n    int sz = (int)nodes.size();\n    cout << \"? \" << sz;\n    for (int v : nodes) cout << ' ' << v;\n    cout << \"\\n\";\n    cout.flush();                       // required\n\n    for (int i = 0; i < sz - 1; ++i) {\n        int a, b;\n        cin >> a >> b;\n        Edge e{a, b, approxDist[a][b]};\n        candEdges[gid].push_back(e);\n    }\n}\n\n// ---------------------------------------------------------------\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------- input ---------- */\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    lx.resize(N); rx.resize(N); ly.resize(N); ry.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n    }\n\n    /* ---------- centre of rectangles ---------- */\n    cx.resize(N); cy.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cx[i] = (lx[i] + rx[i]) / 2;\n        cy[i] = (ly[i] + ry[i]) / 2;\n    }\n\n    /* ---------- heuristic distance matrix ---------- */\n    approxDist.assign(N, vector<int>(N, 0));\n    for (int i = 0; i < N; ++i) {\n        for (int j = i + 1; j < N; ++j) {\n            long long dx = (long long)cx[i] - cx[j];\n            long long dy = (long long)cy[i] - cy[j];\n            int d = (int)floor(sqrt((double)dx * dx + (double)dy * dy) + 1e-9);\n            approxDist[i][j] = approxDist[j][i] = d;\n        }\n    }\n\n    /* ---------- build groups (sorted by centre) ---------- */\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(),\n         [&](int a, int b) {\n             if (cx[a] != cx[b]) return cx[a] < cx[b];\n             return cy[a] < cy[b];\n         });\n\n    vector<vector<int>> groups(M);\n    int pos = 0;\n    for (int g = 0; g < M; ++g) {\n        groups[g].reserve(G[g]);\n        for (int i = 0; i < G[g]; ++i) groups[g].push_back(order[pos++]);\n    }\n\n    candEdges.assign(M, {});\n    int used = 0;          // queries already performed\n\n    /* ---------- baseline queries ---------- */\n    for (int gid = 0; gid < M; ++gid) {\n        int sz = (int)groups[gid].size();\n        if (sz <= 1) continue;\n        if (sz == 2) continue;                     // no query needed\n        if (sz <= L) {                               // whole group\n            query(groups[gid], gid);\n            ++used;\n        } else {                                     // sliding window\n            int i = 0;\n            while (i + L <= sz) {\n                vector<int> sub(L);\n                for (int j = 0; j < L; ++j) sub[j] = groups[gid][i + j];\n                query(sub, gid);\n                ++used;\n                i += L - 1;\n            }\n            if (i < sz - 1) {\n                int rem = sz - i;\n                vector<int> sub(rem);\n                for (int j = 0; j < rem; ++j) sub[j] = groups[gid][i + j];\n                query(sub, gid);\n                ++used;\n            }\n        }\n    }\n\n    /* ---------- extra queries (if budget left) ---------- */\n    int leftover = Q - used;\n    // groups that are still interesting (size >= 3)\n    vector<int> bigGroups;\n    for (int gid = 0; gid < M; ++gid)\n        if ((int)groups[gid].size() >= 3) bigGroups.push_back(gid);\n    // order them by decreasing size \u2013 larger groups get extra queries first\n    sort(bigGroups.begin(), bigGroups.end(),\n         [&](int a, int b) { return groups[a].size() > groups[b].size(); });\n\n    std::mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n\n    int idx = 0;\n    while (leftover > 0 && !bigGroups.empty()) {\n        int gid = bigGroups[idx % bigGroups.size()];\n        int gsz = (int)groups[gid].size();\n        int qsz = min(L, gsz);\n\n        // random subset of size qsz\n        vector<int> idxs(gsz);\n        iota(idxs.begin(), idxs.end(), 0);\n        shuffle(idxs.begin(), idxs.end(), rng);\n        vector<int> sub(qsz);\n        for (int t = 0; t < qsz; ++t) sub[t] = groups[gid][idxs[t]];\n\n        query(sub, gid);\n        ++used;\n        --leftover;\n        ++idx;\n    }\n\n    /* ---------- build final spanning trees (Kruskal) ---------- */\n    vector<vector<pair<int,int>>> answerEdges(M);\n\n    for (int gid = 0; gid < M; ++gid) {\n        int sz = (int)groups[gid].size();\n        if (sz <= 1) continue;\n        if (sz == 2) {\n            answerEdges[gid].push_back({groups[gid][0], groups[gid][1]});\n            continue;\n        }\n\n        auto &edges = candEdges[gid];\n        sort(edges.begin(), edges.end(),\n             [&](const Edge& a, const Edge& b){ return a.approx < b.approx; });\n\n        // mapping city -> local index inside the group\n        vector<int> localId(N, -1);\n        for (int i = 0; i < sz; ++i) localId[groups[gid][i]] = i;\n\n        vector<int> parent(sz), rankv(sz, 0);\n        iota(parent.begin(), parent.end(), 0);\n        function<int(int)> find = [&](int x) {\n            while (parent[x] != x) {\n                parent[x] = parent[parent[x]];\n                x = parent[x];\n            }\n            return x;\n        };\n        auto unite = [&](int a, int b) -> bool {\n            a = find(a); b = find(b);\n            if (a == b) return false;\n            if (rankv[a] < rankv[b]) swap(a, b);\n            parent[b] = a;\n            if (rankv[a] == rankv[b]) ++rankv[a];\n            return true;\n        };\n\n        int taken = 0;\n        for (const Edge& e : edges) {\n            int u = localId[e.u];\n            int v = localId[e.v];\n            if (unite(u, v)) {\n                answerEdges[gid].push_back({e.u, e.v});\n                ++taken;\n                if (taken == sz - 1) break;\n            }\n        }\n    }\n\n    /* ---------- output ---------- */\n    cout << \"!\\n\";\n    for (int gid = 0; gid < M; ++gid) {\n        for (size_t i = 0; i < groups[gid].size(); ++i) {\n            if (i) cout << ' ';\n            cout << groups[gid][i];\n        }\n        cout << \"\\n\";\n        for (auto &e : answerEdges[gid]) {\n            cout << e.first << ' ' << e.second << \"\\n\";\n        }\n    }\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;                         // N = 20, M = 40\nint totalPos;                    // N * N   ( = 400 )\nint totalStates;                 // totalPos * (totalPos + 1)\n\nconst int dr[4] = {-1, 1, 0, 0};\nconst int dc[4] = {0, 0, -1, 1};\nconst char dirc[4] = {'U', 'D', 'L', 'R'};\n\nvector<int> dist;                // distance in the state graph\nvector<int> parent;              // predecessor state\nvector<pair<char,char>> act;    // action + direction stored for each state\n\n/*---------------------------------------------------------------*/\n/* BFS that returns the shortest action sequence from (sr,sc)\n   to (tr,tc) while leaving no block on the board                */\nbool bfs(int sr, int sc, int tr, int tc,\n         vector<pair<char,char>>& out)\n{\n    if (sr == tr && sc == tc) { out.clear(); return true; }\n\n    int startIdx = sr * N + sc;\n    int targetIdx = tr * N + tc;\n\n    const int startState = startIdx * (totalPos + 1);          // block = none\n    const int targetState = targetIdx * (totalPos + 1);\n\n    fill(dist.begin(),   dist.end(),   -1);\n    fill(parent.begin(), parent.end(), -1);\n\n    queue<int> q;\n    dist[startState] = 0;\n    q.push(startState);\n\n    while (!q.empty()) {\n        int cur = q.front(); q.pop();\n        if (cur == targetState) break;               // reached\n\n        int posIdx   = cur / (totalPos + 1);\n        int blockSt  = cur % (totalPos + 1);          // 0 = none, else cell+1\n        int r = posIdx / N;\n        int c = posIdx % N;\n        int blockIdx = blockSt - 1;                  // -1 = none, else cell id\n\n        /* ---- Move ------------------------------------------------*/\n        for (int d = 0; d < 4; ++d) {\n            int nr = r + dr[d], nc = c + dc[d];\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n            int nIdx = nr * N + nc;\n            if (blockIdx == nIdx) continue;          // blocked\n            int ns = nIdx * (totalPos + 1) + blockSt;\n            if (dist[ns] == -1) {\n                dist[ns] = dist[cur] + 1;\n                parent[ns] = cur;\n                act[ns] = {'M', dirc[d]};\n                q.push(ns);\n            }\n        }\n\n        /* ---- Slide ----------------------------------------------*/\n        for (int d = 0; d < 4; ++d) {\n            int tr_ = r, tc_ = c;\n            while (true) {\n                int nr = tr_ + dr[d];\n                int nc = tc_ + dc[d];\n                if (nr < 0 || nr >= N || nc < 0 || nc >= N) break; // border\n                int nIdx = nr * N + nc;\n                if (blockIdx != -1 && nIdx == blockIdx) break;    // block\n                tr_ = nr; tc_ = nc;\n            }\n            int destIdx = tr_ * N + tc_;\n            int ns = destIdx * (totalPos + 1) + blockSt;\n            if (dist[ns] == -1) {\n                dist[ns] = dist[cur] + 1;\n                parent[ns] = cur;\n                act[ns] = {'S', dirc[d]};\n                q.push(ns);\n            }\n        }\n\n        /* ---- Alter (place / remove block) -----------------------*/\n        for (int d = 0; d < 4; ++d) {\n            int nr = r + dr[d], nc = c + dc[d];\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n            int neighIdx = nr * N + nc;\n            int newBlockSt;\n            if (blockIdx != -1 && neighIdx == blockIdx) {\n                newBlockSt = 0;                         // remove\n            } else if (blockIdx == -1) {\n                newBlockSt = neighIdx + 1;             // place\n            } else {\n                continue;                               // a block already elsewhere\n            }\n            int ns = posIdx * (totalPos + 1) + newBlockSt;\n            if (dist[ns] == -1) {\n                dist[ns] = dist[cur] + 1;\n                parent[ns] = cur;\n                act[ns] = {'A', dirc[d]};\n                q.push(ns);\n            }\n        }\n    }\n\n    if (dist[targetState] == -1) return false;   // should never happen\n\n    /* reconstruct the path */\n    vector<pair<char,char>> rev;\n    int cur = targetState;\n    while (cur != startState) {\n        rev.push_back(act[cur]);\n        cur = parent[cur];\n    }\n    reverse(rev.begin(), rev.end());\n    out = move(rev);\n    return true;\n}\n\n/*---------------------------------------------------------------*/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M;                     // N = 20 , M = 40\n    vector<pair<int,int>> pt(M + 1);\n    for (int i = 0; i <= M; ++i) cin >> pt[i].first >> pt[i].second;\n\n    totalPos    = N * N;               // 400\n    totalStates = totalPos * (totalPos + 1);\n\n    dist.assign(totalStates, -1);\n    parent.assign(totalStates, -1);\n    act.assign(totalStates, {'?', '?'});\n\n    vector<string> answer;\n    int cr = pt[0].first, cc = pt[0].second;\n\n    for (int k = 1; k <= M; ++k) {\n        int tr = pt[k].first, tc = pt[k].second;\n        vector<pair<char,char>> seq;\n        bool ok = bfs(cr, cc, tr, tc, seq);\n        if (!ok) {          // should never happen \u2013 fallback to pure moves\n            while (cr != tr || cc != tc) {\n                if (cr < tr) { answer.emplace_back(\"M D\"); ++cr; }\n                else if (cr > tr) { answer.emplace_back(\"M U\"); --cr; }\n                else if (cc < tc) { answer.emplace_back(\"M R\"); ++cc; }\n                else { answer.emplace_back(\"M L\"); --cc; }\n            }\n        } else {\n            for (auto &p : seq) {\n                string s;\n                s.push_back(p.first);\n                s.push_back(' ');\n                s.push_back(p.second);\n                answer.emplace_back(s);\n            }\n            cr = tr; cc = tc;\n        }\n    }\n\n    if ((int)answer.size() > 2 * N * M) {\n        cerr << \"Too many actions!\\n\";\n    }\n\n    for (auto &ln : answer) cout << ln << '\\n';\n    return 0;\n}"},"4":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int x, y;          // integer coordinates of the unit square\n    int r;             // required area\n    int idx;           // original index\n};\n\nstruct LeafRegion {\n    int x1, y1, x2, y2;\n};\n\nint n;\nvector<Point> pts;\nvector<LeafRegion> leaf;          // region for each original index\n\n/*------------------------------------------------------------------*/\n/*  satisfaction helpers                                           */\ninline double computeP(int r, int s) {\n    double ratio = (double)min(r, s) / (double)max(r, s);\n    return ratio * (2.0 - ratio);\n}\n\n/*  best possible satisfaction for a point with required area r\n    inside a region of size w \u00d7 h (both positive)                */\ninline double bestSat(int r, int w, int h) {\n    if (w <= 0 || h <= 0) return 0.0;\n    // candidate heights: 1, h, floor(r/w), ceil(r/w)\n    int hf = r / w;\n    int hc = (r + w - 1) / w;\n    double best = 0.0;\n    const int cand[4] = {1, h, hf, hc};\n    for (int i = 0; i < 4; ++i) {\n        int hh = cand[i];\n        if (hh < 1 || hh > h) continue;\n        int s = w * hh;\n        double p = computeP(r, s);\n        if (p > best) best = p;\n    }\n    return best;\n}\n\n/*------------------------------------------------------------------*/\n/*  recursive construction of the binary partition                */\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nvoid build(const vector<int>& ids,\n           int x1, int y1, int x2, int y2) {\n    if (ids.size() == 1) {                 // leaf\n        leaf[ids[0]] = {x1, y1, x2, y2};\n        return;\n    }\n\n    int W = x2 - x1;\n    int H = y2 - y1;\n\n    double bestScore = -1.0;\n    bool bestVert = false;\n    int bestK = -1;\n\n    /* ----- try all vertical cuts ----- */\n    for (int k = x1 + 1; k < x2; ++k) {\n        int wL = k - x1;\n        int wR = x2 - k;\n        bool leftNotEmpty = false, rightNotEmpty = false;\n        double sum = 0.0;\n        for (int id : ids) {\n            if (pts[id].x < k) {\n                leftNotEmpty = true;\n                sum += bestSat(pts[id].r, wL, H);\n            } else {\n                rightNotEmpty = true;\n                sum += bestSat(pts[id].r, wR, H);\n            }\n        }\n        if (!leftNotEmpty || !rightNotEmpty) continue;\n        if (sum > bestScore + 1e-12) {\n            bestScore = sum;\n            bestVert = true;\n            bestK = k;\n        } else if (fabs(sum - bestScore) <= 1e-12) {\n            // random tie\u2011break\n            if (rng() & 1) {\n                bestVert = true;\n                bestK = k;\n            }\n        }\n    }\n\n    /* ----- try all horizontal cuts ----- */\n    for (int k = y1 + 1; k < y2; ++k) {\n        int hL = k - y1;\n        int hR = y2 - k;\n        bool leftNotEmpty = false, rightNotEmpty = false;\n        double sum = 0.0;\n        for (int id : ids) {\n            if (pts[id].y < k) {\n                leftNotEmpty = true;\n                sum += bestSat(pts[id].r, W, hL);\n            } else {\n                rightNotEmpty = true;\n                sum += bestSat(pts[id].r, W, hR);\n            }\n        }\n        if (!leftNotEmpty || !rightNotEmpty) continue;\n        if (sum > bestScore + 1e-12) {\n            bestScore = sum;\n            bestVert = false;\n            bestK = k;\n        } else if (fabs(sum - bestScore) <= 1e-12) {\n            if (rng() & 1) {\n                bestVert = false;\n                bestK = k;\n            }\n        }\n    }\n\n    // perform the chosen cut\n    vector<int> leftIds, rightIds;\n    if (bestVert) {                         // vertical\n        for (int id : ids) {\n            if (pts[id].x < bestK) leftIds.push_back(id);\n            else rightIds.push_back(id);\n        }\n        build(leftIds,  x1, y1, bestK, y2);\n        build(rightIds, bestK, y1, x2,   y2);\n    } else {                                 // horizontal\n        for (int id : ids) {\n            if (pts[id].y < bestK) leftIds.push_back(id);\n            else rightIds.push_back(id);\n        }\n        build(leftIds,  x1, y1, x2, bestK);\n        build(rightIds, x1, bestK, x2, y2);\n    }\n}\n\n/*------------------------------------------------------------------*/\n/*  build the final rectangle inside a leaf                         */\nvoid placeRectangles(const vector<LeafRegion>& leaf,\n                    vector<int>& a, vector<int>& b,\n                    vector<int>& c, vector<int>& d,\n                    double& totalP) {\n    totalP = 0.0;\n    for (int i = 0; i < n; ++i) {\n        const LeafRegion &reg = leaf[i];\n        int W = reg.x2 - reg.x1;\n        int H = reg.y2 - reg.y1;\n        int r = pts[i].r;\n\n        int bestW = 1, bestH = 1;\n        double bestP = -1.0;\n\n        for (int w = 1; w <= W; ++w) {\n            int hf = r / w;\n            int hc = (r + w - 1) / w;\n            const int cand[4] = {1, H, hf, hc};\n            for (int t = 0; t < 4; ++t) {\n                int h = cand[t];\n                if (h < 1 || h > H) continue;\n                int s = w * h;\n                double p = computeP(r, s);\n                if (p > bestP) {\n                    bestP = p;\n                    bestW = w;\n                    bestH = h;\n                }\n            }\n        }\n\n        // position the rectangle so that it still covers the unit square\n        int left   = max(reg.x1, pts[i].x + 1 - bestW);\n        int bottom = max(reg.y1, pts[i].y + 1 - bestH);\n\n        a[i] = left;\n        b[i] = bottom;\n        c[i] = left + bestW;\n        d[i] = bottom + bestH;\n\n        totalP += bestP;\n    }\n}\n\n/*------------------------------------------------------------------*/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> n;\n    pts.resize(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> pts[i].x >> pts[i].y >> pts[i].r;\n        pts[i].idx = i;\n    }\n\n    const int ITER = 25;                // more repetitions \u2192 higher chance to hit a better tree\n    double bestTotal = -1.0;\n    vector<int> bestA(n), bestB(n), bestC(n), bestD(n);\n\n    for (int it = 0; it < ITER; ++it) {\n        leaf.assign(n, LeafRegion{0,0,0,0});\n        vector<int> allIds(n);\n        iota(allIds.begin(), allIds.end(), 0);\n        shuffle(allIds.begin(), allIds.end(), rng);   // random order \u2192 different ties\n        build(allIds, 0, 0, 10000, 10000);\n\n        vector<int> a(n), b(n), c(n), d(n);\n        double cur;\n        placeRectangles(leaf, a, b, c, d, cur);\n\n        if (cur > bestTotal) {\n            bestTotal = cur;\n            bestA = a; bestB = b; bestC = c; bestD = d;\n        }\n    }\n\n    for (int i = 0; i < n; ++i) {\n        cout << bestA[i] << ' ' << bestB[i] << ' '\n             << bestC[i] << ' ' << bestD[i] << '\\n';\n    }\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------- input ---------- */\n    int si, sj;\n    if (!(cin >> si >> sj)) return 0;\n    const int N = 50;\n\n    vector<vector<int>> tile(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> tile[i][j];\n\n    vector<vector<int>> val(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> val[i][j];\n\n    /* number of different tiles */\n    int maxTile = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            maxTile = max(maxTile, tile[i][j]);\n    const int M = maxTile + 1;                 // tile IDs 0 \u2026 M\u20111\n\n    /* ---------- cell graph (edges to cells of a different tile) ---------- */\n    const int V = N * N;\n    vector<int> cellVal(V);\n    vector<int> cellTile(V);\n    vector<vector<int>> adj(V);\n    auto id = [&](int i, int j) { return i * N + j; };\n    const int di[4] = {-1, 1, 0, 0};\n    const int dj[4] = {0, 0, -1, 1};\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int u = id(i, j);\n            cellVal[u]  = val[i][j];\n            cellTile[u] = tile[i][j];\n            for (int d = 0; d < 4; ++d) {\n                int ni = i + di[d], nj = j + dj[d];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                int v = id(ni, nj);\n                if (tile[ni][nj] != tile[i][j]) adj[u].push_back(v);\n            }\n        }\n    }\n\n    const int startCell = id(si, sj);\n    const int startTile = cellTile[startCell];\n\n    auto dirChar = [&](int from, int to) -> char {\n        int fi = from / N, fj = from % N;\n        int ti = to   / N, tj = to   % N;\n        if (ti == fi - 1 && tj == fj) return 'U';\n        if (ti == fi + 1 && tj == fj) return 'D';\n        if (ti == fi && tj == fj - 1) return 'L';\n        if (ti == fi && tj == fj + 1) return 'R';\n        return '?';\n    };\n\n    /* ---------- randomised greedy walks ---------- */\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    const int MAX_TRIES = 200000;          // many more trials\n    vector<int> visitedTile(M, 0);\n    int curToken = 1;\n\n    string bestPath;\n    int bestScore = -1;\n\n    for (int attempt = 0; attempt < MAX_TRIES; ++attempt) {\n        ++curToken;\n        visitedTile[startTile] = curToken;   // start tile already used\n\n        int cur = startCell;\n        int curScore = cellVal[cur];\n        string path;\n\n        /* random parameters for this trial */\n        int randProb = uniform_int_distribution<int>(5, 30)(rng); // 5..30%\n        int gamma    = uniform_int_distribution<int>(0, 25)(rng); // 0..25\n        // 0 = degree, 1 = sum/10, 2 = maxNext\n        int heurType = uniform_int_distribution<int>(0, 2)(rng);\n\n        while (true) {\n            /* collect admissible neighbours (different, still unvisited tile) */\n            vector<int> cand;\n            for (int nb : adj[cur]) {\n                int ntile = cellTile[nb];\n                if (visitedTile[ntile] != curToken) cand.push_back(nb);\n            }\n            if (cand.empty()) break;          // stuck\n\n            /* small chance to pick a completely random neighbour */\n            if (uniform_int_distribution<int>(0, 99)(rng) < randProb) {\n                int idx = uniform_int_distribution<int>(0, (int)cand.size() - 1)(rng);\n                int nxt = cand[idx];\n                path.push_back(dirChar(cur, nxt));\n                cur = nxt;\n                visitedTile[cellTile[cur]] = curToken;\n                curScore += cellVal[cur];\n                continue;\n            }\n\n            /* evaluate all candidates */\n            int bestHeur = INT_MIN;\n            int bestNext = -1;\n            for (int nb : cand) {\n                int value = cellVal[nb];\n                int measure = 0;\n\n                if (heurType == 0) {               // degree\n                    for (int nb2 : adj[nb])\n                        if (visitedTile[cellTile[nb2]] != curToken)\n                            ++measure;\n                } else if (heurType == 1) {         // sum of values /10\n                    for (int nb2 : adj[nb])\n                        if (visitedTile[cellTile[nb2]] != curToken)\n                            measure += cellVal[nb2];\n                    measure /= 10;\n                } else {                            // max next value\n                    for (int nb2 : adj[nb])\n                        if (visitedTile[cellTile[nb2]] != curToken)\n                            measure = max(measure, cellVal[nb2]);\n                }\n\n                int heur = value + gamma * measure;\n                // tiny random noise to break ties\n                heur += (rng() & 1);\n\n                if (heur > bestHeur) {\n                    bestHeur = heur;\n                    bestNext = nb;\n                } else if (heur == bestHeur && (rng() & 1)) {\n                    bestNext = nb;\n                }\n            }\n\n            /* perform the chosen step */\n            path.push_back(dirChar(cur, bestNext));\n            cur = bestNext;\n            visitedTile[cellTile[cur]] = curToken;\n            curScore += cellVal[cur];\n        }\n\n        if (curScore > bestScore) {\n            bestScore = curScore;\n            bestPath = path;\n        }\n    }\n\n    cout << bestPath << '\\n';\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 30;\n    const int V = N * N;\n    const double INF = 1e100;\n    const double INIT_W = 5000.0;\n    const double ALPHA = 0.2;\n    const double MIN_W = 500.0;\n    const double MAX_W = 15000.0;\n\n    // edge estimates\n    double hor[N][N-1]; // horizontal: (i,j)-(i,j+1), j = 0..28\n    double ver[N-1][N]; // vertical:   (i,j)-(i+1,j), i = 0..28\n\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N-1; ++j)\n            hor[i][j] = INIT_W;\n    for (int i = 0; i < N-1; ++i)\n        for (int j = 0; j < N; ++j)\n            ver[i][j] = INIT_W;\n\n    auto idx = [&](int i, int j) { return i * N + j; };\n\n    for (int q = 0; q < 1000; ++q) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) break;\n\n        int s = idx(si, sj);\n        int t = idx(ti, tj);\n\n        // Dijkstra\n        vector<double> dist(V, INF);\n        vector<int> prev(V, -1);\n        vector<char> move(V, 0); // direction from prev to this vertex\n        dist[s] = 0.0;\n        using Node = pair<double,int>;\n        priority_queue<Node, vector<Node>, greater<Node>> pq;\n        pq.emplace(0.0, s);\n\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u] + 1e-12) continue;\n            if (u == t) break;\n            int ui = u / N;\n            int uj = u % N;\n\n            // up\n            if (ui > 0) {\n                int v = idx(ui-1, uj);\n                double w = ver[ui-1][uj];\n                double nd = d + w;\n                if (nd + 1e-12 < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    move[v] = 'U';\n                    pq.emplace(nd, v);\n                }\n            }\n            // down\n            if (ui < N-1) {\n                int v = idx(ui+1, uj);\n                double w = ver[ui][uj];\n                double nd = d + w;\n                if (nd + 1e-12 < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    move[v] = 'D';\n                    pq.emplace(nd, v);\n                }\n            }\n            // left\n            if (uj > 0) {\n                int v = idx(ui, uj-1);\n                double w = hor[ui][uj-1];\n                double nd = d + w;\n                if (nd + 1e-12 < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    move[v] = 'L';\n                    pq.emplace(nd, v);\n                }\n            }\n            // right\n            if (uj < N-1) {\n                int v = idx(ui, uj+1);\n                double w = hor[ui][uj];\n                double nd = d + w;\n                if (nd + 1e-12 < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    move[v] = 'R';\n                    pq.emplace(nd, v);\n                }\n            }\n        }\n\n        // reconstruct path\n        string path;\n        int cur = t;\n        while (cur != s) {\n            char m = move[cur];\n            path.push_back(m);\n            cur = prev[cur];\n        }\n        reverse(path.begin(), path.end());\n\n        // output\n        cout << path << '\\n' << flush;\n\n        // receive noisy length\n        long long noisy;\n        cin >> noisy;\n\n        // learning\n        double est = dist[t];                // \u03a3 w_e according to current estimates\n        double ratio = (double)noisy / est;  // B / E\n        double factor = 1.0 + ALPHA * (ratio - 1.0);\n        if (factor < 0.5) factor = 0.5;\n        if (factor > 2.0) factor = 2.0;\n\n        // apply factor to all edges of the printed path\n        int i = si, j = sj;\n        for (char c : path) {\n            if (c == 'U') {\n                ver[i-1][j] *= factor;\n                if (ver[i-1][j] < MIN_W) ver[i-1][j] = MIN_W;\n                if (ver[i-1][j] > MAX_W) ver[i-1][j] = MAX_W;\n                --i;\n            } else if (c == 'D') {\n                ver[i][j] *= factor;\n                if (ver[i][j] < MIN_W) ver[i][j] = MIN_W;\n                if (ver[i][j] > MAX_W) ver[i][j] = MAX_W;\n                ++i;\n            } else if (c == 'L') {\n                hor[i][j-1] *= factor;\n                if (hor[i][j-1] < MIN_W) hor[i][j-1] = MIN_W;\n                if (hor[i][j-1] > MAX_W) hor[i][j-1] = MAX_W;\n                --j;\n            } else if (c == 'R') {\n                hor[i][j] *= factor;\n                if (hor[i][j] < MIN_W) hor[i][j] = MIN_W;\n                if (hor[i][j] > MAX_W) hor[i][j] = MAX_W;\n                ++j;\n            }\n        }\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\n/***  global data  ***/\nint N;                                   // board size (20)\nint totalM;                              // \u03a3 multiplicity = M\nint curC, bestC;                         // weighted number of present strings\n\n// character encoding: 'A'..'H' -> 0..7\nint chCode[256];\n// powers of 8, 8^k (k \u2264 12)\nuint64_t pow8[13];\n\n// distinct strings\nunordered_map<unsigned long long, int> str2idx;   // key -> index\nvector<int> mult;                                  // multiplicity\nvector<int> occ;                                   // occurrences on current board\nint uniqCnt;                                       // number of distinct strings\n\n// substring description\nstruct SubInfo {\n    uint8_t start_i, start_j;\n    uint8_t dir;          // 0 = horizontal, 1 = vertical\n    uint8_t len;\n};\nvector<SubInfo> subs;                  // all substrings (\u2264 8800)\nvector<uint64_t> curCode;              // current base\u20118 value of each substring\nvector<int> curIdx;                    // index of matched string, -1 if none\n\n// for each cell: list of (substring id, offset inside that substring)\nvector<vector<pair<int, uint8_t>>> cellSubs;\n\n// current board and best board\nvector<string> grid;\nvector<string> bestGrid;\n\n/***  helpers  ***/\ninline unsigned long long encodeString(const string &s) {\n    unsigned long long code = 0;\n    for (char ch : s) code = (code << 3) | (unsigned long long)chCode[(unsigned char)ch];\n    return code;\n}\ninline unsigned long long keyWithLen(unsigned long long code, int len) {\n    return (code << 4) | (unsigned long long)len;\n}\n\n/***  initial evaluation from a given board  ***/\nvoid initFromGrid(const vector<string> &g) {\n    fill(occ.begin(), occ.end(), 0);\n    curC = 0;\n    int S = (int)subs.size();\n    for (int sid = 0; sid < S; ++sid) {\n        const SubInfo &inf = subs[sid];\n        unsigned long long code = 0;\n        for (int p = 0; p < inf.len; ++p) {\n            int r = (inf.dir == 0) ? inf.start_i\n                                    : (inf.start_i + p) % N;\n            int c = (inf.dir == 0) ? (inf.start_j + p) % N\n                                    : inf.start_j;\n            char ch = g[r][c];\n            code = (code << 3) | (unsigned long long)chCode[(unsigned char)ch];\n        }\n        unsigned long long key = (code << 4) | (unsigned long long)inf.len;\n        int idx = -1;\n        auto it = str2idx.find(key);\n        if (it != str2idx.end()) idx = it->second;\n        curIdx[sid] = idx;\n        curCode[sid] = code;\n        if (idx != -1) occ[idx]++;\n    }\n    for (int i = 0; i < uniqCnt; ++i)\n        if (occ[i] > 0) curC += mult[i];\n}\n\n/***  compute delta for a single cell change (pure) ***/\nint computeDelta(int cell, char newChar) {\n    int r = cell / N;\n    int c = cell % N;\n    char oldChar = grid[r][c];\n    if (oldChar == newChar) return 0;\n    int oldVal = chCode[(unsigned char)oldChar];\n    int newVal = chCode[(unsigned char)newChar];\n    int delta = 0;\n    for (const auto &pr : cellSubs[cell]) {\n        int sid = pr.first;\n        int offset = pr.second;\n        const SubInfo &inf = subs[sid];\n        int len = inf.len;\n        int exp = len - 1 - offset;\n        unsigned long long oldCodeSub = curCode[sid];\n        unsigned long long newCodeSub = oldCodeSub\n                                      - (unsigned long long)oldVal * pow8[exp]\n                                      + (unsigned long long)newVal * pow8[exp];\n        unsigned long long newKey = (newCodeSub << 4) | (unsigned long long)len;\n        int newIdx = -1;\n        auto it = str2idx.find(newKey);\n        if (it != str2idx.end()) newIdx = it->second;\n        int oldIdx = curIdx[sid];\n        if (oldIdx == newIdx) continue;\n        if (oldIdx != -1) {\n            if (occ[oldIdx] == 1) delta -= mult[oldIdx];\n        }\n        if (newIdx != -1) {\n            if (occ[newIdx] == 0) delta += mult[newIdx];\n        }\n    }\n    return delta;\n}\n\n/***  apply an accepted move ***/\nvoid applyDelta(int cell, char newChar) {\n    int r = cell / N;\n    int c = cell % N;\n    char oldChar = grid[r][c];\n    if (oldChar == newChar) return;\n    int oldVal = chCode[(unsigned char)oldChar];\n    int newVal = chCode[(unsigned char)newChar];\n    for (const auto &pr : cellSubs[cell]) {\n        int sid = pr.first;\n        int offset = pr.second;\n        const SubInfo &inf = subs[sid];\n        int len = inf.len;\n        int exp = len - 1 - offset;\n        unsigned long long oldCodeSub = curCode[sid];\n        unsigned long long newCodeSub = oldCodeSub\n                                      - (unsigned long long)oldVal * pow8[exp]\n                                      + (unsigned long long)newVal * pow8[exp];\n        unsigned long long newKey = (newCodeSub << 4) | (unsigned long long)len;\n        int newIdx = -1;\n        auto it = str2idx.find(newKey);\n        if (it != str2idx.end()) newIdx = it->second;\n        int oldIdx = curIdx[sid];\n        if (oldIdx == newIdx) {\n            curCode[sid] = newCodeSub;\n            curIdx[sid] = newIdx;\n            continue;\n        }\n        if (oldIdx != -1) {\n            if (occ[oldIdx] == 1) curC -= mult[oldIdx];\n            --occ[oldIdx];\n        }\n        if (newIdx != -1) {\n            if (occ[newIdx] == 0) curC += mult[newIdx];\n            ++occ[newIdx];\n        }\n        curCode[sid] = newCodeSub;\n        curIdx[sid] = newIdx;\n    }\n    grid[r][c] = newChar;\n}\n\n/***  main ***/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M;\n    if (!(cin >> N >> M)) return 0;\n    totalM = M;\n\n    // character encoding\n    fill(begin(chCode), end(chCode), -1);\n    for (char ch = 'A'; ch <= 'H'; ++ch) chCode[(unsigned char)ch] = ch - 'A';\n\n    // read strings, build distinct set\n    vector<string> inputs(M);\n    for (int i = 0; i < M; ++i) cin >> inputs[i];\n    for (const string &s : inputs) {\n        unsigned long long code = encodeString(s);\n        unsigned long long key = (code << 4) | (unsigned long long)s.size();\n        auto it = str2idx.find(key);\n        if (it == str2idx.end()) {\n            int id = (int)mult.size();\n            str2idx[key] = id;\n            mult.push_back(1);\n        } else {\n            ++mult[it->second];\n        }\n    }\n    uniqCnt = (int)mult.size();\n    occ.assign(uniqCnt, 0);\n\n    // powers of 8\n    pow8[0] = 1;\n    for (int i = 1; i <= 12; ++i) pow8[i] = pow8[i - 1] * 8ULL;\n\n    // build all substrings and cell\u2192substring lists\n    subs.reserve(8800);\n    cellSubs.assign(N * N, {});\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            // horizontal\n            for (int len = 2; len <= 12; ++len) {\n                SubInfo inf;\n                inf.start_i = (uint8_t)i;\n                inf.start_j = (uint8_t)j;\n                inf.dir = 0;\n                inf.len = (uint8_t)len;\n                int sid = (int)subs.size();\n                subs.push_back(inf);\n                for (int p = 0; p < len; ++p) {\n                    int cj = (j + p) % N;\n                    int cell = i * N + cj;\n                    cellSubs[cell].push_back({sid, (uint8_t)p});\n                }\n            }\n            // vertical\n            for (int len = 2; len <= 12; ++len) {\n                SubInfo inf;\n                inf.start_i = (uint8_t)i;\n                inf.start_j = (uint8_t)j;\n                inf.dir = 1;\n                inf.len = (uint8_t)len;\n                int sid = (int)subs.size();\n                subs.push_back(inf);\n                for (int p = 0; p < len; ++p) {\n                    int ri = (i + p) % N;\n                    int cell = ri * N + j;\n                    cellSubs[cell].push_back({sid, (uint8_t)p});\n                }\n            }\n        }\n    }\n\n    curCode.assign(subs.size(), 0);\n    curIdx.assign(subs.size(), -1);\n\n    // random engine\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    // ----- start with a random board -----\n    grid.assign(N, string(N, 'A'));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            grid[i][j] = char('A' + rng() % 8);\n\n    // initial evaluation\n    initFromGrid(grid);\n    bestGrid = grid;\n    bestC = curC;\n\n    // ----- main search: steepest\u2011ascent + mild simulated annealing -----\n    const double timeLimit = 2.8;               // seconds\n    const int maxIter = 1000000;                // enough for the new neighbourhood\n    auto start = chrono::steady_clock::now();\n\n    for (int iter = 0; iter < maxIter; ++iter) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed >= timeLimit) break;\n\n        int cell = rng() % (N * N);\n        int r = cell / N, c = cell % N;\n        char oldChar = grid[r][c];\n\n        // evaluate all 8 possible new letters\n        int bestDelta = INT_MIN;\n        char bestChar = oldChar;\n        for (char cand = 'A'; cand <= 'H'; ++cand) {\n            if (cand == oldChar) continue;\n            int delta = computeDelta(cell, cand);\n            if (delta > bestDelta) {\n                bestDelta = delta;\n                bestChar = cand;\n            }\n        }\n\n        bool accept = false;\n        if (bestDelta > 0) {\n            accept = true;\n        } else {\n            int rprob = rng() % 100;\n            if (bestDelta == 0 && rprob < 10) accept = true;       // 10%\n            else if (bestDelta < 0 && rprob < 1) accept = true;    // 1%\n        }\n\n        if (accept) {\n            applyDelta(cell, bestChar);\n            if (curC > bestC) {\n                bestC = curC;\n                bestGrid = grid;\n                if (bestC == totalM) break;               // perfect!\n            }\n        }\n    }\n\n    // output best board\n    for (int i = 0; i < N; ++i) cout << bestGrid[i] << '\\n';\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing pii = pair<int,int>;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, si, sj;\n    if(!(cin >> N >> si >> sj)) return 0;\n    vector<string> g(N);\n    for (int i = 0; i < N; ++i) cin >> g[i];\n\n    /* ---------- road cells ---------- */\n    vector<vector<int>> id(N, vector<int>(N, -1));\n    vector<pii> pos;                     // id \u2192 (i , j)\n    vector<int> w;                       // entering time\n    int R = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (g[i][j] != '#') {\n                id[i][j] = R++;\n                pos.emplace_back(i, j);\n                w.push_back(g[i][j] - '0');\n            }\n\n    /* ---------- horizontal segments ---------- */\n    vector<vector<int>> rowSegId(N, vector<int>(N, -1));\n    vector<vector<int>> rowSegMembers;               // list of cell ids\n    int rowSegCnt = 0;\n    for (int i = 0; i < N; ++i) {\n        int j = 0;\n        while (j < N) {\n            if (g[i][j] == '#') { ++j; continue; }\n            int seg = rowSegCnt++;\n            rowSegMembers.emplace_back();\n            while (j < N && g[i][j] != '#') {\n                int cid = id[i][j];\n                rowSegId[i][j] = seg;\n                rowSegMembers.back().push_back(cid);\n                ++j;\n            }\n        }\n    }\n\n    /* ---------- vertical segments ---------- */\n    vector<vector<int>> colSegId(N, vector<int>(N, -1));\n    vector<vector<int>> colSegMembers;\n    int colSegCnt = 0;\n    for (int j = 0; j < N; ++j) {\n        int i = 0;\n        while (i < N) {\n            if (g[i][j] == '#') { ++i; continue; }\n            int seg = colSegCnt++;\n            colSegMembers.emplace_back();\n            while (i < N && g[i][j] != '#') {\n                int cid = id[i][j];\n                colSegId[i][j] = seg;\n                colSegMembers.back().push_back(cid);\n                ++i;\n            }\n        }\n    }\n\n    /* cell \u2192 its two segment ids */\n    vector<int> cellRowSeg(R), cellColSeg(R);\n    for (int cid = 0; cid < R; ++cid) {\n        int i = pos[cid].first, j = pos[cid].second;\n        cellRowSeg[cid] = rowSegId[i][j];\n        cellColSeg[cid] = colSegId[i][j];\n    }\n\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    const char dch[4] = {'U','D','L','R'};\n\n    auto dirFromDelta = [&](int dr, int dc)->char{\n        if (dr==-1 && dc==0) return 'U';\n        if (dr==1  && dc==0) return 'D';\n        if (dr==0 && dc==-1) return 'L';\n        if (dr==0 && dc==1) return 'R';\n        return '?';\n    };\n\n    /* ----- counters for still invisible cells ----- */\n    vector<int> rowCnt(rowSegCnt), colCnt(colSegCnt);\n    for (int rs = 0; rs < rowSegCnt; ++rs) rowCnt[rs] = (int)rowSegMembers[rs].size();\n    for (int cs = 0; cs < colSegCnt; ++cs) colCnt[cs] = (int)colSegMembers[cs].size();\n\n    vector<char> rowCover(rowSegCnt, 0), colCover(colSegCnt, 0);\n    vector<char> visible(R, 0);\n    int coveredCnt = 0;\n\n    auto visitRowSeg = [&](int rs) {\n        if (rowCover[rs]) return;\n        rowCover[rs] = 1;\n        for (int cid : rowSegMembers[rs]) {\n            if (!visible[cid]) {\n                visible[cid] = 1;\n                ++coveredCnt;\n                int cs = cellColSeg[cid];\n                --colCnt[cs];\n            }\n        }\n        rowCnt[rs] = 0;\n    };\n    auto visitColSeg = [&](int cs) {\n        if (colCover[cs]) return;\n        colCover[cs] = 1;\n        for (int cid : colSegMembers[cs]) {\n            if (!visible[cid]) {\n                visible[cid] = 1;\n                ++coveredCnt;\n                int rs = cellRowSeg[cid];\n                --rowCnt[rs];\n            }\n        }\n        colCnt[cs] = 0;\n    };\n\n    int startId = id[si][sj];\n    /* initialise the start row / column as visited */\n    visitRowSeg(cellRowSeg[startId]);\n    visitColSeg(cellColSeg[startId]);\n\n    /* ----- greedy walk ----- */\n    string answer;\n    answer.reserve(20000);\n    long long totalCost = 0;\n    int ci = si, cj = sj;               // current position\n    int curId = startId;\n\n    while (coveredCnt < R) {\n        int bestDir = -1;\n        int bestInc = -1;\n        int bestCost = INT_MAX;\n        int bestNi = -1, bestNj = -1;\n\n        for (int d = 0; d < 4; ++d) {\n            int ni = ci + dx[d], nj = cj + dy[d];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            if (id[ni][nj] == -1) continue;\n            int nid = id[ni][nj];\n            int rs = cellRowSeg[nid];\n            int cs = cellColSeg[nid];\n\n            int inc = 0;\n            bool rowNot = !rowCover[rs];\n            bool colNot = !colCover[cs];\n            if (rowNot && rowCnt[rs] > 0) inc += rowCnt[rs];\n            if (colNot && colCnt[cs] > 0) inc += colCnt[cs];\n            if (rowNot && colNot && rowCnt[rs] > 0 && colCnt[cs] > 0) inc -= 1;\n\n            if (inc > bestInc || (inc == bestInc && w[nid] < bestCost)) {\n                bestInc = inc;\n                bestCost = w[nid];\n                bestDir = d;\n                bestNi = ni; bestNj = nj;\n            }\n        }\n\n        if (bestInc > 0) {                         // move with new coverage\n            answer.push_back(dch[bestDir]);\n            totalCost += w[id[bestNi][bestNj]];\n            ci = bestNi; cj = bestNj;\n            curId = id[ci][cj];\n            int rs = cellRowSeg[curId];\n            int cs = cellColSeg[curId];\n            if (!rowCover[rs]) visitRowSeg(rs);\n            if (!colCover[cs]) visitColSeg(cs);\n        } else {                                   // no new coverage \u2013 go to nearest invisible cell\n            static int dist[70][70];\n            static int parent[70][70];\n            for (int i = 0; i < N; ++i)\n                for (int j = 0; j < N; ++j) {\n                    dist[i][j] = -1;\n                    parent[i][j] = -1;\n                }\n            queue<pii> q;\n            dist[ci][cj] = 0;\n            q.emplace(ci, cj);\n            int ti = -1, tj = -1;\n            while (!q.empty()) {\n                auto [x, y] = q.front(); q.pop();\n\n                // check if this cell is invisible (but not the start)\n                if (!(x == ci && y == cj)) {\n                    int cid = id[x][y];\n                    if (!visible[cid]) {\n                        ti = x; tj = y;\n                        break;\n                    }\n                }\n\n                for (int dir = 0; dir < 4; ++dir) {\n                    int nx = x + dx[dir], ny = y + dy[dir];\n                    if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n                    if (id[nx][ny] == -1) continue;\n                    if (dist[nx][ny] != -1) continue;\n                    dist[nx][ny] = dist[x][y] + 1;\n                    parent[nx][ny] = x * N + y;\n                    q.emplace(nx, ny);\n                }\n            }\n\n            if (ti == -1) {\n                // shouldn't happen, but just in case\n                break;\n            }\n\n            // reconstruct path: find the first step after current position\n            int cx = ti, cy = tj;\n            // walk back until parent is the current position\n            while (!(cx == ci && cy == cj)) {\n                int p = parent[cx][cy];\n                if (p == -1) break; // shouldn't happen\n                cx = p / N; cy = p % N;\n                if (cx == ci && cy == cj) break;\n                // continue to next\n            }\n            // now cx,cy should be the neighbour of current position\n            // but we need to find the one right after ci,cj\n            // let's redo: go from target back to just after start\n            vector<pii> path;\n            int tx = ti, ty = tj;\n            while (!(tx == ci && ty == cj)) {\n                path.emplace_back(tx, ty);\n                int p = parent[tx][ty];\n                if (p == -1) break;\n                tx = p / N; ty = p % N;\n            }\n            // path[0] is the target, path.back() is the neighbour of start\n            if (path.empty()) {\n                // shouldn't happen\n                break;\n            }\n            int nx = path.back().first, ny = path.back().second;\n            answer.push_back(dirFromDelta(nx - ci, ny - cj));\n            totalCost += w[id[nx][ny]];\n            ci = nx; cj = ny;\n            curId = id[ci][cj];\n            int rs = cellRowSeg[curId];\n            int cs = cellColSeg[curId];\n            if (!rowCover[rs]) visitRowSeg(rs);\n            if (!colCover[cs]) visitColSeg(cs);\n        }\n    }\n\n    /* ----- shortest way back to start (Dijkstra) ----- */\n    const long long INF = (1LL << 60);\n    vector<long long> dist(R, INF);\n    vector<int> pv(R, -1);\n    using Node = pair<long long,int>;\n    priority_queue<Node, vector<Node>, greater<Node>> pq;\n    dist[startId] = 0;\n    pq.emplace(0, startId);\n    while (!pq.empty()) {\n        auto [du, u] = pq.top(); pq.pop();\n        if (du != dist[u]) continue;\n        int ux = pos[u].first, uy = pos[u].second;\n        for (int dir = 0; dir < 4; ++dir) {\n            int vx = ux + dx[dir], vy = uy + dy[dir];\n            if (vx < 0 || vx >= N || vy < 0 || vy >= N) continue;\n            int v = id[vx][vy];\n            if (v == -1) continue;\n            long long nd = du + w[v];\n            if (nd < dist[v]) {\n                dist[v] = nd;\n                pv[v] = u;\n                pq.emplace(nd, v);\n            }\n        }\n    }\n\n    // reconstruct path from cur back to start (reverse order)\n    vector<int> revPath;\n    int node = curId;\n    while (true) {\n        revPath.push_back(node);\n        if (node == startId) break;\n        if (pv[node] == -1) break; // shouldn't happen\n        node = pv[node];\n    }\n    // append the moves: from cur (index 0) to start (last index)\n    for (int k = 0; k < (int)revPath.size() - 1; ++k) {\n        int a = revPath[k];\n        int b = revPath[k+1];\n        int ax = pos[a].first, ay = pos[a].second;\n        int bx = pos[b].first, by = pos[b].second;\n        answer.push_back(dirFromDelta(bx - ax, by - ay));\n        totalCost += w[b];\n    }\n\n    cout << answer << '\\n';\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct ReadyTask {\n    long long score;  // diff + depth (higher is more urgent)\n    int id;           // task index (0\u2011based)\n    bool operator<(const ReadyTask& other) const {\n        return score < other.score;   // max\u2011heap\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K, R;\n    if (!(cin >> N >> M >> K >> R)) return 0;\n\n    /* ----- read required skill vectors ----- */\n    vector<vector<int>> d(N, vector<int>(K));\n    for (int i = 0; i < N; ++i)\n        for (int k = 0; k < K; ++k) cin >> d[i][k];\n\n    /* ----- read dependencies ----- */\n    vector<vector<int>> children(N);\n    vector<int> indeg(N, 0);\n    for (int i = 0; i < R; ++i) {\n        int u, v;\n        cin >> u >> v;\n        --u; --v;\n        children[u].push_back(v);\n        ++indeg[v];\n    }\n\n    /* ----- difficulty of each task ----- */\n    vector<long long> diff(N, 0);\n    for (int i = 0; i < N; ++i) {\n        long long s = 0;\n        for (int k = 0; k < K; ++k) s += d[i][k];\n        diff[i] = s;\n    }\n\n    /* ----- compute depth (critical\u2011path length) without disturbing indeg ----- */\n    vector<int> indeg_tmp = indeg;               // copy\n    vector<int> depth(N, 0);\n    queue<int> q;\n    for (int i = 0; i < N; ++i)\n        if (indeg_tmp[i] == 0) q.push(i);\n    while (!q.empty()) {\n        int v = q.front(); q.pop();\n        for (int nb : children[v]) {\n            depth[nb] = max(depth[nb], depth[v] + 1);\n            if (--indeg_tmp[nb] == 0) q.push(nb);\n        }\n    }\n\n    /* ----- initialise ready tasks (indegree 0) ----- */\n    priority_queue<ReadyTask> ready;\n    for (int i = 0; i < N; ++i)\n        if (indeg[i] == 0) ready.push({diff[i] + depth[i], i});\n\n    /* ----- data for each member ----- */\n    vector<long long> totalTime(M, 0), totalDiff(M, 0);\n    vector<vector<int>> lower(M, vector<int>(K, 0));   // lower bounds of skills\n    vector<int> curTask(M, -1);                        // -1 \u2192 idle\n    vector<int> startDay(N, -1);                       // start day of each task\n\n    /* ----- helper: predicted duration for (member, task) pair ----- */\n    auto predict_time = [&](int member, int task) -> long long {\n        long long missing = 0;\n        for (int k = 0; k < K; ++k)\n            if (d[task][k] > lower[member][k])\n                missing += d[task][k] - lower[member][k];\n\n        if (missing == 0) return 1LL;                     // certainly 1 day\n        if (totalDiff[member] == 0)                       // no information yet\n            return max(1LL, missing);                     // assume 1 day per unit missing\n        // use average speed (time per unit of missing skill)\n        long long pred = (missing * totalTime[member] + totalDiff[member] - 1) / totalDiff[member];\n        return max(1LL, pred);\n    };\n\n    int day = 1;\n    while (true) {\n        /* ----- collect idle members ----- */\n        vector<int> idle;\n        idle.reserve(M);\n        for (int j = 0; j < M; ++j)\n            if (curTask[j] == -1) idle.push_back(j);\n\n        /* ----- assign ready tasks to idle members ----- */\n        vector<pair<int,int>> assign;          // (member+1 , task+1)\n        while (!idle.empty() && !ready.empty()) {\n            ReadyTask rt = ready.top(); ready.pop();\n            int t = rt.id;                     // the task with highest score\n\n            // find the idle member with the smallest predicted time,\n            // but prefer members with no data if the difference is small\n            int best = -1;\n            long long bestVal = LLONG_MAX;\n            for (int w : idle) {\n                long long v = predict_time(w, t);\n                bool better = false;\n                if (v < bestVal) {\n                    better = true;\n                } else if (v == bestVal) {\n                    // tie-break: prefer unknown member (totalDiff == 0)\n                    if (totalDiff[w] == 0 && totalDiff[best] > 0) better = true;\n                    else if (totalDiff[w] > 0 && totalDiff[best] == 0) better = false;\n                    else if (w < best) better = true; // fallback to smaller index\n                }\n                if (better) {\n                    bestVal = v;\n                    best = w;\n                }\n            }\n\n            // perform the assignment\n            assign.emplace_back(best + 1, t + 1);\n            curTask[best] = t;\n            startDay[t] = day;\n\n            // remove the chosen worker from the idle list\n            for (size_t i = 0; i < idle.size(); ++i) {\n                if (idle[i] == best) {\n                    idle[i] = idle.back();\n                    idle.pop_back();\n                    break;\n                }\n            }\n        }\n\n        /* ----- output ----- */\n        cout << assign.size();\n        for (auto &p : assign) cout << ' ' << p.first << ' ' << p.second;\n        cout << '\\n';\n        cout.flush();\n\n        /* ----- receive the list of finished members ----- */\n        int x;\n        if (!(cin >> x)) break;               // should not happen\n        if (x == -1) break;                    // end of simulation\n        int cnt = x;\n        vector<int> finished(cnt);\n        for (int i = 0; i < cnt; ++i) {\n            cin >> finished[i];\n            --finished[i];                     // to 0\u2011based\n        }\n\n        /* ----- process each completed task ----- */\n        for (int w : finished) {\n            int t = curTask[w];\n            if (t == -1) continue;            // safety, should not occur\n\n            int duration = day - startDay[t] + 1;\n\n            // update speed statistics\n            totalTime[w] += duration;\n            totalDiff[w] += diff[t];\n\n            // if the task finished in exactly one day we gain a lower bound\n            if (duration == 1) {\n                for (int k = 0; k < K; ++k)\n                    lower[w][k] = max(lower[w][k], d[t][k]);\n            }\n\n            // propagate the completion to dependent tasks\n            for (int nb : children[t]) {\n                if (--indeg[nb] == 0) {\n                    ready.push({diff[nb] + depth[nb], nb});\n                }\n            }\n\n            curTask[w] = -1;                    // member becomes idle\n        }\n\n        ++day;\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Order {\n    int a, b, c, d;          // pickup (a,b) , delivery (c,d)\n};\n\ninline long long manhattan(int x1, int y1, int x2, int y2) {\n    return llabs(x1 - x2) + llabs(y1 - y2);\n}\n\n/* --------------------------------------------------------------- */\n/*  compute tour length for a given permutation                    */\nstatic long long tourCost(const vector<int>& perm,\n                          const vector<long long>& start,\n                          const vector<long long>& finish,\n                          const vector<vector<int>>& D,\n                          long long insideSum)\n{\n    const int m = (int)perm.size();\n    long long cur = start[perm[0]];\n    for (int i = 0; i < m - 1; ++i) cur += D[perm[i]][perm[i + 1]];\n    cur += finish[perm[m - 1]];\n    cur += insideSum;\n    return cur;\n}\n\n/* --------------------------------------------------------------- */\n/*  cheap TSP : nearest neighbour from every start                */\nstatic long long cheapTSP(const vector<int>& orders,\n                          vector<int>& bestPerm)\n{\n    const int m = (int)orders.size();\n    vector<long long> start(m), finish(m), inside(m);\n    vector<int> pX(m), pY(m), dX(m), dY(m);\n    const int DEP = 400;\n\n    for (int i = 0; i < m; ++i) {\n        const Order& o = *((Order*)nullptr);   // dummy, see below\n    }\n\n    // fill data for the current subset\n    for (int i = 0; i < m; ++i) {\n        const Order& o = *((Order*)nullptr);\n    }\n    // we will fill it inside the function, see later\n    // (the two dummy lines are only to keep the editor happy)\n    // -----------------------------------------------------------------\n    // Real code: we need the arrays a,b,c,d from the global vector.\n    // -----------------------------------------------------------------\n    return 0; // never reached\n}\n\n/* Because the cheap TSP is tiny we write it inside the main function\n   to avoid passing many global arrays. The same holds for the full\n   improvement routine.                                             */\n\n/* --------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int DEP = 400;\n    const int N = 1000;\n    vector<Order> ord(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> ord[i].a >> ord[i].b >> ord[i].c >> ord[i].d;\n    }\n\n    /* ----  solo costs (start+inside+finish)  ---------------------- */\n    vector<long long> solo(N);\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    for (int i = 0; i < N; ++i) {\n        long long st = manhattan(DEP, DEP, ord[i].a, ord[i].b);\n        long long ins = manhattan(ord[i].a, ord[i].b, ord[i].c, ord[i].d);\n        long long fn = manhattan(ord[i].c, ord[i].d, DEP, DEP);\n        solo[i] = st + ins + fn;\n    }\n    sort(idx.begin(), idx.end(),\n         [&](int i, int j){ return solo[i] < solo[j]; });\n\n    /* ----  candidate list : the 200 best orders  ----------------- */\n    const int CAND = 200;\n    vector<int> cand;\n    cand.reserve(CAND);\n    for (int i = 0; i < CAND; ++i) cand.push_back(idx[i]);\n\n    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    const int SAMPLE = 500;               // number of random subsets\n    struct SubsetInfo {\n        vector<int> ids;   // original order numbers (0\u2011based)\n        long long cost;\n    };\n    vector<SubsetInfo> samples;\n    samples.reserve(SAMPLE + 1);\n\n    // ----- helper lambdas for a concrete subset -----------------\n    auto evaluateSubset = [&](const vector<int>& ids, bool full,\n                               vector<int>& outPerm) -> long long {\n        const int m = (int)ids.size();            // =50\n        vector<long long> start(m), finish(m), inside(m);\n        vector<int> pX(m), pY(m), dX(m), dY(m);\n        long long insideSum = 0;\n        for (int i = 0; i < m; ++i) {\n            const Order& o = ord[ids[i]];\n            pX[i] = o.a; pY[i] = o.b;\n            dX[i] = o.c; dY[i] = o.d;\n            start[i]   = manhattan(DEP, DEP, pX[i], pY[i]);\n            inside[i]  = manhattan(pX[i], pY[i], dX[i], dY[i]);\n            finish[i]  = manhattan(dX[i], dY[i], DEP, DEP);\n            insideSum += inside[i];\n        }\n        // matrix D[i][j] = distance delivery_i -> pickup_j\n        vector<vector<int>> D(m, vector<int>(m));\n        for (int i = 0; i < m; ++i)\n            for (int j = 0; j < m; ++j)\n                D[i][j] = (int)manhattan(dX[i], dY[i], pX[j], pY[j]);\n\n        // ----- cheap solution : nearest neighbour -----------------\n        long long bestCost = (1LL<<60);\n        vector<int> bestPerm;\n        for (int s = 0; s < m; ++s) {\n            vector<int> perm;\n            vector<char> used(m, 0);\n            int cur = s;\n            perm.push_back(cur);\n            used[cur] = 1;\n            for (int step = 1; step < m; ++step) {\n                int nxt = -1;\n                int bestD = INT_MAX;\n                for (int v = 0; v < m; ++v) if (!used[v]) {\n                    int d = D[cur][v];\n                    if (d < bestD) { bestD = d; nxt = v; }\n                }\n                used[nxt] = 1;\n                perm.push_back(nxt);\n                cur = nxt;\n            }\n            long long c = tourCost(perm, start, finish, D, insideSum);\n            if (c < bestCost) {\n                bestCost = c;\n                bestPerm = perm;\n            }\n        }\n\n        if (!full) {\n            outPerm = bestPerm;\n            return bestCost;\n        }\n\n        // ----- full improvement (insertion, swap, 2\u2011opt) ----------\n        vector<int> perm = bestPerm;\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            // insertion\n            for (int i = 0; i < m && !improved; ++i) {\n                for (int j = 0; j < m && !improved; ++j) if (i != j) {\n                    vector<int> np = perm;\n                    int val = np[i];\n                    np.erase(np.begin() + i);\n                    np.insert(np.begin() + j, val);\n                    long long c = tourCost(np, start, finish, D, insideSum);\n                    if (c < tourCost(perm, start, finish, D, insideSum)) {\n                        perm.swap(np);\n                        improved = true;\n                    }\n                }\n            }\n            // swap\n            if (!improved) {\n                for (int i = 0; i < m && !improved; ++i) {\n                    for (int j = i + 1; j < m && !improved; ++j) {\n                        vector<int> np = perm;\n                        swap(np[i], np[j]);\n                        long long c = tourCost(np, start, finish, D, insideSum);\n                        if (c < tourCost(perm, start, finish, D, insideSum)) {\n                            perm.swap(np);\n                            improved = true;\n                        }\n                    }\n                }\n            }\n            // 2\u2011opt (reverse a segment)\n            if (!improved) {\n                for (int i = 0; i < m - 2 && !improved; ++i) {\n                    for (int j = i + 2; j < m && !improved; ++j) {\n                        vector<int> np = perm;\n                        reverse(np.begin() + i + 1, np.begin() + j + 1);\n                        long long c = tourCost(np, start, finish, D, insideSum);\n                        if (c < tourCost(perm, start, finish, D, insideSum)) {\n                            perm.swap(np);\n                            improved = true;\n                        }\n                    }\n                }\n            }\n        }\n        outPerm = perm;\n        return tourCost(perm, start, finish, D, insideSum);\n    };\n\n    // ----- evaluate many random subsets (cheap only) ------------\n    for (int iter = 0; iter < SAMPLE; ++iter) {\n        vector<int> cand2 = cand;\n        shuffle(cand2.begin(), cand2.end(), rng);\n        vector<int> ids(cand2.begin(), cand2.begin() + 50);\n        vector<int> dummyPerm;\n        long long c = evaluateSubset(ids, false, dummyPerm);\n        samples.push_back({ids, c});\n    }\n    // also add the deterministic top\u201150 set\n    {\n        vector<int> ids(idx.begin(), idx.begin() + 50);\n        vector<int> dummy;\n        long long c = evaluateSubset(ids, false, dummy);\n        samples.push_back({ids, c});\n    }\n\n    // keep the 5 best subsets\n    const int KEEP = 5;\n    nth_element(samples.begin(),\n                samples.begin() + KEEP,\n                samples.end(),\n                [](const SubsetInfo& a, const SubsetInfo& b){ return a.cost < b.cost; });\n    samples.resize(KEEP);\n\n    // ----- full improvement on the best subsets -----------------\n    long long bestTotal = (1LL<<60);\n    vector<int> bestIds;\n    vector<int> bestPerm;\n\n    for (auto& s : samples) {\n        vector<int> perm;\n        long long c = evaluateSubset(s.ids, true, perm);\n        if (c < bestTotal) {\n            bestTotal = c;\n            bestIds = s.ids;\n            bestPerm = perm;\n        }\n    }\n\n    // ----- build the output route --------------------------------\n    // bestIds : original order numbers (0\u2011based)\n    // bestPerm : permutation of 0..49  (local index -> order in bestIds)\n\n    // sort the ids for nicer output\n    sort(bestIds.begin(), bestIds.end());\n\n    // route coordinates\n    vector<int> routeX, routeY;\n    routeX.push_back(DEP);\n    routeY.push_back(DEP);\n    for (int k = 0; k < 50; ++k) {\n        int local = bestPerm[k];\n        int orig  = bestIds[local];\n        routeX.push_back(ord[orig].a);\n        routeY.push_back(ord[orig].b);\n        routeX.push_back(ord[orig].c);\n        routeY.push_back(ord[orig].d);\n    }\n    routeX.push_back(DEP);\n    routeY.push_back(DEP);\n    const int n = (int)routeX.size();           // = 2*50+2 = 102\n\n    // ----- output -------------------------------------------------\n    cout << 50;\n    for (int id : bestIds) cout << ' ' << (id + 1);\n    cout << '\\n';\n    cout << n;\n    for (size_t i = 0; i < routeX.size(); ++i)\n        cout << ' ' << routeX[i] << ' ' << routeY[i];\n    cout << '\\n';\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** Disjoint Set Union ***/\nstruct DSU {\n    vector<int> parent, rnk;\n    DSU(int n = 0) { init(n); }\n    void init(int n) {\n        parent.resize(n);\n        rnk.assign(n, 0);\n        iota(parent.begin(), parent.end(), 0);\n    }\n    int find(int x) {\n        if (parent[x] == x) return x;\n        return parent[x] = find(parent[x]);\n    }\n    bool unite(int a, int b) {\n        a = find(a); b = find(b);\n        if (a == b) return false;\n        if (rnk[a] < rnk[b]) swap(a, b);\n        parent[b] = a;\n        if (rnk[a] == rnk[b]) ++rnk[a];\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 400;   // fixed by the problem statement\n    const int M = 1995;  // fixed by the problem statement\n\n    /* ----- read the coordinates (they are not needed later) ----- */\n    for (int i = 0; i < N; ++i) {\n        long long x, y;\n        cin >> x >> y;    // values are read but ignored\n    }\n\n    /* ----- read the edge list ----- */\n    vector<int> U(M), V(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> U[i] >> V[i];\n    }\n\n    DSU dsu(N);\n\n    /* ----- process the lengths one by one ----- */\n    for (int i = 0; i < M; ++i) {\n        long long len;\n        cin >> len;                // the true length of the i\u2011th edge\n\n        if (dsu.find(U[i]) != dsu.find(V[i])) {\n            // edge connects two different components \u2192 accept it\n            cout << 1 << '\\n';\n            dsu.unite(U[i], V[i]);\n        } else {\n            // creates a cycle \u2192 reject\n            cout << 0 << '\\n';\n        }\n        cout.flush();               // required by the statement\n    }\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing pii = pair<int,int>;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int H = 30, W = 30;\n    const int dr[4] = {-1, 1, 0, 0};\n    const int dc[4] = {0, 0, -1, 1};\n    const char wallChar[4] = {'u','d','l','r'};\n    const char moveChar[4] = {'U','D','L','R'};\n\n    /* ---------- input ---------- */\n    int N;                 // number of pets\n    if(!(cin >> N)) return 0;\n    vector<pii> petPos(N);\n    vector<int> petType(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> petPos[i].first >> petPos[i].second >> petType[i];\n    }\n    int M;                 // number of humans\n    cin >> M;\n    vector<pii> humanPos(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> humanPos[i].first >> humanPos[i].second;\n    }\n\n    /* ---------- simulation ---------- */\n    bool wall[H+2][W+2] = {};          // permanent walls\n    bool newWall[H+2][W+2];             // walls built this turn\n\n    for (int turn = 0; turn < 300; ++turn) {\n        /* occupancy and adjacency of pets */\n        static bool occPet[H+2][W+2];\n        static bool occHuman[H+2][W+2];\n        static bool adjPet[H+2][W+2];\n        for (int i = 1; i <= 30; ++i)\n            for (int j = 1; j <= 30; ++j)\n                occPet[i][j] = occHuman[i][j] = adjPet[i][j] = false;\n\n        for (auto &p : petPos)  occPet[p.first][p.second] = true;\n        for (auto &h : humanPos) occHuman[h.first][h.second] = true;\n\n        for (auto &p : petPos) {\n            for (int d = 0; d < 4; ++d) {\n                int nr = p.first + dr[d];\n                int nc = p.second + dc[d];\n                if (nr < 1 || nr > 30 || nc < 1 || nc > 30) continue;\n                adjPet[nr][nc] = true;\n            }\n        }\n\n        /* clear temporary wall array */\n        for (int i = 1; i <= 30; ++i)\n            for (int j = 1; j <= 30; ++j)\n                newWall[i][j] = false;\n\n        vector<char> action(M, '.');\n        vector<pii> moveDest(M);\n\n        for (int i = 0; i < M; ++i) {\n            int hx = humanPos[i].first;\n            int hy = humanPos[i].second;\n            bool placed = false;\n\n            /* ----- try to place a wall ----- */\n            for (int d = 0; d < 4 && !placed; ++d) {\n                int nx = hx + dr[d];\n                int ny = hy + dc[d];\n                if (nx < 1 || nx > 30 || ny < 1 || ny > 30) continue;\n                if (wall[nx][ny]) continue;\n                if (newWall[nx][ny]) continue;\n                if (occPet[nx][ny]) continue;\n                if (occHuman[nx][ny]) continue;\n                if (adjPet[nx][ny]) continue;\n                // place wall\n                action[i] = wallChar[d];\n                newWall[nx][ny] = true;\n                placed = true;\n            }\n\n            if (placed) {\n                moveDest[i] = {hx, hy};\n                continue;\n            }\n\n            /* ----- cannot wall \u2013 try to move ----- */\n            bool moved = false;\n            for (int d = 0; d < 4 && !moved; ++d) {\n                int nx = hx + dr[d];\n                int ny = hy + dc[d];\n                if (nx < 1 || nx > 30 || ny < 1 || ny > 30) continue;\n                if (wall[nx][ny]) continue;\n                if (newWall[nx][ny]) continue;      // would become a wall now\n                action[i] = moveChar[d];\n                moveDest[i] = {nx, ny};\n                moved = true;\n            }\n            if (!moved) {\n                action[i] = '.';\n                moveDest[i] = {hx, hy};\n            }\n        }\n\n        /* ----- output ----- */\n        for (int i = 0; i < M; ++i) cout << action[i];\n        cout << '\\n' << flush;\n\n        /* ----- apply walls ----- */\n        for (int i = 1; i <= 30; ++i)\n            for (int j = 1; j <= 30; ++j)\n                if (newWall[i][j]) wall[i][j] = true;\n\n        /* ----- apply human moves ----- */\n        for (int i = 0; i < M; ++i) {\n            if (action[i] >= 'A' && action[i] <= 'Z')\n                humanPos[i] = moveDest[i];\n        }\n\n        /* ----- read and apply pet moves ----- */\n        for (int i = 0; i < N; ++i) {\n            string s; cin >> s;\n            for (char c : s) {\n                if (c == '.') continue;\n                int dir = 0;\n                if (c == 'U') dir = 0;\n                else if (c == 'D') dir = 1;\n                else if (c == 'L') dir = 2;\n                else if (c == 'R') dir = 3;\n                int nx = petPos[i].first + dr[dir];\n                int ny = petPos[i].second + dc[dir];\n                if (nx < 1 || nx > 30 || ny < 1 || ny > 30) continue;\n                if (wall[nx][ny]) continue;          // impassable\n                petPos[i] = {nx, ny};\n            }\n        }\n    }\n\n    /* ---------- final scoring ---------- */\n    long double sumS = 0.0L;\n    static bool vis[H+2][W+2];\n    for (int i = 0; i < M; ++i) {\n        for (int r = 1; r <= 30; ++r)\n            for (int c = 1; c <= 30; ++c)\n                vis[r][c] = false;\n\n        queue<pii> q;\n        int sx = humanPos[i].first, sy = humanPos[i].second;\n        vis[sx][sy] = true;\n        q.emplace(sx, sy);\n        int reach = 0;\n        while (!q.empty()) {\n            auto [x, y] = q.front(); q.pop();\n            ++reach;\n            for (int d = 0; d < 4; ++d) {\n                int nx = x + dr[d];\n                int ny = y + dc[d];\n                if (nx < 1 || nx > 30 || ny < 1 || ny > 30) continue;\n                if (wall[nx][ny]) continue;\n                if (vis[nx][ny]) continue;\n                vis[nx][ny] = true;\n                q.emplace(nx, ny);\n            }\n        }\n\n        int petsInside = 0;\n        for (auto &p : petPos)\n            if (vis[p.first][p.second]) ++petsInside;\n\n        long double s = (long double)reach / 900.0L *\n                        powl(2.0L, -(long double)petsInside);\n        sumS += s;\n    }\n\n    long double avg = sumS / (long double)M;\n    long long score = llround(avg * 1e8L);\n    // (the judge does not need the score printed)\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj, ti, tj;\n    double p;\n    if (!(cin >> si >> sj >> ti >> tj >> p)) return 0;\n\n    vector<string> h(20);\n    for (int i = 0; i < 20; ++i) cin >> h[i];\n    vector<string> v(19);\n    for (int i = 0; i < 19; ++i) cin >> v[i];\n\n    // wall[i][j][dir] : true if movement in direction dir from (i,j) is blocked\n    // dir: 0=U,1=D,2=L,3=R\n    bool wall[20][20][4];\n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            wall[i][j][0] = (i == 0) ? true : (v[i-1][j] == '1');          // up\n            wall[i][j][1] = (i == 19) ? true : (v[i][j] == '1');          // down\n            wall[i][j][2] = (j == 0) ? true : (h[i][j-1] == '1');          // left\n            wall[i][j][3] = (j == 19) ? true : (h[i][j] == '1');          // right\n        }\n    }\n\n    const int L = 200;\n    const int N = 20 * 20;\n    const int target = ti * 20 + tj;\n    const int start = si * 20 + sj;\n\n    // dp[t][v] : maximal expected score from turn t, square v\n    vector<vector<double>> dp(L + 2, vector<double>(N, 0.0));\n    vector<vector<int>> best(L + 2, vector<int>(N, -1));\n\n    // dp[t][target] = 0 already (vector initialised with 0)\n    for (int t = L; t >= 1; --t) {\n        for (int pos = 0; pos < N; ++pos) {\n            if (pos == target) {\n                dp[t][pos] = 0.0;\n                best[t][pos] = -1;\n                continue;\n            }\n            int i = pos / 20, j = pos % 20;\n            double bestVal = -1.0;\n            int bestDir = 0;\n            for (int d = 0; d < 4; ++d) {\n                bool w = wall[i][j][d];\n                double stayProb = p + (1.0 - p) * (w ? 1.0 : 0.0);\n                double moveProb = (1.0 - p) * (w ? 0.0 : 1.0);\n\n                double expected = stayProb * dp[t + 1][pos];\n                if (moveProb > 0.0) {\n                    int ni = i, nj = j;\n                    if (d == 0) --ni;\n                    else if (d == 1) ++ni;\n                    else if (d == 2) --nj;\n                    else ++nj;\n                    int npos = ni * 20 + nj;\n                    if (npos == target) {\n                        expected += moveProb * (401 - t);\n                    } else {\n                        expected += moveProb * dp[t + 1][npos];\n                    }\n                }\n                if (expected > bestVal + 1e-12) {\n                    bestVal = expected;\n                    bestDir = d;\n                }\n            }\n            dp[t][pos] = bestVal;\n            best[t][pos] = bestDir;\n        }\n    }\n\n    // reconstruction of a concrete string\n    string ans;\n    ans.reserve(L);\n    int cur = start;\n    for (int t = 1; t <= L; ++t) {\n        int d = best[t][cur];\n        char c;\n        if (d == 0) c = 'U';\n        else if (d == 1) c = 'D';\n        else if (d == 2) c = 'L';\n        else c = 'R';\n        ans.push_back(c);\n\n        int i = cur / 20, j = cur % 20;\n        if (!wall[i][j][d]) {               // intended move succeeds\n            if (d == 0) --i;\n            else if (d == 1) ++i;\n            else if (d == 2) --j;\n            else ++j;\n            cur = i * 20 + j;\n        }\n        // if we are already at the target we keep outputting arbitrary\n        // directions \u2013 they will never be executed.\n    }\n\n    cout << ans << '\\n';\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int C = N * N;               // 900 cells\nconst int DIRS = 4;\nconst int STATES = C * DIRS;       // 3600 states\n\nint di[DIRS] = {0, -1, 0, 1};\nint dj[DIRS] = {-1, 0, 1, 0};\n\nint orig_tile[C];                  // original type (0..7)\n\n/* -------------------------------------------------------------\n   table to[t][d]  \u2013 entering direction d, exiting direction\n   ------------------------------------------------------------- */\nint to_orig[8][DIRS] = {\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 to_rot[8][4][DIRS];            // [type][rotation][entry]\n\n/* -------------------------------------------------------------\n   compute the score (L1 * L2) for a given rotation\n   ------------------------------------------------------------- */\nint next_state[STATES];\nint visited_state[STATES];\nint step_idx[STATES];\nvector<int> path;\n\ninline long long compute_score(const int rot[C]) {\n    // build the transition function\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int t = orig_tile[i * N + j];\n            int r = rot[i * N + j];\n            int base = (i * N + j) * DIRS;\n            for (int d = 0; d < DIRS; ++d) {\n                int exit = to_rot[t][r][d];\n                if (exit == -1) {\n                    next_state[base + d] = -1;\n                    continue;\n                }\n                int ni = i + di[exit];\n                int nj = j + dj[exit];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) {\n                    next_state[base + d] = -1;\n                    continue;\n                }\n                int nd = (exit + 2) & 3;\n                next_state[base + d] = (ni * N + nj) * DIRS + nd;\n            }\n        }\n    }\n\n    // find all directed cycles\n    fill(visited_state, visited_state + STATES, 0);\n    fill(step_idx, step_idx + STATES, -1);\n    vector<int> cycles;\n    for (int s = 0; s < STATES; ++s) {\n        if (next_state[s] == -1 || visited_state[s]) continue;\n        int cur = s;\n        path.clear();\n        while (true) {\n            if (next_state[cur] == -1) break;               // dead end\n            if (visited_state[cur]) break;                  // already processed\n            if (step_idx[cur] != -1) {                      // a new cycle\n                int start = step_idx[cur];\n                int len = (int)path.size() - start;\n                cycles.push_back(len);\n                break;\n            }\n            step_idx[cur] = (int)path.size();\n            path.push_back(cur);\n            cur = next_state[cur];\n        }\n        for (int v : path) {\n            visited_state[v] = 1;\n            step_idx[v] = -1;\n        }\n    }\n\n    if (cycles.empty()) return 0LL;\n    sort(cycles.rbegin(), cycles.rend());\n    long long L1 = cycles[0];\n    long long L2 = (cycles.size() >= 2) ? cycles[1] : 0LL;\n    return L1 * L2;\n}\n\n/* -------------------------------------------------------------\n   main\n   ------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* read the board */\n    string line;\n    for (int i = 0; i < N; ++i) {\n        cin >> line;\n        for (int j = 0; j < N; ++j) orig_tile[i * N + j] = line[j] - '0';\n    }\n\n    /* pre\u2011compute rotated tables */\n    for (int t = 0; t < 8; ++t)\n        for (int r = 0; r < 4; ++r)\n            for (int d = 0; d < DIRS; ++d) {\n                int src = (d - r + 4) % 4;\n                int e = to_orig[t][src];\n                to_rot[t][r][d] = (e == -1) ? -1 : (e + r) % 4;\n            }\n\n    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist_rot(0, 3);\n    uniform_int_distribution<int> dist_cell(0, C - 1);\n    uniform_real_distribution<double> dist_prob(0.0, 1.0);\n\n    /* ---------- initial random rotation ------------------------ */\n    int curRot[C];\n    for (int i = 0; i < C; ++i) curRot[i] = dist_rot(rng);\n\n    /* optional greedy improvement (maximise matched sides) */\n    const int GREEDY_PASSES = 4;\n    for (int p = 0; p < GREEDY_PASSES; ++p) {\n        bool changed = false;\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j) {\n                int idx = i * N + j;\n                int t = orig_tile[idx];\n                int best_r = curRot[idx];\n                int best_match = -1;\n                for (int r = 0; r < 4; ++r) {\n                    int match = 0;\n                    for (int d = 0; d < DIRS; ++d) {\n                        int exit = to_rot[t][r][d];\n                        if (exit == -1) continue;\n                        int ni = i + di[exit];\n                        int nj = j + dj[exit];\n                        if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                        int nb = ni * N + nj;\n                        int nb_t = orig_tile[nb];\n                        int nb_r = curRot[nb];\n                        int nb_entry = (exit + 2) & 3;\n                        if (to_rot[nb_t][nb_r][nb_entry] != -1) ++match;\n                    }\n                    if (match > best_match) {\n                        best_match = match;\n                        best_r = r;\n                    }\n                }\n                if (best_r != curRot[idx]) {\n                    curRot[idx] = best_r;\n                    changed = true;\n                }\n            }\n        if (!changed) break;\n    }\n\n    /* ---------- simulated annealing --------------------------- */\n    const int MAX_ITER = 400000;\n    const double T0 = 800.0;\n    const double DECAY = 0.9996;\n\n    long long curScore = compute_score(curRot);\n    long long bestScore = curScore;\n    int bestRot[C];\n    copy(begin(curRot), end(curRot), begin(bestRot));\n\n    double T = T0;\n    auto start = chrono::steady_clock::now();\n\n    for (int it = 0; it < MAX_ITER; ++it) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start).count();\n        if (elapsed > 1.85) break;               // stay within the time limit\n\n        int idx = dist_cell(rng);\n        int old_r = curRot[idx];\n        int new_r = dist_rot(rng);\n        if (new_r == old_r) new_r = (old_r + 1) & 3;   // force a change\n        curRot[idx] = new_r;\n\n        long long newScore = compute_score(curRot);\n        long long delta = newScore - curScore;\n\n        if (delta > 0) {\n            // accept the improvement\n            curScore = newScore;\n            if (newScore > bestScore) {\n                bestScore = newScore;\n                copy(begin(curRot), end(curRot), begin(bestRot));\n            }\n        } else {\n            // Metropolis acceptance of a worse move\n            if (dist_prob(rng) < exp((double)delta / T)) {\n                curScore = newScore;               // keep the worse state\n            } else {\n                curRot[idx] = old_r;                // revert\n            }\n        }\n\n        T = T0 * pow(DECAY, it + 1);\n    }\n\n    /* ---------- hill\u2011climbing (local search) ------------------- */\n    // make curRot the best configuration found so far\n    copy(begin(bestRot), end(bestRot), begin(curRot));\n    curScore = bestScore;\n\n    const int HILL_PASSES = 2;\n    for (int pass = 0; pass < HILL_PASSES; ++pass) {\n        bool any = false;\n        for (int idx = 0; idx < C; ++idx) {\n            int saved_r = curRot[idx];\n            for (int r = 0; r < 4; ++r) {\n                if (r == saved_r) continue;\n                curRot[idx] = r;\n                long long ns = compute_score(curRot);\n                if (ns > curScore) {\n                    curScore = ns;\n                    if (ns > bestScore) {\n                        bestScore = ns;\n                        copy(begin(curRot), end(curRot), begin(bestRot));\n                    }\n                    any = true;\n                    break;          // stay at this tile, try next tile\n                } else {\n                    curRot[idx] = saved_r; // restore\n                }\n            }\n            if (any) break;          // a change happened \u2013 start new pass\n        }\n        if (!any) break;             // no improvement in this pass\n    }\n\n    /* ---------- output --------------------------------------- */\n    string out;\n    out.reserve(C);\n    for (int i = 0; i < C; ++i) out.push_back(char('0' + bestRot[i]));\n    cout << out << '\\n';\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* --------------------------------------------------------------\n   helpers for bit handling\n   -------------------------------------------------------------- */\nint bitFromDelta(int dr, int dc)               // direction -> bit\n{\n    if (dr == -1 && dc == 0) return 2;   // up\n    if (dr ==  1 && dc == 0) return 8;   // down\n    if (dr ==  0 && dc ==-1) return 1;   // left\n    if (dr ==  0 && dc == 1) return 4;   // right\n    return 0;\n}\nint idxFromDelta(int dr, int dc)               // direction -> index 0..3\n{\n    if (dr == -1 && dc == 0) return 0;   // up\n    if (dr ==  1 && dc == 0) return 1;   // down\n    if (dr ==  0 && dc ==-1) return 2;   // left\n    if (dr ==  0 && dc == 1) return 3;   // right\n    return -1;\n}\nint oppositeBit(int b)                         // opposite direction\n{\n    if (b == 1) return 4;\n    if (b == 4) return 1;\n    if (b == 2) return 8;\n    if (b == 8) return 2;\n    return 0;\n}\nchar charFromDelta(int dr, int dc)            // direction -> move character\n{\n    int id = idxFromDelta(dr, dc);\n    static const char mv[4] = {'U','D','L','R'};\n    return (id == -1 ? '?' : mv[id]);\n}\n\n/* --------------------------------------------------------------\n   global data\n   -------------------------------------------------------------- */\nint N, T;\nvector<vector<int>> board;            // board[r][c] = tile id, -1 = empty\nvector<int> maskOrig;                 // original picture of each tile\nvector<int> curMask;                  // bits still unused\nvector<char> inComponent;             // tile already belongs to the tree\nint er, ec;                           // empty cell\n\nconst int dr[4] = {-1, 1, 0, 0};\nconst int dc[4] = {0, 0, -1, 1};\n\n/* --------------------------------------------------------------\n   after a tile has moved to (r,c) delete all bits that correspond\n   to edges that have just appeared\n   -------------------------------------------------------------- */\nvoid updateEdges(int r, int c)\n{\n    int id = board[r][c];\n    if (id == -1) return;\n    for (int d = 0; d < 4; ++d) {\n        int nr = r + dr[d], nc = c + dc[d];\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n        int nid = board[nr][nc];\n        if (nid == -1) continue;\n        int need = bitFromDelta(dr[d], dc[d]);          // id -> nid\n        int opp  = oppositeBit(need);\n        if ( (curMask[id] & need) && (curMask[nid] & opp) ) {\n            curMask[id]  &= ~need;\n            curMask[nid] &= ~opp;\n        }\n    }\n}\n\n/* --------------------------------------------------------------\n   initial removal of bits belonging to edges that already exist\n   -------------------------------------------------------------- */\nvoid removeInitialEdges()\n{\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (board[i][j] != -1)\n                updateEdges(i, j);\n}\n\n/* --------------------------------------------------------------\n   try to attach a new vertex (Step 1).  Returns true if a move\n   was performed.\n   -------------------------------------------------------------- */\nbool tryAttach(string &answer)\n{\n    for (int d = 0; d < 4; ++d) {\n        int pr = er + dr[d], pc = ec + dc[d];\n        if (pr < 0 || pr >= N || pc < 0 || pc >= N) continue;\n        int parent = board[pr][pc];\n        if (parent == -1 || !inComponent[parent]) continue;\n\n        int needParent = oppositeBit(bitFromDelta(dr[d], dc[d]));\n        if ( (curMask[parent] & needParent) == 0 ) continue;\n\n        int cr = er - dr[d], cc = ec - dc[d];\n        if (cr < 0 || cr >= N || cc < 0 || cc >= N) continue;\n        int child = board[cr][cc];\n        if (child == -1 || inComponent[child]) continue;\n\n        int needChild = bitFromDelta(dr[d], dc[d]);\n        if ( (curMask[child] & needChild) == 0 ) continue;\n\n        /* perform the slide */\n        char ch = charFromDelta(dr[d], dc[d]);      // slide child into empty\n        answer.push_back(ch);\n\n        board[er][ec] = child;\n        board[cr][cc] = -1;\n        er = cr; ec = cc;\n\n        curMask[parent] &= ~needParent;\n        curMask[child]  &= ~needChild;\n        inComponent[child] = 1;\n\n        updateEdges(er, ec);        // edges created by the new tile\n        return true;\n    }\n    return false;\n}\n\n/* --------------------------------------------------------------\n   move the empty square by sliding an unplaced tile (Step 2)\n   -------------------------------------------------------------- */\nvoid moveEmpty(string &answer)\n{\n    for (int d = 0; d < 4; ++d) {\n        int nr = er + dr[d], nc = ec + dc[d];\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n        int tid = board[nr][nc];\n        if (tid == -1) continue;\n        if (inComponent[tid]) continue;          // slide only an unplaced tile\n\n        char ch = charFromDelta(dr[d], dc[d]);   // slide this neighbour\n        answer.push_back(ch);\n\n        board[er][ec] = tid;\n        board[nr][nc] = -1;\n        er = nr; ec = nc;\n\n        updateEdges(er, ec);        // possible new edges\n        return;\n    }\n}\n\n/* --------------------------------------------------------------\n   main\n   -------------------------------------------------------------- */\nint main()\n{\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> T)) return 0;\n    vector<string> raw(N);\n    for (int i = 0; i < N; ++i) cin >> raw[i];\n\n    board.assign(N, vector<int>(N, -1));\n    maskOrig.clear();\n    int id = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            char c = raw[i][j];\n            if (c == '0') {\n                er = i; ec = j;\n                board[i][j] = -1;\n            } else {\n                int v;\n                if ('0' <= c && c <= '9') v = c - '0';\n                else v = 10 + (c - 'a');\n                board[i][j] = id;\n                maskOrig.push_back(v);\n                ++id;\n            }\n        }\n    }\n\n    const int M = N * N - 1;                 // number of tiles\n    curMask = maskOrig;\n    inComponent.assign(M, 0);\n\n    /* delete bits that already belong to edges in the initial board */\n    removeInitialEdges();\n\n    string answer;\n    answer.reserve(T);\n\n    /* ----- Step 0 : place the first tile (the root) ----- */\n    bool placedRoot = false;\n    for (int d = 0; d < 4 && !placedRoot; ++d) {\n        int nr = er + dr[d], nc = ec + dc[d];\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n        int tid = board[nr][nc];\n        if (tid == -1) continue;\n        int dir = bitFromDelta(dr[d], dc[d]);           // direction empty -> neighbour\n        if (maskOrig[tid] & oppositeBit(dir)) {\n            char ch = charFromDelta(dr[d], dc[d]);\n            answer.push_back(ch);\n            board[er][ec] = tid;\n            board[nr][nc] = -1;\n            er = nr; ec = nc;\n            inComponent[tid] = 1;\n            updateEdges(er, ec);\n            placedRoot = true;\n            break;\n        }\n    }\n    if (!placedRoot) {                                 // fallback: any neighbour\n        for (int d = 0; d < 4 && !placedRoot; ++d) {\n            int nr = er + dr[d], nc = ec + dc[d];\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n            int tid = board[nr][nc];\n            if (tid == -1) continue;\n            char ch = charFromDelta(dr[d], dc[d]);\n            answer.push_back(ch);\n            board[er][ec] = tid;\n            board[nr][nc] = -1;\n            er = nr; ec = nc;\n            inComponent[tid] = 1;\n            updateEdges(er, ec);\n            placedRoot = true;\n            break;\n        }\n    }\n\n    int placedCnt = 1;                                 // one tile in the component\n\n    /* --------------------------------------------------------------\n       Main loop \u2013 repeatedly enlarge the component or move the empty\n       -------------------------------------------------------------- */\n    while (placedCnt < M && (int)answer.size() < T) {\n        if (tryAttach(answer)) {\n            ++placedCnt;\n            continue;\n        }\n        moveEmpty(answer);\n    }\n\n    cout << answer << '\\n';\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nusing ull = unsigned long long;\n\nstruct Line {\n    ll px, py, qx, qy;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, Kmax;\n    if (!(cin >> N >> Kmax)) return 0;\n    vector<int> a(11);\n    for (int d = 1; d <= 10; ++d) cin >> a[d];\n    vector<ll> xs(N), ys(N);\n    for (int i = 0; i < N; ++i) cin >> xs[i] >> ys[i];\n\n    int sumA = 0;\n    for (int d = 1; d <= 10; ++d) sumA += a[d];\n\n    /* ---------- parameters of the search ---------- */\n    const int USE_K = 70;            // enough pieces, cheaper than 100\n    const int TRIALS = 1500;         // many more than the original 200\n\n    /* ---------- random number generator ---------- */\n    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<ll> distCoord(-10000, 10000);   // inside the cake\n\n    /* ---------- generate a line that does not hit any strawberry ---------- */\n    auto make_line = [&]() -> Line {\n        for (int tries = 0; tries < 10; ++tries) {\n            ll px = distCoord(rng);\n            ll py = distCoord(rng);\n            ll qx = distCoord(rng);\n            ll qy = distCoord(rng);\n            if (px == qx && py == qy) continue;\n            ll dx = qx - px;\n            ll dy = qy - py;\n            bool ok = true;\n            for (int i = 0; i < N; ++i) {\n                ll cross = dx * (ys[i] - py) - dy * (xs[i] - px);\n                if (cross == 0) { ok = false; break; }\n            }\n            if (ok) return Line{px, py, qx, qy};\n        }\n        // fallback \u2013 a line far away, never hits a strawberry\n        return Line{-1000000, 0, 1000000, 0};\n    };\n\n    /* ---------- containers that are reused every trial ---------- */\n    vector<ull> hi(N), lo(N);\n    vector<pair<ull, ull>> sig(N);\n\n    int bestScore = -1;\n    vector<Line> bestLines;\n\n    for (int trial = 0; trial < TRIALS; ++trial) {\n        /* generate USE_K random lines */\n        vector<Line> lines;\n        lines.reserve(USE_K);\n        for (int i = 0; i < USE_K; ++i) lines.push_back(make_line());\n\n        /* reset signatures */\n        fill(hi.begin(), hi.end(), 0ULL);\n        fill(lo.begin(), lo.end(), 0ULL);\n\n        /* apply every line */\n        for (int li = 0; li < USE_K; ++li) {\n            const Line &L = lines[li];\n            ll dx = L.qx - L.px;\n            ll dy = L.qy - L.py;\n            for (int i = 0; i < N; ++i) {\n                ll cross = dx * (ys[i] - L.py) - dy * (xs[i] - L.px);\n                if (cross > 0) {                         // right side\n                    if (li < 64) lo[i] |= (1ULL << li);\n                    else          hi[i] |= (1ULL << (li - 64));\n                }\n            }\n        }\n\n        /* group equal signatures */\n        for (int i = 0; i < N; ++i) sig[i] = {hi[i], lo[i]};\n        sort(sig.begin(), sig.end());\n\n        vector<int> b(11, 0);            // b[d] = #pieces with d strawberries\n        for (int i = 0; i < N; ) {\n            int j = i;\n            while (j < N && sig[j] == sig[i]) ++j;\n            int sz = j - i;\n            if (1 <= sz && sz <= 10) ++b[sz];\n            i = j;\n        }\n\n        int distributed = 0;\n        for (int d = 1; d <= 10; ++d) distributed += min(a[d], b[d]);\n\n        if (distributed > bestScore) {\n            bestScore = distributed;\n            bestLines = lines;\n            if (distributed == sumA) break;   // perfect, stop early\n        }\n    }\n\n    /* ---------- output ---------- */\n    cout << bestLines.size() << '\\n';\n    for (const Line &L : bestLines)\n        cout << L.px << ' ' << L.py << ' ' << L.qx << ' ' << L.qy << '\\n';\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Candidate {\n    int mx, my;                       // missing corner\n    array<pair<int,int>,3> others;    // the three existing corners\n};\n\nint N, M;\nint center_;\nbool hasDot[61][61];\n\n/* data structures for dot queries */\nvector< set<int> > dotX, dotY;                     // 0 \u2026 N\u20111\nunordered_map<int, set<int> > dotD, dotS;        // d = x\u2011y , s = x+y\n\n/* data structures for generating candidates */\nvector< vector<pair<int,int>> > dotsAtS;               // s \u2192 list of points\nunordered_map<int, vector<pair<int,int>> > dotsAtD;   // d \u2192 list of points\n\n/* already drawn edges */\nunordered_map<int, set<pair<int,int>>> edgeHor;   // y \u2192 intervals of x\nunordered_map<int, set<pair<int,int>>> edgeVer;   // x \u2192 intervals of y\nunordered_map<int, set<pair<int,int>>> edgeDiagP; // d \u2192 intervals of x\nunordered_map<int, set<pair<int,int>>> edgeDiagM; // s \u2192 intervals of x\n\ninline int weight(int x, int y) {\n    int dx = x - center_;\n    int dy = y - center_;\n    return dx*dx + dy*dy + 1;\n}\n\n/* ---------- helpers for edges ---------- */\n\ninline bool adjacent(const pair<int,int>& a, const pair<int,int>& b) {\n    return (a.first == b.first) ||\n           (a.second == b.second) ||\n           (a.first - a.second == b.first - b.second) ||\n           (a.first + a.second == b.first + b.second);\n}\n\n/* overlap test for one line */\nbool hasOverlapOnLine(const unordered_map<int, set<pair<int,int>>>& mp,\n                      int line, int l, int r) {\n    auto it = mp.find(line);\n    if (it == mp.end()) return false;\n    const auto& st = it->second;\n    auto itr = st.lower_bound({l, INT_MIN});\n    if (itr != st.end()) {\n        int l2 = itr->first, r2 = itr->second;\n        if (max(l, l2) <= min(r, r2) - 1) return true;\n    }\n    if (itr != st.begin()) {\n        --itr;\n        int l2 = itr->first, r2 = itr->second;\n        if (max(l, l2) <= min(r, r2) - 1) return true;\n    }\n    return false;\n}\n\n/* check whether side (a,b) overlaps an existing edge */\nbool edgeOverlap(const pair<int,int>& a, const pair<int,int>& b) {\n    if (a.first == b.first) {                     // vertical\n        int x = a.first;\n        int l = min(a.second, b.second);\n        int r = max(a.second, b.second);\n        return hasOverlapOnLine(edgeVer, x, l, r);\n    } else if (a.second == b.second) {           // horizontal\n        int y = a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        return hasOverlapOnLine(edgeHor, y, l, r);\n    } else if (a.first - a.second == b.first - b.second) { // diag +1\n        int d = a.first - a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        return hasOverlapOnLine(edgeDiagP, d, l, r);\n    } else {                                      // diag -1\n        int s = a.first + a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        return hasOverlapOnLine(edgeDiagM, s, l, r);\n    }\n}\n\n/* insert an edge into the stored sets */\nvoid addEdgeToSet(const pair<int,int>& a, const pair<int,int>& b) {\n    if (a.first == b.first) {\n        int x = a.first;\n        int l = min(a.second, b.second);\n        int r = max(a.second, b.second);\n        edgeVer[x].insert({l, r});\n    } else if (a.second == b.second) {\n        int y = a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        edgeHor[y].insert({l, r});\n    } else if (a.first - a.second == b.first - b.second) {\n        int d = a.first - a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        edgeDiagP[d].insert({l, r});\n    } else {\n        int s = a.first + a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        edgeDiagM[s].insert({l, r});\n    }\n}\n\n/* does any dot lie on the open interval of the side ? */\nbool dotOnEdgeOpen(const pair<int,int>& a, const pair<int,int>& b) {\n    if (a.first == b.first) {                 // vertical\n        int x = a.first;\n        int lo = min(a.second, b.second);\n        int hi = max(a.second, b.second);\n        const auto& st = dotX[x];\n        auto it = st.lower_bound(lo + 1);\n        if (it != st.end() && *it <= hi - 1) return true;\n        return false;\n    } else if (a.second == b.second) {       // horizontal\n        int y = a.second;\n        int lo = min(a.first, b.first);\n        int hi = max(a.first, b.first);\n        const auto& st = dotY[y];\n        auto it = st.lower_bound(lo + 1);\n        if (it != st.end() && *it <= hi - 1) return true;\n        return false;\n    } else if (a.first - a.second == b.first - b.second) { // diag +1\n        int d = a.first - a.second;\n        int lo = min(a.first, b.first);\n        int hi = max(a.first, b.first);\n        const auto& st = dotD[d];\n        auto it = st.lower_bound(lo + 1);\n        if (it != st.end() && *it <= hi - 1) return true;\n        return false;\n    } else {                                   // diag -1\n        int s = a.first + a.second;\n        int lo = min(a.first, b.first);\n        int hi = max(a.first, b.first);\n        const auto& st = dotS[s];\n        auto it = st.lower_bound(lo + 1);\n        if (it != st.end() && *it <= hi - 1) return true;\n        return false;\n    }\n}\n\n/* ---------- test a candidate ---------- */\nbool isValidMove(const Candidate& cand) {\n    array<pair<int,int>,4> pts;\n    pts[0] = {cand.mx, cand.my};\n    pts[1] = cand.others[0];\n    pts[2] = cand.others[1];\n    pts[3] = cand.others[2];\n\n    // collect the four sides\n    vector<pair<pair<int,int>, pair<int,int>>> sides;\n    for (int i = 0; i < 4; ++i)\n        for (int j = i+1; j < 4; ++j)\n            if (adjacent(pts[i], pts[j]))\n                sides.push_back({pts[i], pts[j]});\n\n    if (sides.size() != 4) return false;   // should not happen\n\n    for (auto &e : sides) {\n        if (edgeOverlap(e.first, e.second)) return false;\n        if (dotOnEdgeOpen(e.first, e.second)) return false;\n    }\n    return true;\n}\n\n/* ---------- total length of the four sides (heuristic) ---------- */\nint totalEdgeLength(const Candidate& cand) {\n    array<pair<int,int>,4> pts;\n    pts[0] = {cand.mx, cand.my};\n    pts[1] = cand.others[0];\n    pts[2] = cand.others[1];\n    pts[3] = cand.others[2];\n\n    int len = 0;\n    for (int i = 0; i < 4; ++i)\n        for (int j = i+1; j < 4; ++j)\n            if (adjacent(pts[i], pts[j])) {\n                int dx = pts[i].first - pts[j].first;\n                int dy = pts[i].second - pts[j].second;\n                len += max(abs(dx), abs(dy));   // side length\n            }\n    return len;\n}\n\n/* ---------- add a new dot ---------- */\nvoid addDot(int x, int y) {\n    hasDot[x][y] = true;\n    dotX[x].insert(y);\n    dotY[y].insert(x);\n    int d = x - y;\n    int s = x + y;\n    dotD[d].insert(x);\n    dotS[s].insert(x);\n\n    dotsAtS[s].push_back({x, y});\n    dotsAtD[d].push_back({x, y});\n}\n\n/* ---------- ordering for output ---------- */\nvector<pair<int,int>> order4(const Candidate& cand) {\n    array<pair<int,int>,4> pts;\n    pts[0] = {cand.mx, cand.my};\n    pts[1] = cand.others[0];\n    pts[2] = cand.others[1];\n    pts[3] = cand.others[2];\n\n    vector<pair<int,int>> neighbors;\n    int oppIdx = -1;\n    for (int i = 1; i < 4; ++i) {\n        if (adjacent(pts[0], pts[i]))\n            neighbors.push_back(pts[i]);\n        else\n            oppIdx = i;\n    }\n    // safety \u2013 should never happen for a legal rectangle\n    if (neighbors.size() != 2 || oppIdx == -1)\n        return {pts[0], pts[1], pts[2], pts[3]};\n\n    vector<pair<int,int>> res;\n    res.push_back(pts[0]);               // the new dot\n    res.push_back(neighbors[0]);         // one neighbour\n    res.push_back(pts[oppIdx]);          // opposite corner\n    res.push_back(neighbors[1]);         // the other neighbour\n    return res;\n}\n\n/* --------------------------------------------------------------- */\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> M;\n    center_ = (N - 1) / 2;\n\n    /* random generator for tie\u2011breaking */\n    std::mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n\n    dotX.assign(N, {});\n    dotY.assign(N, {});\n    dotsAtS.assign(2*N-1, {});\n\n    for (int i = 0; i < M; ++i) {\n        int x, y; cin >> x >> y;\n        addDot(x, y);\n    }\n\n    long long sumW = 0;\n    for (int x = 0; x < N; ++x)\n        for (int y = 0; y < N; ++y)\n            if (hasDot[x][y]) sumW += weight(x, y);\n\n    vector< array<int,8> > operations;\n\n    /* ------------------- main greedy loop ------------------- */\n    while (true) {\n        vector<Candidate> cand;\n        cand.reserve(80000);\n\n        /* ----- axis\u2011parallel rectangles ----- */\n        for (int x = 0; x < N; ++x) {\n            const auto& ys = dotX[x];\n            vector<int> yvec(ys.begin(), ys.end());\n            int sz = (int)yvec.size();\n            for (int i = 0; i < sz; ++i) {\n                int y1 = yvec[i];\n                for (int j = i+1; j < sz; ++j) {\n                    int y2 = yvec[j];\n                    for (int x2 = 0; x2 < N; ++x2) if (x2 != x) {\n                        bool has1 = hasDot[x2][y1];\n                        bool has2 = hasDot[x2][y2];\n                        if (has1 && !has2) {                // missing (x2 , y2)\n                            if (!hasDot[x2][y2]) {\n                                Candidate c;\n                                c.mx = x2; c.my = y2;\n                                c.others[0] = {x, y1};\n                                c.others[1] = {x, y2};\n                                c.others[2] = {x2, y1};\n                                cand.push_back(c);\n                            }\n                        } else if (!has1 && has2) {        // missing (x2 , y1)\n                            if (!hasDot[x2][y1]) {\n                                Candidate c;\n                                c.mx = x2; c.my = y1;\n                                c.others[0] = {x, y1};\n                                c.others[1] = {x, y2};\n                                c.others[2] = {x2, y2};\n                                cand.push_back(c);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        /* ----- 45\u00b0 squares ----- */\n        for (int s = 0; s < 2*N-1; ++s) {\n            const auto &vec = dotsAtS[s];\n            int sz = (int)vec.size();\n            for (int i = 0; i < sz; ++i) {\n                auto A = vec[i];\n                for (int j = i+1; j < sz; ++j) {\n                    auto B = vec[j];\n                    int dA = A.first - A.second;\n                    int dB = B.first - B.second;\n\n                    // C with d = dA\n                    auto itA = dotsAtD.find(dA);\n                    if (itA != dotsAtD.end()) {\n                        for (auto C : itA->second) {\n                            if (C.first + C.second == s) continue; // same s\n                            int s2 = C.first + C.second;\n                            int xm = (s2 + dB) / 2;\n                            int ym = (s2 - dB) / 2;\n                            if (xm < 0 || xm >= N || ym < 0 || ym >= N) continue;\n                            if (hasDot[xm][ym]) continue;\n                            Candidate c;\n                            c.mx = xm; c.my = ym;\n                            c.others[0] = A;\n                            c.others[1] = B;\n                            c.others[2] = C;\n                            cand.push_back(c);\n                        }\n                    }\n                    // C with d = dB\n                    auto itB = dotsAtD.find(dB);\n                    if (itB != dotsAtD.end()) {\n                        for (auto C : itB->second) {\n                            if (C.first + C.second == s) continue;\n                            int s2 = C.first + C.second;\n                            int xm = (s2 + dA) / 2;\n                            int ym = (s2 - dA) / 2;\n                            if (xm < 0 || xm >= N || ym < 0 || ym >= N) continue;\n                            if (hasDot[xm][ym]) continue;\n                            Candidate c;\n                            c.mx = xm; c.my = ym;\n                            c.others[0] = A;\n                            c.others[1] = B;\n                            c.others[2] = C;\n                            cand.push_back(c);\n                        }\n                    }\n                }\n            }\n        }\n\n        /* ----- choose best move ----- */\n        int bestW = -1;\n        int bestLen = INT_MAX;\n        int chosen = -1;\n        for (int i = 0; i < (int)cand.size(); ++i) {\n            if (!isValidMove(cand[i])) continue;\n            int w = weight(cand[i].mx, cand[i].my);\n            if (w > bestW) {\n                bestW = w;\n                bestLen = totalEdgeLength(cand[i]);\n                chosen = i;\n            } else if (w == bestW) {\n                int len = totalEdgeLength(cand[i]);\n                if (len < bestLen) {\n                    bestLen = len;\n                    chosen = i;\n                }\n                // if lengths are equal as well, break tie randomly\n                else if (len == bestLen && (rng() % 2)) {\n                    chosen = i;\n                }\n            }\n        }\n        if (chosen == -1) break;               // no more moves\n\n        const Candidate &chosenCand = cand[chosen];\n\n        // add the dot\n        addDot(chosenCand.mx, chosenCand.my);\n        sumW += bestW;\n\n        // add the four edges\n        array<pair<int,int>,4> pts;\n        pts[0] = {chosenCand.mx, chosenCand.my};\n        pts[1] = chosenCand.others[0];\n        pts[2] = chosenCand.others[1];\n        pts[3] = chosenCand.others[2];\n        for (int i = 0; i < 4; ++i)\n            for (int j = i+1; j < 4; ++j)\n                if (adjacent(pts[i], pts[j]))\n                    addEdgeToSet(pts[i], pts[j]);\n\n        // store operation in required order\n        vector<pair<int,int>> order = order4(chosenCand);\n        array<int,8> op;\n        for (int k = 0; k < 4; ++k) {\n            op[2*k]   = order[k].first;\n            op[2*k+1] = order[k].second;\n        }\n        operations.push_back(op);\n    }\n\n    /* ----- output ----- */\n    cout << operations.size() << '\\n';\n    for (auto &op : operations) {\n        for (int i = 0; i < 8; ++i) {\n            if (i) cout << ' ';\n            cout << op[i];\n        }\n        cout << '\\n';\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int SZ = 10;\nconst array<char, 4> DIRS = {'F', 'B', 'L', 'R'};\n\n/* ------------------------------------------------------------\n   tilt the whole board into direction dir\n   ------------------------------------------------------------ */\nvoid tilt(array<array<int, SZ>, SZ> &a, char dir) {\n    if (dir == 'F') {                     // forward \u2192 top\n        for (int c = 0; c < SZ; ++c) {\n            int wr = 0;\n            for (int r = 0; r < SZ; ++r) {\n                if (a[r][c] != 0) {\n                    if (wr != r) {\n                        a[wr][c] = a[r][c];\n                        a[r][c] = 0;\n                    }\n                    ++wr;\n                }\n            }\n        }\n    } else if (dir == 'B') {              // backward \u2192 bottom\n        for (int c = 0; c < SZ; ++c) {\n            int wr = SZ - 1;\n            for (int r = SZ - 1; r >= 0; --r) {\n                if (a[r][c] != 0) {\n                    a[wr][c] = a[r][c];\n                    if (wr != r) a[r][c] = 0;\n                    --wr;\n                }\n            }\n        }\n    } else if (dir == 'L') {              // left\n        for (int r = 0; r < SZ; ++r) {\n            int wc = 0;\n            for (int c = 0; c < SZ; ++c) {\n                if (a[r][c] != 0) {\n                    a[r][wc] = a[r][c];\n                    if (wc != c) a[r][c] = 0;\n                    ++wc;\n                }\n            }\n        }\n    } else if (dir == 'R') {               // right\n        for (int r = 0; r < SZ; ++r) {\n            int wc = SZ - 1;\n            for (int c = SZ - 1; c >= 0; --c) {\n                if (a[r][c] != 0) {\n                    a[r][wc] = a[r][c];\n                    if (wc != c) a[r][c] = 0;\n                    --wc;\n                }\n            }\n        }\n    }\n}\n\n/* ------------------------------------------------------------\n   \u03a3 size\u00b2 of all connected components\n   ------------------------------------------------------------ */\nlong long sumSquares(const array<array<int, SZ>, SZ> &a) {\n    bool vis[SZ][SZ] = {};\n    const int dr[4] = {-1, 1, 0, 0};\n    const int dc[4] = {0, 0, -1, 1};\n    long long sum = 0;\n    for (int r = 0; r < SZ; ++r) {\n        for (int c = 0; c < SZ; ++c) {\n            if (a[r][c] == 0 || vis[r][c]) continue;\n            int fl = a[r][c];\n            int sz = 0;\n            queue<pair<int, int>> q;\n            q.emplace(r, c);\n            vis[r][c] = true;\n            while (!q.empty()) {\n                auto [cr, cc] = q.front(); q.pop();\n                ++sz;\n                for (int k = 0; k < 4; ++k) {\n                    int nr = cr + dr[k];\n                    int nc = cc + dc[k];\n                    if (0 <= nr && nr < SZ && 0 <= nc && nc < SZ &&\n                        !vis[nr][nc] && a[nr][nc] == fl) {\n                        vis[nr][nc] = true;\n                        q.emplace(nr, nc);\n                    }\n                }\n            }\n            sum += 1LL * sz * sz;\n        }\n    }\n    return sum;\n}\n\n/* ------------------------------------------------------------\n   find the p\u2011th empty cell (1\u2011based)\n   ------------------------------------------------------------ */\npair<int, int> findEmptyCell(const array<array<int, SZ>, SZ> &a, int p) {\n    for (int r = 0; r < SZ; ++r)\n        for (int c = 0; c < SZ; ++c)\n            if (a[r][c] == 0) {\n                if (p == 1) return {r, c};\n                --p;\n            }\n    return {-1, -1};               // never reached\n}\n\n/* ------------------------------------------------------------\n   expected value of S after the next candy has been placed\n   (uniform random cell) and we will tilt optimally afterwards\n   ------------------------------------------------------------ */\nlong long expectedFutureScore(const array<array<int, SZ>, SZ> &board,\n                              int nextFlavour) {\n    vector<pair<int, int>> empties;\n    empties.reserve(100);\n    for (int r = 0; r < SZ; ++r)\n        for (int c = 0; c < SZ; ++c)\n            if (board[r][c] == 0) empties.emplace_back(r, c);\n\n    const int cnt = (int)empties.size();   // > 0 (called only before the last step)\n    long long sum = 0;\n    for (auto [r, c] : empties) {\n        auto b2 = board;\n        b2[r][c] = nextFlavour;\n        long long best = -1;\n        for (char dir : DIRS) {\n            auto b3 = b2;\n            tilt(b3, dir);\n            long long s = sumSquares(b3);\n            if (s > best) best = s;\n        }\n        sum += best;\n    }\n    return sum / cnt;          // uniform average\n}\n\n/* ------------------------------------------------------------\n   main\n   ------------------------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int TOTAL = 100;\n    vector<int> flavour(TOTAL + 1);\n    for (int i = 1; i <= TOTAL; ++i) cin >> flavour[i];\n\n    array<array<int, SZ>, SZ> board{};\n    for (int r = 0; r < SZ; ++r) board[r].fill(0);\n\n    for (int step = 1; step <= TOTAL; ++step) {\n        int p;                     // where the current candy is placed\n        cin >> p;\n        auto pos = findEmptyCell(board, p);\n        board[pos.first][pos.second] = flavour[step];\n\n        char bestDir = 'F';\n        long long bestValue = -1;\n        long long bestCur = -1;    // tie\u2011breaker\n\n        if (step == TOTAL) {      // last step \u2013 only the immediate S matters\n            for (char dir : DIRS) {\n                auto b = board;\n                tilt(b, dir);\n                long long s = sumSquares(b);\n                if (s > bestValue) {\n                    bestValue = s;\n                    bestCur = s;\n                    bestDir = dir;\n                }\n            }\n        } else {\n            for (char dir : DIRS) {\n                auto b = board;\n                tilt(b, dir);\n                long long curS = sumSquares(b);\n                long long expS = expectedFutureScore(b, flavour[step + 1]);\n                // lexicographic comparison: first expected future S,\n                // then current S as a tie\u2011breaker\n                if (expS > bestValue ||\n                    (expS == bestValue && curS > bestCur)) {\n                    bestValue = expS;\n                    bestCur = curS;\n                    bestDir = dir;\n                }\n            }\n        }\n\n        cout << bestDir << '\\n';\n        cout.flush();               // required by the statement\n        tilt(board, bestDir);       // apply the chosen tilt\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int M;\n    double epsInput;\n    if (!(cin >> M >> epsInput)) return 0;\n    const double eps = epsInput;                     // edge\u2011flip probability\n\n    /* ---------- choose the smallest possible N ---------- */\n    int N = 4;\n    while (N * (N - 1) / 2 < M) ++N;                 // N \u2264 100 because M \u2264 100\n    const int L = N * (N - 1) / 2;                   // number of possible edges\n\n    /* ---------- list of edges in lexicographic order ---------- */\n    vector<pair<int,int>> edge;\n    edge.reserve(L);\n    for (int i = 0; i < N; ++i)\n        for (int j = i + 1; j < N; ++j)\n            edge.emplace_back(i, j);\n\n    /* ---------- edge counts for the M graphs (different, as far apart as possible) ---------- */\n    vector<int> edgeCnt(M);\n    if (M == 1) {\n        edgeCnt[0] = 0;\n    } else {\n        for (int i = 0; i < M; ++i) {\n            double val = round(1.0 * i * L / (M - 1));\n            edgeCnt[i] = (int)val;\n        }\n        // make them strictly increasing\n        for (int i = 1; i < M; ++i)\n            if (edgeCnt[i] <= edgeCnt[i-1]) edgeCnt[i] = edgeCnt[i-1] + 1;\n        if (edgeCnt[M-1] > L) edgeCnt[M-1] = L;      // safety\n    }\n\n    /* ---------- pre\u2011compute log\u2011factorials ---------- */\n    int maxFact = max(L, N);\n    vector<double> logFact(maxFact + 1);\n    logFact[0] = 0.0;\n    for (int i = 1; i <= maxFact; ++i) logFact[i] = logFact[i-1] + log((double)i);\n    auto logComb = [&](int n, int k) -> double {\n        if (k < 0 || k > n) return -INFINITY;\n        return logFact[n] - logFact[k] - logFact[n - k];\n    };\n\n    /* ---------- log\u2011add helper (stable sum in log\u2011domain) ---------- */\n    auto logAdd = [&](double a, double b) -> double {\n        if (a == -INFINITY) return b;\n        if (b == -INFINITY) return a;\n        if (a > b) return a + log1p(exp(b - a));\n        else       return b + log1p(exp(a - b));\n    };\n\n    /* ---------- exact degree probability tables ---------- */\n    vector<vector<double>> logProbDeg(N, vector<double>(N, -INFINITY));\n    if (eps == 0.0) {\n        for (int d = 0; d < N; ++d) logProbDeg[d][d] = 0.0;\n    } else {\n        double logEps = log(eps);\n        double log1mEps = log(1.0 - eps);\n        for (int d = 0; d < N; ++d) {\n            vector<double> sum(N, -INFINITY);\n            for (int a = 0; a <= d; ++a) {               // survived original edges\n                double logC1 = logComb(d, a);\n                double term1 = a * log1mEps + (d - a) * logEps;\n                for (int b = 0; b <= N - 1 - d; ++b) {   // newly created edges\n                    int k = a + b;\n                    double logC2 = logComb(N - 1 - d, b);\n                    double term2 = b * logEps + (N - 1 - d - b) * log1mEps;\n                    double cur = logC1 + term1 + logC2 + term2;\n                    sum[k] = logAdd(sum[k], cur);\n                }\n            }\n            for (int k = 0; k < N; ++k) logProbDeg[d][k] = sum[k];\n        }\n    }\n\n    /* ---------- generate the M graphs and store their sorted degree sequences ---------- */\n    vector<string> graphStr(M);\n    vector<vector<int>> degSorted(M, vector<int>(N));\n    for (int idx = 0; idx < M; ++idx) {\n        int e = edgeCnt[idx];\n        string s(L, '0');\n        vector<int> deg(N, 0);\n        // random set of edges (deterministic because of seeded rng)\n        mt19937_64 rng(idx + 1234567);\n        vector<int> ord(L);\n        iota(ord.begin(), ord.end(), 0);\n        shuffle(ord.begin(), ord.end(), rng);\n        for (int p = 0; p < e; ++p) {\n            int pos = ord[p];\n            s[pos] = '1';\n            ++deg[edge[pos].first];\n            ++deg[edge[pos].second];\n        }\n        graphStr[idx] = s;\n        vector<int> d = deg;\n        sort(d.begin(), d.end(), greater<int>());\n        degSorted[idx] = d;\n    }\n\n    /* ---------- output the description of the graphs ---------- */\n    cout << N << '\\n';\n    for (const string &g : graphStr) cout << g << '\\n';\n    cout.flush();\n\n    /* ---------- helper: log\u2011probability of observing m edges when original graph has e edges ---------- */\n    auto edgeLogProb = [&](int e, int m) -> double {\n        if (eps == 0.0) return (m == e) ? 0.0 : -INFINITY;\n        double logEps = log(eps);\n        double log1mEps = log(1.0 - eps);\n        double best = -INFINITY;\n        int a_min = max(0, m - (L - e));\n        int a_max = min(e, m);\n        for (int a = a_min; a <= a_max; ++a) {\n            int b = m - a;                               // newly created edges\n            double logC1 = logComb(e, a);\n            double term1 = a * log1mEps + (e - a) * logEps;\n            double logC2 = logComb(L - e, b);\n            double term2 = b * logEps + (L - e - b) * log1mEps;\n            double cur = logC1 + term1 + logC2 + term2;\n            best = logAdd(best, cur);\n        }\n        return best;\n    };\n\n    /* ---------- answer the 100 queries ---------- */\n    for (int q = 0; q < 100; ++q) {\n        string h;  cin >> h;\n\n        /* observed edge count */\n        int m = 0;\n        for (char c : h) if (c == '1') ++m;\n\n        /* observed degree sequence */\n        vector<int> degObs(N, 0);\n        for (int pos = 0; pos < L; ++pos)\n            if (h[pos] == '1') {\n                ++degObs[edge[pos].first];\n                ++degObs[edge[pos].second];\n            }\n        vector<int> degObsSorted = degObs;\n        sort(degObsSorted.begin(), degObsSorted.end(), greater<int>());\n\n        int answer = 0;\n        double bestScore = -INFINITY;\n\n        for (int i = 0; i < M; ++i) {\n            double cur = edgeLogProb(edgeCnt[i], m);\n            // add degree contributions\n            const vector<int> &dOrig = degSorted[i];\n            bool possible = true;\n            for (int v = 0; v < N; ++v) {\n                double lp = logProbDeg[dOrig[v]][degObsSorted[v]];\n                if (lp == -INFINITY) { possible = false; break; }\n                cur += lp;\n            }\n            if (!possible) continue;\n            if (cur > bestScore) {\n                bestScore = cur;\n                answer = i;\n            }\n        }\n\n        cout << answer << '\\n' << flush;\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v;\n    int w;\n};\n\nstruct Adj {\n    int to;\n    int w;\n    int id;\n};\n\nusing i128 = __int128_t;\nconst long long INF = (1LL << 60);          // enough for all distances\n\n/*---------------------------------------------------------------*/\n/* Dijkstra \u2013 can forbid one edge id ( -1 = allowed everything) */\nvoid dijkstra(int start, int forbid,\n              const vector<vector<Adj>>& adj,\n              vector<long long>& dist) {\n    int n = (int)adj.size() - 1;\n    fill(dist.begin(), dist.end(), INF);\n    dist[start] = 0;\n    using P = pair<long long,int>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n    pq.emplace(0LL, start);\n    while (!pq.empty()) {\n        auto [d, v] = pq.top(); pq.pop();\n        if (d != dist[v]) continue;\n        for (const Adj& e : adj[v]) {\n            if (e.id == forbid) continue;          // edge removed\n            long long nd = d + e.w;\n            if (nd < dist[e.to]) {\n                dist[e.to] = nd;\n                pq.emplace(nd, e.to);\n            }\n        }\n    }\n}\n\n/*---------------------------------------------------------------*/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n    vector<Edge> edges(M);\n    vector<vector<Adj>> adj(N + 1);\n    for (int i = 0; i < M; ++i) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        edges[i] = {u, v, w};\n        adj[u].push_back({v, w, i});\n        adj[v].push_back({u, w, i});\n    }\n    /* read and ignore coordinates */\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    /*------------------------------------------------------*/\n    /* 1) cnt[e] \u2013 number of directed shortest\u2011path pairs using e */\n    vector<long long> cnt(M, 0);\n    vector<long long> dist(N + 1);\n    vector<int> parent(N + 1, -1);\n    for (int s = 1; s <= N; ++s) {\n        fill(dist.begin(), dist.end(), INF);\n        fill(parent.begin(), parent.end(), -1);\n        using P = pair<long long,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        dist[s] = 0;\n        pq.emplace(0LL, s);\n        while (!pq.empty()) {\n            auto [d, v] = pq.top(); pq.pop();\n            if (d != dist[v]) continue;\n            for (const Adj& e : adj[v]) {\n                long long nd = d + e.w;\n                if (nd < dist[e.to]) {\n                    dist[e.to] = nd;\n                    parent[e.to] = e.id;\n                    pq.emplace(nd, e.to);\n                }\n            }\n        }\n        for (int v = 1; v <= N; ++v) {\n            if (v != s && parent[v] != -1) {\n                cnt[parent[v]]++;\n            }\n        }\n    }\n\n    /*------------------------------------------------------*/\n    /* 2) replacement distance for every edge */\n    vector<long long> repDist(M, INF);\n    for (int i = 0; i < M; ++i) {\n        int u = edges[i].u;\n        int v = edges[i].v;\n        dijkstra(u, i, adj, dist);          // run while ignoring edge i\n        repDist[i] = dist[v];\n    }\n\n    /*------------------------------------------------------*/\n    /* 3) improved single\u2011edge cost */\n    vector<long long> cost2(M, 0);\n    for (int i = 0; i < M; ++i) {\n        long long diff = repDist[i] - edges[i].w;   // \u2265 0\n        if (diff < 0) diff = 0;\n        cost2[i] = cnt[i] * diff;                 // fits into 64\u2011bit\n    }\n\n    /*------------------------------------------------------*/\n    /* 4) multi\u2011start greedy assignment */\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    const int RUNS = 10;                 // number of random runs\n    vector<int> bestAssign(M, -1);\n    i128 bestMaxLoad = (i128)1 << 126;   // very large\n\n    for (int run = 0; run < RUNS; ++run) {\n        /* random tie\u2011breaker for equal costs */\n        vector<double> rnd(M);\n        uniform_real_distribution<double> realDist(0.0, 1.0);\n        for (int i = 0; i < M; ++i) rnd[i] = realDist(rng);\n\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(),\n             [&](int a, int b) {\n                 if (cost2[a] != cost2[b]) return cost2[a] > cost2[b];\n                 return rnd[a] > rnd[b];\n             });\n\n        vector<int> dayCnt(D, 0);\n        vector<i128> dayLoad(D, 0);\n        vector<int> curAssign(M, -1);\n\n        for (int idx : order) {\n            // choose day with smallest load among those with free capacity\n            i128 bestLoad = (i128)1 << 126;\n            vector<int> candidates;\n            for (int d = 0; d < D; ++d) {\n                if (dayCnt[d] < K) {\n                    if (dayLoad[d] < bestLoad) {\n                        bestLoad = dayLoad[d];\n                        candidates.clear();\n                        candidates.push_back(d);\n                    } else if (dayLoad[d] == bestLoad) {\n                        candidates.push_back(d);\n                    }\n                }\n            }\n            int chosen = candidates[uniform_int_distribution<int>\n                                    (0, (int)candidates.size() - 1)(rng)];\n            curAssign[idx] = chosen;\n            ++dayCnt[chosen];\n            dayLoad[chosen] += (i128)cost2[idx];\n        }\n\n        // evaluate this schedule (max load)\n        i128 curMaxLoad = 0;\n        for (int d = 0; d < D; ++d)\n            if (dayLoad[d] > curMaxLoad) curMaxLoad = dayLoad[d];\n\n        if (curMaxLoad < bestMaxLoad) {\n            bestMaxLoad = curMaxLoad;\n            bestAssign.swap(curAssign);\n        }\n    }\n\n    /*------------------------------------------------------*/\n    /* 5) output */\n    for (int i = 0; i < M; ++i) {\n        if (i) cout << ' ';\n        cout << (bestAssign[i] + 1);   // days are 1\u2011based\n    }\n    cout << '\\n';\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D;\n    if (!(cin >> D)) return 0;\n    vector<string> f1(D), r1(D), f2(D), r2(D);\n    for (int z = 0; z < D; ++z) cin >> f1[z];\n    for (int z = 0; z < D; ++z) cin >> r1[z];\n    for (int z = 0; z < D; ++z) cin >> f2[z];\n    for (int z = 0; z < D; ++z) cin >> r2[z];\n\n    const int N = D * D * D;\n    auto idx = [&](int x, int y, int z) { return x * D * D + y * D + z; };\n\n    vector<char> allowed1(N, 0), allowed2(N, 0), inter(N, 0);\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                int id = idx(x, y, z);\n                allowed1[id] = (f1[z][x] == '1' && r1[z][y] == '1');\n                allowed2[id] = (f2[z][x] == '1' && r2[z][y] == '1');\n                inter[id] = allowed1[id] & allowed2[id];\n            }\n\n    /* ---------- connected components of intersection ---------- */\n    vector<int> comp(N, -1);\n    vector<vector<int>> comps;\n    const int dx[6] = {1,-1,0,0,0,0};\n    const int dy[6] = {0,0,1,-1,0,0};\n    const int dz[6] = {0,0,0,0,1,-1};\n\n    for (int id = 0; id < N; ++id) if (inter[id] && comp[id] == -1) {\n        queue<int> q;\n        q.push(id);\n        comp[id] = (int)comps.size();\n        vector<int> cells;\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            cells.push_back(v);\n            int x = v / (D * D);\n            int rem = v % (D * D);\n            int y = rem / D;\n            int z = rem % D;\n            for (int dir = 0; dir < 6; ++dir) {\n                int nx = x + dx[dir];\n                int ny = y + dy[dir];\n                int nz = z + dz[dir];\n                if (nx < 0 || nx >= D || ny < 0 || ny >= D || nz < 0 || nz >= D) continue;\n                int nid = idx(nx, ny, nz);\n                if (inter[nid] && comp[nid] == -1) {\n                    comp[nid] = (int)comps.size();\n                    q.push(nid);\n                }\n            }\n        }\n        comps.push_back(move(cells));\n    }\n\n    int nShared = (int)comps.size();\n\n    /* ---------- output arrays ---------- */\n    vector<int> out1(N, 0), out2(N, 0);\n    for (int ci = 0; ci < nShared; ++ci) {\n        int bid = ci + 1;                       // block numbers start with 1\n        for (int v : comps[ci]) {\n            out1[v] = bid;\n            out2[v] = bid;\n        }\n    }\n\n    /* ---------- coverage tables ---------- */\n    vector<vector<vector<char>>> frontCov(2, vector<vector<char>>(D, vector<char>(D, 0)));\n    vector<vector<vector<char>>> rightCov(2, vector<vector<char>>(D, vector<char>(D, 0)));\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                int id = idx(x, y, z);\n                if (inter[id]) {\n                    frontCov[0][z][x] = 1;\n                    rightCov[0][z][y] = 1;\n                    frontCov[1][z][x] = 1;\n                    rightCov[1][z][y] = 1;\n                }\n            }\n\n    int nextBlock = nShared + 1;\n\n    const vector<string>* f[2] = {&f1, &f2};\n    const vector<string>* r[2] = {&r1, &r2};\n    const vector<char>* allow[2] = {&allowed1, &allowed2};\n\n    for (int obj = 0; obj < 2; ++obj) {\n        const vector<string>& fobj = *f[obj];\n        const vector<string>& robj = *r[obj];\n        const vector<char>& allowObj = *allow[obj];\n        vector<int>& out = (obj == 0 ? out1 : out2);\n\n        for (int z = 0; z < D; ++z) {\n            vector<int> X, Y;\n            for (int x = 0; x < D; ++x)\n                if (fobj[z][x] == '1' && !frontCov[obj][z][x]) X.push_back(x);\n            for (int y = 0; y < D; ++y)\n                if (robj[z][y] == '1' && !rightCov[obj][z][y]) Y.push_back(y);\n            int L = (int)X.size();\n            int R = (int)Y.size();\n            if (L == 0 && R == 0) continue;\n\n            /* ---- case L == 0 : only right columns have to be covered ---- */\n            if (L == 0) {\n                for (int y : Y) {\n                    for (int x = 0; x < D; ++x) {\n                        int id = idx(x, y, z);\n                        if (allowObj[id] && !inter[id] && out[id] == 0) {\n                            out[id] = nextBlock++;\n                            frontCov[obj][z][x] = 1;\n                            rightCov[obj][z][y] = 1;\n                            break;\n                        }\n                    }\n                }\n                continue;\n            }\n            /* ---- case R == 0 : only front columns have to be covered ---- */\n            if (R == 0) {\n                for (int x : X) {\n                    for (int y = 0; y < D; ++y) {\n                        int id = idx(x, y, z);\n                        if (allowObj[id] && !inter[id] && out[id] == 0) {\n                            out[id] = nextBlock++;\n                            frontCov[obj][z][x] = 1;\n                            rightCov[obj][z][y] = 1;\n                            break;\n                        }\n                    }\n                }\n                continue;\n            }\n\n            /* ---- general case ---- */\n            vector<vector<int>> adj(L);\n            for (int li = 0; li < L; ++li) {\n                int x = X[li];\n                for (int rj = 0; rj < R; ++rj) {\n                    int y = Y[rj];\n                    int id = idx(x, y, z);\n                    if (allowObj[id] && !inter[id]) adj[li].push_back(rj);\n                }\n            }\n\n            /* maximum matching (simple DFS augment) */\n            vector<int> matchR(R, -1);\n            function<bool(int, vector<char>&)> dfs = [&](int v, vector<char>& seen) -> bool {\n                for (int to : adj[v]) {\n                    if (seen[to]) continue;\n                    seen[to] = true;\n                    if (matchR[to] == -1 || dfs(matchR[to], seen)) {\n                        matchR[to] = v;\n                        return true;\n                    }\n                }\n                return false;\n            };\n            for (int v = 0; v < L; ++v) {\n                vector<char> seen(R, 0);\n                dfs(v, seen);\n            }\n\n            /* build a minimum edge cover */\n            vector<char> covL(L, 0), covR(R, 0);\n            vector<pair<int,int>> edges;\n\n            for (int rj = 0; rj < R; ++rj) {\n                int li = matchR[rj];\n                if (li != -1) {\n                    edges.emplace_back(li, rj);\n                    covL[li] = covR[rj] = 1;\n                }\n            }\n            for (int li = 0; li < L; ++li) if (!covL[li]) {\n                if (!adj[li].empty()) {\n                    int rj = adj[li][0];\n                    edges.emplace_back(li, rj);\n                    covL[li] = 1;\n                }\n            }\n            for (int rj = 0; rj < R; ++rj) if (!covR[rj]) {\n                bool found = false;\n                for (int li = 0; li < L && !found; ++li) {\n                    for (int to : adj[li]) if (to == rj) {\n                        edges.emplace_back(li, rj);\n                        covR[rj] = 1;\n                        found = true;\n                        break;\n                    }\n                }\n                if (!found) {                 // should not happen for a solvable instance\n                    edges.emplace_back(-1, rj);   // placeholder, will be handled later\n                }\n            }\n\n            /* place the exclusive cells */\n            vector<vector<char>> used(D, vector<char>(D, 0));\n            for (auto &pr : edges) {\n                int li = pr.first, rj = pr.second;\n                if (li == -1) {               // placeholder\n                    int y = Y[rj];\n                    for (int x = 0; x < D; ++x) {\n                        int id = idx(x, y, z);\n                        if (allowObj[id] && !inter[id] && out[id] == 0 && !used[x][y]) {\n                            out[id] = nextBlock++;\n                            frontCov[obj][z][x] = 1;\n                            rightCov[obj][z][y] = 1;\n                            used[x][y] = 1;\n                            break;\n                        }\n                    }\n                    continue;\n                }\n                int x = X[li];\n                int y = Y[rj];\n                if (used[x][y]) continue;\n                used[x][y] = 1;\n                int id = idx(x, y, z);\n                out[id] = nextBlock++;\n                frontCov[obj][z][x] = 1;\n                rightCov[obj][z][y] = 1;\n            }\n\n            /* safety net \u2013 guarantee coverage (normally not needed) */\n            for (int x : X) if (!frontCov[obj][z][x]) {\n                for (int y = 0; y < D; ++y) {\n                    int id = idx(x, y, z);\n                    if (allowObj[id] && !inter[id] && out[id] == 0) {\n                        out[id] = nextBlock++;\n                        frontCov[obj][z][x] = 1;\n                        rightCov[obj][z][y] = 1;\n                        break;\n                    }\n                }\n            }\n            for (int y : Y) if (!rightCov[obj][z][y]) {\n                for (int x = 0; x < D; ++x) {\n                    int id = idx(x, y, z);\n                    if (allowObj[id] && !inter[id] && out[id] == 0) {\n                        out[id] = nextBlock++;\n                        frontCov[obj][z][x] = 1;\n                        rightCov[obj][z][y] = 1;\n                        break;\n                    }\n                }\n            }\n        }\n    }\n\n    int totalBlocks = nextBlock - 1;\n    cout << totalBlocks << '\\n';\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << out1[i];\n    }\n    cout << '\\n';\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << out2[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nconst ll INFLL = (1LL << 60);\nconst int MAXR = 5000;\nconst ll MAXD2 = 1LL * MAXR * MAXR;          // 25 000 000\n\n/* ------------------------------------------------------------ */\n/*  global data                                                 */\nint N, M, K;\nint WORDS;                                  // (K+63)/64\n\nvector<int> X, Y;                           // vertex coordinates\nvector<int> A, B;                           // resident coordinates\n\nstruct Edge { int u, v, w; };\nvector<Edge> edges;                         // 1\u2011based\nvector<vector<pair<int,int>>> adj;          // (neighbour, edge id)\n\nvector<vector<ll>> dist2;                   // squared distances vertex \u2192 resident\nvector<vector<ll>> wgt;                     // cheapest edge weight between u and v\nvector<vector<int>> edgeIdx;                // cheapest edge index, -1 if none\n\nvector<vector<unsigned long long>> coverMask;   // bitset of residents covered by each vertex\n\n/* ------------------------------------------------------------ */\n/*  integer ceiling of sqrt                                      */\nint ceil_sqrt_ll(ll x) {\n    if (x <= 0) return 0;\n    ll r = (ll)std::sqrt((double)x);\n    while (r * r < x) ++r;\n    while (r > 0 && (r - 1) * (r - 1) >= x) --r;\n    return (int)r;\n}\n\n/* ------------------------------------------------------------ */\n/*  key for a set of vertices (128 bits)                        */\nstruct Key {\n    uint64_t lo, hi;\n    bool operator==(const Key& o) const noexcept { return lo == o.lo && hi == o.hi; }\n};\nstruct KeyHash {\n    size_t operator()(Key const& k) const noexcept {\n        return std::hash<uint64_t>{}(k.lo ^ (k.hi << 1));\n    }\n};\n\nKey makeKey(const vector<int>& S) {\n    uint64_t lo = 0, hi = 0;\n    for (int v : S) {\n        if (v <= 64) lo |= 1ULL << (v - 1);\n        else          hi |= 1ULL << (v - 65);\n    }\n    return {lo, hi};\n}\n\n/* ------------------------------------------------------------ */\n/*  cache: key \u2192 (feasible , cost)                              */\nstruct CacheVal {\n    bool feasible;\n    ll   cost;\n};\nunordered_map<Key, CacheVal, KeyHash> cache;\n\n/* ------------------------------------------------------------ */\n/*  evaluate a vertex set, return feasibility and cost.\n    The result is cached.                                         */\nbool evaluateSet(const vector<int>& S, ll& cost) {\n    Key key = makeKey(S);\n    auto it = cache.find(key);\n    if (it != cache.end()) {\n        cost = it->second.cost;\n        return it->second.feasible;\n    }\n\n    /* ----- coverage test (bitsets) ----- */\n    vector<unsigned long long> curMask(WORDS, 0);\n    for (int v : S) {\n        for (int w = 0; w < WORDS; ++w) curMask[w] |= coverMask[v][w];\n    }\n    int covered = 0;\n    for (int w = 0; w < WORDS; ++w) covered += __builtin_popcountll(curMask[w]);\n    if (covered < K) {                 // uncovered resident \u2192 infeasible\n        cache[key] = {false, INFLL};\n        return false;\n    }\n\n    /* ----- nearest vertex for each resident ----- */\n    vector<ll> maxDist2(N + 1, 0);\n    for (int k = 0; k < K; ++k) {\n        ll bestDist = INFLL;\n        int bestVert = -1;\n        for (int v : S) {\n            ll d = dist2[v][k];\n            if (d < bestDist) {\n                bestDist = d;\n                bestVert = v;\n            }\n        }\n        if (bestVert == -1) {         // should not happen after coverage test\n            cache[key] = {false, INFLL};\n            return false;\n        }\n        if (bestDist > maxDist2[bestVert]) maxDist2[bestVert] = bestDist;\n    }\n\n    /* ----- radii and \u03a3R\u00b2 ----- */\n    ll sumSq = 0;\n    for (int v : S) {\n        ll md2 = maxDist2[v];\n        int r = (md2 == 0) ? 0 : ceil_sqrt_ll(md2);\n        if (r > MAXR) {\n            cache[key] = {false, INFLL};\n            return false;\n        }\n        sumSq += 1LL * r * r;\n    }\n\n    /* ----- minimum spanning tree (Prim) ----- */\n    vector<char> inS(N + 1, 0);\n    for (int v : S) inS[v] = 1;\n\n    vector<ll>  minEdge(N + 1, INFLL);\n    vector<int> parentEdge(N + 1, -1);\n    vector<char> visited(N + 1, 0);\n    visited[1] = 1;                     // source is always present\n    for (int u = 1; u <= N; ++u) {\n        if (!inS[u] || u == 1) continue;\n        if (edgeIdx[1][u] != -1) {\n            minEdge[u] = wgt[1][u];\n            parentEdge[u] = edgeIdx[1][u];\n        }\n    }\n\n    ll edgeCost = 0;\n    for (int it = 0; it < (int)S.size() - 1; ++it) {\n        int v = -1;\n        ll best = INFLL;\n        for (int u = 1; u <= N; ++u) {\n            if (inS[u] && !visited[u] && minEdge[u] < best) {\n                best = minEdge[u];\n                v = u;\n            }\n        }\n        if (v == -1) {                 // not connected\n            cache[key] = {false, INFLL};\n            return false;\n        }\n        visited[v] = 1;\n        edgeCost += best;\n        for (int u = 1; u <= N; ++u) {\n            if (inS[u] && !visited[u] && edgeIdx[v][u] != -1) {\n                ll w = wgt[v][u];\n                if (w < minEdge[u]) {\n                    minEdge[u] = w;\n                    parentEdge[u] = edgeIdx[v][u];\n                }\n            }\n        }\n    }\n\n    cost = sumSq + edgeCost;\n    cache[key] = {true, cost};\n    return true;\n}\n\n/* ------------------------------------------------------------ */\n/*  full evaluation \u2013 also returns radii and MST edges.\n    (used only for the final answer)                           */\nvoid fullEvaluation(const vector<int>& S,\n                    bool& feasible, ll& cost,\n                    vector<int>& radius,\n                    vector<int>& edgesUsed) {\n    /* ----- coverage test ----- */\n    vector<unsigned long long> curMask(WORDS, 0);\n    for (int v : S) {\n        for (int w = 0; w < WORDS; ++w) curMask[w] |= coverMask[v][w];\n    }\n    int covered = 0;\n    for (int w = 0; w < WORDS; ++w) covered += __builtin_popcountll(curMask[w]);\n    feasible = (covered == K);\n    if (!feasible) { cost = INFLL; return; }\n\n    /* ----- nearest vertex for each resident ----- */\n    vector<ll> maxDist2(N + 1, 0);\n    for (int k = 0; k < K; ++k) {\n        ll bestDist = INFLL;\n        int bestVert = -1;\n        for (int v : S) {\n            ll d = dist2[v][k];\n            if (d < bestDist) {\n                bestDist = d;\n                bestVert = v;\n            }\n        }\n        if (bestDist > maxDist2[bestVert]) maxDist2[bestVert] = bestDist;\n    }\n\n    /* ----- radii ----- */\n    radius.assign(N + 1, 0);\n    ll sumSq = 0;\n    for (int v : S) {\n        ll md2 = maxDist2[v];\n        int r = (md2 == 0) ? 0 : ceil_sqrt_ll(md2);\n        radius[v] = r;\n        sumSq += 1LL * r * r;\n    }\n\n    /* ----- MST (Prim) ----- */\n    vector<char> inS(N + 1, 0);\n    for (int v : S) inS[v] = 1;\n\n    vector<ll>  minEdge(N + 1, INFLL);\n    vector<int> parentEdge(N + 1, -1);\n    vector<char> visited(N + 1, 0);\n    visited[1] = 1;\n    for (int u = 1; u <= N; ++u) {\n        if (!inS[u] || u == 1) continue;\n        if (edgeIdx[1][u] != -1) {\n            minEdge[u] = wgt[1][u];\n            parentEdge[u] = edgeIdx[1][u];\n        }\n    }\n\n    edgesUsed.clear();\n    ll edgeCost = 0;\n    for (int it = 0; it < (int)S.size() - 1; ++it) {\n        int v = -1;\n        ll best = INFLL;\n        for (int u = 1; u <= N; ++u) {\n            if (inS[u] && !visited[u] && minEdge[u] < best) {\n                best = minEdge[u];\n                v = u;\n            }\n        }\n        if (v == -1) {                 // not connected \u2013 should not happen\n            feasible = false;\n            cost = INFLL;\n            return;\n        }\n        visited[v] = 1;\n        edgeCost += best;\n        edgesUsed.push_back(parentEdge[v]);\n        for (int u = 1; u <= N; ++u) {\n            if (inS[u] && !visited[u] && edgeIdx[v][u] != -1) {\n                ll w = wgt[v][u];\n                if (w < minEdge[u]) {\n                    minEdge[u] = w;\n                    parentEdge[u] = edgeIdx[v][u];\n                }\n            }\n        }\n    }\n\n    cost = sumSq + edgeCost;\n}\n\n/* ------------------------------------------------------------ */\n/*  neighbours of a set (vertices not in the set, adjacent to it) */\nvector<int> neighbours(const vector<char>& inS) {\n    vector<char> seen(N + 1, 0);\n    vector<int> res;\n    for (int v = 1; v <= N; ++v) if (inS[v]) {\n        for (auto [to, id] : adj[v]) {\n            if (!inS[to] && !seen[to]) {\n                seen[to] = 1;\n                res.push_back(to);\n            }\n        }\n    }\n    return res;\n}\n\n/* ------------------------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ----- input ----- */\n    cin >> N >> M >> K;\n    X.resize(N + 1);\n    Y.resize(N + 1);\n    for (int i = 1; i <= N; ++i) cin >> X[i] >> Y[i];\n\n    edges.resize(M + 1);\n    adj.assign(N + 1, {});\n    wgt.assign(N + 1, vector<ll>(N + 1, INFLL));\n    edgeIdx.assign(N + 1, vector<int>(N + 1, -1));\n\n    for (int j = 1; j <= M; ++j) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        edges[j] = {u, v, w};\n        adj[u].push_back({v, j});\n        adj[v].push_back({u, j});\n        if (w < wgt[u][v]) {\n            wgt[u][v] = wgt[v][u] = w;\n            edgeIdx[u][v] = edgeIdx[v][u] = j;\n        }\n    }\n\n    A.resize(K);\n    B.resize(K);\n    for (int k = 0; k < K; ++k) cin >> A[k] >> B[k];\n\n    /* ----- pre\u2011computations ----- */\n    WORDS = (K + 63) / 64;\n    dist2.assign(N + 1, vector<ll>(K, 0));\n    coverMask.assign(N + 1, vector<unsigned long long>(WORDS, 0));\n\n    for (int i = 1; i <= N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            ll dx = X[i] - A[k];\n            ll dy = Y[i] - B[k];\n            ll d2 = dx * dx + dy * dy;\n            dist2[i][k] = d2;\n            if (d2 <= MAXD2) {\n                coverMask[i][k / 64] |= 1ULL << (k % 64);\n            }\n        }\n    }\n\n    /* ----- greedy start (add vertices) ----- */\n    vector<int> curS = {1};\n    vector<char> inS(N + 1, 0);\n    inS[1] = 1;\n\n    // current coverage mask\n    vector<unsigned long long> curMask(WORDS, 0);\n    for (int w = 0; w < WORDS; ++w) curMask[w] = coverMask[1][w];\n\n    bool feasible = false;\n    ll curCost = 0;\n    feasible = evaluateSet(curS, curCost);\n    if (!feasible) {\n        while (!feasible) {\n            vector<int> cand = neighbours(inS);\n            // try all candidates, keep the best (lowest cost)\n            ll bestCost = INFLL;\n            int bestV = -1;\n            for (int v : cand) {\n                vector<int> ns = curS;\n                ns.push_back(v);\n                ll c;\n                bool f = evaluateSet(ns, c);\n                if (f && c < bestCost) {\n                    bestCost = c;\n                    bestV = v;\n                }\n            }\n            if (bestV == -1) {      // should not happen \u2013 add any remaining vertex\n                for (int v = 1; v <= N; ++v) if (!inS[v]) {\n                    bestV = v; break;\n                }\n            }\n            // apply the addition\n            inS[bestV] = 1;\n            curS.push_back(bestV);\n            for (int w = 0; w < WORDS; ++w) curMask[w] |= coverMask[bestV][w];\n            feasible = evaluateSet(curS, curCost);\n        }\n    }\n\n    /* ----- keep the best solution found ----- */\n    ll bestCost = curCost;\n    vector<int> bestS = curS;\n    vector<char> bestIn = inS;\n    vector<unsigned long long> bestMask = curMask;\n\n    /* ----- local search (removal \u2013 addition) ----- */\n    std::mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n\n    bool changed = true;\n    while (changed) {\n        changed = false;\n\n        /* ---- removal ---- */\n        for (size_t i = 0; i < bestS.size(); ++i) {\n            int v = bestS[i];\n            if (v == 1) continue;               // source cannot be removed\n            // quick test: would some resident become uncovered?\n            bool essential = false;\n            for (int w = 0; w < WORDS; ++w) {\n                unsigned long long after = bestMask[w] & ~coverMask[v][w];\n                if (after != bestMask[w]) { essential = true; break; }\n            }\n            if (essential) continue;             // removal would be infeasible\n\n            vector<int> ns = bestS;\n            ns.erase(ns.begin() + i);\n            ll c;\n            bool f = evaluateSet(ns, c);\n            if (f && c < bestCost - 1) {\n                // accept\n                bestCost = c;\n                bestS = ns;\n                inS = bestIn;\n                // rebuild mask\n                fill(bestMask.begin(), bestMask.end(), 0ULL);\n                for (int xv : bestS)\n                    for (int w = 0; w < WORDS; ++w) bestMask[w] |= coverMask[xv][w];\n                bestIn = inS;\n                changed = true;\n                break;                            // start a new iteration\n            }\n        }\n        if (changed) continue;\n\n        /* ---- addition ---- */\n        vector<int> cand = neighbours(bestIn);\n        shuffle(cand.begin(), cand.end(), rng);\n        for (int v : cand) {\n            vector<int> ns = bestS;\n            ns.push_back(v);\n            ll c;\n            bool f = evaluateSet(ns, c);\n            if (f && c < bestCost - 1) {\n                bestCost = c;\n                bestS = ns;\n                inS[v] = 1;\n                bestIn = inS;\n                for (int w = 0; w < WORDS; ++w) bestMask[w] |= coverMask[v][w];\n                changed = true;\n                break;\n            }\n        }\n    }\n\n    /* ----- final full evaluation (radii + edges) ----- */\n    bool finalFeas;\n    ll finalCost;\n    vector<int> finalRadius;\n    vector<int> finalEdges;\n    fullEvaluation(bestS, finalFeas, finalCost, finalRadius, finalEdges);\n\n    /* ----- output ----- */\n    for (int i = 1; i <= N; ++i) {\n        if (i > 1) cout << ' ';\n        cout << finalRadius[i];\n    }\n    cout << '\\n';\n    vector<int> B(M + 1, 0);\n    for (int id : finalEdges) B[id] = 1;\n    for (int j = 1; j <= M; ++j) {\n        if (j > 1) cout << ' ';\n        cout << B[j];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Swap {\n    int x1, y1, x2, y2;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 30;\n    const int M = N * (N + 1) / 2;          // 465\n\n    /* ----- convert triangular coordinates to linear indices ----- */\n    vector<vector<int>> idx(N, vector<int>(N, -1));\n    int cur = 0;\n    for (int x = 0; x < N; ++x)\n        for (int y = 0; y <= x; ++y)\n            idx[x][y] = cur++;\n\n    /* ----- read the permutation ----- */\n    vector<int> initValue(M);\n    for (int x = 0; x < N; ++x)\n        for (int y = 0; y <= x; ++y) {\n            int v;  cin >> v;\n            initValue[idx[x][y]] = v;\n        }\n\n    /* ----- helper: test whether the array is a heap ----- */\n    auto isHeap = [&](const vector<int>& a) -> bool {\n        for (int x = 0; x + 1 < N; ++x) {\n            for (int y = 0; y <= x; ++y) {\n                int p = idx[x][y];\n                int l = idx[x + 1][y];\n                int r = idx[x + 1][y + 1];\n                if (a[p] > a[l] || a[p] > a[r]) return false;\n            }\n        }\n        return true;\n    };\n\n    /* ----- many randomised heapify runs ----- */\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    const int TRIALS = 2000;\n    const double EPS = 0.1;               // probability to take the larger child\n\n    vector<Swap> bestOps;\n    int bestK = INT_MAX;\n\n    for (int trial = 0; trial < TRIALS; ++trial) {\n        vector<int> curVal = initValue;   // copy\n        vector<Swap> ops;\n\n        // bottom\u2011up, level by level\n        for (int x = N - 2; x >= 0; --x) {\n            // order of processing the nodes on this level\n            vector<int> ys(x + 1);\n            iota(ys.begin(), ys.end(), 0);\n            if (trial > 0) shuffle(ys.begin(), ys.end(), rng);\n\n            for (int y : ys) {\n                int curX = x, curY = y;\n                while (curX < N - 1) {\n                    int pIdx = idx[curX][curY];\n                    int lIdx = idx[curX + 1][curY];\n                    int rIdx = idx[curX + 1][curY + 1];\n\n                    int childIdx = -1, childX = -1, childY = -1;\n\n                    // look for a child that violates the heap property\n                    if (curVal[pIdx] > curVal[lIdx]) {\n                        childIdx = lIdx;\n                        childX = curX + 1;\n                        childY = curY;\n                    }\n                    if (curVal[pIdx] > curVal[rIdx]) {\n                        if (childIdx == -1 || curVal[rIdx] < curVal[childIdx]) {\n                            childIdx = rIdx;\n                            childX = curX + 1;\n                            childY = curY + 1;\n                        }\n                    }\n\n                    if (childIdx == -1) break;          // heap already satisfied\n\n                    // perform ONE adjacent swap (the two positions are neighbours)\n                    ops.emplace_back(curX, curY, childX, childY);\n                    swap(curVal[pIdx], curVal[childIdx]);\n\n                    // continue sifting the moved ball downwards\n                    curX = childX;\n                    curY = childY;\n                }\n            }\n        }\n\n        if ((int)ops.size() < bestK) {\n            bestK = (int)ops.size();\n            bestOps = move(ops);\n        }\n    }\n\n    /* ----- try to delete useless swaps ----- */\n    for (int i = 0; i < (int)bestOps.size(); ++i) {\n        vector<int> curVal = initValue;\n        // apply all swaps except the i\u2011th\n        for (int j = 0; j < (int)bestOps.size(); ++j) if (j != i) {\n            const Swap& s = bestOps[j];\n            int a = idx[s.x1][s.y1];\n            int b = idx[s.x2][s.y2];\n            swap(curVal[a], curVal[b]);\n        }\n        if (isHeap(curVal)) {\n            bestOps.erase(bestOps.begin() + i);\n            --i;          // continue scanning\n        }\n    }\n\n    /* ----- output ----- */\n    cout << bestOps.size() << '\\n';\n    for (const Swap& s : bestOps)\n        cout << s.x1 << ' ' << s.y1 << ' ' << s.x2 << ' ' << s.y2 << '\\n';\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\n#include <ext/pb_ds/assoc_container.hpp>\nusing namespace std;\nusing namespace __gnu_pbds;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int dr[4] = {-1, 1, 0, 0};\n    const int dc[4] = {0, 0, -1, 1};\n\n    /* ---------- input ---------- */\n    int D_in, N;\n    if (!(cin >> D_in >> N)) return 0;\n    const int D = 9;                     // D is always 9 in the problem\n\n    vector<vector<bool>> obstacle(D, vector<bool>(D, false));\n    for (int k = 0; k < N; ++k) {\n        int ri, rj;\n        cin >> ri >> rj;\n        obstacle[ri][rj] = true;\n    }\n\n    const int R = 0;\n    const int C = (D - 1) / 2;           // entrance (0,4)\n\n    /* ---------- depth (BFS) ---------- */\n    vector<vector<int>> depth(D, vector<int>(D, -1));\n    queue<pair<int,int>> q;\n    depth[R][C] = 0;\n    q.emplace(R, C);\n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        for (int d = 0; d < 4; ++d) {\n            int nr = r + dr[d], nc = c + dc[d];\n            if (nr < 0 || nr >= D || nc < 0 || nc >= D) continue;\n            if (obstacle[nr][nc]) continue;\n            if (depth[nr][nc] != -1) continue;\n            depth[nr][nc] = depth[r][c] + 1;\n            q.emplace(nr, nc);\n        }\n    }\n\n    const int M = D * D - 1 - N;         // number of containers\n\n    /* ---------- ordered set for median ---------- */\n    using ordered_set = tree<int, null_type, less<int>, rb_tree_tag,\n                             tree_order_statistics_node_update>;\n    ordered_set S;\n    for (int i = 0; i < M; ++i) S.insert(i);\n\n    /* ---------- data for storage ---------- */\n    vector<int> pos_x(M, -1), pos_y(M, -1);\n    vector<vector<int>> container_at(D, vector<int>(D, -1));\n    vector<vector<bool>> occupied(D, vector<bool>(D, false));\n\n    /* ---------- storage phase ---------- */\n    for (int step = 0; step < M; ++step) {\n        int t;                           // number written on the arriving container\n        cin >> t;\n\n        /* median of the still unused numbers */\n        int median = *S.find_by_order(S.size() / 2);   // lower median\n        S.erase(t);                                      // number t will be used now\n\n        /* current empty squares */\n        vector<vector<bool>> empty(D, vector<bool>(D, false));\n        for (int i = 0; i < D; ++i)\n            for (int j = 0; j < D; ++j)\n                if (!obstacle[i][j] && !occupied[i][j])\n                    empty[i][j] = true;\n\n        /* articulation points \u2013 Tarjan */\n        vector<vector<int>> disc(D, vector<int>(D, 0));\n        vector<vector<int>> low(D, vector<int>(D, 0));\n        vector<vector<bool>> visited(D, vector<bool>(D, false));\n        vector<vector<bool>> isArt(D, vector<bool>(D, false));\n        int timer = 0;\n        function<void(int,int,int,int)> dfs = [&](int r, int c,\n                                                   int parent_r, int parent_c) {\n            visited[r][c] = true;\n            disc[r][c] = low[r][c] = ++timer;\n            int child = 0;\n            for (int d = 0; d < 4; ++d) {\n                int nr = r + dr[d], nc = c + dc[d];\n                if (nr < 0 || nr >= D || nc < 0 || nc >= D) continue;\n                if (!empty[nr][nc]) continue;\n                if (nr == parent_r && nc == parent_c) continue;\n                if (!visited[nr][nc]) {\n                    ++child;\n                    dfs(nr, nc, r, c);\n                    low[r][c] = min(low[r][c], low[nr][nc]);\n                    if (parent_r == -1 && child > 1) isArt[r][c] = true;\n                    if (parent_r != -1 && low[nr][nc] >= disc[r][c]) isArt[r][c] = true;\n                } else {\n                    low[r][c] = min(low[r][c], disc[nr][nc]);\n                }\n            }\n        };\n        dfs(R, C, -1, -1);\n\n        /* collect candidate cells (empty, not entrance, not articulation) */\n        vector<pair<int, pair<int,int>>> candidates;\n        for (int i = 0; i < D; ++i) {\n            for (int j = 0; j < D; ++j) {\n                if (i == R && j == C) continue;          // entrance\n                if (!empty[i][j]) continue;\n                if (isArt[i][j]) continue;\n                candidates.emplace_back(depth[i][j], make_pair(i, j));\n            }\n        }\n\n        // safety \u2013 should never be empty\n        if (candidates.empty()) {\n            for (int i = 0; i < D; ++i)\n                for (int j = 0; j < D; ++j)\n                    if (empty[i][j])\n                        candidates.emplace_back(depth[i][j], make_pair(i, j));\n        }\n\n        sort(candidates.begin(), candidates.end(),\n             [](const auto& a, const auto& b){ return a.first < b.first; });\n\n        /* choose shallow for small numbers, deep for large numbers */\n        int idx;\n        if (t <= median)          // small number \u2192 shallowest\n            idx = 0;\n        else                      // large number \u2192 deepest\n            idx = (int)candidates.size() - 1;\n\n        // safety bounds\n        if (idx < 0) idx = 0;\n        if (idx >= (int)candidates.size()) idx = (int)candidates.size() - 1;\n\n        int best_r = candidates[idx].second.first;\n        int best_c = candidates[idx].second.second;\n\n        /* store the container */\n        occupied[best_r][best_c] = true;\n        container_at[best_r][best_c] = t;\n        pos_x[t] = best_r;\n        pos_y[t] = best_c;\n\n        cout << best_r << ' ' << best_c << '\\n';\n        cout.flush();\n    }\n\n    /* ---------- retrieval phase \u2013 greedy by smallest number ---------- */\n    for (int step = 0; step < M; ++step) {\n        /* reachable empty region (BFS) */\n        vector<vector<bool>> reachable(D, vector<bool>(D, false));\n        queue<pair<int,int>> qreach;\n        reachable[R][C] = true;\n        qreach.emplace(R, C);\n        while (!qreach.empty()) {\n            auto [r, c] = qreach.front(); qreach.pop();\n            for (int d = 0; d < 4; ++d) {\n                int nr = r + dr[d], nc = c + dc[d];\n                if (nr < 0 || nr >= D || nc < 0 || nc >= D) continue;\n                if (obstacle[nr][nc]) continue;\n                if (occupied[nr][nc]) continue;          // only empty squares\n                if (reachable[nr][nc]) continue;\n                reachable[nr][nc] = true;\n                qreach.emplace(nr, nc);\n            }\n        }\n\n        /* pick reachable container with smallest number */\n        int bestNum = INT_MAX, bestR = -1, bestC = -1;\n        for (int i = 0; i < D; ++i) {\n            for (int j = 0; j < D; ++j) {\n                if (!occupied[i][j]) continue;\n                bool adjacent = false;\n                for (int d = 0; d < 4; ++d) {\n                    int ni = i + dr[d], nj = j + dc[d];\n                    if (ni < 0 || ni >= D || nj < 0 || nj >= D) continue;\n                    if (reachable[ni][nj]) { adjacent = true; break; }\n                }\n                if (!adjacent) continue;\n                int num = container_at[i][j];\n                if (num < bestNum) {\n                    bestNum = num;\n                    bestR = i; bestC = j;\n                }\n            }\n        }\n\n        /* output and remove */\n        cout << bestR << ' ' << bestC << '\\n';\n        cout.flush();\n        occupied[bestR][bestC] = false;\n    }\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n, m;\nconst int MAXC = 105;                     // colours 0 \u2026 m (m \u2264 100)\nint a[55][55];\nint total[MAXC];\nint adjCnt[MAXC][MAXC];\nbool need[MAXC][MAXC];\n\nint dx[4] = {-1, 1, 0, 0};\nint dy[4] = {0, 0, -1, 1};\n\nint vis[55][55];\nint bfsStamp = 0;\n\nqueue<pair<int,int>> q;                   // candidates for deletion\n\n// ------------------------------------------------------------------\nbool canDelete(int x, int y);\nvoid doDelete(int x, int y);\n\n// ------------------------------------------------------------------\nbool canDelete(int x, int y) {\n    int c = a[x][y];\n    if (c == 0) return false;\n    if (total[c] <= 1) return false;                 // colour must survive\n\n    // 1) the square must already touch colour 0 (or the outside)\n    bool adjZero = false;\n    for (int dir = 0; dir < 4; ++dir) {\n        int nx = x + dx[dir], ny = y + dy[dir];\n        if (nx < 0 || nx >= n || ny < 0 || ny >= n) { adjZero = true; break; }\n        if (a[nx][ny] == 0) { adjZero = true; break; }\n    }\n    if (!adjZero) return false;\n\n    // colours of the four neighbours (0 = outside)\n    int nbColour[4];\n    int cnt[MAXC] = {0};\n\n    for (int dir = 0; dir < 4; ++dir) {\n        int nx = x + dx[dir], ny = y + dy[dir];\n        int d;\n        if (nx < 0 || nx >= n || ny < 0 || ny >= n) d = 0;\n        else d = a[nx][ny];\n        nbColour[dir] = d;\n        ++cnt[d];                                    // count neighbours of each colour\n    }\n\n    // 2) must not create a forbidden adjacency 0\u2011d\n    for (int dir = 0; dir < 4; ++dir) {\n        int d = nbColour[dir];\n        if (d == c) continue;\n        if (d != 0 && !need[0][d]) return false;    // would create illegal 0\u2011d\n    }\n\n    // 3) each required adjacency must stay alive (at least one undirected edge left)\n    for (int d = 0; d <= m; ++d) {\n        if (!need[c][d]) continue;\n        if (cnt[d] == 0) continue;                 // we are not touching this colour\n        if (adjCnt[c][d] - 2 * cnt[d] < 2) return false;\n    }\n\n    // 4) after removal the colour must still be connected\n    int sx = -1, sy = -1;\n    for (int dir = 0; dir < 4; ++dir) {\n        int nx = x + dx[dir], ny = y + dy[dir];\n        if (0 <= nx && nx < n && 0 <= ny && ny < n && a[nx][ny] == c) {\n            sx = nx; sy = ny;\n            break;\n        }\n    }\n    if (sx == -1) return false;                     // should not happen (total[c] \u2265 2)\n\n    ++bfsStamp;\n    queue<pair<int,int>> qq;\n    qq.emplace(sx, sy);\n    vis[sx][sy] = bfsStamp;\n    int cntReached = 0;\n    while (!qq.empty()) {\n        auto [cx, cy] = qq.front(); qq.pop();\n        ++cntReached;\n        for (int dir = 0; dir < 4; ++dir) {\n            int nx = cx + dx[dir], ny = cy + dy[dir];\n            if (nx < 0 || nx >= n || ny < 0 || ny >= n) continue;\n            if (a[nx][ny] != c) continue;\n            if (nx == x && ny == y) continue;      // the cell we plan to delete\n            if (vis[nx][ny] == bfsStamp) continue;\n            vis[nx][ny] = bfsStamp;\n            qq.emplace(nx, ny);\n        }\n    }\n    if (cntReached != total[c] - 1) return false; // would disconnect the colour\n\n    return true;\n}\n\n// ------------------------------------------------------------------\nvoid doDelete(int x, int y) {\n    int c = a[x][y];\n    a[x][y] = 0;\n    --total[c];\n\n    for (int dir = 0; dir < 4; ++dir) {\n        int nx = x + dx[dir], ny = y + dy[dir];\n        int d;\n        if (nx < 0 || nx >= n || ny < 0 || ny >= n) {\n            d = 0;                     // outside world\n        } else {\n            d = a[nx][ny];\n        }\n        if (d == c) continue;          // same colour, edge unchanged\n\n        // remove the old adjacency c\u2011d (two directed edges)\n        adjCnt[c][d] -= 2;\n        adjCnt[d][c] -= 2;\n\n        // create a new adjacency 0\u2011d (if d is a coloured cell)\n        if (d != 0) {\n            adjCnt[0][d] += 2;\n            adjCnt[d][0] += 2;\n        }\n    }\n\n    // neighbours may become new candidates because they now touch a 0 cell\n    for (int dir = 0; dir < 4; ++dir) {\n        int nx = x + dx[dir], ny = y + dy[dir];\n        if (0 <= nx && nx < n && 0 <= ny && ny < n && a[nx][ny] > 0) {\n            q.emplace(nx, ny);\n        }\n    }\n}\n\n// ------------------------------------------------------------------\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> n >> m;\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j)\n            cin >> a[i][j];\n\n    // ----- count squares and all adjacency edges of the original map -----\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            int c = a[i][j];\n            ++total[c];\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + dx[dir], nj = j + dy[dir];\n                if (ni < 0 || ni >= n || nj < 0 || nj >= n) {\n                    ++adjCnt[c][0];\n                    ++adjCnt[0][c];\n                } else {\n                    int d = a[ni][nj];\n                    if (d != c) {\n                        ++adjCnt[c][d];\n                        ++adjCnt[d][c];\n                    }\n                }\n            }\n        }\n    }\n\n    // which adjacencies existed in the original map?\n    for (int c = 0; c <= m; ++c)\n        for (int d = 0; d <= m; ++d)\n            need[c][d] = (adjCnt[c][d] > 0);\n\n    // ----- initialise candidate queue: squares already touching colour 0 -----\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) if (a[i][j] > 0) {\n            bool adjZero = false;\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + dx[dir], nj = j + dy[dir];\n                if (ni < 0 || ni >= n || nj < 0 || nj >= n) { adjZero = true; break; }\n                if (a[ni][nj] == 0) { adjZero = true; break; }\n            }\n            if (adjZero) q.emplace(i, j);\n        }\n    }\n\n    // ----- greedy deletion -----\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        if (a[x][y] == 0) continue;                 // already deleted\n        if (canDelete(x, y))\n            doDelete(x, y);\n    }\n\n    // ----- output -----\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            if (j) cout << ' ';\n            cout << a[i][j];\n        }\n        cout << '\\n';\n    }\n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, D, Q;\n    if (!(cin >> N >> D >> Q)) return 0;\n    \n    // win[i] \u2013 times item i was heavier, tie[i] \u2013 times equal\n    vector<int> win(N, 0), tie(N, 0);\n    int performed = 0;\n    \n    // ------------------------------------------------------------\n    // 1) forced consecutive pairs (every item appears at least once)\n    for (int i = 0; i + 1 < N && performed < Q; ++i) {\n        int a = i, b = i + 1;\n        cout << \"1 1 \" << a << ' ' << b << \"\\n\";\n        cout.flush();\n        ++performed;\n        string res; cin >> res;\n        if (res == \">\") {\n            ++win[a];\n        } else if (res == \"<\") {\n            ++win[b];\n        } else { // \"=\"\n            ++tie[a];\n            ++tie[b];\n        }\n    }\n    // ------------------------------------------------------------\n    // 2) random pairs until we have performed exactly Q queries\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    while (performed < Q) {\n        int a = rng() % N;\n        int b = rng() % N;\n        if (a == b) continue;\n        if (a > b) swap(a, b);\n        cout << \"1 1 \" << a << ' ' << b << \"\\n\";\n        cout.flush();\n        ++performed;\n        string res; cin >> res;\n        if (res == \">\") {\n            ++win[a];\n        } else if (res == \"<\") {\n            ++win[b];\n        } else { // \"=\"\n            ++tie[a];\n            ++tie[b];\n        }\n    }\n    \n    // ------------------------------------------------------------\n    // 3) compute rough weight estimates and sort items\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    vector<double> score(N);\n    for (int i = 0; i < N; ++i) score[i] = win[i] + 0.5 * tie[i];\n    stable_sort(idx.begin(), idx.end(),\n                [&](int a, int b) { return score[a] > score[b]; });\n    \n    // ------------------------------------------------------------\n    // 4) LPT (Longest Processing Time) assignment to D groups\n    vector<double> groupSum(D, 0.0);\n    vector<int> groupOf(N, -1);\n    for (int pos = 0; pos < N; ++pos) {\n        int it = idx[pos];\n        // find group with minimal current sum\n        int best = 0;\n        for (int g = 1; g < D; ++g) {\n            if (groupSum[g] < groupSum[best]) best = g;\n        }\n        groupOf[it] = best;\n        groupSum[best] += score[it];\n    }\n    \n    // ------------------------------------------------------------\n    // 5) output the final partition\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << groupOf[i];\n    }\n    cout << \"\\n\";\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    const int per = n / m;\n    vector<vector<int>> st(m);\n    vector<int> where(n + 1, -1);\n\n    for (int i = 0; i < m; ++i) {\n        st[i].reserve(per);\n        for (int j = 0; j < per; ++j) {\n            int v; cin >> v;\n            st[i].push_back(v);\n            where[v] = i;\n        }\n    }\n\n    vector<pair<int,int>> ops;\n\n    for (int v = 1; v <= n; ++v) {\n        int src = where[v];\n\n        // While v is not at the top, move boxes above it\n        while (!st[src].empty() && st[src].back() != v) {\n            int curTop = st[src].back();\n            int dest = -1;\n            \n            // Priority 1: Find a stack with top > curTop (no new inversion)\n            // Choose the one with maximum top to be most useful later\n            int bestTop = -1;\n            for (int i = 0; i < m; ++i) {\n                if (i == src) continue;\n                if (!st[i].empty() && st[i].back() > curTop && st[i].back() > bestTop) {\n                    bestTop = st[i].back();\n                    dest = i;\n                }\n            }\n            \n            // Priority 2: Use an empty stack if available\n            if (dest == -1) {\n                for (int i = 0; i < m; ++i) {\n                    if (i == src) continue;\n                    if (st[i].empty()) {\n                        dest = i;\n                        break;\n                    }\n                }\n            }\n            \n            // Priority 3: Any other stack - prefer larger top to minimize future moves\n            if (dest == -1) {\n                int maxTop = -1;\n                for (int i = 0; i < m; ++i) {\n                    if (i == src) continue;\n                    int top = st[i].empty() ? -1 : st[i].back();\n                    if (top > maxTop) {\n                        maxTop = top;\n                        dest = i;\n                    }\n                }\n            }\n\n            // Operation 1: move curTop to dest\n            ops.emplace_back(curTop, dest + 1);\n            st[src].pop_back();\n            st[dest].push_back(curTop);\n            where[curTop] = dest;\n        }\n\n        // Operation 2: carry out v (free, no energy)\n        ops.emplace_back(v, 0);\n        st[src].pop_back();\n        where[v] = -1;\n    }\n\n    // Output: one operation per line\n    for (auto [box, dst] : ops) {\n        cout << box << ' ' << dst << '\\n';\n    }\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n\n    vector<string> h(N - 1);\n    for (int i = 0; i < N - 1; ++i) cin >> h[i];\n    vector<string> v(N);\n    for (int i = 0; i < N; ++i) cin >> v[i];\n    vector<vector<int>> d(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) cin >> d[i][j];\n\n    const int di[4] = {0, 1, 0, -1};\n    const int dj[4] = {1, 0, -1, 0};\n    const char dc[4] = {'R', 'D', 'L', 'U'};\n\n    // -----------------------------------------------------------------\n    // 1. depth\u2011first walk that visits every cell and returns to (0,0)\n    // -----------------------------------------------------------------\n    vector<vector<char>> visited(N, vector<char>(N, 0));\n    string base;                     // the DFS tour\n    function<void(int,int)> dfs = [&](int i, int j) {\n        visited[i][j] = 1;\n        for (int dir = 0; dir < 4; ++dir) {\n            int ni = i + di[dir];\n            int nj = j + dj[dir];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            if (visited[ni][nj]) continue;\n\n            bool free = false;\n            if (dir == 0 && j + 1 < N && v[i][j] == '0') free = true;          // right\n            if (dir == 1 && i + 1 < N && h[i][j] == '0') free = true;          // down\n            if (dir == 2 && j - 1 >= 0 && v[i][j-1] == '0') free = true;      // left\n            if (dir == 3 && i - 1 >= 0 && h[i-1][j] == '0') free = true;      // up\n            if (!free) continue;\n\n            base.push_back(dc[dir]);                // go forward\n            dfs(ni, nj);\n            base.push_back(dc[(dir + 2) % 4]);      // go back\n        }\n    };\n    dfs(0, 0);               // the walk is closed, starts and ends in (0,0)\n\n    // -----------------------------------------------------------------\n    // 2. repeat the walk as many times as the length limit allows\n    // -----------------------------------------------------------------\n    const int L0 = (int)base.size();               // = 2\u00b7(N\u00b2\u20111)\n    const int Lmax = 100000;\n    int repeat = Lmax / L0;                         // maximal full repetitions\n\n    string answer;\n    answer.reserve(repeat * L0);\n    for (int i = 0; i < repeat; ++i) answer += base;\n\n    cout << answer << '\\n';\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 15;                // keyboard size (always 15)\nconst int TOT = N * N;           // 225 cells\nconst int INF = 1e9;            // a large number used as \"infinite\" cost\n\n// ------------------------------------------------------------\n// longest k (0 \u2264 k \u2264 5) such that suffix of a (len k) = prefix of b (len k)\nint overlap(const string &a, const string &b) {\n    int maxk = min({(int)a.size(), (int)b.size(), 5});\n    for (int k = maxk; k >= 0; --k) {\n        bool ok = true;\n        for (int i = 0; i < k; ++i) {\n            if (a[a.size() - k + i] != b[i]) { ok = false; break; }\n        }\n        if (ok) return k;\n    }\n    return 0;\n}\n\n// ------------------------------------------------------------\n// greedy bidirectional merge, startIdx is the index of the word we begin with\nstring buildSuperstring(const vector<string> &words, int startIdx) {\n    int m = (int)words.size();\n    vector<bool> used(m, false);\n    string cur = words[startIdx];\n    used[startIdx] = true;\n\n    while (true) {\n        int bestId = -1;\n        int bestAdd = INF;          // extra characters added\n        int bestOri = 0;            // 0 = append, 1 = prepend\n        int bestOv = 0;\n\n        for (int j = 0; j < m; ++j) if (!used[j]) {\n            // append\n            int ov_app = overlap(cur, words[j]);\n            int add_app = (int)words[j].size() - ov_app;\n            // prepend\n            int ov_pre = overlap(words[j], cur);\n            int add_pre = (int)words[j].size() - ov_pre;\n\n            if (add_app <= add_pre) {\n                if (add_app < bestAdd) {\n                    bestAdd = add_app;\n                    bestId = j;\n                    bestOri = 0;\n                    bestOv = ov_app;\n                }\n            } else {\n                if (add_pre < bestAdd) {\n                    bestAdd = add_pre;\n                    bestId = j;\n                    bestOri = 1;\n                    bestOv = ov_pre;\n                }\n            }\n        }\n        if (bestId == -1) break;               // all words used\n\n        if (bestOri == 0) {                     // append\n            cur += words[bestId].substr(bestOv);\n        } else {                                 // prepend\n            cur = words[bestId].substr(0, (int)words[bestId].size() - bestOv) + cur;\n        }\n        used[bestId] = true;\n    }\n    return cur;\n}\n\n// ------------------------------------------------------------\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int tmpN, M;\n    if (!(cin >> tmpN >> M)) return 0;   // read N (always 15) and M\n    int si, sj;\n    cin >> si >> sj;\n\n    vector<string> board(N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n\n    // positions of each letter\n    vector<vector<int>> cells(26);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            int id = i * N + j;\n            cells[board[i][j] - 'A'].push_back(id);\n        }\n\n    vector<string> words(M);\n    for (int i = 0; i < M; ++i) cin >> words[i];\n\n    // distance matrix between all cells\n    static int dist[TOT][TOT];\n    for (int i = 0; i < TOT; ++i) {\n        int x1 = i / N, y1 = i % N;\n        for (int j = 0; j < TOT; ++j) {\n            int x2 = j / N, y2 = j % N;\n            dist[i][j] = abs(x1 - x2) + abs(y1 - y2);\n        }\n    }\n\n    // --------------------------------------------------------\n    // try a few random start words\n    mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());\n    const int TRIALS = 5;\n\n    int bestCost = INF;\n    vector<pair<int,int>> bestPath;   // (i , j) for each operation\n\n    for (int trial = 0; trial < TRIALS; ++trial) {\n        int startWord = uniform_int_distribution<int>(0, M-1)(rng);\n        string S = buildSuperstring(words, startWord);\n        int L = (int)S.size();\n\n        // DP: dpPrev[c] = minimal cost to end at cell c after typing the current prefix\n        vector<int> dpPrev(TOT, INF), dpCurr(TOT, INF);\n        // predecessor for reconstruction\n        vector<vector<short>> pre(L+1, vector<short>(TOT, -1));\n\n        int startCell = si * N + sj;\n        dpPrev[startCell] = 0;                 // cost before typing anything\n\n        for (int pos = 0; pos < L; ++pos) {\n            char c = S[pos];\n            const vector<int> &allowed = cells[c - 'A'];\n            fill(dpCurr.begin(), dpCurr.end(), INF);\n            for (int curIdx : allowed) {\n                int best = INF;\n                short bestPrev = -1;\n                for (int prevIdx = 0; prevIdx < TOT; ++prevIdx) {\n                    int pc = dpPrev[prevIdx];\n                    if (pc == INF) continue;\n                    int cand = pc + dist[prevIdx][curIdx] + 1;\n                    if (cand < best) {\n                        best = cand;\n                        bestPrev = (short)prevIdx;\n                    }\n                }\n                dpCurr[curIdx] = best;\n                pre[pos+1][curIdx] = bestPrev;\n            }\n            dpPrev.swap(dpCurr);\n        }\n\n        // best final cell\n        int finalIdx = -1;\n        int finalCost = INF;\n        for (int i = 0; i < TOT; ++i) {\n            if (dpPrev[i] < finalCost) {\n                finalCost = dpPrev[i];\n                finalIdx = i;\n            }\n        }\n\n        if (finalCost < bestCost) {\n            bestCost = finalCost;\n            // reconstruct path\n            bestPath.assign(L, {0,0});\n            int cur = finalIdx;\n            for (int p = L; p >= 1; --p) {\n                bestPath[p-1] = {cur / N, cur % N};\n                cur = pre[p][cur];\n            }\n        }\n    }\n\n    // --------------------------------------------------------\n    // output only the coordinate lines, no extra line with the length\n    for (auto [i,j] : bestPath) {\n        cout << i << ' ' << j << '\\n';\n    }\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\ndouble eps;\nvector<vector<int>> val;          // -1 = unknown, 0 = known zero, >0 = known positive\nvector<vector<char>> drilled;     // true if we have queried this cell exactly\nvector<int> rowPos, colPos;\n\n/* ---------- communication with the judge ---------- */\nint query_divine(const vector<pair<int,int>>& cells) {\n    cout << 'q' << ' ' << (int)cells.size();\n    for (auto [i,j] : cells) cout << ' ' << i << ' ' << j;\n    cout << '\\n' << std::flush;\n    int resp; cin >> resp;\n    return resp;\n}\nint query_drill(int i, int j) {\n    cout << 'q' << ' ' << 1 << ' ' << i << ' ' << j << '\\n' << std::flush;\n    int v; cin >> v;\n    return v;\n}\n\n/* ---------- recursive subdivision ---------- */\nvoid dfs(int r1, int r2, int c1, int c2) {\n    if (r1 > r2 || c1 > c2) return;\n    int h = r2 - r1 + 1, w = c2 - c1 + 1;\n    int area = h * w;\n\n    // base case: at most 2\u00d72 -> just drill\n    if (area <= 4) {\n        for (int i = r1; i <= r2; ++i)\n            for (int j = c1; j <= c2; ++j) {\n                if (!drilled[i][j]) {\n                    val[i][j] = query_drill(i, j);\n                    drilled[i][j] = 1;\n                }\n            }\n        return;\n    }\n\n    // query the whole rectangle\n    vector<pair<int,int>> cells;\n    cells.reserve(area);\n    for (int i = r1; i <= r2; ++i)\n        for (int j = c1; j <= c2; ++j)\n            cells.emplace_back(i, j);\n    int sum = query_divine(cells);\n\n    if (sum == 0) {                 // completely empty\n        for (int i = r1; i <= r2; ++i)\n            for (int j = c1; j <= c2; ++j)\n                val[i][j] = 0;\n        return;\n    }\n\n    // otherwise split into four quadrants\n    int rm = (r1 + r2) / 2;\n    int cm = (c1 + c2) / 2;\n    dfs(r1, rm, c1, cm);\n    dfs(r1, rm, cm+1, c2);\n    dfs(rm+1, r2, c1, cm);\n    dfs(rm+1, r2, cm+1, c2);\n}\n\n/* ---------- main ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> eps)) return 0;\n\n    // read and ignore the shapes\n    for (int k = 0; k < M; ++k) {\n        int d; cin >> d;\n        for (int t = 0; t < d; ++t) { int a,b; cin >> a >> b; }\n    }\n\n    rowPos.assign(N, 0);\n    colPos.assign(N, 0);\n    val.assign(N, vector<int>(N, -1));\n    drilled.assign(N, vector<char>(N, 0));\n\n    // ----- find non\u2011empty rows (single query) -----\n    for (int i = 0; i < N; ++i) {\n        vector<pair<int,int>> cells;\n        cells.reserve(N);\n        for (int j = 0; j < N; ++j) cells.emplace_back(i, j);\n        if (query_divine(cells) > 0) rowPos[i] = 1;\n    }\n\n    // ----- find non\u2011empty columns (single query) -----\n    for (int j = 0; j < N; ++j) {\n        vector<pair<int,int>> cells;\n        cells.reserve(N);\n        for (int i = 0; i < N; ++i) cells.emplace_back(i, j);\n        if (query_divine(cells) > 0) colPos[j] = 1;\n    }\n\n    // locate the bounding rectangle of possible oil cells\n    int r1 = N, r2 = -1, c1 = N, c2 = -1;\n    for (int i = 0; i < N; ++i) if (rowPos[i]) {\n        r1 = min(r1, i);\n        r2 = max(r2, i);\n    }\n    for (int j = 0; j < N; ++j) if (colPos[j]) {\n        c1 = min(c1, j);\n        c2 = max(c2, j);\n    }\n\n    // if there is at least one non\u2011empty row/column, search inside the rectangle\n    if (r1 <= r2 && c1 <= c2) {\n        dfs(r1, r2, c1, c2);\n    }\n\n    // cells outside the rectangle are known to be zero (they cannot contain oil)\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (val[i][j] == -1) val[i][j] = 0;\n\n    // ----- first guess -----\n    vector<pair<int,int>> ans;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (val[i][j] > 0) ans.emplace_back(i, j);\n\n    cout << 'a' << ' ' << (int)ans.size();\n    for (auto [i,j] : ans) cout << ' ' << i << ' ' << j;\n    cout << '\\n' << std::flush;\n    int ok; cin >> ok;\n    if (ok == 1) return 0;          // success\n\n    // ----- fallback: drill all cells that have not been drilled yet -----\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (!drilled[i][j]) {\n                val[i][j] = query_drill(i, j);\n                drilled[i][j] = 1;\n            }\n\n    // ----- second guess (must be correct) -----\n    ans.clear();\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (val[i][j] > 0) ans.emplace_back(i, j);\n\n    cout << 'a' << ' ' << (int)ans.size();\n    for (auto [i,j] : ans) cout << ' ' << i << ' ' << j;\n    cout << '\\n' << std::flush;\n    // the judge will always answer 1 here\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Segment {\n    int cnt;                 // profit = 100 * cnt\n    long long delta;        // how many units are still available\n    int idx;                // rank\n    bool operator<(const Segment& other) const {\n        return cnt < other.cnt;   // max\u2011heap by cnt\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------- read input (the first integer is W = 1000) ---------- */\n    int W, D, N;\n    if (!(cin >> W >> D >> N)) return 0;\n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; ++d)\n        for (int k = 0; k < N; ++k) cin >> a[d][k];\n\n    /* ---------- 1. collect demands for each rank (i\u2011th smallest) ---- */\n    vector<vector<int>> demand(N, vector<int>(D));\n    for (int d = 0; d < D; ++d) {\n        vector<pair<int,int>> v;\n        v.reserve(N);\n        for (int k = 0; k < N; ++k) v.emplace_back(a[d][k], k);\n        sort(v.begin(), v.end(),\n             [](const pair<int,int>& p, const pair<int,int>& q){\n                 return p.first < q.first;\n             });\n        for (int i = 0; i < N; ++i) demand[i][d] = v[i].first;\n    }\n\n    /* ---------- 2. greedy area allocation (optimal B[i]) ------------ */\n    // safe buffer: worst total slack = N * (W-1)\n    long long capacity = 1LL * W * W - 1LL * N * (W - 1);\n    priority_queue<Segment> pq;\n    for (int i = 0; i < N; ++i) {\n        auto &vec = demand[i];\n        sort(vec.begin(), vec.end());\n        int prev = 0;\n        for (int t = 0; t < (int)vec.size(); ++t) {\n            int cur = vec[t];\n            int delta = cur - prev;\n            if (delta > 0) {\n                int cnt = D - t;          // days whose demand > prev\n                pq.push({cnt, delta, i});\n            }\n            prev = cur;\n        }\n    }\n\n    vector<long long> B(N, 0);\n    long long remain = capacity;\n    while (remain > 0 && !pq.empty()) {\n        Segment seg = pq.top(); pq.pop();\n        long long take = min(seg.delta, remain);\n        B[seg.idx] += take;\n        remain -= take;\n        seg.delta -= take;\n        if (seg.delta > 0) pq.push(seg);\n    }\n\n    /* ---------- 3. simple row packing (no overlap) ------------------ */\n    // sort indices by descending area \u2013 larger rectangles first\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(),\n         [&](int i, int j){ return B[i] > B[j]; });\n\n    vector<array<int,4>> placed(N);      // x, y, w, h\n    int curX = 0, curY = 0, rowHeight = 0;\n    for (int id : order) {\n        long long area = B[id];\n        // smallest width that still fits into height \u2264 W\n        int w = max(1, (int)((area + W - 1) / W));   // ceil(area / W)\n        int h = (int)((area + w - 1) / w);           // ceil(area / w)\n\n        if (curX + w > W) {          // start a new row\n            curX = 0;\n            curY += rowHeight;\n            rowHeight = 0;\n        }\n        placed[id] = {curX, curY, w, h};\n        curX += w;\n        rowHeight = max(rowHeight, h);\n    }\n\n    /* ---------- 4. prepare output (assign rectangles to reservations) */\n    // indices of rectangles sorted by area (ascending)\n    vector<int> ascIdx(N);\n    iota(ascIdx.begin(), ascIdx.end(), 0);\n    sort(ascIdx.begin(), ascIdx.end(),\n         [&](int i, int j){ return B[i] < B[j]; });\n\n    vector<vector<array<int,4>>> out(D, vector<array<int,4>>(N));\n    for (int d = 0; d < D; ++d) {\n        vector<pair<int,int>> vp;\n        vp.reserve(N);\n        for (int k = 0; k < N; ++k) vp.emplace_back(a[d][k], k);\n        sort(vp.begin(), vp.end(),\n             [](const pair<int,int>& p, const pair<int,int>& q){\n                 return p.first < q.first;\n             });\n        for (int i = 0; i < N; ++i) {\n            int reservation = vp[i].second;\n            const auto &rc = placed[ ascIdx[i] ];   // i\u2011th smallest rectangle\n            // rc = {x, y, w, h}\n            out[d][reservation] = {rc[0], rc[1],\n                                   rc[0] + rc[2], rc[1] + rc[3]};\n        }\n    }\n\n    /* ---------- 5. print ------------------------------------------------ */\n    for (int d = 0; d < D; ++d)\n        for (int k = 0; k < N; ++k) {\n            const auto &r = out[d][k];\n            cout << r[0] << ' ' << r[1] << ' '\n                 << r[2] << ' ' << r[3] << '\\n';\n        }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MOD = 998244353;\nconst int N = 9;            // board size\nconst int NSTAMP = 3;      // stamp size\nconst int MAX_K = 81;\nconst int M = 20;          // number of stamps\n\nint stamp[M][3][3];         // stamp values\n\n/* structure describing one possible stamp placement */\nstruct Act {\n    long long delta;   // change of the total sum\n    int m, p, q;\n};\n\n/* apply one action to the board (in\u2011place) */\nvoid applyStamp(int board[9][9], const Act& a) {\n    for (int di = 0; di < 3; ++di)\n        for (int dj = 0; dj < 3; ++dj) {\n            int &cell = board[a.p + di][a.q + dj];\n            cell += stamp[a.m][di][dj];\n            if (cell >= MOD) cell -= MOD;\n        }\n}\n\n/* compute delta of every possible action for the current board */\nvector<Act> computeDeltas(const int board[9][9]) {\n    vector<Act> actions;\n    actions.reserve(M * (N - 2) * (N - 2));\n    for (int m = 0; m < M; ++m) {\n        for (int p = 0; p <= N - NSTAMP; ++p) {\n            for (int q = 0; q <= N - NSTAMP; ++q) {\n                long long d = 0;\n                for (int di = 0; di < 3; ++di)\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int cur = board[p + di][q + dj];\n                        int nv = cur + stamp[m][di][dj];\n                        if (nv >= MOD) nv -= MOD;\n                        d += (nv - cur);\n                    }\n                actions.push_back({d, m, p, q});\n            }\n        }\n    }\n    return actions;\n}\n\n/* evaluate the best second step after applying action a1\n   (boardAfter is the board after the first action) */\nlong long bestSecondDelta(const int boardAfter[9][9]) {\n    long long best = LLONG_MIN;\n    for (int m = 0; m < M; ++m) {\n        for (int p = 0; p <= N - NSTAMP; ++p) {\n            for (int q = 0; q <= N - NSTAMP; ++q) {\n                long long d = 0;\n                for (int di = 0; di < 3; ++di)\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int cur = boardAfter[p + di][q + dj];\n                        int nv = cur + stamp[m][di][dj];\n                        if (nv >= MOD) nv -= MOD;\n                        d += (nv - cur);\n                    }\n                if (d > best) best = d;\n            }\n        }\n    }\n    return best;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N_in, M_in, K;\n    if (!(cin >> N_in >> M_in >> K)) return 0;   // N_in = 9, M_in = 20\n\n    int board[N][N];\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            long long x; cin >> x;\n            board[i][j] = int(x % MOD);\n        }\n\n    for (int m = 0; m < M; ++m)\n        for (int i = 0; i < 3; ++i)\n            for (int j = 0; j < 3; ++j) {\n                long long x; cin >> x;\n                stamp[m][i][j] = int(x % MOD);\n            }\n\n    vector<tuple<int,int,int>> ops;          // (m , p , q)\n    int remaining = K;\n\n    // random generator for tie\u2011breaking\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    while (remaining > 0) {\n        vector<Act> all = computeDeltas(board);\n        // find best single action\n        sort(all.begin(), all.end(),\n             [](const Act& a, const Act& b){ return a.delta > b.delta; });\n        Act bestSingle = all[0];\n\n        // greedy step \u2013 positive delta\n        if (bestSingle.delta > 0) {\n            applyStamp(board, bestSingle);\n            ops.emplace_back(bestSingle.m, bestSingle.p, bestSingle.q);\n            --remaining;\n            continue;\n        }\n\n        // --------- 2\u2011step lookahead ----------\n        const int T = 20;                     // number of first actions to try\n        long long bestPairDelta = bestSingle.delta;\n        Act bestFirst = bestSingle;\n        bool foundBetterPair = false;\n\n        // take the T best actions (they are already sorted)\n        vector<int> idx(T);\n        iota(idx.begin(), idx.end(), 0);\n        shuffle(idx.begin(), idx.end(), rng); // random order\n\n        for (int t = 0; t < T; ++t) {\n            const Act &a1 = all[idx[t]];\n            // simulate a1 on a temporary board\n            int tmp[N][N];\n            memcpy(tmp, board, sizeof(board));\n            // apply a1\n            for (int di = 0; di < 3; ++di)\n                for (int dj = 0; dj < 3; ++dj) {\n                    int &cell = tmp[a1.p + di][a1.q + dj];\n                    cell += stamp[a1.m][di][dj];\n                    if (cell >= MOD) cell -= MOD;\n                }\n            // best second step after a1\n            long long best2 = bestSecondDelta(tmp);\n            long long total = a1.delta + best2;\n            if (total > bestPairDelta) {\n                bestPairDelta = total;\n                bestFirst = a1;\n                foundBetterPair = true;\n            }\n        }\n\n        if (foundBetterPair && bestPairDelta > 0) {\n            // apply the first action of the improving pair\n            applyStamp(board, bestFirst);\n            ops.emplace_back(bestFirst.m, bestFirst.p, bestFirst.q);\n            --remaining;\n            continue;\n        }\n\n        // no positive improvement possible any more\n        break;\n    }\n\n    cout << ops.size() << '\\n';\n    for (auto [m, p, q] : ops)\n        cout << m << ' ' << p << ' ' << q << '\\n';\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 5;                 // fixed in all test cases\n    const int TOT = N * N;           // 25\n\n    int Ncase;\n    // the problem supplies exactly one test case, but we also accept several\n    while (cin >> Ncase) {\n        // read the matrix A\n        vector<vector<int>> A(N, vector<int>(N));\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                cin >> A[i][j];\n\n        /* ----- row of each container ----- */\n        vector<int> row_of(TOT, -1);\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                row_of[A[i][j]] = i;\n\n        /* ----- generate actions for the large crane ----- */\n        vector<string> actions(N);\n        string large;\n        large.reserve(500);               // enough for all cases\n\n        int curR = 0, curC = 0;             // initial position of the large crane\n\n        for (int c = 0; c < TOT; ++c) {\n            int targetR = row_of[c];\n\n            // vertical movement\n            while (curR < targetR) { large.push_back('D'); ++curR; }\n            while (curR > targetR) { large.push_back('U'); --curR; }\n\n            // horizontal movement to column 0 (the receiving gate)\n            while (curC > 0) { large.push_back('L'); --curC; }\n\n            // pick up the container\n            large.push_back('P');\n\n            // move to the dispatch gate (column N-1 = 4)\n            while (curC < N - 1) { large.push_back('R'); ++curC; }\n\n            // release the container\n            large.push_back('Q');\n        }\n\n        actions[0] = large;\n        const size_t L = actions[0].size();   // total number of turns\n\n        /* ----- actions for the small cranes ----- */\n        for (int i = 1; i < N; ++i) {\n            string s;\n            s.reserve(L);\n            s.push_back('B');                 // bomb in the first turn\n            s.append(L - 1, '.');             // do nothing afterwards\n            actions[i] = s;\n        }\n\n        /* ----- output ----- */\n        for (int i = 0; i < N; ++i)\n            cout << actions[i] << '\\n';\n    }\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int r, c; };\nstruct Edge { int to, rev, cap, cost; };\nstruct MinCostFlow {\n    const int INF = 1e9;\n    int N;\n    vector<vector<Edge>> G;\n    MinCostFlow(int n) : N(n), G(n) {}\n    void addEdge(int from, int to, int cap, int cost) {\n        Edge a{to, (int)G[to].size(), cap, cost};\n        Edge b{from, (int)G[from].size(), 0, -cost};\n        G[from].push_back(a);\n        G[to].push_back(b);\n    }\n    pair<int, long long> minCostMaxFlow(int s, int t) {\n        int flow = 0;\n        long long cost = 0;\n        vector<int> dist(N), pv(N), pe(N);\n        vector<int> potential(N, 0);\n        while (true) {\n            fill(dist.begin(), dist.end(), INF);\n            dist[s] = 0;\n            using P = pair<int, int>;\n            priority_queue<P, vector<P>, greater<P>> pq;\n            pq.emplace(0, s);\n            while (!pq.empty()) {\n                auto [d, v] = pq.top(); pq.pop();\n                if (d != dist[v]) continue;\n                for (int i = 0; i < (int)G[v].size(); ++i) {\n                    Edge &e = G[v][i];\n                    if (e.cap <= 0) continue;\n                    int nd = d + e.cost + potential[v] - potential[e.to];\n                    if (nd < dist[e.to]) {\n                        dist[e.to] = nd;\n                        pv[e.to] = v;\n                        pe[e.to] = i;\n                        pq.emplace(nd, e.to);\n                    }\n                }\n            }\n            if (dist[t] == INF) break;\n            for (int v = 0; v < N; ++v) {\n                if (dist[v] < INF) potential[v] += dist[v];\n            }\n            int addflow = INF;\n            for (int v = t; v != s; v = pv[v]) {\n                Edge &e = G[pv[v]][pe[v]];\n                addflow = min(addflow, e.cap);\n            }\n            for (int v = t; v != s; v = pv[v]) {\n                Edge &e = G[pv[v]][pe[v]];\n                e.cap -= addflow;\n                G[v][e.rev].cap += addflow;\n            }\n            flow += addflow;\n            cost += 1LL * addflow * potential[t];\n        }\n        return {flow, cost};\n    }\n};\n\nstatic inline int manhattan(const Pos& a, const Pos& b) {\n    return abs(a.r - b.r) + abs(a.c - b.c);\n}\n\nstatic void moveTo(Pos& cur, const Pos& target, vector<string>& ops) {\n    while (cur.r < target.r) { ops.emplace_back(\"D\"); cur.r++; }\n    while (cur.r > target.r) { ops.emplace_back(\"U\"); cur.r--; }\n    while (cur.c < target.c) { ops.emplace_back(\"R\"); cur.c++; }\n    while (cur.c > target.c) { ops.emplace_back(\"L\"); cur.c--; }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\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    vector<Pos> srcPos, snkPos;\n    vector<int> srcSup, snkDem;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (h[i][j] > 0) {\n                srcPos.push_back({i, j});\n                srcSup.push_back(h[i][j]);\n            } else if (h[i][j] < 0) {\n                snkPos.push_back({i, j});\n                snkDem.push_back(-h[i][j]);\n            }\n        }\n    }\n    int S = srcPos.size();\n    int T = snkPos.size();\n    if (S == 0 || T == 0) return 0;\n\n    int V = S + T + 2;\n    int SRC = V - 2, SNK = V - 1;\n    MinCostFlow mcf(V);\n\n    for (int i = 0; i < S; ++i) mcf.addEdge(SRC, i, srcSup[i], 0);\n    for (int j = 0; j < T; ++j) mcf.addEdge(S + j, SNK, snkDem[j], 0);\n\n    struct OrigEdge { int from, to, cap; };\n    vector<OrigEdge> origEdges;\n    \n    for (int i = 0; i < S; ++i) {\n        for (int j = 0; j < T; ++j) {\n            int d = manhattan(srcPos[i], snkPos[j]);\n            int cost = d * (100 + srcSup[i]);\n            int cap = min(srcSup[i], snkDem[j]);\n            if (cap > 0) {\n                mcf.addEdge(i, S + j, cap, cost);\n                origEdges.push_back({i, S + j, cap});\n            }\n        }\n    }\n\n    mcf.minCostMaxFlow(SRC, SNK);\n\n    struct Delivery { Pos sink; int amt; };\n    vector<vector<Delivery>> srcDeliveries(S);\n    \n    for (auto &oe : origEdges) {\n        for (auto &e : mcf.G[oe.from]) {\n            if (e.to == oe.to) {\n                int flow = oe.cap - e.cap;\n                if (flow > 0) {\n                    int sinkIdx = oe.to - S;\n                    srcDeliveries[oe.from].push_back({snkPos[sinkIdx], flow});\n                }\n                break;\n            }\n        }\n    }\n\n    struct SourceInfo {\n        Pos pos;\n        int totalSupply;\n        vector<Delivery> deliveries;\n        bool oneTrip;\n    };\n    vector<SourceInfo> sources;\n    for (int i = 0; i < S; ++i) {\n        if (srcDeliveries[i].empty()) continue;\n        SourceInfo si;\n        si.pos = srcPos[i];\n        si.totalSupply = srcSup[i];\n        si.deliveries = srcDeliveries[i];\n\n        long long costOneTrip = 0;\n        Pos cur = si.pos;\n        int load = si.totalSupply;\n        for (auto &d : si.deliveries) {\n            costOneTrip += 1LL * manhattan(cur, d.sink) * (100 + load);\n            load -= d.amt;\n            cur = d.sink;\n        }\n\n        long long costSeparate = 0;\n        for (auto &d : si.deliveries) {\n            costSeparate += 1LL * manhattan(si.pos, d.sink) * (100 + d.amt);\n            costSeparate += 1LL * manhattan(si.pos, d.sink) * 100;\n        }\n\n        si.oneTrip = (costOneTrip <= costSeparate);\n        sources.push_back(si);\n    }\n\n    Pos cur{0, 0};\n    vector<string> ops;\n    vector<bool> visited(sources.size(), false);\n    \n    while (true) {\n        int bestIdx = -1;\n        int bestDist = 1e9;\n        for (int i = 0; i < (int)sources.size(); ++i) {\n            if (!visited[i]) {\n                int d = manhattan(cur, sources[i].pos);\n                if (d < bestDist) {\n                    bestDist = d;\n                    bestIdx = i;\n                }\n            }\n        }\n        if (bestIdx == -1) break;\n        visited[bestIdx] = true;\n        auto &src = sources[bestIdx];\n\n        moveTo(cur, src.pos, ops);\n\n        if (src.oneTrip) {\n            ops.emplace_back(\"+\" + to_string(src.totalSupply));\n            int curLoad = src.totalSupply;\n            for (auto &d : src.deliveries) {\n                moveTo(cur, d.sink, ops);\n                ops.emplace_back(\"-\" + to_string(d.amt));\n                curLoad -= d.amt;\n            }\n        } else {\n            for (auto &d : src.deliveries) {\n                moveTo(cur, d.sink, ops);\n                ops.emplace_back(\"+\" + to_string(d.amt));\n                ops.emplace_back(\"-\" + to_string(d.amt));\n                moveTo(cur, src.pos, ops);\n            }\n        }\n    }\n\n    for (const string &s : ops) cout << s << '\\n';\n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, T;\n    if (!(cin >> N >> M >> T)) return 0;\n    const int S = 2 * N * (N - 1);           // 60\n    vector<vector<int>> seed(S, vector<int>(M));\n    for (int i = 0; i < S; ++i)\n        for (int j = 0; j < M; ++j)\n            cin >> seed[i][j];\n\n    /* ----- pre\u2011compute positions ordered by degree ----- */\n    vector<tuple<int,int,int>> posDeg;       // (degree, i, j)\n    posDeg.reserve(N * N);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int d = (i > 0) + (i < N - 1) + (j > 0) + (j < N - 1);\n            posDeg.emplace_back(d, i, j);\n        }\n    }\n    sort(posDeg.begin(), posDeg.end(),\n         [](const auto& a, const auto& b) {\n             if (get<0>(a) != get<0>(b)) return get<0>(a) > get<0>(b);\n             // tie\u2011break: arbitrary but deterministic\n             return (get<1>(a) + get<2>(a)) < (get<1>(b) + get<2>(b));\n         });\n\n    /* ------------------- main loop ---------------------- */\n    for (int turn = 0; turn < T; ++turn) {\n        /* ----- evaluate current seeds ----- */\n        vector<int> sum(S, 0);\n        vector<int> bestIdx(M, -1);\n        vector<int> bestVal(M, -1);\n        for (int i = 0; i < S; ++i) {\n            int s = 0;\n            for (int j = 0; j < M; ++j) {\n                int v = seed[i][j];\n                s += v;\n                if (v > bestVal[j]) {\n                    bestVal[j] = v;\n                    bestIdx[j] = i;\n                }\n            }\n            sum[i] = s;\n        }\n\n        /* ----- choose 36 parent seeds ----- */\n        vector<char> used(S, 0);\n        vector<int> parents;\n        parents.reserve(36);\n\n        // keep all specialists (different seeds)\n        for (int j = 0; j < M; ++j) {\n            int idx = bestIdx[j];\n            if (idx >= 0 && !used[idx]) {\n                used[idx] = 1;\n                parents.push_back(idx);\n            }\n        }\n\n        // fill the rest with highest\u2011value seeds\n        vector<int> other;\n        other.reserve(S);\n        for (int i = 0; i < S; ++i)\n            if (!used[i]) other.push_back(i);\n        sort(other.begin(), other.end(),\n             [&](int a, int b) { return sum[a] > sum[b]; });\n\n        int need = 36 - (int)parents.size();\n        for (int i = 0; i < need; ++i) parents.push_back(other[i]);\n\n        // exactly 36 parents \u2013 safety check\n        // (the problem guarantees this is always possible)\n        // sort parents by value (best first) for placement\n        sort(parents.begin(), parents.end(),\n             [&](int a, int b) { return sum[a] > sum[b]; });\n\n        /* ----- place them onto the grid ----- */\n        vector<vector<int>> A(N, vector<int>(N, -1));\n        for (int p = 0; p < 36; ++p) {\n            int di, dj;\n            tie(ignore, di, dj) = posDeg[p];\n            A[di][dj] = parents[p];\n        }\n\n        /* ----- output ----- */\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (j) cout << ' ';\n                cout << A[i][j];\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n\n        /* ----- read next generation ----- */\n        vector<vector<int>> nxt(S, vector<int>(M));\n        for (int i = 0; i < S; ++i)\n            for (int j = 0; j < M; ++j)\n                cin >> nxt[i][j];\n        seed.swap(nxt);\n    }\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, V;\n    if (!(cin >> N >> M >> V)) return 0;\n    vector<string> sgrid(N), tgrid(N);\n    for (int i = 0; i < N; ++i) cin >> sgrid[i];\n    for (int i = 0; i < N; ++i) cin >> tgrid[i];\n\n    /* ----- board representation ----- */\n    vector<vector<bool>> has(N, vector<bool>(N, false));\n    vector<pair<int,int>> src;          // squares with a takoyaki that are NOT targets\n    vector<pair<int,int>> emptyTgt;     // target squares that are NOT already occupied\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (sgrid[i][j] == '1') {\n                has[i][j] = true;\n                if (tgrid[i][j] == '0')\n                    src.emplace_back(i, j);\n            }\n            if (tgrid[i][j] == '1') {\n                if (!has[i][j])\n                    emptyTgt.emplace_back(i, j);\n            }\n        }\n    }\n\n    /* ----- tree description (only root + one leaf) ----- */\n    const int Vprime = 2;\n    cout << Vprime << \"\\n\";\n    cout << 0 << ' ' << 1 << \"\\n\";\n    cout << 0 << ' ' << 0 << \"\\n\";\n\n    /* ----- directions ----- */\n    const int dr[4] = {0, 1, 0, -1};\n    const int dc[4] = {1, 0, -1, 0};\n\n    auto move_char = [&](int d)->char {\n        if (d == 0) return 'R';\n        if (d == 1) return 'D';\n        if (d == 2) return 'L';\n        return 'U';\n    };\n    auto dir_from_delta = [&](int drr, int dcc)->int {\n        for (int d = 0; d < 4; ++d)\n            if (dr[d] == drr && dc[d] == dcc) return d;\n        return -1;          // never happens for a legal step\n    };\n\n    /* ----- simulation ----- */\n    vector<string> ops;\n    int root_x = 0, root_y = 0;   // current root position\n    int leaf_dir = 0;             // direction of the leaf (0 = right)\n    bool holding = false;         // does the leaf hold a takoyaki?\n\n    const int INF = 1e9;\n\n    while (!src.empty() || holding) {\n        if (!holding) {\n            // ---------- pick a takoyaki ----------\n            int bestDist = INF, bestIdx = -1;\n            pair<int,int> bestNeighbour{-1,-1};\n            int bestDir = -1;\n\n            for (int i = 0; i < (int)src.size(); ++i) {\n                int sx = src[i].first, sy = src[i].second;\n                for (int d = 0; d < 4; ++d) {\n                    int nx = sx - dr[d];\n                    int ny = sy - dc[d];\n                    if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n                    int dist = abs(root_x - nx) + abs(root_y - ny);\n                    if (dist < bestDist) {\n                        bestDist = dist;\n                        bestIdx = i;\n                        bestNeighbour = {nx, ny};\n                        bestDir = d;\n                    }\n                }\n            }\n\n            // move root to the neighbour\n            while (root_x != bestNeighbour.first || root_y != bestNeighbour.second) {\n                int ddx = 0, ddy = 0;\n                if (root_x < bestNeighbour.first) ddx = 1;\n                else if (root_x > bestNeighbour.first) ddx = -1;\n                if (root_y < bestNeighbour.second) ddy = 1;\n                else if (root_y > bestNeighbour.second) ddy = -1;\n\n                string op(4, '.');\n                if (abs(root_x - bestNeighbour.first) >= abs(root_y - bestNeighbour.second)) {\n                    op[0] = move_char(dir_from_delta(ddx, 0));\n                    root_x += ddx;\n                } else {\n                    op[0] = move_char(dir_from_delta(0, ddy));\n                    root_y += ddy;\n                }\n                ops.push_back(op);\n            }\n\n            // rotate leaf to point to source, then pick\n            int target_dir = bestDir;\n            int cur_dir = leaf_dir;\n            int diff = (target_dir - cur_dir + 4) % 4;\n            int alt = 4 - diff;\n            int steps, rot;\n            if (diff <= alt) { steps = diff; rot = 1; }\n            else             { steps = alt;  rot = -1; }\n\n            if (steps > 0) {\n                for (int i = 0; i < steps - 1; ++i) {\n                    string op(4, '.');\n                    op[1] = (rot == 1 ? 'R' : 'L');\n                    ops.push_back(op);\n                    leaf_dir = (leaf_dir + rot + 4) % 4;\n                }\n                string op(4, '.');\n                op[1] = (rot == 1 ? 'R' : 'L');\n                op[3] = 'P';\n                ops.push_back(op);\n                leaf_dir = (leaf_dir + rot + 4) % 4;\n            } else {\n                string op(4, '.');\n                op[3] = 'P';\n                ops.push_back(op);\n            }\n\n            // update board and source list\n            has[src[bestIdx].first][src[bestIdx].second] = false;\n            src.erase(src.begin() + bestIdx);\n            holding = true;\n        }\n        else {\n            // ---------- place a takoyaki ----------\n            int bestDist = INF, bestIdx = -1;\n            pair<int,int> bestNeighbour{-1,-1};\n            int bestDir = -1;\n\n            for (int i = 0; i < (int)emptyTgt.size(); ++i) {\n                int tx = emptyTgt[i].first, ty = emptyTgt[i].second;\n                for (int d = 0; d < 4; ++d) {\n                    int nx = tx - dr[d];\n                    int ny = ty - dc[d];\n                    if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n                    int dist = abs(root_x - nx) + abs(root_y - ny);\n                    if (dist < bestDist) {\n                        bestDist = dist;\n                        bestIdx = i;\n                        bestNeighbour = {nx, ny};\n                        bestDir = d;\n                    }\n                }\n            }\n\n            // move root to the neighbour\n            while (root_x != bestNeighbour.first || root_y != bestNeighbour.second) {\n                int ddx = 0, ddy = 0;\n                if (root_x < bestNeighbour.first) ddx = 1;\n                else if (root_x > bestNeighbour.first) ddx = -1;\n                if (root_y < bestNeighbour.second) ddy = 1;\n                else if (root_y > bestNeighbour.second) ddy = -1;\n\n                string op(4, '.');\n                if (abs(root_x - bestNeighbour.first) >= abs(root_y - bestNeighbour.second)) {\n                    op[0] = move_char(dir_from_delta(ddx, 0));\n                    root_x += ddx;\n                } else {\n                    op[0] = move_char(dir_from_delta(0, ddy));\n                    root_y += ddy;\n                }\n                ops.push_back(op);\n            }\n\n            // rotate leaf to point to target, then place\n            int target_dir = bestDir;\n            int cur_dir = leaf_dir;\n            int diff = (target_dir - cur_dir + 4) % 4;\n            int alt = 4 - diff;\n            int steps, rot;\n            if (diff <= alt) { steps = diff; rot = 1; }\n            else             { steps = alt;  rot = -1; }\n\n            if (steps > 0) {\n                for (int i = 0; i < steps - 1; ++i) {\n                    string op(4, '.');\n                    op[1] = (rot == 1 ? 'R' : 'L');\n                    ops.push_back(op);\n                    leaf_dir = (leaf_dir + rot + 4) % 4;\n                }\n                string op(4, '.');\n                op[1] = (rot == 1 ? 'R' : 'L');\n                op[3] = 'P';\n                ops.push_back(op);\n                leaf_dir = (leaf_dir + rot + 4) % 4;\n            } else {\n                string op(4, '.');\n                op[3] = 'P';\n                ops.push_back(op);\n            }\n\n            // update board and target list\n            has[emptyTgt[bestIdx].first][emptyTgt[bestIdx].second] = true;\n            emptyTgt.erase(emptyTgt.begin() + bestIdx);\n            holding = false;\n        }\n    }\n\n    /* ----- output the operation sequence ----- */\n    for (const string &s : ops) cout << s << '\\n';\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    if (!(cin >> N)) return 0;\n\n    const int M = 2 * N;\n    vector<pair<int,int>> pts(M);\n    for (int i = 0; i < M; ++i) cin >> pts[i].first >> pts[i].second;\n\n    /* values: first N are mackerels (+1), next N are sardines (-1) */\n    vector<int> val(M);\n    for (int i = 0; i < N; ++i) val[i] = 1;\n    for (int i = N; i < M; ++i) val[i] = -1;\n\n    /* coordinate compression */\n    vector<int> xs, ys;\n    xs.reserve(M); ys.reserve(M);\n    for (auto &p : pts) {\n        xs.push_back(p.first);\n        ys.push_back(p.second);\n    }\n    sort(xs.begin(), xs.end());\n    xs.erase(unique(xs.begin(), xs.end()), xs.end());\n    sort(ys.begin(), ys.end());\n    ys.erase(unique(ys.begin(), ys.end()), ys.end());\n\n    const int X = (int)xs.size();\n    const int Y = (int)ys.size();\n\n    /* 2\u2011D prefix sums */\n    vector<int> pref( (size_t)(X + 1) * (Y + 1), 0 );\n    for (int i = 0; i < M; ++i) {\n        int ix = lower_bound(xs.begin(), xs.end(), pts[i].first) - xs.begin();\n        int iy = lower_bound(ys.begin(), ys.end(), pts[i].second) - ys.begin();\n        pref[ (size_t)(ix + 1) * (Y + 1) + (iy + 1) ] += val[i];\n    }\n    for (int i = 1; i <= X; ++i) {\n        for (int j = 1; j <= Y; ++j) {\n            size_t idx = (size_t)i * (Y + 1) + j;\n            size_t a = (size_t)(i - 1) * (Y + 1) + j;\n            size_t b = (size_t)i * (Y + 1) + (j - 1);\n            size_t c = (size_t)(i - 1) * (Y + 1) + (j - 1);\n            pref[idx] = pref[idx] + pref[a] + pref[b] - pref[c];\n        }\n    }\n\n    /* helper: sum of a rectangle given by exclusive indices */\n    auto rectSum = [&](int l, int r, int b, int t) -> int {\n        // l,r are exclusive on the right, b,t exclusive on the top\n        if (l >= r || b >= t) return 0;\n        size_t idx_rr = (size_t)r * (Y + 1) + t;\n        size_t idx_lr = (size_t)l * (Y + 1) + t;\n        size_t idx_rb = (size_t)r * (Y + 1) + b;\n        size_t idx_lb = (size_t)l * (Y + 1) + b;\n        return (int)(pref[idx_rr] - pref[idx_lr] - pref[idx_rb] + pref[idx_lb]);\n    };\n\n    /* random generator */\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    const int RESTARTS = 80;\n    const int MAX_ITER  = 80;\n\n    int bestValue = -1000000;\n    int bestL = 0, bestR = 1, bestB = 0, bestT = 1;   // fallback\n\n    vector<int> colSum(X), rowSum(Y);\n    vector<int> prefCol(X + 1), prefRow(Y + 1);\n\n    for (int restart = 0; restart < RESTARTS; ++restart) {\n        int leftIdx, rightIdx, bottomIdx, topIdx;\n\n        if (restart == 0) {                     // whole rectangle\n            leftIdx   = 0;\n            rightIdx  = X;\n            bottomIdx = 0;\n            topIdx    = Y;\n        } else {\n            leftIdx   = uniform_int_distribution<int>(0, X - 1)(rng);\n            rightIdx  = uniform_int_distribution<int>(leftIdx + 1, X)(rng);\n            bottomIdx = uniform_int_distribution<int>(0, Y - 1)(rng);\n            topIdx    = uniform_int_distribution<int>(bottomIdx + 1, Y)(rng);\n        }\n\n        int curValue = rectSum(leftIdx, rightIdx, bottomIdx, topIdx);\n        int bestValueRestart = curValue;\n        int bestLr = xs[leftIdx], bestRr = (rightIdx > 0 ? xs[rightIdx - 1] : xs[0]);\n        int bestBr = ys[bottomIdx], bestTr = (topIdx > 0 ? ys[topIdx - 1] : ys[0]);\n\n        for (int it = 0; it < MAX_ITER; ++it) {\n            /* ----- compute column sums and row sums for current y\u2011interval ----- */\n            int b = bottomIdx, t = topIdx;\n            for (int i = 0; i < X; ++i) {\n                // sum of column i between rows b \u2026 t\u20111\n                colSum[i] = pref[(size_t)(i + 1) * (Y + 1) + t]\n                          - pref[(size_t)(i + 1) * (Y + 1) + b]\n                          - pref[(size_t)i * (Y + 1) + t]\n                          + pref[(size_t)i * (Y + 1) + b];\n            }\n            int l = leftIdx, r = rightIdx;\n            for (int j = 0; j < Y; ++j) {\n                // sum of row j between columns l \u2026 r\u20111\n                rowSum[j] = pref[(size_t)r * (Y + 1) + (j + 1)]\n                          - pref[(size_t)l * (Y + 1) + (j + 1)]\n                          - pref[(size_t)r * (Y + 1) + j]\n                          + pref[(size_t)l * (Y + 1) + j];\n            }\n\n            /* ----- one\u2011dimensional prefix sums ----- */\n            prefCol[0] = 0;\n            for (int i = 0; i < X; ++i) prefCol[i + 1] = prefCol[i] + colSum[i];\n            prefRow[0] = 0;\n            for (int j = 0; j < Y; ++j) prefRow[j + 1] = prefRow[j] + rowSum[j];\n\n            /* ----- choose the best side move ----- */\n            int bestGain = 0;\n            int bestSide = -1;   // 0:left, 1:right, 2:bottom, 3:top\n            int bestNewIdx = -1;\n\n            // left side\n            for (int nl = 0; nl < rightIdx; ++nl) {\n                if (nl == leftIdx) continue;\n                int gain = prefCol[leftIdx] - prefCol[nl];\n                if (gain > bestGain) {\n                    bestGain = gain; bestSide = 0; bestNewIdx = nl;\n                }\n            }\n            // right side\n            for (int nr = leftIdx + 1; nr <= X; ++nr) {\n                if (nr == rightIdx) continue;\n                int gain = prefCol[nr] - prefCol[rightIdx];\n                if (gain > bestGain) {\n                    bestGain = gain; bestSide = 1; bestNewIdx = nr;\n                }\n            }\n            // bottom side\n            for (int nb = 0; nb < topIdx; ++nb) {\n                if (nb == bottomIdx) continue;\n                int gain = prefRow[bottomIdx] - prefRow[nb];\n                if (gain > bestGain) {\n                    bestGain = gain; bestSide = 2; bestNewIdx = nb;\n                }\n            }\n            // top side\n            for (int nt = bottomIdx + 1; nt <= Y; ++nt) {\n                if (nt == topIdx) continue;\n                int gain = prefRow[nt] - prefRow[topIdx];\n                if (gain > bestGain) {\n                    bestGain = gain; bestSide = 3; bestNewIdx = nt;\n                }\n            }\n\n            if (bestGain <= 0) break;          // local optimum\n\n            // apply the move\n            switch (bestSide) {\n                case 0: leftIdx   = bestNewIdx; break;\n                case 1: rightIdx  = bestNewIdx; break;\n                case 2: bottomIdx = bestNewIdx; break;\n                case 3: topIdx    = bestNewIdx; break;\n            }\n            curValue += bestGain;\n\n            if (curValue > bestValueRestart) {\n                bestValueRestart = curValue;\n                bestLr = xs[leftIdx];\n                bestRr = (rightIdx > 0 ? xs[rightIdx - 1] : xs[0]);\n                bestBr = ys[bottomIdx];\n                bestTr = (topIdx > 0 ? ys[topIdx - 1] : ys[0]);\n            }\n        }\n\n        if (bestValueRestart > bestValue) {\n            bestValue = bestValueRestart;\n            bestL = bestLr; bestR = bestRr;\n            bestB = bestBr; bestT = bestTr;\n        }\n    }\n\n    /* ----- output the rectangle as a polygon ----- */\n    cout << 4 << '\\n';\n    cout << bestL << ' ' << bestB << '\\n';\n    cout << bestR << ' ' << bestB << '\\n';\n    cout << bestR << ' ' << bestT << '\\n';\n    cout << bestL << ' ' << bestT << '\\n';\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\n\nstruct Candidate {\n    bool skip;          // true \u2192 skip this rectangle\n    int rot;            // 0 = not rotated, 1 = rotated\n    char dir;           // 'U' or 'L'\n    int ref;            // -1 or index of a previously placed rectangle\n    ll sum;             // heuristic score (width+height+penalty)\n    ll x, y, w, h;      // coordinates and size (valid only if !skip)\n};\n\nstruct PlacedRect {\n    ll x, y, w, h;\n    int idx;            // original index\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, T;\n    long long sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n    vector<ll> mw(N), mh(N);                 // measured sizes\n    for (int i = 0; i < N; ++i) cin >> mw[i] >> mh[i];\n\n    // random generator \u2013 deterministic but different each turn\n    std::mt19937 rng(123456789);\n\n    // -------------------------------------------------------------\n    // process each turn\n    for (int turn = 0; turn < T; ++turn) {\n        // current state\n        vector<int> placedIdx;                     // indices of placed rectangles\n        vector<ll> X(N, 0), Y(N, 0), W(N, 0), H(N, 0);\n        vector<char> used(N, 0);\n        ll curW = 0, curH = 0;                      // current bounding box\n        ll penalty = 0;                             // sum of skipped measured sizes\n\n        vector<tuple<int,int,char,int>> answer;     // (p, r, d, b)\n\n        // ---------------------------------------------------------\n        // greedy construction rectangle after rectangle\n        for (int i = 0; i < N; ++i) {\n            vector<Candidate> cand;\n\n            // ----  skip candidate  --------------------------------\n            ll pen_i = mw[i] + mh[i];\n            cand.push_back({true, 0, '?', -1,\n                            curW + curH + penalty + pen_i,\n                            0,0,0,0});\n\n            // ----  placement candidates  ---------------------------\n            // collect possible references (already placed rectangles)\n            vector<int> refs;\n            refs.push_back(-1);\n            if (!placedIdx.empty()) {\n                refs.push_back(placedIdx.back());          // the last one\n                // a few random ones\n                for (int qq = 0; qq < 3; ++qq) {\n                    int r = placedIdx[uniform_int_distribution<int>(0, (int)placedIdx.size()-1)(rng)];\n                    if (find(refs.begin(), refs.end(), r) == refs.end())\n                        refs.push_back(r);\n                }\n            }\n\n            // try both rotations\n            for (int rot = 0; rot <= 1; ++rot) {\n                ll wi = rot ? mh[i] : mw[i];\n                ll hi = rot ? mw[i] : mh[i];\n\n                // both directions\n                for (char dir : {'U', 'L'}) {\n                    for (int ref : refs) {\n                        ll nx, ny;\n                        if (dir == 'U') {\n                            ll left = (ref == -1) ? 0 : X[ref] + W[ref];\n                            ll highest = 0;\n                            for (int k : placedIdx) {\n                                // overlap in x ?\n                                if (X[k] < left + wi && X[k] + W[k] > left) {\n                                    highest = max(highest, Y[k] + H[k]);\n                                }\n                            }\n                            nx = left;\n                            ny = highest;               // may be 0\n                        } else { // 'L'\n                            ll top = (ref == -1) ? 0 : Y[ref] + H[ref];\n                            ll rightmost = 0;\n                            for (int k : placedIdx) {\n                                // overlap in y ?\n                                if (Y[k] < top + hi && Y[k] + H[k] > top) {\n                                    rightmost = max(rightmost, X[k] + W[k]);\n                                }\n                            }\n                            ll tmp = rightmost - wi;\n                            nx = tmp < 0 ? 0 : tmp;\n                            ny = top;\n                        }\n                        ll nw = max(curW, nx + wi);\n                        ll nh = max(curH, ny + hi);\n                        ll sc = nw + nh + penalty;      // score after placing\n                        cand.push_back({false, rot, dir, ref, sc, nx, ny, wi, hi});\n                    }\n                }\n            }\n\n            // ----  choose best (or one of the best three)  -------\n            sort(cand.begin(), cand.end(),\n                 [](const Candidate& a, const Candidate& b){ return a.sum < b.sum; });\n            int topK = min(3, (int)cand.size());\n            int chosen = uniform_int_distribution<int>(0, topK-1)(rng);\n            const Candidate& c = cand[chosen];\n\n            if (c.skip) {\n                // skip this rectangle\n                penalty += pen_i;\n                // nothing is added to the answer\n            } else {\n                // place it\n                answer.emplace_back(i, c.dir == 'U' ? (c.rot ? 1 : 0) : (c.rot ? 1 : 0),\n                                   c.dir, c.ref);\n                // store data for later references\n                X[i] = c.x; Y[i] = c.y; W[i] = c.w; H[i] = c.h;\n                used[i] = 1;\n                placedIdx.push_back(i);\n                curW = max(curW, c.x + c.w);\n                curH = max(curH, c.y + c.h);\n            }\n        } // end for each rectangle\n\n        // -------------------------------------------------------------\n        // output the description\n        cout << answer.size() << '\\n';\n        for (auto [p, r, d, b] : answer) {\n            cout << p << ' ' << r << ' ' << d << ' ' << b << '\\n';\n        }\n        cout << flush;\n\n        // read the noisy measurement (not used)\n        long long Wobs, Hobs;\n        cin >> Wobs >> Hobs;\n    }\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\n#include <random>\n#include <chrono>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, H;\n    if (!(cin >> N >> M >> H)) return 0;\n    vector<int> A(N);\n    for (int i = 0; i < N; ++i) cin >> A[i];\n    vector<pair<int,int>> edges(M);\n    for (int i = 0; i < M; ++i) {\n        int u, v; cin >> u >> v;\n        edges[i] = {u, v};\n    }\n    // coordinates - not needed\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n    }\n\n    // Build adjacency\n    vector<vector<int>> adj(N);\n    for (auto [u,v] : edges) {\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n\n    auto compute_score = [&](const vector<int>& parent) -> long long {\n        long long score = 0;\n        vector<int> depth(N, -1);\n        queue<int> q;\n        // Find roots and start BFS\n        for (int v = 0; v < N; ++v) {\n            if (parent[v] == -1) {\n                depth[v] = 0;\n                q.push(v);\n            }\n        }\n        // BFS to compute depths\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            for (int u : adj[v]) {\n                if (parent[u] == v && depth[u] == -1) {\n                    depth[u] = depth[v] + 1;\n                    q.push(u);\n                }\n            }\n        }\n        // Compute score\n        for (int v = 0; v < N; ++v) {\n            if (depth[v] == -1) continue;\n            score += (long long)(depth[v] + 1) * A[v];\n        }\n        return score;\n    };\n\n    auto build_solution = [&](const vector<int>& order) -> pair<vector<int>, long long> {\n        vector<int> parent(N, -2);\n        vector<int> depth(N, -1);\n        \n        for (int v : order) {\n            int best_depth = -1;\n            int best_parent = -1;\n            \n            // Try deepest possible level first\n            for (int d = H; d >= 0; --d) {\n                if (d == 0) {\n                    best_depth = 0;\n                    best_parent = -1;\n                    break;\n                }\n                \n                // Check if any neighbor is at depth d-1\n                for (int u : adj[v]) {\n                    if (depth[u] == d - 1) {\n                        best_depth = d;\n                        best_parent = u;\n                        break;\n                    }\n                }\n                if (best_depth != -1) break;\n            }\n            \n            depth[v] = best_depth;\n            parent[v] = best_parent;\n        }\n        \n        return {parent, compute_score(parent)};\n    };\n\n    // Try multiple orderings and keep the best\n    vector<int> best_parent(N, -1);\n    long long best_score = -1;\n    \n    // First: sort by beauty descending (high beauty gets priority for deep positions)\n    vector<int> order_by_beauty(N);\n    iota(order_by_beauty.begin(), order_by_beauty.end(), 0);\n    sort(order_by_beauty.begin(), order_by_beauty.end(), [&](int a, int b) {\n        return A[a] > A[b];\n    });\n    \n    auto [parent1, score1] = build_solution(order_by_beauty);\n    best_parent = parent1;\n    best_score = score1;\n    \n    // Try random shuffles of the beauty-sorted order\n    unsigned seed = chrono::steady_clock::now().time_since_epoch().count();\n    default_random_engine gen(seed);\n    \n    const int NUM_ITERATIONS = 500;\n    for (int iter = 0; iter < NUM_ITERATIONS; ++iter) {\n        vector<int> order = order_by_beauty;\n        // Partial shuffle - swap a few elements to create variety\n        for (int i = 0; i < 50; ++i) {\n            int a = uniform_int_distribution<int>(0, N-1)(gen);\n            int b = uniform_int_distribution<int>(0, N-1)(gen);\n            swap(order[a], order[b]);\n        }\n        auto [parent, score] = build_solution(order);\n        if (score > best_score) {\n            best_score = score;\n            best_parent = parent;\n        }\n    }\n    \n    // Output\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << best_parent[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Set {\n    bool isRow;          // true \u2192 row, false \u2192 column\n    int idx;             // row number or column number\n    char dir;            // 'L','R','U','D'\n    uint64_t mask;       // bitmask of Oni indices contained in the set\n    int cost;            // number of shifts\n};\n\nint N;                                     // board size (20)\nvector<string> board;                      // input board\nint oniIdx[20][20];                        // index of Oni, -1 if none\nbool fuku[20][20];                         // true if Fukunokami\n\nint leftMostF[20], rightMostF[20];\nint topMostF[20], bottomMostF[20];\n\nvector<Set> sets;\nvector<vector<int>> oniToSets;             // for each Oni, list of set ids\n\nint M;                                     // number of Oni\nuint64_t allMask;\n\nint bestCost;\nvector<int> bestSets;\nvector<int> curSets;\nbool rowUsed[20] = {false};\nbool colUsed[20] = {false};\n\nvoid dfs(uint64_t mask, int cost) {\n    if (mask == allMask) {\n        if (cost < bestCost) {\n            bestCost = cost;\n            bestSets = curSets;\n        }\n        return;\n    }\n    if (cost >= bestCost) return;\n    int remain = __builtin_popcountll(~mask & allMask);\n    if (cost + remain >= bestCost) return; // even with 1 per oni we cannot beat\n\n    // choose uncovered Oni with smallest number of candidate sets\n    uint64_t rem = ~mask & allMask;\n    int chosenOni = -1;\n    int minOpts = 100;\n    for (uint64_t sub = rem; sub; sub &= sub - 1) {\n        int idx = __builtin_ctzll(sub);\n        int opts = 0;\n        for (int sid : oniToSets[idx]) {\n            const Set &s = sets[sid];\n            if (s.isRow && rowUsed[s.idx]) continue;\n            if (!s.isRow && colUsed[s.idx]) continue;\n            if (mask & s.mask) continue;          // already covered by chosen sets\n            ++opts;\n        }\n        if (opts == 0) return;                     // dead end (should not happen)\n        if (opts < minOpts) {\n            minOpts = opts;\n            chosenOni = idx;\n            if (minOpts == 1) break;\n        }\n    }\n    if (chosenOni == -1) return;                  // cannot cover\n\n    for (int sid : oniToSets[chosenOni]) {\n        const Set &s = sets[sid];\n        if (s.isRow && rowUsed[s.idx]) continue;\n        if (!s.isRow && colUsed[s.idx]) continue;\n        if (mask & s.mask) continue;              // overlap \u2013 already covered\n        // choose this set\n        if (s.isRow) rowUsed[s.idx] = true;\n        else         colUsed[s.idx] = true;\n        curSets.push_back(sid);\n        dfs(mask | s.mask, cost + s.cost);\n        curSets.pop_back();\n        if (s.isRow) rowUsed[s.idx] = false;\n        else         colUsed[s.idx] = false;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N;\n    board.resize(N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n\n    // locate Oni and Fukunokami, initialise arrays\n    memset(oniIdx, -1, sizeof(oniIdx));\n    memset(fuku, 0, sizeof(fuku));\n    vector<pair<int,int>> oniPos;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 'x')\n                oniIdx[i][j] = (int)oniPos.size(),\n                oniPos.emplace_back(i, j);\n            else if (board[i][j] == 'o')\n                fuku[i][j] = true;\n        }\n    M = (int)oniPos.size();                // = 2\u00b7N\n    allMask = (M == 64) ? ~0ULL : ((1ULL<<M) - 1ULL);\n\n    // left / right most Fukunokami in each row\n    const int INF = N+5;\n    for (int i = 0; i < N; ++i) {\n        leftMostF[i] = INF; rightMostF[i] = -1;\n        for (int j = 0; j < N; ++j)\n            if (fuku[i][j]) {\n                leftMostF[i] = min(leftMostF[i], j);\n                rightMostF[i] = max(rightMostF[i], j);\n            }\n    }\n    // top / bottom most Fukunokami in each column\n    for (int j = 0; j < N; ++j) {\n        topMostF[j] = INF; bottomMostF[j] = -1;\n        for (int i = 0; i < N; ++i)\n            if (fuku[i][j]) {\n                topMostF[j] = min(topMostF[j], i);\n                bottomMostF[j] = max(bottomMostF[j], i);\n            }\n    }\n\n    // build the sets\n    for (int i = 0; i < N; ++i) {\n        vector<int> idsL, idsR;\n        int maxJ = -1, minJ = INF;\n        for (int j = 0; j < N; ++j) {\n            int id = oniIdx[i][j];\n            if (id == -1) continue;\n            bool leftClear = (leftMostF[i] == INF) || (leftMostF[i] > j);\n            bool rightClear = (rightMostF[i] == -1) || (rightMostF[i] < j);\n            if (leftClear) {\n                idsL.push_back(id);\n                maxJ = max(maxJ, j);\n            }\n            if (rightClear) {\n                idsR.push_back(id);\n                minJ = min(minJ, j);\n            }\n        }\n        if (!idsL.empty()) {\n            Set s; s.isRow = true; s.idx = i; s.dir = 'L';\n            s.cost = maxJ + 1;\n            s.mask = 0;\n            for (int id : idsL) s.mask |= (1ULL<<id);\n            sets.push_back(s);\n        }\n        if (!idsR.empty()) {\n            Set s; s.isRow = true; s.idx = i; s.dir = 'R';\n            s.cost = N - minJ;\n            s.mask = 0;\n            for (int id : idsR) s.mask |= (1ULL<<id);\n            sets.push_back(s);\n        }\n    }\n    for (int j = 0; j < N; ++j) {\n        vector<int> idsU, idsD;\n        int maxI = -1, minI = INF;\n        for (int i = 0; i < N; ++i) {\n            int id = oniIdx[i][j];\n            if (id == -1) continue;\n            bool upClear   = (topMostF[j] == INF) || (topMostF[j] > i);\n            bool downClear = (bottomMostF[j] == -1) || (bottomMostF[j] < i);\n            if (upClear) {\n                idsU.push_back(id);\n                maxI = max(maxI, i);\n            }\n            if (downClear) {\n                idsD.push_back(id);\n                minI = min(minI, i);\n            }\n        }\n        if (!idsU.empty()) {\n            Set s; s.isRow = false; s.idx = j; s.dir = 'U';\n            s.cost = maxI + 1;\n            s.mask = 0;\n            for (int id : idsU) s.mask |= (1ULL<<id);\n            sets.push_back(s);\n        }\n        if (!idsD.empty()) {\n            Set s; s.isRow = false; s.idx = j; s.dir = 'D';\n            s.cost = N - minI;\n            s.mask = 0;\n            for (int id : idsD) s.mask |= (1ULL<<id);\n            sets.push_back(s);\n        }\n    }\n\n    // mapping Oni -> sets\n    oniToSets.assign(M, {});\n    for (int sid = 0; sid < (int)sets.size(); ++sid) {\n        uint64_t m = sets[sid].mask;\n        while (m) {\n            int b = __builtin_ctzll(m);\n            oniToSets[b].push_back(sid);\n            m &= m-1;\n        }\n    }\n    // sort by cost (ascending) \u2013 helps the search\n    for (auto &vec : oniToSets) {\n        sort(vec.begin(), vec.end(),\n             [&](int a, int b){ return sets[a].cost < sets[b].cost; });\n    }\n\n    // upper bound = sum of individual minima (one\u2011by\u2011one removal)\n    int upper = 0;\n    for (int id = 0; id < M; ++id) {\n        int i = oniPos[id].first;\n        int j = oniPos[id].second;\n        int best = N+5;\n        bool leftClear = (leftMostF[i] == INF) || (leftMostF[i] > j);\n        bool rightClear= (rightMostF[i]==-1) || (rightMostF[i] < j);\n        bool upClear   = (topMostF[j] == INF) || (topMostF[j] > i);\n        bool downClear = (bottomMostF[j]==-1)|| (bottomMostF[j] < i);\n        if (leftClear)  best = min(best, j+1);\n        if (rightClear) best = min(best, N-j);\n        if (upClear)    best = min(best, i+1);\n        if (downClear)  best = min(best, N-i);\n        upper += best;\n    }\n    bestCost = upper;\n    // start search\n    dfs(0ULL, 0);\n\n    // produce output \u2013 column sets first, then row sets\n    vector<int> colSetIds, rowSetIds;\n    for (int sid : bestSets) {\n        if (!sets[sid].isRow) colSetIds.push_back(sid);\n        else                  rowSetIds.push_back(sid);\n    }\n\n    // output moves\n    ostringstream out;\n    for (int sid : colSetIds) {\n        const Set &s = sets[sid];\n        for (int k = 0; k < s.cost; ++k)\n            out << s.dir << ' ' << s.idx << '\\n';\n    }\n    for (int sid : rowSetIds) {\n        const Set &s = sets[sid];\n        for (int k = 0; k < s.cost; ++k)\n            out << s.dir << ' ' << s.idx << '\\n';\n    }\n    cout << out.str();\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    long long L;\n    if (!(cin >> N >> L)) return 0;\n    vector<int> T(N);\n    for (int i = 0; i < N; ++i) cin >> T[i];\n\n    // -------- adjust T[0] = 0  (error 2 is optimal) ----------\n    vector<int> t = T;\n    if (t[0] == 0) {\n        int j = -1;\n        for (int i = 1; i < N; ++i) if (t[i] > 0) { j = i; break; }\n        // there must be such j because sum = L > 0\n        t[0] = 1;\n        t[j]--;\n    }\n\n    // ----- pre\u2011compute how many odd / even edges each vertex has -----\n    vector<int> oddWeight(N), evenWeight(N);\n    for (int i = 0; i < N; ++i) {\n        oddWeight[i]  = (t[i] + 1) / 2;          // ceil\n        evenWeight[i] = t[i] / 2;                // floor\n    }\n\n    // ----- data for the walk construction -----\n    vector<int> need = t;                       // remaining indegrees\n    vector<int> vis(N, 0);                       // how many times a vertex has been visited\n    vector<int> a(N, -1), b(N, -1);              // targets, -1 = not fixed yet\n    vector<int> usedOdd(N, 0), usedEven(N, 0);   // how many edges of each kind have already been used\n\n    int cur = 0;\n    vis[0] = 1;\n    need[0]--;                                   // first week\n\n    for (long long week = 2; week <= L; ++week) {\n        // decide which kind of edge is needed now\n        bool odd = (vis[cur] % 2 == 1);          // after vis[cur] visits, parity is odd \u2192 need odd edge\n        if (odd) {\n            if (a[cur] == -1) {\n                // choose a target with enough remaining capacity\n                int target = -1;\n                for (int i = 0; i < N; ++i) {\n                    if (need[i] >= oddWeight[cur]) {\n                        target = i;\n                        break;\n                    }\n                }\n                // target must exist\n                a[cur] = target;\n            }\n            cur = a[cur];\n        } else {\n            if (b[cur] == -1) {\n                int target = -1;\n                for (int i = 0; i < N; ++i) {\n                    if (need[i] >= evenWeight[cur]) {\n                        target = i;\n                        break;\n                    }\n                }\n                b[cur] = target;\n            }\n            cur = b[cur];\n        }\n        ++vis[cur];\n        --need[cur];\n    }\n\n    // set default values for edges that never had to be fixed\n    for (int i = 0; i < N; ++i) {\n        if (a[i] == -1) a[i] = i;   // never used odd edge \u2192 self loop\n        if (b[i] == -1) b[i] = i;   // never used even edge \u2192 self loop\n    }\n\n    // --------------- output --------------------\n    for (int i = 0; i < N; ++i) {\n        cout << a[i] << ' ' << b[i] << \"\\n\";\n    }\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v;\n    int approx;          // distance between rectangle centres\n};\n\nint N, M, Q, L, W;\nvector<int> G;\nvector<int> lx, rx, ly, ry;\nvector<int> cx, cy;                     // centre of rectangle\nvector<vector<int>> approxDist;         // heuristic distance matrix\n\n// candidate edges for every group\nvector<vector<Edge>> candEdges;\n\n// ---------------------------------------------------------------\n// ask a query, read the answer and store the edges\nvoid query(const vector<int>& nodes, int gid) {\n    int sz = (int)nodes.size();\n    cout << \"? \" << sz;\n    for (int v : nodes) cout << ' ' << v;\n    cout << \"\\n\";\n    cout.flush();                       // required\n\n    for (int i = 0; i < sz - 1; ++i) {\n        int a, b;\n        cin >> a >> b;\n        Edge e{a, b, approxDist[a][b]};\n        candEdges[gid].push_back(e);\n    }\n}\n\n// ---------------------------------------------------------------\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------- input ---------- */\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    lx.resize(N); rx.resize(N); ly.resize(N); ry.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n    }\n\n    /* ---------- centre of rectangles ---------- */\n    cx.resize(N); cy.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cx[i] = (lx[i] + rx[i]) / 2;\n        cy[i] = (ly[i] + ry[i]) / 2;\n    }\n\n    /* ---------- heuristic distance matrix ---------- */\n    approxDist.assign(N, vector<int>(N, 0));\n    for (int i = 0; i < N; ++i) {\n        for (int j = i + 1; j < N; ++j) {\n            long long dx = (long long)cx[i] - cx[j];\n            long long dy = (long long)cy[i] - cy[j];\n            int d = (int)floor(sqrt((double)dx * dx + (double)dy * dy) + 1e-9);\n            approxDist[i][j] = approxDist[j][i] = d;\n        }\n    }\n\n    /* ---------- build groups (sorted by centre) ---------- */\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(),\n         [&](int a, int b) {\n             if (cx[a] != cx[b]) return cx[a] < cx[b];\n             return cy[a] < cy[b];\n         });\n\n    vector<vector<int>> groups(M);\n    int pos = 0;\n    for (int g = 0; g < M; ++g) {\n        groups[g].reserve(G[g]);\n        for (int i = 0; i < G[g]; ++i) groups[g].push_back(order[pos++]);\n    }\n\n    candEdges.assign(M, {});\n    int used = 0;          // queries already performed\n\n    /* ---------- baseline queries ---------- */\n    for (int gid = 0; gid < M; ++gid) {\n        int sz = (int)groups[gid].size();\n        if (sz <= 1) continue;\n        if (sz == 2) continue;                     // no query needed\n        if (sz <= L) {                               // whole group\n            query(groups[gid], gid);\n            ++used;\n        } else {                                     // sliding window\n            int i = 0;\n            while (i + L <= sz) {\n                vector<int> sub(L);\n                for (int j = 0; j < L; ++j) sub[j] = groups[gid][i + j];\n                query(sub, gid);\n                ++used;\n                i += L - 1;\n            }\n            if (i < sz - 1) {\n                int rem = sz - i;\n                vector<int> sub(rem);\n                for (int j = 0; j < rem; ++j) sub[j] = groups[gid][i + j];\n                query(sub, gid);\n                ++used;\n            }\n        }\n    }\n\n    /* ---------- extra queries (if budget left) ---------- */\n    int leftover = Q - used;\n    // groups that are still interesting (size >= 3)\n    vector<int> bigGroups;\n    for (int gid = 0; gid < M; ++gid)\n        if ((int)groups[gid].size() >= 3) bigGroups.push_back(gid);\n    // order them by decreasing size \u2013 larger groups get extra queries first\n    sort(bigGroups.begin(), bigGroups.end(),\n         [&](int a, int b) { return groups[a].size() > groups[b].size(); });\n\n    std::mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n\n    int idx = 0;\n    while (leftover > 0 && !bigGroups.empty()) {\n        int gid = bigGroups[idx % bigGroups.size()];\n        int gsz = (int)groups[gid].size();\n        int qsz = min(L, gsz);\n\n        // random subset of size qsz\n        vector<int> idxs(gsz);\n        iota(idxs.begin(), idxs.end(), 0);\n        shuffle(idxs.begin(), idxs.end(), rng);\n        vector<int> sub(qsz);\n        for (int t = 0; t < qsz; ++t) sub[t] = groups[gid][idxs[t]];\n\n        query(sub, gid);\n        ++used;\n        --leftover;\n        ++idx;\n    }\n\n    /* ---------- build final spanning trees (Kruskal) ---------- */\n    vector<vector<pair<int,int>>> answerEdges(M);\n\n    for (int gid = 0; gid < M; ++gid) {\n        int sz = (int)groups[gid].size();\n        if (sz <= 1) continue;\n        if (sz == 2) {\n            answerEdges[gid].push_back({groups[gid][0], groups[gid][1]});\n            continue;\n        }\n\n        auto &edges = candEdges[gid];\n        sort(edges.begin(), edges.end(),\n             [&](const Edge& a, const Edge& b){ return a.approx < b.approx; });\n\n        // mapping city -> local index inside the group\n        vector<int> localId(N, -1);\n        for (int i = 0; i < sz; ++i) localId[groups[gid][i]] = i;\n\n        vector<int> parent(sz), rankv(sz, 0);\n        iota(parent.begin(), parent.end(), 0);\n        function<int(int)> find = [&](int x) {\n            while (parent[x] != x) {\n                parent[x] = parent[parent[x]];\n                x = parent[x];\n            }\n            return x;\n        };\n        auto unite = [&](int a, int b) -> bool {\n            a = find(a); b = find(b);\n            if (a == b) return false;\n            if (rankv[a] < rankv[b]) swap(a, b);\n            parent[b] = a;\n            if (rankv[a] == rankv[b]) ++rankv[a];\n            return true;\n        };\n\n        int taken = 0;\n        for (const Edge& e : edges) {\n            int u = localId[e.u];\n            int v = localId[e.v];\n            if (unite(u, v)) {\n                answerEdges[gid].push_back({e.u, e.v});\n                ++taken;\n                if (taken == sz - 1) break;\n            }\n        }\n    }\n\n    /* ---------- output ---------- */\n    cout << \"!\\n\";\n    for (int gid = 0; gid < M; ++gid) {\n        for (size_t i = 0; i < groups[gid].size(); ++i) {\n            if (i) cout << ' ';\n            cout << groups[gid][i];\n        }\n        cout << \"\\n\";\n        for (auto &e : answerEdges[gid]) {\n            cout << e.first << ' ' << e.second << \"\\n\";\n        }\n    }\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;                         // N = 20, M = 40\nint totalPos;                    // N * N   ( = 400 )\nint totalStates;                 // totalPos * (totalPos + 1)\n\nconst int dr[4] = {-1, 1, 0, 0};\nconst int dc[4] = {0, 0, -1, 1};\nconst char dirc[4] = {'U', 'D', 'L', 'R'};\n\nvector<int> dist;                // distance in the state graph\nvector<int> parent;              // predecessor state\nvector<pair<char,char>> act;    // action + direction stored for each state\n\n/*---------------------------------------------------------------*/\n/* BFS that returns the shortest action sequence from (sr,sc)\n   to (tr,tc) while leaving no block on the board                */\nbool bfs(int sr, int sc, int tr, int tc,\n         vector<pair<char,char>>& out)\n{\n    if (sr == tr && sc == tc) { out.clear(); return true; }\n\n    int startIdx = sr * N + sc;\n    int targetIdx = tr * N + tc;\n\n    const int startState = startIdx * (totalPos + 1);          // block = none\n    const int targetState = targetIdx * (totalPos + 1);\n\n    fill(dist.begin(),   dist.end(),   -1);\n    fill(parent.begin(), parent.end(), -1);\n\n    queue<int> q;\n    dist[startState] = 0;\n    q.push(startState);\n\n    while (!q.empty()) {\n        int cur = q.front(); q.pop();\n        if (cur == targetState) break;               // reached\n\n        int posIdx   = cur / (totalPos + 1);\n        int blockSt  = cur % (totalPos + 1);          // 0 = none, else cell+1\n        int r = posIdx / N;\n        int c = posIdx % N;\n        int blockIdx = blockSt - 1;                  // -1 = none, else cell id\n\n        /* ---- Move ------------------------------------------------*/\n        for (int d = 0; d < 4; ++d) {\n            int nr = r + dr[d], nc = c + dc[d];\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n            int nIdx = nr * N + nc;\n            if (blockIdx == nIdx) continue;          // blocked\n            int ns = nIdx * (totalPos + 1) + blockSt;\n            if (dist[ns] == -1) {\n                dist[ns] = dist[cur] + 1;\n                parent[ns] = cur;\n                act[ns] = {'M', dirc[d]};\n                q.push(ns);\n            }\n        }\n\n        /* ---- Slide ----------------------------------------------*/\n        for (int d = 0; d < 4; ++d) {\n            int tr_ = r, tc_ = c;\n            while (true) {\n                int nr = tr_ + dr[d];\n                int nc = tc_ + dc[d];\n                if (nr < 0 || nr >= N || nc < 0 || nc >= N) break; // border\n                int nIdx = nr * N + nc;\n                if (blockIdx != -1 && nIdx == blockIdx) break;    // block\n                tr_ = nr; tc_ = nc;\n            }\n            int destIdx = tr_ * N + tc_;\n            int ns = destIdx * (totalPos + 1) + blockSt;\n            if (dist[ns] == -1) {\n                dist[ns] = dist[cur] + 1;\n                parent[ns] = cur;\n                act[ns] = {'S', dirc[d]};\n                q.push(ns);\n            }\n        }\n\n        /* ---- Alter (place / remove block) -----------------------*/\n        for (int d = 0; d < 4; ++d) {\n            int nr = r + dr[d], nc = c + dc[d];\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n            int neighIdx = nr * N + nc;\n            int newBlockSt;\n            if (blockIdx != -1 && neighIdx == blockIdx) {\n                newBlockSt = 0;                         // remove\n            } else if (blockIdx == -1) {\n                newBlockSt = neighIdx + 1;             // place\n            } else {\n                continue;                               // a block already elsewhere\n            }\n            int ns = posIdx * (totalPos + 1) + newBlockSt;\n            if (dist[ns] == -1) {\n                dist[ns] = dist[cur] + 1;\n                parent[ns] = cur;\n                act[ns] = {'A', dirc[d]};\n                q.push(ns);\n            }\n        }\n    }\n\n    if (dist[targetState] == -1) return false;   // should never happen\n\n    /* reconstruct the path */\n    vector<pair<char,char>> rev;\n    int cur = targetState;\n    while (cur != startState) {\n        rev.push_back(act[cur]);\n        cur = parent[cur];\n    }\n    reverse(rev.begin(), rev.end());\n    out = move(rev);\n    return true;\n}\n\n/*---------------------------------------------------------------*/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M;                     // N = 20 , M = 40\n    vector<pair<int,int>> pt(M + 1);\n    for (int i = 0; i <= M; ++i) cin >> pt[i].first >> pt[i].second;\n\n    totalPos    = N * N;               // 400\n    totalStates = totalPos * (totalPos + 1);\n\n    dist.assign(totalStates, -1);\n    parent.assign(totalStates, -1);\n    act.assign(totalStates, {'?', '?'});\n\n    vector<string> answer;\n    int cr = pt[0].first, cc = pt[0].second;\n\n    for (int k = 1; k <= M; ++k) {\n        int tr = pt[k].first, tc = pt[k].second;\n        vector<pair<char,char>> seq;\n        bool ok = bfs(cr, cc, tr, tc, seq);\n        if (!ok) {          // should never happen \u2013 fallback to pure moves\n            while (cr != tr || cc != tc) {\n                if (cr < tr) { answer.emplace_back(\"M D\"); ++cr; }\n                else if (cr > tr) { answer.emplace_back(\"M U\"); --cr; }\n                else if (cc < tc) { answer.emplace_back(\"M R\"); ++cc; }\n                else { answer.emplace_back(\"M L\"); --cc; }\n            }\n        } else {\n            for (auto &p : seq) {\n                string s;\n                s.push_back(p.first);\n                s.push_back(' ');\n                s.push_back(p.second);\n                answer.emplace_back(s);\n            }\n            cr = tr; cc = tc;\n        }\n    }\n\n    if ((int)answer.size() > 2 * N * M) {\n        cerr << \"Too many actions!\\n\";\n    }\n\n    for (auto &ln : answer) cout << ln << '\\n';\n    return 0;\n}"},"8":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int x, y;          // integer coordinates of the unit square\n    int r;             // required area\n    int idx;           // original index\n};\n\nstruct LeafRegion {\n    int x1, y1, x2, y2;\n};\n\nint n;\nvector<Point> pts;\nvector<LeafRegion> leaf;          // region for each original index\n\n/*------------------------------------------------------------------*/\n/*  satisfaction helpers                                           */\ninline double computeP(int r, int s) {\n    double ratio = (double)min(r, s) / (double)max(r, s);\n    return ratio * (2.0 - ratio);\n}\n\n/*  best possible satisfaction for a point with required area r\n    inside a region of size w \u00d7 h (both positive)                */\ninline double bestSat(int r, int w, int h) {\n    if (w <= 0 || h <= 0) return 0.0;\n    // candidate heights: 1, h, floor(r/w), ceil(r/w)\n    int hf = r / w;\n    int hc = (r + w - 1) / w;\n    double best = 0.0;\n    const int cand[4] = {1, h, hf, hc};\n    for (int i = 0; i < 4; ++i) {\n        int hh = cand[i];\n        if (hh < 1 || hh > h) continue;\n        int s = w * hh;\n        double p = computeP(r, s);\n        if (p > best) best = p;\n    }\n    return best;\n}\n\n/*------------------------------------------------------------------*/\n/*  recursive construction of the binary partition                */\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nvoid build(const vector<int>& ids,\n           int x1, int y1, int x2, int y2) {\n    if (ids.size() == 1) {                 // leaf\n        leaf[ids[0]] = {x1, y1, x2, y2};\n        return;\n    }\n\n    int W = x2 - x1;\n    int H = y2 - y1;\n\n    double bestScore = -1.0;\n    bool bestVert = false;\n    int bestK = -1;\n\n    /* ----- try all vertical cuts ----- */\n    for (int k = x1 + 1; k < x2; ++k) {\n        int wL = k - x1;\n        int wR = x2 - k;\n        bool leftNotEmpty = false, rightNotEmpty = false;\n        double sum = 0.0;\n        for (int id : ids) {\n            if (pts[id].x < k) {\n                leftNotEmpty = true;\n                sum += bestSat(pts[id].r, wL, H);\n            } else {\n                rightNotEmpty = true;\n                sum += bestSat(pts[id].r, wR, H);\n            }\n        }\n        if (!leftNotEmpty || !rightNotEmpty) continue;\n        if (sum > bestScore + 1e-12) {\n            bestScore = sum;\n            bestVert = true;\n            bestK = k;\n        } else if (fabs(sum - bestScore) <= 1e-12) {\n            // random tie\u2011break\n            if (rng() & 1) {\n                bestVert = true;\n                bestK = k;\n            }\n        }\n    }\n\n    /* ----- try all horizontal cuts ----- */\n    for (int k = y1 + 1; k < y2; ++k) {\n        int hL = k - y1;\n        int hR = y2 - k;\n        bool leftNotEmpty = false, rightNotEmpty = false;\n        double sum = 0.0;\n        for (int id : ids) {\n            if (pts[id].y < k) {\n                leftNotEmpty = true;\n                sum += bestSat(pts[id].r, W, hL);\n            } else {\n                rightNotEmpty = true;\n                sum += bestSat(pts[id].r, W, hR);\n            }\n        }\n        if (!leftNotEmpty || !rightNotEmpty) continue;\n        if (sum > bestScore + 1e-12) {\n            bestScore = sum;\n            bestVert = false;\n            bestK = k;\n        } else if (fabs(sum - bestScore) <= 1e-12) {\n            if (rng() & 1) {\n                bestVert = false;\n                bestK = k;\n            }\n        }\n    }\n\n    // perform the chosen cut\n    vector<int> leftIds, rightIds;\n    if (bestVert) {                         // vertical\n        for (int id : ids) {\n            if (pts[id].x < bestK) leftIds.push_back(id);\n            else rightIds.push_back(id);\n        }\n        build(leftIds,  x1, y1, bestK, y2);\n        build(rightIds, bestK, y1, x2,   y2);\n    } else {                                 // horizontal\n        for (int id : ids) {\n            if (pts[id].y < bestK) leftIds.push_back(id);\n            else rightIds.push_back(id);\n        }\n        build(leftIds,  x1, y1, x2, bestK);\n        build(rightIds, x1, bestK, x2, y2);\n    }\n}\n\n/*------------------------------------------------------------------*/\n/*  build the final rectangle inside a leaf                         */\nvoid placeRectangles(const vector<LeafRegion>& leaf,\n                    vector<int>& a, vector<int>& b,\n                    vector<int>& c, vector<int>& d,\n                    double& totalP) {\n    totalP = 0.0;\n    for (int i = 0; i < n; ++i) {\n        const LeafRegion &reg = leaf[i];\n        int W = reg.x2 - reg.x1;\n        int H = reg.y2 - reg.y1;\n        int r = pts[i].r;\n\n        int bestW = 1, bestH = 1;\n        double bestP = -1.0;\n\n        for (int w = 1; w <= W; ++w) {\n            int hf = r / w;\n            int hc = (r + w - 1) / w;\n            const int cand[4] = {1, H, hf, hc};\n            for (int t = 0; t < 4; ++t) {\n                int h = cand[t];\n                if (h < 1 || h > H) continue;\n                int s = w * h;\n                double p = computeP(r, s);\n                if (p > bestP) {\n                    bestP = p;\n                    bestW = w;\n                    bestH = h;\n                }\n            }\n        }\n\n        // position the rectangle so that it still covers the unit square\n        int left   = max(reg.x1, pts[i].x + 1 - bestW);\n        int bottom = max(reg.y1, pts[i].y + 1 - bestH);\n\n        a[i] = left;\n        b[i] = bottom;\n        c[i] = left + bestW;\n        d[i] = bottom + bestH;\n\n        totalP += bestP;\n    }\n}\n\n/*------------------------------------------------------------------*/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> n;\n    pts.resize(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> pts[i].x >> pts[i].y >> pts[i].r;\n        pts[i].idx = i;\n    }\n\n    const int ITER = 25;                // more repetitions \u2192 higher chance to hit a better tree\n    double bestTotal = -1.0;\n    vector<int> bestA(n), bestB(n), bestC(n), bestD(n);\n\n    for (int it = 0; it < ITER; ++it) {\n        leaf.assign(n, LeafRegion{0,0,0,0});\n        vector<int> allIds(n);\n        iota(allIds.begin(), allIds.end(), 0);\n        shuffle(allIds.begin(), allIds.end(), rng);   // random order \u2192 different ties\n        build(allIds, 0, 0, 10000, 10000);\n\n        vector<int> a(n), b(n), c(n), d(n);\n        double cur;\n        placeRectangles(leaf, a, b, c, d, cur);\n\n        if (cur > bestTotal) {\n            bestTotal = cur;\n            bestA = a; bestB = b; bestC = c; bestD = d;\n        }\n    }\n\n    for (int i = 0; i < n; ++i) {\n        cout << bestA[i] << ' ' << bestB[i] << ' '\n             << bestC[i] << ' ' << bestD[i] << '\\n';\n    }\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------- input ---------- */\n    int si, sj;\n    if (!(cin >> si >> sj)) return 0;\n    const int N = 50;\n\n    vector<vector<int>> tile(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> tile[i][j];\n\n    vector<vector<int>> val(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> val[i][j];\n\n    /* number of different tiles */\n    int maxTile = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            maxTile = max(maxTile, tile[i][j]);\n    const int M = maxTile + 1;                 // tile IDs 0 \u2026 M\u20111\n\n    /* ---------- cell graph (edges only to cells of a different tile) ---------- */\n    const int V = N * N;\n    vector<int> cellVal(V);\n    vector<int> cellTile(V);\n    vector<int> adj[V];\n    auto id = [&](int i, int j) { return i * N + j; };\n    const int di[4] = {-1, 1, 0, 0};\n    const int dj[4] = {0, 0, -1, 1};\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int u = id(i, j);\n            cellVal[u]  = val[i][j];\n            cellTile[u] = tile[i][j];\n            for (int d = 0; d < 4; ++d) {\n                int ni = i + di[d], nj = j + dj[d];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                int v = id(ni, nj);\n                if (tile[ni][nj] != tile[i][j]) adj[u].push_back(v);\n            }\n        }\n    }\n\n    const int startCell = id(si, sj);\n    const int startTile = cellTile[startCell];\n\n    /* ---------- randomised greedy walks ---------- */\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    const int MAX_TRIES = 600000;               // safe middle ground\n    vector<int> visitedTile(M, 0);\n    int curToken = 1;\n\n    string bestPath;\n    int bestScore = -1;\n\n    for (int attempt = 0; attempt < MAX_TRIES; ++attempt) {\n        ++curToken;\n        visitedTile[startTile] = curToken;       // start tile already used\n\n        int cur = startCell;\n        int curScore = cellVal[cur];\n        string path;\n        path.reserve(2500);                     // avoid reallocations\n\n        /* random parameters for this trial */\n        int randProb = 5 + (rng() % 36);         // 5 \u2026 40 %\n        int gamma    = rng() % 51;                // 0 \u2026 50\n        int heurType = rng() % 4;                 // 0 \u2026 3  (degree, sum10, max1, deg+max1)\n\n        while (true) {\n            /* collect admissible neighbours (different, still unvisited tile) */\n            int cand[4];\n            int candCnt = 0;\n            for (int nb : adj[cur]) {\n                int ntile = cellTile[nb];\n                if (visitedTile[ntile] != curToken)\n                    cand[candCnt++] = nb;\n            }\n            if (candCnt == 0) break;             // stuck\n\n            /* small chance to pick a completely random neighbour */\n            if (rng() % 100 < randProb) {\n                int idx = rng() % candCnt;\n                int nxt = cand[idx];\n                // direction character\n                int fi = cur / N, fj = cur % N;\n                int ti = nxt / N, tj = nxt % N;\n                char mc;\n                if (ti == fi - 1 && tj == fj) mc = 'U';\n                else if (ti == fi + 1 && tj == fj) mc = 'D';\n                else if (ti == fi && tj == fj - 1) mc = 'L';\n                else mc = 'R';\n                path.push_back(mc);\n                cur = nxt;\n                visitedTile[cellTile[cur]] = curToken;\n                curScore += cellVal[cur];\n                continue;\n            }\n\n            /* evaluate all candidates */\n            int bestHeur = INT_MIN;\n            int bestNext = -1;\n            for (int i = 0; i < candCnt; ++i) {\n                int nb = cand[i];\n                int value = cellVal[nb];\n                int measure = 0;\n\n                if (heurType == 0) {               // degree\n                    for (int nb2 : adj[nb])\n                        if (visitedTile[cellTile[nb2]] != curToken)\n                            ++measure;\n                } else if (heurType == 1) {         // sum / 10\n                    for (int nb2 : adj[nb])\n                        if (visitedTile[cellTile[nb2]] != curToken)\n                            measure += cellVal[nb2];\n                    measure /= 10;\n                } else if (heurType == 2) {         // max1\n                    for (int nb2 : adj[nb])\n                        if (visitedTile[cellTile[nb2]] != curToken)\n                            measure = max(measure, cellVal[nb2]);\n                } else {                            // deg + max1\n                    int deg = 0, mx = 0;\n                    for (int nb2 : adj[nb]) {\n                        if (visitedTile[cellTile[nb2]] != curToken) {\n                            ++deg;\n                            mx = max(mx, cellVal[nb2]);\n                        }\n                    }\n                    measure = deg + mx;\n                }\n\n                int heur = value + gamma * measure;\n                // tiny random noise to break ties\n                heur += (rng() & 1);\n\n                if (heur > bestHeur) {\n                    bestHeur = heur;\n                    bestNext = nb;\n                } else if (heur == bestHeur && (rng() & 1)) {\n                    bestNext = nb;\n                }\n            }\n\n            /* perform the chosen step */\n            int nxt = bestNext;\n            int fi = cur / N, fj = cur % N;\n            int ti = nxt / N, tj = nxt % N;\n            char mc;\n            if (ti == fi - 1 && tj == fj) mc = 'U';\n            else if (ti == fi + 1 && tj == fj) mc = 'D';\n            else if (ti == fi && tj == fj - 1) mc = 'L';\n            else mc = 'R';\n            path.push_back(mc);\n            cur = nxt;\n            visitedTile[cellTile[cur]] = curToken;\n            curScore += cellVal[cur];\n        }\n\n        if (curScore > bestScore) {\n            bestScore = curScore;\n            bestPath = path;\n        }\n    }\n\n    cout << bestPath << '\\n';\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 30;\n    const int V = N * N;\n    const double INF = 1e100;\n    const double INIT_W = 5000.0;\n    const double MIN_W = 500.0;\n    const double MAX_W = 15000.0;\n    const double ALPHA = 0.2;\n    const double FACTOR_MIN = 0.5;\n    const double FACTOR_MAX = 2.0;\n\n    /* ---------- edge weight estimates ---------- */\n    double hor[N][N - 1];   // horizontal edges\n    double ver[N - 1][N];   // vertical edges\n\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N - 1; ++j)\n            hor[i][j] = INIT_W;\n    for (int i = 0; i < N - 1; ++i)\n        for (int j = 0; j < N; ++j)\n            ver[i][j] = INIT_W;\n\n    auto idx = [&](int i, int j) { return i * N + j; };\n\n    for (int q = 0; q < 1000; ++q) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) break;\n\n        int s = idx(si, sj);\n        int t = idx(ti, tj);\n\n        /* ---------- Dijkstra (shortest path with current estimates) ---------- */\n        vector<double> dist(V, INF);\n        vector<int> prev(V, -1);\n        vector<char> mv(V, 0);\n        dist[s] = 0.0;\n        using Node = pair<double, int>;\n        priority_queue<Node, vector<Node>, greater<Node>> pq;\n        pq.emplace(0.0, s);\n\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u] + 1e-12) continue;\n            if (u == t) break;\n            int ui = u / N, uj = u % N;\n\n            // up\n            if (ui > 0) {\n                int v = idx(ui - 1, uj);\n                double w = ver[ui - 1][uj];\n                double nd = d + w;\n                if (nd + 1e-12 < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    mv[v] = 'U';\n                    pq.emplace(nd, v);\n                }\n            }\n            // down\n            if (ui < N - 1) {\n                int v = idx(ui + 1, uj);\n                double w = ver[ui][uj];\n                double nd = d + w;\n                if (nd + 1e-12 < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    mv[v] = 'D';\n                    pq.emplace(nd, v);\n                }\n            }\n            // left\n            if (uj > 0) {\n                int v = idx(ui, uj - 1);\n                double w = hor[ui][uj - 1];\n                double nd = d + w;\n                if (nd + 1e-12 < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    mv[v] = 'L';\n                    pq.emplace(nd, v);\n                }\n            }\n            // right\n            if (uj < N - 1) {\n                int v = idx(ui, uj + 1);\n                double w = hor[ui][uj];\n                double nd = d + w;\n                if (nd + 1e-12 < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    mv[v] = 'R';\n                    pq.emplace(nd, v);\n                }\n            }\n        }\n\n        /* ---------- rebuild the path ---------- */\n        string path;\n        int cur = t;\n        while (cur != s) {\n            path.push_back(mv[cur]);\n            cur = prev[cur];\n        }\n        reverse(path.begin(), path.end());\n\n        /* ---------- output ---------- */\n        cout << path << '\\n' << flush;\n\n        /* ---------- receive noisy length ---------- */\n        long long noisy;\n        cin >> noisy;\n\n        /* ---------- compute estimated length of the printed path ---------- */\n        double est = 0.0;\n        int ci = si, cj = sj;\n        for (char c : path) {\n            if (c == 'U') { est += ver[ci - 1][cj]; --ci; }\n            else if (c == 'D') { est += ver[ci][cj]; ++ci; }\n            else if (c == 'L') { est += hor[ci][cj - 1]; --cj; }\n            else if (c == 'R') { est += hor[ci][cj]; ++cj; }\n        }\n\n        /* ---------- multiplicative update (pow\u2011based) ---------- */\n        double ratio = static_cast<double>(noisy) / est;\n        double factor = pow(ratio, ALPHA);          // <-- slight improvement\n        if (factor < FACTOR_MIN) factor = FACTOR_MIN;\n        if (factor > FACTOR_MAX) factor = FACTOR_MAX;\n\n        /* ---------- apply the factor to every edge of the printed path ---------- */\n        ci = si; cj = sj;\n        for (char c : path) {\n            if (c == 'U') {\n                double &w = ver[ci - 1][cj];\n                w *= factor;\n                if (w < MIN_W) w = MIN_W;\n                if (w > MAX_W) w = MAX_W;\n                --ci;\n            } else if (c == 'D') {\n                double &w = ver[ci][cj];\n                w *= factor;\n                if (w < MIN_W) w = MIN_W;\n                if (w > MAX_W) w = MAX_W;\n                ++ci;\n            } else if (c == 'L') {\n                double &w = hor[ci][cj - 1];\n                w *= factor;\n                if (w < MIN_W) w = MIN_W;\n                if (w > MAX_W) w = MAX_W;\n                --cj;\n            } else if (c == 'R') {\n                double &w = hor[ci][cj];\n                w *= factor;\n                if (w < MIN_W) w = MIN_W;\n                if (w > MAX_W) w = MAX_W;\n                ++cj;\n            }\n        }\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\n/***  global data  ***/\nint N = 20;                              // board size (fixed)\nint totalM;                              // \u03a3 multiplicity = M\nint curC, bestC;                         // weighted number of present strings\n\n// character encoding: 'A'..'H' -> 0..7\nint chCode[256];\n// powers of 8, 8^k (k \u2264 12)\nuint64_t pow8[13];\n\n// distinct strings\nunordered_map<unsigned long long, int> str2idx;\nvector<int> mult;\nvector<int> occ;\nint uniqCnt;\n\n// substring description\nstruct SubInfo {\n    uint8_t start_i, start_j;\n    uint8_t dir;          // 0 = horizontal, 1 = vertical\n    uint8_t len;\n};\nvector<SubInfo> subs;\nvector<uint64_t> curCode;\nvector<int> curIdx;\n\n// for each cell: list of (substring id, offset inside the substring)\nvector<vector<pair<int, uint8_t>>> cellSubs;\n\n// current board and best board\nvector<string> grid;\nvector<string> bestGrid;\n\n/***  helpers  ***/\ninline unsigned long long encodeString(const string &s) {\n    unsigned long long code = 0;\n    for (char ch : s) code = (code << 3) | (unsigned long long)chCode[(unsigned char)ch];\n    return code;\n}\n\n/***  initial evaluation from a given board ***/\nvoid initFromGrid(const vector<string> &g) {\n    fill(occ.begin(), occ.end(), 0);\n    curC = 0;\n    int S = (int)subs.size();\n    for (int sid = 0; sid < S; ++sid) {\n        const SubInfo &inf = subs[sid];\n        unsigned long long code = 0;\n        for (int p = 0; p < inf.len; ++p) {\n            int r = (inf.dir == 0) ? inf.start_i\n                                    : (inf.start_i + p) % N;\n            int c = (inf.dir == 0) ? (inf.start_j + p) % N\n                                    : inf.start_j;\n            char ch = g[r][c];\n            code = (code << 3) | (unsigned long long)chCode[(unsigned char)ch];\n        }\n        unsigned long long key = (code << 4) | (unsigned long long)inf.len;\n        int idx = -1;\n        auto it = str2idx.find(key);\n        if (it != str2idx.end()) idx = it->second;\n        curIdx[sid] = idx;\n        curCode[sid] = code;\n        if (idx != -1) occ[idx]++;\n    }\n    for (int i = 0; i < uniqCnt; ++i)\n        if (occ[i] > 0) curC += mult[i];\n}\n\n/***  compute delta for a single cell change ***/\nint computeDelta(int cell, char newChar) {\n    int r = cell / N;\n    int c = cell % N;\n    char oldChar = grid[r][c];\n    if (oldChar == newChar) return 0;\n    int oldVal = chCode[(unsigned char)oldChar];\n    int newVal = chCode[(unsigned char)newChar];\n    int delta = 0;\n    for (const auto &pr : cellSubs[cell]) {\n        int sid = pr.first;\n        int offset = pr.second;\n        const SubInfo &inf = subs[sid];\n        int len = inf.len;\n        int exp = len - 1 - offset;\n        unsigned long long oldCodeSub = curCode[sid];\n        unsigned long long newCodeSub = oldCodeSub\n                                      - (unsigned long long)oldVal * pow8[exp]\n                                      + (unsigned long long)newVal * pow8[exp];\n        unsigned long long newKey = (newCodeSub << 4) | (unsigned long long)len;\n        int newIdx = -1;\n        auto it = str2idx.find(newKey);\n        if (it != str2idx.end()) newIdx = it->second;\n        int oldIdx = curIdx[sid];\n        if (oldIdx == newIdx) continue;\n        if (oldIdx != -1) {\n            if (occ[oldIdx] == 1) delta -= mult[oldIdx];\n        }\n        if (newIdx != -1) {\n            if (occ[newIdx] == 0) delta += mult[newIdx];\n        }\n    }\n    return delta;\n}\n\n/***  apply an accepted move ***/\nvoid applyDelta(int cell, char newChar) {\n    int r = cell / N;\n    int c = cell % N;\n    char oldChar = grid[r][c];\n    if (oldChar == newChar) return;\n    int oldVal = chCode[(unsigned char)oldChar];\n    int newVal = chCode[(unsigned char)newChar];\n    for (const auto &pr : cellSubs[cell]) {\n        int sid = pr.first;\n        int offset = pr.second;\n        const SubInfo &inf = subs[sid];\n        int len = inf.len;\n        int exp = len - 1 - offset;\n        unsigned long long oldCodeSub = curCode[sid];\n        unsigned long long newCodeSub = oldCodeSub\n                                      - (unsigned long long)oldVal * pow8[exp]\n                                      + (unsigned long long)newVal * pow8[exp];\n        unsigned long long newKey = (newCodeSub << 4) | (unsigned long long)len;\n        int newIdx = -1;\n        auto it = str2idx.find(newKey);\n        if (it != str2idx.end()) newIdx = it->second;\n        int oldIdx = curIdx[sid];\n        if (oldIdx == newIdx) {\n            curCode[sid] = newCodeSub;\n            curIdx[sid] = newIdx;\n            continue;\n        }\n        if (oldIdx != -1) {\n            if (occ[oldIdx] == 1) curC -= mult[oldIdx];\n            --occ[oldIdx];\n        }\n        if (newIdx != -1) {\n            if (occ[newIdx] == 0) curC += mult[newIdx];\n            ++occ[newIdx];\n        }\n        curCode[sid] = newCodeSub;\n        curIdx[sid] = newIdx;\n    }\n    grid[r][c] = newChar;\n}\n\n/***  run a single hill\u2011climbing search ***/\nvoid runSearch(double timeLimit) {\n    // fresh random generator for this restart\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    // random initial board\n    grid.assign(N, string(N, 'A'));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            grid[i][j] = char('A' + rng() % 8);\n\n    initFromGrid(grid);\n\n    auto start = chrono::steady_clock::now();\n    // scale the number of iterations to the given time limit\n    int maxIter = (int)(timeLimit * 1'000'000.0 / 2.8);\n    if (maxIter < 100000) maxIter = 100000;   // at least this many\n\n    for (int iter = 0; iter < maxIter; ++iter) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed >= timeLimit) break;\n\n        int cell = rng() % (N * N);\n        int r = cell / N, c = cell % N;\n        char oldChar = grid[r][c];\n\n        // evaluate all 8 possible new letters\n        int bestDelta = INT_MIN;\n        char bestChar = oldChar;\n        for (char cand = 'A'; cand <= 'H'; ++cand) {\n            if (cand == oldChar) continue;\n            int delta = computeDelta(cell, cand);\n            if (delta > bestDelta) {\n                bestDelta = delta;\n                bestChar = cand;\n            }\n        }\n\n        bool accept = false;\n        if (bestDelta > 0) {\n            accept = true;\n        } else {\n            int rprob = rng() % 100;\n            if (bestDelta == 0 && rprob < 10) accept = true;      // 10%\n            else if (bestDelta < 0 && rprob < 1) accept = true;   // 1%\n        }\n\n        if (accept) {\n            applyDelta(cell, bestChar);\n            if (curC > bestC) {\n                bestC = curC;\n                bestGrid = grid;\n                if (bestC == totalM) break;               // perfect!\n            }\n        }\n    }\n}\n\n/***  main ***/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M;\n    if (!(cin >> N >> M)) return 0;\n    totalM = M;\n\n    // character encoding\n    fill(begin(chCode), end(chCode), -1);\n    for (char ch = 'A'; ch <= 'H'; ++ch) chCode[(unsigned char)ch] = ch - 'A';\n\n    // read strings, build distinct set\n    vector<string> inputs(M);\n    for (int i = 0; i < M; ++i) cin >> inputs[i];\n    for (const string &s : inputs) {\n        unsigned long long code = encodeString(s);\n        unsigned long long key = (code << 4) | (unsigned long long)s.size();\n        auto it = str2idx.find(key);\n        if (it == str2idx.end()) {\n            int id = (int)mult.size();\n            str2idx[key] = id;\n            mult.push_back(1);\n        } else {\n            ++mult[it->second];\n        }\n    }\n    uniqCnt = (int)mult.size();\n    occ.assign(uniqCnt, 0);\n\n    // speed up hash table\n    str2idx.reserve(uniqCnt * 2);\n\n    // powers of 8\n    pow8[0] = 1;\n    for (int i = 1; i <= 12; ++i) pow8[i] = pow8[i - 1] * 8ULL;\n\n    // build all substrings and cell\u2192substring lists\n    subs.reserve(8800);\n    cellSubs.assign(N * N, {});\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            // horizontal\n            for (int len = 2; len <= 12; ++len) {\n                SubInfo inf;\n                inf.start_i = (uint8_t)i;\n                inf.start_j = (uint8_t)j;\n                inf.dir = 0;\n                inf.len = (uint8_t)len;\n                int sid = (int)subs.size();\n                subs.push_back(inf);\n                for (int p = 0; p < len; ++p) {\n                    int cj = (j + p) % N;\n                    int cell = i * N + cj;\n                    cellSubs[cell].push_back({sid, (uint8_t)p});\n                }\n            }\n            // vertical\n            for (int len = 2; len <= 12; ++len) {\n                SubInfo inf;\n                inf.start_i = (uint8_t)i;\n                inf.start_j = (uint8_t)j;\n                inf.dir = 1;\n                inf.len = (uint8_t)len;\n                int sid = (int)subs.size();\n                subs.push_back(inf);\n                for (int p = 0; p < len; ++p) {\n                    int ri = (i + p) % N;\n                    int cell = ri * N + j;\n                    cellSubs[cell].push_back({sid, (uint8_t)p});\n                }\n            }\n        }\n    }\n\n    curCode.assign(subs.size(), 0);\n    curIdx.assign(subs.size(), -1);\n\n    // global best\n    bestC = -1;\n    bestGrid.assign(N, string(N, 'A'));\n\n    // ----- three independent restarts -----\n    const double totalTime = 2.8;          // seconds\n    const double perRun = 0.9;              // seconds per restart\n\n    auto overallStart = chrono::steady_clock::now();\n\n    for (int run = 0; run < 3; ++run) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - overallStart).count();\n        double remain = totalTime - elapsed;\n        if (remain < 0.1) break;            // no time left\n        runSearch(min(perRun, remain));\n        if (bestC == totalM) break;         // perfect!\n    }\n\n    // output best board\n    for (int i = 0; i < N; ++i) cout << bestGrid[i] << '\\n';\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing pii = pair<int,int>;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, si, sj;\n    if(!(cin >> N >> si >> sj)) return 0;\n    vector<string> g(N);\n    for (int i = 0; i < N; ++i) cin >> g[i];\n\n    /* ---------- road cells ---------- */\n    vector<vector<int>> id(N, vector<int>(N, -1));\n    vector<pii> pos;                     // id \u2192 (i , j)\n    vector<int> w;                       // entering time\n    int R = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (g[i][j] != '#') {\n                id[i][j] = R++;\n                pos.emplace_back(i, j);\n                w.push_back(g[i][j] - '0');\n            }\n\n    /* ---------- horizontal segments ---------- */\n    vector<vector<int>> rowSegId(N, vector<int>(N, -1));\n    vector<vector<int>> rowSegMembers;               // list of cell ids\n    int rowSegCnt = 0;\n    for (int i = 0; i < N; ++i) {\n        int j = 0;\n        while (j < N) {\n            if (g[i][j] == '#') { ++j; continue; }\n            int seg = rowSegCnt++;\n            rowSegMembers.emplace_back();\n            while (j < N && g[i][j] != '#') {\n                int cid = id[i][j];\n                rowSegId[i][j] = seg;\n                rowSegMembers.back().push_back(cid);\n                ++j;\n            }\n        }\n    }\n\n    /* ---------- vertical segments ---------- */\n    vector<vector<int>> colSegId(N, vector<int>(N, -1));\n    vector<vector<int>> colSegMembers;\n    int colSegCnt = 0;\n    for (int j = 0; j < N; ++j) {\n        int i = 0;\n        while (i < N) {\n            if (g[i][j] == '#') { ++i; continue; }\n            int seg = colSegCnt++;\n            colSegMembers.emplace_back();\n            while (i < N && g[i][j] != '#') {\n                int cid = id[i][j];\n                colSegId[i][j] = seg;\n                colSegMembers.back().push_back(cid);\n                ++i;\n            }\n        }\n    }\n\n    /* cell \u2192 its two segment ids */\n    vector<int> cellRowSeg(R), cellColSeg(R);\n    for (int cid = 0; cid < R; ++cid) {\n        int i = pos[cid].first, j = pos[cid].second;\n        cellRowSeg[cid] = rowSegId[i][j];\n        cellColSeg[cid] = colSegId[i][j];\n    }\n\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    const char dch[4] = {'U','D','L','R'};\n\n    auto dirFromDelta = [&](int dr, int dc)->char{\n        if (dr==-1 && dc==0) return 'U';\n        if (dr==1  && dc==0) return 'D';\n        if (dr==0 && dc==-1) return 'L';\n        if (dr==0 && dc==1) return 'R';\n        return '?';\n    };\n\n    /* ----- counters for still invisible cells ----- */\n    vector<int> rowCnt(rowSegCnt), colCnt(colSegCnt);\n    for (int rs = 0; rs < rowSegCnt; ++rs) rowCnt[rs] = (int)rowSegMembers[rs].size();\n    for (int cs = 0; cs < colSegCnt; ++cs) colCnt[cs] = (int)colSegMembers[cs].size();\n\n    vector<char> rowCover(rowSegCnt, 0), colCover(colSegCnt, 0);\n    vector<char> visible(R, 0);\n    int coveredCnt = 0;\n\n    auto visitRowSeg = [&](int rs) {\n        if (rowCover[rs]) return;\n        rowCover[rs] = 1;\n        for (int cid : rowSegMembers[rs]) {\n            if (!visible[cid]) {\n                visible[cid] = 1;\n                ++coveredCnt;\n                int cs = cellColSeg[cid];\n                --colCnt[cs];\n            }\n        }\n        rowCnt[rs] = 0;\n    };\n    auto visitColSeg = [&](int cs) {\n        if (colCover[cs]) return;\n        colCover[cs] = 1;\n        for (int cid : colSegMembers[cs]) {\n            if (!visible[cid]) {\n                visible[cid] = 1;\n                ++coveredCnt;\n                int rs = cellRowSeg[cid];\n                --rowCnt[rs];\n            }\n        }\n        colCnt[cs] = 0;\n    };\n\n    int startId = id[si][sj];\n    /* initialise the start row / column as visited */\n    visitRowSeg(cellRowSeg[startId]);\n    visitColSeg(cellColSeg[startId]);\n\n    /* ----- greedy walk ----- */\n    string answer;\n    answer.reserve(20000);\n    long long totalCost = 0;\n    int ci = si, cj = sj;               // current position\n    int curId = startId;\n\n    while (coveredCnt < R) {\n        int bestDir = -1;\n        int bestInc = -1;\n        int bestCost = INT_MAX;\n        int bestNi = -1, bestNj = -1;\n\n        for (int d = 0; d < 4; ++d) {\n            int ni = ci + dx[d], nj = cj + dy[d];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            if (id[ni][nj] == -1) continue;\n            int nid = id[ni][nj];\n            int rs = cellRowSeg[nid];\n            int cs = cellColSeg[nid];\n\n            int inc = 0;\n            bool rowNot = !rowCover[rs];\n            bool colNot = !colCover[cs];\n            if (rowNot && rowCnt[rs] > 0) inc += rowCnt[rs];\n            if (colNot && colCnt[cs] > 0) inc += colCnt[cs];\n            if (rowNot && colNot && rowCnt[rs] > 0 && colCnt[cs] > 0) inc -= 1;\n\n            if (inc > bestInc || (inc == bestInc && w[nid] < bestCost)) {\n                bestInc = inc;\n                bestCost = w[nid];\n                bestDir = d;\n                bestNi = ni; bestNj = nj;\n            }\n        }\n\n        if (bestInc > 0) {                         // move with new coverage\n            answer.push_back(dch[bestDir]);\n            totalCost += w[id[bestNi][bestNj]];\n            ci = bestNi; cj = bestNj;\n            curId = id[ci][cj];\n            int rs = cellRowSeg[curId];\n            int cs = cellColSeg[curId];\n            if (!rowCover[rs]) visitRowSeg(rs);\n            if (!colCover[cs]) visitColSeg(cs);\n        } else {                                   // no new coverage \u2013 go to nearest invisible cell\n            static int dist[70][70];\n            static int parent[70][70];\n            for (int i = 0; i < N; ++i)\n                for (int j = 0; j < N; ++j) {\n                    dist[i][j] = -1;\n                    parent[i][j] = -1;\n                }\n            queue<pii> q;\n            dist[ci][cj] = 0;\n            q.emplace(ci, cj);\n            int ti = -1, tj = -1;\n            while (!q.empty()) {\n                auto [x, y] = q.front(); q.pop();\n\n                // check if this cell is invisible (but not the start)\n                if (!(x == ci && y == cj)) {\n                    int cid = id[x][y];\n                    if (!visible[cid]) {\n                        ti = x; tj = y;\n                        break;\n                    }\n                }\n\n                for (int dir = 0; dir < 4; ++dir) {\n                    int nx = x + dx[dir], ny = y + dy[dir];\n                    if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n                    if (id[nx][ny] == -1) continue;\n                    if (dist[nx][ny] != -1) continue;\n                    dist[nx][ny] = dist[x][y] + 1;\n                    parent[nx][ny] = x * N + y;\n                    q.emplace(nx, ny);\n                }\n            }\n\n            if (ti == -1) {\n                // shouldn't happen, but just in case\n                break;\n            }\n\n            // reconstruct path: find the first step after current position\n            int cx = ti, cy = tj;\n            // walk back until parent is the current position\n            while (!(cx == ci && cy == cj)) {\n                int p = parent[cx][cy];\n                if (p == -1) break; // shouldn't happen\n                cx = p / N; cy = p % N;\n                if (cx == ci && cy == cj) break;\n                // continue to next\n            }\n            // now cx,cy should be the neighbour of current position\n            // but we need to find the one right after ci,cj\n            // let's redo: go from target back to just after start\n            vector<pii> path;\n            int tx = ti, ty = tj;\n            while (!(tx == ci && ty == cj)) {\n                path.emplace_back(tx, ty);\n                int p = parent[tx][ty];\n                if (p == -1) break;\n                tx = p / N; ty = p % N;\n            }\n            // path[0] is the target, path.back() is the neighbour of start\n            if (path.empty()) {\n                // shouldn't happen\n                break;\n            }\n            int nx = path.back().first, ny = path.back().second;\n            answer.push_back(dirFromDelta(nx - ci, ny - cj));\n            totalCost += w[id[nx][ny]];\n            ci = nx; cj = ny;\n            curId = id[ci][cj];\n            int rs = cellRowSeg[curId];\n            int cs = cellColSeg[curId];\n            if (!rowCover[rs]) visitRowSeg(rs);\n            if (!colCover[cs]) visitColSeg(cs);\n        }\n    }\n\n    /* ----- shortest way back to start (Dijkstra) ----- */\n    const long long INF = (1LL << 60);\n    vector<long long> dist(R, INF);\n    vector<int> pv(R, -1);\n    using Node = pair<long long,int>;\n    priority_queue<Node, vector<Node>, greater<Node>> pq;\n    dist[startId] = 0;\n    pq.emplace(0, startId);\n    while (!pq.empty()) {\n        auto [du, u] = pq.top(); pq.pop();\n        if (du != dist[u]) continue;\n        int ux = pos[u].first, uy = pos[u].second;\n        for (int dir = 0; dir < 4; ++dir) {\n            int vx = ux + dx[dir], vy = uy + dy[dir];\n            if (vx < 0 || vx >= N || vy < 0 || vy >= N) continue;\n            int v = id[vx][vy];\n            if (v == -1) continue;\n            long long nd = du + w[v];\n            if (nd < dist[v]) {\n                dist[v] = nd;\n                pv[v] = u;\n                pq.emplace(nd, v);\n            }\n        }\n    }\n\n    // reconstruct path from cur back to start (reverse order)\n    vector<int> revPath;\n    int node = curId;\n    while (true) {\n        revPath.push_back(node);\n        if (node == startId) break;\n        if (pv[node] == -1) break; // shouldn't happen\n        node = pv[node];\n    }\n    // append the moves: from cur (index 0) to start (last index)\n    for (int k = 0; k < (int)revPath.size() - 1; ++k) {\n        int a = revPath[k];\n        int b = revPath[k+1];\n        int ax = pos[a].first, ay = pos[a].second;\n        int bx = pos[b].first, by = pos[b].second;\n        answer.push_back(dirFromDelta(bx - ax, by - ay));\n        totalCost += w[b];\n    }\n\n    cout << answer << '\\n';\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct ReadyTask {\n    long long score;   // diff * (depth + 1)\n    int id;            // task index (0\u2011based)\n    bool operator<(const ReadyTask& other) const {\n        return score < other.score;          // max\u2011heap\n    }\n};\n\n/*** Hungarian algorithm for a rectangular cost matrix (n x m, n <= m) ***/\nstruct Hungarian {\n    int n, m;                 // n workers, m jobs (n <= m)\n    vector<vector<long long>> a;   // cost matrix\n    vector<long long> u, v;        // potentials\n    vector<int> p, way;           // matching\n\n    Hungarian(int n_, int m_, const vector<vector<long long>>& cost)\n        : n(n_), m(m_), a(cost), u(n_+1), v(m_+1), p(m_+1), way(m_+1) {}\n\n    // returns minimum total cost, p[j] = assigned worker (1\u2011based), 0 = none\n    long long solve() {\n        for (int i = 1; i <= n; ++i) {\n            p[0] = i;\n            int j0 = 0;\n            vector<long long> minv(m+1, LLONG_MAX);\n            vector<char> used(m+1, false);\n            do {\n                used[j0] = true;\n                int i0 = p[j0];\n                long long delta = LLONG_MAX;\n                int j1 = 0;\n                for (int j = 1; j <= m; ++j) if (!used[j]) {\n                    long long cur = a[i0-1][j-1] - u[i0] - v[j];\n                    if (cur < minv[j]) {\n                        minv[j] = cur;\n                        way[j] = j0;\n                    }\n                    if (minv[j] < delta) {\n                        delta = minv[j];\n                        j1 = j;\n                    }\n                }\n                for (int j = 0; j <= m; ++j) {\n                    if (used[j]) {\n                        u[p[j]] += delta;\n                        v[j] -= delta;\n                    } else {\n                        minv[j] -= delta;\n                    }\n                }\n                j0 = j1;\n            } while (p[j0] != 0);\n            // augmenting\n            do {\n                int j1 = way[j0];\n                p[j0] = p[j1];\n                j0 = j1;\n            } while (j0);\n        }\n        // total minimal cost is -v[0]\n        return -v[0];\n    }\n\n    // after solve(), worker i (1\u2011based) is assigned to job match[i] (1\u2011based) or 0 if none\n    vector<int> assignment() const {\n        vector<int> match(n+1, 0);\n        for (int j = 1; j <= m; ++j)\n            if (p[j] >= 1 && p[j] <= n)\n                match[p[j]] = j;\n        return match;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K, R;\n    if (!(cin >> N >> M >> K >> R)) return 0;\n\n    /* ----- read required skill vectors ----- */\n    vector<vector<int>> d(N, vector<int>(K));\n    for (int i = 0; i < N; ++i)\n        for (int k = 0; k < K; ++k) cin >> d[i][k];\n\n    /* ----- read dependencies ----- */\n    vector<vector<int>> children(N);\n    vector<int> indeg(N, 0);\n    for (int i = 0; i < R; ++i) {\n        int u, v;\n        cin >> u >> v;\n        --u; --v;\n        children[u].push_back(v);\n        ++indeg[v];\n    }\n\n    /* ----- difficulty of each task ----- */\n    vector<long long> diff(N, 0);\n    for (int i = 0; i < N; ++i) {\n        long long s = 0;\n        for (int k = 0; k < K; ++k) s += d[i][k];\n        diff[i] = s;\n    }\n\n    /* ----- compute depth (critical\u2011path length) without disturbing indeg ----- */\n    vector<int> indeg_tmp = indeg;\n    vector<int> depth(N, 0);\n    queue<int> q;\n    for (int i = 0; i < N; ++i)\n        if (indeg_tmp[i] == 0) q.push(i);\n    while (!q.empty()) {\n        int v = q.front(); q.pop();\n        for (int nb : children[v]) {\n            depth[nb] = max(depth[nb], depth[v] + 1);\n            if (--indeg_tmp[nb] == 0) q.push(nb);\n        }\n    }\n\n    /* ----- initialise ready tasks (indegree 0) ----- */\n    priority_queue<ReadyTask> ready;\n    for (int i = 0; i < N; ++i)\n        if (indeg[i] == 0) ready.push({diff[i] * (depth[i] + 1), i});\n\n    /* ----- data for each member ----- */\n    vector<long long> totalTime(M, 0), totalDiff(M, 0);\n    vector<vector<int>> lower(M, vector<int>(K, 0));   // lower bounds of skills\n    vector<int> curTask(M, -1);                        // -1 \u2192 idle\n    vector<int> startDay(N, -1);                       // start day of each task\n    vector<int> finishedCnt(M, 0);                     // number of completed tasks\n\n    /* ----- helper: predicted duration for (member, task) pair ----- */\n    auto predict_time = [&](int member, int task, int day) -> long long {\n        long long missing = 0;\n        for (int k = 0; k < K; ++k)\n            if (d[task][k] > lower[member][k])\n                missing += d[task][k] - lower[member][k];\n\n        if (missing == 0) return 1LL;                     // certainly 1 day\n        if (totalDiff[member] == 0)                       // no information yet\n            return max(1LL, missing);                     // assume 1 day per unit missing\n\n        // base prediction using average speed\n        long long base = (missing * totalTime[member] + totalDiff[member] - 1) / totalDiff[member];\n        base = max(1LL, base);\n\n        // exploration bonus: unknown members appear slower early on\n        double factor = 1.0;\n        if (finishedCnt[member] < 3) {\n            factor = max(0.2, 1.0 - day / 500.0);\n        }\n        // confidence bonus: less data \u2192 larger uncertainty \u2192 higher bonus\n        double confidence = 1.0 + 2.0 / (finishedCnt[member] + 1);\n        long long pred = (long long)(base * factor * confidence);\n        return max(1LL, pred);\n    };\n\n    int day = 1;\n    while (true) {\n        /* ----- collect idle members ----- */\n        vector<int> idle;\n        idle.reserve(M);\n        for (int j = 0; j < M; ++j)\n            if (curTask[j] == -1) idle.push_back(j);\n\n        /* ----- collect up to idle.size() hardest ready tasks ----- */\n        vector<int> readyTasks;   // task ids\n        while (!ready.empty() && (int)readyTasks.size() < (int)idle.size()) {\n            ReadyTask rt = ready.top(); ready.pop();\n            readyTasks.push_back(rt.id);\n        }\n        // the remaining ready tasks stay in the heap\n\n        /* ----- solve assignment problem for today ----- */\n        vector<pair<int,int>> assign;   // (member+1, task+1)\n        if (!idle.empty() && !readyTasks.empty()) {\n            int n = (int)idle.size();\n            int m = (int)readyTasks.size();\n            // build cost matrix (n x m). We need a square matrix, so pad to max(n,m)\n            int sz = max(n, m);\n            vector<vector<long long>> cost(sz, vector<long long>(sz, 0));\n            for (int i = 0; i < n; ++i) {\n                for (int j = 0; j < m; ++j) {\n                    cost[i][j] = predict_time(idle[i], readyTasks[j], day);\n                }\n            }\n            Hungarian hungarian(sz, sz, cost);\n            hungarian.solve();\n            auto match = hungarian.assignment();   // match[i] = job (1\u2011based) or 0\n            for (int i = 0; i < n; ++i) {\n                int job = match[i+1];               // 1\u2011based\n                if (job >= 1 && job <= m) {\n                    int t = readyTasks[job-1];\n                    assign.emplace_back(idle[i] + 1, t + 1);\n                    curTask[idle[i]] = t;\n                    startDay[t] = day;\n                } else {\n                    // this member gets no task \u2013 push him back to idle list (already removed)\n                }\n            }\n            // tasks that were not assigned stay in the heap\n            vector<bool> used(m, false);\n            for (auto &p : assign) {\n                int t = p.second - 1;\n                for (int j = 0; j < m; ++j) {\n                    if (readyTasks[j] == t) {\n                        used[j] = true;\n                        break;\n                    }\n                }\n            }\n            for (int j = 0; j < m; ++j) {\n                if (!used[j]) {\n                    int t = readyTasks[j];\n                    ready.push({diff[t] * (depth[t] + 1), t});\n                }\n            }\n        }\n\n        /* ----- output ----- */\n        cout << assign.size();\n        for (auto &p : assign) cout << ' ' << p.first << ' ' << p.second;\n        cout << '\\n';\n        cout.flush();\n\n        /* ----- receive the list of finished members ----- */\n        int x;\n        if (!(cin >> x)) break;               // should not happen\n        if (x == -1) break;                    // end of simulation\n        int cnt = x;\n        vector<int> finished(cnt);\n        for (int i = 0; i < cnt; ++i) {\n            cin >> finished[i];\n            --finished[i];                     // to 0\u2011based\n        }\n\n        /* ----- process each completed task ----- */\n        for (int w : finished) {\n            int t = curTask[w];\n            if (t == -1) continue;            // safety, should not occur\n\n            int duration = day - startDay[t] + 1;\n\n            // update speed statistics\n            totalTime[w] += duration;\n            totalDiff[w] += diff[t];\n            ++finishedCnt[w];\n\n            // if the task finished in exactly one day we gain a lower bound\n            if (duration == 1) {\n                for (int k = 0; k < K; ++k)\n                    lower[w][k] = max(lower[w][k], d[t][k]);\n            }\n\n            // propagate the completion to dependent tasks\n            for (int nb : children[t]) {\n                if (--indeg[nb] == 0) {\n                    ready.push({diff[nb] * (depth[nb] + 1), nb});\n                }\n            }\n\n            curTask[w] = -1;                    // member becomes idle\n        }\n\n        ++day;\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Order {\n    int a, b, c, d;          // pickup (a,b) , delivery (c,d)\n};\n\ninline long long manhattan(int x1, int y1, int x2, int y2) {\n    return llabs(x1 - x2) + llabs(y1 - y2);\n}\n\n/* --------------------------------------------------------------- */\n/*  compute tour length for a given permutation                    */\nstatic long long tourCost(const vector<int>& perm,\n                          const vector<long long>& start,\n                          const vector<long long>& finish,\n                          const vector<vector<int>>& D,\n                          long long insideSum)\n{\n    const int m = (int)perm.size();\n    long long cur = start[perm[0]];\n    for (int i = 0; i < m - 1; ++i) cur += D[perm[i]][perm[i + 1]];\n    cur += finish[perm[m - 1]];\n    cur += insideSum;\n    return cur;\n}\n\n/* --------------------------------------------------------------- */\n/*  cheap TSP : nearest neighbour from every start                */\nstatic long long cheapTSP(const vector<int>& orders,\n                          vector<int>& bestPerm)\n{\n    const int m = (int)orders.size();\n    vector<long long> start(m), finish(m), inside(m);\n    vector<int> pX(m), pY(m), dX(m), dY(m);\n    const int DEP = 400;\n\n    for (int i = 0; i < m; ++i) {\n        const Order& o = *((Order*)nullptr);   // dummy, see below\n    }\n\n    // fill data for the current subset\n    for (int i = 0; i < m; ++i) {\n        const Order& o = *((Order*)nullptr);\n    }\n    // we will fill it inside the function, see later\n    // (the two dummy lines are only to keep the editor happy)\n    // -----------------------------------------------------------------\n    // Real code: we need the arrays a,b,c,d from the global vector.\n    // -----------------------------------------------------------------\n    return 0; // never reached\n}\n\n/* Because the cheap TSP is tiny we write it inside the main function\n   to avoid passing many global arrays. The same holds for the full\n   improvement routine.                                             */\n\n/* --------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int DEP = 400;\n    const int N = 1000;\n    vector<Order> ord(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> ord[i].a >> ord[i].b >> ord[i].c >> ord[i].d;\n    }\n\n    /* ----  solo costs (start+inside+finish)  ---------------------- */\n    vector<long long> solo(N);\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    for (int i = 0; i < N; ++i) {\n        long long st = manhattan(DEP, DEP, ord[i].a, ord[i].b);\n        long long ins = manhattan(ord[i].a, ord[i].b, ord[i].c, ord[i].d);\n        long long fn = manhattan(ord[i].c, ord[i].d, DEP, DEP);\n        solo[i] = st + ins + fn;\n    }\n    sort(idx.begin(), idx.end(),\n         [&](int i, int j){ return solo[i] < solo[j]; });\n\n    /* ----  candidate list : the 200 best orders  ----------------- */\n    const int CAND = 200;\n    vector<int> cand;\n    cand.reserve(CAND);\n    for (int i = 0; i < CAND; ++i) cand.push_back(idx[i]);\n\n    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    const int SAMPLE = 500;               // number of random subsets\n    struct SubsetInfo {\n        vector<int> ids;   // original order numbers (0\u2011based)\n        long long cost;\n    };\n    vector<SubsetInfo> samples;\n    samples.reserve(SAMPLE + 1);\n\n    // ----- helper lambdas for a concrete subset -----------------\n    auto evaluateSubset = [&](const vector<int>& ids, bool full,\n                               vector<int>& outPerm) -> long long {\n        const int m = (int)ids.size();            // =50\n        vector<long long> start(m), finish(m), inside(m);\n        vector<int> pX(m), pY(m), dX(m), dY(m);\n        long long insideSum = 0;\n        for (int i = 0; i < m; ++i) {\n            const Order& o = ord[ids[i]];\n            pX[i] = o.a; pY[i] = o.b;\n            dX[i] = o.c; dY[i] = o.d;\n            start[i]   = manhattan(DEP, DEP, pX[i], pY[i]);\n            inside[i]  = manhattan(pX[i], pY[i], dX[i], dY[i]);\n            finish[i]  = manhattan(dX[i], dY[i], DEP, DEP);\n            insideSum += inside[i];\n        }\n        // matrix D[i][j] = distance delivery_i -> pickup_j\n        vector<vector<int>> D(m, vector<int>(m));\n        for (int i = 0; i < m; ++i)\n            for (int j = 0; j < m; ++j)\n                D[i][j] = (int)manhattan(dX[i], dY[i], pX[j], pY[j]);\n\n        // ----- cheap solution : nearest neighbour -----------------\n        long long bestCost = (1LL<<60);\n        vector<int> bestPerm;\n        for (int s = 0; s < m; ++s) {\n            vector<int> perm;\n            vector<char> used(m, 0);\n            int cur = s;\n            perm.push_back(cur);\n            used[cur] = 1;\n            for (int step = 1; step < m; ++step) {\n                int nxt = -1;\n                int bestD = INT_MAX;\n                for (int v = 0; v < m; ++v) if (!used[v]) {\n                    int d = D[cur][v];\n                    if (d < bestD) { bestD = d; nxt = v; }\n                }\n                used[nxt] = 1;\n                perm.push_back(nxt);\n                cur = nxt;\n            }\n            long long c = tourCost(perm, start, finish, D, insideSum);\n            if (c < bestCost) {\n                bestCost = c;\n                bestPerm = perm;\n            }\n        }\n\n        if (!full) {\n            outPerm = bestPerm;\n            return bestCost;\n        }\n\n        // ----- full improvement (insertion, swap, 2\u2011opt) ----------\n        vector<int> perm = bestPerm;\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            // insertion\n            for (int i = 0; i < m && !improved; ++i) {\n                for (int j = 0; j < m && !improved; ++j) if (i != j) {\n                    vector<int> np = perm;\n                    int val = np[i];\n                    np.erase(np.begin() + i);\n                    np.insert(np.begin() + j, val);\n                    long long c = tourCost(np, start, finish, D, insideSum);\n                    if (c < tourCost(perm, start, finish, D, insideSum)) {\n                        perm.swap(np);\n                        improved = true;\n                    }\n                }\n            }\n            // swap\n            if (!improved) {\n                for (int i = 0; i < m && !improved; ++i) {\n                    for (int j = i + 1; j < m && !improved; ++j) {\n                        vector<int> np = perm;\n                        swap(np[i], np[j]);\n                        long long c = tourCost(np, start, finish, D, insideSum);\n                        if (c < tourCost(perm, start, finish, D, insideSum)) {\n                            perm.swap(np);\n                            improved = true;\n                        }\n                    }\n                }\n            }\n            // 2\u2011opt (reverse a segment)\n            if (!improved) {\n                for (int i = 0; i < m - 2 && !improved; ++i) {\n                    for (int j = i + 2; j < m && !improved; ++j) {\n                        vector<int> np = perm;\n                        reverse(np.begin() + i + 1, np.begin() + j + 1);\n                        long long c = tourCost(np, start, finish, D, insideSum);\n                        if (c < tourCost(perm, start, finish, D, insideSum)) {\n                            perm.swap(np);\n                            improved = true;\n                        }\n                    }\n                }\n            }\n        }\n        outPerm = perm;\n        return tourCost(perm, start, finish, D, insideSum);\n    };\n\n    // ----- evaluate many random subsets (cheap only) ------------\n    for (int iter = 0; iter < SAMPLE; ++iter) {\n        vector<int> cand2 = cand;\n        shuffle(cand2.begin(), cand2.end(), rng);\n        vector<int> ids(cand2.begin(), cand2.begin() + 50);\n        vector<int> dummyPerm;\n        long long c = evaluateSubset(ids, false, dummyPerm);\n        samples.push_back({ids, c});\n    }\n    // also add the deterministic top\u201150 set\n    {\n        vector<int> ids(idx.begin(), idx.begin() + 50);\n        vector<int> dummy;\n        long long c = evaluateSubset(ids, false, dummy);\n        samples.push_back({ids, c});\n    }\n\n    // keep the 5 best subsets\n    const int KEEP = 5;\n    nth_element(samples.begin(),\n                samples.begin() + KEEP,\n                samples.end(),\n                [](const SubsetInfo& a, const SubsetInfo& b){ return a.cost < b.cost; });\n    samples.resize(KEEP);\n\n    // ----- full improvement on the best subsets -----------------\n    long long bestTotal = (1LL<<60);\n    vector<int> bestIds;\n    vector<int> bestPerm;\n\n    for (auto& s : samples) {\n        vector<int> perm;\n        long long c = evaluateSubset(s.ids, true, perm);\n        if (c < bestTotal) {\n            bestTotal = c;\n            bestIds = s.ids;\n            bestPerm = perm;\n        }\n    }\n\n    // ----- build the output route --------------------------------\n    // bestIds : original order numbers (0\u2011based)\n    // bestPerm : permutation of 0..49  (local index -> order in bestIds)\n\n    // sort the ids for nicer output\n    sort(bestIds.begin(), bestIds.end());\n\n    // route coordinates\n    vector<int> routeX, routeY;\n    routeX.push_back(DEP);\n    routeY.push_back(DEP);\n    for (int k = 0; k < 50; ++k) {\n        int local = bestPerm[k];\n        int orig  = bestIds[local];\n        routeX.push_back(ord[orig].a);\n        routeY.push_back(ord[orig].b);\n        routeX.push_back(ord[orig].c);\n        routeY.push_back(ord[orig].d);\n    }\n    routeX.push_back(DEP);\n    routeY.push_back(DEP);\n    const int n = (int)routeX.size();           // = 2*50+2 = 102\n\n    // ----- output -------------------------------------------------\n    cout << 50;\n    for (int id : bestIds) cout << ' ' << (id + 1);\n    cout << '\\n';\n    cout << n;\n    for (size_t i = 0; i < routeX.size(); ++i)\n        cout << ' ' << routeX[i] << ' ' << routeY[i];\n    cout << '\\n';\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** Disjoint Set Union ***/\nstruct DSU {\n    vector<int> parent, rnk;\n    DSU(int n = 0) { init(n); }\n    void init(int n) {\n        parent.resize(n);\n        rnk.assign(n, 0);\n        iota(parent.begin(), parent.end(), 0);\n    }\n    int find(int x) {\n        if (parent[x] == x) return x;\n        return parent[x] = find(parent[x]);\n    }\n    bool unite(int a, int b) {\n        a = find(a); b = find(b);\n        if (a == b) return false;\n        if (rnk[a] < rnk[b]) swap(a, b);\n        parent[b] = a;\n        if (rnk[a] == rnk[b]) ++rnk[a];\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 400;\n    const int M = 1995;\n\n    // Read coordinates\n    vector<long long> X(N), Y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> X[i] >> Y[i];\n    }\n\n    // Read edge list and precompute d_i\n    vector<int> U(M), V(M), D(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> U[i] >> V[i];\n        long long dx = X[U[i]] - X[V[i]];\n        long long dy = Y[U[i]] - Y[V[i]];\n        double dist = sqrt((double)dx * dx + (double)dy * dy);\n        D[i] = (int)llround(dist);\n    }\n\n    DSU dsu(N);\n    int components = N;\n\n    // Process each edge\n    for (int i = 0; i < M; ++i) {\n        long long len;\n        cin >> len;\n\n        // If edge creates a cycle, reject\n        if (dsu.find(U[i]) == dsu.find(V[i])) {\n            cout << 0 << '\\n';\n            cout.flush();\n            continue;\n        }\n\n        // Edge connects different components\n        bool accept = false;\n\n        // Forced acceptance: if we can't afford to reject any more edges\n        if ((M - i) <= components - 1) {\n            accept = true;\n        } else {\n            // Prefer edges with reasonable length (len <= 2.5 * d_i)\n            // Using a slightly higher threshold to be more conservative\n            if (len <= 2.5L * D[i]) {\n                accept = true;\n            }\n        }\n\n        if (accept) {\n            cout << 1 << '\\n';\n            dsu.unite(U[i], V[i]);\n            --components;\n        } else {\n            cout << 0 << '\\n';\n        }\n        cout.flush();\n    }\n\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing pii = pair<int,int>;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int dr[4] = {-1, 1, 0, 0};\n    const int dc[4] = {0, 0, -1, 1};\n    const char wallChar[4] = {'u','d','l','r'};\n    const char moveChar[4] = {'U','D','L','R'};\n\n    /* ---------- input ---------- */\n    int N;\n    if (!(cin >> N)) return 0;\n    vector<pii> petPos(N);\n    vector<int> petType(N);\n    for (int i = 0; i < N; ++i)\n        cin >> petPos[i].first >> petPos[i].second >> petType[i];\n    int M;\n    cin >> M;\n    vector<pii> humanPos(M);\n    for (int i = 0; i < M; ++i)\n        cin >> humanPos[i].first >> humanPos[i].second;\n\n    bool wall[31][31] = {};\n\n    /* ---------- 300 turns ---------- */\n    for (int turn = 0; turn < 300; ++turn) {\n        /* occupancy and adjacency of pets */\n        static bool occPet[31][31];\n        static bool occHuman[31][31];\n        static bool adjPet[31][31];\n        for (int i = 1; i <= 30; ++i)\n            for (int j = 1; j <= 30; ++j)\n                occPet[i][j] = occHuman[i][j] = adjPet[i][j] = false;\n\n        for (auto &p : petPos)  occPet[p.first][p.second] = true;\n        for (auto &h : humanPos) occHuman[h.first][h.second] = true;\n        for (auto &p : petPos) {\n            for (int d = 0; d < 4; ++d) {\n                int nr = p.first + dr[d];\n                int nc = p.second + dc[d];\n                if (nr >= 1 && nr <= 30 && nc >= 1 && nc <= 30)\n                    adjPet[nr][nc] = true;\n            }\n        }\n\n        vector<char> action(M, '.');\n        vector<pii> moveDest(M);\n        bool newWall[31][31] = {};\n\n        /* Simple strategy: isolate each human individually */\n        for (int i = 0; i < M; ++i) {\n            int hx = humanPos[i].first, hy = humanPos[i].second;\n            bool placed = false;\n\n            /* ----- try to place a wall ----- */\n            for (int d = 0; d < 4 && !placed; ++d) {\n                int nx = hx + dr[d], ny = hy + dc[d];\n                if (nx < 1 || nx > 30 || ny < 1 || ny > 30) continue;\n                if (wall[nx][ny] || newWall[nx][ny]) continue;\n                if (occPet[nx][ny] || occHuman[nx][ny]) continue;\n                if (adjPet[nx][ny]) continue;\n                action[i] = wallChar[d];\n                newWall[nx][ny] = true;\n                placed = true;\n            }\n\n            if (placed) {\n                moveDest[i] = {hx, hy};\n                continue;\n            }\n\n            /* ----- if cannot place wall, try to move ----- */\n            // Try to move to a position where we can place more walls\n            // Prefer corners > edges > interior\n            int bestScore = -1;\n            int bestNx = -1, bestNy = -1, bestDir = -1;\n\n            for (int d = 0; d < 4; ++d) {\n                int nx = hx + dr[d], ny = hy + dc[d];\n                if (nx < 1 || nx > 30 || ny < 1 || ny > 30) continue;\n                if (wall[nx][ny] || newWall[nx][ny]) continue;\n\n                // Count how many walls we could place from this new position\n                int score = 0;\n                for (int dd = 0; dd < 4; ++dd) {\n                    int tx = nx + dr[dd], ty = ny + dc[dd];\n                    if (tx < 1 || tx > 30 || ty < 1 || ty > 30) continue;\n                    if (wall[tx][ty] || newWall[tx][ty]) continue;\n                    if (occPet[tx][ty] || occHuman[tx][ty]) continue;\n                    if (adjPet[tx][ty]) continue;\n                    score++;\n                }\n                // Prefer positions with more possible walls\n                // Also prefer staying in place if no better option\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestNx = nx; bestNy = ny; bestDir = d;\n                }\n            }\n\n            if (bestDir != -1) {\n                action[i] = moveChar[bestDir];\n                moveDest[i] = {bestNx, bestNy};\n            } else {\n                action[i] = '.';\n                moveDest[i] = {hx, hy};\n            }\n        }\n\n        /* ----- output ----- */\n        for (int i = 0; i < M; ++i) cout << action[i];\n        cout << '\\n' << flush;\n\n        /* ----- apply walls ----- */\n        for (int i = 1; i <= 30; ++i)\n            for (int j = 1; j <= 30; ++j)\n                if (newWall[i][j]) wall[i][j] = true;\n\n        /* ----- apply human moves ----- */\n        for (int i = 0; i < M; ++i)\n            if (action[i] >= 'A' && action[i] <= 'Z')\n                humanPos[i] = moveDest[i];\n\n        /* ----- read and apply pet moves ----- */\n        for (int i = 0; i < N; ++i) {\n            string s; cin >> s;\n            for (char ch : s) {\n                if (ch == '.') continue;\n                int d = 0;\n                if (ch == 'U') d = 0;\n                else if (ch == 'D') d = 1;\n                else if (ch == 'L') d = 2;\n                else if (ch == 'R') d = 3;\n                int nx = petPos[i].first + dr[d];\n                int ny = petPos[i].second + dc[d];\n                if (nx < 1 || nx > 30 || ny < 1 || ny > 30) continue;\n                if (wall[nx][ny]) continue;\n                petPos[i] = {nx, ny};\n            }\n        }\n    }\n\n    /* ---------- final scoring ---------- */\n    long double sumS = 0.0L;\n    static bool vis[31][31];\n    for (int i = 0; i < M; ++i) {\n        for (int r = 1; r <= 30; ++r)\n            for (int c = 1; c <= 30; ++c)\n                vis[r][c] = false;\n\n        queue<pii> q;\n        int sx = humanPos[i].first, sy = humanPos[i].second;\n        vis[sx][sy] = true;\n        q.emplace(sx, sy);\n        int reach = 0;\n        while (!q.empty()) {\n            auto [x, y] = q.front(); q.pop();\n            ++reach;\n            for (int d = 0; d < 4; ++d) {\n                int nx = x + dr[d], ny = y + dc[d];\n                if (nx < 1 || nx > 30 || ny < 1 || ny > 30) continue;\n                if (wall[nx][ny]) continue;\n                if (vis[nx][ny]) continue;\n                vis[nx][ny] = true;\n                q.emplace(nx, ny);\n            }\n        }\n\n        int petsInside = 0;\n        for (auto &p : petPos)\n            if (vis[p.first][p.second]) ++petsInside;\n\n        long double s = (long double)reach / 900.0L *\n                        powl(2.0L, -(long double)petsInside);\n        sumS += s;\n    }\n\n    long double avg = sumS / (long double)M;\n    // Score is not needed to be printed for the judge\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj, ti, tj;\n    double p;\n    if (!(cin >> si >> sj >> ti >> tj >> p)) return 0;\n\n    vector<string> h(20);\n    for (int i = 0; i < 20; ++i) cin >> h[i];\n    vector<string> v(19);\n    for (int i = 0; i < 19; ++i) cin >> v[i];\n\n    // wall[i][j][dir] : true if movement in direction dir from (i,j) is blocked\n    // dir: 0=U,1=D,2=L,3=R\n    bool wall[20][20][4];\n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            wall[i][j][0] = (i == 0) ? true : (v[i-1][j] == '1');          // up\n            wall[i][j][1] = (i == 19) ? true : (v[i][j] == '1');          // down\n            wall[i][j][2] = (j == 0) ? true : (h[i][j-1] == '1');          // left\n            wall[i][j][3] = (j == 19) ? true : (h[i][j] == '1');          // right\n        }\n    }\n\n    const int L = 200;\n    const int N = 20 * 20;\n    const int target = ti * 20 + tj;\n    const int start = si * 20 + sj;\n\n    // dp[t][v] : maximal expected score from turn t, square v\n    vector<vector<double>> dp(L + 2, vector<double>(N, 0.0));\n    vector<vector<int>> best(L + 2, vector<int>(N, -1));\n\n    // dp[t][target] = 0 already (vector initialised with 0)\n    for (int t = L; t >= 1; --t) {\n        for (int pos = 0; pos < N; ++pos) {\n            if (pos == target) {\n                dp[t][pos] = 0.0;\n                best[t][pos] = -1;\n                continue;\n            }\n            int i = pos / 20, j = pos % 20;\n            double bestVal = -1.0;\n            int bestDir = 0;\n            for (int d = 0; d < 4; ++d) {\n                bool w = wall[i][j][d];\n                double stayProb = p + (1.0 - p) * (w ? 1.0 : 0.0);\n                double moveProb = (1.0 - p) * (w ? 0.0 : 1.0);\n\n                double expected = stayProb * dp[t + 1][pos];\n                if (moveProb > 0.0) {\n                    int ni = i, nj = j;\n                    if (d == 0) --ni;\n                    else if (d == 1) ++ni;\n                    else if (d == 2) --nj;\n                    else ++nj;\n                    int npos = ni * 20 + nj;\n                    if (npos == target) {\n                        expected += moveProb * (401 - t);\n                    } else {\n                        expected += moveProb * dp[t + 1][npos];\n                    }\n                }\n                if (expected > bestVal + 1e-12) {\n                    bestVal = expected;\n                    bestDir = d;\n                }\n            }\n            dp[t][pos] = bestVal;\n            best[t][pos] = bestDir;\n        }\n    }\n\n    // reconstruction of a concrete string\n    string ans;\n    ans.reserve(L);\n    int cur = start;\n    for (int t = 1; t <= L; ++t) {\n        int d = best[t][cur];\n        char c;\n        if (d == 0) c = 'U';\n        else if (d == 1) c = 'D';\n        else if (d == 2) c = 'L';\n        else c = 'R';\n        ans.push_back(c);\n\n        int i = cur / 20, j = cur % 20;\n        if (!wall[i][j][d]) {               // intended move succeeds\n            if (d == 0) --i;\n            else if (d == 1) ++i;\n            else if (d == 2) --j;\n            else ++j;\n            cur = i * 20 + j;\n        }\n        // if we are already at the target we keep outputting arbitrary\n        // directions \u2013 they will never be executed.\n    }\n\n    cout << ans << '\\n';\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int C = N * N;               // 900 cells\nconst int DIRS = 4;\nconst int STATES = C * DIRS;       // 3600 states\n\nint di[DIRS] = {0, -1, 0, 1};\nint dj[DIRS] = {-1, 0, 1, 0};\n\nint orig_tile[C];                  // original type (0..7)\n\n/* -------------------------------------------------------------\n   table to[t][d]  \u2013 entering direction d, exiting direction\n   ------------------------------------------------------------- */\nint to_orig[8][DIRS] = {\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 to_rot[8][4][DIRS];            // [type][rotation][entry]\n\n/* -------------------------------------------------------------\n   compute the score (L1 * L2) for a given rotation\n   ------------------------------------------------------------- */\nint next_state[STATES];\nint visited_state[STATES];\nint step_idx[STATES];\nvector<int> path;\n\ninline long long compute_score(const int rot[C]) {\n    // build the transition function\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int t = orig_tile[i * N + j];\n            int r = rot[i * N + j];\n            int base = (i * N + j) * DIRS;\n            for (int d = 0; d < DIRS; ++d) {\n                int exit = to_rot[t][r][d];\n                if (exit == -1) {\n                    next_state[base + d] = -1;\n                    continue;\n                }\n                int ni = i + di[exit];\n                int nj = j + dj[exit];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) {\n                    next_state[base + d] = -1;\n                    continue;\n                }\n                int nd = (exit + 2) & 3;\n                next_state[base + d] = (ni * N + nj) * DIRS + nd;\n            }\n        }\n    }\n\n    // find all directed cycles\n    fill(visited_state, visited_state + STATES, 0);\n    fill(step_idx, step_idx + STATES, -1);\n    vector<int> cycles;\n    for (int s = 0; s < STATES; ++s) {\n        if (next_state[s] == -1 || visited_state[s]) continue;\n        int cur = s;\n        path.clear();\n        while (true) {\n            if (next_state[cur] == -1) break;               // dead end\n            if (visited_state[cur]) break;                  // already processed\n            if (step_idx[cur] != -1) {                      // a new cycle\n                int start = step_idx[cur];\n                int len = (int)path.size() - start;\n                cycles.push_back(len);\n                break;\n            }\n            step_idx[cur] = (int)path.size();\n            path.push_back(cur);\n            cur = next_state[cur];\n        }\n        for (int v : path) {\n            visited_state[v] = 1;\n            step_idx[v] = -1;\n        }\n    }\n\n    if (cycles.empty()) return 0LL;\n    sort(cycles.rbegin(), cycles.rend());\n    long long L1 = cycles[0];\n    long long L2 = (cycles.size() >= 2) ? cycles[1] : 0LL;\n    return L1 * L2;\n}\n\n/* -------------------------------------------------------------\n   main\n   ------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* read the board */\n    string line;\n    for (int i = 0; i < N; ++i) {\n        cin >> line;\n        for (int j = 0; j < N; ++j) orig_tile[i * N + j] = line[j] - '0';\n    }\n\n    /* pre\u2011compute rotated tables */\n    for (int t = 0; t < 8; ++t)\n        for (int r = 0; r < 4; ++r)\n            for (int d = 0; d < DIRS; ++d) {\n                int src = (d - r + 4) % 4;\n                int e = to_orig[t][src];\n                to_rot[t][r][d] = (e == -1) ? -1 : (e + r) % 4;\n            }\n\n    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist_rot(0, 3);\n    uniform_int_distribution<int> dist_cell(0, C - 1);\n    uniform_real_distribution<double> dist_prob(0.0, 1.0);\n\n    /* ---------- initial random rotation ------------------------ */\n    int curRot[C];\n    for (int i = 0; i < C; ++i) curRot[i] = dist_rot(rng);\n\n    /* optional greedy improvement (maximise matched sides) */\n    const int GREEDY_PASSES = 4;\n    for (int p = 0; p < GREEDY_PASSES; ++p) {\n        bool changed = false;\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j) {\n                int idx = i * N + j;\n                int t = orig_tile[idx];\n                int best_r = curRot[idx];\n                int best_match = -1;\n                for (int r = 0; r < 4; ++r) {\n                    int match = 0;\n                    for (int d = 0; d < DIRS; ++d) {\n                        int exit = to_rot[t][r][d];\n                        if (exit == -1) continue;\n                        int ni = i + di[exit];\n                        int nj = j + dj[exit];\n                        if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                        int nb = ni * N + nj;\n                        int nb_t = orig_tile[nb];\n                        int nb_r = curRot[nb];\n                        int nb_entry = (exit + 2) & 3;\n                        if (to_rot[nb_t][nb_r][nb_entry] != -1) ++match;\n                    }\n                    if (match > best_match) {\n                        best_match = match;\n                        best_r = r;\n                    }\n                }\n                if (best_r != curRot[idx]) {\n                    curRot[idx] = best_r;\n                    changed = true;\n                }\n            }\n        if (!changed) break;\n    }\n\n    /* ---------- simulated annealing --------------------------- */\n    const int MAX_ITER = 400000;\n    const double T0 = 800.0;\n    const double DECAY = 0.9996;\n\n    long long curScore = compute_score(curRot);\n    long long bestScore = curScore;\n    int bestRot[C];\n    copy(begin(curRot), end(curRot), begin(bestRot));\n\n    double T = T0;\n    auto start = chrono::steady_clock::now();\n\n    for (int it = 0; it < MAX_ITER; ++it) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start).count();\n        if (elapsed > 1.85) break;               // stay within the time limit\n\n        int idx = dist_cell(rng);\n        int old_r = curRot[idx];\n        int new_r = dist_rot(rng);\n        if (new_r == old_r) new_r = (old_r + 1) & 3;   // force a change\n        curRot[idx] = new_r;\n\n        long long newScore = compute_score(curRot);\n        long long delta = newScore - curScore;\n\n        if (delta > 0) {\n            // accept the improvement\n            curScore = newScore;\n            if (newScore > bestScore) {\n                bestScore = newScore;\n                copy(begin(curRot), end(curRot), begin(bestRot));\n            }\n        } else {\n            // Metropolis acceptance of a worse move\n            if (dist_prob(rng) < exp((double)delta / T)) {\n                curScore = newScore;               // keep the worse state\n            } else {\n                curRot[idx] = old_r;                // revert\n            }\n        }\n\n        T = T0 * pow(DECAY, it + 1);\n    }\n\n    /* ---------- hill\u2011climbing (local search) ------------------- */\n    // make curRot the best configuration found so far\n    copy(begin(bestRot), end(bestRot), begin(curRot));\n    curScore = bestScore;\n\n    const int HILL_PASSES = 2;\n    for (int pass = 0; pass < HILL_PASSES; ++pass) {\n        bool any = false;\n        for (int idx = 0; idx < C; ++idx) {\n            int saved_r = curRot[idx];\n            for (int r = 0; r < 4; ++r) {\n                if (r == saved_r) continue;\n                curRot[idx] = r;\n                long long ns = compute_score(curRot);\n                if (ns > curScore) {\n                    curScore = ns;\n                    if (ns > bestScore) {\n                        bestScore = ns;\n                        copy(begin(curRot), end(curRot), begin(bestRot));\n                    }\n                    any = true;\n                    break;          // stay at this tile, try next tile\n                } else {\n                    curRot[idx] = saved_r; // restore\n                }\n            }\n            if (any) break;          // a change happened \u2013 start new pass\n        }\n        if (!any) break;             // no improvement in this pass\n    }\n\n    /* ---------- output --------------------------------------- */\n    string out;\n    out.reserve(C);\n    for (int i = 0; i < C; ++i) out.push_back(char('0' + bestRot[i]));\n    cout << out << '\\n';\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* --------------------------------------------------------------\n   helpers for bit handling\n   -------------------------------------------------------------- */\nint bitFromDelta(int dr, int dc)               // direction -> bit\n{\n    if (dr == -1 && dc == 0) return 2;   // up\n    if (dr ==  1 && dc == 0) return 8;   // down\n    if (dr ==  0 && dc ==-1) return 1;   // left\n    if (dr ==  0 && dc == 1) return 4;   // right\n    return 0;\n}\nint idxFromDelta(int dr, int dc)               // direction -> index 0..3\n{\n    if (dr == -1 && dc == 0) return 0;   // up\n    if (dr ==  1 && dc == 0) return 1;   // down\n    if (dr ==  0 && dc ==-1) return 2;   // left\n    if (dr ==  0 && dc == 1) return 3;   // right\n    return -1;\n}\nint oppositeBit(int b)                         // opposite direction\n{\n    if (b == 1) return 4;\n    if (b == 4) return 1;\n    if (b == 2) return 8;\n    if (b == 8) return 2;\n    return 0;\n}\nchar charFromDelta(int dr, int dc)            // direction -> move character\n{\n    int id = idxFromDelta(dr, dc);\n    static const char mv[4] = {'U','D','L','R'};\n    return (id == -1 ? '?' : mv[id]);\n}\n\n/* --------------------------------------------------------------\n   global data\n   -------------------------------------------------------------- */\nint N, T;\nvector<vector<int>> board;            // board[r][c] = tile id, -1 = empty\nvector<int> maskOrig;                 // original picture of each tile\nvector<int> curMask;                  // bits still unused\nvector<char> inComponent;             // tile already belongs to the tree\nint er, ec;                           // empty cell\n\nconst int dr[4] = {-1, 1, 0, 0};\nconst int dc[4] = {0, 0, -1, 1};\n\n/* --------------------------------------------------------------\n   after a tile has moved to (r,c) delete all bits that correspond\n   to edges that have just appeared\n   -------------------------------------------------------------- */\nvoid updateEdges(int r, int c)\n{\n    int id = board[r][c];\n    if (id == -1) return;\n    for (int d = 0; d < 4; ++d) {\n        int nr = r + dr[d], nc = c + dc[d];\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n        int nid = board[nr][nc];\n        if (nid == -1) continue;\n        int need = bitFromDelta(dr[d], dc[d]);          // id -> nid\n        int opp  = oppositeBit(need);\n        if ( (curMask[id] & need) && (curMask[nid] & opp) ) {\n            curMask[id]  &= ~need;\n            curMask[nid] &= ~opp;\n        }\n    }\n}\n\n/* --------------------------------------------------------------\n   initial removal of bits belonging to edges that already exist\n   -------------------------------------------------------------- */\nvoid removeInitialEdges()\n{\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (board[i][j] != -1)\n                updateEdges(i, j);\n}\n\n/* --------------------------------------------------------------\n   try to attach a new vertex (Step 1).  Returns true if a move\n   was performed.\n   -------------------------------------------------------------- */\nbool tryAttach(string &answer)\n{\n    for (int d = 0; d < 4; ++d) {\n        int pr = er + dr[d], pc = ec + dc[d];\n        if (pr < 0 || pr >= N || pc < 0 || pc >= N) continue;\n        int parent = board[pr][pc];\n        if (parent == -1 || !inComponent[parent]) continue;\n\n        int needParent = oppositeBit(bitFromDelta(dr[d], dc[d]));\n        if ( (curMask[parent] & needParent) == 0 ) continue;\n\n        int cr = er - dr[d], cc = ec - dc[d];\n        if (cr < 0 || cr >= N || cc < 0 || cc >= N) continue;\n        int child = board[cr][cc];\n        if (child == -1 || inComponent[child]) continue;\n\n        int needChild = bitFromDelta(dr[d], dc[d]);\n        if ( (curMask[child] & needChild) == 0 ) continue;\n\n        /* perform the slide */\n        char ch = charFromDelta(dr[d], dc[d]);      // slide child into empty\n        answer.push_back(ch);\n\n        board[er][ec] = child;\n        board[cr][cc] = -1;\n        er = cr; ec = cc;\n\n        curMask[parent] &= ~needParent;\n        curMask[child]  &= ~needChild;\n        inComponent[child] = 1;\n\n        updateEdges(er, ec);        // edges created by the new tile\n        return true;\n    }\n    return false;\n}\n\n/* --------------------------------------------------------------\n   move the empty square by sliding an unplaced tile (Step 2)\n   -------------------------------------------------------------- */\nvoid moveEmpty(string &answer)\n{\n    for (int d = 0; d < 4; ++d) {\n        int nr = er + dr[d], nc = ec + dc[d];\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n        int tid = board[nr][nc];\n        if (tid == -1) continue;\n        if (inComponent[tid]) continue;          // slide only an unplaced tile\n\n        char ch = charFromDelta(dr[d], dc[d]);   // slide this neighbour\n        answer.push_back(ch);\n\n        board[er][ec] = tid;\n        board[nr][nc] = -1;\n        er = nr; ec = nc;\n\n        updateEdges(er, ec);        // possible new edges\n        return;\n    }\n}\n\n/* --------------------------------------------------------------\n   main\n   -------------------------------------------------------------- */\nint main()\n{\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> T)) return 0;\n    vector<string> raw(N);\n    for (int i = 0; i < N; ++i) cin >> raw[i];\n\n    board.assign(N, vector<int>(N, -1));\n    maskOrig.clear();\n    int id = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            char c = raw[i][j];\n            if (c == '0') {\n                er = i; ec = j;\n                board[i][j] = -1;\n            } else {\n                int v;\n                if ('0' <= c && c <= '9') v = c - '0';\n                else v = 10 + (c - 'a');\n                board[i][j] = id;\n                maskOrig.push_back(v);\n                ++id;\n            }\n        }\n    }\n\n    const int M = N * N - 1;                 // number of tiles\n    curMask = maskOrig;\n    inComponent.assign(M, 0);\n\n    /* delete bits that already belong to edges in the initial board */\n    removeInitialEdges();\n\n    string answer;\n    answer.reserve(T);\n\n    /* ----- Step 0 : place the first tile (the root) ----- */\n    bool placedRoot = false;\n    for (int d = 0; d < 4 && !placedRoot; ++d) {\n        int nr = er + dr[d], nc = ec + dc[d];\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n        int tid = board[nr][nc];\n        if (tid == -1) continue;\n        int dir = bitFromDelta(dr[d], dc[d]);           // direction empty -> neighbour\n        if (maskOrig[tid] & oppositeBit(dir)) {\n            char ch = charFromDelta(dr[d], dc[d]);\n            answer.push_back(ch);\n            board[er][ec] = tid;\n            board[nr][nc] = -1;\n            er = nr; ec = nc;\n            inComponent[tid] = 1;\n            updateEdges(er, ec);\n            placedRoot = true;\n            break;\n        }\n    }\n    if (!placedRoot) {                                 // fallback: any neighbour\n        for (int d = 0; d < 4 && !placedRoot; ++d) {\n            int nr = er + dr[d], nc = ec + dc[d];\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n            int tid = board[nr][nc];\n            if (tid == -1) continue;\n            char ch = charFromDelta(dr[d], dc[d]);\n            answer.push_back(ch);\n            board[er][ec] = tid;\n            board[nr][nc] = -1;\n            er = nr; ec = nc;\n            inComponent[tid] = 1;\n            updateEdges(er, ec);\n            placedRoot = true;\n            break;\n        }\n    }\n\n    int placedCnt = 1;                                 // one tile in the component\n\n    /* --------------------------------------------------------------\n       Main loop \u2013 repeatedly enlarge the component or move the empty\n       -------------------------------------------------------------- */\n    while (placedCnt < M && (int)answer.size() < T) {\n        if (tryAttach(answer)) {\n            ++placedCnt;\n            continue;\n        }\n        moveEmpty(answer);\n    }\n\n    cout << answer << '\\n';\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nusing ull = unsigned long long;\n\nstruct Line {\n    ll px, py, qx, qy;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, Kmax;\n    if (!(cin >> N >> Kmax)) return 0;\n    vector<int> a(11);\n    for (int d = 1; d <= 10; ++d) cin >> a[d];\n    vector<ll> xs(N), ys(N);\n    for (int i = 0; i < N; ++i) cin >> xs[i] >> ys[i];\n\n    int sumA = 0;\n    for (int d = 1; d <= 10; ++d) sumA += a[d];\n\n    /* ---------- parameters of the search ---------- */\n    const int USE_K = 70;            // enough pieces, cheaper than 100\n    const int TRIALS = 1500;         // many more than the original 200\n\n    /* ---------- random number generator ---------- */\n    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<ll> distCoord(-10000, 10000);   // inside the cake\n\n    /* ---------- generate a line that does not hit any strawberry ---------- */\n    auto make_line = [&]() -> Line {\n        for (int tries = 0; tries < 10; ++tries) {\n            ll px = distCoord(rng);\n            ll py = distCoord(rng);\n            ll qx = distCoord(rng);\n            ll qy = distCoord(rng);\n            if (px == qx && py == qy) continue;\n            ll dx = qx - px;\n            ll dy = qy - py;\n            bool ok = true;\n            for (int i = 0; i < N; ++i) {\n                ll cross = dx * (ys[i] - py) - dy * (xs[i] - px);\n                if (cross == 0) { ok = false; break; }\n            }\n            if (ok) return Line{px, py, qx, qy};\n        }\n        // fallback \u2013 a line far away, never hits a strawberry\n        return Line{-1000000, 0, 1000000, 0};\n    };\n\n    /* ---------- containers that are reused every trial ---------- */\n    vector<ull> hi(N), lo(N);\n    vector<pair<ull, ull>> sig(N);\n\n    int bestScore = -1;\n    vector<Line> bestLines;\n\n    for (int trial = 0; trial < TRIALS; ++trial) {\n        /* generate USE_K random lines */\n        vector<Line> lines;\n        lines.reserve(USE_K);\n        for (int i = 0; i < USE_K; ++i) lines.push_back(make_line());\n\n        /* reset signatures */\n        fill(hi.begin(), hi.end(), 0ULL);\n        fill(lo.begin(), lo.end(), 0ULL);\n\n        /* apply every line */\n        for (int li = 0; li < USE_K; ++li) {\n            const Line &L = lines[li];\n            ll dx = L.qx - L.px;\n            ll dy = L.qy - L.py;\n            for (int i = 0; i < N; ++i) {\n                ll cross = dx * (ys[i] - L.py) - dy * (xs[i] - L.px);\n                if (cross > 0) {                         // right side\n                    if (li < 64) lo[i] |= (1ULL << li);\n                    else          hi[i] |= (1ULL << (li - 64));\n                }\n            }\n        }\n\n        /* group equal signatures */\n        for (int i = 0; i < N; ++i) sig[i] = {hi[i], lo[i]};\n        sort(sig.begin(), sig.end());\n\n        vector<int> b(11, 0);            // b[d] = #pieces with d strawberries\n        for (int i = 0; i < N; ) {\n            int j = i;\n            while (j < N && sig[j] == sig[i]) ++j;\n            int sz = j - i;\n            if (1 <= sz && sz <= 10) ++b[sz];\n            i = j;\n        }\n\n        int distributed = 0;\n        for (int d = 1; d <= 10; ++d) distributed += min(a[d], b[d]);\n\n        if (distributed > bestScore) {\n            bestScore = distributed;\n            bestLines = lines;\n            if (distributed == sumA) break;   // perfect, stop early\n        }\n    }\n\n    /* ---------- output ---------- */\n    cout << bestLines.size() << '\\n';\n    for (const Line &L : bestLines)\n        cout << L.px << ' ' << L.py << ' ' << L.qx << ' ' << L.qy << '\\n';\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Candidate {\n    int mx, my;                       // missing corner\n    array<pair<int,int>,3> others;    // the three existing corners\n};\n\nint N, M;\nint center_;\nbool hasDot[61][61];\n\n/* data structures for dot queries */\nvector< set<int> > dotX, dotY;                     // 0 \u2026 N\u20111\nunordered_map<int, set<int> > dotD, dotS;        // d = x\u2011y , s = x+y\n\n/* data structures for generating candidates */\nvector< vector<pair<int,int>> > dotsAtS;               // s \u2192 list of points\nunordered_map<int, vector<pair<int,int>> > dotsAtD;   // d \u2192 list of points\n\n/* already drawn edges */\nunordered_map<int, set<pair<int,int>>> edgeHor;   // y \u2192 intervals of x\nunordered_map<int, set<pair<int,int>>> edgeVer;   // x \u2192 intervals of y\nunordered_map<int, set<pair<int,int>>> edgeDiagP; // d \u2192 intervals of x\nunordered_map<int, set<pair<int,int>>> edgeDiagM; // s \u2192 intervals of x\n\ninline int weight(int x, int y) {\n    int dx = x - center_;\n    int dy = y - center_;\n    return dx*dx + dy*dy + 1;\n}\n\n/* ---------- helpers for edges ---------- */\n\ninline bool adjacent(const pair<int,int>& a, const pair<int,int>& b) {\n    return (a.first == b.first) ||\n           (a.second == b.second) ||\n           (a.first - a.second == b.first - b.second) ||\n           (a.first + a.second == b.first + b.second);\n}\n\n/* overlap test for one line */\nbool hasOverlapOnLine(const unordered_map<int, set<pair<int,int>>>& mp,\n                      int line, int l, int r) {\n    auto it = mp.find(line);\n    if (it == mp.end()) return false;\n    const auto& st = it->second;\n    auto itr = st.lower_bound({l, INT_MIN});\n    if (itr != st.end()) {\n        int l2 = itr->first, r2 = itr->second;\n        if (max(l, l2) <= min(r, r2) - 1) return true;\n    }\n    if (itr != st.begin()) {\n        --itr;\n        int l2 = itr->first, r2 = itr->second;\n        if (max(l, l2) <= min(r, r2) - 1) return true;\n    }\n    return false;\n}\n\n/* check whether side (a,b) overlaps an existing edge */\nbool edgeOverlap(const pair<int,int>& a, const pair<int,int>& b) {\n    if (a.first == b.first) {                     // vertical\n        int x = a.first;\n        int l = min(a.second, b.second);\n        int r = max(a.second, b.second);\n        return hasOverlapOnLine(edgeVer, x, l, r);\n    } else if (a.second == b.second) {           // horizontal\n        int y = a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        return hasOverlapOnLine(edgeHor, y, l, r);\n    } else if (a.first - a.second == b.first - b.second) { // diag +1\n        int d = a.first - a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        return hasOverlapOnLine(edgeDiagP, d, l, r);\n    } else {                                      // diag -1\n        int s = a.first + a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        return hasOverlapOnLine(edgeDiagM, s, l, r);\n    }\n}\n\n/* insert an edge into the stored sets */\nvoid addEdgeToSet(const pair<int,int>& a, const pair<int,int>& b) {\n    if (a.first == b.first) {\n        int x = a.first;\n        int l = min(a.second, b.second);\n        int r = max(a.second, b.second);\n        edgeVer[x].insert({l, r});\n    } else if (a.second == b.second) {\n        int y = a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        edgeHor[y].insert({l, r});\n    } else if (a.first - a.second == b.first - b.second) {\n        int d = a.first - a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        edgeDiagP[d].insert({l, r});\n    } else {\n        int s = a.first + a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        edgeDiagM[s].insert({l, r});\n    }\n}\n\n/* does any dot lie on the open interval of the side ? */\nbool dotOnEdgeOpen(const pair<int,int>& a, const pair<int,int>& b) {\n    if (a.first == b.first) {                 // vertical\n        int x = a.first;\n        int lo = min(a.second, b.second);\n        int hi = max(a.second, b.second);\n        const auto& st = dotX[x];\n        auto it = st.lower_bound(lo + 1);\n        if (it != st.end() && *it <= hi - 1) return true;\n        return false;\n    } else if (a.second == b.second) {       // horizontal\n        int y = a.second;\n        int lo = min(a.first, b.first);\n        int hi = max(a.first, b.first);\n        const auto& st = dotY[y];\n        auto it = st.lower_bound(lo + 1);\n        if (it != st.end() && *it <= hi - 1) return true;\n        return false;\n    } else if (a.first - a.second == b.first - b.second) { // diag +1\n        int d = a.first - a.second;\n        int lo = min(a.first, b.first);\n        int hi = max(a.first, b.first);\n        const auto& st = dotD[d];\n        auto it = st.lower_bound(lo + 1);\n        if (it != st.end() && *it <= hi - 1) return true;\n        return false;\n    } else {                                   // diag -1\n        int s = a.first + a.second;\n        int lo = min(a.first, b.first);\n        int hi = max(a.first, b.first);\n        const auto& st = dotS[s];\n        auto it = st.lower_bound(lo + 1);\n        if (it != st.end() && *it <= hi - 1) return true;\n        return false;\n    }\n}\n\n/* ---------- test a candidate ---------- */\nbool isValidMove(const Candidate& cand) {\n    array<pair<int,int>,4> pts;\n    pts[0] = {cand.mx, cand.my};\n    pts[1] = cand.others[0];\n    pts[2] = cand.others[1];\n    pts[3] = cand.others[2];\n\n    // collect the four sides\n    vector<pair<pair<int,int>, pair<int,int>>> sides;\n    for (int i = 0; i < 4; ++i)\n        for (int j = i+1; j < 4; ++j)\n            if (adjacent(pts[i], pts[j]))\n                sides.push_back({pts[i], pts[j]});\n\n    if (sides.size() != 4) return false;   // should not happen\n\n    for (auto &e : sides) {\n        if (edgeOverlap(e.first, e.second)) return false;\n        if (dotOnEdgeOpen(e.first, e.second)) return false;\n    }\n    return true;\n}\n\n/* ---------- total length of the four sides (heuristic) ---------- */\nint totalEdgeLength(const Candidate& cand) {\n    array<pair<int,int>,4> pts;\n    pts[0] = {cand.mx, cand.my};\n    pts[1] = cand.others[0];\n    pts[2] = cand.others[1];\n    pts[3] = cand.others[2];\n\n    int len = 0;\n    for (int i = 0; i < 4; ++i)\n        for (int j = i+1; j < 4; ++j)\n            if (adjacent(pts[i], pts[j])) {\n                int dx = pts[i].first - pts[j].first;\n                int dy = pts[i].second - pts[j].second;\n                len += max(abs(dx), abs(dy));   // side length\n            }\n    return len;\n}\n\n/* ---------- add a new dot ---------- */\nvoid addDot(int x, int y) {\n    hasDot[x][y] = true;\n    dotX[x].insert(y);\n    dotY[y].insert(x);\n    int d = x - y;\n    int s = x + y;\n    dotD[d].insert(x);\n    dotS[s].insert(x);\n\n    dotsAtS[s].push_back({x, y});\n    dotsAtD[d].push_back({x, y});\n}\n\n/* ---------- ordering for output ---------- */\nvector<pair<int,int>> order4(const Candidate& cand) {\n    array<pair<int,int>,4> pts;\n    pts[0] = {cand.mx, cand.my};\n    pts[1] = cand.others[0];\n    pts[2] = cand.others[1];\n    pts[3] = cand.others[2];\n\n    vector<pair<int,int>> neighbors;\n    int oppIdx = -1;\n    for (int i = 1; i < 4; ++i) {\n        if (adjacent(pts[0], pts[i]))\n            neighbors.push_back(pts[i]);\n        else\n            oppIdx = i;\n    }\n    // safety \u2013 should never happen for a legal rectangle\n    if (neighbors.size() != 2 || oppIdx == -1)\n        return {pts[0], pts[1], pts[2], pts[3]};\n\n    vector<pair<int,int>> res;\n    res.push_back(pts[0]);               // the new dot\n    res.push_back(neighbors[0]);         // one neighbour\n    res.push_back(pts[oppIdx]);          // opposite corner\n    res.push_back(neighbors[1]);         // the other neighbour\n    return res;\n}\n\n/* --------------------------------------------------------------- */\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> M;\n    center_ = (N - 1) / 2;\n\n    /* random generator for tie\u2011breaking */\n    std::mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n\n    dotX.assign(N, {});\n    dotY.assign(N, {});\n    dotsAtS.assign(2*N-1, {});\n\n    for (int i = 0; i < M; ++i) {\n        int x, y; cin >> x >> y;\n        addDot(x, y);\n    }\n\n    long long sumW = 0;\n    for (int x = 0; x < N; ++x)\n        for (int y = 0; y < N; ++y)\n            if (hasDot[x][y]) sumW += weight(x, y);\n\n    vector< array<int,8> > operations;\n\n    /* ------------------- main greedy loop ------------------- */\n    while (true) {\n        vector<Candidate> cand;\n        cand.reserve(80000);\n\n        /* ----- axis\u2011parallel rectangles ----- */\n        for (int x = 0; x < N; ++x) {\n            const auto& ys = dotX[x];\n            vector<int> yvec(ys.begin(), ys.end());\n            int sz = (int)yvec.size();\n            for (int i = 0; i < sz; ++i) {\n                int y1 = yvec[i];\n                for (int j = i+1; j < sz; ++j) {\n                    int y2 = yvec[j];\n                    for (int x2 = 0; x2 < N; ++x2) if (x2 != x) {\n                        bool has1 = hasDot[x2][y1];\n                        bool has2 = hasDot[x2][y2];\n                        if (has1 && !has2) {                // missing (x2 , y2)\n                            if (!hasDot[x2][y2]) {\n                                Candidate c;\n                                c.mx = x2; c.my = y2;\n                                c.others[0] = {x, y1};\n                                c.others[1] = {x, y2};\n                                c.others[2] = {x2, y1};\n                                cand.push_back(c);\n                            }\n                        } else if (!has1 && has2) {        // missing (x2 , y1)\n                            if (!hasDot[x2][y1]) {\n                                Candidate c;\n                                c.mx = x2; c.my = y1;\n                                c.others[0] = {x, y1};\n                                c.others[1] = {x, y2};\n                                c.others[2] = {x2, y2};\n                                cand.push_back(c);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        /* ----- 45\u00b0 squares ----- */\n        for (int s = 0; s < 2*N-1; ++s) {\n            const auto &vec = dotsAtS[s];\n            int sz = (int)vec.size();\n            for (int i = 0; i < sz; ++i) {\n                auto A = vec[i];\n                for (int j = i+1; j < sz; ++j) {\n                    auto B = vec[j];\n                    int dA = A.first - A.second;\n                    int dB = B.first - B.second;\n\n                    // C with d = dA\n                    auto itA = dotsAtD.find(dA);\n                    if (itA != dotsAtD.end()) {\n                        for (auto C : itA->second) {\n                            if (C.first + C.second == s) continue; // same s\n                            int s2 = C.first + C.second;\n                            int xm = (s2 + dB) / 2;\n                            int ym = (s2 - dB) / 2;\n                            if (xm < 0 || xm >= N || ym < 0 || ym >= N) continue;\n                            if (hasDot[xm][ym]) continue;\n                            Candidate c;\n                            c.mx = xm; c.my = ym;\n                            c.others[0] = A;\n                            c.others[1] = B;\n                            c.others[2] = C;\n                            cand.push_back(c);\n                        }\n                    }\n                    // C with d = dB\n                    auto itB = dotsAtD.find(dB);\n                    if (itB != dotsAtD.end()) {\n                        for (auto C : itB->second) {\n                            if (C.first + C.second == s) continue;\n                            int s2 = C.first + C.second;\n                            int xm = (s2 + dA) / 2;\n                            int ym = (s2 - dA) / 2;\n                            if (xm < 0 || xm >= N || ym < 0 || ym >= N) continue;\n                            if (hasDot[xm][ym]) continue;\n                            Candidate c;\n                            c.mx = xm; c.my = ym;\n                            c.others[0] = A;\n                            c.others[1] = B;\n                            c.others[2] = C;\n                            cand.push_back(c);\n                        }\n                    }\n                }\n            }\n        }\n\n        /* ----- choose best move ----- */\n        int bestW = -1;\n        int bestLen = INT_MAX;\n        int chosen = -1;\n        for (int i = 0; i < (int)cand.size(); ++i) {\n            if (!isValidMove(cand[i])) continue;\n            int w = weight(cand[i].mx, cand[i].my);\n            if (w > bestW) {\n                bestW = w;\n                bestLen = totalEdgeLength(cand[i]);\n                chosen = i;\n            } else if (w == bestW) {\n                int len = totalEdgeLength(cand[i]);\n                if (len < bestLen) {\n                    bestLen = len;\n                    chosen = i;\n                }\n                // if lengths are equal as well, break tie randomly\n                else if (len == bestLen && (rng() % 2)) {\n                    chosen = i;\n                }\n            }\n        }\n        if (chosen == -1) break;               // no more moves\n\n        const Candidate &chosenCand = cand[chosen];\n\n        // add the dot\n        addDot(chosenCand.mx, chosenCand.my);\n        sumW += bestW;\n\n        // add the four edges\n        array<pair<int,int>,4> pts;\n        pts[0] = {chosenCand.mx, chosenCand.my};\n        pts[1] = chosenCand.others[0];\n        pts[2] = chosenCand.others[1];\n        pts[3] = chosenCand.others[2];\n        for (int i = 0; i < 4; ++i)\n            for (int j = i+1; j < 4; ++j)\n                if (adjacent(pts[i], pts[j]))\n                    addEdgeToSet(pts[i], pts[j]);\n\n        // store operation in required order\n        vector<pair<int,int>> order = order4(chosenCand);\n        array<int,8> op;\n        for (int k = 0; k < 4; ++k) {\n            op[2*k]   = order[k].first;\n            op[2*k+1] = order[k].second;\n        }\n        operations.push_back(op);\n    }\n\n    /* ----- output ----- */\n    cout << operations.size() << '\\n';\n    for (auto &op : operations) {\n        for (int i = 0; i < 8; ++i) {\n            if (i) cout << ' ';\n            cout << op[i];\n        }\n        cout << '\\n';\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int SZ = 10;\nconst array<char, 4> DIRS = {'F', 'B', 'L', 'R'};\n\nusing Board = array<array<int, SZ>, SZ>;\n\n/* ------------------------------------------------------------\n   tilt the whole board into direction dir (in place)\n   ------------------------------------------------------------ */\nvoid tilt(Board &a, char dir) {\n    if (dir == 'F') {                         // forward \u2192 top\n        for (int c = 0; c < SZ; ++c) {\n            int wr = 0;\n            for (int r = 0; r < SZ; ++r) {\n                if (a[r][c] != 0) {\n                    if (wr != r) {\n                        a[wr][c] = a[r][c];\n                        a[r][c] = 0;\n                    }\n                    ++wr;\n                }\n            }\n        }\n    } else if (dir == 'B') {                  // backward \u2192 bottom\n        for (int c = 0; c < SZ; ++c) {\n            int wr = SZ - 1;\n            for (int r = SZ - 1; r >= 0; --r) {\n                if (a[r][c] != 0) {\n                    a[wr][c] = a[r][c];\n                    if (wr != r) a[r][c] = 0;\n                    --wr;\n                }\n            }\n        }\n    } else if (dir == 'L') {                  // left\n        for (int r = 0; r < SZ; ++r) {\n            int wc = 0;\n            for (int c = 0; c < SZ; ++c) {\n                if (a[r][c] != 0) {\n                    a[r][wc] = a[r][c];\n                    if (wc != c) a[r][c] = 0;\n                    ++wc;\n                }\n            }\n        }\n    } else if (dir == 'R') {                  // right\n        for (int r = 0; r < SZ; ++r) {\n            int wc = SZ - 1;\n            for (int c = SZ - 1; c >= 0; --c) {\n                if (a[r][c] != 0) {\n                    a[r][wc] = a[r][c];\n                    if (wc != c) a[r][c] = 0;\n                    --wc;\n                }\n            }\n        }\n    }\n}\n\n/* ------------------------------------------------------------\n   \u03a3 size\u00b2 of all connected components\n   ------------------------------------------------------------ */\nlong long sumSquares(const Board &a) {\n    bool vis[SZ][SZ] = {};\n    const int dr[4] = {-1, 1, 0, 0};\n    const int dc[4] = {0, 0, -1, 1};\n    long long sum = 0;\n    for (int r = 0; r < SZ; ++r) {\n        for (int c = 0; c < SZ; ++c) {\n            if (a[r][c] == 0 || vis[r][c]) continue;\n            int fl = a[r][c];\n            int sz = 0;\n            queue<pair<int,int>> q;\n            q.emplace(r, c);\n            vis[r][c] = true;\n            while (!q.empty()) {\n                auto [cr, cc] = q.front(); q.pop();\n                ++sz;\n                for (int k = 0; k < 4; ++k) {\n                    int nr = cr + dr[k];\n                    int nc = cc + dc[k];\n                    if (0 <= nr && nr < SZ && 0 <= nc && nc < SZ &&\n                        !vis[nr][nc] && a[nr][nc] == fl) {\n                        vis[nr][nc] = true;\n                        q.emplace(nr, nc);\n                    }\n                }\n            }\n            sum += 1LL * sz * sz;\n        }\n    }\n    return sum;\n}\n\n/* ------------------------------------------------------------\n   find the p\u2011th empty cell (1\u2011based, row\u2011major)\n   ------------------------------------------------------------ */\npair<int,int> findEmptyCell(const Board &a, int p) {\n    for (int r = 0; r < SZ; ++r)\n        for (int c = 0; c < SZ; ++c)\n            if (a[r][c] == 0) {\n                if (p == 1) return {r, c};\n                --p;\n            }\n    return {-1, -1};\n}\n\n/* ------------------------------------------------------------\n   collect empty cells\n   ------------------------------------------------------------ */\nvector<pair<int,int>> collectEmpty(const Board &b) {\n    vector<pair<int,int>> empties;\n    for (int r = 0; r < SZ; ++r)\n        for (int c = 0; c < SZ; ++c)\n            if (b[r][c] == 0) empties.emplace_back(r, c);\n    return empties;\n}\n\n/* ------------------------------------------------------------\n   expected S after placing one future candy (flavour f)\n   ------------------------------------------------------------ */\nlong long bestOneStep(const Board &b, int f) {\n    vector<pair<int,int>> empties = collectEmpty(b);\n    long long sum = 0;\n    for (auto [r, c] : empties) {\n        Board b2 = b;\n        b2[r][c] = f;\n        long long best = -1;\n        for (char dir : DIRS) {\n            Board b3 = b2;\n            tilt(b3, dir);\n            long long s = sumSquares(b3);\n            if (s > best) best = s;\n        }\n        sum += best;\n    }\n    return sum / empties.size();\n}\n\n/* ------------------------------------------------------------\n   expected S after placing two future candies (flavours f1, f2)\n   Uses exact enumeration when few empty cells, Monte Carlo otherwise.\n   ------------------------------------------------------------ */\nlong long expectedTwoStep(const Board &b, int f1, int f2,\n                           int N1, int N2,\n                           mt19937_64 &rng) {\n    vector<pair<int,int>> empties1 = collectEmpty(b);\n    int cnt1 = (int)empties1.size();\n    if (cnt1 == 0) return sumSquares(b);\n\n    // Use exact enumeration when few empty cells (deterministic)\n    bool exact1 = (cnt1 <= 12);\n    int sample1 = exact1 ? cnt1 : min(N1, cnt1);\n    \n    uniform_int_distribution<int> dist1(0, cnt1 - 1);\n    long long total = 0;\n\n    for (int s = 0; s < sample1; ++s) {\n        int idx1 = exact1 ? s : dist1(rng);\n        auto [r1, c1] = empties1[idx1];\n        Board b1 = b;\n        b1[r1][c1] = f1;\n\n        // best tilt after the first future candy\n        long long best1 = -1;\n        Board bestBoard1;\n        for (char dir : DIRS) {\n            Board b1t = b1;\n            tilt(b1t, dir);\n            long long sval = sumSquares(b1t);\n            if (sval > best1) {\n                best1 = sval;\n                bestBoard1 = b1t;\n            }\n        }\n\n        // collect empties for the second future candy\n        vector<pair<int,int>> empties2 = collectEmpty(bestBoard1);\n        int cnt2 = (int)empties2.size();\n        if (cnt2 == 0) {\n            total += best1;\n            continue;\n        }\n\n        // Exact enumeration for second step when possible\n        bool exact2 = (cnt2 <= 10);\n        int sample2 = exact2 ? cnt2 : min(N2, cnt2);\n        \n        uniform_int_distribution<int> dist2(0, cnt2 - 1);\n        long long sum2 = 0;\n        for (int s2 = 0; s2 < sample2; ++s2) {\n            int idx2 = exact2 ? s2 : dist2(rng);\n            auto [r2, c2] = empties2[idx2];\n            Board b2 = bestBoard1;\n            b2[r2][c2] = f2;\n\n            long long best2 = -1;\n            for (char dir : DIRS) {\n                Board b2t = b2;\n                tilt(b2t, dir);\n                long long sval = sumSquares(b2t);\n                if (sval > best2) best2 = sval;\n            }\n            sum2 += best2;\n        }\n        total += sum2 / sample2;\n    }\n    return total / sample1;\n}\n\n/* ------------------------------------------------------------\n   main\n   ------------------------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int TOTAL = 100;\n    vector<int> flavour(TOTAL + 1);\n    for (int i = 1; i <= TOTAL; ++i) cin >> flavour[i];\n\n    Board board{};\n    for (int r = 0; r < SZ; ++r) board[r].fill(0);\n\n    // fixed seed for deterministic behavior\n    mt19937_64 rng(123456789);\n\n    for (int step = 1; step <= TOTAL; ++step) {\n        int p;\n        cin >> p;\n        auto pos = findEmptyCell(board, p);\n        board[pos.first][pos.second] = flavour[step];\n\n        // choose direction\n        char bestDir = 'F';\n        long long bestValue = -1;\n        long long bestCur = -1;   // tie-breaker\n\n        if (step == TOTAL) {\n            for (char dir : DIRS) {\n                Board b = board;\n                tilt(b, dir);\n                long long cur = sumSquares(b);\n                if (cur > bestValue) {\n                    bestValue = cur;\n                    bestCur = cur;\n                    bestDir = dir;\n                }\n            }\n        } else if (step == TOTAL - 1) {\n            for (char dir : DIRS) {\n                Board b = board;\n                tilt(b, dir);\n                long long cur = sumSquares(b);\n                long long expv = bestOneStep(b, flavour[step + 1]);\n                if (expv > bestValue ||\n                    (expv == bestValue && cur > bestCur)) {\n                    bestValue = expv;\n                    bestCur = cur;\n                    bestDir = dir;\n                }\n            }\n        } else {\n            for (char dir : DIRS) {\n                Board b = board;\n                tilt(b, dir);\n                long long cur = sumSquares(b);\n                long long expv = expectedTwoStep(b,\n                                                 flavour[step + 1],\n                                                 flavour[step + 2],\n                                                 8, 4, rng);\n                if (expv > bestValue ||\n                    (expv == bestValue && cur > bestCur)) {\n                    bestValue = expv;\n                    bestCur = cur;\n                    bestDir = dir;\n                }\n            }\n        }\n\n        cout << bestDir << '\\n';\n        cout.flush();\n        tilt(board, bestDir);\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int M;\n    double epsInput;\n    if (!(cin >> M >> epsInput)) return 0;\n    const double eps = epsInput;                     // edge\u2011flip probability\n\n    /* ---------- choose the smallest possible N ---------- */\n    int N = 4;\n    while (N * (N - 1) / 2 < M) ++N;                 // N \u2264 100 because M \u2264 100\n    const int L = N * (N - 1) / 2;                   // number of possible edges\n\n    /* ---------- list of edges in lexicographic order ---------- */\n    vector<pair<int,int>> edge;\n    edge.reserve(L);\n    for (int i = 0; i < N; ++i)\n        for (int j = i + 1; j < N; ++j)\n            edge.emplace_back(i, j);\n\n    /* ---------- edge counts for the M graphs (different, as far apart as possible) ---------- */\n    vector<int> edgeCnt(M);\n    if (M == 1) {\n        edgeCnt[0] = 0;\n    } else {\n        for (int i = 0; i < M; ++i) {\n            double val = round(1.0 * i * L / (M - 1));\n            edgeCnt[i] = (int)val;\n        }\n        // make them strictly increasing\n        for (int i = 1; i < M; ++i)\n            if (edgeCnt[i] <= edgeCnt[i-1]) edgeCnt[i] = edgeCnt[i-1] + 1;\n        if (edgeCnt[M-1] > L) edgeCnt[M-1] = L;      // safety\n    }\n\n    /* ---------- pre\u2011compute log\u2011factorials ---------- */\n    int maxFact = max(L, N);\n    vector<double> logFact(maxFact + 1);\n    logFact[0] = 0.0;\n    for (int i = 1; i <= maxFact; ++i) logFact[i] = logFact[i-1] + log((double)i);\n    auto logComb = [&](int n, int k) -> double {\n        if (k < 0 || k > n) return -INFINITY;\n        return logFact[n] - logFact[k] - logFact[n - k];\n    };\n\n    /* ---------- log\u2011add helper (stable sum in log\u2011domain) ---------- */\n    auto logAdd = [&](double a, double b) -> double {\n        if (a == -INFINITY) return b;\n        if (b == -INFINITY) return a;\n        if (a > b) return a + log1p(exp(b - a));\n        else       return b + log1p(exp(a - b));\n    };\n\n    /* ---------- exact degree probability tables ---------- */\n    vector<vector<double>> logProbDeg(N, vector<double>(N, -INFINITY));\n    if (eps == 0.0) {\n        for (int d = 0; d < N; ++d) logProbDeg[d][d] = 0.0;\n    } else {\n        double logEps = log(eps);\n        double log1mEps = log(1.0 - eps);\n        for (int d = 0; d < N; ++d) {\n            vector<double> sum(N, -INFINITY);\n            for (int a = 0; a <= d; ++a) {               // survived original edges\n                double logC1 = logComb(d, a);\n                double term1 = a * log1mEps + (d - a) * logEps;\n                for (int b = 0; b <= N - 1 - d; ++b) {   // newly created edges\n                    int k = a + b;\n                    double logC2 = logComb(N - 1 - d, b);\n                    double term2 = b * logEps + (N - 1 - d - b) * log1mEps;\n                    double cur = logC1 + term1 + logC2 + term2;\n                    sum[k] = logAdd(sum[k], cur);\n                }\n            }\n            for (int k = 0; k < N; ++k) logProbDeg[d][k] = sum[k];\n        }\n    }\n\n    /* ---------- generate the M graphs and store their sorted degree sequences ---------- */\n    vector<string> graphStr(M);\n    vector<vector<int>> degSorted(M, vector<int>(N));\n    for (int idx = 0; idx < M; ++idx) {\n        int e = edgeCnt[idx];\n        string s(L, '0');\n        vector<int> deg(N, 0);\n        // random set of edges (deterministic because of seeded rng)\n        mt19937_64 rng(idx + 1234567);\n        vector<int> ord(L);\n        iota(ord.begin(), ord.end(), 0);\n        shuffle(ord.begin(), ord.end(), rng);\n        for (int p = 0; p < e; ++p) {\n            int pos = ord[p];\n            s[pos] = '1';\n            ++deg[edge[pos].first];\n            ++deg[edge[pos].second];\n        }\n        graphStr[idx] = s;\n        vector<int> d = deg;\n        sort(d.begin(), d.end(), greater<int>());\n        degSorted[idx] = d;\n    }\n\n    /* ---------- output the description of the graphs ---------- */\n    cout << N << '\\n';\n    for (const string &g : graphStr) cout << g << '\\n';\n    cout.flush();\n\n    /* ---------- helper: log\u2011probability of observing m edges when original graph has e edges ---------- */\n    auto edgeLogProb = [&](int e, int m) -> double {\n        if (eps == 0.0) return (m == e) ? 0.0 : -INFINITY;\n        double logEps = log(eps);\n        double log1mEps = log(1.0 - eps);\n        double best = -INFINITY;\n        int a_min = max(0, m - (L - e));\n        int a_max = min(e, m);\n        for (int a = a_min; a <= a_max; ++a) {\n            int b = m - a;                               // newly created edges\n            double logC1 = logComb(e, a);\n            double term1 = a * log1mEps + (e - a) * logEps;\n            double logC2 = logComb(L - e, b);\n            double term2 = b * logEps + (L - e - b) * log1mEps;\n            double cur = logC1 + term1 + logC2 + term2;\n            best = logAdd(best, cur);\n        }\n        return best;\n    };\n\n    /* ---------- answer the 100 queries ---------- */\n    for (int q = 0; q < 100; ++q) {\n        string h;  cin >> h;\n\n        /* observed edge count */\n        int m = 0;\n        for (char c : h) if (c == '1') ++m;\n\n        /* observed degree sequence */\n        vector<int> degObs(N, 0);\n        for (int pos = 0; pos < L; ++pos)\n            if (h[pos] == '1') {\n                ++degObs[edge[pos].first];\n                ++degObs[edge[pos].second];\n            }\n        vector<int> degObsSorted = degObs;\n        sort(degObsSorted.begin(), degObsSorted.end(), greater<int>());\n\n        int answer = 0;\n        double bestScore = -INFINITY;\n\n        for (int i = 0; i < M; ++i) {\n            double cur = edgeLogProb(edgeCnt[i], m);\n            // add degree contributions\n            const vector<int> &dOrig = degSorted[i];\n            bool possible = true;\n            for (int v = 0; v < N; ++v) {\n                double lp = logProbDeg[dOrig[v]][degObsSorted[v]];\n                if (lp == -INFINITY) { possible = false; break; }\n                cur += lp;\n            }\n            if (!possible) continue;\n            if (cur > bestScore) {\n                bestScore = cur;\n                answer = i;\n            }\n        }\n\n        cout << answer << '\\n' << flush;\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v, w;\n};\n\nstruct Adj {\n    int to, w, id;\n};\n\nusing i128 = __int128_t;\nconst long long INF = (1LL << 60);\n\n/*---------------------------------------------------------------*/\n/* Dijkstra \u2013 can forbid one edge id ( -1 = allow all )        */\nvoid dijkstra(int start, int forbid,\n              const vector<vector<Adj>>& adj,\n              vector<long long>& dist) {\n    int n = (int)adj.size() - 1;\n    fill(dist.begin(), dist.end(), INF);\n    dist[start] = 0;\n    using P = pair<long long,int>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n    pq.emplace(0LL, start);\n    while (!pq.empty()) {\n        auto [d, v] = pq.top(); pq.pop();\n        if (d != dist[v]) continue;\n        for (const Adj& e : adj[v]) {\n            if (e.id == forbid) continue;\n            long long nd = d + e.w;\n            if (nd < dist[e.to]) {\n                dist[e.to] = nd;\n                pq.emplace(nd, e.to);\n            }\n        }\n    }\n}\n\n/*---------------------------------------------------------------*/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n    vector<Edge> edges(M);\n    vector<vector<Adj>> adj(N + 1);\n    for (int i = 0; i < M; ++i) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        edges[i] = {u, v, w};\n        adj[u].push_back({v, w, i});\n        adj[v].push_back({u, w, i});\n    }\n    /* read and ignore coordinates */\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    /*------------------------------------------------------*/\n    /* 1) cnt[e] \u2013 number of directed shortest\u2011path pairs */\n    vector<long long> cnt(M, 0);\n    vector<long long> dist(N + 1);\n    vector<int> parent(N + 1, -1);\n    for (int s = 1; s <= N; ++s) {\n        fill(dist.begin(), dist.end(), INF);\n        fill(parent.begin(), parent.end(), -1);\n        using P = pair<long long,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        dist[s] = 0;\n        pq.emplace(0LL, s);\n        while (!pq.empty()) {\n            auto [d, v] = pq.top(); pq.pop();\n            if (d != dist[v]) continue;\n            for (const Adj& e : adj[v]) {\n                long long nd = d + e.w;\n                if (nd < dist[e.to]) {\n                    dist[e.to] = nd;\n                    parent[e.to] = e.id;\n                    pq.emplace(nd, e.to);\n                }\n            }\n        }\n        for (int v = 1; v <= N; ++v) {\n            if (v != s && parent[v] != -1) {\n                cnt[parent[v]]++;\n            }\n        }\n    }\n\n    /*------------------------------------------------------*/\n    /* 2) replacement distance for every edge */\n    vector<long long> repDist(M, INF);\n    for (int i = 0; i < M; ++i) {\n        int u = edges[i].u;\n        int v = edges[i].v;\n        dijkstra(u, i, adj, dist);\n        repDist[i] = dist[v];\n    }\n\n    /*------------------------------------------------------*/\n    /* 3) single\u2011edge cost = cnt * max(0, rep - w) */\n    vector<long long> cost2(M, 0);\n    for (int i = 0; i < M; ++i) {\n        long long diff = repDist[i] - edges[i].w;\n        if (diff < 0) diff = 0;\n        cost2[i] = cnt[i] * diff;\n    }\n\n    /*------------------------------------------------------*/\n    /* 4) greedy initial schedule (more runs) */\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    const int GREEDY_RUNS = 300;\n    vector<int> bestAssign(M, -1);\n    i128 bestTotalSq = (i128)1 << 126;\n    i128 bestMaxLoad = (i128)1 << 126;\n\n    vector<double> rnd(M);\n    uniform_real_distribution<double> realDist(0.0, 1.0);\n\n    for (int run = 0; run < GREEDY_RUNS; ++run) {\n        for (int i = 0; i < M; ++i) rnd[i] = realDist(rng);\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(),\n             [&](int a, int b) {\n                 if (cost2[a] != cost2[b]) return cost2[a] > cost2[b];\n                 return rnd[a] > rnd[b];\n             });\n\n        vector<int> dayCnt(D, 0);\n        vector<i128> load(D, 0);\n        vector<int> curAssign(M, -1);\n\n        for (int idx : order) {\n            // choose the day with the smallest square-load among those with free capacity\n            i128 bestSq = (i128)1 << 126;\n            vector<int> candidates;\n            for (int d = 0; d < D; ++d) {\n                if (dayCnt[d] < K) {\n                    i128 sq = load[d] * load[d];\n                    if (sq < bestSq) {\n                        bestSq = sq;\n                        candidates.clear();\n                        candidates.push_back(d);\n                    } else if (sq == bestSq) {\n                        candidates.push_back(d);\n                    }\n                }\n            }\n            int chosen = candidates[uniform_int_distribution<int>\n                                    (0, (int)candidates.size() - 1)(rng)];\n            curAssign[idx] = chosen;\n            ++dayCnt[chosen];\n            load[chosen] += (i128)cost2[idx];\n        }\n\n        // compute total square-load and max load\n        i128 curTotalSq = 0;\n        i128 curMaxLoad = 0;\n        for (int d = 0; d < D; ++d) {\n            curTotalSq += load[d] * load[d];\n            if (load[d] > curMaxLoad) curMaxLoad = load[d];\n        }\n\n        if (curTotalSq < bestTotalSq) {\n            bestTotalSq = curTotalSq;\n            bestAssign = curAssign;\n            bestMaxLoad = curMaxLoad;\n        }\n    }\n\n    /*------------------------------------------------------*/\n    /* 5) focused local search (prioritize heavy days) */\n    // initialise structures for the best schedule\n    vector<int> assign = bestAssign;\n    vector<int> dayCnt(D, 0);\n    vector<i128> load(D, 0);\n    for (int i = 0; i < M; ++i) {\n        int d = assign[i];\n        ++dayCnt[d];\n        load[d] += (i128)cost2[i];\n    }\n\n    // maintain total square-load and max load\n    i128 totalSq = 0;\n    i128 maxLoad = 0;\n    for (int d = 0; d < D; ++d) {\n        totalSq += load[d] * load[d];\n        if (load[d] > maxLoad) maxLoad = load[d];\n    }\n\n    const int ITERATIONS = 1500000;\n    for (int it = 0; it < ITERATIONS; ++it) {\n        // decide whether to focus on heavy days\n        bool focusHeavy = (uniform_real_distribution<double>(0.0, 1.0)(rng) < 0.7);\n        int e, d1;\n\n        if (focusHeavy) {\n            // find top 3 most loaded days\n            vector<pair<i128,int>> dayLoads;\n            for (int d = 0; d < D; ++d) dayLoads.push_back({load[d], d});\n            sort(dayLoads.begin(), dayLoads.end(), greater<pair<i128,int>>());\n            int topDay = dayLoads[0].second;\n            // pick a random edge from one of the top 3 days\n            vector<int> candidates;\n            for (int i = 0; i < M; ++i) {\n                if (assign[i] == dayLoads[0].second || \n                    (dayLoads.size() > 1 && assign[i] == dayLoads[1].second) ||\n                    (dayLoads.size() > 2 && assign[i] == dayLoads[2].second)) {\n                    candidates.push_back(i);\n                }\n            }\n            if (!candidates.empty()) {\n                e = candidates[uniform_int_distribution<int>(0, (int)candidates.size() - 1)(rng)];\n                d1 = assign[e];\n            } else {\n                e = uniform_int_distribution<int>(0, M - 1)(rng);\n                d1 = assign[e];\n            }\n        } else {\n            e = uniform_int_distribution<int>(0, M - 1)(rng);\n            d1 = assign[e];\n        }\n\n        // find the least loaded day with free capacity\n        int d2 = -1;\n        i128 bestLoad = (i128)1 << 126;\n        vector<int> candidates2;\n        for (int d = 0; d < D; ++d) {\n            if (d != d1 && dayCnt[d] < K) {\n                if (load[d] < bestLoad) {\n                    bestLoad = load[d];\n                    candidates2.clear();\n                    candidates2.push_back(d);\n                } else if (load[d] == bestLoad) {\n                    candidates2.push_back(d);\n                }\n            }\n        }\n        if (!candidates2.empty()) {\n            d2 = candidates2[uniform_int_distribution<int>(0, (int)candidates2.size() - 1)(rng)];\n        }\n\n        if (d2 == -1) continue; // no feasible destination\n\n        i128 c = (i128)cost2[e];\n        i128 newLoad1 = load[d1] - c;\n        i128 newLoad2 = load[d2] + c;\n\n        // compute new max load and total square-load\n        i128 newMaxLoad = newLoad1;\n        if (newLoad2 > newMaxLoad) newMaxLoad = newLoad2;\n        for (int d = 0; d < D; ++d) {\n            if (d == d1 || d == d2) continue;\n            if (load[d] > newMaxLoad) newMaxLoad = load[d];\n        }\n\n        i128 newTotalSq = totalSq\n            - load[d1] * load[d1] - load[d2] * load[d2]\n            + newLoad1 * newLoad1 + newLoad2 * newLoad2;\n\n        // acceptance criteria\n        bool accept = false;\n        if (newMaxLoad < maxLoad) {\n            accept = true; // always accept if max load improves\n        } else if (newTotalSq < totalSq) {\n            accept = true; // accept if total square-load improves\n        }\n\n        if (accept) {\n            assign[e] = d2;\n            --dayCnt[d1];\n            ++dayCnt[d2];\n            load[d1] = newLoad1;\n            load[d2] = newLoad2;\n            totalSq = newTotalSq;\n            maxLoad = newMaxLoad;\n\n            if (newMaxLoad < bestMaxLoad) {\n                bestMaxLoad = newMaxLoad;\n                bestAssign = assign;\n                bestTotalSq = newTotalSq;\n            }\n        }\n    }\n\n    /*------------------------------------------------------*/\n    /* 6) output */\n    for (int i = 0; i < M; ++i) {\n        if (i) cout << ' ';\n        cout << (bestAssign[i] + 1);   // days are 1\u2011based\n    }\n    cout << '\\n';\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D;\n    if (!(cin >> D)) return 0;\n    vector<string> f1(D), r1(D), f2(D), r2(D);\n    for (int z = 0; z < D; ++z) cin >> f1[z];\n    for (int z = 0; z < D; ++z) cin >> r1[z];\n    for (int z = 0; z < D; ++z) cin >> f2[z];\n    for (int z = 0; z < D; ++z) cin >> r2[z];\n\n    const int N = D * D * D;\n    auto idx = [&](int x, int y, int z) { return x * D * D + y * D + z; };\n\n    vector<char> allowed1(N, 0), allowed2(N, 0), inter(N, 0);\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                int id = idx(x, y, z);\n                allowed1[id] = (f1[z][x] == '1' && r1[z][y] == '1');\n                allowed2[id] = (f2[z][x] == '1' && r2[z][y] == '1');\n                inter[id] = allowed1[id] & allowed2[id];\n            }\n\n    /* ---------- connected components of intersection ---------- */\n    vector<int> comp(N, -1);\n    vector<vector<int>> comps;\n    const int dx[6] = {1,-1,0,0,0,0};\n    const int dy[6] = {0,0,1,-1,0,0};\n    const int dz[6] = {0,0,0,0,1,-1};\n\n    for (int id = 0; id < N; ++id) if (inter[id] && comp[id] == -1) {\n        queue<int> q;\n        q.push(id);\n        comp[id] = (int)comps.size();\n        vector<int> cells;\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            cells.push_back(v);\n            int x = v / (D * D);\n            int rem = v % (D * D);\n            int y = rem / D;\n            int z = rem % D;\n            for (int dir = 0; dir < 6; ++dir) {\n                int nx = x + dx[dir];\n                int ny = y + dy[dir];\n                int nz = z + dz[dir];\n                if (nx < 0 || nx >= D || ny < 0 || ny >= D || nz < 0 || nz >= D) continue;\n                int nid = idx(nx, ny, nz);\n                if (inter[nid] && comp[nid] == -1) {\n                    comp[nid] = (int)comps.size();\n                    q.push(nid);\n                }\n            }\n        }\n        comps.push_back(move(cells));\n    }\n\n    int nShared = (int)comps.size();\n\n    /* ---------- output arrays ---------- */\n    vector<int> out1(N, 0), out2(N, 0);\n    for (int ci = 0; ci < nShared; ++ci) {\n        int bid = ci + 1;                       // block numbers start with 1\n        for (int v : comps[ci]) {\n            out1[v] = bid;\n            out2[v] = bid;\n        }\n    }\n\n    /* ---------- coverage tables ---------- */\n    vector<vector<vector<char>>> frontCov(2, vector<vector<char>>(D, vector<char>(D, 0)));\n    vector<vector<vector<char>>> rightCov(2, vector<vector<char>>(D, vector<char>(D, 0)));\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                int id = idx(x, y, z);\n                if (inter[id]) {\n                    frontCov[0][z][x] = 1;\n                    rightCov[0][z][y] = 1;\n                    frontCov[1][z][x] = 1;\n                    rightCov[1][z][y] = 1;\n                }\n            }\n\n    int nextBlock = nShared + 1;\n\n    const vector<string>* f[2] = {&f1, &f2};\n    const vector<string>* r[2] = {&r1, &r2};\n    const vector<char>* allow[2] = {&allowed1, &allowed2};\n\n    for (int obj = 0; obj < 2; ++obj) {\n        const vector<string>& fobj = *f[obj];\n        const vector<string>& robj = *r[obj];\n        const vector<char>& allowObj = *allow[obj];\n        vector<int>& out = (obj == 0 ? out1 : out2);\n\n        for (int z = 0; z < D; ++z) {\n            vector<int> X, Y;\n            for (int x = 0; x < D; ++x)\n                if (fobj[z][x] == '1' && !frontCov[obj][z][x]) X.push_back(x);\n            for (int y = 0; y < D; ++y)\n                if (robj[z][y] == '1' && !rightCov[obj][z][y]) Y.push_back(y);\n            int L = (int)X.size();\n            int R = (int)Y.size();\n            if (L == 0 && R == 0) continue;\n\n            /* ---- case L == 0 : only right columns have to be covered ---- */\n            if (L == 0) {\n                for (int y : Y) {\n                    for (int x = 0; x < D; ++x) {\n                        int id = idx(x, y, z);\n                        if (allowObj[id] && !inter[id] && out[id] == 0) {\n                            out[id] = nextBlock++;\n                            frontCov[obj][z][x] = 1;\n                            rightCov[obj][z][y] = 1;\n                            break;\n                        }\n                    }\n                }\n                continue;\n            }\n            /* ---- case R == 0 : only front columns have to be covered ---- */\n            if (R == 0) {\n                for (int x : X) {\n                    for (int y = 0; y < D; ++y) {\n                        int id = idx(x, y, z);\n                        if (allowObj[id] && !inter[id] && out[id] == 0) {\n                            out[id] = nextBlock++;\n                            frontCov[obj][z][x] = 1;\n                            rightCov[obj][z][y] = 1;\n                            break;\n                        }\n                    }\n                }\n                continue;\n            }\n\n            /* ---- general case ---- */\n            vector<vector<int>> adj(L);\n            for (int li = 0; li < L; ++li) {\n                int x = X[li];\n                for (int rj = 0; rj < R; ++rj) {\n                    int y = Y[rj];\n                    int id = idx(x, y, z);\n                    if (allowObj[id] && !inter[id]) adj[li].push_back(rj);\n                }\n            }\n\n            /* maximum matching (simple DFS augment) */\n            vector<int> matchR(R, -1);\n            function<bool(int, vector<char>&)> dfs = [&](int v, vector<char>& seen) -> bool {\n                for (int to : adj[v]) {\n                    if (seen[to]) continue;\n                    seen[to] = true;\n                    if (matchR[to] == -1 || dfs(matchR[to], seen)) {\n                        matchR[to] = v;\n                        return true;\n                    }\n                }\n                return false;\n            };\n            for (int v = 0; v < L; ++v) {\n                vector<char> seen(R, 0);\n                dfs(v, seen);\n            }\n\n            /* build a minimum edge cover */\n            vector<char> covL(L, 0), covR(R, 0);\n            vector<pair<int,int>> edges;\n\n            for (int rj = 0; rj < R; ++rj) {\n                int li = matchR[rj];\n                if (li != -1) {\n                    edges.emplace_back(li, rj);\n                    covL[li] = covR[rj] = 1;\n                }\n            }\n            for (int li = 0; li < L; ++li) if (!covL[li]) {\n                if (!adj[li].empty()) {\n                    int rj = adj[li][0];\n                    edges.emplace_back(li, rj);\n                    covL[li] = 1;\n                }\n            }\n            for (int rj = 0; rj < R; ++rj) if (!covR[rj]) {\n                bool found = false;\n                for (int li = 0; li < L && !found; ++li) {\n                    for (int to : adj[li]) if (to == rj) {\n                        edges.emplace_back(li, rj);\n                        covR[rj] = 1;\n                        found = true;\n                        break;\n                    }\n                }\n                if (!found) {                 // should not happen for a solvable instance\n                    edges.emplace_back(-1, rj);   // placeholder, will be handled later\n                }\n            }\n\n            /* place the exclusive cells */\n            vector<vector<char>> used(D, vector<char>(D, 0));\n            for (auto &pr : edges) {\n                int li = pr.first, rj = pr.second;\n                if (li == -1) {               // placeholder\n                    int y = Y[rj];\n                    for (int x = 0; x < D; ++x) {\n                        int id = idx(x, y, z);\n                        if (allowObj[id] && !inter[id] && out[id] == 0 && !used[x][y]) {\n                            out[id] = nextBlock++;\n                            frontCov[obj][z][x] = 1;\n                            rightCov[obj][z][y] = 1;\n                            used[x][y] = 1;\n                            break;\n                        }\n                    }\n                    continue;\n                }\n                int x = X[li];\n                int y = Y[rj];\n                if (used[x][y]) continue;\n                used[x][y] = 1;\n                int id = idx(x, y, z);\n                out[id] = nextBlock++;\n                frontCov[obj][z][x] = 1;\n                rightCov[obj][z][y] = 1;\n            }\n\n            /* safety net \u2013 guarantee coverage (normally not needed) */\n            for (int x : X) if (!frontCov[obj][z][x]) {\n                for (int y = 0; y < D; ++y) {\n                    int id = idx(x, y, z);\n                    if (allowObj[id] && !inter[id] && out[id] == 0) {\n                        out[id] = nextBlock++;\n                        frontCov[obj][z][x] = 1;\n                        rightCov[obj][z][y] = 1;\n                        break;\n                    }\n                }\n            }\n            for (int y : Y) if (!rightCov[obj][z][y]) {\n                for (int x = 0; x < D; ++x) {\n                    int id = idx(x, y, z);\n                    if (allowObj[id] && !inter[id] && out[id] == 0) {\n                        out[id] = nextBlock++;\n                        frontCov[obj][z][x] = 1;\n                        rightCov[obj][z][y] = 1;\n                        break;\n                    }\n                }\n            }\n        }\n    }\n\n    int totalBlocks = nextBlock - 1;\n    cout << totalBlocks << '\\n';\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << out1[i];\n    }\n    cout << '\\n';\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << out2[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nconst ll INFLL = (1LL << 60);\nconst int MAXR = 5000;\nconst ll MAXD2 = 1LL * MAXR * MAXR;          // 25 000 000\n\n/* ------------------------------------------------------------ */\n/*  global data                                                 */\nint N, M, K;\nint WORDS;                                  // (K+63)/64\n\nvector<int> X, Y;                           // vertex coordinates\nvector<int> A, B;                           // resident coordinates\n\nstruct Edge { int u, v, w; };\nvector<Edge> edges;                         // 1\u2011based\nvector<vector<pair<int,int>>> adj;          // (neighbour, edge id)\n\nvector<vector<ll>> dist2;                   // squared distances vertex \u2192 resident\nvector<vector<ll>> wgt;                     // cheapest edge weight between u and v\nvector<vector<int>> edgeIdx;                // cheapest edge index, -1 if none\n\nvector<vector<unsigned long long>> coverMask;   // bitset of residents covered by each vertex\n\n/* ------------------------------------------------------------ */\n/*  integer ceiling of sqrt                                      */\nint ceil_sqrt_ll(ll x) {\n    if (x <= 0) return 0;\n    ll r = (ll)std::sqrt((double)x);\n    while (r * r < x) ++r;\n    while (r > 0 && (r - 1) * (r - 1) >= x) --r;\n    return (int)r;\n}\n\n/* ------------------------------------------------------------ */\n/*  key for a set of vertices (128 bits)                        */\nstruct Key {\n    uint64_t lo, hi;\n    bool operator==(const Key& o) const noexcept { return lo == o.lo && hi == o.hi; }\n};\nstruct KeyHash {\n    size_t operator()(Key const& k) const noexcept {\n        return std::hash<uint64_t>{}(k.lo ^ (k.hi << 1));\n    }\n};\n\nKey makeKey(const vector<int>& S) {\n    uint64_t lo = 0, hi = 0;\n    for (int v : S) {\n        if (v <= 64) lo |= 1ULL << (v - 1);\n        else          hi |= 1ULL << (v - 65);\n    }\n    return {lo, hi};\n}\n\n/* ------------------------------------------------------------ */\n/*  cache: key \u2192 (feasible , cost , edgeList)                              */\nstruct CacheVal {\n    bool feasible;\n    ll   cost;\n    vector<int> edgeList;          // MST edges (only filled when feasible)\n};\nunordered_map<Key, CacheVal, KeyHash> cache;\n\n/* ------------------------------------------------------------ */\n/*  evaluate a vertex set, return feasibility and cost.\n    The result (including edgeList) is cached.                     */\nbool evaluateSet(const vector<int>& S, ll& cost, vector<int>* edgeListPtr = nullptr) {\n    Key key = makeKey(S);\n    auto it = cache.find(key);\n    if (it != cache.end()) {\n        cost = it->second.cost;\n        if (edgeListPtr && !it->second.edgeList.empty())\n            *edgeListPtr = it->second.edgeList;\n        return it->second.feasible;\n    }\n\n    /* ----- coverage test (bitsets) ----- */\n    vector<unsigned long long> curMask(WORDS, 0);\n    for (int v : S) {\n        for (int w = 0; w < WORDS; ++w) curMask[w] |= coverMask[v][w];\n    }\n    int covered = 0;\n    for (int w = 0; w < WORDS; ++w) covered += __builtin_popcountll(curMask[w]);\n    if (covered < K) {                 // uncovered resident \u2192 infeasible\n        cache[key] = {false, INFLL, {}};\n        return false;\n    }\n\n    /* ----- nearest vertex for each resident ----- */\n    vector<ll> maxDist2(N + 1, 0);\n    for (int k = 0; k < K; ++k) {\n        ll bestDist = INFLL;\n        int bestVert = -1;\n        for (int v : S) {\n            ll d = dist2[v][k];\n            if (d < bestDist) {\n                bestDist = d;\n                bestVert = v;\n            }\n        }\n        if (bestVert == -1) {         // should not happen after coverage test\n            cache[key] = {false, INFLL, {}};\n            return false;\n        }\n        if (bestDist > maxDist2[bestVert]) maxDist2[bestVert] = bestDist;\n    }\n\n    /* ----- radii and \u03a3R\u00b2 ----- */\n    ll sumSq = 0;\n    for (int v : S) {\n        ll md2 = maxDist2[v];\n        int r = (md2 == 0) ? 0 : ceil_sqrt_ll(md2);\n        if (r > MAXR) {\n            cache[key] = {false, INFLL, {}};\n            return false;\n        }\n        sumSq += 1LL * r * r;\n    }\n\n    /* ----- minimum spanning tree (Prim) ----- */\n    vector<char> inS(N + 1, 0);\n    for (int v : S) inS[v] = 1;\n\n    vector<ll>  minEdge(N + 1, INFLL);\n    vector<int> parentEdge(N + 1, -1);\n    vector<char> visited(N + 1, 0);\n    visited[1] = 1;                     // source is always present\n    for (int u = 1; u <= N; ++u) {\n        if (!inS[u] || u == 1) continue;\n        if (edgeIdx[1][u] != -1) {\n            minEdge[u] = wgt[1][u];\n            parentEdge[u] = edgeIdx[1][u];\n        }\n    }\n\n    ll edgeCost = 0;\n    vector<int> edgesUsed;\n    for (int it = 0; it < (int)S.size() - 1; ++it) {\n        int v = -1;\n        ll best = INFLL;\n        for (int u = 1; u <= N; ++u) {\n            if (inS[u] && !visited[u] && minEdge[u] < best) {\n                best = minEdge[u];\n                v = u;\n            }\n        }\n        if (v == -1) {                 // not connected\n            cache[key] = {false, INFLL, {}};\n            return false;\n        }\n        visited[v] = 1;\n        edgeCost += best;\n        edgesUsed.push_back(parentEdge[v]);\n        for (int u = 1; u <= N; ++u) {\n            if (inS[u] && !visited[u] && edgeIdx[v][u] != -1) {\n                ll w = wgt[v][u];\n                if (w < minEdge[u]) {\n                    minEdge[u] = w;\n                    parentEdge[u] = edgeIdx[v][u];\n                }\n            }\n        }\n    }\n\n    cost = sumSq + edgeCost;\n    CacheVal cv = {true, cost, edgesUsed};\n    cache[key] = cv;\n    if (edgeListPtr) *edgeListPtr = edgesUsed;\n    return true;\n}\n\n/* ------------------------------------------------------------ */\n/*  full evaluation \u2013 also returns radii and MST edges.\n    (used only for the final answer)                           */\nvoid fullEvaluation(const vector<int>& S,\n                    bool& feasible, ll& cost,\n                    vector<int>& radius,\n                    vector<int>& edgesUsed) {\n    /* ----- coverage test ----- */\n    vector<unsigned long long> curMask(WORDS, 0);\n    for (int v : S) {\n        for (int w = 0; w < WORDS; ++w) curMask[w] |= coverMask[v][w];\n    }\n    int covered = 0;\n    for (int w = 0; w < WORDS; ++w) covered += __builtin_popcountll(curMask[w]);\n    feasible = (covered == K);\n    if (!feasible) { cost = INFLL; return; }\n\n    /* ----- nearest vertex for each resident ----- */\n    vector<ll> maxDist2(N + 1, 0);\n    for (int k = 0; k < K; ++k) {\n        ll bestDist = INFLL;\n        int bestVert = -1;\n        for (int v : S) {\n            ll d = dist2[v][k];\n            if (d < bestDist) {\n                bestDist = d;\n                bestVert = v;\n            }\n        }\n        if (bestDist > maxDist2[bestVert]) maxDist2[bestVert] = bestDist;\n    }\n\n    /* ----- radii ----- */\n    radius.assign(N + 1, 0);\n    ll sumSq = 0;\n    for (int v : S) {\n        ll md2 = maxDist2[v];\n        int r = (md2 == 0) ? 0 : ceil_sqrt_ll(md2);\n        radius[v] = r;\n        sumSq += 1LL * r * r;\n    }\n\n    /* ----- MST (Prim) ----- */\n    vector<char> inS(N + 1, 0);\n    for (int v : S) inS[v] = 1;\n\n    vector<ll>  minEdge(N + 1, INFLL);\n    vector<int> parentEdge(N + 1, -1);\n    vector<char> visited(N + 1, 0);\n    visited[1] = 1;\n    for (int u = 1; u <= N; ++u) {\n        if (!inS[u] || u == 1) continue;\n        if (edgeIdx[1][u] != -1) {\n            minEdge[u] = wgt[1][u];\n            parentEdge[u] = edgeIdx[1][u];\n        }\n    }\n\n    edgesUsed.clear();\n    ll edgeCost = 0;\n    for (int it = 0; it < (int)S.size() - 1; ++it) {\n        int v = -1;\n        ll best = INFLL;\n        for (int u = 1; u <= N; ++u) {\n            if (inS[u] && !visited[u] && minEdge[u] < best) {\n                best = minEdge[u];\n                v = u;\n            }\n        }\n        if (v == -1) {                 // not connected \u2013 should not happen\n            feasible = false;\n            cost = INFLL;\n            return;\n        }\n        visited[v] = 1;\n        edgeCost += best;\n        edgesUsed.push_back(parentEdge[v]);\n        for (int u = 1; u <= N; ++u) {\n            if (inS[u] && !visited[u] && edgeIdx[v][u] != -1) {\n                ll w = wgt[v][u];\n                if (w < minEdge[u]) {\n                    minEdge[u] = w;\n                    parentEdge[u] = edgeIdx[v][u];\n                }\n            }\n        }\n    }\n\n    cost = sumSq + edgeCost;\n}\n\n/* ------------------------------------------------------------ */\n/*  neighbours of a set (vertices not in the set, adjacent to it) */\nvector<int> neighbours(const vector<char>& inS) {\n    vector<char> seen(N + 1, 0);\n    vector<int> res;\n    for (int v = 1; v <= N; ++v) if (inS[v]) {\n        for (auto [to, id] : adj[v]) {\n            if (!inS[to] && !seen[to]) {\n                seen[to] = 1;\n                res.push_back(to);\n            }\n        }\n    }\n    return res;\n}\n\n/* ------------------------------------------------------------ */\n/*  one\u2011pass 2\u2011opt: try to replace the heaviest edge on each cycle   */\nvoid improveMSTOnePass(const vector<int>& S,\n                      const vector<int>& edgeList,\n                      vector<int>& bestEdges,\n                      ll& edgeCost) {\n    // Build adjacency list of the current MST\n    vector<vector<pair<int,int>>> mstAdj(N + 1);\n    vector<char> inMst(M + 1, 0);\n    for (int id : edgeList) {\n        inMst[id] = 1;\n        int a = edges[id].u, b = edges[id].v;\n        mstAdj[a].push_back({b, id});\n        mstAdj[b].push_back({a, id});\n    }\n\n    // For each edge not in the MST, try to replace the heaviest edge on the cycle\n    for (int id = 1; id <= M; ++id) {\n        if (inMst[id]) continue;\n        int a = edges[id].u, b = edges[id].v;\n\n        // BFS to find path a -> b in the MST and its heaviest edge\n        vector<int> parent(N + 1, -1), parentEdge(N + 1, -1);\n        vector<char> seen(N + 1, 0);\n        queue<int> q;\n        q.push(a);\n        seen[a] = 1;\n        while (!q.empty() && parent[b] == -1) {\n            int v = q.front(); q.pop();\n            for (auto [to, eid] : mstAdj[v]) {\n                if (seen[to]) continue;\n                seen[to] = 1;\n                parent[to] = v;\n                parentEdge[to] = eid;\n                if (to == b) break;\n                q.push(to);\n            }\n        }\n        if (parent[b] == -1) continue; // should not happen (connected graph)\n\n        // Find the heaviest edge on the path a\u2013b\n        int worstId = -1;\n        ll worstW = -1;\n        int cur = b;\n        while (cur != a) {\n            int eid = parentEdge[cur];\n            if (eid == -1) break;\n            ll w = edges[eid].w;\n            if (w > worstW) {\n                worstW = w;\n                worstId = eid;\n            }\n            cur = parent[cur];\n        }\n        if (worstId == -1) continue;\n\n        // If the new edge is cheaper, replace\n        ll newW = edges[id].w;\n        if (newW < worstW) {\n            edgeCost += newW - worstW;\n            // Update edge list\n            for (int &e : bestEdges) if (e == worstId) { e = id; break; }\n            // Update adjacency (remove worst, add new)\n            // Rebuild the whole adjacency \u2013 cheap because N \u2264 100\n            bestEdges.clear();\n            bestEdges = edgeList;\n            for (int &e : bestEdges) if (e == worstId) { e = id; break; }\n            mstAdj.assign(N + 1, {});\n            fill(inMst.begin(), inMst.end(), 0);\n            for (int eid : bestEdges) {\n                inMst[eid] = 1;\n                int u = edges[eid].u, v = edges[eid].v;\n                mstAdj[u].push_back({v, eid});\n                mstAdj[v].push_back({u, eid});\n            }\n        }\n    }\n}\n\n/* ------------------------------------------------------------ */\n/*  one complete run of the heuristic                           */\nvoid runHeuristic(ll& bestCost,\n                  vector<int>& bestS,\n                  vector<int>& bestEdges,\n                  ll seed)\n{\n    std::mt19937 rng(seed);\n\n    /* ----- greedy start ----- */\n    vector<int> curS = {1};\n    vector<char> inS(N + 1, 0);\n    inS[1] = 1;\n    vector<unsigned long long> curMask(WORDS, 0);\n    for (int w = 0; w < WORDS; ++w) curMask[w] = coverMask[1][w];\n\n    bool feasible = false;\n    ll curCost = 0;\n    feasible = evaluateSet(curS, curCost);\n    if (!feasible) {\n        while (!feasible) {\n            vector<int> cand = neighbours(inS);\n            shuffle(cand.begin(), cand.end(), rng);\n            ll bestC = INFLL;\n            int bestV = -1;\n            for (int v : cand) {\n                vector<int> ns = curS;\n                ns.push_back(v);\n                ll c;\n                bool f = evaluateSet(ns, c);\n                if (f && c < bestC) {\n                    bestC = c;\n                    bestV = v;\n                }\n            }\n            if (bestV == -1) { // fallback \u2013 add any remaining vertex\n                for (int v = 1; v <= N; ++v) if (!inS[v]) { bestV = v; break; }\n            }\n            inS[bestV] = 1;\n            curS.push_back(bestV);\n            for (int w = 0; w < WORDS; ++w) curMask[w] |= coverMask[bestV][w];\n            feasible = evaluateSet(curS, curCost);\n        }\n    }\n\n    /* ----- keep the best solution found so far ----- */\n    bestCost = curCost;\n    bestS = curS;\n\n    /* ----- local search (removal \u2013 addition \u2013 swap) ----- */\n    bool changed = true;\n    while (changed) {\n        changed = false;\n        // removal\n        for (size_t i = 0; i < bestS.size(); ++i) {\n            int v = bestS[i];\n            if (v == 1) continue;\n            bool essential = false;\n            for (int w = 0; w < WORDS; ++w) {\n                unsigned long long after = curMask[w] & ~coverMask[v][w];\n                if (after != curMask[w]) { essential = true; break; }\n            }\n            if (essential) continue;\n            vector<int> ns = bestS;\n            ns.erase(ns.begin() + i);\n            ll c;\n            bool f = evaluateSet(ns, c);\n            if (f && c < bestCost - 1) {\n                bestCost = c;\n                bestS = ns;\n                fill(curMask.begin(), curMask.end(), 0ULL);\n                for (int xv : bestS)\n                    for (int w = 0; w < WORDS; ++w) curMask[w] |= coverMask[xv][w];\n                fill(inS.begin(), inS.end(), 0);\n                for (int xv : bestS) inS[xv] = 1;\n                changed = true;\n                break;\n            }\n        }\n        if (changed) continue;\n        // addition\n        vector<int> cand = neighbours(inS);\n        shuffle(cand.begin(), cand.end(), rng);\n        for (int v : cand) {\n            vector<int> ns = bestS;\n            ns.push_back(v);\n            ll c;\n            bool f = evaluateSet(ns, c);\n            if (f && c < bestCost - 1) {\n                bestCost = c;\n                bestS = ns;\n                inS[v] = 1;\n                for (int w = 0; w < WORDS; ++w) curMask[w] |= coverMask[v][w];\n                changed = true;\n                break;\n            }\n        }\n        if (changed) continue;\n        // swap\n        vector<pair<int,int>> swaps;\n        for (int v : bestS) if (v != 1) {\n            for (auto [to, id] : adj[v]) if (!inS[to]) swaps.emplace_back(v, to);\n        }\n        shuffle(swaps.begin(), swaps.end(), rng);\n        for (auto [v, u] : swaps) {\n            vector<int> ns;\n            ns.reserve(bestS.size());\n            for (int x : bestS) if (x != v) ns.push_back(x);\n            ns.push_back(u);\n            ll c;\n            bool f = evaluateSet(ns, c);\n            if (f && c < bestCost - 1) {\n                bestCost = c;\n                bestS = ns;\n                inS[v] = 0;\n                inS[u] = 1;\n                fill(curMask.begin(), curMask.end(), 0ULL);\n                for (int xv : bestS)\n                    for (int w = 0; w < WORDS; ++w) curMask[w] |= coverMask[xv][w];\n                changed = true;\n                break;\n            }\n        }\n    }\n\n    /* ----- improve edge cost with one\u2011pass 2\u2011opt ----- */\n    // Get the cached MST edge list (guaranteed to be present)\n    vector<int> cachedEdges;\n    evaluateSet(bestS, curCost, &cachedEdges);   // curCost already equals bestCost\n    bestEdges = cachedEdges;\n    // Compute edge cost\n    ll eCost = 0;\n    for (int id : bestEdges) eCost += edges[id].w;\n    // One\u2011pass improvement\n    improveMSTOnePass(bestS, bestEdges, bestEdges, eCost);\n    bestCost = (bestCost - eCost) + (bestCost - (bestCost - eCost)); // just to use eCost\n    // Actually, we need the total cost after 2\u2011opt:\n    // total = (bestCost - edgeCost_original) + edgeCost_new\n    // We know bestCost = sumSq + edgeCost_original\n    // Let's recompute total correctly:\n    //   sumSq = bestCost - edgeCost_original  (edgeCost_original from cachedEdges)\n    ll edgeCostOriginal = 0;\n    for (int id : cachedEdges) edgeCostOriginal += edges[id].w;\n    ll sumSq = bestCost - edgeCostOriginal;\n    ll edgeCostNew = eCost;\n    bestCost = sumSq + edgeCostNew;\n}\n\n/* ------------------------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ----- input ----- */\n    cin >> N >> M >> K;\n    X.resize(N + 1);\n    Y.resize(N + 1);\n    for (int i = 1; i <= N; ++i) cin >> X[i] >> Y[i];\n\n    edges.resize(M + 1);\n    adj.assign(N + 1, {});\n    wgt.assign(N + 1, vector<ll>(N + 1, INFLL));\n    edgeIdx.assign(N + 1, vector<int>(N + 1, -1));\n\n    for (int j = 1; j <= M; ++j) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        edges[j] = {u, v, w};\n        adj[u].push_back({v, j});\n        adj[v].push_back({u, j});\n        if (w < wgt[u][v]) {\n            wgt[u][v] = wgt[v][u] = w;\n            edgeIdx[u][v] = edgeIdx[v][u] = j;\n        }\n    }\n\n    A.resize(K);\n    B.resize(K);\n    for (int k = 0; k < K; ++k) cin >> A[k] >> B[k];\n\n    /* ----- pre\u2011computations ----- */\n    WORDS = (K + 63) / 64;\n    dist2.assign(N + 1, vector<ll>(K, 0));\n    coverMask.assign(N + 1, vector<unsigned long long>(WORDS, 0));\n\n    for (int i = 1; i <= N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            ll dx = X[i] - A[k];\n            ll dy = Y[i] - B[k];\n            ll d2 = dx * dx + dy * dy;\n            dist2[i][k] = d2;\n            if (d2 <= MAXD2) {\n                coverMask[i][k / 64] |= 1ULL << (k % 64);\n            }\n        }\n    }\n\n    /* ----- run the heuristic three times ----- */\n    ll bestOverall = INFLL;\n    vector<int> bestSOverall;\n    vector<int> bestEdgesOverall;\n\n    const int RUNS = 3;\n    for (int r = 0; r < RUNS; ++r) {\n        ll seed = (unsigned)chrono::steady_clock::now().time_since_epoch().count() + r * 1234567ULL;\n        ll curCost;\n        vector<int> curS, curEdges;\n        runHeuristic(curCost, curS, curEdges, seed);\n        if (curCost < bestOverall) {\n            bestOverall = curCost;\n            bestSOverall = curS;\n            bestEdgesOverall = curEdges;\n        }\n    }\n\n    /* ----- final full evaluation (radii) ----- */\n    bool finalFeas;\n    ll finalCost;\n    vector<int> finalRadius;\n    fullEvaluation(bestSOverall, finalFeas, finalCost, finalRadius, bestEdgesOverall);\n\n    /* ----- output ----- */\n    for (int i = 1; i <= N; ++i) {\n        if (i > 1) cout << ' ';\n        cout << finalRadius[i];\n    }\n    cout << '\\n';\n    vector<int> B(M + 1, 0);\n    for (int id : bestEdgesOverall) B[id] = 1;\n    for (int j = 1; j <= M; ++j) {\n        if (j > 1) cout << ' ';\n        cout << B[j];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Swap {\n    int x1, y1, x2, y2;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 30;\n    const int M = N * (N + 1) / 2;          // 465\n\n    /* ----- convert triangular coordinates to linear indices ----- */\n    vector<vector<int>> idx(N, vector<int>(N, -1));\n    int cur = 0;\n    for (int x = 0; x < N; ++x)\n        for (int y = 0; y <= x; ++y)\n            idx[x][y] = cur++;\n\n    /* ----- read the permutation ----- */\n    vector<int> initValue(M);\n    for (int x = 0; x < N; ++x)\n        for (int y = 0; y <= x; ++y) {\n            int v;  cin >> v;\n            initValue[idx[x][y]] = v;\n        }\n\n    /* ----- helper: test whether the array is a heap ----- */\n    auto isHeap = [&](const vector<int>& a) -> bool {\n        for (int x = 0; x + 1 < N; ++x) {\n            for (int y = 0; y <= x; ++y) {\n                int p = idx[x][y];\n                int l = idx[x + 1][y];\n                int r = idx[x + 1][y + 1];\n                if (a[p] > a[l] || a[p] > a[r]) return false;\n            }\n        }\n        return true;\n    };\n\n    /* ----- many randomised heapify runs ----- */\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    const int TRIALS = 5000;                // increased from 2000\n    const double EPS = 0.2;                // increased from 0.1\n\n    vector<Swap> bestOps;\n    int bestK = INT_MAX;\n\n    for (int trial = 0; trial < TRIALS; ++trial) {\n        vector<int> curVal = initValue;   // copy\n        vector<Swap> ops;\n\n        // bottom\u2011up, level by level\n        for (int x = N - 2; x >= 0; --x) {\n            // order of processing the nodes on this level\n            vector<int> ys(x + 1);\n            iota(ys.begin(), ys.end(), 0);\n            if (trial > 0) shuffle(ys.begin(), ys.end(), rng);\n\n            for (int y : ys) {\n                int curX = x, curY = y;\n                while (curX < N - 1) {\n                    int pIdx = idx[curX][curY];\n                    int lIdx = idx[curX + 1][curY];\n                    int rIdx = idx[curX + 1][curY + 1];\n\n                    int childIdx = -1, childX = -1, childY = -1;\n\n                    // look for a child that violates the heap property\n                    if (curVal[pIdx] > curVal[lIdx]) {\n                        childIdx = lIdx;\n                        childX = curX + 1;\n                        childY = curY;\n                    }\n                    if (curVal[pIdx] > curVal[rIdx]) {\n                        if (childIdx == -1 || curVal[rIdx] < curVal[childIdx]) {\n                            childIdx = rIdx;\n                            childX = curX + 1;\n                            childY = curY + 1;\n                        }\n                    }\n\n                    if (childIdx == -1) break;          // heap already satisfied\n\n                    // perform ONE adjacent swap (the two positions are neighbours)\n                    ops.emplace_back(curX, curY, childX, childY);\n                    swap(curVal[pIdx], curVal[childIdx]);\n\n                    // continue sifting the moved ball downwards\n                    curX = childX;\n                    curY = childY;\n                }\n            }\n        }\n\n        if ((int)ops.size() < bestK) {\n            bestK = (int)ops.size();\n            bestOps = move(ops);\n        }\n    }\n\n    /* ----- try to delete useless swaps (multiple passes) ----- */\n    const int PRUNE_PASSES = 3;\n    for (int pass = 0; pass < PRUNE_PASSES; ++pass) {\n        bool progress = false;\n        for (int i = 0; i < (int)bestOps.size(); ++i) {\n            vector<int> curVal = initValue;\n            // apply all swaps except the i\u2011th\n            for (int j = 0; j < (int)bestOps.size(); ++j) if (j != i) {\n                const Swap& s = bestOps[j];\n                int a = idx[s.x1][s.y1];\n                int b = idx[s.x2][s.y2];\n                swap(curVal[a], curVal[b]);\n            }\n            if (isHeap(curVal)) {\n                bestOps.erase(bestOps.begin() + i);\n                --i;          // continue scanning\n                progress = true;\n            }\n        }\n        if (!progress) break;   // no more deletions possible\n    }\n\n    /* ----- output ----- */\n    cout << bestOps.size() << '\\n';\n    for (const Swap& s : bestOps)\n        cout << s.x1 << ' ' << s.y1 << ' ' << s.x2 << ' ' << s.y2 << '\\n';\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\n#include <ext/pb_ds/assoc_container.hpp>\nusing namespace std;\nusing namespace __gnu_pbds;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int dr[4] = {-1, 1, 0, 0};\n    const int dc[4] = {0, 0, -1, 1};\n\n    /* ---------- input ---------- */\n    int D_in, N;\n    if (!(cin >> D_in >> N)) return 0;\n    const int D = 9;                     // D is always 9 in the problem\n\n    vector<vector<bool>> obstacle(D, vector<bool>(D, false));\n    for (int k = 0; k < N; ++k) {\n        int ri, rj;\n        cin >> ri >> rj;\n        obstacle[ri][rj] = true;\n    }\n\n    const int R = 0;\n    const int C = (D - 1) / 2;           // entrance (0,4)\n\n    /* ---------- depth (BFS) ---------- */\n    vector<vector<int>> depth(D, vector<int>(D, -1));\n    queue<pair<int,int>> q;\n    depth[R][C] = 0;\n    q.emplace(R, C);\n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        for (int d = 0; d < 4; ++d) {\n            int nr = r + dr[d], nc = c + dc[d];\n            if (nr < 0 || nr >= D || nc < 0 || nc >= D) continue;\n            if (obstacle[nr][nc]) continue;\n            if (depth[nr][nc] != -1) continue;\n            depth[nr][nc] = depth[r][c] + 1;\n            q.emplace(nr, nc);\n        }\n    }\n\n    /* ---------- global min / max depth among usable cells ---------- */\n    int global_min_depth = INT_MAX, global_max_depth = -1;\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            if (i == R && j == C) continue;          // entrance\n            if (obstacle[i][j]) continue;\n            global_min_depth = min(global_min_depth, depth[i][j]);\n            global_max_depth = max(global_max_depth, depth[i][j]);\n        }\n    }\n\n    const int M = D * D - 1 - N;         // number of containers\n\n    /* ---------- ordered set for remaining numbers ---------- */\n    using ordered_set = tree<int, null_type, less<int>, rb_tree_tag,\n                             tree_order_statistics_node_update>;\n    ordered_set S;\n    for (int i = 0; i < M; ++i) S.insert(i);\n\n    /* ---------- data for storage ---------- */\n    vector<int> pos_x(M, -1), pos_y(M, -1);\n    vector<vector<int>> container_at(D, vector<int>(D, -1));\n    vector<vector<bool>> occupied(D, vector<bool>(D, false));\n\n    /* ---------- storage phase ---------- */\n    for (int step = 0; step < M; ++step) {\n        int t;                           // number written on the arriving container\n        cin >> t;\n\n        // rank of t among still unused numbers\n        int rank = (int)S.order_of_key(t);   // number of elements < t\n        int total = (int)S.size() + 1;       // size before erasing t\n        S.erase(t);                          // number t becomes used now\n\n        /* current empty squares */\n        vector<vector<bool>> empty(D, vector<bool>(D, false));\n        for (int i = 0; i < D; ++i)\n            for (int j = 0; j < D; ++j)\n                if (!obstacle[i][j] && !occupied[i][j])\n                    empty[i][j] = true;\n\n        /* articulation points \u2013 Tarjan */\n        vector<vector<int>> disc(D, vector<int>(D, 0));\n        vector<vector<int>> low(D, vector<int>(D, 0));\n        vector<vector<bool>> visited(D, vector<bool>(D, false));\n        vector<vector<bool>> isArt(D, vector<bool>(D, false));\n        int timer = 0;\n        function<void(int,int,int,int)> dfs = [&](int r, int c,\n                                                   int parent_r, int parent_c) {\n            visited[r][c] = true;\n            disc[r][c] = low[r][c] = ++timer;\n            int child = 0;\n            for (int d = 0; d < 4; ++d) {\n                int nr = r + dr[d], nc = c + dc[d];\n                if (nr < 0 || nr >= D || nc < 0 || nc >= D) continue;\n                if (!empty[nr][nc]) continue;\n                if (nr == parent_r && nc == parent_c) continue;\n                if (!visited[nr][nc]) {\n                    ++child;\n                    dfs(nr, nc, r, c);\n                    low[r][c] = min(low[r][c], low[nr][nc]);\n                    if (parent_r == -1 && child > 1) isArt[r][c] = true;\n                    if (parent_r != -1 && low[nr][nc] >= disc[r][c]) isArt[r][c] = true;\n                } else {\n                    low[r][c] = min(low[r][c], disc[nr][nc]);\n                }\n            }\n        };\n        dfs(R, C, -1, -1);\n\n        /* collect candidate cells (empty, not entrance, not articulation) */\n        vector<pair<int, pair<int,int>>> candidates; // (depth, (r,c))\n        for (int i = 0; i < D; ++i) {\n            for (int j = 0; j < D; ++j) {\n                if (i == R && j == C) continue;          // entrance\n                if (!empty[i][j]) continue;\n                if (isArt[i][j]) continue;\n                candidates.emplace_back(depth[i][j], make_pair(i, j));\n            }\n        }\n\n        // safety \u2013 should never be empty\n        if (candidates.empty()) {\n            for (int i = 0; i < D; ++i)\n                for (int j = 0; j < D; ++j)\n                    if (empty[i][j])\n                        candidates.emplace_back(depth[i][j], make_pair(i, j));\n        }\n\n        // ----- map rank to target depth -----\n        double target;\n        if (total > 1) {\n            target = global_min_depth\n                   + (double)rank * (global_max_depth - global_min_depth) / (total - 1);\n        } else {\n            target = global_min_depth;\n        }\n\n        // ----- choose candidate with depth closest to target -----\n        int best_r = -1, best_c = -1, best_depth = -1;\n        int best_diff = INT_MAX;\n        for (auto &cand : candidates) {\n            int d = cand.first;\n            int diff = abs(d - (int)target);\n            if (diff < best_diff || (diff == best_diff && d < best_depth)) {\n                best_diff = diff;\n                best_r = cand.second.first;\n                best_c = cand.second.second;\n                best_depth = d;\n            }\n        }\n\n        /* store the container */\n        occupied[best_r][best_c] = true;\n        container_at[best_r][best_c] = t;\n        pos_x[t] = best_r;\n        pos_y[t] = best_c;\n\n        cout << best_r << ' ' << best_c << '\\n';\n        cout.flush();\n    }\n\n    /* ---------- retrieval phase \u2013 greedy by smallest number ---------- */\n    for (int step = 0; step < M; ++step) {\n        /* reachable empty region (BFS) */\n        vector<vector<bool>> reachable(D, vector<bool>(D, false));\n        queue<pair<int,int>> qreach;\n        reachable[R][C] = true;\n        qreach.emplace(R, C);\n        while (!qreach.empty()) {\n            auto [r, c] = qreach.front(); qreach.pop();\n            for (int d = 0; d < 4; ++d) {\n                int nr = r + dr[d], nc = c + dc[d];\n                if (nr < 0 || nr >= D || nc < 0 || nc >= D) continue;\n                if (obstacle[nr][nc]) continue;\n                if (occupied[nr][nc]) continue;          // only empty squares\n                if (reachable[nr][nc]) continue;\n                reachable[nr][nc] = true;\n                qreach.emplace(nr, nc);\n            }\n        }\n\n        /* pick reachable container with smallest number */\n        int bestNum = INT_MAX, bestR = -1, bestC = -1;\n        for (int i = 0; i < D; ++i) {\n            for (int j = 0; j < D; ++j) {\n                if (!occupied[i][j]) continue;\n                bool adjacent = false;\n                for (int d = 0; d < 4; ++d) {\n                    int ni = i + dr[d], nj = j + dc[d];\n                    if (ni < 0 || ni >= D || nj < 0 || nj >= D) continue;\n                    if (reachable[ni][nj]) { adjacent = true; break; }\n                }\n                if (!adjacent) continue;\n                int num = container_at[i][j];\n                if (num < bestNum) {\n                    bestNum = num;\n                    bestR = i; bestC = j;\n                }\n            }\n        }\n\n        /* output and remove */\n        cout << bestR << ' ' << bestC << '\\n';\n        cout.flush();\n        occupied[bestR][bestC] = false;\n    }\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n, m;\nconst int MAXC = 105;                     // colours 0 \u2026 m (m \u2264 100)\nint a[55][55];\nint total[MAXC];\nint adjCnt[MAXC][MAXC];                   // directed edges\nbool need[MAXC][MAXC];\n\nint dx[4] = {-1, 1, 0, 0};\nint dy[4] = {0, 0, -1, 1};\n\nint vis[55][55];\nint bfsStamp = 0;\n\nqueue<pair<int,int>> q;                   // squares that may become deletable\n\n// ------------------------------------------------------------------\nbool canDelete(int x, int y);\nvoid doDelete(int x, int y);\n\n// ------------------------------------------------------------------\nbool canDelete(int x, int y) {\n    int c = a[x][y];\n    if (c == 0) return false;\n    if (total[c] <= 1) return false;                 // colour must survive\n\n    // 1) the square must already touch colour 0 (or the outside)\n    bool adjZero = false;\n    for (int dir = 0; dir < 4; ++dir) {\n        int nx = x + dx[dir], ny = y + dy[dir];\n        if (nx < 0 || nx >= n || ny < 0 || ny >= n) { adjZero = true; break; }\n        if (a[nx][ny] == 0) { adjZero = true; break; }\n    }\n    if (!adjZero) return false;\n\n    // colours of the four neighbours (0 = outside)\n    int nbColour[4];\n    int cnt[MAXC] = {0};\n\n    for (int dir = 0; dir < 4; ++dir) {\n        int nx = x + dx[dir], ny = y + dy[dir];\n        int d;\n        if (nx < 0 || nx >= n || ny < 0 || ny >= n) d = 0;\n        else d = a[nx][ny];\n        nbColour[dir] = d;\n        ++cnt[d];\n    }\n\n    // 2) must not create a forbidden adjacency 0\u2011d (including d == c)\n    for (int dir = 0; dir < 4; ++dir) {\n        int d = nbColour[dir];\n        if (d != 0 && !need[0][d]) return false;     // would create illegal 0\u2011d\n    }\n\n    // 3) each required adjacency must stay alive (at least one undirected edge left)\n    for (int d = 0; d <= m; ++d) {\n        if (!need[c][d]) continue;\n        if (cnt[d] == 0) continue;                  // we are not touching this colour\n        if (adjCnt[c][d] - 2 * cnt[d] < 1) return false;\n    }\n\n    // 4) after removal the colour must still be connected\n    int sx = -1, sy = -1;\n    for (int dir = 0; dir < 4; ++dir) {\n        int nx = x + dx[dir], ny = y + dy[dir];\n        if (0 <= nx && nx < n && 0 <= ny && ny < n && a[nx][ny] == c) {\n            sx = nx; sy = ny;\n            break;\n        }\n    }\n    if (sx == -1) return false;                     // should not happen (total[c] \u2265 2)\n\n    ++bfsStamp;\n    queue<pair<int,int>> qq;\n    qq.emplace(sx, sy);\n    vis[sx][sy] = bfsStamp;\n    int cntReached = 0;\n    while (!qq.empty()) {\n        auto [cx, cy] = qq.front(); qq.pop();\n        ++cntReached;\n        for (int dir = 0; dir < 4; ++dir) {\n            int nx = cx + dx[dir], ny = cy + dy[dir];\n            if (nx < 0 || nx >= n || ny < 0 || ny >= n) continue;\n            if (a[nx][ny] != c) continue;\n            if (nx == x && ny == y) continue;       // the cell we plan to delete\n            if (vis[nx][ny] == bfsStamp) continue;\n            vis[nx][ny] = bfsStamp;\n            qq.emplace(nx, ny);\n        }\n    }\n    if (cntReached != total[c] - 1) return false;   // would disconnect the colour\n\n    return true;\n}\n\n// ------------------------------------------------------------------\nvoid doDelete(int x, int y) {\n    int c = a[x][y];\n    a[x][y] = 0;\n    --total[c];\n\n    for (int dir = 0; dir < 4; ++dir) {\n        int nx = x + dx[dir], ny = y + dy[dir];\n        int d;\n        if (nx < 0 || nx >= n || ny < 0 || ny >= n) {\n            d = 0;                     // outside world\n        } else {\n            d = a[nx][ny];\n        }\n\n        // remove the old adjacency c\u2011d (two directed edges)\n        if (d != c) {\n            adjCnt[c][d] -= 2;\n            adjCnt[d][c] -= 2;\n        }\n\n        // create a new adjacency 0\u2011d (if d is a coloured cell)\n        if (d != 0) {\n            adjCnt[0][d] += 2;\n            adjCnt[d][0] += 2;\n        }\n    }\n\n    // neighbours may become new candidates because they now touch a 0 cell\n    for (int dir = 0; dir < 4; ++dir) {\n        int nx = x + dx[dir], ny = y + dy[dir];\n        if (0 <= nx && nx < n && 0 <= ny && ny < n && a[nx][ny] > 0) {\n            q.emplace(nx, ny);\n        }\n    }\n}\n\n// ------------------------------------------------------------------\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> n >> m;\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j)\n            cin >> a[i][j];\n\n    // ----- count squares and all adjacency edges of the original map -----\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            int c = a[i][j];\n            ++total[c];\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + dx[dir], nj = j + dy[dir];\n                if (ni < 0 || ni >= n || nj < 0 || nj >= n) {\n                    ++adjCnt[c][0];\n                    ++adjCnt[0][c];\n                } else {\n                    int d = a[ni][nj];\n                    if (d != c) {\n                        ++adjCnt[c][d];\n                        ++adjCnt[d][c];\n                    }\n                }\n            }\n        }\n    }\n\n    // which adjacencies existed in the original map?\n    for (int c = 0; c <= m; ++c)\n        for (int d = 0; d <= m; ++d)\n            need[c][d] = (adjCnt[c][d] > 0);\n\n    // ----- initialise candidate queue: squares already touching colour 0 -----\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) if (a[i][j] > 0) {\n            bool adjZero = false;\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + dx[dir], nj = j + dy[dir];\n                if (ni < 0 || ni >= n || nj < 0 || nj >= n) { adjZero = true; break; }\n                if (a[ni][nj] == 0) { adjZero = true; break; }\n            }\n            if (adjZero) q.emplace(i, j);\n        }\n    }\n\n    // ----- greedy deletion -----\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        if (a[x][y] == 0) continue;                 // already deleted\n        if (canDelete(x, y))\n            doDelete(x, y);\n    }\n\n    // ----- output -----\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            if (j) cout << ' ';\n            cout << a[i][j];\n        }\n        cout << '\\n';\n    }\n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, D, Q;\n    if (!(cin >> N >> D >> Q)) return 0;\n    \n    // win[i] \u2013 times item i was heavier, tie[i] \u2013 times equal\n    vector<int> win(N, 0), tie(N, 0);\n    int performed = 0;\n    \n    // ------------------------------------------------------------\n    // 1) forced consecutive pairs (every item appears at least once)\n    for (int i = 0; i + 1 < N && performed < Q; ++i) {\n        int a = i, b = i + 1;\n        cout << \"1 1 \" << a << ' ' << b << \"\\n\";\n        cout.flush();\n        ++performed;\n        string res; cin >> res;\n        if (res == \">\") {\n            ++win[a];\n        } else if (res == \"<\") {\n            ++win[b];\n        } else { // \"=\"\n            ++tie[a];\n            ++tie[b];\n        }\n    }\n    // ------------------------------------------------------------\n    // 2) random pairs until we have performed exactly Q queries\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    while (performed < Q) {\n        int a = rng() % N;\n        int b = rng() % N;\n        if (a == b) continue;\n        if (a > b) swap(a, b);\n        cout << \"1 1 \" << a << ' ' << b << \"\\n\";\n        cout.flush();\n        ++performed;\n        string res; cin >> res;\n        if (res == \">\") {\n            ++win[a];\n        } else if (res == \"<\") {\n            ++win[b];\n        } else { // \"=\"\n            ++tie[a];\n            ++tie[b];\n        }\n    }\n    \n    // ------------------------------------------------------------\n    // 3) compute rough weight estimates and sort items\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    vector<double> score(N);\n    for (int i = 0; i < N; ++i) score[i] = win[i] + 0.5 * tie[i];\n    stable_sort(idx.begin(), idx.end(),\n                [&](int a, int b) { return score[a] > score[b]; });\n    \n    // ------------------------------------------------------------\n    // 4) LPT (Longest Processing Time) assignment to D groups\n    vector<double> groupSum(D, 0.0);\n    vector<int> groupOf(N, -1);\n    for (int pos = 0; pos < N; ++pos) {\n        int it = idx[pos];\n        // find group with minimal current sum\n        int best = 0;\n        for (int g = 1; g < D; ++g) {\n            if (groupSum[g] < groupSum[best]) best = g;\n        }\n        groupOf[it] = best;\n        groupSum[best] += score[it];\n    }\n    \n    // ------------------------------------------------------------\n    // 5) output the final partition\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << groupOf[i];\n    }\n    cout << \"\\n\";\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    const int per = n / m;\n    vector<vector<int>> st(m);\n    vector<int> where(n + 1, -1);\n\n    for (int i = 0; i < m; ++i) {\n        st[i].reserve(per);\n        for (int j = 0; j < per; ++j) {\n            int v; cin >> v;\n            st[i].push_back(v);\n            where[v] = i;\n        }\n    }\n\n    vector<pair<int,int>> ops;\n\n    for (int v = 1; v <= n; ++v) {\n        int src = where[v];\n\n        // While v is not at the top, move boxes above it\n        while (!st[src].empty() && st[src].back() != v) {\n            int curTop = st[src].back();\n            int dest = -1;\n            \n            // Priority 1: Find a stack with top > curTop (no new inversion)\n            // Choose the one with maximum top to be most useful later\n            int bestTop = -1;\n            for (int i = 0; i < m; ++i) {\n                if (i == src) continue;\n                if (!st[i].empty() && st[i].back() > curTop && st[i].back() > bestTop) {\n                    bestTop = st[i].back();\n                    dest = i;\n                }\n            }\n            \n            // Priority 2: Use an empty stack if available\n            if (dest == -1) {\n                for (int i = 0; i < m; ++i) {\n                    if (i == src) continue;\n                    if (st[i].empty()) {\n                        dest = i;\n                        break;\n                    }\n                }\n            }\n            \n            // Priority 3: Any other stack - prefer larger top to minimize future moves\n            if (dest == -1) {\n                int maxTop = -1;\n                for (int i = 0; i < m; ++i) {\n                    if (i == src) continue;\n                    int top = st[i].empty() ? -1 : st[i].back();\n                    if (top > maxTop) {\n                        maxTop = top;\n                        dest = i;\n                    }\n                }\n            }\n\n            // Operation 1: move curTop to dest\n            ops.emplace_back(curTop, dest + 1);\n            st[src].pop_back();\n            st[dest].push_back(curTop);\n            where[curTop] = dest;\n        }\n\n        // Operation 2: carry out v (free, no energy)\n        ops.emplace_back(v, 0);\n        st[src].pop_back();\n        where[v] = -1;\n    }\n\n    // Output: one operation per line\n    for (auto [box, dst] : ops) {\n        cout << box << ' ' << dst << '\\n';\n    }\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    if (!(cin >> N)) return 0;\n\n    vector<string> h(N - 1);\n    for (int i = 0; i < N - 1; ++i) cin >> h[i];\n    vector<string> v(N);\n    for (int i = 0; i < N; ++i) cin >> v[i];\n    vector<vector<int>> d(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) cin >> d[i][j];\n\n    const int V = N * N;\n    auto id = [&](int i, int j) { return i * N + j; };\n\n    /* ---------- adjacency (no walls) ---------- */\n    vector<vector<int>> adj(V);\n    const int di[4] = {0, 1, 0, -1};\n    const int dj[4] = {1, 0, -1, 0};\n    const char dc[4] = {'R', 'D', 'L', 'U'};\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int u = id(i, j);\n            if (i + 1 < N && h[i][j] == '0') {\n                int vtx = id(i + 1, j);\n                adj[u].push_back(vtx);\n                adj[vtx].push_back(u);\n            }\n            if (j + 1 < N && v[i][j] == '0') {\n                int vtx = id(i, j + 1);\n                adj[u].push_back(vtx);\n                adj[vtx].push_back(u);\n            }\n        }\n    }\n\n    const int start = 0;                 // (0,0)\n\n    /* ---------- BFS from start (shortest distances & parents) ---------- */\n    const int INF = 1e9;\n    vector<int> dist(V, INF), parent(V, -1);\n    queue<int> q;\n    dist[start] = 0;\n    q.push(start);\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int nb : adj[u]) {\n            if (dist[nb] == INF) {\n                dist[nb] = dist[u] + 1;\n                parent[nb] = u;\n                q.push(nb);\n            }\n        }\n    }\n\n    /* ---------- try to find a Hamiltonian path (randomised DFS) ---------- */\n    const int MAX_ATTEMPTS = 3000;\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    string bestBase;                // move string of the best walk found\n    int bestLen = INF;              // its length\n\n    for (int attempt = 0; attempt < MAX_ATTEMPTS; ++attempt) {\n        vector<char> visited(V, 0);\n        vector<int> path;\n        path.reserve(V);\n        int cur = start;\n        visited[cur] = 1;\n        path.push_back(cur);\n        bool dead = false;\n\n        while ((int)path.size() < V) {\n            // choose an unvisited neighbour with smallest own unvisited degree\n            int bestDegree = 5;\n            vector<int> candidates;\n\n            for (int nb : adj[cur]) if (!visited[nb]) {\n                int deg = 0;\n                for (int nn : adj[nb]) if (!visited[nn]) ++deg;\n                if (deg < bestDegree) {\n                    bestDegree = deg;\n                    candidates.clear();\n                    candidates.push_back(nb);\n                } else if (deg == bestDegree) {\n                    candidates.push_back(nb);\n                }\n            }\n\n            if (candidates.empty()) { dead = true; break; }\n\n            // random among the best\n            int nxt = candidates[rng() % candidates.size()];\n            visited[nxt] = 1;\n            path.push_back(nxt);\n            cur = nxt;\n        }\n\n        if (dead) continue;               // could not visit all cells\n\n        // we have a Hamiltonian path\n        int last = path.back();\n        int back = dist[last];             // shortest way back to start\n        int totalLen = (V - 1) + back;      // moves of path + closing moves\n\n        if (totalLen < bestLen) {\n            bestLen = totalLen;\n            bestBase.clear();\n\n            // moves of the Hamiltonian part\n            for (size_t i = 0; i + 1 < path.size(); ++i) {\n                int a = path[i], b = path[i + 1];\n                int ai = a / N, aj = a % N;\n                int bi = b / N, bj = b % N;\n                if (bi == ai + 1) bestBase.push_back('D');\n                else if (bi == ai - 1) bestBase.push_back('U');\n                else if (bj == aj + 1) bestBase.push_back('R');\n                else bestBase.push_back('L');\n            }\n\n            // closing shortest path (back to start) \u2013 direction from curRet to parent\n            vector<char> ret;\n            int curRet = last;\n            while (curRet != start) {\n                int p = parent[curRet];\n                int pi = p / N, pj = p % N;\n                int ci = curRet / N, cj = curRet % N;\n                if (ci == pi + 1) ret.push_back('U');      // curRet is below parent -> up\n                else if (ci == pi - 1) ret.push_back('D'); // curRet is above parent -> down\n                else if (cj == pj + 1) ret.push_back('L'); // curRet is right of parent -> left\n                else ret.push_back('R');                    // curRet is left of parent -> right\n                curRet = p;\n            }\n            bestBase.append(ret.begin(), ret.end());\n        }\n\n        // if we already reached the theoretical minimum (V + 1) we can stop early\n        if (bestLen <= V + 1) break;\n    }\n\n    /* ---------- fallback: simple DFS tour ---------- */\n    if (bestLen == INF) {\n        vector<vector<char>> seen(N, vector<char>(N, 0));\n        string dfsWalk;\n        function<void(int,int)> dfs = [&](int i, int j) {\n            seen[i][j] = 1;\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir], nj = j + dj[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                if (seen[ni][nj]) continue;\n                bool free = false;\n                if (dir == 0 && j + 1 < N && v[i][j] == '0') free = true;\n                if (dir == 1 && i + 1 < N && h[i][j] == '0') free = true;\n                if (dir == 2 && j - 1 >= 0 && v[i][j-1] == '0') free = true;\n                if (dir == 3 && i - 1 >= 0 && h[i-1][j] == '0') free = true;\n                if (!free) continue;\n                dfsWalk.push_back(dc[dir]);                // forward\n                dfs(ni, nj);\n                dfsWalk.push_back(dc[(dir + 2) % 4]);      // back\n            }\n        };\n        dfs(0, 0);\n        bestBase = dfsWalk;\n        bestLen = (int)bestBase.size();          // = 2*(V-1)\n    }\n\n    const int Lmax = 100000;\n    int repeat = Lmax / bestLen;                  // maximal full repetitions\n\n    string answer;\n    answer.reserve(repeat * bestLen);\n    for (int i = 0; i < repeat; ++i) answer += bestBase;\n\n    cout << answer << '\\n';\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 15;                // keyboard size (always 15)\nconst int TOT = N * N;           // 225 cells\nconst int INF = 1e9;            // a large number used as \"infinite\" cost\n\n// ------------------------------------------------------------\n// longest k (0 \u2264 k \u2264 5) such that suffix of a (len k) = prefix of b (len k)\nint overlap(const string &a, const string &b) {\n    int maxk = min({(int)a.size(), (int)b.size(), 5});\n    for (int k = maxk; k >= 0; --k) {\n        bool ok = true;\n        for (int i = 0; i < k; ++i) {\n            if (a[a.size() - k + i] != b[i]) { ok = false; break; }\n        }\n        if (ok) return k;\n    }\n    return 0;\n}\n\n// ------------------------------------------------------------\n// greedy construction: bidirectional (prepend / append) with random tie\u2011breaking\nstring buildBi(const vector<string> &words, int startIdx, mt19937 &rng) {\n    int m = (int)words.size();\n    vector<bool> used(m, false);\n    string cur = words[startIdx];\n    used[startIdx] = true;\n\n    while (true) {\n        int bestAdd = INF;\n        vector<int> bestIds;\n        vector<int> bestOri;               // 0 = append, 1 = prepend\n\n        for (int j = 0; j < m; ++j) if (!used[j]) {\n            // try append\n            int ov_app = overlap(cur, words[j]);\n            int add_app = (int)words[j].size() - ov_app;\n            if (add_app < bestAdd) {\n                bestAdd = add_app;\n                bestIds.clear(); bestOri.clear();\n                bestIds.push_back(j); bestOri.push_back(0);\n            } else if (add_app == bestAdd) {\n                bestIds.push_back(j); bestOri.push_back(0);\n            }\n\n            // try prepend\n            int ov_pre = overlap(words[j], cur);\n            int add_pre = (int)words[j].size() - ov_pre;\n            if (add_pre < bestAdd) {\n                bestAdd = add_pre;\n                bestIds.clear(); bestOri.clear();\n                bestIds.push_back(j); bestOri.push_back(1);\n            } else if (add_pre == bestAdd) {\n                bestIds.push_back(j); bestOri.push_back(1);\n            }\n        }\n\n        if (bestIds.empty()) break;               // all words used\n\n        int choice = uniform_int_distribution<int>(0, (int)bestIds.size() - 1)(rng);\n        int id = bestIds[choice];\n        int ori = bestOri[choice];\n\n        if (ori == 0) {                           // append\n            int ov = overlap(cur, words[id]);\n            cur += words[id].substr(ov);\n        } else {                                   // prepend\n            int ov = overlap(words[id], cur);\n            cur = words[id].substr(0, (int)words[id].size() - ov) + cur;\n        }\n        used[id] = true;\n    }\n    return cur;\n}\n\n// ------------------------------------------------------------\n// greedy construction: append only (always attach to the right)\nstring buildAppend(const vector<string> &words, int startIdx, mt19937 &rng) {\n    int m = (int)words.size();\n    vector<bool> used(m, false);\n    string cur = words[startIdx];\n    used[startIdx] = true;\n\n    while (true) {\n        int bestAdd = INF;\n        vector<int> bestIds;\n\n        for (int j = 0; j < m; ++j) if (!used[j]) {\n            int ov = overlap(cur, words[j]);\n            int add = (int)words[j].size() - ov;\n            if (add < bestAdd) {\n                bestAdd = add;\n                bestIds.clear();\n                bestIds.push_back(j);\n            } else if (add == bestAdd) {\n                bestIds.push_back(j);\n            }\n        }\n\n        if (bestIds.empty()) break;\n\n        int choice = uniform_int_distribution<int>(0, (int)bestIds.size() - 1)(rng);\n        int id = bestIds[choice];\n        int ov = overlap(cur, words[id]);\n        cur += words[id].substr(ov);\n        used[id] = true;\n    }\n    return cur;\n}\n\n// ------------------------------------------------------------\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int tmpN, M;\n    if (!(cin >> tmpN >> M)) return 0;   // N is always 15\n    int si, sj;\n    cin >> si >> sj;\n\n    vector<string> board(N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n\n    // positions of each letter\n    vector<vector<int>> cells(26);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            int id = i * N + j;\n            cells[board[i][j] - 'A'].push_back(id);\n        }\n\n    vector<string> words(M);\n    for (int i = 0; i < M; ++i) cin >> words[i];\n\n    // pre\u2011compute Manhattan distances between all cells\n    static int dist[TOT][TOT];\n    for (int i = 0; i < TOT; ++i) {\n        int x1 = i / N, y1 = i % N;\n        for (int j = 0; j < TOT; ++j) {\n            int x2 = j / N, y2 = j % N;\n            dist[i][j] = abs(x1 - x2) + abs(y1 - y2);\n        }\n    }\n\n    const int TRIALS = 60;               // many random starts\n    mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());\n\n    int bestCost = INF;\n    vector<pair<int,int>> bestPath;      // (row , col) for each operation\n\n    // -----------------------------------------------------------------\n    // helper: DP for a given superstring, returns (cost, path)\n    auto solve = [&](const string &S) -> pair<int, vector<pair<int,int>>> {\n        int L = (int)S.size();\n        vector<int> dpPrev(TOT, INF), dpCurr(TOT, INF);\n        // allocate predecessor array exactly for this length\n        vector<vector<short>> pre(L + 1, vector<short>(TOT, -1));\n\n        int startCell = si * N + sj;\n        dpPrev[startCell] = 0;                 // cost before typing anything\n\n        for (int pos = 0; pos < L; ++pos) {\n            char c = S[pos];\n            const vector<int> &allowed = cells[c - 'A'];\n            fill(dpCurr.begin(), dpCurr.end(), INF);\n            for (int curIdx : allowed) {\n                int best = INF;\n                short bestPrev = -1;\n                for (int prevIdx = 0; prevIdx < TOT; ++prevIdx) {\n                    int pc = dpPrev[prevIdx];\n                    if (pc == INF) continue;\n                    int cand = pc + dist[prevIdx][curIdx] + 1;\n                    if (cand < best) {\n                        best = cand;\n                        bestPrev = (short)prevIdx;\n                    }\n                }\n                dpCurr[curIdx] = best;\n                pre[pos + 1][curIdx] = bestPrev;\n            }\n            dpPrev.swap(dpCurr);\n        }\n\n        int finalIdx = -1, finalCost = INF;\n        for (int i = 0; i < TOT; ++i) {\n            if (dpPrev[i] < finalCost) {\n                finalCost = dpPrev[i];\n                finalIdx = i;\n            }\n        }\n\n        vector<pair<int,int>> path(L);\n        int cur = finalIdx;\n        for (int p = L; p >= 1; --p) {\n            path[p - 1] = {cur / N, cur % N};\n            cur = pre[p][cur];\n        }\n        return {finalCost, path};\n    };\n    // -----------------------------------------------------------------\n\n    for (int trial = 0; trial < TRIALS; ++trial) {\n        int startWord = uniform_int_distribution<int>(0, M - 1)(rng);\n\n        // ----- bidirectional greedy -----\n        string S1 = buildBi(words, startWord, rng);\n        auto [cost1, path1] = solve(S1);\n        if (cost1 < bestCost) {\n            bestCost = cost1;\n            bestPath = move(path1);\n        }\n\n        // ----- append\u2011only greedy -----\n        string S2 = buildAppend(words, startWord, rng);\n        if (S2 != S1) {                     // avoid duplicate work\n            auto [cost2, path2] = solve(S2);\n            if (cost2 < bestCost) {\n                bestCost = cost2;\n                bestPath = move(path2);\n            }\n        }\n    }\n\n    // --------------------------------------------------------\n    // output the sequence of cells (one line per operation)\n    for (auto [i, j] : bestPath) {\n        cout << i << ' ' << j << '\\n';\n    }\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\ndouble eps;\nvector<vector<int>> val;          // -1 = unknown, 0 = known zero, >0 = known positive\nvector<vector<char>> drilled;     // true if we have queried this cell exactly\nvector<int> rowPos, colPos;\n\n/* ---------- communication with the judge ---------- */\nint query_divine(const vector<pair<int,int>>& cells) {\n    cout << 'q' << ' ' << (int)cells.size();\n    for (auto [i,j] : cells) cout << ' ' << i << ' ' << j;\n    cout << '\\n' << std::flush;\n    int resp; cin >> resp;\n    return resp;\n}\nint query_drill(int i, int j) {\n    cout << 'q' << ' ' << 1 << ' ' << i << ' ' << j << '\\n' << std::flush;\n    int v; cin >> v;\n    return v;\n}\n\n/* ---------- recursive subdivision ---------- */\nvoid dfs(int r1, int r2, int c1, int c2) {\n    if (r1 > r2 || c1 > c2) return;\n    int h = r2 - r1 + 1, w = c2 - c1 + 1;\n    int area = h * w;\n\n    // base case: at most 2\u00d72 -> just drill\n    if (area <= 4) {\n        for (int i = r1; i <= r2; ++i)\n            for (int j = c1; j <= c2; ++j) {\n                if (!drilled[i][j]) {\n                    val[i][j] = query_drill(i, j);\n                    drilled[i][j] = 1;\n                }\n            }\n        return;\n    }\n\n    // query the whole rectangle\n    vector<pair<int,int>> cells;\n    cells.reserve(area);\n    for (int i = r1; i <= r2; ++i)\n        for (int j = c1; j <= c2; ++j)\n            cells.emplace_back(i, j);\n    int sum = query_divine(cells);\n\n    if (sum == 0) {                 // completely empty\n        for (int i = r1; i <= r2; ++i)\n            for (int j = c1; j <= c2; ++j)\n                val[i][j] = 0;\n        return;\n    }\n\n    // otherwise split into four quadrants\n    int rm = (r1 + r2) / 2;\n    int cm = (c1 + c2) / 2;\n    dfs(r1, rm, c1, cm);\n    dfs(r1, rm, cm+1, c2);\n    dfs(rm+1, r2, c1, cm);\n    dfs(rm+1, r2, cm+1, c2);\n}\n\n/* ---------- main ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> eps)) return 0;\n\n    // read and ignore the shapes\n    for (int k = 0; k < M; ++k) {\n        int d; cin >> d;\n        for (int t = 0; t < d; ++t) { int a,b; cin >> a >> b; }\n    }\n\n    rowPos.assign(N, 0);\n    colPos.assign(N, 0);\n    val.assign(N, vector<int>(N, -1));\n    drilled.assign(N, vector<char>(N, 0));\n\n    // ----- find non\u2011empty rows (single query) -----\n    for (int i = 0; i < N; ++i) {\n        vector<pair<int,int>> cells;\n        cells.reserve(N);\n        for (int j = 0; j < N; ++j) cells.emplace_back(i, j);\n        if (query_divine(cells) > 0) rowPos[i] = 1;\n    }\n\n    // ----- find non\u2011empty columns (single query) -----\n    for (int j = 0; j < N; ++j) {\n        vector<pair<int,int>> cells;\n        cells.reserve(N);\n        for (int i = 0; i < N; ++i) cells.emplace_back(i, j);\n        if (query_divine(cells) > 0) colPos[j] = 1;\n    }\n\n    // locate the bounding rectangle of possible oil cells\n    int r1 = N, r2 = -1, c1 = N, c2 = -1;\n    for (int i = 0; i < N; ++i) if (rowPos[i]) {\n        r1 = min(r1, i);\n        r2 = max(r2, i);\n    }\n    for (int j = 0; j < N; ++j) if (colPos[j]) {\n        c1 = min(c1, j);\n        c2 = max(c2, j);\n    }\n\n    // if there is at least one non\u2011empty row/column, search inside the rectangle\n    if (r1 <= r2 && c1 <= c2) {\n        dfs(r1, r2, c1, c2);\n    }\n\n    // cells outside the rectangle are known to be zero (they cannot contain oil)\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (val[i][j] == -1) val[i][j] = 0;\n\n    // ----- first guess -----\n    vector<pair<int,int>> ans;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (val[i][j] > 0) ans.emplace_back(i, j);\n\n    cout << 'a' << ' ' << (int)ans.size();\n    for (auto [i,j] : ans) cout << ' ' << i << ' ' << j;\n    cout << '\\n' << std::flush;\n    int ok; cin >> ok;\n    if (ok == 1) return 0;          // success\n\n    // ----- fallback: drill all cells that have not been drilled yet -----\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (!drilled[i][j]) {\n                val[i][j] = query_drill(i, j);\n                drilled[i][j] = 1;\n            }\n\n    // ----- second guess (must be correct) -----\n    ans.clear();\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (val[i][j] > 0) ans.emplace_back(i, j);\n\n    cout << 'a' << ' ' << (int)ans.size();\n    for (auto [i,j] : ans) cout << ' ' << i << ' ' << j;\n    cout << '\\n' << std::flush;\n    // the judge will always answer 1 here\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing Segment = tuple<int, long long, int>; // cnt, delta, idx\n\n/* ------------------------------------------------------------\n   MaxRects packing: best\u2011short\u2011side\u2011fit.\n   Returns true if all placed, false otherwise.\n   ------------------------------------------------------------ */\nbool packRectangles(const vector<long long>& areas,\n                    vector<array<int,4>>& placed,\n                    int W = 1000) {\n    int N = (int)areas.size();\n    placed.assign(N, {0,0,0,0});\n\n    // free rectangles \u2013 always inside the grid\n    struct FR { int x, y, w, h; };\n    vector<FR> freeRects;\n    freeRects.push_back({0, 0, W, W});\n\n    // indices sorted by descending area\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(),\n         [&](int i, int j){ return areas[i] > areas[j]; });\n\n    for (int id : order) {\n        long long need = areas[id];\n        if (need == 0) { // give a tiny 1\u00d71 rectangle\n            placed[id] = {0, 0, 1, 1};\n            continue;\n        }\n\n        // generate candidate dimensions (w,h) with w*h >= need, w,h>0, w<=W, h<=W\n        vector<pair<int,int>> cand;\n        for (int w = 1; w <= W; ++w) {\n            int h = (int)((need + w - 1) / w);   // ceil(need / w)\n            if (h == 0) continue;                // skip zero height\n            if (h > W) continue;\n            cand.emplace_back(w, h);\n        }\n        sort(cand.begin(), cand.end());\n        cand.erase(unique(cand.begin(), cand.end()), cand.end());\n\n        // best placement among all free rectangles\n        int bestScore = -1;\n        int bestFree = -1, bestW = -1, bestH = -1;\n        for (int fi = 0; fi < (int)freeRects.size(); ++fi) {\n            const FR &fr = freeRects[fi];\n            for (auto [cw, ch] : cand) {\n                if (cw > fr.w || ch > fr.h) continue;\n                int score = min(fr.w - cw, fr.h - ch); // short side fit\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestFree = fi;\n                    bestW = cw;\n                    bestH = ch;\n                }\n            }\n        }\n\n        // fallback: if not placed, enlarge to the free rectangle's size\n        if (bestFree == -1) {\n            for (int fi = 0; fi < (int)freeRects.size(); ++fi) {\n                FR &fr = freeRects[fi];\n                // try using the whole free rectangle width\n                int cw = fr.w;\n                int ch = (int)((need + cw - 1) / cw);\n                if (ch <= fr.h && ch > 0) {\n                    bestFree = fi;\n                    bestW = cw;\n                    bestH = ch;\n                    break;\n                }\n                // try using the whole free rectangle height\n                ch = fr.h;\n                cw = (int)((need + ch - 1) / ch);\n                if (cw <= fr.w && cw > 0) {\n                    bestFree = fi;\n                    bestW = cw;\n                    bestH = ch;\n                    break;\n                }\n            }\n        }\n\n        // still not placed -> failure\n        if (bestFree == -1) return false;\n\n        // place rectangle\n        FR fr = freeRects[bestFree];\n        placed[id] = {fr.x, fr.y, bestW, bestH};\n\n        // remove used free rectangle\n        freeRects.erase(freeRects.begin() + bestFree);\n\n        // create new free rectangles (right and bottom parts)\n        if (fr.w > bestW) {\n            FR right = {fr.x + bestW, fr.y, fr.w - bestW, bestH};\n            if (right.w > 0 && right.h > 0) freeRects.push_back(right);\n        }\n        if (fr.h > bestH) {\n            FR bottom = {fr.x, fr.y + bestH, fr.w, fr.h - bestH};\n            if (bottom.w > 0 && bottom.h > 0) freeRects.push_back(bottom);\n        }\n\n        // prune free rectangles that are completely inside another\n        bool changed = true;\n        while (changed) {\n            changed = false;\n            int F = (int)freeRects.size();\n            vector<char> toRemove(F, 0);\n            for (int i = 0; i < F && !changed; ++i) {\n                for (int j = 0; j < F; ++j) if (i != j) {\n                    const FR &a = freeRects[i];\n                    const FR &b = freeRects[j];\n                    if (a.x >= b.x && a.y >= b.y &&\n                        a.x + a.w <= b.x + b.w &&\n                        a.y + a.h <= b.y + b.h) {\n                        toRemove[i] = 1;\n                        changed = true;\n                        break;\n                    }\n                }\n            }\n            if (changed) {\n                vector<FR> nxt;\n                for (int i = 0; i < F; ++i)\n                    if (!toRemove[i]) nxt.push_back(freeRects[i]);\n                freeRects.swap(nxt);\n            }\n        }\n    }\n    return true;\n}\n\n/* ------------------------------------------------------------\n   Simple row packing (fallback)\n   ------------------------------------------------------------ */\nvoid packRow(const vector<long long>& areas,\n             vector<array<int,4>>& placed,\n             int W = 1000) {\n    int N = (int)areas.size();\n    placed.assign(N, {0,0,0,0});\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(),\n         [&](int i, int j){ return areas[i] > areas[j]; });\n\n    int curX = 0, curY = 0, rowH = 0;\n    for (int id : order) {\n        long long area = areas[id];\n        if (area == 0) area = 1; // tiny rectangle\n        int w = max(1, (int)((area + W - 1) / W));\n        int h = (int)((area + w - 1) / w);\n        if (curX + w > W) {\n            curX = 0;\n            curY += rowH;\n            rowH = 0;\n        }\n        placed[id] = {curX, curY, w, h};\n        curX += w;\n        rowH = max(rowH, h);\n    }\n}\n\n/* ------------------------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int W, D, N;\n    if (!(cin >> W >> D >> N)) return 0;\n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; ++d)\n        for (int k = 0; k < N; ++k) cin >> a[d][k];\n\n    /* ---------- 1. collect demands for each rank (i\u2011th smallest) ---- */\n    vector<vector<int>> demand(N, vector<int>(D));\n    for (int d = 0; d < D; ++d) {\n        vector<pair<int,int>> v;\n        v.reserve(N);\n        for (int k = 0; k < N; ++k) v.emplace_back(a[d][k], k);\n        sort(v.begin(), v.end(),\n             [](const pair<int,int>& p, const pair<int,int>& q){\n                 return p.first < q.first;\n             });\n        for (int i = 0; i < N; ++i) demand[i][d] = v[i].first;\n    }\n\n    /* ---------- 2. greedy area allocation (optimal B[i]) ------------ */\n    // safe buffer: worst total slack = N * (W-1)\n    long long capacity = 1LL * W * W - 1LL * N * (W - 1);\n    priority_queue<Segment> pq;\n    for (int i = 0; i < N; ++i) {\n        auto &vec = demand[i];\n        sort(vec.begin(), vec.end());\n        int prev = 0;\n        for (int t = 0; t < (int)vec.size(); ++t) {\n            int cur = vec[t];\n            int delta = cur - prev;\n            if (delta > 0) {\n                int cnt = D - t;               // days whose demand > prev\n                pq.emplace(cnt, (long long)delta, i);\n            }\n            prev = cur;\n        }\n    }\n\n    vector<long long> B(N, 0);\n    long long remain = capacity;\n    while (remain > 0 && !pq.empty()) {\n        auto [cnt, delta, idx] = pq.top(); pq.pop();\n        long long take = min(delta, remain);\n        B[idx] += take;\n        remain -= take;\n        delta -= take;\n        if (delta > 0) pq.emplace(cnt, delta, idx);\n    }\n\n    /* ---------- 3. pack rectangles (MaxRects) ---------------------- */\n    vector<array<int,4>> placed;\n    bool ok = packRectangles(B, placed, W);\n    if (!ok) {\n        // fallback to simple row packing\n        packRow(B, placed, W);\n    }\n\n    /* ---------- 4. compute actual areas after packing ---------------- */\n    vector<long long> actual(N);\n    for (int i = 0; i < N; ++i) {\n        actual[i] = 1LL * placed[i][2] * placed[i][3];\n    }\n\n    /* ---------- 5. prepare output (assign rectangles to reservations) */\n    // indices sorted by actual area (ascending)\n    vector<int> ascIdx(N);\n    iota(ascIdx.begin(), ascIdx.end(), 0);\n    sort(ascIdx.begin(), ascIdx.end(),\n         [&](int i, int j){ return actual[i] < actual[j]; });\n\n    vector<vector<array<int,4>>> out(D, vector<array<int,4>>(N));\n    for (int d = 0; d < D; ++d) {\n        vector<pair<int,int>> vp;\n        vp.reserve(N);\n        for (int k = 0; k < N; ++k) vp.emplace_back(a[d][k], k);\n        sort(vp.begin(), vp.end(),\n             [](const pair<int,int>& p, const pair<int,int>& q){\n                 return p.first < q.first;\n             });\n        for (int i = 0; i < N; ++i) {\n            int reservation = vp[i].second;\n            const auto &rc = placed[ ascIdx[i] ];   // i\u2011th smallest actual area\n            // rc = {x, y, w, h}\n            out[d][reservation] = {rc[0], rc[1],\n                                    rc[0] + rc[2], rc[1] + rc[3]};\n        }\n    }\n\n    /* ---------- 6. print ------------------------------------------------ */\n    for (int d = 0; d < D; ++d)\n        for (int k = 0; k < N; ++k) {\n            const auto &r = out[d][k];\n            cout << r[0] << ' ' << r[1] << ' '\n                 << r[2] << ' ' << r[3] << '\\n';\n        }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MOD = 998244353;\nconst int N = 9;\nconst int NSTAMP = 3;\nconst int M = 20;\nconst int MAX_K = 81;\n\nint stamp[M][3][3];\n\nstruct Act {\n    long long delta;\n    int m, p, q;\n};\n\nvoid applyStamp(int board[9][9], const Act& a) {\n    for (int di = 0; di < 3; ++di)\n        for (int dj = 0; dj < 3; ++dj) {\n            int &cell = board[a.p + di][a.q + dj];\n            cell += stamp[a.m][di][dj];\n            if (cell >= MOD) cell -= MOD;\n        }\n}\n\n// generate all possible actions for the current board\nvector<Act> computeActions(const int board[9][9]) {\n    vector<Act> actions;\n    actions.reserve(M * (N - 2) * (N - 2));\n    for (int m = 0; m < M; ++m) {\n        for (int p = 0; p <= N - NSTAMP; ++p) {\n            for (int q = 0; q <= N - NSTAMP; ++q) {\n                long long d = 0;\n                for (int di = 0; di < 3; ++di)\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int cur = board[p + di][q + dj];\n                        int nv = cur + stamp[m][di][dj];\n                        if (nv >= MOD) nv -= MOD;\n                        d += (nv - cur);\n                    }\n                actions.push_back({d, m, p, q});\n            }\n        }\n    }\n    return actions;\n}\n\n// maximal delta on the given board (the action is stored in 'best')\nlong long maxDelta(const int board[9][9], Act &best) {\n    long long bestVal = LLONG_MIN;\n    for (int m = 0; m < M; ++m) {\n        for (int p = 0; p <= N - NSTAMP; ++p) {\n            for (int q = 0; q <= N - NSTAMP; ++q) {\n                long long d = 0;\n                for (int di = 0; di < 3; ++di)\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int cur = board[p + di][q + dj];\n                        int nv = cur + stamp[m][di][dj];\n                        if (nv >= MOD) nv -= MOD;\n                        d += (nv - cur);\n                    }\n                if (d > bestVal) {\n                    bestVal = d;\n                    best = {d, m, p, q};\n                }\n            }\n        }\n    }\n    return bestVal;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N_in, M_in, K;\n    if (!(cin >> N_in >> M_in >> K)) return 0;\n\n    int initBoard[N][N];\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            long long x; cin >> x;\n            initBoard[i][j] = int(x % MOD);\n        }\n\n    for (int m = 0; m < M; ++m)\n        for (int i = 0; i < 3; ++i)\n            for (int j = 0; j < 3; ++j) {\n                long long x; cin >> x;\n                stamp[m][i][j] = int(x % MOD);\n            }\n\n    // ----- parameters of the heuristic -----\n    const int NUM_TRIALS = 25;      // number of random restarts\n    const int T = 80;               // number of first\u2011move candidates for 2\u2011step lookahead\n    const double PROB_ZERO = 0.20;  // probability to accept a pair with total delta == 0\n\n    random_device rd;\n    mt19937 rng(rd());\n\n    // baseline score (initial board)\n    long long bestScore = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) bestScore += initBoard[i][j];\n\n    vector<tuple<int,int,int>> bestOps;\n\n    for (int trial = 0; trial < NUM_TRIALS; ++trial) {\n        // different seed for each trial\n        rng.seed(rd() + trial * 1000);\n\n        int board[N][N];\n        memcpy(board, initBoard, sizeof(board));\n        int remaining = K;\n        vector<tuple<int,int,int>> ops;\n\n        while (remaining > 0) {\n            // ----- step 1 : best single action -----\n            vector<Act> actions = computeActions(board);\n\n            // collect all actions with maximal delta\n            long long maxd = LLONG_MIN;\n            vector<Act> bestList;\n            for (auto &a : actions) {\n                if (a.delta > maxd) {\n                    maxd = a.delta;\n                    bestList.clear();\n                    bestList.push_back(a);\n                } else if (a.delta == maxd) {\n                    bestList.push_back(a);\n                }\n            }\n            // random tie\u2011breaking\n            Act bestSingle = bestList[rng() % bestList.size()];\n\n            if (bestSingle.delta > 0) {\n                applyStamp(board, bestSingle);\n                ops.emplace_back(bestSingle.m, bestSingle.p, bestSingle.q);\n                --remaining;\n                continue;\n            }\n\n            // ----- step 2 : 2\u2011step lookahead (pair search) -----\n            sort(actions.begin(), actions.end(),\n                 [](const Act& a, const Act& b) { return a.delta > b.delta; });\n\n            int candCount = min(T, (int)actions.size());\n            vector<int> idx(candCount);\n            iota(idx.begin(), idx.end(), 0);\n            shuffle(idx.begin(), idx.end(), rng);\n\n            long long bestPairDelta = bestSingle.delta;\n            Act bestFirst = bestSingle;\n            bool foundBetter = false;\n\n            for (int t = 0; t < candCount; ++t) {\n                const Act &a1 = actions[idx[t]];\n\n                // simulate a1 on a temporary board\n                int tmp[N][N];\n                memcpy(tmp, board, sizeof(board));\n                for (int di = 0; di < 3; ++di)\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int &cell = tmp[a1.p + di][a1.q + dj];\n                        cell += stamp[a1.m][di][dj];\n                        if (cell >= MOD) cell -= MOD;\n                    }\n\n                // best second action after a1\n                Act dummy;\n                long long best2 = maxDelta(tmp, dummy);\n                long long total = a1.delta + best2;\n\n                if (total > bestPairDelta) {\n                    bestPairDelta = total;\n                    bestFirst = a1;\n                    foundBetter = true;\n                }\n            }\n\n            if (foundBetter && (bestPairDelta > 0 ||\n                (bestPairDelta == 0 && uniform_real_distribution<double>(0.0, 1.0)(rng) < PROB_ZERO))) {\n                applyStamp(board, bestFirst);\n                ops.emplace_back(bestFirst.m, bestFirst.p, bestFirst.q);\n                --remaining;\n                continue;\n            }\n\n            // no positive (or zero\u2011with\u2011probability) improvement possible any more\n            break;\n        }\n\n        // evaluate final score\n        long long curScore = 0;\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j) curScore += board[i][j];\n\n        if (curScore > bestScore) {\n            bestScore = curScore;\n            bestOps = ops;\n        }\n    }\n\n    cout << bestOps.size() << '\\n';\n    for (auto [m, p, q] : bestOps)\n        cout << m << ' ' << p << ' ' << q << '\\n';\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 5;                 // fixed in all test cases\n    const int TOT = N * N;           // 25\n\n    int Ncase;\n    // the problem supplies exactly one test case, but we also accept several\n    while (cin >> Ncase) {\n        // read the matrix A\n        vector<vector<int>> A(N, vector<int>(N));\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                cin >> A[i][j];\n\n        /* ----- row of each container ----- */\n        vector<int> row_of(TOT, -1);\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                row_of[A[i][j]] = i;\n\n        /* ----- generate actions for the large crane ----- */\n        vector<string> actions(N);\n        string large;\n        large.reserve(500);               // enough for all cases\n\n        int curR = 0, curC = 0;             // initial position of the large crane\n\n        for (int c = 0; c < TOT; ++c) {\n            int targetR = row_of[c];\n\n            // vertical movement\n            while (curR < targetR) { large.push_back('D'); ++curR; }\n            while (curR > targetR) { large.push_back('U'); --curR; }\n\n            // horizontal movement to column 0 (the receiving gate)\n            while (curC > 0) { large.push_back('L'); --curC; }\n\n            // pick up the container\n            large.push_back('P');\n\n            // move to the dispatch gate (column N-1 = 4)\n            while (curC < N - 1) { large.push_back('R'); ++curC; }\n\n            // release the container\n            large.push_back('Q');\n        }\n\n        actions[0] = large;\n        const size_t L = actions[0].size();   // total number of turns\n\n        /* ----- actions for the small cranes ----- */\n        for (int i = 1; i < N; ++i) {\n            string s;\n            s.reserve(L);\n            s.push_back('B');                 // bomb in the first turn\n            s.append(L - 1, '.');             // do nothing afterwards\n            actions[i] = s;\n        }\n\n        /* ----- output ----- */\n        for (int i = 0; i < N; ++i)\n            cout << actions[i] << '\\n';\n    }\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int r, c; };\nstruct Edge { int to, rev, cap, cost; };\nstruct MinCostFlow {\n    const int INF = 1e9;\n    int N;\n    vector<vector<Edge>> G;\n    MinCostFlow(int n) : N(n), G(n) {}\n    void addEdge(int from, int to, int cap, int cost) {\n        Edge a{to, (int)G[to].size(), cap, cost};\n        Edge b{from, (int)G[from].size(), 0, -cost};\n        G[from].push_back(a);\n        G[to].push_back(b);\n    }\n    pair<int, long long> minCostMaxFlow(int s, int t) {\n        int flow = 0;\n        long long cost = 0;\n        vector<int> dist(N), pv(N), pe(N);\n        vector<int> potential(N, 0);\n        while (true) {\n            fill(dist.begin(), dist.end(), INF);\n            dist[s] = 0;\n            using P = pair<int, int>;\n            priority_queue<P, vector<P>, greater<P>> pq;\n            pq.emplace(0, s);\n            while (!pq.empty()) {\n                auto [d, v] = pq.top(); pq.pop();\n                if (d != dist[v]) continue;\n                for (int i = 0; i < (int)G[v].size(); ++i) {\n                    Edge &e = G[v][i];\n                    if (e.cap <= 0) continue;\n                    int nd = d + e.cost + potential[v] - potential[e.to];\n                    if (nd < dist[e.to]) {\n                        dist[e.to] = nd;\n                        pv[e.to] = v;\n                        pe[e.to] = i;\n                        pq.emplace(nd, e.to);\n                    }\n                }\n            }\n            if (dist[t] == INF) break;\n            for (int v = 0; v < N; ++v) {\n                if (dist[v] < INF) potential[v] += dist[v];\n            }\n            int addflow = INF;\n            for (int v = t; v != s; v = pv[v]) {\n                Edge &e = G[pv[v]][pe[v]];\n                addflow = min(addflow, e.cap);\n            }\n            for (int v = t; v != s; v = pv[v]) {\n                Edge &e = G[pv[v]][pe[v]];\n                e.cap -= addflow;\n                G[v][e.rev].cap += addflow;\n            }\n            flow += addflow;\n            cost += 1LL * addflow * potential[t];\n        }\n        return {flow, cost};\n    }\n};\n\nstatic inline int manhattan(const Pos& a, const Pos& b) {\n    return abs(a.r - b.r) + abs(a.c - b.c);\n}\n\nstatic void moveTo(Pos& cur, const Pos& target, vector<string>& ops) {\n    while (cur.r < target.r) { ops.emplace_back(\"D\"); cur.r++; }\n    while (cur.r > target.r) { ops.emplace_back(\"U\"); cur.r--; }\n    while (cur.c < target.c) { ops.emplace_back(\"R\"); cur.c++; }\n    while (cur.c > target.c) { ops.emplace_back(\"L\"); cur.c--; }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\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    vector<Pos> srcPos, snkPos;\n    vector<int> srcSup, snkDem;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (h[i][j] > 0) {\n                srcPos.push_back({i, j});\n                srcSup.push_back(h[i][j]);\n            } else if (h[i][j] < 0) {\n                snkPos.push_back({i, j});\n                snkDem.push_back(-h[i][j]);\n            }\n        }\n    }\n    int S = srcPos.size();\n    int T = snkPos.size();\n    if (S == 0 || T == 0) return 0;\n\n    int V = S + T + 2;\n    int SRC = V - 2, SNK = V - 1;\n    MinCostFlow mcf(V);\n\n    for (int i = 0; i < S; ++i) mcf.addEdge(SRC, i, srcSup[i], 0);\n    for (int j = 0; j < T; ++j) mcf.addEdge(S + j, SNK, snkDem[j], 0);\n\n    struct OrigEdge { int from, to, cap; };\n    vector<OrigEdge> origEdges;\n    \n    for (int i = 0; i < S; ++i) {\n        for (int j = 0; j < T; ++j) {\n            int d = manhattan(srcPos[i], snkPos[j]);\n            int cost = d * (100 + srcSup[i]);\n            int cap = min(srcSup[i], snkDem[j]);\n            if (cap > 0) {\n                mcf.addEdge(i, S + j, cap, cost);\n                origEdges.push_back({i, S + j, cap});\n            }\n        }\n    }\n\n    mcf.minCostMaxFlow(SRC, SNK);\n\n    struct Delivery { Pos sink; int amt; };\n    vector<vector<Delivery>> srcDeliveries(S);\n    \n    for (auto &oe : origEdges) {\n        for (auto &e : mcf.G[oe.from]) {\n            if (e.to == oe.to) {\n                int flow = oe.cap - e.cap;\n                if (flow > 0) {\n                    int sinkIdx = oe.to - S;\n                    srcDeliveries[oe.from].push_back({snkPos[sinkIdx], flow});\n                }\n                break;\n            }\n        }\n    }\n\n    struct SourceInfo {\n        Pos pos;\n        int totalSupply;\n        vector<Delivery> deliveries;\n        bool oneTrip;\n    };\n    vector<SourceInfo> sources;\n    for (int i = 0; i < S; ++i) {\n        if (srcDeliveries[i].empty()) continue;\n        SourceInfo si;\n        si.pos = srcPos[i];\n        si.totalSupply = srcSup[i];\n        si.deliveries = srcDeliveries[i];\n\n        // Don't sort - keep the order from min-cost flow\n\n        long long costOneTrip = 0;\n        Pos cur = si.pos;\n        int load = si.totalSupply;\n        for (auto &d : si.deliveries) {\n            costOneTrip += 1LL * manhattan(cur, d.sink) * (100 + load);\n            load -= d.amt;\n            cur = d.sink;\n        }\n\n        long long costSeparate = 0;\n        for (auto &d : si.deliveries) {\n            // load at source, move loaded to sink, unload, return empty\n            costSeparate += 1LL * manhattan(si.pos, d.sink) * (100 + d.amt);\n            costSeparate += 1LL * manhattan(si.pos, d.sink) * 100;\n        }\n\n        si.oneTrip = (costOneTrip <= costSeparate);\n        sources.push_back(si);\n    }\n\n    Pos cur{0, 0};\n    vector<string> ops;\n    vector<bool> visited(sources.size(), false);\n    \n    // Greedy nearest neighbor\n    while (true) {\n        int bestIdx = -1;\n        int bestDist = 1e9;\n        for (int i = 0; i < (int)sources.size(); ++i) {\n            if (!visited[i]) {\n                int d = manhattan(cur, sources[i].pos);\n                if (d < bestDist) {\n                    bestDist = d;\n                    bestIdx = i;\n                }\n            }\n        }\n        if (bestIdx == -1) break;\n        visited[bestIdx] = true;\n        auto &src = sources[bestIdx];\n\n        moveTo(cur, src.pos, ops);\n\n        if (src.oneTrip) {\n            // Load at source, visit all sinks in order, return empty\n            ops.emplace_back(\"+\" + to_string(src.totalSupply));\n            int curLoad = src.totalSupply;\n            for (auto &d : src.deliveries) {\n                moveTo(cur, d.sink, ops);\n                ops.emplace_back(\"-\" + to_string(d.amt));\n                curLoad -= d.amt;\n            }\n        } else {\n            // Separate trips: for each delivery\n            for (auto &d : src.deliveries) {\n                // Load at source\n                ops.emplace_back(\"+\" + to_string(d.amt));\n                // Move to sink (loaded)\n                moveTo(cur, d.sink, ops);\n                // Unload at sink\n                ops.emplace_back(\"-\" + to_string(d.amt));\n                // Return empty to source\n                moveTo(cur, src.pos, ops);\n            }\n        }\n    }\n\n    for (const string &s : ops) cout << s << '\\n';\n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, T;\n    if (!(cin >> N >> M >> T)) return 0;\n    const int S = 2 * N * (N - 1);           // 60\n    vector<vector<int>> seed(S, vector<int>(M));\n    for (int i = 0; i < S; ++i)\n        for (int j = 0; j < M; ++j)\n            cin >> seed[i][j];\n\n    /* ----- pre\u2011compute positions ordered by degree ----- */\n    vector<tuple<int,int,int>> posDeg;       // (degree, i, j)\n    posDeg.reserve(N * N);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int d = (i > 0) + (i < N - 1) + (j > 0) + (j < N - 1);\n            posDeg.emplace_back(d, i, j);\n        }\n    }\n    sort(posDeg.begin(), posDeg.end(),\n         [](const auto& a, const auto& b) {\n             if (get<0>(a) != get<0>(b)) return get<0>(a) > get<0>(b);\n             return (get<1>(a) + get<2>(a)) < (get<1>(b) + get<2>(b));\n         });\n\n    /* ------------------- main loop ---------------------- */\n    for (int turn = 0; turn < T; ++turn) {\n        /* ----- evaluate current seeds ----- */\n        vector<int> sum(S, 0);\n        vector<int> bestIdx(M, -1);\n        vector<int> bestVal(M, -1);\n        \n        for (int i = 0; i < S; ++i) {\n            int s = 0;\n            for (int j = 0; j < M; ++j) {\n                int v = seed[i][j];\n                s += v;\n                if (v > bestVal[j]) {\n                    bestVal[j] = v;\n                    bestIdx[j] = i;\n                }\n            }\n            sum[i] = s;\n        }\n\n        /* ----- choose 36 parent seeds ----- */\n        // Score each seed by: (number of criteria it's best at) * 1000 + total sum\n        // This prioritizes specialists but also considers total value\n        vector<pair<long long, int>> scored;\n        scored.reserve(S);\n        vector<int> specialistCount(S, 0);\n        for (int j = 0; j < M; ++j) {\n            if (bestIdx[j] >= 0) specialistCount[bestIdx[j]]++;\n        }\n        for (int i = 0; i < S; ++i) {\n            long long score = (long long)specialistCount[i] * 10000 + sum[i];\n            scored.emplace_back(score, i);\n        }\n        sort(scored.begin(), scored.end(), greater<>());\n        \n        // Take top 36\n        vector<int> parents;\n        parents.reserve(36);\n        vector<char> used(S, 0);\n        for (int i = 0; i < 36; ++i) {\n            parents.push_back(scored[i].second);\n            used[scored[i].second] = 1;\n        }\n\n        // sort parents by value (best first) for placement\n        sort(parents.begin(), parents.end(),\n             [&](int a, int b) { return sum[a] > sum[b]; });\n\n        /* ----- place them onto the grid ----- */\n        vector<vector<int>> A(N, vector<int>(N, -1));\n        for (int p = 0; p < 36; ++p) {\n            int d, di, dj;\n            tie(d, di, dj) = posDeg[p];\n            A[di][dj] = parents[p];\n        }\n\n        /* ----- output ----- */\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (j) cout << ' ';\n                cout << A[i][j];\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n\n        /* ----- read next generation ----- */\n        vector<vector<int>> nxt(S, vector<int>(M));\n        for (int i = 0; i < S; ++i)\n            for (int j = 0; j < M; ++j)\n                cin >> nxt[i][j];\n        seed.swap(nxt);\n    }\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, V;\n    if (!(cin >> N >> M >> V)) return 0;\n    vector<string> sgrid(N), tgrid(N);\n    for (int i = 0; i < N; ++i) cin >> sgrid[i];\n    for (int i = 0; i < N; ++i) cin >> tgrid[i];\n\n    /* ----- board representation ----- */\n    vector<vector<bool>> has(N, vector<bool>(N, false));\n    vector<pair<int,int>> src;\n    vector<pair<int,int>> emptyTgt;\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (sgrid[i][j] == '1') {\n                has[i][j] = true;\n                if (tgrid[i][j] == '0')\n                    src.emplace_back(i, j);\n            }\n            if (tgrid[i][j] == '1') {\n                if (!has[i][j])\n                    emptyTgt.emplace_back(i, j);\n            }\n        }\n    }\n\n    // Use up to 4 leaves, but not more than V-1\n    int numLeaves = min(4, V - 1);\n    if (numLeaves < 1) numLeaves = 1;\n\n    /* ----- tree description ----- */\n    const int Vprime = numLeaves + 1;\n    cout << Vprime << \"\\n\";\n    for (int i = 1; i < Vprime; ++i) {\n        cout << 0 << ' ' << 1 << \"\\n\";\n    }\n    \n    // Start at center of mass\n    int sumX = 0, sumY = 0, total = 0;\n    for (auto &p : src) { sumX += p.first; sumY += p.second; total++; }\n    for (auto &p : emptyTgt) { sumX += p.first; sumY += p.second; total++; }\n    int start_x = (total > 0) ? (sumX / total) : 0;\n    int start_y = (total > 0) ? (sumY / total) : 0;\n    start_x = max(0, min(N-1, start_x));\n    start_y = max(0, min(N-1, start_y));\n    cout << start_x << ' ' << start_y << \"\\n\";\n\n    /* ----- directions ----- */\n    const int dr[4] = {0, 1, 0, -1};\n    const int dc[4] = {1, 0, -1, 0};\n\n    auto move_char = [&](int d)->char {\n        if (d == 0) return 'R';\n        if (d == 1) return 'D';\n        if (d == 2) return 'L';\n        return 'U';\n    };\n    auto dir_from_delta = [&](int drr, int dcc)->int {\n        for (int d = 0; d < 4; ++d)\n            if (dr[d] == drr && dc[d] == dcc) return d;\n        return -1;\n    };\n\n    /* ----- simulation ----- */\n    vector<string> ops;\n    int root_x = start_x, root_y = start_y;\n    vector<int> leaf_dir(numLeaves, 0);\n    vector<bool> holding(numLeaves, false);\n\n    const int INF = 1e9;\n\n    auto pick_for_leaf = [&](int leaf) {\n        if (src.empty()) return;\n        \n        int bestDist = INF, bestIdx = -1;\n        pair<int,int> bestNeighbour{-1,-1};\n        int bestDir = -1;\n\n        for (int i = 0; i < (int)src.size(); ++i) {\n            int sx = src[i].first, sy = src[i].second;\n            for (int d = 0; d < 4; ++d) {\n                int nx = sx - dr[d];\n                int ny = sy - dc[d];\n                if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n                int dist = abs(root_x - nx) + abs(root_y - ny);\n                // Add small penalty for rotation needed\n                int cur_dir = leaf_dir[leaf];\n                int diff = (d - cur_dir + 4) % 4;\n                int alt = 4 - diff;\n                int rot_needed = min(diff, alt);\n                dist += rot_needed;\n                if (dist < bestDist) {\n                    bestDist = dist;\n                    bestIdx = i;\n                    bestNeighbour = {nx, ny};\n                    bestDir = d;\n                }\n            }\n        }\n\n        // Move root towards neighbour\n        while (root_x != bestNeighbour.first || root_y != bestNeighbour.second) {\n            int ddx = 0, ddy = 0;\n            if (root_x < bestNeighbour.first) ddx = 1;\n            else if (root_x > bestNeighbour.first) ddx = -1;\n            if (root_y < bestNeighbour.second) ddy = 1;\n            else if (root_y > bestNeighbour.second) ddy = -1;\n\n            string op(2*Vprime, '.');\n            if (abs(root_x - bestNeighbour.first) >= abs(root_y - bestNeighbour.second)) {\n                op[0] = move_char(dir_from_delta(ddx, 0));\n                root_x += ddx;\n            } else {\n                op[0] = move_char(dir_from_delta(0, ddy));\n                root_y += ddy;\n            }\n            ops.push_back(op);\n        }\n\n        int target_dir = bestDir;\n        int cur_dir = leaf_dir[leaf];\n        int diff = (target_dir - cur_dir + 4) % 4;\n        int alt = 4 - diff;\n        int steps, rot;\n        if (diff <= alt) { steps = diff; rot = 1; }\n        else { steps = alt; rot = -1; }\n\n        int leaf_vertex = leaf + 1;\n\n        if (steps > 0) {\n            for (int i = 0; i < steps - 1; ++i) {\n                string op(2*Vprime, '.');\n                op[leaf_vertex] = (rot == 1 ? 'R' : 'L');\n                ops.push_back(op);\n                leaf_dir[leaf] = (leaf_dir[leaf] + rot + 4) % 4;\n            }\n            string op(2*Vprime, '.');\n            op[leaf_vertex] = (rot == 1 ? 'R' : 'L');\n            op[Vprime + leaf_vertex] = 'P';\n            ops.push_back(op);\n            leaf_dir[leaf] = (leaf_dir[leaf] + rot + 4) % 4;\n        } else {\n            string op(2*Vprime, '.');\n            op[Vprime + leaf_vertex] = 'P';\n            ops.push_back(op);\n        }\n\n        holding[leaf] = true;\n        has[src[bestIdx].first][src[bestIdx].second] = false;\n        src.erase(src.begin() + bestIdx);\n    };\n\n    auto place_for_leaf = [&](int leaf) {\n        if (emptyTgt.empty()) return;\n\n        int bestDist = INF, bestIdx = -1;\n        pair<int,int> bestNeighbour{-1,-1};\n        int bestDir = -1;\n\n        for (int i = 0; i < (int)emptyTgt.size(); ++i) {\n            int tx = emptyTgt[i].first, ty = emptyTgt[i].second;\n            for (int d = 0; d < 4; ++d) {\n                int nx = tx - dr[d];\n                int ny = ty - dc[d];\n                if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n                int dist = abs(root_x - nx) + abs(root_y - ny);\n                // Add small penalty for rotation needed\n                int cur_dir = leaf_dir[leaf];\n                int diff = (d - cur_dir + 4) % 4;\n                int alt = 4 - diff;\n                int rot_needed = min(diff, alt);\n                dist += rot_needed;\n                if (dist < bestDist) {\n                    bestDist = dist;\n                    bestIdx = i;\n                    bestNeighbour = {nx, ny};\n                    bestDir = d;\n                }\n            }\n        }\n\n        // Move root towards neighbour\n        while (root_x != bestNeighbour.first || root_y != bestNeighbour.second) {\n            int ddx = 0, ddy = 0;\n            if (root_x < bestNeighbour.first) ddx = 1;\n            else if (root_x > bestNeighbour.first) ddx = -1;\n            if (root_y < bestNeighbour.second) ddy = 1;\n            else if (root_y > bestNeighbour.second) ddy = -1;\n\n            string op(2*Vprime, '.');\n            if (abs(root_x - bestNeighbour.first) >= abs(root_y - bestNeighbour.second)) {\n                op[0] = move_char(dir_from_delta(ddx, 0));\n                root_x += ddx;\n            } else {\n                op[0] = move_char(dir_from_delta(0, ddy));\n                root_y += ddy;\n            }\n            ops.push_back(op);\n        }\n\n        int target_dir = bestDir;\n        int cur_dir = leaf_dir[leaf];\n        int diff = (target_dir - cur_dir + 4) % 4;\n        int alt = 4 - diff;\n        int steps, rot;\n        if (diff <= alt) { steps = diff; rot = 1; }\n        else { steps = alt; rot = -1; }\n\n        int leaf_vertex = leaf + 1;\n\n        if (steps > 0) {\n            for (int i = 0; i < steps - 1; ++i) {\n                string op(2*Vprime, '.');\n                op[leaf_vertex] = (rot == 1 ? 'R' : 'L');\n                ops.push_back(op);\n                leaf_dir[leaf] = (leaf_dir[leaf] + rot + 4) % 4;\n            }\n            string op(2*Vprime, '.');\n            op[leaf_vertex] = (rot == 1 ? 'R' : 'L');\n            op[Vprime + leaf_vertex] = 'P';\n            ops.push_back(op);\n            leaf_dir[leaf] = (leaf_dir[leaf] + rot + 4) % 4;\n        } else {\n            string op(2*Vprime, '.');\n            op[Vprime + leaf_vertex] = 'P';\n            ops.push_back(op);\n        }\n\n        has[emptyTgt[bestIdx].first][emptyTgt[bestIdx].second] = true;\n        emptyTgt.erase(emptyTgt.begin() + bestIdx);\n        holding[leaf] = false;\n    };\n\n    while (!src.empty() || !emptyTgt.empty()) {\n        // Try to pick with empty leaves\n        for (int leaf = 0; leaf < numLeaves && !holding[leaf]; ++leaf) {\n            if (src.empty()) break;\n            pick_for_leaf(leaf);\n        }\n\n        // Try to place with holding leaves\n        for (int leaf = 0; leaf < numLeaves && holding[leaf]; ++leaf) {\n            if (emptyTgt.empty()) break;\n            place_for_leaf(leaf);\n        }\n    }\n\n    /* ----- output ----- */\n    for (const string &s : ops) cout << s << '\\n';\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    if (!(cin >> N)) return 0;\n\n    const int M = 2 * N;\n    vector<pair<int,int>> pts(M);\n    for (int i = 0; i < M; ++i) cin >> pts[i].first >> pts[i].second;\n\n    /* values: first N are mackerels (+1), next N are sardines (-1) */\n    vector<int> val(M);\n    for (int i = 0; i < N; ++i) val[i] = 1;\n    for (int i = N; i < M; ++i) val[i] = -1;\n\n    /* coordinate compression */\n    vector<int> xs, ys;\n    xs.reserve(M); ys.reserve(M);\n    for (auto &p : pts) {\n        xs.push_back(p.first);\n        ys.push_back(p.second);\n    }\n    sort(xs.begin(), xs.end());\n    xs.erase(unique(xs.begin(), xs.end()), xs.end());\n    sort(ys.begin(), ys.end());\n    ys.erase(unique(ys.begin(), ys.end()), ys.end());\n\n    const int X = (int)xs.size();\n    const int Y = (int)ys.size();\n\n    /* 2\u2011D prefix sums */\n    vector<int> pref( (size_t)(X + 1) * (Y + 1), 0 );\n    for (int i = 0; i < M; ++i) {\n        int ix = lower_bound(xs.begin(), xs.end(), pts[i].first) - xs.begin();\n        int iy = lower_bound(ys.begin(), ys.end(), pts[i].second) - ys.begin();\n        pref[ (size_t)(ix + 1) * (Y + 1) + (iy + 1) ] += val[i];\n    }\n    for (int i = 1; i <= X; ++i) {\n        for (int j = 1; j <= Y; ++j) {\n            size_t idx = (size_t)i * (Y + 1) + j;\n            size_t a = (size_t)(i - 1) * (Y + 1) + j;\n            size_t b = (size_t)i * (Y + 1) + (j - 1);\n            size_t c = (size_t)(i - 1) * (Y + 1) + (j - 1);\n            pref[idx] = pref[idx] + pref[a] + pref[b] - pref[c];\n        }\n    }\n\n    /* helper: sum of a rectangle given by exclusive indices */\n    auto rectSum = [&](int l, int r, int b, int t) -> int {\n        // l,r are exclusive on the right, b,t exclusive on the top\n        if (l >= r || b >= t) return 0;\n        size_t idx_rr = (size_t)r * (Y + 1) + t;\n        size_t idx_lr = (size_t)l * (Y + 1) + t;\n        size_t idx_rb = (size_t)r * (Y + 1) + b;\n        size_t idx_lb = (size_t)l * (Y + 1) + b;\n        return (int)(pref[idx_rr] - pref[idx_lr] - pref[idx_rb] + pref[idx_lb]);\n    };\n\n    /* random generator */\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    const int RESTARTS = 80;\n    const int MAX_ITER  = 80;\n\n    int bestValue = -1000000;\n    int bestL = 0, bestR = 1, bestB = 0, bestT = 1;   // fallback\n\n    vector<int> colSum(X), rowSum(Y);\n    vector<int> prefCol(X + 1), prefRow(Y + 1);\n\n    for (int restart = 0; restart < RESTARTS; ++restart) {\n        int leftIdx, rightIdx, bottomIdx, topIdx;\n\n        if (restart == 0) {                     // whole rectangle\n            leftIdx   = 0;\n            rightIdx  = X;\n            bottomIdx = 0;\n            topIdx    = Y;\n        } else {\n            leftIdx   = uniform_int_distribution<int>(0, X - 1)(rng);\n            rightIdx  = uniform_int_distribution<int>(leftIdx + 1, X)(rng);\n            bottomIdx = uniform_int_distribution<int>(0, Y - 1)(rng);\n            topIdx    = uniform_int_distribution<int>(bottomIdx + 1, Y)(rng);\n        }\n\n        int curValue = rectSum(leftIdx, rightIdx, bottomIdx, topIdx);\n        int bestValueRestart = curValue;\n        int bestLr = xs[leftIdx], bestRr = (rightIdx > 0 ? xs[rightIdx - 1] : xs[0]);\n        int bestBr = ys[bottomIdx], bestTr = (topIdx > 0 ? ys[topIdx - 1] : ys[0]);\n\n        for (int it = 0; it < MAX_ITER; ++it) {\n            /* ----- compute column sums and row sums for current y\u2011interval ----- */\n            int b = bottomIdx, t = topIdx;\n            for (int i = 0; i < X; ++i) {\n                // sum of column i between rows b \u2026 t\u20111\n                colSum[i] = pref[(size_t)(i + 1) * (Y + 1) + t]\n                          - pref[(size_t)(i + 1) * (Y + 1) + b]\n                          - pref[(size_t)i * (Y + 1) + t]\n                          + pref[(size_t)i * (Y + 1) + b];\n            }\n            int l = leftIdx, r = rightIdx;\n            for (int j = 0; j < Y; ++j) {\n                // sum of row j between columns l \u2026 r\u20111\n                rowSum[j] = pref[(size_t)r * (Y + 1) + (j + 1)]\n                          - pref[(size_t)l * (Y + 1) + (j + 1)]\n                          - pref[(size_t)r * (Y + 1) + j]\n                          + pref[(size_t)l * (Y + 1) + j];\n            }\n\n            /* ----- one\u2011dimensional prefix sums ----- */\n            prefCol[0] = 0;\n            for (int i = 0; i < X; ++i) prefCol[i + 1] = prefCol[i] + colSum[i];\n            prefRow[0] = 0;\n            for (int j = 0; j < Y; ++j) prefRow[j + 1] = prefRow[j] + rowSum[j];\n\n            /* ----- choose the best side move ----- */\n            int bestGain = 0;\n            int bestSide = -1;   // 0:left, 1:right, 2:bottom, 3:top\n            int bestNewIdx = -1;\n\n            // left side\n            for (int nl = 0; nl < rightIdx; ++nl) {\n                if (nl == leftIdx) continue;\n                int gain = prefCol[leftIdx] - prefCol[nl];\n                if (gain > bestGain) {\n                    bestGain = gain; bestSide = 0; bestNewIdx = nl;\n                }\n            }\n            // right side\n            for (int nr = leftIdx + 1; nr <= X; ++nr) {\n                if (nr == rightIdx) continue;\n                int gain = prefCol[nr] - prefCol[rightIdx];\n                if (gain > bestGain) {\n                    bestGain = gain; bestSide = 1; bestNewIdx = nr;\n                }\n            }\n            // bottom side\n            for (int nb = 0; nb < topIdx; ++nb) {\n                if (nb == bottomIdx) continue;\n                int gain = prefRow[bottomIdx] - prefRow[nb];\n                if (gain > bestGain) {\n                    bestGain = gain; bestSide = 2; bestNewIdx = nb;\n                }\n            }\n            // top side\n            for (int nt = bottomIdx + 1; nt <= Y; ++nt) {\n                if (nt == topIdx) continue;\n                int gain = prefRow[nt] - prefRow[topIdx];\n                if (gain > bestGain) {\n                    bestGain = gain; bestSide = 3; bestNewIdx = nt;\n                }\n            }\n\n            if (bestGain <= 0) break;          // local optimum\n\n            // apply the move\n            switch (bestSide) {\n                case 0: leftIdx   = bestNewIdx; break;\n                case 1: rightIdx  = bestNewIdx; break;\n                case 2: bottomIdx = bestNewIdx; break;\n                case 3: topIdx    = bestNewIdx; break;\n            }\n            curValue += bestGain;\n\n            if (curValue > bestValueRestart) {\n                bestValueRestart = curValue;\n                bestLr = xs[leftIdx];\n                bestRr = (rightIdx > 0 ? xs[rightIdx - 1] : xs[0]);\n                bestBr = ys[bottomIdx];\n                bestTr = (topIdx > 0 ? ys[topIdx - 1] : ys[0]);\n            }\n        }\n\n        if (bestValueRestart > bestValue) {\n            bestValue = bestValueRestart;\n            bestL = bestLr; bestR = bestRr;\n            bestB = bestBr; bestT = bestTr;\n        }\n    }\n\n    /* ----- output the rectangle as a polygon ----- */\n    cout << 4 << '\\n';\n    cout << bestL << ' ' << bestB << '\\n';\n    cout << bestR << ' ' << bestB << '\\n';\n    cout << bestR << ' ' << bestT << '\\n';\n    cout << bestL << ' ' << bestT << '\\n';\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\n\nstruct Candidate {\n    bool skip;          // true \u2192 skip this rectangle\n    int rot;            // 0 = not rotated, 1 = rotated\n    char dir;           // 'U' or 'L'\n    int ref;            // -1 or index of a previously placed rectangle\n    ll sum;             // heuristic score (width+height+penalty)\n    ll x, y;            // coordinates of the placed rectangle\n    ll rw, rh;          // its width and height\n};\n\nint N, T;\nll sigma_;\nvector<ll> mw, mh;                 // measured sizes\nmt19937 rng(123456789);             // fixed seed, same as first version\n\n/* -------------------------------------------------------------\n   Build ONE greedy placement (exactly matching the first version).\n   The function fills `ans` with the list of decisions,\n   `placed` tells which indices are really placed.\n   ------------------------------------------------------------- */\nvoid build_one_placement(vector<tuple<int,int,char,int>>& ans,\n                         vector<char>& placed)\n{\n    ans.clear();\n    placed.assign(N, 0);\n    ll penalty = 0;\n\n    vector<ll> X(N, 0), Y(N, 0), W(N, 0), H(N, 0);\n    vector<int> placedIdx;               // indices of already placed rectangles\n    ll curW = 0, curH = 0;\n\n    const int TOP_K = 3;                  // random tie\u2011break among the best this many\n\n    for (int i = 0; i < N; ++i) {\n        vector<Candidate> cand;\n\n        // ----- skip -------------------------------------------------\n        cand.push_back({true, 0, '?', -1,\n                        curW + curH + penalty + mw[i] + mh[i],\n                        0, 0, 0, 0});\n\n        // ----- build reference set ---------------------------------\n        // This exactly matches the first version:\n        // 1. Add -1\n        // 2. Add the last placed rectangle (may duplicate -1)\n        // 3. Add three random earlier rectangles (no duplicate check)\n        vector<int> refs;\n        refs.push_back(-1);\n        if (!placedIdx.empty()) {\n            refs.push_back(placedIdx.back());   // last placed\n            // three random earlier rectangles\n            for (int qq = 0; qq < 3; ++qq) {\n                int r = placedIdx[uniform_int_distribution<int>(0, (int)placedIdx.size() - 1)(rng)];\n                refs.push_back(r);\n            }\n        }\n\n        // ----- try all rotations, directions, references ----------\n        for (int rot : {0, 1}) {\n            ll w = rot ? mh[i] : mw[i];\n            ll h = rot ? mw[i] : mh[i];\n            for (char dir : {'U', 'L'}) {\n                for (int ref : refs) {\n                    ll nx, ny;\n                    if (dir == 'U') {\n                        ll left = (ref == -1) ? 0 : X[ref] + W[ref];\n                        ll highest = 0;\n                        for (int k : placedIdx) {\n                            if (X[k] < left + w && X[k] + W[k] > left) {\n                                highest = max(highest, Y[k] + H[k]);\n                            }\n                        }\n                        nx = left;\n                        ny = highest;                 // may be 0\n                    } else { // dir == 'L' (BUGGY: uses right edge)\n                        ll top = (ref == -1) ? 0 : Y[ref] + H[ref];\n                        ll rightmost = LLONG_MAX;\n                        for (int k : placedIdx) {\n                            if (Y[k] < top + h && Y[k] + H[k] > top) {\n                                rightmost = min(rightmost, X[k] + W[k]); // BUG: should be X[k]\n                            }\n                        }\n                        if (rightmost == LLONG_MAX) nx = 0;\n                        else nx = max(0LL, rightmost - w);\n                        ny = top;\n                    }\n                    ll nw = max(curW, nx + w);\n                    ll nh = max(curH, ny + h);\n                    ll sc = nw + nh + penalty;\n                    cand.push_back({false, rot, dir, ref, sc, nx, ny, w, h});\n                }\n            }\n        }\n\n        // ----- choose a candidate (random among the best TOP_K) --\n        sort(cand.begin(), cand.end(),\n             [](const Candidate& a, const Candidate& b){ return a.sum < b.sum; });\n        int bestCnt = min(TOP_K, (int)cand.size());\n        int chosen = uniform_int_distribution<int>(0, bestCnt - 1)(rng);\n        const Candidate& c = cand[chosen];\n\n        if (c.skip) {\n            // skip this rectangle\n            penalty += mw[i] + mh[i];\n        } else {\n            // place it\n            ans.emplace_back(i, c.rot, c.dir, c.ref);\n            placed[i] = 1;\n            X[i] = c.x;  Y[i] = c.y;  W[i] = c.rw;  H[i] = c.rh;\n            placedIdx.push_back(i);\n            curW = max(curW, c.x + c.rw);\n            curH = max(curH, c.y + c.rh);\n        }\n    }\n}\n\n/* ------------------------------------------------------------- */\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> T >> sigma_)) return 0;\n    mw.resize(N);\n    mh.resize(N);\n    for (int i = 0; i < N; ++i) cin >> mw[i] >> mh[i];\n\n    for (int turn = 0; turn < T; ++turn) {\n        vector<tuple<int,int,char,int>> ans;\n        vector<char> placed;\n        build_one_placement(ans, placed);   // generate placement\n\n        // output the placement of this turn\n        cout << ans.size() << '\\n';\n        for (auto &tp : ans) {\n            int p, r; char d; int b;\n            tie(p, r, d, b) = tp;\n            cout << p << ' ' << r << ' ' << d << ' ' << b << '\\n';\n        }\n        cout.flush();\n\n        // read the noisy measurement (not used)\n        ll Wobs, Hobs;\n        cin >> Wobs >> Hobs;\n    }\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\n#include <random>\n#include <chrono>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, H;\n    if (!(cin >> N >> M >> H)) return 0;\n    vector<int> A(N);\n    for (int i = 0; i < N; ++i) cin >> A[i];\n    vector<pair<int,int>> edges(M);\n    for (int i = 0; i < M; ++i) {\n        int u, v; cin >> u >> v;\n        edges[i] = {u, v};\n    }\n    // coordinates - not needed\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n    }\n\n    // Build adjacency\n    vector<vector<int>> adj(N);\n    for (auto [u,v] : edges) {\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n\n    // Compute depths from parent array\n    auto compute_depths = [&](const vector<int>& parent) -> vector<int> {\n        vector<int> depth(N, -1);\n        queue<int> q;\n        for (int v = 0; v < N; ++v) {\n            if (parent[v] == -1) {\n                depth[v] = 0;\n                q.push(v);\n            }\n        }\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            for (int u : adj[v]) {\n                if (parent[u] == v && depth[u] == -1) {\n                    depth[u] = depth[v] + 1;\n                    q.push(u);\n                }\n            }\n        }\n        return depth;\n    };\n\n    auto compute_score = [&](const vector<int>& parent) -> long long {\n        long long score = 0;\n        vector<int> depth = compute_depths(parent);\n        for (int v = 0; v < N; ++v) {\n            if (depth[v] == -1) continue;\n            score += (long long)(depth[v] + 1) * A[v];\n        }\n        return score;\n    };\n\n    // Build solution - greedy with best parent selection\n    auto build_solution = [&](const vector<int>& order) -> pair<vector<int>, long long> {\n        vector<int> parent(N, -2);\n        vector<int> depth(N, -1);\n        \n        for (int v : order) {\n            int best_depth = -1;\n            int best_parent = -1;\n            int best_parent_beauty = -1;\n            \n            for (int d = H; d >= 0; --d) {\n                if (d == 0) {\n                    best_depth = 0;\n                    best_parent = -1;\n                    best_parent_beauty = 0;\n                    break;\n                }\n                \n                for (int u : adj[v]) {\n                    if (depth[u] == d - 1) {\n                        if (A[u] > best_parent_beauty) {\n                            best_depth = d;\n                            best_parent = u;\n                            best_parent_beauty = A[u];\n                        }\n                    }\n                }\n                if (best_depth != -1) break;\n            }\n            \n            depth[v] = best_depth;\n            parent[v] = best_parent;\n        }\n        \n        return {parent, compute_score(parent)};\n    };\n\n    vector<int> best_parent(N, -1);\n    long long best_score = -1;\n    \n    // Try multiple base orderings\n    vector<vector<int>> base_orders;\n    \n    // Order 1: by beauty descending\n    vector<int> order1(N);\n    iota(order1.begin(), order1.end(), 0);\n    sort(order1.begin(), order1.end(), [&](int a, int b) {\n        return A[a] > A[b];\n    });\n    base_orders.push_back(order1);\n    \n    // Order 2: by beauty/degree ratio (high beauty, low degree = can be deep)\n    vector<int> order2(N);\n    iota(order2.begin(), order2.end(), 0);\n    sort(order2.begin(), order2.end(), [&](int a, int b) {\n        double ra = (double)A[a] / adj[a].size();\n        double rb = (double)A[b] / adj[b].size();\n        return ra > rb;\n    });\n    base_orders.push_back(order2);\n    \n    // Order 3: by beauty * degree (high beauty, high degree = can support many children)\n    vector<int> order3(N);\n    iota(order3.begin(), order3.end(), 0);\n    sort(order3.begin(), order3.end(), [&](int a, int b) {\n        long long ra = (long long)A[a] * adj[a].size();\n        long long rb = (long long)A[b] * adj[b].size();\n        return ra > rb;\n    });\n    base_orders.push_back(order3);\n    \n    unsigned seed = chrono::steady_clock::now().time_since_epoch().count();\n    default_random_engine gen(seed);\n    \n    // Try each base ordering with many variations\n    for (const auto& base_order : base_orders) {\n        // First try the base order itself\n        auto [parent, score] = build_solution(base_order);\n        if (score > best_score) {\n            best_score = score;\n            best_parent = parent;\n        }\n        \n        // Then try variations with different swap counts\n        for (int iter = 0; iter < 1000; ++iter) {\n            vector<int> order = base_order;\n            int num_swaps = 20 + (iter % 80);\n            for (int i = 0; i < num_swaps; ++i) {\n                int a = uniform_int_distribution<int>(0, N-1)(gen);\n                int b = uniform_int_distribution<int>(0, N-1)(gen);\n                swap(order[a], order[b]);\n            }\n            auto [p, s] = build_solution(order);\n            if (s > best_score) {\n                best_score = s;\n                best_parent = p;\n            }\n        }\n    }\n    \n    // Also try completely random orders\n    for (int iter = 0; iter < 300; ++iter) {\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        shuffle(order.begin(), order.end(), gen);\n        auto [parent, score] = build_solution(order);\n        if (score > best_score) {\n            best_score = score;\n            best_parent = parent;\n        }\n    }\n    \n    // Output\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << best_parent[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Set {\n    bool isRow;          // true \u2192 row, false \u2192 column\n    int idx;             // row number or column number\n    char dir;            // 'L','R','U','D'\n    uint64_t mask;       // bitmask of Oni indices contained in the set\n    int cost;            // number of shifts\n};\n\nint N;                                     // board size (20)\nvector<string> board;                      // input board\nint oniIdx[20][20];                        // index of Oni, -1 if none\nbool fuku[20][20];                         // true if Fukunokami\n\nint leftMostF[20], rightMostF[20];\nint topMostF[20], bottomMostF[20];\n\nvector<Set> sets;\nvector<vector<int>> oniToSets;             // for each Oni, list of set ids\n\nint M;                                     // number of Oni\nuint64_t allMask;\n\nint bestCost;\nvector<int> bestSets;\nvector<int> curSets;\nbool rowUsed[20] = {false};\nbool colUsed[20] = {false};\n\nvoid dfs(uint64_t mask, int cost) {\n    if (mask == allMask) {\n        if (cost < bestCost) {\n            bestCost = cost;\n            bestSets = curSets;\n        }\n        return;\n    }\n    if (cost >= bestCost) return;\n    int remain = __builtin_popcountll(~mask & allMask);\n    if (cost + remain >= bestCost) return; // even with 1 per oni we cannot beat\n\n    // choose uncovered Oni with smallest number of candidate sets\n    uint64_t rem = ~mask & allMask;\n    int chosenOni = -1;\n    int minOpts = 100;\n    for (uint64_t sub = rem; sub; sub &= sub - 1) {\n        int idx = __builtin_ctzll(sub);\n        int opts = 0;\n        for (int sid : oniToSets[idx]) {\n            const Set &s = sets[sid];\n            if (s.isRow && rowUsed[s.idx]) continue;\n            if (!s.isRow && colUsed[s.idx]) continue;\n            if (mask & s.mask) continue;          // already covered by chosen sets\n            ++opts;\n        }\n        if (opts == 0) return;                     // dead end (should not happen)\n        if (opts < minOpts) {\n            minOpts = opts;\n            chosenOni = idx;\n            if (minOpts == 1) break;\n        }\n    }\n    if (chosenOni == -1) return;                  // cannot cover\n\n    for (int sid : oniToSets[chosenOni]) {\n        const Set &s = sets[sid];\n        if (s.isRow && rowUsed[s.idx]) continue;\n        if (!s.isRow && colUsed[s.idx]) continue;\n        if (mask & s.mask) continue;              // overlap \u2013 already covered\n        // choose this set\n        if (s.isRow) rowUsed[s.idx] = true;\n        else         colUsed[s.idx] = true;\n        curSets.push_back(sid);\n        dfs(mask | s.mask, cost + s.cost);\n        curSets.pop_back();\n        if (s.isRow) rowUsed[s.idx] = false;\n        else         colUsed[s.idx] = false;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N;\n    board.resize(N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n\n    // locate Oni and Fukunokami, initialise arrays\n    memset(oniIdx, -1, sizeof(oniIdx));\n    memset(fuku, 0, sizeof(fuku));\n    vector<pair<int,int>> oniPos;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 'x')\n                oniIdx[i][j] = (int)oniPos.size(),\n                oniPos.emplace_back(i, j);\n            else if (board[i][j] == 'o')\n                fuku[i][j] = true;\n        }\n    M = (int)oniPos.size();                // = 2\u00b7N\n    allMask = (M == 64) ? ~0ULL : ((1ULL<<M) - 1ULL);\n\n    // left / right most Fukunokami in each row\n    const int INF = N+5;\n    for (int i = 0; i < N; ++i) {\n        leftMostF[i] = INF; rightMostF[i] = -1;\n        for (int j = 0; j < N; ++j)\n            if (fuku[i][j]) {\n                leftMostF[i] = min(leftMostF[i], j);\n                rightMostF[i] = max(rightMostF[i], j);\n            }\n    }\n    // top / bottom most Fukunokami in each column\n    for (int j = 0; j < N; ++j) {\n        topMostF[j] = INF; bottomMostF[j] = -1;\n        for (int i = 0; i < N; ++i)\n            if (fuku[i][j]) {\n                topMostF[j] = min(topMostF[j], i);\n                bottomMostF[j] = max(bottomMostF[j], i);\n            }\n    }\n\n    // build the sets\n    for (int i = 0; i < N; ++i) {\n        vector<int> idsL, idsR;\n        int maxJ = -1, minJ = INF;\n        for (int j = 0; j < N; ++j) {\n            int id = oniIdx[i][j];\n            if (id == -1) continue;\n            bool leftClear = (leftMostF[i] == INF) || (leftMostF[i] > j);\n            bool rightClear = (rightMostF[i] == -1) || (rightMostF[i] < j);\n            if (leftClear) {\n                idsL.push_back(id);\n                maxJ = max(maxJ, j);\n            }\n            if (rightClear) {\n                idsR.push_back(id);\n                minJ = min(minJ, j);\n            }\n        }\n        if (!idsL.empty()) {\n            Set s; s.isRow = true; s.idx = i; s.dir = 'L';\n            s.cost = maxJ + 1;\n            s.mask = 0;\n            for (int id : idsL) s.mask |= (1ULL<<id);\n            sets.push_back(s);\n        }\n        if (!idsR.empty()) {\n            Set s; s.isRow = true; s.idx = i; s.dir = 'R';\n            s.cost = N - minJ;\n            s.mask = 0;\n            for (int id : idsR) s.mask |= (1ULL<<id);\n            sets.push_back(s);\n        }\n    }\n    for (int j = 0; j < N; ++j) {\n        vector<int> idsU, idsD;\n        int maxI = -1, minI = INF;\n        for (int i = 0; i < N; ++i) {\n            int id = oniIdx[i][j];\n            if (id == -1) continue;\n            bool upClear   = (topMostF[j] == INF) || (topMostF[j] > i);\n            bool downClear = (bottomMostF[j] == -1) || (bottomMostF[j] < i);\n            if (upClear) {\n                idsU.push_back(id);\n                maxI = max(maxI, i);\n            }\n            if (downClear) {\n                idsD.push_back(id);\n                minI = min(minI, i);\n            }\n        }\n        if (!idsU.empty()) {\n            Set s; s.isRow = false; s.idx = j; s.dir = 'U';\n            s.cost = maxI + 1;\n            s.mask = 0;\n            for (int id : idsU) s.mask |= (1ULL<<id);\n            sets.push_back(s);\n        }\n        if (!idsD.empty()) {\n            Set s; s.isRow = false; s.idx = j; s.dir = 'D';\n            s.cost = N - minI;\n            s.mask = 0;\n            for (int id : idsD) s.mask |= (1ULL<<id);\n            sets.push_back(s);\n        }\n    }\n\n    // mapping Oni -> sets\n    oniToSets.assign(M, {});\n    for (int sid = 0; sid < (int)sets.size(); ++sid) {\n        uint64_t m = sets[sid].mask;\n        while (m) {\n            int b = __builtin_ctzll(m);\n            oniToSets[b].push_back(sid);\n            m &= m-1;\n        }\n    }\n    // sort by cost (ascending) \u2013 helps the search\n    for (auto &vec : oniToSets) {\n        sort(vec.begin(), vec.end(),\n             [&](int a, int b){ return sets[a].cost < sets[b].cost; });\n    }\n\n    // upper bound = sum of individual minima (one\u2011by\u2011one removal)\n    int upper = 0;\n    for (int id = 0; id < M; ++id) {\n        int i = oniPos[id].first;\n        int j = oniPos[id].second;\n        int best = N+5;\n        bool leftClear = (leftMostF[i] == INF) || (leftMostF[i] > j);\n        bool rightClear= (rightMostF[i]==-1) || (rightMostF[i] < j);\n        bool upClear   = (topMostF[j] == INF) || (topMostF[j] > i);\n        bool downClear = (bottomMostF[j]==-1)|| (bottomMostF[j] < i);\n        if (leftClear)  best = min(best, j+1);\n        if (rightClear) best = min(best, N-j);\n        if (upClear)    best = min(best, i+1);\n        if (downClear)  best = min(best, N-i);\n        upper += best;\n    }\n    bestCost = upper;\n    // start search\n    dfs(0ULL, 0);\n\n    // produce output \u2013 column sets first, then row sets\n    vector<int> colSetIds, rowSetIds;\n    for (int sid : bestSets) {\n        if (!sets[sid].isRow) colSetIds.push_back(sid);\n        else                  rowSetIds.push_back(sid);\n    }\n\n    // output moves\n    ostringstream out;\n    for (int sid : colSetIds) {\n        const Set &s = sets[sid];\n        for (int k = 0; k < s.cost; ++k)\n            out << s.dir << ' ' << s.idx << '\\n';\n    }\n    for (int sid : rowSetIds) {\n        const Set &s = sets[sid];\n        for (int k = 0; k < s.cost; ++k)\n            out << s.dir << ' ' << s.idx << '\\n';\n    }\n    cout << out.str();\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    long long L;\n    if (!(cin >> N >> L)) return 0;\n    vector<int> T(N);\n    for (int i = 0; i < N; ++i) cin >> T[i];\n\n    // -------- adjust T[0] = 0  (error 2 is optimal) ----------\n    vector<int> t = T;\n    if (t[0] == 0) {\n        int j = -1;\n        for (int i = 1; i < N; ++i) if (t[i] > 0) { j = i; break; }\n        // there must be such j because sum = L > 0\n        t[0] = 1;\n        t[j]--;\n    }\n\n    // ----- pre\u2011compute how many odd / even edges each vertex has -----\n    vector<int> oddWeight(N), evenWeight(N);\n    for (int i = 0; i < N; ++i) {\n        oddWeight[i]  = (t[i] + 1) / 2;          // ceil\n        evenWeight[i] = t[i] / 2;                // floor\n    }\n\n    // ----- data for the walk construction -----\n    vector<int> need = t;                       // remaining indegrees\n    vector<int> vis(N, 0);                       // how many times a vertex has been visited\n    vector<int> a(N, -1), b(N, -1);              // targets, -1 = not fixed yet\n    vector<int> usedOdd(N, 0), usedEven(N, 0);   // how many edges of each kind have already been used\n\n    int cur = 0;\n    vis[0] = 1;\n    need[0]--;                                   // first week\n\n    for (long long week = 2; week <= L; ++week) {\n        // decide which kind of edge is needed now\n        bool odd = (vis[cur] % 2 == 1);          // after vis[cur] visits, parity is odd \u2192 need odd edge\n        if (odd) {\n            if (a[cur] == -1) {\n                // choose a target with enough remaining capacity\n                int target = -1;\n                for (int i = 0; i < N; ++i) {\n                    if (need[i] >= oddWeight[cur]) {\n                        target = i;\n                        break;\n                    }\n                }\n                // target must exist\n                a[cur] = target;\n            }\n            cur = a[cur];\n        } else {\n            if (b[cur] == -1) {\n                int target = -1;\n                for (int i = 0; i < N; ++i) {\n                    if (need[i] >= evenWeight[cur]) {\n                        target = i;\n                        break;\n                    }\n                }\n                b[cur] = target;\n            }\n            cur = b[cur];\n        }\n        ++vis[cur];\n        --need[cur];\n    }\n\n    // set default values for edges that never had to be fixed\n    for (int i = 0; i < N; ++i) {\n        if (a[i] == -1) a[i] = i;   // never used odd edge \u2192 self loop\n        if (b[i] == -1) b[i] = i;   // never used even edge \u2192 self loop\n    }\n\n    // --------------- output --------------------\n    for (int i = 0; i < N; ++i) {\n        cout << a[i] << ' ' << b[i] << \"\\n\";\n    }\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v;\n    int approx;\n};\n\nint N, M, Q, L, W;\nvector<int> G;\nvector<int> lx, rx, ly, ry;\nvector<int> cx, cy;\nvector<vector<int>> approxDist;\n\nvector<vector<Edge>> candEdges;\n\nvoid query(const vector<int>& nodes, int gid) {\n    int sz = (int)nodes.size();\n    cout << \"? \" << sz;\n    for (int v : nodes) cout << ' ' << v;\n    cout << \"\\n\";\n    cout.flush();\n\n    for (int i = 0; i < sz - 1; ++i) {\n        int a, b;\n        cin >> a >> b;\n        Edge e{a, b, approxDist[a][b]};\n        candEdges[gid].push_back(e);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    lx.resize(N); rx.resize(N); ly.resize(N); ry.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n    }\n\n    cx.resize(N); cy.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cx[i] = (lx[i] + rx[i]) / 2;\n        cy[i] = (ly[i] + ry[i]) / 2;\n    }\n\n    // Center-based distance matrix\n    approxDist.assign(N, vector<int>(N, 0));\n    for (int i = 0; i < N; ++i) {\n        for (int j = i + 1; j < N; ++j) {\n            long long dx = (long long)cx[i] - cx[j];\n            long long dy = (long long)cy[i] - cy[j];\n            int d = (int)floor(sqrt((double)dx * dx + (double)dy * dy) + 1e-9);\n            approxDist[i][j] = approxDist[j][i] = d;\n        }\n    }\n\n    // Group by center sorting\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(),\n         [&](int a, int b) {\n             if (cx[a] != cx[b]) return cx[a] < cx[b];\n             return cy[a] < cy[b];\n         });\n\n    vector<vector<int>> groups(M);\n    int pos = 0;\n    for (int g = 0; g < M; ++g) {\n        groups[g].reserve(G[g]);\n        for (int i = 0; i < G[g]; ++i) groups[g].push_back(order[pos++]);\n    }\n\n    candEdges.assign(M, {});\n    int used = 0;\n\n    // Baseline queries - sliding window\n    for (int gid = 0; gid < M; ++gid) {\n        int sz = (int)groups[gid].size();\n        if (sz <= 1) continue;\n        if (sz == 2) continue;\n        if (sz <= L) {\n            query(groups[gid], gid);\n            ++used;\n        } else {\n            int i = 0;\n            while (i + L <= sz) {\n                vector<int> sub(L);\n                for (int j = 0; j < L; ++j) sub[j] = groups[gid][i + j];\n                query(sub, gid);\n                ++used;\n                i += L - 1;\n            }\n            if (i < sz - 1) {\n                int rem = sz - i;\n                vector<int> sub(rem);\n                for (int j = 0; j < rem; ++j) sub[j] = groups[gid][i + j];\n                query(sub, gid);\n                ++used;\n            }\n        }\n    }\n\n    // Extra queries - prioritize large groups with smart city selection\n    int leftover = Q - used;\n    \n    // Compute potential improvement for each group\n    vector<pair<long long, int>> groupPriority; // (potential, gid)\n    for (int gid = 0; gid < M; ++gid) {\n        int sz = (int)groups[gid].size();\n        if (sz >= 3) {\n            // Larger groups have more potential\n            long long potential = 1LL * sz * sz;\n            groupPriority.emplace_back(potential, gid);\n        }\n    }\n    sort(groupPriority.rbegin(), groupPriority.rend());\n    \n    std::mt19937 rng(123456);\n    int idx = 0;\n    while (leftover > 0 && !groupPriority.empty()) {\n        int gid = groupPriority[idx % groupPriority.size()].second;\n        int gsz = (int)groups[gid].size();\n        int qsz = min(L, gsz);\n        \n        // For extra queries, select cities that are closer together\n        vector<int> candidates;\n        \n        // Pick a random starting point, then select nearby cities\n        int start = uniform_int_distribution<int>(0, gsz - 1)(rng);\n        candidates.push_back(groups[gid][start]);\n        \n        // Add L-1 closest cities to start based on heuristic\n        vector<pair<int, int>> dists; // (dist, city idx)\n        for (int i = 0; i < gsz; ++i) {\n            if (i == start) continue;\n            dists.emplace_back(approxDist[groups[gid][start]][groups[gid][i]], i);\n        }\n        sort(dists.begin(), dists.end());\n        for (int i = 0; i < qsz - 1 && i < (int)dists.size(); ++i) {\n            candidates.push_back(groups[gid][dists[i].second]);\n        }\n        \n        // If we don't have enough candidates, fill with random\n        while ((int)candidates.size() < qsz) {\n            int r = uniform_int_distribution<int>(0, gsz - 1)(rng);\n            int city = groups[gid][r];\n            if (find(candidates.begin(), candidates.end(), city) == candidates.end()) {\n                candidates.push_back(city);\n            }\n        }\n        \n        // Shuffle to avoid bias\n        shuffle(candidates.begin(), candidates.end(), rng);\n        vector<int> sub(candidates.begin(), candidates.begin() + qsz);\n        \n        query(sub, gid);\n        ++used;\n        --leftover;\n        ++idx;\n    }\n\n    // Build final trees\n    vector<vector<pair<int,int>>> answerEdges(M);\n\n    for (int gid = 0; gid < M; ++gid) {\n        int sz = (int)groups[gid].size();\n        if (sz <= 1) continue;\n        if (sz == 2) {\n            answerEdges[gid].push_back({groups[gid][0], groups[gid][1]});\n            continue;\n        }\n\n        auto &edges = candEdges[gid];\n        if (edges.empty()) {\n            for (int i = 0; i < sz - 1; ++i) {\n                answerEdges[gid].push_back({groups[gid][i], groups[gid][i+1]});\n            }\n            continue;\n        }\n\n        // Sort by approx distance\n        sort(edges.begin(), edges.end(),\n             [&](const Edge& a, const Edge& b) {\n                 if (a.approx != b.approx) return a.approx < b.approx;\n                 return a.u < b.u || (a.u == b.u && a.v < b.v);\n             });\n\n        // Kruskal\n        vector<int> localId(N, -1);\n        for (int i = 0; i < sz; ++i) localId[groups[gid][i]] = i;\n\n        vector<int> parent(sz), rankv(sz, 0);\n        iota(parent.begin(), parent.end(), 0);\n        function<int(int)> find = [&](int x) {\n            while (parent[x] != x) {\n                parent[x] = parent[parent[x]];\n                x = parent[x];\n            }\n            return x;\n        };\n        auto unite = [&](int a, int b) -> bool {\n            a = find(a); b = find(b);\n            if (a == b) return false;\n            if (rankv[a] < rankv[b]) swap(a, b);\n            parent[b] = a;\n            if (rankv[a] == rankv[b]) ++rankv[a];\n            return true;\n        };\n\n        for (const Edge& e : edges) {\n            int u = localId[e.u];\n            int v = localId[e.v];\n            if (unite(u, v)) {\n                answerEdges[gid].push_back({e.u, e.v});\n                if ((int)answerEdges[gid].size() == sz - 1) break;\n            }\n        }\n    }\n\n    cout << \"!\\n\";\n    for (int gid = 0; gid < M; ++gid) {\n        for (size_t i = 0; i < groups[gid].size(); ++i) {\n            if (i) cout << ' ';\n            cout << groups[gid][i];\n        }\n        cout << \"\\n\";\n        for (auto &e : answerEdges[gid]) {\n            cout << e.first << ' ' << e.second << \"\\n\";\n        }\n    }\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;                         // N = 20, M = 40\nint totalPos;                    // N * N   ( = 400 )\nint totalStates;                 // totalPos * (totalPos + 1)\n\nconst int dr[4] = {-1, 1, 0, 0};\nconst int dc[4] = {0, 0, -1, 1};\nconst char dirc[4] = {'U', 'D', 'L', 'R'};\n\nvector<int> dist;                // distance in the state graph\nvector<int> parent;              // predecessor state\nvector<pair<char,char>> act;    // action + direction stored for each state\n\n/*---------------------------------------------------------------*/\n/* BFS that returns the shortest action sequence from (sr,sc)\n   to (tr,tc) while leaving no block on the board                */\nbool bfs(int sr, int sc, int tr, int tc,\n         vector<pair<char,char>>& out)\n{\n    if (sr == tr && sc == tc) { out.clear(); return true; }\n\n    int startIdx = sr * N + sc;\n    int targetIdx = tr * N + tc;\n\n    const int startState = startIdx * (totalPos + 1);          // block = none\n    const int targetState = targetIdx * (totalPos + 1);\n\n    fill(dist.begin(),   dist.end(),   -1);\n    fill(parent.begin(), parent.end(), -1);\n\n    queue<int> q;\n    dist[startState] = 0;\n    q.push(startState);\n\n    while (!q.empty()) {\n        int cur = q.front(); q.pop();\n        if (cur == targetState) break;               // reached\n\n        int posIdx   = cur / (totalPos + 1);\n        int blockSt  = cur % (totalPos + 1);          // 0 = none, else cell+1\n        int r = posIdx / N;\n        int c = posIdx % N;\n        int blockIdx = blockSt - 1;                  // -1 = none, else cell id\n\n        /* ---- Move ------------------------------------------------*/\n        for (int d = 0; d < 4; ++d) {\n            int nr = r + dr[d], nc = c + dc[d];\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n            int nIdx = nr * N + nc;\n            if (blockIdx == nIdx) continue;          // blocked\n            int ns = nIdx * (totalPos + 1) + blockSt;\n            if (dist[ns] == -1) {\n                dist[ns] = dist[cur] + 1;\n                parent[ns] = cur;\n                act[ns] = {'M', dirc[d]};\n                q.push(ns);\n            }\n        }\n\n        /* ---- Slide ----------------------------------------------*/\n        for (int d = 0; d < 4; ++d) {\n            int tr_ = r, tc_ = c;\n            while (true) {\n                int nr = tr_ + dr[d];\n                int nc = tc_ + dc[d];\n                if (nr < 0 || nr >= N || nc < 0 || nc >= N) break; // border\n                int nIdx = nr * N + nc;\n                if (blockIdx != -1 && nIdx == blockIdx) break;    // block\n                tr_ = nr; tc_ = nc;\n            }\n            int destIdx = tr_ * N + tc_;\n            int ns = destIdx * (totalPos + 1) + blockSt;\n            if (dist[ns] == -1) {\n                dist[ns] = dist[cur] + 1;\n                parent[ns] = cur;\n                act[ns] = {'S', dirc[d]};\n                q.push(ns);\n            }\n        }\n\n        /* ---- Alter (place / remove block) -----------------------*/\n        for (int d = 0; d < 4; ++d) {\n            int nr = r + dr[d], nc = c + dc[d];\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n            int neighIdx = nr * N + nc;\n            int newBlockSt;\n            if (blockIdx != -1 && neighIdx == blockIdx) {\n                newBlockSt = 0;                         // remove\n            } else if (blockIdx == -1) {\n                newBlockSt = neighIdx + 1;             // place\n            } else {\n                continue;                               // a block already elsewhere\n            }\n            int ns = posIdx * (totalPos + 1) + newBlockSt;\n            if (dist[ns] == -1) {\n                dist[ns] = dist[cur] + 1;\n                parent[ns] = cur;\n                act[ns] = {'A', dirc[d]};\n                q.push(ns);\n            }\n        }\n    }\n\n    if (dist[targetState] == -1) return false;   // should never happen\n\n    /* reconstruct the path */\n    vector<pair<char,char>> rev;\n    int cur = targetState;\n    while (cur != startState) {\n        rev.push_back(act[cur]);\n        cur = parent[cur];\n    }\n    reverse(rev.begin(), rev.end());\n    out = move(rev);\n    return true;\n}\n\n/*---------------------------------------------------------------*/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M;                     // N = 20 , M = 40\n    vector<pair<int,int>> pt(M + 1);\n    for (int i = 0; i <= M; ++i) cin >> pt[i].first >> pt[i].second;\n\n    totalPos    = N * N;               // 400\n    totalStates = totalPos * (totalPos + 1);\n\n    dist.assign(totalStates, -1);\n    parent.assign(totalStates, -1);\n    act.assign(totalStates, {'?', '?'});\n\n    vector<string> answer;\n    int cr = pt[0].first, cc = pt[0].second;\n\n    for (int k = 1; k <= M; ++k) {\n        int tr = pt[k].first, tc = pt[k].second;\n        vector<pair<char,char>> seq;\n        bool ok = bfs(cr, cc, tr, tc, seq);\n        if (!ok) {          // should never happen \u2013 fallback to pure moves\n            while (cr != tr || cc != tc) {\n                if (cr < tr) { answer.emplace_back(\"M D\"); ++cr; }\n                else if (cr > tr) { answer.emplace_back(\"M U\"); --cr; }\n                else if (cc < tc) { answer.emplace_back(\"M R\"); ++cc; }\n                else { answer.emplace_back(\"M L\"); --cc; }\n            }\n        } else {\n            for (auto &p : seq) {\n                string s;\n                s.push_back(p.first);\n                s.push_back(' ');\n                s.push_back(p.second);\n                answer.emplace_back(s);\n            }\n            cr = tr; cc = tc;\n        }\n    }\n\n    if ((int)answer.size() > 2 * N * M) {\n        cerr << \"Too many actions!\\n\";\n    }\n\n    for (auto &ln : answer) cout << ln << '\\n';\n    return 0;\n}"},"16":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int x, y;          // integer coordinates of the unit square\n    int r;             // required area\n    int idx;           // original index\n};\n\nstruct LeafRegion {\n    int x1, y1, x2, y2;\n};\n\nint n;\nvector<Point> pts;\nvector<LeafRegion> leaf;          // region for each original index\n\n/*------------------------------------------------------------------*/\n/*  satisfaction helpers                                           */\ninline double computeP(int r, int s) {\n    double ratio = (double)min(r, s) / (double)max(r, s);\n    return ratio * (2.0 - ratio);\n}\n\n/*  best possible satisfaction for a point with required area r\n    inside a region of size w \u00d7 h (both positive)                */\ninline double bestSat(int r, int w, int h) {\n    if (w <= 0 || h <= 0) return 0.0;\n    // candidate heights: 1, h, floor(r/w), ceil(r/w)\n    int hf = r / w;\n    int hc = (r + w - 1) / w;\n    double best = 0.0;\n    const int cand[4] = {1, h, hf, hc};\n    for (int i = 0; i < 4; ++i) {\n        int hh = cand[i];\n        if (hh < 1 || hh > h) continue;\n        int s = w * hh;\n        double p = computeP(r, s);\n        if (p > best) best = p;\n    }\n    return best;\n}\n\n/*------------------------------------------------------------------*/\n/*  recursive construction of the binary partition                */\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nvoid build(const vector<int>& ids,\n           int x1, int y1, int x2, int y2) {\n    if (ids.size() == 1) {                 // leaf\n        leaf[ids[0]] = {x1, y1, x2, y2};\n        return;\n    }\n\n    int W = x2 - x1;\n    int H = y2 - y1;\n\n    // total required area of the points in this node (computed once)\n    long long totalR = 0;\n    for (int id : ids) totalR += pts[id].r;\n\n    double bestScore = -1.0;\n    long long bestAreaDiff = (1LL << 60);\n    bool bestVert = false;\n    int bestK = -1;\n\n    /* ----- try all vertical cuts ----- */\n    for (int k = x1 + 1; k < x2; ++k) {\n        int wL = k - x1;\n        int wR = x2 - k;\n        bool leftNotEmpty = false, rightNotEmpty = false;\n        double sum = 0.0;\n        long long sumR = 0;\n        for (int id : ids) {\n            if (pts[id].x < k) {\n                leftNotEmpty = true;\n                sumR += pts[id].r;\n                sum += bestSat(pts[id].r, wL, H);\n            } else {\n                rightNotEmpty = true;\n                sum += bestSat(pts[id].r, wR, H);\n            }\n        }\n        if (!leftNotEmpty || !rightNotEmpty) continue;\n        long long areaL = 1LL * wL * H;\n        long long areaR = 1LL * wR * H;\n        long long diff = llabs(areaL - sumR) + llabs(areaR - (totalR - sumR));\n\n        if (sum > bestScore + 1e-12) {\n            bestScore = sum;\n            bestAreaDiff = diff;\n            bestVert = true;\n            bestK = k;\n        } else if (fabs(sum - bestScore) <= 1e-12) {\n            if (diff < bestAreaDiff) {\n                bestAreaDiff = diff;\n                bestVert = true;\n                bestK = k;\n            } else if (diff == bestAreaDiff && (rng() & 1)) {\n                bestVert = true;\n                bestK = k;\n            }\n        }\n    }\n\n    /* ----- try all horizontal cuts ----- */\n    for (int k = y1 + 1; k < y2; ++k) {\n        int hL = k - y1;\n        int hR = y2 - k;\n        bool leftNotEmpty = false, rightNotEmpty = false;\n        double sum = 0.0;\n        long long sumR = 0;\n        for (int id : ids) {\n            if (pts[id].y < k) {\n                leftNotEmpty = true;\n                sumR += pts[id].r;\n                sum += bestSat(pts[id].r, W, hL);\n            } else {\n                rightNotEmpty = true;\n                sum += bestSat(pts[id].r, W, hR);\n            }\n        }\n        if (!leftNotEmpty || !rightNotEmpty) continue;\n        long long areaL = 1LL * W * hL;\n        long long areaR = 1LL * W * hR;\n        long long diff = llabs(areaL - sumR) + llabs(areaR - (totalR - sumR));\n\n        if (sum > bestScore + 1e-12) {\n            bestScore = sum;\n            bestAreaDiff = diff;\n            bestVert = false;\n            bestK = k;\n        } else if (fabs(sum - bestScore) <= 1e-12) {\n            if (diff < bestAreaDiff) {\n                bestAreaDiff = diff;\n                bestVert = false;\n                bestK = k;\n            } else if (diff == bestAreaDiff && (rng() & 1)) {\n                bestVert = false;\n                bestK = k;\n            }\n        }\n    }\n\n    // perform the chosen cut\n    vector<int> leftIds, rightIds;\n    if (bestVert) {                         // vertical\n        for (int id : ids) {\n            if (pts[id].x < bestK) leftIds.push_back(id);\n            else rightIds.push_back(id);\n        }\n        build(leftIds,  x1, y1, bestK, y2);\n        build(rightIds, bestK, y1, x2,   y2);\n    } else {                                 // horizontal\n        for (int id : ids) {\n            if (pts[id].y < bestK) leftIds.push_back(id);\n            else rightIds.push_back(id);\n        }\n        build(leftIds,  x1, y1, x2, bestK);\n        build(rightIds, x1, bestK, x2, y2);\n    }\n}\n\n/*------------------------------------------------------------------*/\n/*  build the final rectangle inside a leaf                         */\nvoid placeRectangles(const vector<LeafRegion>& leaf,\n                    vector<int>& a, vector<int>& b,\n                    vector<int>& c, vector<int>& d,\n                    double& totalP) {\n    totalP = 0.0;\n    for (int i = 0; i < n; ++i) {\n        const LeafRegion &reg = leaf[i];\n        int W = reg.x2 - reg.x1;\n        int H = reg.y2 - reg.y1;\n        int r = pts[i].r;\n\n        int bestW = 1, bestH = 1;\n        double bestP = -1.0;\n\n        // ----- enumerate all widths -----\n        for (int w = 1; w <= W; ++w) {\n            int hf = r / w;\n            int hc = (r + w - 1) / w;\n            const int cand[4] = {1, H, hf, hc};\n            for (int t = 0; t < 4; ++t) {\n                int h = cand[t];\n                if (h < 1 || h > H) continue;\n                int s = w * h;\n                double p = computeP(r, s);\n                if (p > bestP) {\n                    bestP = p;\n                    bestW = w;\n                    bestH = h;\n                }\n            }\n        }\n\n        // ----- tiny local search: try to enlarge by 1 in either direction -----\n        if (bestW < W) {\n            int w2 = bestW + 1;\n            int h2 = bestH;\n            double p2 = computeP(r, w2 * h2);\n            if (p2 > bestP) {\n                bestP = p2;\n                bestW = w2;\n            }\n        }\n        if (bestH < H) {\n            int w2 = bestW;\n            int h2 = bestH + 1;\n            double p2 = computeP(r, w2 * h2);\n            if (p2 > bestP) {\n                bestP = p2;\n                bestH = h2;\n            }\n        }\n\n        // position the rectangle so that it still covers the unit square\n        int left   = max(reg.x1, pts[i].x + 1 - bestW);\n        int bottom = max(reg.y1, pts[i].y + 1 - bestH);\n\n        a[i] = left;\n        b[i] = bottom;\n        c[i] = left + bestW;\n        d[i] = bottom + bestH;\n\n        totalP += bestP;\n    }\n}\n\n/*------------------------------------------------------------------*/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> n;\n    pts.resize(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> pts[i].x >> pts[i].y >> pts[i].r;\n        pts[i].idx = i;\n    }\n\n    const int ITER = 25;               // safe number of repetitions (known to fit in time limit)\n    double bestTotal = -1.0;\n    vector<int> bestA(n), bestB(n), bestC(n), bestD(n);\n\n    for (int it = 0; it < ITER; ++it) {\n        leaf.assign(n, LeafRegion{0,0,0,0});\n        vector<int> allIds(n);\n        iota(allIds.begin(), allIds.end(), 0);\n        shuffle(allIds.begin(), allIds.end(), rng);\n        build(allIds, 0, 0, 10000, 10000);\n\n        vector<int> a(n), b(n), c(n), d(n);\n        double cur;\n        placeRectangles(leaf, a, b, c, d, cur);\n\n        if (cur > bestTotal) {\n            bestTotal = cur;\n            bestA = a; bestB = b; bestC = c; bestD = d;\n        }\n    }\n\n    for (int i = 0; i < n; ++i) {\n        cout << bestA[i] << ' ' << bestB[i] << ' '\n             << bestC[i] << ' ' << bestD[i] << '\\n';\n    }\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------- input ---------- */\n    int si, sj;\n    if (!(cin >> si >> sj)) return 0;\n    const int N = 50;\n\n    vector<vector<int>> tile(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> tile[i][j];\n\n    vector<vector<int>> val(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> val[i][j];\n\n    /* number of different tiles */\n    int maxTile = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            maxTile = max(maxTile, tile[i][j]);\n    const int M = maxTile + 1;                 // tile IDs 0 \u2026 M\u20111\n\n    /* ---------- cell graph (edges only to cells of a different tile) ---------- */\n    const int V = N * N;\n    vector<int> cellVal(V);\n    vector<int> cellTile(V);\n    vector<int> adj[V];\n    auto id = [&](int i, int j) { return i * N + j; };\n    const int di[4] = {-1, 1, 0, 0};\n    const int dj[4] = {0, 0, -1, 1};\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int u = id(i, j);\n            cellVal[u]  = val[i][j];\n            cellTile[u] = tile[i][j];\n            for (int d = 0; d < 4; ++d) {\n                int ni = i + di[d], nj = j + dj[d];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                int v = id(ni, nj);\n                if (tile[ni][nj] != tile[i][j]) adj[u].push_back(v);\n            }\n        }\n    }\n\n    const int startCell = id(si, sj);\n    const int startTile = cellTile[startCell];\n\n    /* ---------- randomised greedy walks ---------- */\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    const int MAX_TRIES = 720000;               // a bit more trials\n    vector<int> visitedTile(M, 0);\n    int curToken = 1;\n\n    string bestPath;\n    int bestScore = -1;\n\n    for (int attempt = 0; attempt < MAX_TRIES; ++attempt) {\n        ++curToken;\n        visitedTile[startTile] = curToken;       // start tile already used\n\n        int cur = startCell;\n        int curScore = cellVal[cur];\n        string path;\n        path.reserve(2500);                     // avoid reallocations\n\n        /* random parameters for this trial */\n        int randProb = 5 + (rng() % 46);         // 5 \u2026 50 %\n        int gamma    = rng() % 81;                // 0 \u2026 80\n        int heurType = rng() % 5;                 // 0 \u2026 4\n\n        while (true) {\n            /* collect admissible neighbours (different, still unvisited tile) */\n            int cand[4];\n            int candCnt = 0;\n            for (int nb : adj[cur]) {\n                int ntile = cellTile[nb];\n                if (visitedTile[ntile] != curToken)\n                    cand[candCnt++] = nb;\n            }\n            if (candCnt == 0) break;             // stuck\n\n            /* small chance to pick a completely random neighbour */\n            if (static_cast<int>(rng() % 100) < randProb) {\n                int idx = rng() % candCnt;\n                int nxt = cand[idx];\n                // direction character\n                int fi = cur / N, fj = cur % N;\n                int ti = nxt / N, tj = nxt % N;\n                char mc;\n                if (ti == fi - 1 && tj == fj) mc = 'U';\n                else if (ti == fi + 1 && tj == fj) mc = 'D';\n                else if (ti == fi && tj == fj - 1) mc = 'L';\n                else mc = 'R';\n                path.push_back(mc);\n                cur = nxt;\n                visitedTile[cellTile[cur]] = curToken;\n                curScore += cellVal[cur];\n                continue;\n            }\n\n            /* evaluate all candidates */\n            int bestHeur = INT_MIN;\n            int bestNext = -1;\n            for (int i = 0; i < candCnt; ++i) {\n                int nb = cand[i];\n                int value = cellVal[nb];\n                int measure = 0;\n\n                if (heurType == 0) {               // degree (dynamic)\n                    int cnt = 0;\n                    for (int nb2 : adj[nb])\n                        if (visitedTile[cellTile[nb2]] != curToken)\n                            ++cnt;\n                    measure = cnt;\n                } else if (heurType == 1) {         // sum / 10 (dynamic)\n                    for (int nb2 : adj[nb])\n                        if (visitedTile[cellTile[nb2]] != curToken)\n                            measure += cellVal[nb2];\n                    measure /= 10;\n                } else if (heurType == 2) {         // max (dynamic)\n                    for (int nb2 : adj[nb])\n                        if (visitedTile[cellTile[nb2]] != curToken)\n                            measure = max(measure, cellVal[nb2]);\n                } else if (heurType == 3) {         // degree + max (dynamic)\n                    int cnt = 0, mx = 0;\n                    for (int nb2 : adj[nb]) {\n                        if (visitedTile[cellTile[nb2]] != curToken) {\n                            ++cnt;\n                            mx = max(mx, cellVal[nb2]);\n                        }\n                    }\n                    measure = cnt + mx;\n                } else {                            // value * degree (dynamic)\n                    int cnt = 0;\n                    for (int nb2 : adj[nb])\n                        if (visitedTile[cellTile[nb2]] != curToken)\n                            ++cnt;\n                    measure = value * cnt;\n                }\n\n                int heur = value + gamma * measure;\n                // tiny random noise to break ties\n                heur += (rng() & 1);\n\n                if (heur > bestHeur) {\n                    bestHeur = heur;\n                    bestNext = nb;\n                } else if (heur == bestHeur && (rng() & 1)) {\n                    bestNext = nb;\n                }\n            }\n\n            /* perform the chosen step */\n            int nxt = bestNext;\n            int fi = cur / N, fj = cur % N;\n            int ti = nxt / N, tj = nxt % N;\n            char mc;\n            if (ti == fi - 1 && tj == fj) mc = 'U';\n            else if (ti == fi + 1 && tj == fj) mc = 'D';\n            else if (ti == fi && tj == fj - 1) mc = 'L';\n            else mc = 'R';\n            path.push_back(mc);\n            cur = nxt;\n            visitedTile[cellTile[cur]] = curToken;\n            curScore += cellVal[cur];\n        }\n\n        if (curScore > bestScore) {\n            bestScore = curScore;\n            bestPath = path;\n        }\n    }\n\n    cout << bestPath << '\\n';\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    constexpr int N = 30;\n    constexpr int V = N * N;\n    constexpr double INF = 1e100;\n    constexpr double INIT_W = 5000.0;\n    constexpr double MIN_W = 500.0;\n    constexpr double MAX_W = 15000.0;\n    constexpr double ALPHA = 0.23;               // <-- changed from 0.22\n    constexpr double FACTOR_MIN = 0.5;\n    constexpr double FACTOR_MAX = 2.0;\n\n    /* edge weight estimates */\n    double hor[N][N - 1];\n    double ver[N - 1][N];\n\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N - 1; ++j)\n            hor[i][j] = INIT_W;\n    for (int i = 0; i < N - 1; ++i)\n        for (int j = 0; j < N; ++j)\n            ver[i][j] = INIT_W;\n\n    auto idx = [&](int i, int j) { return i * N + j; };\n\n    for (int q = 0; q < 1000; ++q) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) break;\n\n        const int s = idx(si, sj);\n        const int t = idx(ti, tj);\n\n        /* Dijkstra with current estimates */\n        vector<double> dist(V, INF);\n        vector<int> prev(V, -1);\n        vector<char> mv(V, 0);\n        dist[s] = 0.0;\n        using Node = pair<double, int>;\n        priority_queue<Node, vector<Node>, greater<Node>> pq;\n        pq.emplace(0.0, s);\n\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u] + 1e-12) continue;\n            if (u == t) break;\n            const int ui = u / N, uj = u % N;\n\n            // up\n            if (ui > 0) {\n                const int v = idx(ui - 1, uj);\n                const double w = ver[ui - 1][uj];\n                const double nd = d + w;\n                if (nd + 1e-12 < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    mv[v] = 'U';\n                    pq.emplace(nd, v);\n                }\n            }\n            // down\n            if (ui < N - 1) {\n                const int v = idx(ui + 1, uj);\n                const double w = ver[ui][uj];\n                const double nd = d + w;\n                if (nd + 1e-12 < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    mv[v] = 'D';\n                    pq.emplace(nd, v);\n                }\n            }\n            // left\n            if (uj > 0) {\n                const int v = idx(ui, uj - 1);\n                const double w = hor[ui][uj - 1];\n                const double nd = d + w;\n                if (nd + 1e-12 < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    mv[v] = 'L';\n                    pq.emplace(nd, v);\n                }\n            }\n            // right\n            if (uj < N - 1) {\n                const int v = idx(ui, uj + 1);\n                const double w = hor[ui][uj];\n                const double nd = d + w;\n                if (nd + 1e-12 < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    mv[v] = 'R';\n                    pq.emplace(nd, v);\n                }\n            }\n        }\n\n        /* rebuild the path */\n        string path;\n        for (int cur = t; cur != s; cur = prev[cur])\n            path.push_back(mv[cur]);\n        reverse(path.begin(), path.end());\n\n        /* output */\n        cout << path << '\\n' << flush;\n\n        /* receive noisy length */\n        long long noisy;\n        cin >> noisy;\n\n        /* estimated length of the printed path */\n        double est = 0.0;\n        int ci = si, cj = sj;\n        for (char c : path) {\n            if (c == 'U') { est += ver[ci - 1][cj]; --ci; }\n            else if (c == 'D') { est += ver[ci][cj]; ++ci; }\n            else if (c == 'L') { est += hor[ci][cj - 1]; --cj; }\n            else if (c == 'R') { est += hor[ci][cj]; ++cj; }\n        }\n\n        /* multiplicative update (power version) */\n        const double ratio = static_cast<double>(noisy) / est;\n        double factor = pow(ratio, ALPHA);\n        if (factor < FACTOR_MIN) factor = FACTOR_MIN;\n        if (factor > FACTOR_MAX) factor = FACTOR_MAX;\n\n        /* apply the factor to every edge of the printed path */\n        ci = si; cj = sj;\n        for (char c : path) {\n            if (c == 'U') {\n                double &w = ver[ci - 1][cj];\n                w *= factor;\n                if (w < MIN_W) w = MIN_W;\n                if (w > MAX_W) w = MAX_W;\n                --ci;\n            } else if (c == 'D') {\n                double &w = ver[ci][cj];\n                w *= factor;\n                if (w < MIN_W) w = MIN_W;\n                if (w > MAX_W) w = MAX_W;\n                ++ci;\n            } else if (c == 'L') {\n                double &w = hor[ci][cj - 1];\n                w *= factor;\n                if (w < MIN_W) w = MIN_W;\n                if (w > MAX_W) w = MAX_W;\n                --cj;\n            } else if (c == 'R') {\n                double &w = hor[ci][cj];\n                w *= factor;\n                if (w < MIN_W) w = MIN_W;\n                if (w > MAX_W) w = MAX_W;\n                ++cj;\n            }\n        }\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\n/***  global data  ***/\nint N = 20;                              // board size (fixed)\nint totalM;                              // \u03a3 multiplicity = M\nint curC, bestC;                         // weighted number of present strings\n\n// character encoding: 'A'..'H' -> 0..7\nint chCode[256];\n// powers of 8, 8^k (k \u2264 12)\nuint64_t pow8[13];\n\n// distinct strings\nunordered_map<unsigned long long, int> str2idx;\nvector<int> mult;\nvector<int> occ;\nint uniqCnt;\n\n// substring description\nstruct SubInfo {\n    uint8_t start_i, start_j;\n    uint8_t dir;          // 0 = horizontal, 1 = vertical\n    uint8_t len;\n};\nvector<SubInfo> subs;\nvector<uint64_t> curCode;\nvector<int> curIdx;\n\n// for each cell: list of (substring id, offset inside the substring)\nvector<vector<pair<int, uint8_t>>> cellSubs;\n\n// current board and best board\nvector<string> grid;\nvector<string> bestGrid;\n\n/***  helpers  ***/\ninline unsigned long long encodeString(const string &s) {\n    unsigned long long code = 0;\n    for (char ch : s) code = (code << 3) | (unsigned long long)chCode[(unsigned char)ch];\n    return code;\n}\n\n/***  initial evaluation from a given board ***/\nvoid initFromGrid(const vector<string> &g) {\n    fill(occ.begin(), occ.end(), 0);\n    curC = 0;\n    int S = (int)subs.size();\n    for (int sid = 0; sid < S; ++sid) {\n        const SubInfo &inf = subs[sid];\n        unsigned long long code = 0;\n        for (int p = 0; p < inf.len; ++p) {\n            int r = (inf.dir == 0) ? inf.start_i\n                                    : (inf.start_i + p) % N;\n            int c = (inf.dir == 0) ? (inf.start_j + p) % N\n                                    : inf.start_j;\n            char ch = g[r][c];\n            code = (code << 3) | (unsigned long long)chCode[(unsigned char)ch];\n        }\n        unsigned long long key = (code << 4) | (unsigned long long)inf.len;\n        int idx = -1;\n        auto it = str2idx.find(key);\n        if (it != str2idx.end()) idx = it->second;\n        curIdx[sid] = idx;\n        curCode[sid] = code;\n        if (idx != -1) occ[idx]++;\n    }\n    for (int i = 0; i < uniqCnt; ++i)\n        if (occ[i] > 0) curC += mult[i];\n}\n\n/***  compute delta for a single cell change ***/\nint computeDelta(int cell, char newChar) {\n    int r = cell / N;\n    int c = cell % N;\n    char oldChar = grid[r][c];\n    if (oldChar == newChar) return 0;\n    int oldVal = chCode[(unsigned char)oldChar];\n    int newVal = chCode[(unsigned char)newChar];\n    int delta = 0;\n    for (const auto &pr : cellSubs[cell]) {\n        int sid = pr.first;\n        int offset = pr.second;\n        const SubInfo &inf = subs[sid];\n        int len = inf.len;\n        int exp = len - 1 - offset;\n        unsigned long long oldCodeSub = curCode[sid];\n        unsigned long long newCodeSub = oldCodeSub\n                                      - (unsigned long long)oldVal * pow8[exp]\n                                      + (unsigned long long)newVal * pow8[exp];\n        unsigned long long newKey = (newCodeSub << 4) | (unsigned long long)len;\n        int newIdx = -1;\n        auto it = str2idx.find(newKey);\n        if (it != str2idx.end()) newIdx = it->second;\n        int oldIdx = curIdx[sid];\n        if (oldIdx == newIdx) continue;\n        if (oldIdx != -1) {\n            if (occ[oldIdx] == 1) delta -= mult[oldIdx];\n        }\n        if (newIdx != -1) {\n            if (occ[newIdx] == 0) delta += mult[newIdx];\n        }\n    }\n    return delta;\n}\n\n/***  apply an accepted move ***/\nvoid applyDelta(int cell, char newChar) {\n    int r = cell / N;\n    int c = cell % N;\n    char oldChar = grid[r][c];\n    if (oldChar == newChar) return;\n    int oldVal = chCode[(unsigned char)oldChar];\n    int newVal = chCode[(unsigned char)newChar];\n    for (const auto &pr : cellSubs[cell]) {\n        int sid = pr.first;\n        int offset = pr.second;\n        const SubInfo &inf = subs[sid];\n        int len = inf.len;\n        int exp = len - 1 - offset;\n        unsigned long long oldCodeSub = curCode[sid];\n        unsigned long long newCodeSub = oldCodeSub\n                                      - (unsigned long long)oldVal * pow8[exp]\n                                      + (unsigned long long)newVal * pow8[exp];\n        unsigned long long newKey = (newCodeSub << 4) | (unsigned long long)len;\n        int newIdx = -1;\n        auto it = str2idx.find(newKey);\n        if (it != str2idx.end()) newIdx = it->second;\n        int oldIdx = curIdx[sid];\n        if (oldIdx == newIdx) {\n            curCode[sid] = newCodeSub;\n            curIdx[sid] = newIdx;\n            continue;\n        }\n        if (oldIdx != -1) {\n            if (occ[oldIdx] == 1) curC -= mult[oldIdx];\n            --occ[oldIdx];\n        }\n        if (newIdx != -1) {\n            if (occ[newIdx] == 0) curC += mult[newIdx];\n            ++occ[newIdx];\n        }\n        curCode[sid] = newCodeSub;\n        curIdx[sid] = newIdx;\n    }\n    grid[r][c] = newChar;\n}\n\n/***  run a single hill\u2011climbing search ***/\nvoid runSearch(double timeLimit) {\n    // fresh random generator for this restart\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    // random initial board\n    grid.assign(N, string(N, 'A'));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            grid[i][j] = char('A' + rng() % 8);\n\n    initFromGrid(grid);\n\n    auto start = chrono::steady_clock::now();\n    // scale the number of iterations to the given time limit\n    int maxIter = (int)(timeLimit * 1'000'000.0 / 2.8);\n    if (maxIter < 100000) maxIter = 100000;   // at least this many\n\n    for (int iter = 0; iter < maxIter; ++iter) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed >= timeLimit) break;\n\n        int cell = rng() % (N * N);\n        int r = cell / N, c = cell % N;\n        char oldChar = grid[r][c];\n\n        // evaluate all 8 possible new letters\n        int bestDelta = INT_MIN;\n        char bestChar = oldChar;\n        for (char cand = 'A'; cand <= 'H'; ++cand) {\n            if (cand == oldChar) continue;\n            int delta = computeDelta(cell, cand);\n            if (delta > bestDelta) {\n                bestDelta = delta;\n                bestChar = cand;\n            }\n        }\n\n        bool accept = false;\n        if (bestDelta > 0) {\n            accept = true;\n        } else {\n            int rprob = rng() % 100;\n            if (bestDelta == 0 && rprob < 10) accept = true;      // 10%\n            else if (bestDelta < 0 && rprob < 1) accept = true;   // 1% (back to original)\n        }\n\n        if (accept) {\n            applyDelta(cell, bestChar);\n            if (curC > bestC) {\n                bestC = curC;\n                bestGrid = grid;\n                if (bestC == totalM) break;               // perfect!\n            }\n        }\n    }\n}\n\n/***  main ***/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M;\n    if (!(cin >> N >> M)) return 0;\n    totalM = M;\n\n    // character encoding\n    fill(begin(chCode), end(chCode), -1);\n    for (char ch = 'A'; ch <= 'H'; ++ch) chCode[(unsigned char)ch] = ch - 'A';\n\n    // read strings, build distinct set\n    vector<string> inputs(M);\n    for (int i = 0; i < M; ++i) cin >> inputs[i];\n    for (const string &s : inputs) {\n        unsigned long long code = encodeString(s);\n        unsigned long long key = (code << 4) | (unsigned long long)s.size();\n        auto it = str2idx.find(key);\n        if (it == str2idx.end()) {\n            int id = (int)mult.size();\n            str2idx[key] = id;\n            mult.push_back(1);\n        } else {\n            ++mult[it->second];\n        }\n    }\n    uniqCnt = (int)mult.size();\n    occ.assign(uniqCnt, 0);\n\n    // speed up hash table\n    str2idx.reserve(uniqCnt * 2);\n\n    // powers of 8\n    pow8[0] = 1;\n    for (int i = 1; i <= 12; ++i) pow8[i] = pow8[i - 1] * 8ULL;\n\n    // build all substrings and cell\u2192substring lists\n    subs.reserve(8800);\n    cellSubs.assign(N * N, {});\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            // horizontal\n            for (int len = 2; len <= 12; ++len) {\n                SubInfo inf;\n                inf.start_i = (uint8_t)i;\n                inf.start_j = (uint8_t)j;\n                inf.dir = 0;\n                inf.len = (uint8_t)len;\n                int sid = (int)subs.size();\n                subs.push_back(inf);\n                for (int p = 0; p < len; ++p) {\n                    int cj = (j + p) % N;\n                    int cell = i * N + cj;\n                    cellSubs[cell].push_back({sid, (uint8_t)p});\n                }\n            }\n            // vertical\n            for (int len = 2; len <= 12; ++len) {\n                SubInfo inf;\n                inf.start_i = (uint8_t)i;\n                inf.start_j = (uint8_t)j;\n                inf.dir = 1;\n                inf.len = (uint8_t)len;\n                int sid = (int)subs.size();\n                subs.push_back(inf);\n                for (int p = 0; p < len; ++p) {\n                    int ri = (i + p) % N;\n                    int cell = ri * N + j;\n                    cellSubs[cell].push_back({sid, (uint8_t)p});\n                }\n            }\n        }\n    }\n\n    // reserve space for each cell's list (max \u2248 156)\n    for (auto &v : cellSubs) v.reserve(160);\n\n    curCode.assign(subs.size(), 0);\n    curIdx.assign(subs.size(), -1);\n\n    // global best\n    bestC = -1;\n    bestGrid.assign(N, string(N, 'A'));\n\n    // ----- three independent restarts -----\n    const double totalTime = 2.8;          // seconds\n    const double perRun = 0.9;            // seconds per restart (optimal)\n\n    auto overallStart = chrono::steady_clock::now();\n\n    for (int run = 0; run < 3; ++run) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - overallStart).count();\n        double remain = totalTime - elapsed;\n        if (remain < 0.1) break;            // no time left\n        runSearch(min(perRun, remain));\n        if (bestC == totalM) break;         // perfect!\n    }\n\n    // output best board\n    for (int i = 0; i < N; ++i) cout << bestGrid[i] << '\\n';\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing pii = pair<int,int>;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, si, sj;\n    if(!(cin >> N >> si >> sj)) return 0;\n    vector<string> g(N);\n    for (int i = 0; i < N; ++i) cin >> g[i];\n\n    /* ---------- road cells ---------- */\n    vector<vector<int>> id(N, vector<int>(N, -1));\n    vector<pii> pos;                     // id \u2192 (i , j)\n    vector<int> w;                       // entering time\n    int R = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (g[i][j] != '#') {\n                id[i][j] = R++;\n                pos.emplace_back(i, j);\n                w.push_back(g[i][j] - '0');\n            }\n\n    /* ---------- horizontal segments ---------- */\n    vector<vector<int>> rowSegId(N, vector<int>(N, -1));\n    vector<vector<int>> rowSegMembers;               // list of cell ids\n    int rowSegCnt = 0;\n    for (int i = 0; i < N; ++i) {\n        int j = 0;\n        while (j < N) {\n            if (g[i][j] == '#') { ++j; continue; }\n            int seg = rowSegCnt++;\n            rowSegMembers.emplace_back();\n            while (j < N && g[i][j] != '#') {\n                int cid = id[i][j];\n                rowSegId[i][j] = seg;\n                rowSegMembers.back().push_back(cid);\n                ++j;\n            }\n        }\n    }\n\n    /* ---------- vertical segments ---------- */\n    vector<vector<int>> colSegId(N, vector<int>(N, -1));\n    vector<vector<int>> colSegMembers;\n    int colSegCnt = 0;\n    for (int j = 0; j < N; ++j) {\n        int i = 0;\n        while (i < N) {\n            if (g[i][j] == '#') { ++i; continue; }\n            int seg = colSegCnt++;\n            colSegMembers.emplace_back();\n            while (i < N && g[i][j] != '#') {\n                int cid = id[i][j];\n                colSegId[i][j] = seg;\n                colSegMembers.back().push_back(cid);\n                ++i;\n            }\n        }\n    }\n\n    /* cell \u2192 its two segment ids */\n    vector<int> cellRowSeg(R), cellColSeg(R);\n    for (int cid = 0; cid < R; ++cid) {\n        int i = pos[cid].first, j = pos[cid].second;\n        cellRowSeg[cid] = rowSegId[i][j];\n        cellColSeg[cid] = colSegId[i][j];\n    }\n\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    const char dch[4] = {'U','D','L','R'};\n\n    auto dirFromDelta = [&](int dr, int dc)->char{\n        if (dr==-1 && dc==0) return 'U';\n        if (dr==1  && dc==0) return 'D';\n        if (dr==0 && dc==-1) return 'L';\n        if (dr==0 && dc==1) return 'R';\n        return '?';\n    };\n\n    /* ----- counters for still invisible cells ----- */\n    vector<int> rowCnt(rowSegCnt), colCnt(colSegCnt);\n    for (int rs = 0; rs < rowSegCnt; ++rs) rowCnt[rs] = (int)rowSegMembers[rs].size();\n    for (int cs = 0; cs < colSegCnt; ++cs) colCnt[cs] = (int)colSegMembers[cs].size();\n\n    vector<char> rowCover(rowSegCnt, 0), colCover(colSegCnt, 0);\n    vector<char> visible(R, 0);\n    int coveredCnt = 0;\n\n    auto visitRowSeg = [&](int rs) {\n        if (rowCover[rs]) return;\n        rowCover[rs] = 1;\n        for (int cid : rowSegMembers[rs]) {\n            if (!visible[cid]) {\n                visible[cid] = 1;\n                ++coveredCnt;\n                int cs = cellColSeg[cid];\n                --colCnt[cs];\n            }\n        }\n        rowCnt[rs] = 0;\n    };\n    auto visitColSeg = [&](int cs) {\n        if (colCover[cs]) return;\n        colCover[cs] = 1;\n        for (int cid : colSegMembers[cs]) {\n            if (!visible[cid]) {\n                visible[cid] = 1;\n                ++coveredCnt;\n                int rs = cellRowSeg[cid];\n                --rowCnt[rs];\n            }\n        }\n        colCnt[cs] = 0;\n    };\n\n    int startId = id[si][sj];\n    /* initialise the start row / column as visited */\n    visitRowSeg(cellRowSeg[startId]);\n    visitColSeg(cellColSeg[startId]);\n\n    /* ----- greedy walk ----- */\n    string answer;\n    answer.reserve(20000);\n    long long totalCost = 0;\n    int ci = si, cj = sj;               // current position\n    int curId = startId;\n\n    while (coveredCnt < R) {\n        int bestDir = -1;\n        int bestInc = -1;\n        int bestCost = INT_MAX;\n        int bestNi = -1, bestNj = -1;\n\n        for (int d = 0; d < 4; ++d) {\n            int ni = ci + dx[d], nj = cj + dy[d];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            if (id[ni][nj] == -1) continue;\n            int nid = id[ni][nj];\n            int rs = cellRowSeg[nid];\n            int cs = cellColSeg[nid];\n\n            int inc = 0;\n            bool rowNot = !rowCover[rs];\n            bool colNot = !colCover[cs];\n            if (rowNot && rowCnt[rs] > 0) inc += rowCnt[rs];\n            if (colNot && colCnt[cs] > 0) inc += colCnt[cs];\n            if (rowNot && colNot && rowCnt[rs] > 0 && colCnt[cs] > 0) inc -= 1;\n\n            if (inc > bestInc || (inc == bestInc && w[nid] < bestCost)) {\n                bestInc = inc;\n                bestCost = w[nid];\n                bestDir = d;\n                bestNi = ni; bestNj = nj;\n            }\n        }\n\n        if (bestInc > 0) {                         // move with new coverage\n            answer.push_back(dch[bestDir]);\n            totalCost += w[id[bestNi][bestNj]];\n            ci = bestNi; cj = bestNj;\n            curId = id[ci][cj];\n            int rs = cellRowSeg[curId];\n            int cs = cellColSeg[curId];\n            if (!rowCover[rs]) visitRowSeg(rs);\n            if (!colCover[cs]) visitColSeg(cs);\n        } else {                                   // no new coverage \u2013 go to nearest invisible cell\n            static int dist[70][70];\n            static int parent[70][70];\n            for (int i = 0; i < N; ++i)\n                for (int j = 0; j < N; ++j) {\n                    dist[i][j] = -1;\n                    parent[i][j] = -1;\n                }\n            queue<pii> q;\n            dist[ci][cj] = 0;\n            q.emplace(ci, cj);\n            int ti = -1, tj = -1;\n            while (!q.empty()) {\n                auto [x, y] = q.front(); q.pop();\n\n                // check if this cell is invisible (but not the start)\n                if (!(x == ci && y == cj)) {\n                    int cid = id[x][y];\n                    if (!visible[cid]) {\n                        ti = x; tj = y;\n                        break;\n                    }\n                }\n\n                for (int dir = 0; dir < 4; ++dir) {\n                    int nx = x + dx[dir], ny = y + dy[dir];\n                    if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n                    if (id[nx][ny] == -1) continue;\n                    if (dist[nx][ny] != -1) continue;\n                    dist[nx][ny] = dist[x][y] + 1;\n                    parent[nx][ny] = x * N + y;\n                    q.emplace(nx, ny);\n                }\n            }\n\n            if (ti == -1) {\n                // shouldn't happen, but just in case\n                break;\n            }\n\n            // reconstruct path: find the first step after current position\n            int cx = ti, cy = tj;\n            // walk back until parent is the current position\n            while (!(cx == ci && cy == cj)) {\n                int p = parent[cx][cy];\n                if (p == -1) break; // shouldn't happen\n                cx = p / N; cy = p % N;\n                if (cx == ci && cy == cj) break;\n                // continue to next\n            }\n            // now cx,cy should be the neighbour of current position\n            // but we need to find the one right after ci,cj\n            // let's redo: go from target back to just after start\n            vector<pii> path;\n            int tx = ti, ty = tj;\n            while (!(tx == ci && ty == cj)) {\n                path.emplace_back(tx, ty);\n                int p = parent[tx][ty];\n                if (p == -1) break;\n                tx = p / N; ty = p % N;\n            }\n            // path[0] is the target, path.back() is the neighbour of start\n            if (path.empty()) {\n                // shouldn't happen\n                break;\n            }\n            int nx = path.back().first, ny = path.back().second;\n            answer.push_back(dirFromDelta(nx - ci, ny - cj));\n            totalCost += w[id[nx][ny]];\n            ci = nx; cj = ny;\n            curId = id[ci][cj];\n            int rs = cellRowSeg[curId];\n            int cs = cellColSeg[curId];\n            if (!rowCover[rs]) visitRowSeg(rs);\n            if (!colCover[cs]) visitColSeg(cs);\n        }\n    }\n\n    /* ----- shortest way back to start (Dijkstra) ----- */\n    const long long INF = (1LL << 60);\n    vector<long long> dist(R, INF);\n    vector<int> pv(R, -1);\n    using Node = pair<long long,int>;\n    priority_queue<Node, vector<Node>, greater<Node>> pq;\n    dist[startId] = 0;\n    pq.emplace(0, startId);\n    while (!pq.empty()) {\n        auto [du, u] = pq.top(); pq.pop();\n        if (du != dist[u]) continue;\n        int ux = pos[u].first, uy = pos[u].second;\n        for (int dir = 0; dir < 4; ++dir) {\n            int vx = ux + dx[dir], vy = uy + dy[dir];\n            if (vx < 0 || vx >= N || vy < 0 || vy >= N) continue;\n            int v = id[vx][vy];\n            if (v == -1) continue;\n            long long nd = du + w[v];\n            if (nd < dist[v]) {\n                dist[v] = nd;\n                pv[v] = u;\n                pq.emplace(nd, v);\n            }\n        }\n    }\n\n    // reconstruct path from cur back to start (reverse order)\n    vector<int> revPath;\n    int node = curId;\n    while (true) {\n        revPath.push_back(node);\n        if (node == startId) break;\n        if (pv[node] == -1) break; // shouldn't happen\n        node = pv[node];\n    }\n    // append the moves: from cur (index 0) to start (last index)\n    for (int k = 0; k < (int)revPath.size() - 1; ++k) {\n        int a = revPath[k];\n        int b = revPath[k+1];\n        int ax = pos[a].first, ay = pos[a].second;\n        int bx = pos[b].first, by = pos[b].second;\n        answer.push_back(dirFromDelta(bx - ax, by - ay));\n        totalCost += w[b];\n    }\n\n    cout << answer << '\\n';\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** task priority: difficulty \u00d7 (depth+1) \u00d7 (height+1)\u00b2 ***/\nstruct ReadyTask {\n    long long score;\n    int id;                     // task index (0\u2011based)\n    bool operator<(const ReadyTask& other) const {\n        return score < other.score;          // max\u2011heap\n    }\n};\n\n/*** Hungarian algorithm for a square cost matrix ***/\nstruct Hungarian {\n    int n, m;\n    vector<vector<long long>> a;\n    vector<long long> u, v;\n    vector<int> p, way;\n\n    Hungarian(int n_, int m_, const vector<vector<long long>>& cost)\n        : n(n_), m(m_), a(cost), u(n_+1), v(m_+1), p(m_+1), way(m_+1) {}\n\n    long long solve() {\n        for (int i = 1; i <= n; ++i) {\n            p[0] = i;\n            int j0 = 0;\n            vector<long long> minv(m+1, LLONG_MAX);\n            vector<char> used(m+1, false);\n            do {\n                used[j0] = true;\n                int i0 = p[j0];\n                long long delta = LLONG_MAX;\n                int j1 = 0;\n                for (int j = 1; j <= m; ++j) if (!used[j]) {\n                    long long cur = a[i0-1][j-1] - u[i0] - v[j];\n                    if (cur < minv[j]) {\n                        minv[j] = cur;\n                        way[j] = j0;\n                    }\n                    if (minv[j] < delta) {\n                        delta = minv[j];\n                        j1 = j;\n                    }\n                }\n                for (int j = 0; j <= m; ++j) {\n                    if (used[j]) {\n                        u[p[j]] += delta;\n                        v[j] -= delta;\n                    } else {\n                        minv[j] -= delta;\n                    }\n                }\n                j0 = j1;\n            } while (p[j0] != 0);\n            do {\n                int j1 = way[j0];\n                p[j0] = p[j1];\n                j0 = j1;\n            } while (j0);\n        }\n        return -v[0];\n    }\n\n    vector<int> assignment() const {\n        vector<int> match(n+1, 0);\n        for (int j = 1; j <= m; ++j)\n            if (p[j] >= 1 && p[j] <= n)\n                match[p[j]] = j;\n        return match;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K, R;\n    if (!(cin >> N >> M >> K >> R)) return 0;\n\n    /* ----- read required skill vectors ----- */\n    vector<vector<int>> d(N, vector<int>(K));\n    for (int i = 0; i < N; ++i)\n        for (int k = 0; k < K; ++k) cin >> d[i][k];\n\n    /* ----- read dependencies ----- */\n    vector<vector<int>> children(N);\n    vector<int> indeg(N, 0);\n    for (int i = 0; i < R; ++i) {\n        int u, v;\n        cin >> u >> v;\n        --u; --v;\n        children[u].push_back(v);\n        ++indeg[v];\n    }\n\n    /* ----- difficulty of each task ----- */\n    vector<long long> diff(N, 0);\n    for (int i = 0; i < N; ++i) {\n        long long s = 0;\n        for (int k = 0; k < K; ++k) s += d[i][k];\n        diff[i] = s;\n    }\n\n    /* ----- compute depth (distance from sources) ----- */\n    vector<int> indeg_tmp = indeg;\n    vector<int> depth(N, 0);\n    queue<int> q;\n    for (int i = 0; i < N; ++i)\n        if (indeg_tmp[i] == 0) q.push(i);\n    while (!q.empty()) {\n        int v = q.front(); q.pop();\n        for (int nb : children[v]) {\n            depth[nb] = max(depth[nb], depth[v] + 1);\n            if (--indeg_tmp[nb] == 0) q.push(nb);\n        }\n    }\n\n    /* ----- compute height (distance to sinks) ----- */\n    vector<int> height(N, 0);\n    for (int i = N-1; i >= 0; --i) {\n        int best = 0;\n        for (int nb : children[i])\n            best = max(best, height[nb] + 1);\n        height[i] = best;\n    }\n\n    /* ----- initialise ready tasks ----- */\n    priority_queue<ReadyTask> ready;\n    for (int i = 0; i < N; ++i)\n        if (indeg[i] == 0)\n            ready.push({diff[i] * (depth[i] + 1) * (height[i] + 1) * (height[i] + 1), i});\n\n    /* ----- data for each member ----- */\n    vector<long long> totalTime(M, 0), totalDiff(M, 0);\n    vector<vector<int>> lower(M, vector<int>(K, 0));\n    vector<int> curTask(M, -1);\n    vector<int> startDay(N, -1);\n    vector<int> finishedCnt(M, 0);\n\n    const long long EPS = 2;               // preference for experienced members\n\n    /* ----- predicted duration for (member, task) pair ----- */\n    auto predict_time = [&](int member, int task, int day) -> long long {\n        long long missing = 0;\n        for (int k = 0; k < K; ++k)\n            if (d[task][k] > lower[member][k])\n                missing += d[task][k] - lower[member][k];\n\n        if (missing == 0) return 1LL;\n        if (totalDiff[member] == 0)\n            return max(1LL, missing);\n\n        long long base = (missing * totalTime[member] + totalDiff[member] - 1) / totalDiff[member];\n        base = max(1LL, base);\n\n        // unknown members appear slower (exploration)\n        double factor = 1.0;\n        if (finishedCnt[member] < 4) {                // unknown threshold = 4\n            factor = max(0.12, 1.0 - day / 600.0);    // slower decay, floor 0.12\n        }\n        // confidence bonus\n        double confidence = 1.0 + 2.5 / (finishedCnt[member] + 1);\n        long long pred = (long long)(base * factor * confidence);\n        return max(1LL, pred);\n    };\n\n    int day = 1;\n    while (true) {\n        /* ----- collect idle members ----- */\n        vector<int> idle;\n        idle.reserve(M);\n        for (int j = 0; j < M; ++j)\n            if (curTask[j] == -1) idle.push_back(j);\n\n        /* ----- collect up to idle.size() hardest ready tasks ----- */\n        vector<int> readyTasks;\n        while (!ready.empty() && (int)readyTasks.size() < (int)idle.size()) {\n            ReadyTask rt = ready.top(); ready.pop();\n            readyTasks.push_back(rt.id);\n        }\n\n        /* ----- solve assignment problem for today ----- */\n        vector<pair<int,int>> assign;\n        if (!idle.empty() && !readyTasks.empty()) {\n            int n = (int)idle.size();\n            int m = (int)readyTasks.size();\n            int sz = max(n, m);\n            vector<vector<long long>> cost(sz, vector<long long>(sz, 0));\n            for (int i = 0; i < n; ++i) {\n                for (int j = 0; j < m; ++j) {\n                    long long base = predict_time(idle[i], readyTasks[j], day);\n                    // tiny preference for members with more experience\n                    long long pref = EPS * (M - finishedCnt[idle[i]]);\n                    cost[i][j] = base + pref;\n                }\n            }\n            Hungarian hungarian(sz, sz, cost);\n            hungarian.solve();\n            auto match = hungarian.assignment();\n            for (int i = 0; i < n; ++i) {\n                int job = match[i+1];\n                if (job >= 1 && job <= m) {\n                    int t = readyTasks[job-1];\n                    assign.emplace_back(idle[i] + 1, t + 1);\n                    curTask[idle[i]] = t;\n                    startDay[t] = day;\n                }\n            }\n            // tasks not assigned go back to the heap\n            vector<bool> used(m, false);\n            for (auto &p : assign) {\n                int t = p.second - 1;\n                for (int j = 0; j < m; ++j)\n                    if (readyTasks[j] == t) { used[j] = true; break; }\n            }\n            for (int j = 0; j < m; ++j)\n                if (!used[j]) {\n                    int t = readyTasks[j];\n                    ready.push({diff[t] * (depth[t] + 1) * (height[t] + 1) * (height[t] + 1), t});\n                }\n        }\n\n        /* ----- output ----- */\n        cout << assign.size();\n        for (auto &p : assign) cout << ' ' << p.first << ' ' << p.second;\n        cout << '\\n';\n        cout.flush();\n\n        /* ----- receive the list of finished members ----- */\n        int x;\n        if (!(cin >> x)) break;\n        if (x == -1) break;\n        int cnt = x;\n        vector<int> finished(cnt);\n        for (int i = 0; i < cnt; ++i) {\n            cin >> finished[i];\n            --finished[i];\n        }\n\n        /* ----- process each completed task ----- */\n        for (int w : finished) {\n            int t = curTask[w];\n            if (t == -1) continue;\n\n            int duration = day - startDay[t] + 1;\n\n            totalTime[w] += duration;\n            totalDiff[w] += diff[t];\n            ++finishedCnt[w];\n\n            if (duration == 1) {\n                // one\u2011day task \u2192 exact lower bound\n                for (int k = 0; k < K; ++k)\n                    lower[w][k] = max(lower[w][k], d[t][k]);\n            } else {\n                // longer task \u2192 weaker bound: skill >= d[t][k] - (duration - 3)\n                for (int k = 0; k < K; ++k) {\n                    int bound = max(0, d[t][k] - (duration - 3));\n                    lower[w][k] = max(lower[w][k], bound);\n                }\n            }\n\n            for (int nb : children[t]) {\n                if (--indeg[nb] == 0) {\n                    ready.push({diff[nb] * (depth[nb] + 1) * (height[nb] + 1) * (height[nb] + 1), nb});\n                }\n            }\n\n            curTask[w] = -1;\n        }\n\n        ++day;\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Order {\n    int a, b, c, d;          // pickup (a,b) , delivery (c,d)\n};\n\ninline long long manhattan(int x1, int y1, int x2, int y2) {\n    return llabs(x1 - x2) + llabs(y1 - y2);\n}\n\n/* --------------------------------------------------------------- */\n/*  compute tour length for a given permutation                    */\nstatic long long tourCost(const vector<int>& perm,\n                          const vector<long long>& start,\n                          const vector<long long>& finish,\n                          const vector<vector<int>>& D,\n                          long long insideSum)\n{\n    const int m = (int)perm.size();\n    long long cur = start[perm[0]];\n    for (int i = 0; i < m - 1; ++i) cur += D[perm[i]][perm[i + 1]];\n    cur += finish[perm[m - 1]];\n    cur += insideSum;\n    return cur;\n}\n\n/* --------------------------------------------------------------- */\n/*  cheap TSP : nearest neighbour from every start                */\nstatic long long cheapTSP(const vector<int>& orders,\n                          vector<int>& bestPerm)\n{\n    const int m = (int)orders.size();\n    vector<long long> start(m), finish(m), inside(m);\n    vector<int> pX(m), pY(m), dX(m), dY(m);\n    const int DEP = 400;\n\n    for (int i = 0; i < m; ++i) {\n        const Order& o = *((Order*)nullptr);   // dummy, see below\n    }\n\n    // fill data for the current subset\n    for (int i = 0; i < m; ++i) {\n        const Order& o = *((Order*)nullptr);\n    }\n    // we will fill it inside the function, see later\n    // (the two dummy lines are only to keep the editor happy)\n    // -----------------------------------------------------------------\n    // Real code: we need the arrays a,b,c,d from the global vector.\n    // -----------------------------------------------------------------\n    return 0; // never reached\n}\n\n/* Because the cheap TSP is tiny we write it inside the main function\n   to avoid passing many global arrays. The same holds for the full\n   improvement routine.                                             */\n\n/* --------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int DEP = 400;\n    const int N = 1000;\n    vector<Order> ord(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> ord[i].a >> ord[i].b >> ord[i].c >> ord[i].d;\n    }\n\n    /* ----  solo costs (start+inside+finish)  ---------------------- */\n    vector<long long> solo(N);\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    for (int i = 0; i < N; ++i) {\n        long long st = manhattan(DEP, DEP, ord[i].a, ord[i].b);\n        long long ins = manhattan(ord[i].a, ord[i].b, ord[i].c, ord[i].d);\n        long long fn = manhattan(ord[i].c, ord[i].d, DEP, DEP);\n        solo[i] = st + ins + fn;\n    }\n    sort(idx.begin(), idx.end(),\n         [&](int i, int j){ return solo[i] < solo[j]; });\n\n    /* ----  candidate list : the 200 best orders  ----------------- */\n    const int CAND = 200;\n    vector<int> cand;\n    cand.reserve(CAND);\n    for (int i = 0; i < CAND; ++i) cand.push_back(idx[i]);\n\n    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    const int SAMPLE = 500;               // number of random subsets\n    struct SubsetInfo {\n        vector<int> ids;   // original order numbers (0\u2011based)\n        long long cost;\n    };\n    vector<SubsetInfo> samples;\n    samples.reserve(SAMPLE + 1);\n\n    // ----- helper lambdas for a concrete subset -----------------\n    auto evaluateSubset = [&](const vector<int>& ids, bool full,\n                               vector<int>& outPerm) -> long long {\n        const int m = (int)ids.size();            // =50\n        vector<long long> start(m), finish(m), inside(m);\n        vector<int> pX(m), pY(m), dX(m), dY(m);\n        long long insideSum = 0;\n        for (int i = 0; i < m; ++i) {\n            const Order& o = ord[ids[i]];\n            pX[i] = o.a; pY[i] = o.b;\n            dX[i] = o.c; dY[i] = o.d;\n            start[i]   = manhattan(DEP, DEP, pX[i], pY[i]);\n            inside[i]  = manhattan(pX[i], pY[i], dX[i], dY[i]);\n            finish[i]  = manhattan(dX[i], dY[i], DEP, DEP);\n            insideSum += inside[i];\n        }\n        // matrix D[i][j] = distance delivery_i -> pickup_j\n        vector<vector<int>> D(m, vector<int>(m));\n        for (int i = 0; i < m; ++i)\n            for (int j = 0; j < m; ++j)\n                D[i][j] = (int)manhattan(dX[i], dY[i], pX[j], pY[j]);\n\n        // ----- cheap solution : nearest neighbour -----------------\n        long long bestCost = (1LL<<60);\n        vector<int> bestPerm;\n        for (int s = 0; s < m; ++s) {\n            vector<int> perm;\n            vector<char> used(m, 0);\n            int cur = s;\n            perm.push_back(cur);\n            used[cur] = 1;\n            for (int step = 1; step < m; ++step) {\n                int nxt = -1;\n                int bestD = INT_MAX;\n                for (int v = 0; v < m; ++v) if (!used[v]) {\n                    int d = D[cur][v];\n                    if (d < bestD) { bestD = d; nxt = v; }\n                }\n                used[nxt] = 1;\n                perm.push_back(nxt);\n                cur = nxt;\n            }\n            long long c = tourCost(perm, start, finish, D, insideSum);\n            if (c < bestCost) {\n                bestCost = c;\n                bestPerm = perm;\n            }\n        }\n\n        if (!full) {\n            outPerm = bestPerm;\n            return bestCost;\n        }\n\n        // ----- full improvement (insertion, swap, 2\u2011opt) ----------\n        vector<int> perm = bestPerm;\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            // insertion\n            for (int i = 0; i < m && !improved; ++i) {\n                for (int j = 0; j < m && !improved; ++j) if (i != j) {\n                    vector<int> np = perm;\n                    int val = np[i];\n                    np.erase(np.begin() + i);\n                    np.insert(np.begin() + j, val);\n                    long long c = tourCost(np, start, finish, D, insideSum);\n                    if (c < tourCost(perm, start, finish, D, insideSum)) {\n                        perm.swap(np);\n                        improved = true;\n                    }\n                }\n            }\n            // swap\n            if (!improved) {\n                for (int i = 0; i < m && !improved; ++i) {\n                    for (int j = i + 1; j < m && !improved; ++j) {\n                        vector<int> np = perm;\n                        swap(np[i], np[j]);\n                        long long c = tourCost(np, start, finish, D, insideSum);\n                        if (c < tourCost(perm, start, finish, D, insideSum)) {\n                            perm.swap(np);\n                            improved = true;\n                        }\n                    }\n                }\n            }\n            // 2\u2011opt (reverse a segment)\n            if (!improved) {\n                for (int i = 0; i < m - 2 && !improved; ++i) {\n                    for (int j = i + 2; j < m && !improved; ++j) {\n                        vector<int> np = perm;\n                        reverse(np.begin() + i + 1, np.begin() + j + 1);\n                        long long c = tourCost(np, start, finish, D, insideSum);\n                        if (c < tourCost(perm, start, finish, D, insideSum)) {\n                            perm.swap(np);\n                            improved = true;\n                        }\n                    }\n                }\n            }\n        }\n        outPerm = perm;\n        return tourCost(perm, start, finish, D, insideSum);\n    };\n\n    // ----- evaluate many random subsets (cheap only) ------------\n    for (int iter = 0; iter < SAMPLE; ++iter) {\n        vector<int> cand2 = cand;\n        shuffle(cand2.begin(), cand2.end(), rng);\n        vector<int> ids(cand2.begin(), cand2.begin() + 50);\n        vector<int> dummyPerm;\n        long long c = evaluateSubset(ids, false, dummyPerm);\n        samples.push_back({ids, c});\n    }\n    // also add the deterministic top\u201150 set\n    {\n        vector<int> ids(idx.begin(), idx.begin() + 50);\n        vector<int> dummy;\n        long long c = evaluateSubset(ids, false, dummy);\n        samples.push_back({ids, c});\n    }\n\n    // keep the 5 best subsets\n    const int KEEP = 5;\n    nth_element(samples.begin(),\n                samples.begin() + KEEP,\n                samples.end(),\n                [](const SubsetInfo& a, const SubsetInfo& b){ return a.cost < b.cost; });\n    samples.resize(KEEP);\n\n    // ----- full improvement on the best subsets -----------------\n    long long bestTotal = (1LL<<60);\n    vector<int> bestIds;\n    vector<int> bestPerm;\n\n    for (auto& s : samples) {\n        vector<int> perm;\n        long long c = evaluateSubset(s.ids, true, perm);\n        if (c < bestTotal) {\n            bestTotal = c;\n            bestIds = s.ids;\n            bestPerm = perm;\n        }\n    }\n\n    // ----- build the output route --------------------------------\n    // bestIds : original order numbers (0\u2011based)\n    // bestPerm : permutation of 0..49  (local index -> order in bestIds)\n\n    // sort the ids for nicer output\n    sort(bestIds.begin(), bestIds.end());\n\n    // route coordinates\n    vector<int> routeX, routeY;\n    routeX.push_back(DEP);\n    routeY.push_back(DEP);\n    for (int k = 0; k < 50; ++k) {\n        int local = bestPerm[k];\n        int orig  = bestIds[local];\n        routeX.push_back(ord[orig].a);\n        routeY.push_back(ord[orig].b);\n        routeX.push_back(ord[orig].c);\n        routeY.push_back(ord[orig].d);\n    }\n    routeX.push_back(DEP);\n    routeY.push_back(DEP);\n    const int n = (int)routeX.size();           // = 2*50+2 = 102\n\n    // ----- output -------------------------------------------------\n    cout << 50;\n    for (int id : bestIds) cout << ' ' << (id + 1);\n    cout << '\\n';\n    cout << n;\n    for (size_t i = 0; i < routeX.size(); ++i)\n        cout << ' ' << routeX[i] << ' ' << routeY[i];\n    cout << '\\n';\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** Disjoint Set Union ***/\nstruct DSU {\n    vector<int> parent, rnk;\n    DSU(int n = 0) { init(n); }\n    void init(int n) {\n        parent.resize(n);\n        rnk.assign(n, 0);\n        iota(parent.begin(), parent.end(), 0);\n    }\n    int find(int x) {\n        if (parent[x] == x) return x;\n        return parent[x] = find(parent[x]);\n    }\n    bool unite(int a, int b) {\n        a = find(a); b = find(b);\n        if (a == b) return false;\n        if (rnk[a] < rnk[b]) swap(a, b);\n        parent[b] = a;\n        if (rnk[a] == rnk[b]) ++rnk[a];\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 400;\n    const int M = 1995;\n\n    // Read coordinates\n    vector<long long> X(N), Y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> X[i] >> Y[i];\n    }\n\n    // Read edge list and precompute d_i\n    vector<int> U(M), V(M), D(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> U[i] >> V[i];\n        long long dx = X[U[i]] - X[V[i]];\n        long long dy = Y[U[i]] - Y[V[i]];\n        double dist = sqrt((double)dx * dx + (double)dy * dy);\n        D[i] = (int)llround(dist);\n    }\n\n    DSU dsu(N);\n    int components = N;\n\n    // Process each edge\n    for (int i = 0; i < M; ++i) {\n        long long len;\n        cin >> len;\n\n        // If edge creates a cycle, reject\n        if (dsu.find(U[i]) == dsu.find(V[i])) {\n            cout << 0 << '\\n';\n            cout.flush();\n            continue;\n        }\n\n        // Edge connects different components\n        bool accept = false;\n\n        // Forced acceptance: if we can't afford to reject any more edges\n        if ((M - i) <= components - 1) {\n            accept = true;\n        } else {\n            // Prefer shorter edges (len <= 2.5 * d_i)\n            // Also accept edges with small d_i (important for connectivity)\n            if (len <= 2.5L * D[i] || D[i] <= 20) {\n                accept = true;\n            }\n        }\n\n        if (accept) {\n            cout << 1 << '\\n';\n            dsu.unite(U[i], V[i]);\n            --components;\n        } else {\n            cout << 0 << '\\n';\n        }\n        cout.flush();\n    }\n\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing pii = pair<int,int>;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int dr[4] = {-1, 1, 0, 0};\n    const int dc[4] = {0, 0, -1, 1};\n    const char wallChar[4] = {'u','d','l','r'};\n    const char moveChar[4] = {'U','D','L','R'};\n\n    /* ---------- input ---------- */\n    int N;\n    if (!(cin >> N)) return 0;\n    vector<pii> petPos(N);\n    vector<int> petType(N);\n    for (int i = 0; i < N; ++i)\n        cin >> petPos[i].first >> petPos[i].second >> petType[i];\n    int M;\n    cin >> M;\n    vector<pii> humanPos(M);\n    for (int i = 0; i < M; ++i)\n        cin >> humanPos[i].first >> humanPos[i].second;\n\n    bool wall[31][31] = {};\n\n    // Define corner positions (highest priority for isolation)\n    const pii corners[4] = {{1,1}, {1,30}, {30,1}, {30,30}};\n    const pii edges[12] = {\n        {1,2}, {1,3}, {1,4}, {1,5},\n        {30,2}, {30,3}, {30,4}, {30,5},\n        {2,1}, {3,1}, {4,1}, {5,1}\n    };\n\n    // Assign each human a target: prefer corners, then edges, then stay\n    vector<pii> target(M);\n    vector<bool> cornerUsed(4, false);\n    vector<bool> edgeUsed(12, false);\n    \n    // First try to assign humans to corners\n    for (int i = 0; i < M; ++i) {\n        int bestDist = 1000;\n        pii bestPos = humanPos[i];\n        int bestType = 3; // 0=corner, 1=edge, 2=interior\n        \n        // Check corners\n        for (int c = 0; c < 4; ++c) {\n            if (cornerUsed[c]) continue;\n            int dist = abs(humanPos[i].first - corners[c].first) + \n                       abs(humanPos[i].second - corners[c].second);\n            if (dist < bestDist) {\n                bestDist = dist;\n                bestPos = corners[c];\n                bestType = 0;\n            }\n        }\n        \n        // Check edges if no corner is better\n        if (bestType > 0) {\n            for (int e = 0; e < 12; ++e) {\n                if (edgeUsed[e]) continue;\n                int dist = abs(humanPos[i].first - edges[e].first) + \n                           abs(humanPos[i].second - edges[e].second);\n                if (dist < bestDist) {\n                    bestDist = dist;\n                    bestPos = edges[e];\n                    bestType = 1;\n                }\n            }\n        }\n        \n        target[i] = bestPos;\n        if (bestType == 0) cornerUsed[find(corners, corners+4, bestPos) - corners] = true;\n        if (bestType == 1) edgeUsed[find(edges, edges+12, bestPos) - edges] = true;\n    }\n\n    const int maxMoveTurns = 50;\n    bool moveDone = false;\n\n    /* ---------- 300 turns ---------- */\n    for (int turn = 0; turn < 300; ++turn) {\n        /* occupancy and adjacency of pets */\n        static bool occPet[31][31];\n        static bool occHuman[31][31];\n        static bool adjPet[31][31];\n        for (int i = 1; i <= 30; ++i)\n            for (int j = 1; j <= 30; ++j)\n                occPet[i][j] = occHuman[i][j] = adjPet[i][j] = false;\n\n        for (auto &p : petPos)  occPet[p.first][p.second] = true;\n        for (auto &h : humanPos) occHuman[h.first][h.second] = true;\n        for (auto &p : petPos) {\n            for (int d = 0; d < 4; ++d) {\n                int nr = p.first + dr[d];\n                int nc = p.second + dc[d];\n                if (nr >= 1 && nr <= 30 && nc >= 1 && nc <= 30)\n                    adjPet[nr][nc] = true;\n            }\n        }\n\n        vector<char> action(M, '.');\n        vector<pii> moveDest(M);\n        bool newWall[31][31] = {};\n\n        // Check if all humans reached their targets\n        if (!moveDone) {\n            bool allReached = true;\n            for (int i = 0; i < M; ++i) {\n                if (humanPos[i] != target[i]) { allReached = false; break; }\n            }\n            if (allReached || turn >= maxMoveTurns) moveDone = true;\n        }\n\n        if (!moveDone) {\n            // Move phase - move toward targets\n            for (int i = 0; i < M; ++i) {\n                if (humanPos[i] == target[i]) {\n                    action[i] = '.';\n                    moveDest[i] = humanPos[i];\n                    continue;\n                }\n                int hx = humanPos[i].first, hy = humanPos[i].second;\n                bool moved = false;\n                \n                // Vertical first\n                if (hx != target[i].first) {\n                    int dir = (hx < target[i].first) ? 1 : 0;\n                    int nx = hx + dr[dir], ny = hy;\n                    if (nx >= 1 && nx <= 30 && ny >= 1 && ny <= 30 && !wall[nx][ny]) {\n                        action[i] = moveChar[dir];\n                        moveDest[i] = {nx, ny};\n                        moved = true;\n                    }\n                }\n                // Then horizontal\n                if (!moved && hy != target[i].second) {\n                    int dir = (hy < target[i].second) ? 3 : 2;\n                    int nx = hx, ny = hy + dc[dir];\n                    if (nx >= 1 && nx <= 30 && ny >= 1 && ny <= 30 && !wall[nx][ny]) {\n                        action[i] = moveChar[dir];\n                        moveDest[i] = {nx, ny};\n                        moved = true;\n                    }\n                }\n                if (!moved) {\n                    action[i] = '.';\n                    moveDest[i] = {hx, hy};\n                }\n            }\n        } else {\n            // Isolation phase - place walls\n            for (int i = 0; i < M; ++i) {\n                int hx = humanPos[i].first, hy = humanPos[i].second;\n                bool placed = false;\n\n                // Try to place wall\n                for (int d = 0; d < 4 && !placed; ++d) {\n                    int nx = hx + dr[d], ny = hy + dc[d];\n                    if (nx < 1 || nx > 30 || ny < 1 || ny > 30) continue;\n                    if (wall[nx][ny] || newWall[nx][ny]) continue;\n                    if (occPet[nx][ny] || occHuman[nx][ny]) continue;\n                    if (adjPet[nx][ny]) continue;\n                    action[i] = wallChar[d];\n                    newWall[nx][ny] = true;\n                    placed = true;\n                }\n\n                if (placed) {\n                    moveDest[i] = {hx, hy};\n                    continue;\n                }\n\n                // If can't place wall, move to position with most wall options\n                int bestScore = -1;\n                int bestNx = -1, bestNy = -1, bestDir = -1;\n\n                for (int d = 0; d < 4; ++d) {\n                    int nx = hx + dr[d], ny = hy + dc[d];\n                    if (nx < 1 || nx > 30 || ny < 1 || ny > 30) continue;\n                    if (wall[nx][ny] || newWall[nx][ny]) continue;\n\n                    int score = 0;\n                    for (int dd = 0; dd < 4; ++dd) {\n                        int tx = nx + dr[dd], ty = ny + dc[dd];\n                        if (tx < 1 || tx > 30 || ty < 1 || ty > 30) continue;\n                        if (wall[tx][ty] || newWall[tx][ty]) continue;\n                        if (occPet[tx][ty] || occHuman[tx][ty]) continue;\n                        if (adjPet[tx][ty]) continue;\n                        score++;\n                    }\n                    if (score > bestScore) {\n                        bestScore = score;\n                        bestNx = nx; bestNy = ny; bestDir = d;\n                    }\n                }\n\n                if (bestDir != -1) {\n                    action[i] = moveChar[bestDir];\n                    moveDest[i] = {bestNx, bestNy};\n                } else {\n                    action[i] = '.';\n                    moveDest[i] = {hx, hy};\n                }\n            }\n        }\n\n        /* ----- output ----- */\n        for (int i = 0; i < M; ++i) cout << action[i];\n        cout << '\\n' << flush;\n\n        /* ----- apply walls ----- */\n        for (int i = 1; i <= 30; ++i)\n            for (int j = 1; j <= 30; ++j)\n                if (newWall[i][j]) wall[i][j] = true;\n\n        /* ----- apply human moves ----- */\n        for (int i = 0; i < M; ++i)\n            if (action[i] >= 'A' && action[i] <= 'Z')\n                humanPos[i] = moveDest[i];\n\n        /* ----- read and apply pet moves ----- */\n        for (int i = 0; i < N; ++i) {\n            string s; cin >> s;\n            for (char ch : s) {\n                if (ch == '.') continue;\n                int d = 0;\n                if (ch == 'U') d = 0;\n                else if (ch == 'D') d = 1;\n                else if (ch == 'L') d = 2;\n                else if (ch == 'R') d = 3;\n                int nx = petPos[i].first + dr[d];\n                int ny = petPos[i].second + dc[d];\n                if (nx < 1 || nx > 30 || ny < 1 || ny > 30) continue;\n                if (wall[nx][ny]) continue;\n                petPos[i] = {nx, ny};\n            }\n        }\n    }\n\n    /* ---------- final scoring ---------- */\n    long double sumS = 0.0L;\n    static bool vis[31][31];\n    for (int i = 0; i < M; ++i) {\n        for (int r = 1; r <= 30; ++r)\n            for (int c = 1; c <= 30; ++c)\n                vis[r][c] = false;\n\n        queue<pii> q;\n        int sx = humanPos[i].first, sy = humanPos[i].second;\n        vis[sx][sy] = true;\n        q.emplace(sx, sy);\n        int reach = 0;\n        while (!q.empty()) {\n            auto [x, y] = q.front(); q.pop();\n            ++reach;\n            for (int d = 0; d < 4; ++d) {\n                int nx = x + dr[d], ny = y + dc[d];\n                if (nx < 1 || nx > 30 || ny < 1 || ny > 30) continue;\n                if (wall[nx][ny]) continue;\n                if (vis[nx][ny]) continue;\n                vis[nx][ny] = true;\n                q.emplace(nx, ny);\n            }\n        }\n\n        int petsInside = 0;\n        for (auto &p : petPos)\n            if (vis[p.first][p.second]) ++petsInside;\n\n        long double s = (long double)reach / 900.0L *\n                        powl(2.0L, -(long double)petsInside);\n        sumS += s;\n    }\n\n    long double avg = sumS / (long double)M;\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj, ti, tj;\n    double p;\n    if (!(cin >> si >> sj >> ti >> tj >> p)) return 0;\n\n    vector<string> h(20);\n    for (int i = 0; i < 20; ++i) cin >> h[i];\n    vector<string> v(19);\n    for (int i = 0; i < 19; ++i) cin >> v[i];\n\n    // wall[i][j][dir] : true if movement in direction dir from (i,j) is blocked\n    // dir: 0=U,1=D,2=L,3=R\n    bool wall[20][20][4];\n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            wall[i][j][0] = (i == 0) ? true : (v[i-1][j] == '1');          // up\n            wall[i][j][1] = (i == 19) ? true : (v[i][j] == '1');          // down\n            wall[i][j][2] = (j == 0) ? true : (h[i][j-1] == '1');          // left\n            wall[i][j][3] = (j == 19) ? true : (h[i][j] == '1');          // right\n        }\n    }\n\n    const int L = 200;\n    const int N = 20 * 20;\n    const int target = ti * 20 + tj;\n    const int start = si * 20 + sj;\n\n    // dp[t][v] : maximal expected score from turn t, square v\n    vector<vector<double>> dp(L + 2, vector<double>(N, 0.0));\n    vector<vector<int>> best(L + 2, vector<int>(N, -1));\n\n    // dp[t][target] = 0 already (vector initialised with 0)\n    for (int t = L; t >= 1; --t) {\n        for (int pos = 0; pos < N; ++pos) {\n            if (pos == target) {\n                dp[t][pos] = 0.0;\n                best[t][pos] = -1;\n                continue;\n            }\n            int i = pos / 20, j = pos % 20;\n            double bestVal = -1.0;\n            int bestDir = 0;\n            for (int d = 0; d < 4; ++d) {\n                bool w = wall[i][j][d];\n                double stayProb = p + (1.0 - p) * (w ? 1.0 : 0.0);\n                double moveProb = (1.0 - p) * (w ? 0.0 : 1.0);\n\n                double expected = stayProb * dp[t + 1][pos];\n                if (moveProb > 0.0) {\n                    int ni = i, nj = j;\n                    if (d == 0) --ni;\n                    else if (d == 1) ++ni;\n                    else if (d == 2) --nj;\n                    else ++nj;\n                    int npos = ni * 20 + nj;\n                    if (npos == target) {\n                        expected += moveProb * (401 - t);\n                    } else {\n                        expected += moveProb * dp[t + 1][npos];\n                    }\n                }\n                if (expected > bestVal + 1e-12) {\n                    bestVal = expected;\n                    bestDir = d;\n                }\n            }\n            dp[t][pos] = bestVal;\n            best[t][pos] = bestDir;\n        }\n    }\n\n    // reconstruction of a concrete string\n    string ans;\n    ans.reserve(L);\n    int cur = start;\n    for (int t = 1; t <= L; ++t) {\n        int d = best[t][cur];\n        char c;\n        if (d == 0) c = 'U';\n        else if (d == 1) c = 'D';\n        else if (d == 2) c = 'L';\n        else c = 'R';\n        ans.push_back(c);\n\n        int i = cur / 20, j = cur % 20;\n        if (!wall[i][j][d]) {               // intended move succeeds\n            if (d == 0) --i;\n            else if (d == 1) ++i;\n            else if (d == 2) --j;\n            else ++j;\n            cur = i * 20 + j;\n        }\n        // if we are already at the target we keep outputting arbitrary\n        // directions \u2013 they will never be executed.\n    }\n\n    cout << ans << '\\n';\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int C = N * N;               // 900 cells\nconst int DIRS = 4;\nconst int STATES = C * DIRS;       // 3600 states\n\nint di[DIRS] = {0, -1, 0, 1};\nint dj[DIRS] = {-1, 0, 1, 0};\n\nint orig_tile[C];                  // original type (0..7)\n\n/* -------------------------------------------------------------\n   table to[t][d]  \u2013 entering direction d, exiting direction\n   ------------------------------------------------------------- */\nint to_orig[8][DIRS] = {\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 to_rot[8][4][DIRS];            // [type][rotation][entry]\n\n/* -------------------------------------------------------------\n   compute the score (L1 * L2) for a given rotation\n   ------------------------------------------------------------- */\nint next_state[STATES];\nint visited_state[STATES];\nint step_idx[STATES];\nvector<int> path;\n\ninline long long compute_score(const int rot[C]) {\n    // build the transition function\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int t = orig_tile[i * N + j];\n            int r = rot[i * N + j];\n            int base = (i * N + j) * DIRS;\n            for (int d = 0; d < DIRS; ++d) {\n                int exit = to_rot[t][r][d];\n                if (exit == -1) {\n                    next_state[base + d] = -1;\n                    continue;\n                }\n                int ni = i + di[exit];\n                int nj = j + dj[exit];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) {\n                    next_state[base + d] = -1;\n                    continue;\n                }\n                int nd = (exit + 2) & 3;\n                next_state[base + d] = (ni * N + nj) * DIRS + nd;\n            }\n        }\n    }\n\n    // find all directed cycles\n    fill(visited_state, visited_state + STATES, 0);\n    fill(step_idx, step_idx + STATES, -1);\n    vector<int> cycles;\n    for (int s = 0; s < STATES; ++s) {\n        if (next_state[s] == -1 || visited_state[s]) continue;\n        int cur = s;\n        path.clear();\n        while (true) {\n            if (next_state[cur] == -1) break;               // dead end\n            if (visited_state[cur]) break;                  // already processed\n            if (step_idx[cur] != -1) {                      // a new cycle\n                int start = step_idx[cur];\n                int len = (int)path.size() - start;\n                cycles.push_back(len);\n                break;\n            }\n            step_idx[cur] = (int)path.size();\n            path.push_back(cur);\n            cur = next_state[cur];\n        }\n        for (int v : path) {\n            visited_state[v] = 1;\n            step_idx[v] = -1;\n        }\n    }\n\n    if (cycles.empty()) return 0LL;\n    sort(cycles.rbegin(), cycles.rend());\n    long long L1 = cycles[0];\n    long long L2 = (cycles.size() >= 2) ? cycles[1] : 0LL;\n    return L1 * L2;\n}\n\n/* -------------------------------------------------------------\n   main\n   ------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* read the board */\n    string line;\n    for (int i = 0; i < N; ++i) {\n        cin >> line;\n        for (int j = 0; j < N; ++j) orig_tile[i * N + j] = line[j] - '0';\n    }\n\n    /* pre\u2011compute rotated tables */\n    for (int t = 0; t < 8; ++t)\n        for (int r = 0; r < 4; ++r)\n            for (int d = 0; d < DIRS; ++d) {\n                int src = (d - r + 4) % 4;\n                int e = to_orig[t][src];\n                to_rot[t][r][d] = (e == -1) ? -1 : (e + r) % 4;\n            }\n\n    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist_rot(0, 3);\n    uniform_int_distribution<int> dist_cell(0, C - 1);\n    uniform_real_distribution<double> dist_prob(0.0, 1.0);\n\n    /* ---------- initial random rotation ------------------------ */\n    int curRot[C];\n    for (int i = 0; i < C; ++i) curRot[i] = dist_rot(rng);\n\n    /* optional greedy improvement (maximise matched sides) */\n    const int GREEDY_PASSES = 4;\n    for (int p = 0; p < GREEDY_PASSES; ++p) {\n        bool changed = false;\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j) {\n                int idx = i * N + j;\n                int t = orig_tile[idx];\n                int best_r = curRot[idx];\n                int best_match = -1;\n                for (int r = 0; r < 4; ++r) {\n                    int match = 0;\n                    for (int d = 0; d < DIRS; ++d) {\n                        int exit = to_rot[t][r][d];\n                        if (exit == -1) continue;\n                        int ni = i + di[exit];\n                        int nj = j + dj[exit];\n                        if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                        int nb = ni * N + nj;\n                        int nb_t = orig_tile[nb];\n                        int nb_r = curRot[nb];\n                        int nb_entry = (exit + 2) & 3;\n                        if (to_rot[nb_t][nb_r][nb_entry] != -1) ++match;\n                    }\n                    if (match > best_match) {\n                        best_match = match;\n                        best_r = r;\n                    }\n                }\n                if (best_r != curRot[idx]) {\n                    curRot[idx] = best_r;\n                    changed = true;\n                }\n            }\n        if (!changed) break;\n    }\n\n    /* ---------- simulated annealing --------------------------- */\n    const int MAX_ITER = 400000;\n    const double T0 = 800.0;\n    const double DECAY = 0.9996;\n\n    long long curScore = compute_score(curRot);\n    long long bestScore = curScore;\n    int bestRot[C];\n    copy(begin(curRot), end(curRot), begin(bestRot));\n\n    double T = T0;\n    auto start = chrono::steady_clock::now();\n\n    for (int it = 0; it < MAX_ITER; ++it) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start).count();\n        if (elapsed > 1.85) break;               // stay within the time limit\n\n        int idx = dist_cell(rng);\n        int old_r = curRot[idx];\n        int new_r = dist_rot(rng);\n        if (new_r == old_r) new_r = (old_r + 1) & 3;   // force a change\n        curRot[idx] = new_r;\n\n        long long newScore = compute_score(curRot);\n        long long delta = newScore - curScore;\n\n        if (delta > 0) {\n            // accept the improvement\n            curScore = newScore;\n            if (newScore > bestScore) {\n                bestScore = newScore;\n                copy(begin(curRot), end(curRot), begin(bestRot));\n            }\n        } else {\n            // Metropolis acceptance of a worse move\n            if (dist_prob(rng) < exp((double)delta / T)) {\n                curScore = newScore;               // keep the worse state\n            } else {\n                curRot[idx] = old_r;                // revert\n            }\n        }\n\n        T = T0 * pow(DECAY, it + 1);\n    }\n\n    /* ---------- hill\u2011climbing (local search) ------------------- */\n    // make curRot the best configuration found so far\n    copy(begin(bestRot), end(bestRot), begin(curRot));\n    curScore = bestScore;\n\n    const int HILL_PASSES = 2;\n    for (int pass = 0; pass < HILL_PASSES; ++pass) {\n        bool any = false;\n        for (int idx = 0; idx < C; ++idx) {\n            int saved_r = curRot[idx];\n            for (int r = 0; r < 4; ++r) {\n                if (r == saved_r) continue;\n                curRot[idx] = r;\n                long long ns = compute_score(curRot);\n                if (ns > curScore) {\n                    curScore = ns;\n                    if (ns > bestScore) {\n                        bestScore = ns;\n                        copy(begin(curRot), end(curRot), begin(bestRot));\n                    }\n                    any = true;\n                    break;          // stay at this tile, try next tile\n                } else {\n                    curRot[idx] = saved_r; // restore\n                }\n            }\n            if (any) break;          // a change happened \u2013 start new pass\n        }\n        if (!any) break;             // no improvement in this pass\n    }\n\n    /* ---------- output --------------------------------------- */\n    string out;\n    out.reserve(C);\n    for (int i = 0; i < C; ++i) out.push_back(char('0' + bestRot[i]));\n    cout << out << '\\n';\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* --------------------------------------------------------------\n   helpers for bit handling\n   -------------------------------------------------------------- */\nint bitFromDelta(int dr, int dc)               // direction -> bit\n{\n    if (dr == -1 && dc == 0) return 2;   // up\n    if (dr ==  1 && dc == 0) return 8;   // down\n    if (dr ==  0 && dc ==-1) return 1;   // left\n    if (dr ==  0 && dc == 1) return 4;   // right\n    return 0;\n}\nint idxFromDelta(int dr, int dc)               // direction -> index 0..3\n{\n    if (dr == -1 && dc == 0) return 0;   // up\n    if (dr ==  1 && dc == 0) return 1;   // down\n    if (dr ==  0 && dc ==-1) return 2;   // left\n    if (dr ==  0 && dc == 1) return 3;   // right\n    return -1;\n}\nint oppositeBit(int b)                         // opposite direction\n{\n    if (b == 1) return 4;\n    if (b == 4) return 1;\n    if (b == 2) return 8;\n    if (b == 8) return 2;\n    return 0;\n}\nchar charFromDelta(int dr, int dc)            // direction -> move character\n{\n    int id = idxFromDelta(dr, dc);\n    static const char mv[4] = {'U','D','L','R'};\n    return (id == -1 ? '?' : mv[id]);\n}\n\n/* --------------------------------------------------------------\n   global data\n   -------------------------------------------------------------- */\nint N, T;\nvector<vector<int>> board;            // board[r][c] = tile id, -1 = empty\nvector<int> maskOrig;                 // original picture of each tile\nvector<int> curMask;                  // bits still unused\nvector<char> inComponent;             // tile already belongs to the tree\nint er, ec;                           // empty cell\n\nconst int dr[4] = {-1, 1, 0, 0};\nconst int dc[4] = {0, 0, -1, 1};\n\n/* --------------------------------------------------------------\n   after a tile has moved to (r,c) delete all bits that correspond\n   to edges that have just appeared\n   -------------------------------------------------------------- */\nvoid updateEdges(int r, int c)\n{\n    int id = board[r][c];\n    if (id == -1) return;\n    for (int d = 0; d < 4; ++d) {\n        int nr = r + dr[d], nc = c + dc[d];\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n        int nid = board[nr][nc];\n        if (nid == -1) continue;\n        int need = bitFromDelta(dr[d], dc[d]);          // id -> nid\n        int opp  = oppositeBit(need);\n        if ( (curMask[id] & need) && (curMask[nid] & opp) ) {\n            curMask[id]  &= ~need;\n            curMask[nid] &= ~opp;\n        }\n    }\n}\n\n/* --------------------------------------------------------------\n   initial removal of bits belonging to edges that already exist\n   -------------------------------------------------------------- */\nvoid removeInitialEdges()\n{\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (board[i][j] != -1)\n                updateEdges(i, j);\n}\n\n/* --------------------------------------------------------------\n   try to attach a new vertex (Step 1).  Returns true if a move\n   was performed.\n   -------------------------------------------------------------- */\nbool tryAttach(string &answer)\n{\n    for (int d = 0; d < 4; ++d) {\n        int pr = er + dr[d], pc = ec + dc[d];\n        if (pr < 0 || pr >= N || pc < 0 || pc >= N) continue;\n        int parent = board[pr][pc];\n        if (parent == -1 || !inComponent[parent]) continue;\n\n        int needParent = oppositeBit(bitFromDelta(dr[d], dc[d]));\n        if ( (curMask[parent] & needParent) == 0 ) continue;\n\n        int cr = er - dr[d], cc = ec - dc[d];\n        if (cr < 0 || cr >= N || cc < 0 || cc >= N) continue;\n        int child = board[cr][cc];\n        if (child == -1 || inComponent[child]) continue;\n\n        int needChild = bitFromDelta(dr[d], dc[d]);\n        if ( (curMask[child] & needChild) == 0 ) continue;\n\n        /* perform the slide */\n        char ch = charFromDelta(dr[d], dc[d]);      // slide child into empty\n        answer.push_back(ch);\n\n        board[er][ec] = child;\n        board[cr][cc] = -1;\n        er = cr; ec = cc;\n\n        curMask[parent] &= ~needParent;\n        curMask[child]  &= ~needChild;\n        inComponent[child] = 1;\n\n        updateEdges(er, ec);        // edges created by the new tile\n        return true;\n    }\n    return false;\n}\n\n/* --------------------------------------------------------------\n   move the empty square by sliding an unplaced tile (Step 2)\n   Prefer tiles that have unused bits (potential edges)\n   -------------------------------------------------------------- */\nvoid moveEmpty(string &answer)\n{\n    // First check if any neighbor has unused bits\n    for (int d = 0; d < 4; ++d) {\n        int nr = er + dr[d], nc = ec + dc[d];\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n        int tid = board[nr][nc];\n        if (tid == -1) continue;\n        if (inComponent[tid]) continue;          // slide only an unplaced tile\n        \n        // If this tile has unused bits, prefer it\n        if (curMask[tid] != 0) {\n            char ch = charFromDelta(dr[d], dc[d]);\n            answer.push_back(ch);\n            board[er][ec] = tid;\n            board[nr][nc] = -1;\n            er = nr; ec = nc;\n            updateEdges(er, ec);\n            return;\n        }\n    }\n    \n    // Otherwise, any unplaced tile\n    for (int d = 0; d < 4; ++d) {\n        int nr = er + dr[d], nc = ec + dc[d];\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n        int tid = board[nr][nc];\n        if (tid == -1) continue;\n        if (inComponent[tid]) continue;          // slide only an unplaced tile\n\n        char ch = charFromDelta(dr[d], dc[d]);\n        answer.push_back(ch);\n        board[er][ec] = tid;\n        board[nr][nc] = -1;\n        er = nr; ec = nc;\n        updateEdges(er, ec);\n        return;\n    }\n}\n\n/* --------------------------------------------------------------\n   main\n   -------------------------------------------------------------- */\nint main()\n{\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> T)) return 0;\n    vector<string> raw(N);\n    for (int i = 0; i < N; ++i) cin >> raw[i];\n\n    board.assign(N, vector<int>(N, -1));\n    maskOrig.clear();\n    int id = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            char c = raw[i][j];\n            if (c == '0') {\n                er = i; ec = j;\n                board[i][j] = -1;\n            } else {\n                int v;\n                if ('0' <= c && c <= '9') v = c - '0';\n                else v = 10 + (c - 'a');\n                board[i][j] = id;\n                maskOrig.push_back(v);\n                ++id;\n            }\n        }\n    }\n\n    const int M = N * N - 1;                 // number of tiles\n    curMask = maskOrig;\n    inComponent.assign(M, 0);\n\n    /* delete bits that already belong to edges in the initial board */\n    removeInitialEdges();\n\n    string answer;\n    answer.reserve(T);\n\n    /* ----- Step 0 : place the first tile (the root) ----- */\n    bool placedRoot = false;\n    for (int d = 0; d < 4 && !placedRoot; ++d) {\n        int nr = er + dr[d], nc = ec + dc[d];\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n        int tid = board[nr][nc];\n        if (tid == -1) continue;\n        int dir = bitFromDelta(dr[d], dc[d]);           // direction empty -> neighbour\n        if (maskOrig[tid] & oppositeBit(dir)) {\n            char ch = charFromDelta(dr[d], dc[d]);\n            answer.push_back(ch);\n            board[er][ec] = tid;\n            board[nr][nc] = -1;\n            er = nr; ec = nc;\n            inComponent[tid] = 1;\n            updateEdges(er, ec);\n            placedRoot = true;\n            break;\n        }\n    }\n    if (!placedRoot) {                                 // fallback: any neighbour\n        for (int d = 0; d < 4 && !placedRoot; ++d) {\n            int nr = er + dr[d], nc = ec + dc[d];\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n            int tid = board[nr][nc];\n            if (tid == -1) continue;\n            char ch = charFromDelta(dr[d], dc[d]);\n            answer.push_back(ch);\n            board[er][ec] = tid;\n            board[nr][nc] = -1;\n            er = nr; ec = nc;\n            inComponent[tid] = 1;\n            updateEdges(er, ec);\n            placedRoot = true;\n            break;\n        }\n    }\n\n    int placedCnt = 1;                                 // one tile in the component\n\n    /* --------------------------------------------------------------\n       Main loop \u2013 repeatedly enlarge the component or move the empty\n       -------------------------------------------------------------- */\n    while (placedCnt < M && (int)answer.size() < T) {\n        if (tryAttach(answer)) {\n            ++placedCnt;\n            continue;\n        }\n        moveEmpty(answer);\n    }\n\n    cout << answer << '\\n';\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nusing ull = unsigned long long;\n\nstruct Line {\n    ll px, py, qx, qy;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, Kmax;\n    if (!(cin >> N >> Kmax)) return 0;\n    vector<int> a(11);\n    for (int d = 1; d <= 10; ++d) cin >> a[d];\n    vector<ll> xs(N), ys(N);\n    for (int i = 0; i < N; ++i) cin >> xs[i] >> ys[i];\n\n    int sumA = 0;\n    for (int d = 1; d <= 10; ++d) sumA += a[d];\n\n    /* ---------- parameters of the search ---------- */\n    const int USE_K = 70;            // enough pieces (70\u00b771/2+1 = 2486)\n    const int TRIALS = 1900;         // slightly more attempts than before\n\n    /* ---------- random number generator ---------- */\n    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<ll> distCoord(-10000, 10000);\n\n    /* ---------- generate a line that does not hit any strawberry ---------- */\n    auto make_line = [&]() -> Line {\n        for (int tries = 0; tries < 3; ++tries) {\n            ll px = distCoord(rng);\n            ll py = distCoord(rng);\n            ll qx = distCoord(rng);\n            ll qy = distCoord(rng);\n            if (px == qx && py == qy) continue;\n            // minimal length to avoid almost\u2011parallel or degenerate lines\n            if ((px - qx) * (px - qx) + (py - qy) * (py - qy) < 100) continue;\n            ll dx = qx - px;\n            ll dy = qy - py;\n            bool ok = true;\n            for (int i = 0; i < N; ++i) {\n                ll cross = dx * (ys[i] - py) - dy * (xs[i] - px);\n                if (cross == 0) { ok = false; break; }\n            }\n            if (ok) return Line{px, py, qx, qy};\n        }\n        // fallback \u2013 a line far away, never hits a strawberry\n        return Line{-1000000, 0, 1000000, 0};\n    };\n\n    /* ---------- containers that are reused every trial ---------- */\n    // 70 bits > 64, need two 64\u2011bit integers for the signature\n    vector<ull> sig_hi(N), sig_lo(N);\n\n    int bestScore = -1;\n    vector<Line> bestLines;\n\n    for (int trial = 0; trial < TRIALS; ++trial) {\n        /* generate USE_K random lines */\n        vector<Line> lines;\n        lines.reserve(USE_K);\n        for (int i = 0; i < USE_K; ++i) lines.push_back(make_line());\n\n        /* reset signatures */\n        fill(sig_hi.begin(), sig_hi.end(), 0ULL);\n        fill(sig_lo.begin(), sig_lo.end(), 0ULL);\n\n        /* apply every line */\n        for (int li = 0; li < USE_K; ++li) {\n            const Line &L = lines[li];\n            ll dx = L.qx - L.px;\n            ll dy = L.qy - L.py;\n            for (int i = 0; i < N; ++i) {\n                ll cross = dx * (ys[i] - L.py) - dy * (xs[i] - L.px);\n                if (cross > 0) {                         // right side \u2192 set bit\n                    if (li < 64) sig_lo[i] |= (1ULL << li);\n                    else          sig_hi[i] |= (1ULL << (li - 64));\n                }\n                // cross == 0 never happens because of line generation\n            }\n        }\n\n        /* sort signatures (by (hi, lo) pair) using std::sort */\n        vector<pair<ull, ull>> sig(N);\n        for (int i = 0; i < N; ++i) sig[i] = {sig_hi[i], sig_lo[i]};\n        sort(sig.begin(), sig.end());\n\n        /* count piece sizes */\n        vector<int> b(11, 0);            // b[d] = #pieces with d strawberries\n        for (int i = 0; i < N; ) {\n            int j = i;\n            while (j < N && sig[j] == sig[i]) ++j;\n            int sz = j - i;\n            if (1 <= sz && sz <= 10) ++b[sz];\n            i = j;\n        }\n\n        int distributed = 0;\n        for (int d = 1; d <= 10; ++d) distributed += min(a[d], b[d]);\n\n        if (distributed > bestScore) {\n            bestScore = distributed;\n            bestLines = lines;\n            if (distributed == sumA) break;   // perfect, stop early\n        }\n    }\n\n    /* ---------- output ---------- */\n    cout << bestLines.size() << '\\n';\n    for (const Line &L : bestLines)\n        cout << L.px << ' ' << L.py << ' ' << L.qx << ' ' << L.qy << '\\n';\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Candidate {\n    int mx, my;                              // missing corner (new dot)\n    array<pair<int,int>,3> others;           // three existing corners\n};\n\nint N, M;\nint centre_;\nbool hasDot[61][61];\n\n/* data structures for dot queries */\nvector< set<int> > dotX, dotY;                     // 0 \u2026 N\u20111\nunordered_map<int, set<int> > dotD, dotS;        // d = x\u2011y , s = x+y\n\n/* data structures for generating candidates */\nvector< vector<pair<int,int>> > dotsAtS;               // s \u2192 list of points\nunordered_map<int, vector<pair<int,int>> > dotsAtD;   // d \u2192 list of points\n\n/* already drawn edges */\nunordered_map<int, set<pair<int,int>>> edgeHor;   // y \u2192 intervals of x\nunordered_map<int, set<pair<int,int>>> edgeVer;   // x \u2192 intervals of y\nunordered_map<int, set<pair<int,int>>> edgeDiagP; // d \u2192 intervals of x\nunordered_map<int, set<pair<int,int>>> edgeDiagM; // s \u2192 intervals of x\n\ninline int weight(int x, int y) {\n    int dx = x - centre_;\n    int dy = y - centre_;\n    return dx*dx + dy*dy + 1;\n}\n\n/* ---------- helpers for edges ---------- */\n\ninline bool adjacent(const pair<int,int>& a, const pair<int,int>& b) {\n    return (a.first == b.first) ||\n           (a.second == b.second) ||\n           (a.first - a.second == b.first - b.second) ||\n           (a.first + a.second == b.first + b.second);\n}\n\n/* overlap test for one line */\nbool hasOverlapOnLine(const unordered_map<int, set<pair<int,int>>>& mp,\n                      int line, int l, int r) {\n    auto it = mp.find(line);\n    if (it == mp.end()) return false;\n    const auto& st = it->second;\n    auto itr = st.lower_bound({l, INT_MIN});\n    if (itr != st.end()) {\n        int l2 = itr->first, r2 = itr->second;\n        if (max(l, l2) <= min(r, r2) - 1) return true;\n    }\n    if (itr != st.begin()) {\n        --itr;\n        int l2 = itr->first, r2 = itr->second;\n        if (max(l, l2) <= min(r, r2) - 1) return true;\n    }\n    return false;\n}\n\n/* check whether side (a,b) overlaps an existing edge */\nbool edgeOverlap(const pair<int,int>& a, const pair<int,int>& b) {\n    if (a.first == b.first) {                     // vertical\n        int x = a.first;\n        int l = min(a.second, b.second);\n        int r = max(a.second, b.second);\n        return hasOverlapOnLine(edgeVer, x, l, r);\n    } else if (a.second == b.second) {           // horizontal\n        int y = a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        return hasOverlapOnLine(edgeHor, y, l, r);\n    } else if (a.first - a.second == b.first - b.second) { // diag +1\n        int d = a.first - a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        return hasOverlapOnLine(edgeDiagP, d, l, r);\n    } else {                                      // diag -1\n        int s = a.first + a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        return hasOverlapOnLine(edgeDiagM, s, l, r);\n    }\n}\n\n/* insert an edge into the stored sets */\nvoid addEdgeToSet(const pair<int,int>& a, const pair<int,int>& b) {\n    if (a.first == b.first) {\n        int x = a.first;\n        int l = min(a.second, b.second);\n        int r = max(a.second, b.second);\n        edgeVer[x].insert({l, r});\n    } else if (a.second == b.second) {\n        int y = a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        edgeHor[y].insert({l, r});\n    } else if (a.first - a.second == b.first - b.second) {\n        int d = a.first - a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        edgeDiagP[d].insert({l, r});\n    } else {\n        int s = a.first + a.second;\n        int l = min(a.first, b.first);\n        int r = max(a.first, b.first);\n        edgeDiagM[s].insert({l, r});\n    }\n}\n\n/* does any dot lie on the open interval of the side ? */\nbool dotOnEdgeOpen(const pair<int,int>& a, const pair<int,int>& b) {\n    if (a.first == b.first) {                 // vertical\n        int x = a.first;\n        int lo = min(a.second, b.second);\n        int hi = max(a.second, b.second);\n        const auto& st = dotX[x];\n        auto it = st.lower_bound(lo + 1);\n        if (it != st.end() && *it <= hi - 1) return true;\n        return false;\n    } else if (a.second == b.second) {       // horizontal\n        int y = a.second;\n        int lo = min(a.first, b.first);\n        int hi = max(a.first, b.first);\n        const auto& st = dotY[y];\n        auto it = st.lower_bound(lo + 1);\n        if (it != st.end() && *it <= hi - 1) return true;\n        return false;\n    } else if (a.first - a.second == b.first - b.second) { // diag +1\n        int d = a.first - a.second;\n        int lo = min(a.first, b.first);\n        int hi = max(a.first, b.first);\n        const auto& st = dotD[d];\n        auto it = st.lower_bound(lo + 1);\n        if (it != st.end() && *it <= hi - 1) return true;\n        return false;\n    } else {                                   // diag -1\n        int s = a.first + a.second;\n        int lo = min(a.first, b.first);\n        int hi = max(a.first, b.first);\n        const auto& st = dotS[s];\n        auto it = st.lower_bound(lo + 1);\n        if (it != st.end() && *it <= hi - 1) return true;\n        return false;\n    }\n}\n\n/* ---------- test a candidate ---------- */\ninline bool isValidMove(const Candidate& cand) {\n    array<pair<int,int>,4> pts;\n    pts[0] = {cand.mx, cand.my};\n    pts[1] = cand.others[0];\n    pts[2] = cand.others[1];\n    pts[3] = cand.others[2];\n\n    int sides = 0;\n    for (int i = 0; i < 4; ++i) {\n        for (int j = i+1; j < 4; ++j) {\n            if (adjacent(pts[i], pts[j])) {\n                ++sides;\n                if (edgeOverlap(pts[i], pts[j])) return false;\n                if (dotOnEdgeOpen(pts[i], pts[j])) return false;\n            }\n        }\n    }\n    return sides == 4;   // must be a rectangle\n}\n\n/* ---------- total length of the four sides (heuristic) ---------- */\nint totalEdgeLength(const Candidate& cand) {\n    array<pair<int,int>,4> pts;\n    pts[0] = {cand.mx, cand.my};\n    pts[1] = cand.others[0];\n    pts[2] = cand.others[1];\n    pts[3] = cand.others[2];\n\n    int len = 0;\n    for (int i = 0; i < 4; ++i)\n        for (int j = i+1; j < 4; ++j)\n            if (adjacent(pts[i], pts[j])) {\n                int dx = pts[i].first - pts[j].first;\n                int dy = pts[i].second - pts[j].second;\n                len += max(abs(dx), abs(dy));   // side length\n            }\n    return len;\n}\n\n/* ---------- add a new dot ---------- */\nvoid addDot(int x, int y) {\n    hasDot[x][y] = true;\n    dotX[x].insert(y);\n    dotY[y].insert(x);\n    int d = x - y;\n    int s = x + y;\n    dotD[d].insert(x);\n    dotS[s].insert(x);\n    dotsAtS[s].push_back({x, y});\n    dotsAtD[d].push_back({x, y});\n}\n\n/* ---------- ordering for output ---------- */\nvector<pair<int,int>> order4(const Candidate& cand) {\n    array<pair<int,int>,4> pts;\n    pts[0] = {cand.mx, cand.my};\n    pts[1] = cand.others[0];\n    pts[2] = cand.others[1];\n    pts[3] = cand.others[2];\n\n    vector<pair<int,int>> neighbours;\n    int oppIdx = -1;\n    for (int i = 1; i < 4; ++i) {\n        if (adjacent(pts[0], pts[i]))\n            neighbours.push_back(pts[i]);\n        else\n            oppIdx = i;\n    }\n    if (neighbours.size() != 2 || oppIdx == -1)\n        return {pts[0], pts[1], pts[2], pts[3]};\n\n    vector<pair<int,int>> res;\n    res.push_back(pts[0]);               // the new dot\n    res.push_back(neighbours[0]);         // one neighbour\n    res.push_back(pts[oppIdx]);          // opposite corner\n    res.push_back(neighbours[1]);         // the other neighbour\n    return res;\n}\n\n/* --------------------------------------------------------------- */\n\n/* run one attempt and return (totalWeight, operations) */\npair<long long, vector<array<int,8>>> runAttempt(const vector<pair<int,int>>& init,\n                                                  mt19937_64& rng) {\n    /* reset all data structures */\n    memset(hasDot, 0, sizeof(hasDot));\n    dotX.assign(N, {});\n    dotY.assign(N, {});\n    dotD.clear(); dotS.clear();\n    edgeVer.clear(); edgeHor.clear(); edgeDiagP.clear(); edgeDiagM.clear();\n    dotsAtS.assign(2*N-1, {});\n    dotsAtD.clear();\n\n    long long sumW = 0;\n    for (auto &p : init) {\n        int x = p.first, y = p.second;\n        addDot(x, y);\n        sumW += weight(x, y);\n    }\n\n    vector<array<int,8>> ops;\n\n    while (true) {\n        vector<Candidate> cand;\n        cand.reserve(80000);\n\n        /* axis\u2011parallel rectangles */\n        for (int x = 0; x < N; ++x) {\n            const auto& ys = dotX[x];\n            vector<int> yvec(ys.begin(), ys.end());\n            int sz = (int)yvec.size();\n            for (int i = 0; i < sz; ++i) {\n                int y1 = yvec[i];\n                for (int j = i+1; j < sz; ++j) {\n                    int y2 = yvec[j];\n                    for (int x2 = 0; x2 < N; ++x2) if (x2 != x) {\n                        bool has1 = hasDot[x2][y1];\n                        bool has2 = hasDot[x2][y2];\n                        if (has1 && !has2) {\n                            if (!hasDot[x2][y2]) {\n                                Candidate c;\n                                c.mx = x2; c.my = y2;\n                                c.others[0] = {x, y1};\n                                c.others[1] = {x, y2};\n                                c.others[2] = {x2, y1};\n                                cand.push_back(c);\n                            }\n                        } else if (!has1 && has2) {\n                            if (!hasDot[x2][y1]) {\n                                Candidate c;\n                                c.mx = x2; c.my = y1;\n                                c.others[0] = {x, y1};\n                                c.others[1] = {x, y2};\n                                c.others[2] = {x2, y2};\n                                cand.push_back(c);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        /* 45\u00b0 squares */\n        for (int s = 0; s < 2*N-1; ++s) {\n            const auto &vec = dotsAtS[s];\n            int sz = (int)vec.size();\n            for (int i = 0; i < sz; ++i) {\n                auto A = vec[i];\n                for (int j = i+1; j < sz; ++j) {\n                    auto B = vec[j];\n                    int dA = A.first - A.second;\n                    int dB = B.first - B.second;\n\n                    auto itA = dotsAtD.find(dA);\n                    if (itA != dotsAtD.end()) {\n                        for (auto C : itA->second) {\n                            if (C.first + C.second == s) continue;\n                            int s2 = C.first + C.second;\n                            int xm = (s2 + dB) / 2;\n                            int ym = (s2 - dB) / 2;\n                            if (xm < 0 || xm >= N || ym < 0 || ym >= N) continue;\n                            if (hasDot[xm][ym]) continue;\n                            Candidate c;\n                            c.mx = xm; c.my = ym;\n                            c.others[0] = A;\n                            c.others[1] = B;\n                            c.others[2] = C;\n                            cand.push_back(c);\n                        }\n                    }\n                    auto itB = dotsAtD.find(dB);\n                    if (itB != dotsAtD.end()) {\n                        for (auto C : itB->second) {\n                            if (C.first + C.second == s) continue;\n                            int s2 = C.first + C.second;\n                            int xm = (s2 + dA) / 2;\n                            int ym = (s2 - dA) / 2;\n                            if (xm < 0 || xm >= N || ym < 0 || ym >= N) continue;\n                            if (hasDot[xm][ym]) continue;\n                            Candidate c;\n                            c.mx = xm; c.my = ym;\n                            c.others[0] = A;\n                            c.others[1] = B;\n                            c.others[2] = C;\n                            cand.push_back(c);\n                        }\n                    }\n                }\n            }\n        }\n\n        if (cand.empty()) break;   // no candidates at all\n\n        /* cache validity */\n        vector<char> valid(cand.size(), 0);\n        for (size_t i = 0; i < cand.size(); ++i) {\n            valid[i] = isValidMove(cand[i]) ? 1 : 0;\n        }\n\n        /* find maximal weight */\n        int bestW = -1;\n        for (size_t i = 0; i < cand.size(); ++i) {\n            if (!valid[i]) continue;\n            int w = weight(cand[i].mx, cand[i].my);\n            if (w > bestW) bestW = w;\n        }\n        if (bestW == -1) break;                 // no legal move\n\n        /* collect best and near\u2011best buckets */\n        vector<int> bestIdx, nearBestIdx;\n        int nearBestThreshold = bestW - max(1, bestW / 8);   // 12.5% below best\n        for (size_t i = 0; i < cand.size(); ++i) {\n            if (!valid[i]) continue;\n            int w = weight(cand[i].mx, cand[i].my);\n            if (w == bestW) {\n                bestIdx.push_back((int)i);\n            } else if (w >= nearBestThreshold) {\n                nearBestIdx.push_back((int)i);\n            }\n        }\n\n        int chosen = -1;\n        /* 80 % stay in best bucket, 20 % explore near\u2011best */\n        if (bestIdx.empty() || (rng() % 100 >= 20)) {\n            /* choose among bestIdx, prefer shorter edge length, then random */\n            int bestLen = INT_MAX;\n            for (int idx : bestIdx) {\n                int len = totalEdgeLength(cand[idx]);\n                if (len < bestLen) {\n                    bestLen = len;\n                    chosen = idx;\n                } else if (len == bestLen && (rng() & 1)) {\n                    chosen = idx;          // random tie\u2011break\n                }\n            }\n        } else {\n            /* explore near\u2011best bucket (or best if empty) */\n            vector<int> &pool = nearBestIdx.empty() ? bestIdx : nearBestIdx;\n            chosen = pool[rng() % pool.size()];\n        }\n\n        if (chosen == -1) break; // safety\n\n        const Candidate &c = cand[chosen];\n        int w = weight(c.mx, c.my);\n        addDot(c.mx, c.my);\n        sumW += w;\n\n        /* add the four edges */\n        array<pair<int,int>,4> pts;\n        pts[0] = {c.mx, c.my};\n        pts[1] = c.others[0];\n        pts[2] = c.others[1];\n        pts[3] = c.others[2];\n        for (int i = 0; i < 4; ++i)\n            for (int j = i+1; j < 4; ++j)\n                if (adjacent(pts[i], pts[j]))\n                    addEdgeToSet(pts[i], pts[j]);\n\n        /* store the operation */\n        vector<pair<int,int>> order = order4(c);\n        array<int,8> op;\n        for (int k = 0; k < 4; ++k) {\n            op[2*k]   = order[k].first;\n            op[2*k+1] = order[k].second;\n        }\n        ops.push_back(op);\n    }\n\n    return {sumW, ops};\n}\n\n/* --------------------------------------------------------------- */\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> M;\n    centre_ = (N - 1) / 2;\n\n    vector<pair<int,int>> initPoints(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> initPoints[i].first >> initPoints[i].second;\n    }\n\n    const int ATTEMPTS = 6;                     // run six times, keep the best\n    const uint64_t baseSeed = 123456789ULL;\n    long long bestSum = -1;\n    vector<array<int,8>> bestOps;\n\n    for (int a = 0; a < ATTEMPTS; ++a) {\n        mt19937_64 rng(baseSeed + a * 1111111ULL);\n        auto res = runAttempt(initPoints, rng);\n        if (res.first > bestSum) {\n            bestSum = res.first;\n            bestOps = std::move(res.second);\n        }\n    }\n\n    cout << bestOps.size() << '\\n';\n    for (auto &op : bestOps) {\n        for (int i = 0; i < 8; ++i) {\n            if (i) cout << ' ';\n            cout << op[i];\n        }\n        cout << '\\n';\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int SZ = 10;\nconst array<char, 4> DIRS = {'F', 'B', 'L', 'R'};\n\nusing Board = array<array<int, SZ>, SZ>;\n\n/* ------------------------------------------------------------\n   tilt the whole board into direction dir (in place)\n   ------------------------------------------------------------ */\nvoid tilt(Board &a, char dir) {\n    if (dir == 'F') {                         // forward \u2192 top\n        for (int c = 0; c < SZ; ++c) {\n            int wr = 0;\n            for (int r = 0; r < SZ; ++r) {\n                if (a[r][c] != 0) {\n                    if (wr != r) {\n                        a[wr][c] = a[r][c];\n                        a[r][c] = 0;\n                    }\n                    ++wr;\n                }\n            }\n        }\n    } else if (dir == 'B') {                  // backward \u2192 bottom\n        for (int c = 0; c < SZ; ++c) {\n            int wr = SZ - 1;\n            for (int r = SZ - 1; r >= 0; --r) {\n                if (a[r][c] != 0) {\n                    a[wr][c] = a[r][c];\n                    if (wr != r) a[r][c] = 0;\n                    --wr;\n                }\n            }\n        }\n    } else if (dir == 'L') {                  // left\n        for (int r = 0; r < SZ; ++r) {\n            int wc = 0;\n            for (int c = 0; c < SZ; ++c) {\n                if (a[r][c] != 0) {\n                    a[r][wc] = a[r][c];\n                    if (wc != c) a[r][c] = 0;\n                    ++wc;\n                }\n            }\n        }\n    } else if (dir == 'R') {                  // right\n        for (int r = 0; r < SZ; ++r) {\n            int wc = SZ - 1;\n            for (int c = SZ - 1; c >= 0; --c) {\n                if (a[r][c] != 0) {\n                    a[r][wc] = a[r][c];\n                    if (wc != c) a[r][c] = 0;\n                    --wc;\n                }\n            }\n        }\n    }\n}\n\n/* ------------------------------------------------------------\n   \u03a3 size\u00b2 of all connected components\n   ------------------------------------------------------------ */\nlong long sumSquares(const Board &a) {\n    bool vis[SZ][SZ] = {};\n    const int dr[4] = {-1, 1, 0, 0};\n    const int dc[4] = {0, 0, -1, 1};\n    long long sum = 0;\n    for (int r = 0; r < SZ; ++r) {\n        for (int c = 0; c < SZ; ++c) {\n            if (a[r][c] == 0 || vis[r][c]) continue;\n            int fl = a[r][c];\n            int sz = 0;\n            queue<pair<int,int>> q;\n            q.emplace(r, c);\n            vis[r][c] = true;\n            while (!q.empty()) {\n                auto [cr, cc] = q.front(); q.pop();\n                ++sz;\n                for (int k = 0; k < 4; ++k) {\n                    int nr = cr + dr[k];\n                    int nc = cc + dc[k];\n                    if (0 <= nr && nr < SZ && 0 <= nc && nc < SZ &&\n                        !vis[nr][nc] && a[nr][nc] == fl) {\n                        vis[nr][nc] = true;\n                        q.emplace(nr, nc);\n                    }\n                }\n            }\n            sum += 1LL * sz * sz;\n        }\n    }\n    return sum;\n}\n\n/* ------------------------------------------------------------\n   find the p\u2011th empty cell (1\u2011based, row\u2011major)\n   ------------------------------------------------------------ */\npair<int,int> findEmptyCell(const Board &a, int p) {\n    for (int r = 0; r < SZ; ++r)\n        for (int c = 0; c < SZ; ++c)\n            if (a[r][c] == 0) {\n                if (p == 1) return {r, c};\n                --p;\n            }\n    return {-1, -1};\n}\n\n/* ------------------------------------------------------------\n   collect empty cells\n   ------------------------------------------------------------ */\nvector<pair<int,int>> collectEmpty(const Board &b) {\n    vector<pair<int,int>> empties;\n    for (int r = 0; r < SZ; ++r)\n        for (int c = 0; c < SZ; ++c)\n            if (b[r][c] == 0) empties.emplace_back(r, c);\n    return empties;\n}\n\n/* ------------------------------------------------------------\n   expected S after placing one future candy (flavour f)\n   ------------------------------------------------------------ */\nlong long bestOneStep(const Board &b, int f) {\n    vector<pair<int,int>> empties = collectEmpty(b);\n    long long sum = 0;\n    for (auto [r, c] : empties) {\n        Board b2 = b;\n        b2[r][c] = f;\n        long long best = -1;\n        for (char dir : DIRS) {\n            Board b3 = b2;\n            tilt(b3, dir);\n            long long s = sumSquares(b3);\n            if (s > best) best = s;\n        }\n        sum += best;\n    }\n    return sum / empties.size();\n}\n\n/* ------------------------------------------------------------\n   expected S after placing two future candies (flavours f1, f2)\n   Uses exact enumeration when few empty cells, Monte Carlo otherwise.\n   ------------------------------------------------------------ */\nlong long expectedTwoStep(const Board &b, int f1, int f2,\n                           int N1, int N2,\n                           mt19937_64 &rng) {\n    vector<pair<int,int>> empties1 = collectEmpty(b);\n    int cnt1 = (int)empties1.size();\n    if (cnt1 == 0) return sumSquares(b);\n\n    // Use exact enumeration when few empty cells (deterministic)\n    bool exact1 = (cnt1 <= 12);\n    int sample1 = exact1 ? cnt1 : min(N1, cnt1);\n    \n    uniform_int_distribution<int> dist1(0, cnt1 - 1);\n    long long total = 0;\n\n    for (int s = 0; s < sample1; ++s) {\n        int idx1 = exact1 ? s : dist1(rng);\n        auto [r1, c1] = empties1[idx1];\n        Board b1 = b;\n        b1[r1][c1] = f1;\n\n        // best tilt after the first future candy\n        long long best1 = -1;\n        Board bestBoard1;\n        for (char dir : DIRS) {\n            Board b1t = b1;\n            tilt(b1t, dir);\n            long long sval = sumSquares(b1t);\n            if (sval > best1) {\n                best1 = sval;\n                bestBoard1 = b1t;\n            }\n        }\n\n        // collect empties for the second future candy\n        vector<pair<int,int>> empties2 = collectEmpty(bestBoard1);\n        int cnt2 = (int)empties2.size();\n        if (cnt2 == 0) {\n            total += best1;\n            continue;\n        }\n\n        // Exact enumeration for second step when possible\n        bool exact2 = (cnt2 <= 10);\n        int sample2 = exact2 ? cnt2 : min(N2, cnt2);\n        \n        uniform_int_distribution<int> dist2(0, cnt2 - 1);\n        long long sum2 = 0;\n        for (int s2 = 0; s2 < sample2; ++s2) {\n            int idx2 = exact2 ? s2 : dist2(rng);\n            auto [r2, c2] = empties2[idx2];\n            Board b2 = bestBoard1;\n            b2[r2][c2] = f2;\n\n            long long best2 = -1;\n            for (char dir : DIRS) {\n                Board b2t = b2;\n                tilt(b2t, dir);\n                long long sval = sumSquares(b2t);\n                if (sval > best2) best2 = sval;\n            }\n            sum2 += best2;\n        }\n        total += sum2 / sample2;\n    }\n    return total / sample1;\n}\n\n/* ------------------------------------------------------------\n   main\n   ------------------------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int TOTAL = 100;\n    vector<int> flavour(TOTAL + 1);\n    for (int i = 1; i <= TOTAL; ++i) cin >> flavour[i];\n\n    Board board{};\n    for (int r = 0; r < SZ; ++r) board[r].fill(0);\n\n    // fixed seed for deterministic behavior\n    mt19937_64 rng(123456789);\n\n    for (int step = 1; step <= TOTAL; ++step) {\n        int p;\n        cin >> p;\n        auto pos = findEmptyCell(board, p);\n        board[pos.first][pos.second] = flavour[step];\n\n        // choose direction\n        char bestDir = 'F';\n        long long bestValue = -1;\n        long long bestCur = -1;   // tie-breaker\n\n        if (step == TOTAL) {\n            for (char dir : DIRS) {\n                Board b = board;\n                tilt(b, dir);\n                long long cur = sumSquares(b);\n                if (cur > bestValue) {\n                    bestValue = cur;\n                    bestCur = cur;\n                    bestDir = dir;\n                }\n            }\n        } else if (step == TOTAL - 1) {\n            for (char dir : DIRS) {\n                Board b = board;\n                tilt(b, dir);\n                long long cur = sumSquares(b);\n                long long expv = bestOneStep(b, flavour[step + 1]);\n                if (expv > bestValue ||\n                    (expv == bestValue && cur > bestCur)) {\n                    bestValue = expv;\n                    bestCur = cur;\n                    bestDir = dir;\n                }\n            }\n        } else {\n            for (char dir : DIRS) {\n                Board b = board;\n                tilt(b, dir);\n                long long cur = sumSquares(b);\n                long long expv = expectedTwoStep(b,\n                                                 flavour[step + 1],\n                                                 flavour[step + 2],\n                                                 8, 4, rng);\n                if (expv > bestValue ||\n                    (expv == bestValue && cur > bestCur)) {\n                    bestValue = expv;\n                    bestCur = cur;\n                    bestDir = dir;\n                }\n            }\n        }\n\n        cout << bestDir << '\\n';\n        cout.flush();\n        tilt(board, bestDir);\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int M;\n    double epsInput;\n    if (!(cin >> M >> epsInput)) return 0;\n    const double eps = epsInput;                     // edge\u2011flip probability\n\n    /* ---------- choose the smallest possible N ---------- */\n    int N = 4;\n    while (N * (N - 1) / 2 < M) ++N;                 // N \u2264 100 because M \u2264 100\n    const int L = N * (N - 1) / 2;                   // number of possible edges\n\n    /* ---------- list of edges in lexicographic order ---------- */\n    vector<pair<int,int>> edge;\n    edge.reserve(L);\n    for (int i = 0; i < N; ++i)\n        for (int j = i + 1; j < N; ++j)\n            edge.emplace_back(i, j);\n\n    /* ---------- edge counts for the M graphs (different, as far apart as possible) ---------- */\n    vector<int> edgeCnt(M);\n    if (M == 1) {\n        edgeCnt[0] = 0;\n    } else {\n        for (int i = 0; i < M; ++i) {\n            double val = round(1.0 * i * L / (M - 1));\n            edgeCnt[i] = (int)val;\n        }\n        // make them strictly increasing\n        for (int i = 1; i < M; ++i)\n            if (edgeCnt[i] <= edgeCnt[i-1]) edgeCnt[i] = edgeCnt[i-1] + 1;\n        if (edgeCnt[M-1] > L) edgeCnt[M-1] = L;      // safety\n    }\n\n    /* ---------- pre\u2011compute log\u2011factorials ---------- */\n    int maxFact = max(L, N);\n    vector<double> logFact(maxFact + 1);\n    logFact[0] = 0.0;\n    for (int i = 1; i <= maxFact; ++i) logFact[i] = logFact[i-1] + log((double)i);\n    auto logComb = [&](int n, int k) -> double {\n        if (k < 0 || k > n) return -INFINITY;\n        return logFact[n] - logFact[k] - logFact[n - k];\n    };\n\n    /* ---------- log\u2011add helper (stable sum in log\u2011domain) ---------- */\n    auto logAdd = [&](double a, double b) -> double {\n        if (a == -INFINITY) return b;\n        if (b == -INFINITY) return a;\n        if (a > b) return a + log1p(exp(b - a));\n        else       return b + log1p(exp(a - b));\n    };\n\n    /* ---------- exact degree probability tables ---------- */\n    vector<vector<double>> logProbDeg(N, vector<double>(N, -INFINITY));\n    if (eps == 0.0) {\n        for (int d = 0; d < N; ++d) logProbDeg[d][d] = 0.0;\n    } else {\n        double logEps = log(eps);\n        double log1mEps = log(1.0 - eps);\n        for (int d = 0; d < N; ++d) {\n            vector<double> sum(N, -INFINITY);\n            for (int a = 0; a <= d; ++a) {               // survived original edges\n                double logC1 = logComb(d, a);\n                double term1 = a * log1mEps + (d - a) * logEps;\n                for (int b = 0; b <= N - 1 - d; ++b) {   // newly created edges\n                    int k = a + b;\n                    double logC2 = logComb(N - 1 - d, b);\n                    double term2 = b * logEps + (N - 1 - d - b) * log1mEps;\n                    double cur = logC1 + term1 + logC2 + term2;\n                    sum[k] = logAdd(sum[k], cur);\n                }\n            }\n            for (int k = 0; k < N; ++k) logProbDeg[d][k] = sum[k];\n        }\n    }\n\n    /* ---------- generate the M graphs and store their sorted degree sequences ---------- */\n    vector<string> graphStr(M);\n    vector<vector<int>> degSorted(M, vector<int>(N));\n    for (int idx = 0; idx < M; ++idx) {\n        int e = edgeCnt[idx];\n        string s(L, '0');\n        vector<int> deg(N, 0);\n        // random set of edges (deterministic because of seeded rng)\n        mt19937_64 rng(idx + 1234567);\n        vector<int> ord(L);\n        iota(ord.begin(), ord.end(), 0);\n        shuffle(ord.begin(), ord.end(), rng);\n        for (int p = 0; p < e; ++p) {\n            int pos = ord[p];\n            s[pos] = '1';\n            ++deg[edge[pos].first];\n            ++deg[edge[pos].second];\n        }\n        graphStr[idx] = s;\n        vector<int> d = deg;\n        sort(d.begin(), d.end(), greater<int>());\n        degSorted[idx] = d;\n    }\n\n    /* ---------- output the description of the graphs ---------- */\n    cout << N << '\\n';\n    for (const string &g : graphStr) cout << g << '\\n';\n    cout.flush();\n\n    /* ---------- helper: log\u2011probability of observing m edges when original graph has e edges ---------- */\n    auto edgeLogProb = [&](int e, int m) -> double {\n        if (eps == 0.0) return (m == e) ? 0.0 : -INFINITY;\n        double logEps = log(eps);\n        double log1mEps = log(1.0 - eps);\n        double best = -INFINITY;\n        int a_min = max(0, m - (L - e));\n        int a_max = min(e, m);\n        for (int a = a_min; a <= a_max; ++a) {\n            int b = m - a;                               // newly created edges\n            double logC1 = logComb(e, a);\n            double term1 = a * log1mEps + (e - a) * logEps;\n            double logC2 = logComb(L - e, b);\n            double term2 = b * logEps + (L - e - b) * log1mEps;\n            double cur = logC1 + term1 + logC2 + term2;\n            best = logAdd(best, cur);\n        }\n        return best;\n    };\n\n    /* ---------- answer the 100 queries ---------- */\n    for (int q = 0; q < 100; ++q) {\n        string h;  cin >> h;\n\n        /* observed edge count */\n        int m = 0;\n        for (char c : h) if (c == '1') ++m;\n\n        /* observed degree sequence */\n        vector<int> degObs(N, 0);\n        for (int pos = 0; pos < L; ++pos)\n            if (h[pos] == '1') {\n                ++degObs[edge[pos].first];\n                ++degObs[edge[pos].second];\n            }\n        vector<int> degObsSorted = degObs;\n        sort(degObsSorted.begin(), degObsSorted.end(), greater<int>());\n\n        int answer = 0;\n        double bestScore = -INFINITY;\n\n        for (int i = 0; i < M; ++i) {\n            double cur = edgeLogProb(edgeCnt[i], m);\n            // add degree contributions\n            const vector<int> &dOrig = degSorted[i];\n            bool possible = true;\n            for (int v = 0; v < N; ++v) {\n                double lp = logProbDeg[dOrig[v]][degObsSorted[v]];\n                if (lp == -INFINITY) { possible = false; break; }\n                cur += lp;\n            }\n            if (!possible) continue;\n            if (cur > bestScore) {\n                bestScore = cur;\n                answer = i;\n            }\n        }\n\n        cout << answer << '\\n' << flush;\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v, w;\n};\n\nstruct Adj {\n    int to, w, id;\n};\n\nusing i128 = __int128_t;\nconst long long INF = (1LL << 60);\n\n/*---------------------------------------------------------------*/\n/* Dijkstra \u2013 can forbid one edge id ( -1 = allow all )        */\nvoid dijkstra(int start, int forbid,\n              const vector<vector<Adj>>& adj,\n              vector<long long>& dist) {\n    fill(dist.begin(), dist.end(), INF);\n    dist[start] = 0;\n    using P = pair<long long,int>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n    pq.emplace(0LL, start);\n    while (!pq.empty()) {\n        auto [d, v] = pq.top(); pq.pop();\n        if (d != dist[v]) continue;\n        for (const Adj& e : adj[v]) {\n            if (e.id == forbid) continue;\n            long long nd = d + e.w;\n            if (nd < dist[e.to]) {\n                dist[e.to] = nd;\n                pq.emplace(nd, e.to);\n            }\n        }\n    }\n}\n\n/*---------------------------------------------------------------*/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n    vector<Edge> edges(M);\n    vector<vector<Adj>> adj(N + 1);\n    for (int i = 0; i < M; ++i) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        edges[i] = {u, v, w};\n        adj[u].push_back({v, w, i});\n        adj[v].push_back({u, w, i});\n    }\n    /* read and ignore coordinates */\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    /*------------------------------------------------------*/\n    /* 1) cnt[e] \u2013 number of directed shortest\u2011path pairs */\n    vector<long long> cnt(M, 0);\n    vector<long long> dist(N + 1);\n    vector<int> parent(N + 1, -1);\n    for (int s = 1; s <= N; ++s) {\n        fill(dist.begin(), dist.end(), INF);\n        fill(parent.begin(), parent.end(), -1);\n        using P = pair<long long,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        dist[s] = 0;\n        pq.emplace(0LL, s);\n        while (!pq.empty()) {\n            auto [d, v] = pq.top(); pq.pop();\n            if (d != dist[v]) continue;\n            for (const Adj& e : adj[v]) {\n                long long nd = d + e.w;\n                if (nd < dist[e.to]) {\n                    dist[e.to] = nd;\n                    parent[e.to] = e.id;\n                    pq.emplace(nd, e.to);\n                }\n            }\n        }\n        for (int v = 1; v <= N; ++v) {\n            if (v != s && parent[v] != -1) {\n                cnt[parent[v]]++;\n            }\n        }\n    }\n\n    /*------------------------------------------------------*/\n    /* 2) replacement distance for every edge */\n    vector<long long> repDist(M, INF);\n    for (int i = 0; i < M; ++i) {\n        int u = edges[i].u;\n        int v = edges[i].v;\n        dijkstra(u, i, adj, dist);\n        repDist[i] = dist[v];\n    }\n\n    /*------------------------------------------------------*/\n    /* 3) single\u2011edge cost = cnt * max(0, rep - w) */\n    vector<long long> cost2(M, 0);\n    for (int i = 0; i < M; ++i) {\n        long long diff = repDist[i] - edges[i].w;\n        if (diff < 0) diff = 0;\n        cost2[i] = cnt[i] * diff;\n    }\n\n    /*------------------------------------------------------*/\n    /* 4) greedy initial schedule */\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    const int GREEDY_RUNS = 350;\n    vector<int> bestAssign(M, -1);\n    i128 bestMaxLoad = (i128)1 << 126;\n    i128 bestSumLoad = (i128)1 << 126;\n\n    vector<double> rnd(M);\n    uniform_real_distribution<double> realDist(0.0, 1.0);\n\n    for (int run = 0; run < GREEDY_RUNS; ++run) {\n        for (int i = 0; i < M; ++i) rnd[i] = realDist(rng);\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(),\n             [&](int a, int b) {\n                 if (cost2[a] != cost2[b]) return cost2[a] > cost2[b];\n                 return rnd[a] > rnd[b];\n             });\n\n        vector<int> dayCnt(D, 0);\n        vector<i128> load(D, 0);\n        vector<int> curAssign(M, -1);\n\n        for (int idx : order) {\n            // choose the day with the smallest load among those with free capacity\n            i128 bestLoad = (i128)1 << 126;\n            vector<int> candidates;\n            for (int d = 0; d < D; ++d) {\n                if (dayCnt[d] < K) {\n                    if (load[d] < bestLoad) {\n                        bestLoad = load[d];\n                        candidates.clear();\n                        candidates.push_back(d);\n                    } else if (load[d] == bestLoad) {\n                        candidates.push_back(d);\n                    }\n                }\n            }\n            int chosen = candidates[uniform_int_distribution<int>\n                                    (0, (int)candidates.size() - 1)(rng)];\n            curAssign[idx] = chosen;\n            ++dayCnt[chosen];\n            load[chosen] += (i128)cost2[idx];\n        }\n\n        // compute max load and sum load\n        i128 curMaxLoad = 0;\n        i128 curSumLoad = 0;\n        for (int d = 0; d < D; ++d) {\n            if (load[d] > curMaxLoad) curMaxLoad = load[d];\n            curSumLoad += load[d];\n        }\n\n        if (curMaxLoad < bestMaxLoad || (curMaxLoad == bestMaxLoad && curSumLoad < bestSumLoad)) {\n            bestMaxLoad = curMaxLoad;\n            bestSumLoad = curSumLoad;\n            bestAssign = curAssign;\n        }\n    }\n\n    /*------------------------------------------------------*/\n    /* 5) improved local search (lexicographic objective) */\n    // initialise structures for the best schedule\n    vector<int> assign = bestAssign;\n    vector<int> dayCnt(D, 0);\n    vector<i128> load(D, 0);\n    vector<vector<int>> dayEdges(D);   // edges on each day\n\n    for (int i = 0; i < M; ++i) {\n        int d = assign[i];\n        ++dayCnt[d];\n        load[d] += (i128)cost2[i];\n        dayEdges[d].push_back(i);\n    }\n\n    // maintain max load and sum load\n    i128 maxLoad = 0;\n    i128 sumLoad = 0;\n    for (int d = 0; d < D; ++d) {\n        if (load[d] > maxLoad) maxLoad = load[d];\n        sumLoad += load[d];\n    }\n\n    const int ITERATIONS = 5000000;\n    const int MAX_TRIES = 10;  // number of destination days to try\n\n    for (int it = 0; it < ITERATIONS; ++it) {\n        // decide: relocate or swap\n        if (rng() % 2 == 0) {\n            // ----- relocate: pick worst day, then try multiple destinations -----\n            // find worst day (max load)\n            i128 worst = -1;\n            vector<int> worstDays;\n            for (int d = 0; d < D; ++d) {\n                if (load[d] > worst) {\n                    worst = load[d];\n                    worstDays.clear();\n                    worstDays.push_back(d);\n                } else if (load[d] == worst) {\n                    worstDays.push_back(d);\n                }\n            }\n            int d1 = worstDays[uniform_int_distribution<int>(0, (int)worstDays.size() - 1)(rng)];\n\n            if (dayEdges[d1].empty()) continue; // should not happen\n            int idxInDay = uniform_int_distribution<int>(0, (int)dayEdges[d1].size() - 1)(rng);\n            int e = dayEdges[d1][idxInDay];\n\n            // try up to MAX_TRIES random destination days\n            int bestD2 = -1;\n            i128 bestNewMax = maxLoad;\n            i128 bestNewSum = sumLoad;\n            for (int t = 0; t < MAX_TRIES; ++t) {\n                int d2 = uniform_int_distribution<int>(0, D - 1)(rng);\n                if (d2 == d1) continue;\n                if (dayCnt[d2] >= K) continue;\n\n                i128 c = (i128)cost2[e];\n                i128 newLoad1 = load[d1] - c;\n                i128 newLoad2 = load[d2] + c;\n\n                // compute new max load and sum load\n                i128 newMax = newLoad1;\n                if (newLoad2 > newMax) newMax = newLoad2;\n                for (int d = 0; d < D; ++d) {\n                    if (d == d1 || d == d2) continue;\n                    if (load[d] > newMax) newMax = load[d];\n                }\n                i128 newSum = sumLoad; // sum unchanged\n\n                // accept if better (max, sum)\n                if (newMax < bestNewMax || (newMax == bestNewMax && newSum < bestNewSum)) {\n                    bestNewMax = newMax;\n                    bestNewSum = newSum;\n                    bestD2 = d2;\n                }\n            }\n\n            if (bestD2 != -1 && (bestNewMax < maxLoad || (bestNewMax == maxLoad && bestNewSum < sumLoad))) {\n                // accept move to bestD2\n                int d2 = bestD2;\n                i128 c = (i128)cost2[e];\n                // update assign\n                assign[e] = d2;\n                // update dayEdges\n                int lastE = dayEdges[d1].back();\n                dayEdges[d1][idxInDay] = lastE;\n                dayEdges[d1].pop_back();\n                dayEdges[d2].push_back(e);\n                // update counts and loads\n                --dayCnt[d1];\n                ++dayCnt[d2];\n                load[d1] -= c;\n                load[d2] += c;\n                maxLoad = bestNewMax;\n                sumLoad = bestNewSum;\n\n                if (maxLoad < bestMaxLoad || (maxLoad == bestMaxLoad && sumLoad < bestSumLoad)) {\n                    bestMaxLoad = maxLoad;\n                    bestSumLoad = sumLoad;\n                    bestAssign = assign;\n                }\n            }\n        } else {\n            // ----- swap: pick two random edges from two random days -----\n            int d1 = uniform_int_distribution<int>(0, D - 1)(rng);\n            int d2;\n            do {\n                d2 = uniform_int_distribution<int>(0, D - 1)(rng);\n            } while (d2 == d1);\n\n            if (dayEdges[d1].empty() || dayEdges[d2].empty()) continue;\n\n            int idx1 = uniform_int_distribution<int>(0, (int)dayEdges[d1].size() - 1)(rng);\n            int idx2 = uniform_int_distribution<int>(0, (int)dayEdges[d2].size() - 1)(rng);\n            int e1 = dayEdges[d1][idx1];\n            int e2 = dayEdges[d2][idx2];\n\n            // compute new loads after swap\n            i128 c1 = (i128)cost2[e1];\n            i128 c2 = (i128)cost2[e2];\n            i128 newLoad1 = load[d1] - c1 + c2;\n            i128 newLoad2 = load[d2] - c2 + c1;\n\n            // compute new max load and sum load\n            i128 newMax = newLoad1;\n            if (newLoad2 > newMax) newMax = newLoad2;\n            for (int d = 0; d < D; ++d) {\n                if (d == d1 || d == d2) continue;\n                if (load[d] > newMax) newMax = load[d];\n            }\n            i128 newSum = sumLoad; // sum unchanged\n\n            if (newMax < maxLoad || (newMax == maxLoad && newSum < sumLoad)) {\n                // accept swap\n                // update assign\n                assign[e1] = d2;\n                assign[e2] = d1;\n                // update dayEdges\n                dayEdges[d1][idx1] = e2;\n                dayEdges[d2][idx2] = e1;\n                // update loads\n                load[d1] = newLoad1;\n                load[d2] = newLoad2;\n                maxLoad = newMax;\n                sumLoad = newSum;\n\n                if (maxLoad < bestMaxLoad || (maxLoad == bestMaxLoad && sumLoad < bestSumLoad)) {\n                    bestMaxLoad = maxLoad;\n                    bestSumLoad = sumLoad;\n                    bestAssign = assign;\n                }\n            }\n        }\n    }\n\n    /*------------------------------------------------------*/\n    /* 6) output */\n    for (int i = 0; i < M; ++i) {\n        if (i) cout << ' ';\n        cout << (bestAssign[i] + 1);   // days are 1\u2011based\n    }\n    cout << '\\n';\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D;\n    if (!(cin >> D)) return 0;\n    vector<string> f1(D), r1(D), f2(D), r2(D);\n    for (int z = 0; z < D; ++z) cin >> f1[z];\n    for (int z = 0; z < D; ++z) cin >> r1[z];\n    for (int z = 0; z < D; ++z) cin >> f2[z];\n    for (int z = 0; z < D; ++z) cin >> r2[z];\n\n    const int N = D * D * D;\n    auto idx = [&](int x, int y, int z) { return x * D * D + y * D + z; };\n\n    vector<char> allowed1(N, 0), allowed2(N, 0), inter(N, 0);\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                int id = idx(x, y, z);\n                allowed1[id] = (f1[z][x] == '1' && r1[z][y] == '1');\n                allowed2[id] = (f2[z][x] == '1' && r2[z][y] == '1');\n                inter[id] = allowed1[id] & allowed2[id];\n            }\n\n    /* ---------- connected components of intersection ---------- */\n    vector<int> comp(N, -1);\n    vector<vector<int>> comps;\n    const int dx[6] = {1,-1,0,0,0,0};\n    const int dy[6] = {0,0,1,-1,0,0};\n    const int dz[6] = {0,0,0,0,1,-1};\n\n    for (int id = 0; id < N; ++id) if (inter[id] && comp[id] == -1) {\n        queue<int> q;\n        q.push(id);\n        comp[id] = (int)comps.size();\n        vector<int> cells;\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            cells.push_back(v);\n            int x = v / (D * D);\n            int rem = v % (D * D);\n            int y = rem / D;\n            int z = rem % D;\n            for (int dir = 0; dir < 6; ++dir) {\n                int nx = x + dx[dir];\n                int ny = y + dy[dir];\n                int nz = z + dz[dir];\n                if (nx < 0 || nx >= D || ny < 0 || ny >= D || nz < 0 || nz >= D) continue;\n                int nid = idx(nx, ny, nz);\n                if (inter[nid] && comp[nid] == -1) {\n                    comp[nid] = (int)comps.size();\n                    q.push(nid);\n                }\n            }\n        }\n        comps.push_back(move(cells));\n    }\n\n    int nShared = (int)comps.size();\n\n    /* ---------- output arrays ---------- */\n    vector<int> out1(N, 0), out2(N, 0);\n    for (int ci = 0; ci < nShared; ++ci) {\n        int bid = ci + 1;                       // block numbers start with 1\n        for (int v : comps[ci]) {\n            out1[v] = bid;\n            out2[v] = bid;\n        }\n    }\n\n    /* ---------- coverage tables ---------- */\n    vector<vector<vector<char>>> frontCov(2, vector<vector<char>>(D, vector<char>(D, 0)));\n    vector<vector<vector<char>>> rightCov(2, vector<vector<char>>(D, vector<char>(D, 0)));\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                int id = idx(x, y, z);\n                if (inter[id]) {\n                    frontCov[0][z][x] = 1;\n                    rightCov[0][z][y] = 1;\n                    frontCov[1][z][x] = 1;\n                    rightCov[1][z][y] = 1;\n                }\n            }\n\n    int nextBlock = nShared + 1;\n\n    const vector<string>* f[2] = {&f1, &f2};\n    const vector<string>* r[2] = {&r1, &r2};\n    const vector<char>* allow[2] = {&allowed1, &allowed2};\n\n    for (int obj = 0; obj < 2; ++obj) {\n        const vector<string>& fobj = *f[obj];\n        const vector<string>& robj = *r[obj];\n        const vector<char>& allowObj = *allow[obj];\n        vector<int>& out = (obj == 0 ? out1 : out2);\n\n        for (int z = 0; z < D; ++z) {\n            vector<int> X, Y;\n            for (int x = 0; x < D; ++x)\n                if (fobj[z][x] == '1' && !frontCov[obj][z][x]) X.push_back(x);\n            for (int y = 0; y < D; ++y)\n                if (robj[z][y] == '1' && !rightCov[obj][z][y]) Y.push_back(y);\n            int L = (int)X.size();\n            int R = (int)Y.size();\n            if (L == 0 && R == 0) continue;\n\n            /* ---- case L == 0 : only right columns have to be covered ---- */\n            if (L == 0) {\n                for (int y : Y) {\n                    for (int x = 0; x < D; ++x) {\n                        int id = idx(x, y, z);\n                        if (allowObj[id] && !inter[id] && out[id] == 0) {\n                            out[id] = nextBlock++;\n                            frontCov[obj][z][x] = 1;\n                            rightCov[obj][z][y] = 1;\n                            break;\n                        }\n                    }\n                }\n                continue;\n            }\n            /* ---- case R == 0 : only front columns have to be covered ---- */\n            if (R == 0) {\n                for (int x : X) {\n                    for (int y = 0; y < D; ++y) {\n                        int id = idx(x, y, z);\n                        if (allowObj[id] && !inter[id] && out[id] == 0) {\n                            out[id] = nextBlock++;\n                            frontCov[obj][z][x] = 1;\n                            rightCov[obj][z][y] = 1;\n                            break;\n                        }\n                    }\n                }\n                continue;\n            }\n\n            /* ---- general case ---- */\n            vector<vector<int>> adj(L);\n            for (int li = 0; li < L; ++li) {\n                int x = X[li];\n                for (int rj = 0; rj < R; ++rj) {\n                    int y = Y[rj];\n                    int id = idx(x, y, z);\n                    if (allowObj[id] && !inter[id]) adj[li].push_back(rj);\n                }\n            }\n\n            /* maximum matching (simple DFS augment) */\n            vector<int> matchR(R, -1);\n            function<bool(int, vector<char>&)> dfs = [&](int v, vector<char>& seen) -> bool {\n                for (int to : adj[v]) {\n                    if (seen[to]) continue;\n                    seen[to] = true;\n                    if (matchR[to] == -1 || dfs(matchR[to], seen)) {\n                        matchR[to] = v;\n                        return true;\n                    }\n                }\n                return false;\n            };\n            for (int v = 0; v < L; ++v) {\n                vector<char> seen(R, 0);\n                dfs(v, seen);\n            }\n\n            /* build a minimum edge cover */\n            vector<char> covL(L, 0), covR(R, 0);\n            vector<pair<int,int>> edges;\n\n            for (int rj = 0; rj < R; ++rj) {\n                int li = matchR[rj];\n                if (li != -1) {\n                    edges.emplace_back(li, rj);\n                    covL[li] = covR[rj] = 1;\n                }\n            }\n            for (int li = 0; li < L; ++li) if (!covL[li]) {\n                if (!adj[li].empty()) {\n                    int rj = adj[li][0];\n                    edges.emplace_back(li, rj);\n                    covL[li] = 1;\n                }\n            }\n            for (int rj = 0; rj < R; ++rj) if (!covR[rj]) {\n                bool found = false;\n                for (int li = 0; li < L && !found; ++li) {\n                    for (int to : adj[li]) if (to == rj) {\n                        edges.emplace_back(li, rj);\n                        covR[rj] = 1;\n                        found = true;\n                        break;\n                    }\n                }\n                if (!found) {                 // should not happen for a solvable instance\n                    edges.emplace_back(-1, rj);   // placeholder, will be handled later\n                }\n            }\n\n            /* place the exclusive cells */\n            vector<vector<char>> used(D, vector<char>(D, 0));\n            for (auto &pr : edges) {\n                int li = pr.first, rj = pr.second;\n                if (li == -1) {               // placeholder\n                    int y = Y[rj];\n                    for (int x = 0; x < D; ++x) {\n                        int id = idx(x, y, z);\n                        if (allowObj[id] && !inter[id] && out[id] == 0 && !used[x][y]) {\n                            out[id] = nextBlock++;\n                            frontCov[obj][z][x] = 1;\n                            rightCov[obj][z][y] = 1;\n                            used[x][y] = 1;\n                            break;\n                        }\n                    }\n                    continue;\n                }\n                int x = X[li];\n                int y = Y[rj];\n                if (used[x][y]) continue;\n                used[x][y] = 1;\n                int id = idx(x, y, z);\n                out[id] = nextBlock++;\n                frontCov[obj][z][x] = 1;\n                rightCov[obj][z][y] = 1;\n            }\n\n            /* safety net \u2013 guarantee coverage (normally not needed) */\n            for (int x : X) if (!frontCov[obj][z][x]) {\n                for (int y = 0; y < D; ++y) {\n                    int id = idx(x, y, z);\n                    if (allowObj[id] && !inter[id] && out[id] == 0) {\n                        out[id] = nextBlock++;\n                        frontCov[obj][z][x] = 1;\n                        rightCov[obj][z][y] = 1;\n                        break;\n                    }\n                }\n            }\n            for (int y : Y) if (!rightCov[obj][z][y]) {\n                for (int x = 0; x < D; ++x) {\n                    int id = idx(x, y, z);\n                    if (allowObj[id] && !inter[id] && out[id] == 0) {\n                        out[id] = nextBlock++;\n                        frontCov[obj][z][x] = 1;\n                        rightCov[obj][z][y] = 1;\n                        break;\n                    }\n                }\n            }\n        }\n    }\n\n    int totalBlocks = nextBlock - 1;\n    cout << totalBlocks << '\\n';\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << out1[i];\n    }\n    cout << '\\n';\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << out2[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nconst ll INFLL = (1LL << 60);\nconst int MAXR = 5000;\nconst ll MAXD2 = 1LL * MAXR * MAXR;          // 25 000 000\n\n/* ------------------------------------------------------------ */\n/*  global data                                                 */\nint N, M, K;\nint WORDS;                                  // (K+63)/64\n\nvector<int> X, Y;                           // vertex coordinates\nvector<int> A, B;                           // resident coordinates\n\nstruct Edge { int u, v, w; };\nvector<Edge> edges;                         // 1\u2011based\nvector<vector<pair<int,int>>> adj;          // (neighbour, edge id)\n\nvector<vector<ll>> dist2;                   // squared distances vertex \u2192 resident\nvector<vector<ll>> wgt;                     // cheapest edge weight between u and v\nvector<vector<int>> edgeIdx;                // cheapest edge index, -1 if none\n\nvector<vector<unsigned long long>> coverMask;   // bitset of residents covered by each vertex\n\n/* ------------------------------------------------------------ */\n/*  integer ceiling of sqrt                                      */\nint ceil_sqrt_ll(ll x) {\n    if (x <= 0) return 0;\n    ll r = (ll)std::sqrt((double)x);\n    while (r * r < x) ++r;\n    while (r > 0 && (r - 1) * (r - 1) >= x) --r;\n    return (int)r;\n}\n\n/* ------------------------------------------------------------ */\n/*  key for a set of vertices (128 bits)                        */\nstruct Key {\n    uint64_t lo, hi;\n    bool operator==(const Key& o) const noexcept { return lo == o.lo && hi == o.hi; }\n};\nstruct KeyHash {\n    size_t operator()(Key const& k) const noexcept {\n        return std::hash<uint64_t>{}(k.lo ^ (k.hi << 1));\n    }\n};\n\nKey makeKey(const vector<int>& S) {\n    uint64_t lo = 0, hi = 0;\n    for (int v : S) {\n        if (v <= 64) lo |= 1ULL << (v - 1);\n        else          hi |= 1ULL << (v - 65);\n    }\n    return {lo, hi};\n}\n\n/* ------------------------------------------------------------ */\n/*  cache: key \u2192 (feasible , cost , edgeList)                   */\nstruct CacheVal {\n    bool feasible;\n    ll   cost;\n    vector<int> edgeList;          // MST edges (only filled when feasible)\n};\nunordered_map<Key, CacheVal, KeyHash> cache;\n\n/* ------------------------------------------------------------ */\n/*  evaluate a vertex set, return feasibility and cost.\n    The result (including edgeList) is cached.                     */\nbool evaluateSet(const vector<int>& S, ll& cost, vector<int>* edgeListPtr = nullptr) {\n    Key key = makeKey(S);\n    auto it = cache.find(key);\n    if (it != cache.end()) {\n        cost = it->second.cost;\n        if (edgeListPtr && !it->second.edgeList.empty())\n            *edgeListPtr = it->second.edgeList;\n        return it->second.feasible;\n    }\n\n    /* ----- coverage test (bitsets) ----- */\n    vector<unsigned long long> curMask(WORDS, 0);\n    for (int v : S) {\n        for (int w = 0; w < WORDS; ++w) curMask[w] |= coverMask[v][w];\n    }\n    int covered = 0;\n    for (int w = 0; w < WORDS; ++w) covered += __builtin_popcountll(curMask[w]);\n    if (covered < K) {                 // uncovered resident \u2192 infeasible\n        cache[key] = {false, INFLL, {}};\n        return false;\n    }\n\n    /* ----- nearest vertex for each resident ----- */\n    vector<ll> maxDist2(N + 1, 0);\n    for (int k = 0; k < K; ++k) {\n        ll bestDist = INFLL;\n        int bestVert = -1;\n        for (int v : S) {\n            ll d = dist2[v][k];\n            if (d < bestDist) {\n                bestDist = d;\n                bestVert = v;\n            }\n        }\n        if (bestVert == -1) {         // should not happen after coverage test\n            cache[key] = {false, INFLL, {}};\n            return false;\n        }\n        if (bestDist > maxDist2[bestVert]) maxDist2[bestVert] = bestDist;\n    }\n\n    /* ----- radii and \u03a3R\u00b2 ----- */\n    ll sumSq = 0;\n    for (int v : S) {\n        ll md2 = maxDist2[v];\n        int r = (md2 == 0) ? 0 : ceil_sqrt_ll(md2);\n        if (r > MAXR) {\n            cache[key] = {false, INFLL, {}};\n            return false;\n        }\n        sumSq += 1LL * r * r;\n    }\n\n    /* ----- minimum spanning tree (Prim) ----- */\n    vector<char> inS(N + 1, 0);\n    for (int v : S) inS[v] = 1;\n\n    vector<ll>  minEdge(N + 1, INFLL);\n    vector<int> parentEdge(N + 1, -1);\n    vector<char> visited(N + 1, 0);\n    visited[1] = 1;                     // source is always present\n    for (int u = 1; u <= N; ++u) {\n        if (!inS[u] || u == 1) continue;\n        if (edgeIdx[1][u] != -1) {\n            minEdge[u] = wgt[1][u];\n            parentEdge[u] = edgeIdx[1][u];\n        }\n    }\n\n    ll edgeCost = 0;\n    vector<int> edgesUsed;\n    for (int it = 0; it < (int)S.size() - 1; ++it) {\n        int v = -1;\n        ll best = INFLL;\n        for (int u = 1; u <= N; ++u) {\n            if (inS[u] && !visited[u] && minEdge[u] < best) {\n                best = minEdge[u];\n                v = u;\n            }\n        }\n        if (v == -1) {                 // not connected\n            cache[key] = {false, INFLL, {}};\n            return false;\n        }\n        visited[v] = 1;\n        edgeCost += best;\n        edgesUsed.push_back(parentEdge[v]);\n        for (int u = 1; u <= N; ++u) {\n            if (inS[u] && !visited[u] && edgeIdx[v][u] != -1) {\n                ll w = wgt[v][u];\n                if (w < minEdge[u]) {\n                    minEdge[u] = w;\n                    parentEdge[u] = edgeIdx[v][u];\n                }\n            }\n        }\n    }\n\n    cost = sumSq + edgeCost;\n    CacheVal cv = {true, cost, edgesUsed};\n    cache[key] = cv;\n    if (edgeListPtr) *edgeListPtr = edgesUsed;\n    return true;\n}\n\n/* ------------------------------------------------------------ */\n/*  full evaluation \u2013 also returns radii and MST edges.\n    (used only for the final answer)                           */\nvoid fullEvaluation(const vector<int>& S,\n                    bool& feasible, ll& cost,\n                    vector<int>& radius,\n                    vector<int>& edgesUsed) {\n    /* ----- coverage test ----- */\n    vector<unsigned long long> curMask(WORDS, 0);\n    for (int v : S) {\n        for (int w = 0; w < WORDS; ++w) curMask[w] |= coverMask[v][w];\n    }\n    int covered = 0;\n    for (int w = 0; w < WORDS; ++w) covered += __builtin_popcountll(curMask[w]);\n    feasible = (covered == K);\n    if (!feasible) { cost = INFLL; return; }\n\n    /* ----- nearest vertex for each resident ----- */\n    vector<ll> maxDist2(N + 1, 0);\n    for (int k = 0; k < K; ++k) {\n        ll bestDist = INFLL;\n        int bestVert = -1;\n        for (int v : S) {\n            ll d = dist2[v][k];\n            if (d < bestDist) {\n                bestDist = d;\n                bestVert = v;\n            }\n        }\n        if (bestDist > maxDist2[bestVert]) maxDist2[bestVert] = bestDist;\n    }\n\n    /* ----- radii ----- */\n    radius.assign(N + 1, 0);\n    ll sumSq = 0;\n    for (int v : S) {\n        ll md2 = maxDist2[v];\n        int r = (md2 == 0) ? 0 : ceil_sqrt_ll(md2);\n        radius[v] = r;\n        sumSq += 1LL * r * r;\n    }\n\n    /* ----- MST (Prim) ----- */\n    vector<char> inS(N + 1, 0);\n    for (int v : S) inS[v] = 1;\n\n    vector<ll>  minEdge(N + 1, INFLL);\n    vector<int> parentEdge(N + 1, -1);\n    vector<char> visited(N + 1, 0);\n    visited[1] = 1;\n    for (int u = 1; u <= N; ++u) {\n        if (!inS[u] || u == 1) continue;\n        if (edgeIdx[1][u] != -1) {\n            minEdge[u] = wgt[1][u];\n            parentEdge[u] = edgeIdx[1][u];\n        }\n    }\n\n    edgesUsed.clear();\n    ll edgeCost = 0;\n    for (int it = 0; it < (int)S.size() - 1; ++it) {\n        int v = -1;\n        ll best = INFLL;\n        for (int u = 1; u <= N; ++u) {\n            if (inS[u] && !visited[u] && minEdge[u] < best) {\n                best = minEdge[u];\n                v = u;\n            }\n        }\n        if (v == -1) {                 // not connected \u2013 should not happen\n            feasible = false;\n            cost = INFLL;\n            return;\n        }\n        visited[v] = 1;\n        edgeCost += best;\n        edgesUsed.push_back(parentEdge[v]);\n        for (int u = 1; u <= N; ++u) {\n            if (inS[u] && !visited[u] && edgeIdx[v][u] != -1) {\n                ll w = wgt[v][u];\n                if (w < minEdge[u]) {\n                    minEdge[u] = w;\n                    parentEdge[u] = edgeIdx[v][u];\n                }\n            }\n        }\n    }\n\n    cost = sumSq + edgeCost;\n}\n\n/* ------------------------------------------------------------ */\n/*  neighbours of a set (vertices not in the set, adjacent to it) */\nvector<int> neighbours(const vector<char>& inS) {\n    vector<char> seen(N + 1, 0);\n    vector<int> res;\n    for (int v = 1; v <= N; ++v) if (inS[v]) {\n        for (auto [to, id] : adj[v]) {\n            if (!inS[to] && !seen[to]) {\n                seen[to] = 1;\n                res.push_back(to);\n            }\n        }\n    }\n    return res;\n}\n\n/* ------------------------------------------------------------ */\n/*  one\u2011pass 2\u2011opt: try to replace the heaviest edge on each cycle   */\nvoid improveMSTOnePass(const vector<int>& edgeList,\n                      vector<int>& bestEdges,\n                      ll& edgeCost) {\n    // Build adjacency list of the current MST\n    vector<vector<pair<int,int>>> mstAdj(N + 1);\n    vector<char> inMst(M + 1, 0);\n    for (int id : edgeList) {\n        inMst[id] = 1;\n        int a = edges[id].u, b = edges[id].v;\n        mstAdj[a].push_back({b, id});\n        mstAdj[b].push_back({a, id});\n    }\n\n    // For each edge not in the MST, try to replace the heaviest edge on the cycle\n    for (int id = 1; id <= M; ++id) {\n        if (inMst[id]) continue;\n        int a = edges[id].u, b = edges[id].v;\n\n        // BFS to find path a -> b in the MST and its heaviest edge\n        vector<int> parent(N + 1, -1), parentEdge(N + 1, -1);\n        vector<char> seen(N + 1, 0);\n        queue<int> q;\n        q.push(a);\n        seen[a] = 1;\n        while (!q.empty() && parent[b] == -1) {\n            int v = q.front(); q.pop();\n            for (auto [to, eid] : mstAdj[v]) {\n                if (seen[to]) continue;\n                seen[to] = 1;\n                parent[to] = v;\n                parentEdge[to] = eid;\n                if (to == b) break;\n                q.push(to);\n            }\n        }\n        if (parent[b] == -1) continue; // should not happen (connected graph)\n\n        // Find the heaviest edge on the path a\u2013b\n        int worstId = -1;\n        ll worstW = -1;\n        int cur = b;\n        while (cur != a) {\n            int eid = parentEdge[cur];\n            if (eid == -1) break;\n            ll w = edges[eid].w;\n            if (w > worstW) {\n                worstW = w;\n                worstId = eid;\n            }\n            cur = parent[cur];\n        }\n        if (worstId == -1) continue;\n\n        // If the new edge is cheaper, replace\n        ll newW = edges[id].w;\n        if (newW < worstW) {\n            edgeCost += newW - worstW;\n            // Update edge list\n            for (int &e : bestEdges) if (e == worstId) { e = id; break; }\n            // Rebuild adjacency\n            bestEdges.clear();\n            bestEdges = edgeList;\n            for (int &e : bestEdges) if (e == worstId) { e = id; break; }\n            mstAdj.assign(N + 1, {});\n            fill(inMst.begin(), inMst.end(), 0);\n            for (int eid : bestEdges) {\n                inMst[eid] = 1;\n                int u = edges[eid].u, v = edges[eid].v;\n                mstAdj[u].push_back({v, eid});\n                mstAdj[v].push_back({u, eid});\n            }\n        }\n    }\n}\n\n/* ------------------------------------------------------------ */\n/*  one complete run of the heuristic                           */\nvoid runHeuristic(ll& bestCost,\n                  vector<int>& bestS,\n                  vector<int>& bestEdges,\n                  ll seed)\n{\n    std::mt19937 rng(seed);\n\n    /* ----- greedy start ----- */\n    vector<int> curS = {1};\n    vector<char> inS(N + 1, 0);\n    inS[1] = 1;\n    vector<unsigned long long> curMask(WORDS, 0);\n    for (int w = 0; w < WORDS; ++w) curMask[w] = coverMask[1][w];\n\n    bool feasible = false;\n    ll curCost = 0;\n    feasible = evaluateSet(curS, curCost);\n    if (!feasible) {\n        while (!feasible) {\n            vector<int> cand = neighbours(inS);\n            shuffle(cand.begin(), cand.end(), rng);\n            ll bestC = INFLL;\n            int bestV = -1;\n            for (int v : cand) {\n                vector<int> ns = curS;\n                ns.push_back(v);\n                ll c;\n                bool f = evaluateSet(ns, c);\n                if (f && c < bestC) {\n                    bestC = c;\n                    bestV = v;\n                }\n            }\n            if (bestV == -1) { // fallback \u2013 add any remaining vertex\n                for (int v = 1; v <= N; ++v) if (!inS[v]) { bestV = v; break; }\n            }\n            inS[bestV] = 1;\n            curS.push_back(bestV);\n            for (int w = 0; w < WORDS; ++w) curMask[w] |= coverMask[bestV][w];\n            feasible = evaluateSet(curS, curCost);\n        }\n    }\n\n    /* ----- keep the best solution found so far ----- */\n    bestCost = curCost;\n    bestS = curS;\n\n    /* ----- local search (removal \u2013 addition \u2013 swap) ----- */\n    bool changed = true;\n    while (changed) {\n        changed = false;\n        // ---- removal (shuffled order) ----\n        vector<int> remOrder(bestS.size());\n        iota(remOrder.begin(), remOrder.end(), 0);\n        shuffle(remOrder.begin(), remOrder.end(), rng);\n        for (size_t ii = 0; ii < remOrder.size(); ++ii) {\n            int i = remOrder[ii];\n            int v = bestS[i];\n            if (v == 1) continue;\n            bool essential = false;\n            for (int w = 0; w < WORDS; ++w) {\n                unsigned long long after = curMask[w] & ~coverMask[v][w];\n                if (after != curMask[w]) { essential = true; break; }\n            }\n            if (essential) continue;\n            vector<int> ns = bestS;\n            ns.erase(ns.begin() + i);\n            ll c;\n            bool f = evaluateSet(ns, c);\n            if (f && c < bestCost - 1) {\n                bestCost = c;\n                bestS = ns;\n                fill(curMask.begin(), curMask.end(), 0ULL);\n                for (int xv : bestS)\n                    for (int w = 0; w < WORDS; ++w) curMask[w] |= coverMask[xv][w];\n                fill(inS.begin(), inS.end(), 0);\n                for (int xv : bestS) inS[xv] = 1;\n                changed = true;\n                break;\n            }\n        }\n        if (changed) continue;\n        // ---- addition ----\n        vector<int> cand = neighbours(inS);\n        shuffle(cand.begin(), cand.end(), rng);\n        for (int v : cand) {\n            vector<int> ns = bestS;\n            ns.push_back(v);\n            ll c;\n            bool f = evaluateSet(ns, c);\n            if (f && c < bestCost - 1) {\n                bestCost = c;\n                bestS = ns;\n                inS[v] = 1;\n                for (int w = 0; w < WORDS; ++w) curMask[w] |= coverMask[v][w];\n                changed = true;\n                break;\n            }\n        }\n        if (changed) continue;\n        // ---- swap ----\n        vector<pair<int,int>> swaps;\n        for (int v : bestS) if (v != 1) {\n            for (auto [to, id] : adj[v]) if (!inS[to]) swaps.emplace_back(v, to);\n        }\n        shuffle(swaps.begin(), swaps.end(), rng);\n        for (auto [v, u] : swaps) {\n            vector<int> ns;\n            ns.reserve(bestS.size());\n            for (int x : bestS) if (x != v) ns.push_back(x);\n            ns.push_back(u);\n            ll c;\n            bool f = evaluateSet(ns, c);\n            if (f && c < bestCost - 1) {\n                bestCost = c;\n                bestS = ns;\n                inS[v] = 0;\n                inS[u] = 1;\n                fill(curMask.begin(), curMask.end(), 0ULL);\n                for (int xv : bestS)\n                    for (int w = 0; w < WORDS; ++w) curMask[w] |= coverMask[xv][w];\n                changed = true;\n                break;\n            }\n        }\n    }\n\n    /* ----- improve edge cost with one\u2011pass 2\u2011opt ----- */\n    // Get the cached MST edge list (guaranteed to be present)\n    vector<int> cachedEdges;\n    evaluateSet(bestS, curCost, &cachedEdges);   // curCost already equals bestCost\n    bestEdges = cachedEdges;\n    // Compute original edge cost\n    ll edgeCostOriginal = 0;\n    for (int id : cachedEdges) edgeCostOriginal += edges[id].w;\n    // Single 2\u2011opt pass\n    ll edgeCostNew = edgeCostOriginal;\n    improveMSTOnePass(bestEdges, bestEdges, edgeCostNew);\n    // Compute total cost\n    ll sumSq = bestCost - edgeCostOriginal;\n    bestCost = sumSq + edgeCostNew;\n}\n\n/* ------------------------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ----- input ----- */\n    cin >> N >> M >> K;\n    X.resize(N + 1);\n    Y.resize(N + 1);\n    for (int i = 1; i <= N; ++i) cin >> X[i] >> Y[i];\n\n    edges.resize(M + 1);\n    adj.assign(N + 1, {});\n    wgt.assign(N + 1, vector<ll>(N + 1, INFLL));\n    edgeIdx.assign(N + 1, vector<int>(N + 1, -1));\n\n    for (int j = 1; j <= M; ++j) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        edges[j] = {u, v, w};\n        adj[u].push_back({v, j});\n        adj[v].push_back({u, j});\n        if (w < wgt[u][v]) {\n            wgt[u][v] = wgt[v][u] = w;\n            edgeIdx[u][v] = edgeIdx[v][u] = j;\n        }\n    }\n\n    A.resize(K);\n    B.resize(K);\n    for (int k = 0; k < K; ++k) cin >> A[k] >> B[k];\n\n    /* ----- pre\u2011computations ----- */\n    WORDS = (K + 63) / 64;\n    dist2.assign(N + 1, vector<ll>(K, 0));\n    coverMask.assign(N + 1, vector<unsigned long long>(WORDS, 0));\n\n    for (int i = 1; i <= N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            ll dx = X[i] - A[k];\n            ll dy = Y[i] - B[k];\n            ll d2 = dx * dx + dy * dy;\n            dist2[i][k] = d2;\n            if (d2 <= MAXD2) {\n                coverMask[i][k / 64] |= 1ULL << (k % 64);\n            }\n        }\n    }\n\n    /* ----- run the heuristic three times ----- */\n    ll bestOverall = INFLL;\n    vector<int> bestSOverall;\n    vector<int> bestEdgesOverall;\n\n    const int RUNS = 3;                 // three runs \u2013 fast enough\n    for (int r = 0; r < RUNS; ++r) {\n        ll seed = (unsigned)chrono::steady_clock::now().time_since_epoch().count() + r * 1234567ULL;\n        ll curCost;\n        vector<int> curS, curEdges;\n        runHeuristic(curCost, curS, curEdges, seed);\n        if (curCost < bestOverall) {\n            bestOverall = curCost;\n            bestSOverall = curS;\n            bestEdgesOverall = curEdges;\n        }\n    }\n\n    /* ----- final full evaluation (radii) ----- */\n    bool finalFeas;\n    ll finalCost;\n    vector<int> finalRadius;\n    fullEvaluation(bestSOverall, finalFeas, finalCost, finalRadius, bestEdgesOverall);\n\n    /* ----- output ----- */\n    for (int i = 1; i <= N; ++i) {\n        if (i > 1) cout << ' ';\n        cout << finalRadius[i];\n    }\n    cout << '\\n';\n    vector<int> B(M + 1, 0);\n    for (int id : bestEdgesOverall) B[id] = 1;\n    for (int j = 1; j <= M; ++j) {\n        if (j > 1) cout << ' ';\n        cout << B[j];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Swap {\n    int x1, y1, x2, y2;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 30;\n    const int M = N * (N + 1) / 2;          // 465\n\n    /* ----- convert triangular coordinates to linear indices ----- */\n    vector<vector<int>> idx(N, vector<int>(N, -1));\n    int cur = 0;\n    for (int x = 0; x < N; ++x)\n        for (int y = 0; y <= x; ++y)\n            idx[x][y] = cur++;\n\n    /* ----- read the permutation ----- */\n    vector<int> initValue(M);\n    for (int x = 0; x < N; ++x)\n        for (int y = 0; y <= x; ++y) {\n            int v;  cin >> v;\n            initValue[idx[x][y]] = v;\n        }\n\n    /* ----- helper: test whether the array is a heap ----- */\n    auto isHeap = [&](const vector<int>& a) -> bool {\n        for (int x = 0; x + 1 < N; ++x) {\n            for (int y = 0; y <= x; ++y) {\n                int p = idx[x][y];\n                int l = idx[x + 1][y];\n                int r = idx[x + 1][y + 1];\n                if (a[p] > a[l] || a[p] > a[r]) return false;\n            }\n        }\n        return true;\n    };\n\n    /* ----- many randomised heapify runs ----- */\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    const int TRIALS = 5000;                // increased from 2000\n    const double EPS = 0.2;                // increased from 0.1\n\n    vector<Swap> bestOps;\n    int bestK = INT_MAX;\n\n    for (int trial = 0; trial < TRIALS; ++trial) {\n        vector<int> curVal = initValue;   // copy\n        vector<Swap> ops;\n\n        // bottom\u2011up, level by level\n        for (int x = N - 2; x >= 0; --x) {\n            // order of processing the nodes on this level\n            vector<int> ys(x + 1);\n            iota(ys.begin(), ys.end(), 0);\n            if (trial > 0) shuffle(ys.begin(), ys.end(), rng);\n\n            for (int y : ys) {\n                int curX = x, curY = y;\n                while (curX < N - 1) {\n                    int pIdx = idx[curX][curY];\n                    int lIdx = idx[curX + 1][curY];\n                    int rIdx = idx[curX + 1][curY + 1];\n\n                    int childIdx = -1, childX = -1, childY = -1;\n\n                    // look for a child that violates the heap property\n                    if (curVal[pIdx] > curVal[lIdx]) {\n                        childIdx = lIdx;\n                        childX = curX + 1;\n                        childY = curY;\n                    }\n                    if (curVal[pIdx] > curVal[rIdx]) {\n                        if (childIdx == -1 || curVal[rIdx] < curVal[childIdx]) {\n                            childIdx = rIdx;\n                            childX = curX + 1;\n                            childY = curY + 1;\n                        }\n                    }\n\n                    if (childIdx == -1) break;          // heap already satisfied\n\n                    // perform ONE adjacent swap (the two positions are neighbours)\n                    ops.emplace_back(curX, curY, childX, childY);\n                    swap(curVal[pIdx], curVal[childIdx]);\n\n                    // continue sifting the moved ball downwards\n                    curX = childX;\n                    curY = childY;\n                }\n            }\n        }\n\n        if ((int)ops.size() < bestK) {\n            bestK = (int)ops.size();\n            bestOps = move(ops);\n        }\n    }\n\n    /* ----- try to delete useless swaps (multiple passes) ----- */\n    const int PRUNE_PASSES = 3;\n    for (int pass = 0; pass < PRUNE_PASSES; ++pass) {\n        bool progress = false;\n        for (int i = 0; i < (int)bestOps.size(); ++i) {\n            vector<int> curVal = initValue;\n            // apply all swaps except the i\u2011th\n            for (int j = 0; j < (int)bestOps.size(); ++j) if (j != i) {\n                const Swap& s = bestOps[j];\n                int a = idx[s.x1][s.y1];\n                int b = idx[s.x2][s.y2];\n                swap(curVal[a], curVal[b]);\n            }\n            if (isHeap(curVal)) {\n                bestOps.erase(bestOps.begin() + i);\n                --i;          // continue scanning\n                progress = true;\n            }\n        }\n        if (!progress) break;   // no more deletions possible\n    }\n\n    /* ----- output ----- */\n    cout << bestOps.size() << '\\n';\n    for (const Swap& s : bestOps)\n        cout << s.x1 << ' ' << s.y1 << ' ' << s.x2 << ' ' << s.y2 << '\\n';\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\n#include <ext/pb_ds/assoc_container.hpp>\nusing namespace std;\nusing namespace __gnu_pbds;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int dr[4] = {-1, 1, 0, 0};\n    const int dc[4] = {0, 0, -1, 1};\n\n    /* ---------- input ---------- */\n    int D_in, N;\n    if (!(cin >> D_in >> N)) return 0;\n    const int D = 9;                     // D is always 9 in the problem\n\n    vector<vector<bool>> obstacle(D, vector<bool>(D, false));\n    for (int k = 0; k < N; ++k) {\n        int ri, rj;\n        cin >> ri >> rj;\n        obstacle[ri][rj] = true;\n    }\n\n    const int R = 0;\n    const int C = (D - 1) / 2;           // entrance (0,4)\n\n    /* ---------- depth (BFS) ---------- */\n    vector<vector<int>> depth(D, vector<int>(D, -1));\n    queue<pair<int,int>> q;\n    depth[R][C] = 0;\n    q.emplace(R, C);\n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        for (int d = 0; d < 4; ++d) {\n            int nr = r + dr[d], nc = c + dc[d];\n            if (nr < 0 || nr >= D || nc < 0 || nc >= D) continue;\n            if (obstacle[nr][nc]) continue;\n            if (depth[nr][nc] != -1) continue;\n            depth[nr][nc] = depth[r][c] + 1;\n            q.emplace(nr, nc);\n        }\n    }\n\n    const int M = D * D - 1 - N;         // number of containers\n\n    /* ---------- ordered set for remaining numbers ---------- */\n    using ordered_set = tree<int, null_type, less<int>, rb_tree_tag,\n                             tree_order_statistics_node_update>;\n    ordered_set S;\n    for (int i = 0; i < M; ++i) S.insert(i);\n\n    /* ---------- data for storage ---------- */\n    vector<int> pos_x(M, -1), pos_y(M, -1);\n    vector<vector<int>> container_at(D, vector<int>(D, -1));\n    vector<vector<bool>> occupied(D, vector<bool>(D, false));\n\n    const int MAX_DEPTH = 20;            // enough for 9x9 grid\n\n    /* ---------- storage phase ---------- */\n    for (int step = 0; step < M; ++step) {\n        int t;                           // number written on the arriving container\n        cin >> t;\n\n        // rank of t among still unused numbers\n        int rank = (int)S.order_of_key(t);   // number of elements < t\n        int total = (int)S.size() + 1;       // size before erasing t\n        S.erase(t);                          // number t becomes used now\n\n        /* current empty squares */\n        vector<vector<bool>> empty(D, vector<bool>(D, false));\n        for (int i = 0; i < D; ++i)\n            for (int j = 0; j < D; ++j)\n                if (!obstacle[i][j] && !occupied[i][j])\n                    empty[i][j] = true;\n\n        /* articulation points \u2013 Tarjan */\n        vector<vector<int>> disc(D, vector<int>(D, 0));\n        vector<vector<int>> low(D, vector<int>(D, 0));\n        vector<vector<bool>> visited(D, vector<bool>(D, false));\n        vector<vector<bool>> isArt(D, vector<bool>(D, false));\n        int timer = 0;\n        function<void(int,int,int,int)> dfs = [&](int r, int c,\n                                                   int parent_r, int parent_c) {\n            visited[r][c] = true;\n            disc[r][c] = low[r][c] = ++timer;\n            int child = 0;\n            for (int d = 0; d < 4; ++d) {\n                int nr = r + dr[d], nc = c + dc[d];\n                if (nr < 0 || nr >= D || nc < 0 || nc >= D) continue;\n                if (!empty[nr][nc]) continue;\n                if (nr == parent_r && nc == parent_c) continue;\n                if (!visited[nr][nc]) {\n                    ++child;\n                    dfs(nr, nc, r, c);\n                    low[r][c] = min(low[r][c], low[nr][nc]);\n                    if (parent_r == -1 && child > 1) isArt[r][c] = true;\n                    if (parent_r != -1 && low[nr][nc] >= disc[r][c]) isArt[r][c] = true;\n                } else {\n                    low[r][c] = min(low[r][c], disc[nr][nc]);\n                }\n            }\n        };\n        dfs(R, C, -1, -1);\n\n        /* collect candidate cells (empty, not entrance, not articulation) */\n        vector<pair<int, pair<int,int>>> candidates; // (depth, (r,c))\n        for (int i = 0; i < D; ++i) {\n            for (int j = 0; j < D; ++j) {\n                if (i == R && j == C) continue;          // entrance\n                if (!empty[i][j]) continue;\n                if (isArt[i][j]) continue;\n                candidates.emplace_back(depth[i][j], make_pair(i, j));\n            }\n        }\n\n        // safety \u2013 should never be empty\n        if (candidates.empty()) {\n            for (int i = 0; i < D; ++i)\n                for (int j = 0; j < D; ++j)\n                    if (empty[i][j])\n                        candidates.emplace_back(depth[i][j], make_pair(i, j));\n        }\n\n        // ----- compute depth distribution of candidates -----\n        int Ccnt = (int)candidates.size();\n        vector<int> freq(MAX_DEPTH + 1, 0);\n        for (auto &cand : candidates) {\n            int d = cand.first;\n            if (d >= 0 && d <= MAX_DEPTH) freq[d]++;\n        }\n        // cumulative distribution\n        vector<int> pref(MAX_DEPTH + 1, 0);\n        int sum = 0;\n        for (int d = 0; d <= MAX_DEPTH; ++d) {\n            if (freq[d] > 0) {\n                sum += freq[d];\n                pref[d] = sum;\n            }\n        }\n\n        // ----- map rank to target depth using cumulative distribution -----\n        int target_depth = 0;\n        if (total == 1) {\n            // only one number left, pick shallowest\n            target_depth = candidates[0].first;\n            for (auto &cand : candidates)\n                target_depth = min(target_depth, cand.first);\n        } else {\n            double f = (double)rank / (total - 1);      // fraction in [0,1]\n            double target_cnt = f * Ccnt;                // target position\n            // find smallest depth with pref >= target_cnt\n            for (int d = 0; d <= MAX_DEPTH; ++d) {\n                if (pref[d] >= target_cnt) {\n                    target_depth = d;\n                    break;\n                }\n            }\n        }\n\n        // ----- choose candidate with depth closest to target -----\n        int best_r = -1, best_c = -1, best_depth = -1;\n        int best_diff = INT_MAX;\n        for (auto &cand : candidates) {\n            int d = cand.first;\n            int diff = abs(d - target_depth);\n            if (diff < best_diff || (diff == best_diff && d < best_depth)) {\n                best_diff = diff;\n                best_r = cand.second.first;\n                best_c = cand.second.second;\n                best_depth = d;\n            }\n        }\n\n        /* store the container */\n        occupied[best_r][best_c] = true;\n        container_at[best_r][best_c] = t;\n        pos_x[t] = best_r;\n        pos_y[t] = best_c;\n\n        cout << best_r << ' ' << best_c << '\\n';\n        cout.flush();\n    }\n\n    /* ---------- retrieval phase \u2013 greedy by smallest number ---------- */\n    for (int step = 0; step < M; ++step) {\n        /* reachable empty region (BFS) */\n        vector<vector<bool>> reachable(D, vector<bool>(D, false));\n        queue<pair<int,int>> qreach;\n        reachable[R][C] = true;\n        qreach.emplace(R, C);\n        while (!qreach.empty()) {\n            auto [r, c] = qreach.front(); qreach.pop();\n            for (int d = 0; d < 4; ++d) {\n                int nr = r + dr[d], nc = c + dc[d];\n                if (nr < 0 || nr >= D || nc < 0 || nc >= D) continue;\n                if (obstacle[nr][nc]) continue;\n                if (occupied[nr][nc]) continue;          // only empty squares\n                if (reachable[nr][nc]) continue;\n                reachable[nr][nc] = true;\n                qreach.emplace(nr, nc);\n            }\n        }\n\n        /* pick reachable container with smallest number */\n        int bestNum = INT_MAX, bestR = -1, bestC = -1;\n        for (int i = 0; i < D; ++i) {\n            for (int j = 0; j < D; ++j) {\n                if (!occupied[i][j]) continue;\n                bool adjacent = false;\n                for (int d = 0; d < 4; ++d) {\n                    int ni = i + dr[d], nj = j + dc[d];\n                    if (ni < 0 || ni >= D || nj < 0 || nj >= D) continue;\n                    if (reachable[ni][nj]) { adjacent = true; break; }\n                }\n                if (!adjacent) continue;\n                int num = container_at[i][j];\n                if (num < bestNum) {\n                    bestNum = num;\n                    bestR = i; bestC = j;\n                }\n            }\n        }\n\n        /* output and remove */\n        cout << bestR << ' ' << bestC << '\\n';\n        cout.flush();\n        occupied[bestR][bestC] = false;\n    }\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n, m;\nconst int MAXC = 105;                     // colours 0 \u2026 m (m \u2264 100)\nint a[55][55];\nint total[MAXC];\nint adjCnt[MAXC][MAXC];                   // directed edges\nbool need[MAXC][MAXC];\n\nint dx[4] = {-1, 1, 0, 0};\nint dy[4] = {0, 0, -1, 1};\n\nint vis[55][55];\nint bfsStamp = 0;\n\nqueue<pair<int,int>> q;                   // squares that may become deletable\n\n// ------------------------------------------------------------------\nbool canDelete(int x, int y);\nvoid doDelete(int x, int y);\n\n// ------------------------------------------------------------------\nbool canDelete(int x, int y) {\n    int c = a[x][y];\n    if (c == 0) return false;\n    if (total[c] <= 1) return false;                 // colour must survive\n\n    // 1) the square must already touch colour 0 (or the outside)\n    bool adjZero = false;\n    for (int dir = 0; dir < 4; ++dir) {\n        int nx = x + dx[dir], ny = y + dy[dir];\n        if (nx < 0 || nx >= n || ny < 0 || ny >= n) { adjZero = true; break; }\n        if (a[nx][ny] == 0) { adjZero = true; break; }\n    }\n    if (!adjZero) return false;\n\n    // colours of the four neighbours (0 = outside)\n    int nbColour[4];\n    int cnt[MAXC] = {0};\n\n    for (int dir = 0; dir < 4; ++dir) {\n        int nx = x + dx[dir], ny = y + dy[dir];\n        int d;\n        if (nx < 0 || nx >= n || ny < 0 || ny >= n) d = 0;\n        else d = a[nx][ny];\n        nbColour[dir] = d;\n        ++cnt[d];\n    }\n\n    // 2) must not create a forbidden adjacency 0\u2011d (including d == c)\n    for (int dir = 0; dir < 4; ++dir) {\n        int d = nbColour[dir];\n        if (d != 0 && !need[0][d]) return false;     // would create illegal 0\u2011d\n    }\n\n    // 3) each required adjacency must stay alive (at least one undirected edge left)\n    for (int d = 0; d <= m; ++d) {\n        if (!need[c][d]) continue;\n        if (cnt[d] == 0) continue;                  // we are not touching this colour\n        if (adjCnt[c][d] - 2 * cnt[d] < 1) return false;\n    }\n\n    // 4) after removal the colour must still be connected\n    int sx = -1, sy = -1;\n    for (int dir = 0; dir < 4; ++dir) {\n        int nx = x + dx[dir], ny = y + dy[dir];\n        if (0 <= nx && nx < n && 0 <= ny && ny < n && a[nx][ny] == c) {\n            sx = nx; sy = ny;\n            break;\n        }\n    }\n    if (sx == -1) return false;                     // should not happen (total[c] \u2265 2)\n\n    ++bfsStamp;\n    queue<pair<int,int>> qq;\n    qq.emplace(sx, sy);\n    vis[sx][sy] = bfsStamp;\n    int cntReached = 0;\n    while (!qq.empty()) {\n        auto [cx, cy] = qq.front(); qq.pop();\n        ++cntReached;\n        for (int dir = 0; dir < 4; ++dir) {\n            int nx = cx + dx[dir], ny = cy + dy[dir];\n            if (nx < 0 || nx >= n || ny < 0 || ny >= n) continue;\n            if (a[nx][ny] != c) continue;\n            if (nx == x && ny == y) continue;       // the cell we plan to delete\n            if (vis[nx][ny] == bfsStamp) continue;\n            vis[nx][ny] = bfsStamp;\n            qq.emplace(nx, ny);\n        }\n    }\n    if (cntReached != total[c] - 1) return false;   // would disconnect the colour\n\n    return true;\n}\n\n// ------------------------------------------------------------------\nvoid doDelete(int x, int y) {\n    int c = a[x][y];\n    a[x][y] = 0;\n    --total[c];\n\n    for (int dir = 0; dir < 4; ++dir) {\n        int nx = x + dx[dir], ny = y + dy[dir];\n        int d;\n        if (nx < 0 || nx >= n || ny < 0 || ny >= n) {\n            d = 0;                     // outside world\n        } else {\n            d = a[nx][ny];\n        }\n\n        // remove the old adjacency c\u2011d (two directed edges)\n        if (d != c) {\n            adjCnt[c][d] -= 2;\n            adjCnt[d][c] -= 2;\n        }\n\n        // create a new adjacency 0\u2011d (if d is a coloured cell)\n        if (d != 0) {\n            adjCnt[0][d] += 2;\n            adjCnt[d][0] += 2;\n        }\n    }\n\n    // neighbours may become new candidates because they now touch a 0 cell\n    for (int dir = 0; dir < 4; ++dir) {\n        int nx = x + dx[dir], ny = y + dy[dir];\n        if (0 <= nx && nx < n && 0 <= ny && ny < n && a[nx][ny] > 0) {\n            q.emplace(nx, ny);\n        }\n    }\n}\n\n// ------------------------------------------------------------------\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> n >> m;\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j)\n            cin >> a[i][j];\n\n    // ----- count squares and all adjacency edges of the original map -----\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            int c = a[i][j];\n            ++total[c];\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + dx[dir], nj = j + dy[dir];\n                if (ni < 0 || ni >= n || nj < 0 || nj >= n) {\n                    ++adjCnt[c][0];\n                    ++adjCnt[0][c];\n                } else {\n                    int d = a[ni][nj];\n                    if (d != c) {\n                        ++adjCnt[c][d];\n                        ++adjCnt[d][c];\n                    }\n                }\n            }\n        }\n    }\n\n    // which adjacencies existed in the original map?\n    for (int c = 0; c <= m; ++c)\n        for (int d = 0; d <= m; ++d)\n            need[c][d] = (adjCnt[c][d] > 0);\n\n    // ----- initialise candidate queue: squares already touching colour 0 -----\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) if (a[i][j] > 0) {\n            bool adjZero = false;\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + dx[dir], nj = j + dy[dir];\n                if (ni < 0 || ni >= n || nj < 0 || nj >= n) { adjZero = true; break; }\n                if (a[ni][nj] == 0) { adjZero = true; break; }\n            }\n            if (adjZero) q.emplace(i, j);\n        }\n    }\n\n    // ----- greedy deletion -----\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        if (a[x][y] == 0) continue;                 // already deleted\n        if (canDelete(x, y))\n            doDelete(x, y);\n    }\n\n    // ----- output -----\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            if (j) cout << ' ';\n            cout << a[i][j];\n        }\n        cout << '\\n';\n    }\n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, D, Q;\nint used = 0;\nvector<int> win, tieCnt, totalCnt;\nvector<int> a;\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint compareItems(int i, int j) {\n    cout << \"1 1 \" << i << ' ' << j << \"\\n\";\n    cout.flush();\n    ++used;\n    ++totalCnt[i];\n    ++totalCnt[j];\n    string res;\n    cin >> res;\n    if (res == \">\") {\n        ++win[i];\n    } else if (res == \"<\") {\n        ++win[j];\n    } else {\n        ++tieCnt[i];\n        ++tieCnt[j];\n    }\n    if (res == \">\") return 1;\n    if (res == \"<\") return -1;\n    return 0;\n}\n\nvoid mergeArr(int l, int m, int r) {\n    vector<int> tmp;\n    int i = l, j = m;\n    while (i < m && j < r) {\n        if (used >= Q) {\n            while (i < m) { tmp.push_back(a[i]); ++i; }\n            while (j < r) { tmp.push_back(a[j]); ++j; }\n            break;\n        }\n        int cr = compareItems(a[i], a[j]);\n        if (cr > 0) {\n            tmp.push_back(a[i]); ++i;\n        } else if (cr < 0) {\n            tmp.push_back(a[j]); ++j;\n        } else {\n            tmp.push_back(a[i]); ++i;\n            tmp.push_back(a[j]); ++j;\n        }\n    }\n    while (i < m) { tmp.push_back(a[i]); ++i; }\n    while (j < r) { tmp.push_back(a[j]); ++j; }\n    for (int k = 0; k < (int)tmp.size(); ++k) a[l + k] = tmp[k];\n}\n\nvoid mergeSort(int l, int r) {\n    if (r - l <= 1) return;\n    int m = (l + r) / 2;\n    if (used < Q) mergeSort(l, m);\n    if (used < Q) mergeSort(m, r);\n    if (used < Q) mergeArr(l, m, r);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> D >> Q;\n    win.assign(N, 0);\n    tieCnt.assign(N, 0);\n    totalCnt.assign(N, 0);\n    a.resize(N);\n    iota(a.begin(), a.end(), 0);\n\n    // Phase 1: Sort using merge sort\n    mergeSort(0, N);\n\n    // Phase 2: Refine sorted order using bubble-sort passes\n    int maxPasses = 5;\n    for (int pass = 0; pass < maxPasses && used < Q; ++pass) {\n        bool anySwap = false;\n        for (int pos = 0; pos + 1 < N && used < Q; ++pos) {\n            int cr = compareItems(a[pos], a[pos + 1]);\n            if (cr < 0) {\n                swap(a[pos], a[pos + 1]);\n                anySwap = true;\n            }\n        }\n        if (!anySwap) break;\n    }\n\n    // Phase 3: Use remaining queries for random comparisons\n    while (used < Q) {\n        int i = rng() % N;\n        int j = rng() % N;\n        if (i != j) compareItems(i, j);\n    }\n\n    // Compute score: win rate weighted by sqrt of comparisons\n    vector<double> score(N);\n    double maxScore = 0;\n    for (int i = 0; i < N; ++i) {\n        if (totalCnt[i] > 0) {\n            score[i] = (win[i] + 0.5 * tieCnt[i]) / sqrt(totalCnt[i]);\n        } else {\n            score[i] = 0;\n        }\n        maxScore = max(maxScore, score[i]);\n    }\n    \n    // Normalize scores\n    if (maxScore > 0) {\n        for (int i = 0; i < N; ++i) {\n            score[i] = score[i] / maxScore * 1000;\n        }\n    }\n\n    // Sort by score - use stable_sort to maintain merge sort order for ties\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    stable_sort(idx.begin(), idx.end(),\n                [&](int i, int j) { return score[i] > score[j]; });\n\n    // Simple LPT assignment\n    vector<double> groupSum(D, 0.0);\n    vector<int> group(N, -1);\n    for (int pos = 0; pos < N; ++pos) {\n        int it = idx[pos];\n        int best = 0;\n        for (int g = 1; g < D; ++g) {\n            if (groupSum[g] < groupSum[best]) best = g;\n        }\n        group[it] = best;\n        groupSum[best] += score[it];\n    }\n\n    // Output\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << group[i];\n    }\n    cout << \"\\n\";\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    const int per = n / m;\n    vector<vector<int>> st(m);\n    vector<int> where(n + 1, -1);\n\n    for (int i = 0; i < m; ++i) {\n        st[i].reserve(per);\n        for (int j = 0; j < per; ++j) {\n            int v; cin >> v;\n            st[i].push_back(v);\n            where[v] = i;\n        }\n    }\n\n    vector<pair<int,int>> ops;\n\n    for (int v = 1; v <= n; ++v) {\n        int src = where[v];\n\n        // While v is not at the top, move boxes above it\n        while (!st[src].empty() && st[src].back() != v) {\n            int curTop = st[src].back();\n            int dest = -1;\n            \n            // Priority 1: Find a stack with top > curTop (no new inversion)\n            // Choose the one with maximum top to be most useful later\n            int bestTop = -1;\n            for (int i = 0; i < m; ++i) {\n                if (i == src) continue;\n                if (!st[i].empty() && st[i].back() > curTop && st[i].back() > bestTop) {\n                    bestTop = st[i].back();\n                    dest = i;\n                }\n            }\n            \n            // Priority 2: Use an empty stack if available\n            if (dest == -1) {\n                for (int i = 0; i < m; ++i) {\n                    if (i == src) continue;\n                    if (st[i].empty()) {\n                        dest = i;\n                        break;\n                    }\n                }\n            }\n            \n            // Priority 3: Any other stack - prefer larger top to minimize future moves\n            if (dest == -1) {\n                int maxTop = -1;\n                for (int i = 0; i < m; ++i) {\n                    if (i == src) continue;\n                    int top = st[i].empty() ? -1 : st[i].back();\n                    if (top > maxTop) {\n                        maxTop = top;\n                        dest = i;\n                    }\n                }\n            }\n\n            // Operation 1: move curTop to dest\n            ops.emplace_back(curTop, dest + 1);\n            st[src].pop_back();\n            st[dest].push_back(curTop);\n            where[curTop] = dest;\n        }\n\n        // Operation 2: carry out v (free, no energy)\n        ops.emplace_back(v, 0);\n        st[src].pop_back();\n        where[v] = -1;\n    }\n\n    // Output: one operation per line\n    for (auto [box, dst] : ops) {\n        cout << box << ' ' << dst << '\\n';\n    }\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    if (!(cin >> N)) return 0;\n\n    vector<string> h(N - 1);\n    for (int i = 0; i < N - 1; ++i) cin >> h[i];\n    vector<string> v(N);\n    for (int i = 0; i < N; ++i) cin >> v[i];\n    vector<vector<int>> d(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) cin >> d[i][j];\n\n    const int V = N * N;\n    auto id = [&](int i, int j) { return i * N + j; };\n\n    /* ---------- adjacency (no walls) ---------- */\n    vector<vector<int>> adj(V);\n    const int di[4] = {0, 1, 0, -1};\n    const int dj[4] = {1, 0, -1, 0};\n    const char dc[4] = {'R', 'D', 'L', 'U'};\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int u = id(i, j);\n            if (i + 1 < N && h[i][j] == '0') {\n                int vtx = id(i + 1, j);\n                adj[u].push_back(vtx);\n                adj[vtx].push_back(u);\n            }\n            if (j + 1 < N && v[i][j] == '0') {\n                int vtx = id(i, j + 1);\n                adj[u].push_back(vtx);\n                adj[vtx].push_back(u);\n            }\n        }\n    }\n\n    const int start = 0;                 // (0,0)\n\n    /* ---------- BFS from start (shortest distances & parents) ---------- */\n    const int INF = 1e9;\n    vector<int> dist(V, INF), parent(V, -1);\n    queue<int> q;\n    dist[start] = 0;\n    q.push(start);\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int nb : adj[u]) {\n            if (dist[nb] == INF) {\n                dist[nb] = dist[u] + 1;\n                parent[nb] = u;\n                q.push(nb);\n            }\n        }\n    }\n\n    /* ---------- try to find a Hamiltonian path (randomised DFS) ---------- */\n    const int MAX_ATTEMPTS = 3000;\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    string bestBase;                // move string of the best walk found\n    int bestLen = INF;              // its length\n\n    for (int attempt = 0; attempt < MAX_ATTEMPTS; ++attempt) {\n        vector<char> visited(V, 0);\n        vector<int> path;\n        path.reserve(V);\n        int cur = start;\n        visited[cur] = 1;\n        path.push_back(cur);\n        bool dead = false;\n\n        while ((int)path.size() < V) {\n            // choose an unvisited neighbour with smallest own unvisited degree\n            int bestDegree = 5;\n            vector<int> candidates;\n\n            for (int nb : adj[cur]) if (!visited[nb]) {\n                int deg = 0;\n                for (int nn : adj[nb]) if (!visited[nn]) ++deg;\n                if (deg < bestDegree) {\n                    bestDegree = deg;\n                    candidates.clear();\n                    candidates.push_back(nb);\n                } else if (deg == bestDegree) {\n                    candidates.push_back(nb);\n                }\n            }\n\n            if (candidates.empty()) { dead = true; break; }\n\n            // random among the best\n            int nxt = candidates[rng() % candidates.size()];\n            visited[nxt] = 1;\n            path.push_back(nxt);\n            cur = nxt;\n        }\n\n        if (dead) continue;               // could not visit all cells\n\n        // we have a Hamiltonian path\n        int last = path.back();\n        int back = dist[last];             // shortest way back to start\n        int totalLen = (V - 1) + back;      // moves of path + closing moves\n\n        if (totalLen < bestLen) {\n            bestLen = totalLen;\n            bestBase.clear();\n\n            // moves of the Hamiltonian part\n            for (size_t i = 0; i + 1 < path.size(); ++i) {\n                int a = path[i], b = path[i + 1];\n                int ai = a / N, aj = a % N;\n                int bi = b / N, bj = b % N;\n                if (bi == ai + 1) bestBase.push_back('D');\n                else if (bi == ai - 1) bestBase.push_back('U');\n                else if (bj == aj + 1) bestBase.push_back('R');\n                else bestBase.push_back('L');\n            }\n\n            // closing shortest path (back to start) \u2013 direction from curRet to parent\n            vector<char> ret;\n            int curRet = last;\n            while (curRet != start) {\n                int p = parent[curRet];\n                int pi = p / N, pj = p % N;\n                int ci = curRet / N, cj = curRet % N;\n                if (ci == pi + 1) ret.push_back('U');      // curRet is below parent -> up\n                else if (ci == pi - 1) ret.push_back('D'); // curRet is above parent -> down\n                else if (cj == pj + 1) ret.push_back('L'); // curRet is right of parent -> left\n                else ret.push_back('R');                    // curRet is left of parent -> right\n                curRet = p;\n            }\n            bestBase.append(ret.begin(), ret.end());\n        }\n\n        // if we already reached the theoretical minimum (V + 1) we can stop early\n        if (bestLen <= V + 1) break;\n    }\n\n    /* ---------- fallback: simple DFS tour ---------- */\n    if (bestLen == INF) {\n        vector<vector<char>> seen(N, vector<char>(N, 0));\n        string dfsWalk;\n        function<void(int,int)> dfs = [&](int i, int j) {\n            seen[i][j] = 1;\n            for (int dir = 0; dir < 4; ++dir) {\n                int ni = i + di[dir], nj = j + dj[dir];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                if (seen[ni][nj]) continue;\n                bool free = false;\n                if (dir == 0 && j + 1 < N && v[i][j] == '0') free = true;\n                if (dir == 1 && i + 1 < N && h[i][j] == '0') free = true;\n                if (dir == 2 && j - 1 >= 0 && v[i][j-1] == '0') free = true;\n                if (dir == 3 && i - 1 >= 0 && h[i-1][j] == '0') free = true;\n                if (!free) continue;\n                dfsWalk.push_back(dc[dir]);                // forward\n                dfs(ni, nj);\n                dfsWalk.push_back(dc[(dir + 2) % 4]);      // back\n            }\n        };\n        dfs(0, 0);\n        bestBase = dfsWalk;\n        bestLen = (int)bestBase.size();          // = 2*(V-1)\n    }\n\n    const int Lmax = 100000;\n    int repeat = Lmax / bestLen;                  // maximal full repetitions\n\n    string answer;\n    answer.reserve(repeat * bestLen);\n    for (int i = 0; i < repeat; ++i) answer += bestBase;\n\n    cout << answer << '\\n';\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 15;                // keyboard size (always 15)\nconst int TOT = N * N;           // 225 cells\nconst int INF = 1e9;            // a large number used as \"infinite\" cost\n\n// ------------------------------------------------------------\n// longest k (0 \u2264 k \u2264 5) such that suffix of a (len k) = prefix of b (len k)\nint overlap(const string &a, const string &b) {\n    int maxk = min({(int)a.size(), (int)b.size(), 5});\n    for (int k = maxk; k >= 0; --k) {\n        bool ok = true;\n        for (int i = 0; i < k; ++i) {\n            if (a[a.size() - k + i] != b[i]) { ok = false; break; }\n        }\n        if (ok) return k;\n    }\n    return 0;\n}\n\n// ------------------------------------------------------------\n// greedy construction: bidirectional (prepend / append) with random tie\u2011breaking\nstring buildBi(const vector<string> &words, int startIdx, mt19937 &rng) {\n    int m = (int)words.size();\n    vector<bool> used(m, false);\n    string cur = words[startIdx];\n    used[startIdx] = true;\n\n    while (true) {\n        int bestAdd = INF;\n        vector<int> bestIds;\n        vector<int> bestOri;               // 0 = append, 1 = prepend\n\n        for (int j = 0; j < m; ++j) if (!used[j]) {\n            // try append\n            int ov_app = overlap(cur, words[j]);\n            int add_app = (int)words[j].size() - ov_app;\n            if (add_app < bestAdd) {\n                bestAdd = add_app;\n                bestIds.clear(); bestOri.clear();\n                bestIds.push_back(j); bestOri.push_back(0);\n            } else if (add_app == bestAdd) {\n                bestIds.push_back(j); bestOri.push_back(0);\n            }\n\n            // try prepend\n            int ov_pre = overlap(words[j], cur);\n            int add_pre = (int)words[j].size() - ov_pre;\n            if (add_pre < bestAdd) {\n                bestAdd = add_pre;\n                bestIds.clear(); bestOri.clear();\n                bestIds.push_back(j); bestOri.push_back(1);\n            } else if (add_pre == bestAdd) {\n                bestIds.push_back(j); bestOri.push_back(1);\n            }\n        }\n\n        if (bestIds.empty()) break;               // all words used\n\n        int choice = uniform_int_distribution<int>(0, (int)bestIds.size() - 1)(rng);\n        int id = bestIds[choice];\n        int ori = bestOri[choice];\n\n        if (ori == 0) {                           // append\n            int ov = overlap(cur, words[id]);\n            cur += words[id].substr(ov);\n        } else {                                   // prepend\n            int ov = overlap(words[id], cur);\n            cur = words[id].substr(0, (int)words[id].size() - ov) + cur;\n        }\n        used[id] = true;\n    }\n    return cur;\n}\n\n// ------------------------------------------------------------\n// greedy construction: append only (always attach to the right)\nstring buildAppend(const vector<string> &words, int startIdx, mt19937 &rng) {\n    int m = (int)words.size();\n    vector<bool> used(m, false);\n    string cur = words[startIdx];\n    used[startIdx] = true;\n\n    while (true) {\n        int bestAdd = INF;\n        vector<int> bestIds;\n\n        for (int j = 0; j < m; ++j) if (!used[j]) {\n            int ov = overlap(cur, words[j]);\n            int add = (int)words[j].size() - ov;\n            if (add < bestAdd) {\n                bestAdd = add;\n                bestIds.clear();\n                bestIds.push_back(j);\n            } else if (add == bestAdd) {\n                bestIds.push_back(j);\n            }\n        }\n\n        if (bestIds.empty()) break;\n\n        int choice = uniform_int_distribution<int>(0, (int)bestIds.size() - 1)(rng);\n        int id = bestIds[choice];\n        int ov = overlap(cur, words[id]);\n        cur += words[id].substr(ov);\n        used[id] = true;\n    }\n    return cur;\n}\n\n// ------------------------------------------------------------\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int tmpN, M;\n    if (!(cin >> tmpN >> M)) return 0;   // N is always 15\n    int si, sj;\n    cin >> si >> sj;\n\n    vector<string> board(N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n\n    // positions of each letter\n    vector<vector<int>> cells(26);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            int id = i * N + j;\n            cells[board[i][j] - 'A'].push_back(id);\n        }\n\n    vector<string> words(M);\n    for (int i = 0; i < M; ++i) cin >> words[i];\n\n    // pre\u2011compute Manhattan distances between all cells\n    static int dist[TOT][TOT];\n    for (int i = 0; i < TOT; ++i) {\n        int x1 = i / N, y1 = i % N;\n        for (int j = 0; j < TOT; ++j) {\n            int x2 = j / N, y2 = j % N;\n            dist[i][j] = abs(x1 - x2) + abs(y1 - y2);\n        }\n    }\n\n    mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());\n\n    int bestCost = INF;\n    vector<pair<int,int>> bestPath;      // (row , col) for each operation\n\n    // -----------------------------------------------------------------\n    // helper: DP for a given superstring, returns (cost, path)\n    auto solve = [&](const string &S) -> pair<int, vector<pair<int,int>>> {\n        int L = (int)S.size();\n        if (L > bestCost) return {INF, {}};   // pruning\n\n        vector<int> dpPrev(TOT, INF), dpCurr(TOT, INF);\n        vector<vector<short>> pre(L + 1, vector<short>(TOT, -1));\n\n        int startCell = si * N + sj;\n        dpPrev[startCell] = 0;                 // cost before typing anything\n\n        for (int pos = 0; pos < L; ++pos) {\n            char c = S[pos];\n            const vector<int> &allowed = cells[c - 'A'];\n            fill(dpCurr.begin(), dpCurr.end(), INF);\n            for (int curIdx : allowed) {\n                int best = INF;\n                short bestPrev = -1;\n                for (int prevIdx = 0; prevIdx < TOT; ++prevIdx) {\n                    int pc = dpPrev[prevIdx];\n                    if (pc == INF) continue;\n                    int cand = pc + dist[prevIdx][curIdx] + 1;\n                    if (cand < best) {\n                        best = cand;\n                        bestPrev = (short)prevIdx;\n                    }\n                }\n                dpCurr[curIdx] = best;\n                pre[pos + 1][curIdx] = bestPrev;\n            }\n            dpPrev.swap(dpCurr);\n        }\n\n        int finalIdx = -1, finalCost = INF;\n        for (int i = 0; i < TOT; ++i) {\n            if (dpPrev[i] < finalCost) {\n                finalCost = dpPrev[i];\n                finalIdx = i;\n            }\n        }\n\n        vector<pair<int,int>> path(L);\n        int cur = finalIdx;\n        for (int p = L; p >= 1; --p) {\n            path[p - 1] = {cur / N, cur % N};\n            cur = pre[p][cur];\n        }\n        return {finalCost, path};\n    };\n    // -----------------------------------------------------------------\n\n    // ---- systematic: try every word as the start ----\n    for (int start = 0; start < M; ++start) {\n        // bidirectional greedy\n        string S1 = buildBi(words, start, rng);\n        auto [cost1, path1] = solve(S1);\n        if (cost1 < bestCost) {\n            bestCost = cost1;\n            bestPath = move(path1);\n        }\n\n        // append\u2011only greedy\n        string S2 = buildAppend(words, start, rng);\n        if (S2 != S1) {\n            auto [cost2, path2] = solve(S2);\n            if (cost2 < bestCost) {\n                bestCost = cost2;\n                bestPath = move(path2);\n            }\n        }\n    }\n\n    // ---- extra random trials for diversity (more than before) ----\n    const int EXTRA_TRIALS = 100;               // increased from 50\n    for (int trial = 0; trial < EXTRA_TRIALS; ++trial) {\n        int startWord = uniform_int_distribution<int>(0, M - 1)(rng);\n\n        // bidirectional\n        string S1 = buildBi(words, startWord, rng);\n        auto [cost1, path1] = solve(S1);\n        if (cost1 < bestCost) {\n            bestCost = cost1;\n            bestPath = move(path1);\n        }\n\n        // append\u2011only\n        string S2 = buildAppend(words, startWord, rng);\n        if (S2 != S1) {\n            auto [cost2, path2] = solve(S2);\n            if (cost2 < bestCost) {\n                bestCost = cost2;\n                bestPath = move(path2);\n            }\n        }\n    }\n\n    // --------------------------------------------------------\n    // output the sequence of cells\n    for (auto [i, j] : bestPath) {\n        cout << i << ' ' << j << '\\n';\n    }\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\ndouble eps;\nvector<vector<int>> val;          // -1 = unknown, 0 = known zero, >0 = known positive\nvector<vector<char>> drilled;     // true if we have queried this cell exactly\nvector<int> rowPos, colPos;\n\n/* ---------- communication with the judge ---------- */\nint query_divine(const vector<pair<int,int>>& cells) {\n    cout << 'q' << ' ' << (int)cells.size();\n    for (auto [i,j] : cells) cout << ' ' << i << ' ' << j;\n    cout << '\\n' << std::flush;\n    int resp; cin >> resp;\n    return resp;\n}\nint query_drill(int i, int j) {\n    cout << 'q' << ' ' << 1 << ' ' << i << ' ' << j << '\\n' << std::flush;\n    int v; cin >> v;\n    return v;\n}\n\n/* ---------- recursive subdivision ---------- */\nvoid dfs(int r1, int r2, int c1, int c2) {\n    if (r1 > r2 || c1 > c2) return;\n    int h = r2 - r1 + 1, w = c2 - c1 + 1;\n    int area = h * w;\n\n    // base case: at most 2\u00d72 -> just drill\n    if (area <= 4) {\n        for (int i = r1; i <= r2; ++i)\n            for (int j = c1; j <= c2; ++j) {\n                if (!drilled[i][j]) {\n                    val[i][j] = query_drill(i, j);\n                    drilled[i][j] = 1;\n                }\n            }\n        return;\n    }\n\n    // query the whole rectangle\n    vector<pair<int,int>> cells;\n    cells.reserve(area);\n    for (int i = r1; i <= r2; ++i)\n        for (int j = c1; j <= c2; ++j)\n            cells.emplace_back(i, j);\n    int sum = query_divine(cells);\n\n    if (sum == 0) {                 // completely empty\n        for (int i = r1; i <= r2; ++i)\n            for (int j = c1; j <= c2; ++j)\n                val[i][j] = 0;\n        return;\n    }\n\n    // otherwise split into four quadrants\n    int rm = (r1 + r2) / 2;\n    int cm = (c1 + c2) / 2;\n    dfs(r1, rm, c1, cm);\n    dfs(r1, rm, cm+1, c2);\n    dfs(rm+1, r2, c1, cm);\n    dfs(rm+1, r2, cm+1, c2);\n}\n\n/* ---------- main ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M >> eps)) return 0;\n\n    // read and ignore the shapes\n    for (int k = 0; k < M; ++k) {\n        int d; cin >> d;\n        for (int t = 0; t < d; ++t) { int a,b; cin >> a >> b; }\n    }\n\n    rowPos.assign(N, 0);\n    colPos.assign(N, 0);\n    val.assign(N, vector<int>(N, -1));\n    drilled.assign(N, vector<char>(N, 0));\n\n    // ----- find non\u2011empty rows (single query) -----\n    for (int i = 0; i < N; ++i) {\n        vector<pair<int,int>> cells;\n        cells.reserve(N);\n        for (int j = 0; j < N; ++j) cells.emplace_back(i, j);\n        if (query_divine(cells) > 0) rowPos[i] = 1;\n    }\n\n    // ----- find non\u2011empty columns (single query) -----\n    for (int j = 0; j < N; ++j) {\n        vector<pair<int,int>> cells;\n        cells.reserve(N);\n        for (int i = 0; i < N; ++i) cells.emplace_back(i, j);\n        if (query_divine(cells) > 0) colPos[j] = 1;\n    }\n\n    // locate the bounding rectangle of possible oil cells\n    int r1 = N, r2 = -1, c1 = N, c2 = -1;\n    for (int i = 0; i < N; ++i) if (rowPos[i]) {\n        r1 = min(r1, i);\n        r2 = max(r2, i);\n    }\n    for (int j = 0; j < N; ++j) if (colPos[j]) {\n        c1 = min(c1, j);\n        c2 = max(c2, j);\n    }\n\n    // if there is at least one non\u2011empty row/column, search inside the rectangle\n    if (r1 <= r2 && c1 <= c2) {\n        dfs(r1, r2, c1, c2);\n    }\n\n    // cells outside the rectangle are known to be zero (they cannot contain oil)\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (val[i][j] == -1) val[i][j] = 0;\n\n    // ----- first guess -----\n    vector<pair<int,int>> ans;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (val[i][j] > 0) ans.emplace_back(i, j);\n\n    cout << 'a' << ' ' << (int)ans.size();\n    for (auto [i,j] : ans) cout << ' ' << i << ' ' << j;\n    cout << '\\n' << std::flush;\n    int ok; cin >> ok;\n    if (ok == 1) return 0;          // success\n\n    // ----- fallback: drill all cells that have not been drilled yet -----\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (!drilled[i][j]) {\n                val[i][j] = query_drill(i, j);\n                drilled[i][j] = 1;\n            }\n\n    // ----- second guess (must be correct) -----\n    ans.clear();\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (val[i][j] > 0) ans.emplace_back(i, j);\n\n    cout << 'a' << ' ' << (int)ans.size();\n    for (auto [i,j] : ans) cout << ' ' << i << ' ' << j;\n    cout << '\\n' << std::flush;\n    // the judge will always answer 1 here\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing Segment = tuple<int, long long, int>; // cnt, delta, idx\n\n/* ------------------------------------------------------------\n   MaxRects packing: best\u2011short\u2011side\u2011fit.\n   Returns true if all placed, false otherwise.\n   ------------------------------------------------------------ */\nbool packRectangles(const vector<long long>& areas,\n                    vector<array<int,4>>& placed,\n                    int W = 1000) {\n    int N = (int)areas.size();\n    placed.assign(N, {0,0,0,0});\n\n    // free rectangles \u2013 always inside the grid\n    struct FR { int x, y, w, h; };\n    vector<FR> freeRects;\n    freeRects.push_back({0, 0, W, W});\n\n    // indices sorted by descending area\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(),\n         [&](int i, int j){ return areas[i] > areas[j]; });\n\n    for (int id : order) {\n        long long need = areas[id];\n        if (need == 0) { // give a tiny 1\u00d71 rectangle\n            placed[id] = {0, 0, 1, 1};\n            continue;\n        }\n\n        // generate candidate dimensions (w,h) with w*h >= need, w,h>0, w<=W, h<=W\n        vector<pair<int,int>> cand;\n        for (int w = 1; w <= W; ++w) {\n            int h = (int)((need + w - 1) / w);   // ceil(need / w)\n            if (h == 0) continue;                // skip zero height\n            if (h > W) continue;\n            cand.emplace_back(w, h);\n        }\n        sort(cand.begin(), cand.end());\n        cand.erase(unique(cand.begin(), cand.end()), cand.end());\n\n        // best placement among all free rectangles\n        int bestScore = -1;\n        int bestFree = -1, bestW = -1, bestH = -1;\n        for (int fi = 0; fi < (int)freeRects.size(); ++fi) {\n            const FR &fr = freeRects[fi];\n            for (auto [cw, ch] : cand) {\n                if (cw > fr.w || ch > fr.h) continue;\n                int score = min(fr.w - cw, fr.h - ch); // short side fit\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestFree = fi;\n                    bestW = cw;\n                    bestH = ch;\n                }\n            }\n        }\n\n        // fallback: if not placed, enlarge to the free rectangle's size\n        if (bestFree == -1) {\n            for (int fi = 0; fi < (int)freeRects.size(); ++fi) {\n                FR &fr = freeRects[fi];\n                // try using the whole free rectangle width\n                int cw = fr.w;\n                int ch = (int)((need + cw - 1) / cw);\n                if (ch <= fr.h && ch > 0) {\n                    bestFree = fi;\n                    bestW = cw;\n                    bestH = ch;\n                    break;\n                }\n                // try using the whole free rectangle height\n                ch = fr.h;\n                cw = (int)((need + ch - 1) / ch);\n                if (cw <= fr.w && cw > 0) {\n                    bestFree = fi;\n                    bestW = cw;\n                    bestH = ch;\n                    break;\n                }\n            }\n        }\n\n        // still not placed -> failure\n        if (bestFree == -1) return false;\n\n        // place rectangle\n        FR fr = freeRects[bestFree];\n        placed[id] = {fr.x, fr.y, bestW, bestH};\n\n        // remove used free rectangle\n        freeRects.erase(freeRects.begin() + bestFree);\n\n        // create new free rectangles (right and bottom parts)\n        if (fr.w > bestW) {\n            FR right = {fr.x + bestW, fr.y, fr.w - bestW, bestH};\n            if (right.w > 0 && right.h > 0) freeRects.push_back(right);\n        }\n        if (fr.h > bestH) {\n            FR bottom = {fr.x, fr.y + bestH, fr.w, fr.h - bestH};\n            if (bottom.w > 0 && bottom.h > 0) freeRects.push_back(bottom);\n        }\n\n        // prune free rectangles that are completely inside another\n        bool changed = true;\n        while (changed) {\n            changed = false;\n            int F = (int)freeRects.size();\n            vector<char> toRemove(F, 0);\n            for (int i = 0; i < F && !changed; ++i) {\n                for (int j = 0; j < F; ++j) if (i != j) {\n                    const FR &a = freeRects[i];\n                    const FR &b = freeRects[j];\n                    if (a.x >= b.x && a.y >= b.y &&\n                        a.x + a.w <= b.x + b.w &&\n                        a.y + a.h <= b.y + b.h) {\n                        toRemove[i] = 1;\n                        changed = true;\n                        break;\n                    }\n                }\n            }\n            if (changed) {\n                vector<FR> nxt;\n                for (int i = 0; i < F; ++i)\n                    if (!toRemove[i]) nxt.push_back(freeRects[i]);\n                freeRects.swap(nxt);\n            }\n        }\n    }\n    return true;\n}\n\n/* ------------------------------------------------------------\n   Simple row packing (fallback)\n   ------------------------------------------------------------ */\nvoid packRow(const vector<long long>& areas,\n             vector<array<int,4>>& placed,\n             int W = 1000) {\n    int N = (int)areas.size();\n    placed.assign(N, {0,0,0,0});\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(),\n         [&](int i, int j){ return areas[i] > areas[j]; });\n\n    int curX = 0, curY = 0, rowH = 0;\n    for (int id : order) {\n        long long area = areas[id];\n        if (area == 0) area = 1; // tiny rectangle\n        int w = max(1, (int)((area + W - 1) / W));\n        int h = (int)((area + w - 1) / w);\n        if (curX + w > W) {\n            curX = 0;\n            curY += rowH;\n            rowH = 0;\n        }\n        placed[id] = {curX, curY, w, h};\n        curX += w;\n        rowH = max(rowH, h);\n    }\n}\n\n/* ------------------------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int W, D, N;\n    if (!(cin >> W >> D >> N)) return 0;\n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; ++d)\n        for (int k = 0; k < N; ++k) cin >> a[d][k];\n\n    /* ---------- 1. collect demands for each rank (i\u2011th smallest) ---- */\n    vector<vector<int>> demand(N, vector<int>(D));\n    for (int d = 0; d < D; ++d) {\n        vector<pair<int,int>> v;\n        v.reserve(N);\n        for (int k = 0; k < N; ++k) v.emplace_back(a[d][k], k);\n        sort(v.begin(), v.end(),\n             [](const pair<int,int>& p, const pair<int,int>& q){\n                 return p.first < q.first;\n             });\n        for (int i = 0; i < N; ++i) demand[i][d] = v[i].first;\n    }\n\n    /* ---------- 2. greedy area allocation (optimal B[i]) ------------ */\n    // safe buffer: worst total slack = N * (W-1)\n    long long capacity = 1LL * W * W - 1LL * N * (W - 1);\n    priority_queue<Segment> pq;\n    for (int i = 0; i < N; ++i) {\n        auto &vec = demand[i];\n        sort(vec.begin(), vec.end());\n        int prev = 0;\n        for (int t = 0; t < (int)vec.size(); ++t) {\n            int cur = vec[t];\n            int delta = cur - prev;\n            if (delta > 0) {\n                int cnt = D - t;               // days whose demand > prev\n                pq.emplace(cnt, (long long)delta, i);\n            }\n            prev = cur;\n        }\n    }\n\n    vector<long long> B(N, 0);\n    long long remain = capacity;\n    while (remain > 0 && !pq.empty()) {\n        auto [cnt, delta, idx] = pq.top(); pq.pop();\n        long long take = min(delta, remain);\n        B[idx] += take;\n        remain -= take;\n        delta -= take;\n        if (delta > 0) pq.emplace(cnt, delta, idx);\n    }\n\n    /* ---------- 3. pack rectangles (MaxRects) ---------------------- */\n    vector<array<int,4>> placed;\n    bool ok = packRectangles(B, placed, W);\n    if (!ok) {\n        // fallback to simple row packing\n        packRow(B, placed, W);\n    }\n\n    /* ---------- 4. compute actual areas after packing ---------------- */\n    vector<long long> actual(N);\n    for (int i = 0; i < N; ++i) {\n        actual[i] = 1LL * placed[i][2] * placed[i][3];\n    }\n\n    /* ---------- 5. prepare output (assign rectangles to reservations) */\n    // indices sorted by actual area (ascending)\n    vector<int> ascIdx(N);\n    iota(ascIdx.begin(), ascIdx.end(), 0);\n    sort(ascIdx.begin(), ascIdx.end(),\n         [&](int i, int j){ return actual[i] < actual[j]; });\n\n    vector<vector<array<int,4>>> out(D, vector<array<int,4>>(N));\n    for (int d = 0; d < D; ++d) {\n        vector<pair<int,int>> vp;\n        vp.reserve(N);\n        for (int k = 0; k < N; ++k) vp.emplace_back(a[d][k], k);\n        sort(vp.begin(), vp.end(),\n             [](const pair<int,int>& p, const pair<int,int>& q){\n                 return p.first < q.first;\n             });\n        for (int i = 0; i < N; ++i) {\n            int reservation = vp[i].second;\n            const auto &rc = placed[ ascIdx[i] ];   // i\u2011th smallest actual area\n            // rc = {x, y, w, h}\n            out[d][reservation] = {rc[0], rc[1],\n                                    rc[0] + rc[2], rc[1] + rc[3]};\n        }\n    }\n\n    /* ---------- 6. print ------------------------------------------------ */\n    for (int d = 0; d < D; ++d)\n        for (int k = 0; k < N; ++k) {\n            const auto &r = out[d][k];\n            cout << r[0] << ' ' << r[1] << ' '\n                 << r[2] << ' ' << r[3] << '\\n';\n        }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MOD = 998244353;\nconst int N = 9;\nconst int NSTAMP = 3;\nconst int M = 20;\nconst int MAX_K = 81;\n\nint stamp[M][3][3];\n\nstruct Act {\n    long long delta;\n    int m, p, q;\n    \n    // Equality operator needed for vector comparison\n    bool operator==(const Act& other) const {\n        return m == other.m && p == other.p && q == other.q;\n    }\n};\n\nvoid applyStamp(int board[9][9], const Act& a) {\n    for (int di = 0; di < 3; ++di)\n        for (int dj = 0; dj < 3; ++dj) {\n            int &cell = board[a.p + di][a.q + dj];\n            cell += stamp[a.m][di][dj];\n            if (cell >= MOD) cell -= MOD;\n        }\n}\n\n// generate all possible actions for the current board\nvector<Act> computeActions(const int board[9][9]) {\n    vector<Act> actions;\n    actions.reserve(M * (N - 2) * (N - 2));\n    for (int m = 0; m < M; ++m) {\n        for (int p = 0; p <= N - NSTAMP; ++p) {\n            for (int q = 0; q <= N - NSTAMP; ++q) {\n                long long d = 0;\n                for (int di = 0; di < 3; ++di)\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int cur = board[p + di][q + dj];\n                        int nv = cur + stamp[m][di][dj];\n                        if (nv >= MOD) nv -= MOD;\n                        d += (nv - cur);\n                    }\n                actions.push_back({d, m, p, q});\n            }\n        }\n    }\n    return actions;\n}\n\n// maximal delta on the given board (the action is stored in 'best')\nlong long maxDelta(const int board[9][9], Act &best) {\n    long long bestVal = LLONG_MIN;\n    for (int m = 0; m < M; ++m) {\n        for (int p = 0; p <= N - NSTAMP; ++p) {\n            for (int q = 0; q <= N - NSTAMP; ++q) {\n                long long d = 0;\n                for (int di = 0; di < 3; ++di)\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int cur = board[p + di][q + dj];\n                        int nv = cur + stamp[m][di][dj];\n                        if (nv >= MOD) nv -= MOD;\n                        d += (nv - cur);\n                    }\n                if (d > bestVal) {\n                    bestVal = d;\n                    best = {d, m, p, q};\n                }\n            }\n        }\n    }\n    return bestVal;\n}\n\n// evaluate the score of a board\nlong long boardScore(const int board[9][9]) {\n    long long sum = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) sum += board[i][j];\n    return sum;\n}\n\n// Apply sequence to a board and return final board\nvoid applySequenceToBoard(const vector<Act>& seq, const int initBoard[9][9], int board[9][9]) {\n    memcpy(board, initBoard, sizeof(int) * N * N);\n    for (const auto& a : seq) {\n        applyStamp(board, a);\n    }\n}\n\n// Local search with simulated annealing-like acceptance\nlong long localSearchWithSA(const vector<Act>& initial, const int initBoard[9][9], vector<Act>& bestSeq) {\n    vector<Act> seq = initial;\n    int board[N][N];\n    applySequenceToBoard(seq, initBoard, board);\n    long long bestScore = boardScore(board);\n    bestSeq = seq;\n    \n    const int MAX_ITER = 3;\n    const double START_TEMP = 10.0;\n    \n    for (int iter = 0; iter < MAX_ITER; ++iter) {\n        double temp = START_TEMP / (iter + 1);\n        \n        // Try random moves\n        for (int attempt = 0; attempt < 500; ++attempt) {\n            int board1[N][N];\n            applySequenceToBoard(seq, initBoard, board1);\n            \n            // Random move: replace, insert, or delete\n            int moveType = rand() % 3;\n            vector<Act> newSeq = seq;\n            bool changed = false;\n            \n            if (moveType == 0 && !seq.empty()) {\n                // Replace\n                int idx = rand() % seq.size();\n                vector<Act> actions = computeActions(board1);\n                if (!actions.empty()) {\n                    Act newAct = actions[rand() % actions.size()];\n                    newSeq[idx] = newAct;\n                    changed = true;\n                }\n            } else if (moveType == 1 && seq.size() < MAX_K) {\n                // Insert\n                vector<Act> actions = computeActions(board1);\n                if (!actions.empty()) {\n                    Act newAct = actions[rand() % actions.size()];\n                    int idx = rand() % (seq.size() + 1);\n                    newSeq.insert(newSeq.begin() + idx, newAct);\n                    changed = true;\n                }\n            } else if (moveType == 2 && seq.size() > 1) {\n                // Delete\n                int idx = rand() % seq.size();\n                newSeq.erase(newSeq.begin() + idx);\n                changed = true;\n            }\n            \n            if (!changed) continue;\n            \n            int board2[N][N];\n            applySequenceToBoard(newSeq, initBoard, board2);\n            long long newScore = boardScore(board2);\n            \n            long long delta = newScore - bestScore;\n            if (delta > 0 || (temp > 0 && exp((double)delta / temp) > (double)rand() / RAND_MAX)) {\n                seq = newSeq;\n                if (newScore > bestScore) {\n                    bestScore = newScore;\n                    bestSeq = seq;\n                }\n            }\n        }\n    }\n    return bestScore;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    srand(time(nullptr));\n\n    int N_in, M_in, K;\n    if (!(cin >> N_in >> M_in >> K)) return 0;\n\n    int initBoard[N][N];\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            long long x; cin >> x;\n            initBoard[i][j] = int(x % MOD);\n        }\n\n    for (int m = 0; m < M; ++m)\n        for (int i = 0; i < 3; ++i)\n            for (int j = 0; j < 3; ++j) {\n                long long x; cin >> x;\n                stamp[m][i][j] = int(x % MOD);\n            }\n\n    // ----- parameters of the heuristic -----\n    const int NUM_TRIALS = 40;      // number of random restarts\n    const int T = 100;              // number of first\u2011move candidates for 2\u2011step lookahead\n    const double PROB_ZERO = 0.30;  // probability to accept a pair with total delta == 0\n\n    random_device rd;\n    mt19937 rng(rd());\n\n    // baseline score (initial board)\n    long long bestScore = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) bestScore += initBoard[i][j];\n\n    vector<tuple<int,int,int>> bestOps;\n\n    for (int trial = 0; trial < NUM_TRIALS; ++trial) {\n        // different seed for each trial\n        rng.seed(rd() + trial * 1000);\n\n        int board[N][N];\n        memcpy(board, initBoard, sizeof(board));\n        int remaining = K;\n        vector<tuple<int,int,int>> ops;\n\n        while (remaining > 0) {\n            // ----- step 1 : best single action -----\n            vector<Act> actions = computeActions(board);\n\n            // collect all actions with maximal delta\n            long long maxd = LLONG_MIN;\n            vector<Act> bestList;\n            for (auto &a : actions) {\n                if (a.delta > maxd) {\n                    maxd = a.delta;\n                    bestList.clear();\n                    bestList.push_back(a);\n                } else if (a.delta == maxd) {\n                    bestList.push_back(a);\n                }\n            }\n            // random tie\u2011breaking\n            Act bestSingle = bestList[rng() % bestList.size()];\n\n            if (bestSingle.delta > 0) {\n                applyStamp(board, bestSingle);\n                ops.emplace_back(bestSingle.m, bestSingle.p, bestSingle.q);\n                --remaining;\n                continue;\n            }\n\n            // ----- step 2 : 2\u2011step lookahead (pair search) -----\n            sort(actions.begin(), actions.end(),\n                 [](const Act& a, const Act& b) { return a.delta > b.delta; });\n\n            int candCount = min(T, (int)actions.size());\n            vector<int> idx(candCount);\n            iota(idx.begin(), idx.end(), 0);\n            shuffle(idx.begin(), idx.end(), rng);\n\n            long long bestPairDelta = bestSingle.delta;\n            Act bestFirst = bestSingle;\n            bool foundBetter = false;\n\n            for (int t = 0; t < candCount; ++t) {\n                const Act &a1 = actions[idx[t]];\n\n                // simulate a1 on a temporary board\n                int tmp[N][N];\n                memcpy(tmp, board, sizeof(tmp));\n                for (int di = 0; di < 3; ++di)\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int &cell = tmp[a1.p + di][a1.q + dj];\n                        cell += stamp[a1.m][di][dj];\n                        if (cell >= MOD) cell -= MOD;\n                    }\n\n                // best second action after a1\n                Act dummy;\n                long long best2 = maxDelta(tmp, dummy);\n                long long total = a1.delta + best2;\n\n                if (total > bestPairDelta) {\n                    bestPairDelta = total;\n                    bestFirst = a1;\n                    foundBetter = true;\n                }\n            }\n\n            if (foundBetter && (bestPairDelta > 0 ||\n                (bestPairDelta == 0 && uniform_real_distribution<double>(0.0, 1.0)(rng) < PROB_ZERO))) {\n                applyStamp(board, bestFirst);\n                ops.emplace_back(bestFirst.m, bestFirst.p, bestFirst.q);\n                --remaining;\n                continue;\n            }\n\n            // no positive (or zero\u2011with\u2011probability) improvement possible any more\n            break;\n        }\n\n        // convert ops to vector<Act> for local search\n        vector<Act> seq;\n        for (auto [m, p, q] : ops) {\n            seq.push_back({0, m, p, q});  // delta will be recomputed\n        }\n        \n        // Apply local search with simulated annealing\n        vector<Act> improvedSeq;\n        localSearchWithSA(seq, initBoard, improvedSeq);\n        \n        // Convert back to ops format\n        ops.clear();\n        for (const auto& a : improvedSeq) {\n            ops.emplace_back(a.m, a.p, a.q);\n        }\n        \n        // Compute actual score\n        long long curScore = 0;\n        memcpy(board, initBoard, sizeof(board));\n        for (auto [m, p, q] : ops) {\n            for (int di = 0; di < 3; ++di)\n                for (int dj = 0; dj < 3; ++dj) {\n                    int &cell = board[p + di][q + dj];\n                    cell += stamp[m][di][dj];\n                    if (cell >= MOD) cell -= MOD;\n                }\n        }\n        curScore = boardScore(board);\n\n        if (curScore > bestScore) {\n            bestScore = curScore;\n            bestOps = ops;\n        }\n    }\n\n    cout << bestOps.size() << '\\n';\n    for (auto [m, p, q] : bestOps)\n        cout << m << ' ' << p << ' ' << q << '\\n';\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 5;                 // fixed in all test cases\n    const int TOT = N * N;           // 25\n\n    int Ncase;\n    // the problem supplies exactly one test case, but we also accept several\n    while (cin >> Ncase) {\n        // read the matrix A\n        vector<vector<int>> A(N, vector<int>(N));\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                cin >> A[i][j];\n\n        /* ----- row of each container ----- */\n        vector<int> row_of(TOT, -1);\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                row_of[A[i][j]] = i;\n\n        /* ----- generate actions for the large crane ----- */\n        vector<string> actions(N);\n        string large;\n        large.reserve(500);               // enough for all cases\n\n        int curR = 0, curC = 0;             // initial position of the large crane\n\n        for (int c = 0; c < TOT; ++c) {\n            int targetR = row_of[c];\n\n            // vertical movement\n            while (curR < targetR) { large.push_back('D'); ++curR; }\n            while (curR > targetR) { large.push_back('U'); --curR; }\n\n            // horizontal movement to column 0 (the receiving gate)\n            while (curC > 0) { large.push_back('L'); --curC; }\n\n            // pick up the container\n            large.push_back('P');\n\n            // move to the dispatch gate (column N-1 = 4)\n            while (curC < N - 1) { large.push_back('R'); ++curC; }\n\n            // release the container\n            large.push_back('Q');\n        }\n\n        actions[0] = large;\n        const size_t L = actions[0].size();   // total number of turns\n\n        /* ----- actions for the small cranes ----- */\n        for (int i = 1; i < N; ++i) {\n            string s;\n            s.reserve(L);\n            s.push_back('B');                 // bomb in the first turn\n            s.append(L - 1, '.');             // do nothing afterwards\n            actions[i] = s;\n        }\n\n        /* ----- output ----- */\n        for (int i = 0; i < N; ++i)\n            cout << actions[i] << '\\n';\n    }\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int r, c; };\nstruct Edge { int to, rev, cap, cost; };\nstruct MinCostFlow {\n    const int INF = 1e9;\n    int N;\n    vector<vector<Edge>> G;\n    MinCostFlow(int n) : N(n), G(n) {}\n    void addEdge(int from, int to, int cap, int cost) {\n        Edge a{to, (int)G[to].size(), cap, cost};\n        Edge b{from, (int)G[from].size(), 0, -cost};\n        G[from].push_back(a);\n        G[to].push_back(b);\n    }\n    pair<int, long long> minCostMaxFlow(int s, int t) {\n        int flow = 0;\n        long long cost = 0;\n        vector<int> dist(N), pv(N), pe(N);\n        vector<int> potential(N, 0);\n        while (true) {\n            fill(dist.begin(), dist.end(), INF);\n            dist[s] = 0;\n            using P = pair<int, int>;\n            priority_queue<P, vector<P>, greater<P>> pq;\n            pq.emplace(0, s);\n            while (!pq.empty()) {\n                auto [d, v] = pq.top(); pq.pop();\n                if (d != dist[v]) continue;\n                for (int i = 0; i < (int)G[v].size(); ++i) {\n                    Edge &e = G[v][i];\n                    if (e.cap <= 0) continue;\n                    int nd = d + e.cost + potential[v] - potential[e.to];\n                    if (nd < dist[e.to]) {\n                        dist[e.to] = nd;\n                        pv[e.to] = v;\n                        pe[e.to] = i;\n                        pq.emplace(nd, e.to);\n                    }\n                }\n            }\n            if (dist[t] == INF) break;\n            for (int v = 0; v < N; ++v) {\n                if (dist[v] < INF) potential[v] += dist[v];\n            }\n            int addflow = INF;\n            for (int v = t; v != s; v = pv[v]) {\n                Edge &e = G[pv[v]][pe[v]];\n                addflow = min(addflow, e.cap);\n            }\n            for (int v = t; v != s; v = pv[v]) {\n                Edge &e = G[pv[v]][pe[v]];\n                e.cap -= addflow;\n                G[v][e.rev].cap += addflow;\n            }\n            flow += addflow;\n            cost += 1LL * addflow * potential[t];\n        }\n        return {flow, cost};\n    }\n};\n\nstatic inline int manhattan(const Pos& a, const Pos& b) {\n    return abs(a.r - b.r) + abs(a.c - b.c);\n}\n\nstatic void moveTo(Pos& cur, const Pos& target, vector<string>& ops) {\n    while (cur.r < target.r) { ops.emplace_back(\"D\"); cur.r++; }\n    while (cur.r > target.r) { ops.emplace_back(\"U\"); cur.r--; }\n    while (cur.c < target.c) { ops.emplace_back(\"R\"); cur.c++; }\n    while (cur.c > target.c) { ops.emplace_back(\"L\"); cur.c--; }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\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    vector<Pos> srcPos, snkPos;\n    vector<int> srcSup, snkDem;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (h[i][j] > 0) {\n                srcPos.push_back({i, j});\n                srcSup.push_back(h[i][j]);\n            } else if (h[i][j] < 0) {\n                snkPos.push_back({i, j});\n                snkDem.push_back(-h[i][j]);\n            }\n        }\n    }\n    int S = srcPos.size();\n    int T = snkPos.size();\n    if (S == 0 || T == 0) return 0;\n\n    int V = S + T + 2;\n    int SRC = V - 2, SNK = V - 1;\n    MinCostFlow mcf(V);\n\n    for (int i = 0; i < S; ++i) mcf.addEdge(SRC, i, srcSup[i], 0);\n    for (int j = 0; j < T; ++j) mcf.addEdge(S + j, SNK, snkDem[j], 0);\n\n    struct OrigEdge { int from, to, cap; };\n    vector<OrigEdge> origEdges;\n    \n    for (int i = 0; i < S; ++i) {\n        for (int j = 0; j < T; ++j) {\n            int d = manhattan(srcPos[i], snkPos[j]);\n            int cost = d * (100 + srcSup[i]);\n            int cap = min(srcSup[i], snkDem[j]);\n            if (cap > 0) {\n                mcf.addEdge(i, S + j, cap, cost);\n                origEdges.push_back({i, S + j, cap});\n            }\n        }\n    }\n\n    mcf.minCostMaxFlow(SRC, SNK);\n\n    struct Delivery { Pos sink; int amt; };\n    vector<vector<Delivery>> srcDeliveries(S);\n    \n    for (auto &oe : origEdges) {\n        for (auto &e : mcf.G[oe.from]) {\n            if (e.to == oe.to) {\n                int flow = oe.cap - e.cap;\n                if (flow > 0) {\n                    int sinkIdx = oe.to - S;\n                    srcDeliveries[oe.from].push_back({snkPos[sinkIdx], flow});\n                }\n                break;\n            }\n        }\n    }\n\n    struct SourceInfo {\n        Pos pos;\n        int totalSupply;\n        vector<Delivery> deliveries;\n        bool oneTrip;\n    };\n    vector<SourceInfo> sources;\n    for (int i = 0; i < S; ++i) {\n        if (srcDeliveries[i].empty()) continue;\n        SourceInfo si;\n        si.pos = srcPos[i];\n        si.totalSupply = srcSup[i];\n        si.deliveries = srcDeliveries[i];\n\n        // Don't sort - keep the order from min-cost flow\n\n        long long costOneTrip = 0;\n        Pos cur = si.pos;\n        int load = si.totalSupply;\n        for (auto &d : si.deliveries) {\n            costOneTrip += 1LL * manhattan(cur, d.sink) * (100 + load);\n            load -= d.amt;\n            cur = d.sink;\n        }\n\n        long long costSeparate = 0;\n        for (auto &d : si.deliveries) {\n            // load at source, move loaded to sink, unload, return empty\n            costSeparate += 1LL * manhattan(si.pos, d.sink) * (100 + d.amt);\n            costSeparate += 1LL * manhattan(si.pos, d.sink) * 100;\n        }\n\n        si.oneTrip = (costOneTrip <= costSeparate);\n        sources.push_back(si);\n    }\n\n    Pos cur{0, 0};\n    vector<string> ops;\n    vector<bool> visited(sources.size(), false);\n    \n    // Greedy nearest neighbor\n    while (true) {\n        int bestIdx = -1;\n        int bestDist = 1e9;\n        for (int i = 0; i < (int)sources.size(); ++i) {\n            if (!visited[i]) {\n                int d = manhattan(cur, sources[i].pos);\n                if (d < bestDist) {\n                    bestDist = d;\n                    bestIdx = i;\n                }\n            }\n        }\n        if (bestIdx == -1) break;\n        visited[bestIdx] = true;\n        auto &src = sources[bestIdx];\n\n        moveTo(cur, src.pos, ops);\n\n        if (src.oneTrip) {\n            // Load at source, visit all sinks in order, return empty\n            ops.emplace_back(\"+\" + to_string(src.totalSupply));\n            int curLoad = src.totalSupply;\n            for (auto &d : src.deliveries) {\n                moveTo(cur, d.sink, ops);\n                ops.emplace_back(\"-\" + to_string(d.amt));\n                curLoad -= d.amt;\n            }\n        } else {\n            // Separate trips: for each delivery\n            for (auto &d : src.deliveries) {\n                // Load at source\n                ops.emplace_back(\"+\" + to_string(d.amt));\n                // Move to sink (loaded)\n                moveTo(cur, d.sink, ops);\n                // Unload at sink\n                ops.emplace_back(\"-\" + to_string(d.amt));\n                // Return empty to source\n                moveTo(cur, src.pos, ops);\n            }\n        }\n    }\n\n    for (const string &s : ops) cout << s << '\\n';\n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, T;\n    if (!(cin >> N >> M >> T)) return 0;\n    const int S = 2 * N * (N - 1);           // 60\n    vector<vector<int>> seed(S, vector<int>(M));\n    for (int i = 0; i < S; ++i)\n        for (int j = 0; j < M; ++j)\n            cin >> seed[i][j];\n\n    /* ----- pre\u2011compute positions ordered by degree ----- */\n    vector<tuple<int,int,int>> posDeg;       // (degree, i, j)\n    posDeg.reserve(N * N);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int d = (i > 0) + (i < N - 1) + (j > 0) + (j < N - 1);\n            posDeg.emplace_back(d, i, j);\n        }\n    }\n    sort(posDeg.begin(), posDeg.end(),\n         [](const auto& a, const auto& b) {\n             if (get<0>(a) != get<0>(b)) return get<0>(a) > get<0>(b);\n             return (get<1>(a) + get<2>(a)) < (get<1>(b) + get<2>(b));\n         });\n\n    /* ----- pre-compute neighbors for each position ----- */\n    vector<vector<int>> neighbors(36);\n    for (int p = 0; p < 36; ++p) {\n        int i = get<1>(posDeg[p]);\n        int j = get<2>(posDeg[p]);\n        if (i > 0) neighbors[p].push_back((i-1)*N + j);\n        if (i + 1 < N) neighbors[p].push_back((i+1)*N + j);\n        if (j > 0) neighbors[p].push_back(i*N + (j-1));\n        if (j + 1 < N) neighbors[p].push_back(i*N + (j+1));\n    }\n\n    /* ------------------- main loop ---------------------- */\n    for (int turn = 0; turn < T; ++turn) {\n        /* ----- evaluate current seeds ----- */\n        vector<int> sum(S, 0);\n        vector<int> bestIdx(M, -1);\n        vector<int> bestVal(M, -1);\n        \n        for (int i = 0; i < S; ++i) {\n            int s = 0;\n            for (int j = 0; j < M; ++j) {\n                int v = seed[i][j];\n                s += v;\n                if (v > bestVal[j]) {\n                    bestVal[j] = v;\n                    bestIdx[j] = i;\n                }\n            }\n            sum[i] = s;\n        }\n\n        /* ----- choose 36 parent seeds ----- */\n        vector<pair<long long, int>> scored;\n        scored.reserve(S);\n        vector<int> specialistCount(S, 0);\n        for (int j = 0; j < M; ++j) {\n            if (bestIdx[j] >= 0) specialistCount[bestIdx[j]]++;\n        }\n        for (int i = 0; i < S; ++i) {\n            long long score = (long long)specialistCount[i] * 10000 + sum[i];\n            scored.emplace_back(score, i);\n        }\n        sort(scored.begin(), scored.end(), greater<>());\n        \n        // Take top 36\n        vector<int> parents;\n        parents.reserve(36);\n        vector<char> used(S, 0);\n        for (int i = 0; i < 36; ++i) {\n            parents.push_back(scored[i].second);\n            used[scored[i].second] = 1;\n        }\n\n        /* ----- greedy placement: maximize expected child value ----- */\n        vector<int> assign(36, -1);  // position -> seed\n        vector<char> placed(36, 0);  // which parent seeds are used\n        \n        for (int pos = 0; pos < 36; ++pos) {\n            long long bestPosScore = -1;\n            int bestSeedIdx = -1;\n            \n            // Try each unused parent seed\n            for (int si = 0; si < 36; ++si) {\n                if (placed[si]) continue;\n                int seedId = parents[si];\n                \n                // Calculate expected contribution from this placement\n                long long contrib = 0;\n                for (int nb : neighbors[pos]) {\n                    if (assign[nb] != -1) {\n                        // There's already a neighbor placed\n                        contrib += sum[seedId] + sum[assign[nb]];\n                    }\n                }\n                \n                if (contrib > bestPosScore) {\n                    bestPosScore = contrib;\n                    bestSeedIdx = si;\n                }\n            }\n            \n            // Place the best seed here\n            assign[pos] = parents[bestSeedIdx];\n            placed[bestSeedIdx] = 1;\n        }\n\n        /* ----- output ----- */\n        vector<vector<int>> A(N, vector<int>(N, -1));\n        for (int p = 0; p < 36; ++p) {\n            int di = get<1>(posDeg[p]);\n            int dj = get<2>(posDeg[p]);\n            A[di][dj] = assign[p];\n        }\n\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (j) cout << ' ';\n                cout << A[i][j];\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n\n        /* ----- read next generation ----- */\n        vector<vector<int>> nxt(S, vector<int>(M));\n        for (int i = 0; i < S; ++i)\n            for (int j = 0; j < M; ++j)\n                cin >> nxt[i][j];\n        seed.swap(nxt);\n    }\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, V;\n    if (!(cin >> N >> M >> V)) return 0;\n    vector<string> sgrid(N), tgrid(N);\n    for (int i = 0; i < N; ++i) cin >> sgrid[i];\n    for (int i = 0; i < N; ++i) cin >> tgrid[i];\n\n    /* ----- board representation ----- */\n    vector<vector<bool>> has(N, vector<bool>(N, false));\n    vector<pair<int,int>> src;\n    vector<pair<int,int>> emptyTgt;\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (sgrid[i][j] == '1') {\n                has[i][j] = true;\n                if (tgrid[i][j] == '0')\n                    src.emplace_back(i, j);\n            }\n            if (tgrid[i][j] == '1') {\n                if (!has[i][j])\n                    emptyTgt.emplace_back(i, j);\n            }\n        }\n    }\n\n    // Use maximum available leaves\n    int numLeaves = V - 1;\n    if (numLeaves < 1) numLeaves = 1;\n\n    /* ----- tree description ----- */\n    const int Vprime = numLeaves + 1;\n    cout << Vprime << \"\\n\";\n    for (int i = 1; i < Vprime; ++i) {\n        cout << 0 << ' ' << 1 << \"\\n\";\n    }\n    \n    // Start at center of mass\n    int sumX = 0, sumY = 0, total = 0;\n    for (auto &p : src) { sumX += p.first; sumY += p.second; total++; }\n    for (auto &p : emptyTgt) { sumX += p.first; sumY += p.second; total++; }\n    int start_x = (total > 0) ? (sumX / total) : 0;\n    int start_y = (total > 0) ? (sumY / total) : 0;\n    start_x = max(0, min(N-1, start_x));\n    start_y = max(0, min(N-1, start_y));\n    cout << start_x << ' ' << start_y << \"\\n\";\n\n    /* ----- directions ----- */\n    const int dr[4] = {0, 1, 0, -1};\n    const int dc[4] = {1, 0, -1, 0};\n\n    auto move_char = [&](int d)->char {\n        if (d == 0) return 'R';\n        if (d == 1) return 'D';\n        if (d == 2) return 'L';\n        return 'U';\n    };\n    auto dir_from_delta = [&](int drr, int dcc)->int {\n        for (int d = 0; d < 4; ++d)\n            if (dr[d] == drr && dc[d] == dcc) return d;\n        return -1;\n    };\n\n    /* ----- simulation ----- */\n    vector<string> ops;\n    int root_x = start_x, root_y = start_y;\n    vector<int> leaf_dir(numLeaves, 0);\n    vector<bool> holding(numLeaves, false);\n\n    const int INF = 1e9;\n\n    auto pick_for_leaf = [&](int leaf) {\n        if (src.empty()) return false;\n        \n        int bestDist = INF, bestIdx = -1;\n        pair<int,int> bestNeighbour{-1,-1};\n        int bestDir = -1;\n\n        for (int i = 0; i < (int)src.size(); ++i) {\n            int sx = src[i].first, sy = src[i].second;\n            for (int d = 0; d < 4; ++d) {\n                int nx = sx - dr[d];\n                int ny = sy - dc[d];\n                if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n                int dist = abs(root_x - nx) + abs(root_y - ny);\n                int cur_dir = leaf_dir[leaf];\n                int diff = (d - cur_dir + 4) % 4;\n                int alt = 4 - diff;\n                int rot_needed = min(diff, alt);\n                dist += rot_needed;\n                if (dist < bestDist) {\n                    bestDist = dist;\n                    bestIdx = i;\n                    bestNeighbour = {nx, ny};\n                    bestDir = d;\n                }\n            }\n        }\n\n        while (root_x != bestNeighbour.first || root_y != bestNeighbour.second) {\n            int ddx = 0, ddy = 0;\n            if (root_x < bestNeighbour.first) ddx = 1;\n            else if (root_x > bestNeighbour.first) ddx = -1;\n            if (root_y < bestNeighbour.second) ddy = 1;\n            else if (root_y > bestNeighbour.second) ddy = -1;\n\n            string op(2*Vprime, '.');\n            if (abs(root_x - bestNeighbour.first) >= abs(root_y - bestNeighbour.second)) {\n                op[0] = move_char(dir_from_delta(ddx, 0));\n                root_x += ddx;\n            } else {\n                op[0] = move_char(dir_from_delta(0, ddy));\n                root_y += ddy;\n            }\n            ops.push_back(op);\n        }\n\n        int target_dir = bestDir;\n        int cur_dir = leaf_dir[leaf];\n        int diff = (target_dir - cur_dir + 4) % 4;\n        int alt = 4 - diff;\n        int steps, rot;\n        if (diff <= alt) { steps = diff; rot = 1; }\n        else { steps = alt; rot = -1; }\n\n        int leaf_vertex = leaf + 1;\n\n        if (steps > 0) {\n            for (int i = 0; i < steps - 1; ++i) {\n                string op(2*Vprime, '.');\n                op[leaf_vertex] = (rot == 1 ? 'R' : 'L');\n                ops.push_back(op);\n                leaf_dir[leaf] = (leaf_dir[leaf] + rot + 4) % 4;\n            }\n            string op(2*Vprime, '.');\n            op[leaf_vertex] = (rot == 1 ? 'R' : 'L');\n            op[Vprime + leaf_vertex] = 'P';\n            ops.push_back(op);\n            leaf_dir[leaf] = (leaf_dir[leaf] + rot + 4) % 4;\n        } else {\n            string op(2*Vprime, '.');\n            op[Vprime + leaf_vertex] = 'P';\n            ops.push_back(op);\n        }\n\n        holding[leaf] = true;\n        has[src[bestIdx].first][src[bestIdx].second] = false;\n        src.erase(src.begin() + bestIdx);\n        return true;\n    };\n\n    auto place_for_leaf = [&](int leaf) {\n        if (emptyTgt.empty()) return false;\n\n        int bestDist = INF, bestIdx = -1;\n        pair<int,int> bestNeighbour{-1,-1};\n        int bestDir = -1;\n\n        for (int i = 0; i < (int)emptyTgt.size(); ++i) {\n            int tx = emptyTgt[i].first, ty = emptyTgt[i].second;\n            for (int d = 0; d < 4; ++d) {\n                int nx = tx - dr[d];\n                int ny = ty - dc[d];\n                if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n                int dist = abs(root_x - nx) + abs(root_y - ny);\n                int cur_dir = leaf_dir[leaf];\n                int diff = (d - cur_dir + 4) % 4;\n                int alt = 4 - diff;\n                int rot_needed = min(diff, alt);\n                dist += rot_needed;\n                if (dist < bestDist) {\n                    bestDist = dist;\n                    bestIdx = i;\n                    bestNeighbour = {nx, ny};\n                    bestDir = d;\n                }\n            }\n        }\n\n        while (root_x != bestNeighbour.first || root_y != bestNeighbour.second) {\n            int ddx = 0, ddy = 0;\n            if (root_x < bestNeighbour.first) ddx = 1;\n            else if (root_x > bestNeighbour.first) ddx = -1;\n            if (root_y < bestNeighbour.second) ddy = 1;\n            else if (root_y > bestNeighbour.second) ddy = -1;\n\n            string op(2*Vprime, '.');\n            if (abs(root_x - bestNeighbour.first) >= abs(root_y - bestNeighbour.second)) {\n                op[0] = move_char(dir_from_delta(ddx, 0));\n                root_x += ddx;\n            } else {\n                op[0] = move_char(dir_from_delta(0, ddy));\n                root_y += ddy;\n            }\n            ops.push_back(op);\n        }\n\n        int target_dir = bestDir;\n        int cur_dir = leaf_dir[leaf];\n        int diff = (target_dir - cur_dir + 4) % 4;\n        int alt = 4 - diff;\n        int steps, rot;\n        if (diff <= alt) { steps = diff; rot = 1; }\n        else { steps = alt; rot = -1; }\n\n        int leaf_vertex = leaf + 1;\n\n        if (steps > 0) {\n            for (int i = 0; i < steps - 1; ++i) {\n                string op(2*Vprime, '.');\n                op[leaf_vertex] = (rot == 1 ? 'R' : 'L');\n                ops.push_back(op);\n                leaf_dir[leaf] = (leaf_dir[leaf] + rot + 4) % 4;\n            }\n            string op(2*Vprime, '.');\n            op[leaf_vertex] = (rot == 1 ? 'R' : 'L');\n            op[Vprime + leaf_vertex] = 'P';\n            ops.push_back(op);\n            leaf_dir[leaf] = (leaf_dir[leaf] + rot + 4) % 4;\n        } else {\n            string op(2*Vprime, '.');\n            op[Vprime + leaf_vertex] = 'P';\n            ops.push_back(op);\n        }\n\n        has[emptyTgt[bestIdx].first][emptyTgt[bestIdx].second] = true;\n        emptyTgt.erase(emptyTgt.begin() + bestIdx);\n        holding[leaf] = false;\n        return true;\n    };\n\n    while (!src.empty() || !emptyTgt.empty()) {\n        // Try to pick - iterate multiple times to give all leaves a chance\n        for (int round = 0; round < 3 && !src.empty(); ++round) {\n            for (int leaf = 0; leaf < numLeaves && !holding[leaf]; ++leaf) {\n                if (!src.empty()) {\n                    pick_for_leaf(leaf);\n                }\n            }\n        }\n\n        // Try to place\n        for (int round = 0; round < 3 && !emptyTgt.empty(); ++round) {\n            for (int leaf = 0; leaf < numLeaves && holding[leaf]; ++leaf) {\n                if (!emptyTgt.empty()) {\n                    place_for_leaf(leaf);\n                }\n            }\n        }\n    }\n\n    for (const string &s : ops) cout << s << '\\n';\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    if (!(cin >> N)) return 0;\n\n    const int M = 2 * N;\n    vector<pair<int,int>> pts(M);\n    for (int i = 0; i < M; ++i) cin >> pts[i].first >> pts[i].second;\n\n    /* values: first N are mackerels (+1), next N are sardines (-1) */\n    vector<int> val(M);\n    for (int i = 0; i < N; ++i) val[i] = 1;\n    for (int i = N; i < M; ++i) val[i] = -1;\n\n    /* coordinate compression */\n    vector<int> xs, ys;\n    xs.reserve(M); ys.reserve(M);\n    for (auto &p : pts) {\n        xs.push_back(p.first);\n        ys.push_back(p.second);\n    }\n    sort(xs.begin(), xs.end());\n    xs.erase(unique(xs.begin(), xs.end()), xs.end());\n    sort(ys.begin(), ys.end());\n    ys.erase(unique(ys.begin(), ys.end()), ys.end());\n\n    const int X = (int)xs.size();\n    const int Y = (int)ys.size();\n\n    /* 2\u2011D prefix sums */\n    vector<int> pref( (size_t)(X + 1) * (Y + 1), 0 );\n    for (int i = 0; i < M; ++i) {\n        int ix = lower_bound(xs.begin(), xs.end(), pts[i].first) - xs.begin();\n        int iy = lower_bound(ys.begin(), ys.end(), pts[i].second) - ys.begin();\n        pref[ (size_t)(ix + 1) * (Y + 1) + (iy + 1) ] += val[i];\n    }\n    for (int i = 1; i <= X; ++i) {\n        for (int j = 1; j <= Y; ++j) {\n            size_t idx = (size_t)i * (Y + 1) + j;\n            size_t a = (size_t)(i - 1) * (Y + 1) + j;\n            size_t b = (size_t)i * (Y + 1) + (j - 1);\n            size_t c = (size_t)(i - 1) * (Y + 1) + (j - 1);\n            pref[idx] = pref[idx] + pref[a] + pref[b] - pref[c];\n        }\n    }\n\n    /* helper: sum of a rectangle given by exclusive indices */\n    auto rectSum = [&](int l, int r, int b, int t) -> int {\n        // l,r are exclusive on the right, b,t exclusive on the top\n        if (l >= r || b >= t) return 0;\n        size_t idx_rr = (size_t)r * (Y + 1) + t;\n        size_t idx_lr = (size_t)l * (Y + 1) + t;\n        size_t idx_rb = (size_t)r * (Y + 1) + b;\n        size_t idx_lb = (size_t)l * (Y + 1) + b;\n        return (int)(pref[idx_rr] - pref[idx_lr] - pref[idx_rb] + pref[idx_lb]);\n    };\n\n    /* random generator */\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    const int RESTARTS = 80;\n    const int MAX_ITER  = 80;\n\n    int bestValue = -1000000;\n    int bestL = 0, bestR = 1, bestB = 0, bestT = 1;   // fallback\n\n    vector<int> colSum(X), rowSum(Y);\n    vector<int> prefCol(X + 1), prefRow(Y + 1);\n\n    for (int restart = 0; restart < RESTARTS; ++restart) {\n        int leftIdx, rightIdx, bottomIdx, topIdx;\n\n        if (restart == 0) {                     // whole rectangle\n            leftIdx   = 0;\n            rightIdx  = X;\n            bottomIdx = 0;\n            topIdx    = Y;\n        } else {\n            leftIdx   = uniform_int_distribution<int>(0, X - 1)(rng);\n            rightIdx  = uniform_int_distribution<int>(leftIdx + 1, X)(rng);\n            bottomIdx = uniform_int_distribution<int>(0, Y - 1)(rng);\n            topIdx    = uniform_int_distribution<int>(bottomIdx + 1, Y)(rng);\n        }\n\n        int curValue = rectSum(leftIdx, rightIdx, bottomIdx, topIdx);\n        int bestValueRestart = curValue;\n        int bestLr = xs[leftIdx], bestRr = (rightIdx > 0 ? xs[rightIdx - 1] : xs[0]);\n        int bestBr = ys[bottomIdx], bestTr = (topIdx > 0 ? ys[topIdx - 1] : ys[0]);\n\n        for (int it = 0; it < MAX_ITER; ++it) {\n            /* ----- compute column sums and row sums for current y\u2011interval ----- */\n            int b = bottomIdx, t = topIdx;\n            for (int i = 0; i < X; ++i) {\n                // sum of column i between rows b \u2026 t\u20111\n                colSum[i] = pref[(size_t)(i + 1) * (Y + 1) + t]\n                          - pref[(size_t)(i + 1) * (Y + 1) + b]\n                          - pref[(size_t)i * (Y + 1) + t]\n                          + pref[(size_t)i * (Y + 1) + b];\n            }\n            int l = leftIdx, r = rightIdx;\n            for (int j = 0; j < Y; ++j) {\n                // sum of row j between columns l \u2026 r\u20111\n                rowSum[j] = pref[(size_t)r * (Y + 1) + (j + 1)]\n                          - pref[(size_t)l * (Y + 1) + (j + 1)]\n                          - pref[(size_t)r * (Y + 1) + j]\n                          + pref[(size_t)l * (Y + 1) + j];\n            }\n\n            /* ----- one\u2011dimensional prefix sums ----- */\n            prefCol[0] = 0;\n            for (int i = 0; i < X; ++i) prefCol[i + 1] = prefCol[i] + colSum[i];\n            prefRow[0] = 0;\n            for (int j = 0; j < Y; ++j) prefRow[j + 1] = prefRow[j] + rowSum[j];\n\n            /* ----- choose the best side move ----- */\n            int bestGain = 0;\n            int bestSide = -1;   // 0:left, 1:right, 2:bottom, 3:top\n            int bestNewIdx = -1;\n\n            // left side\n            for (int nl = 0; nl < rightIdx; ++nl) {\n                if (nl == leftIdx) continue;\n                int gain = prefCol[leftIdx] - prefCol[nl];\n                if (gain > bestGain) {\n                    bestGain = gain; bestSide = 0; bestNewIdx = nl;\n                }\n            }\n            // right side\n            for (int nr = leftIdx + 1; nr <= X; ++nr) {\n                if (nr == rightIdx) continue;\n                int gain = prefCol[nr] - prefCol[rightIdx];\n                if (gain > bestGain) {\n                    bestGain = gain; bestSide = 1; bestNewIdx = nr;\n                }\n            }\n            // bottom side\n            for (int nb = 0; nb < topIdx; ++nb) {\n                if (nb == bottomIdx) continue;\n                int gain = prefRow[bottomIdx] - prefRow[nb];\n                if (gain > bestGain) {\n                    bestGain = gain; bestSide = 2; bestNewIdx = nb;\n                }\n            }\n            // top side\n            for (int nt = bottomIdx + 1; nt <= Y; ++nt) {\n                if (nt == topIdx) continue;\n                int gain = prefRow[nt] - prefRow[topIdx];\n                if (gain > bestGain) {\n                    bestGain = gain; bestSide = 3; bestNewIdx = nt;\n                }\n            }\n\n            if (bestGain <= 0) break;          // local optimum\n\n            // apply the move\n            switch (bestSide) {\n                case 0: leftIdx   = bestNewIdx; break;\n                case 1: rightIdx  = bestNewIdx; break;\n                case 2: bottomIdx = bestNewIdx; break;\n                case 3: topIdx    = bestNewIdx; break;\n            }\n            curValue += bestGain;\n\n            if (curValue > bestValueRestart) {\n                bestValueRestart = curValue;\n                bestLr = xs[leftIdx];\n                bestRr = (rightIdx > 0 ? xs[rightIdx - 1] : xs[0]);\n                bestBr = ys[bottomIdx];\n                bestTr = (topIdx > 0 ? ys[topIdx - 1] : ys[0]);\n            }\n        }\n\n        if (bestValueRestart > bestValue) {\n            bestValue = bestValueRestart;\n            bestL = bestLr; bestR = bestRr;\n            bestB = bestBr; bestT = bestTr;\n        }\n    }\n\n    /* ----- output the rectangle as a polygon ----- */\n    cout << 4 << '\\n';\n    cout << bestL << ' ' << bestB << '\\n';\n    cout << bestR << ' ' << bestB << '\\n';\n    cout << bestR << ' ' << bestT << '\\n';\n    cout << bestL << ' ' << bestT << '\\n';\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\n\nstruct Candidate {\n    bool skip;          // true \u2192 skip this rectangle\n    int rot;            // 0 = not rotated, 1 = rotated\n    char dir;           // 'U' or 'L'\n    int ref;            // -1 or index of a previously placed rectangle\n    ll sum;             // heuristic score (width+height+penalty)\n    ll x, y;            // coordinates of the placed rectangle\n    ll rw, rh;          // its width and height\n};\n\nint N, T;\nll sigma_;\nvector<ll> mw, mh;                 // measured sizes\nmt19937 rng(123456789);             // fixed seed\n\n/* -------------------------------------------------------------\n   Build ONE greedy placement.\n   The function fills `ans` with the list of decisions,\n   `placed` tells which indices are really placed.\n   ------------------------------------------------------------- */\nvoid build_one_placement(vector<tuple<int,int,char,int>>& ans,\n                         vector<char>& placed)\n{\n    ans.clear();\n    placed.assign(N, 0);\n    ll penalty = 0;\n\n    vector<ll> X(N, 0), Y(N, 0), W(N, 0), H(N, 0);\n    vector<int> placedIdx;               // indices of already placed rectangles\n    ll curW = 0, curH = 0;\n\n    const int TOP_K = 3;                  // best version\n\n    for (int i = 0; i < N; ++i) {\n        vector<Candidate> cand;\n\n        // ----- build reference set ---------------------------------\n        // 1 random reference (best version):\n        // 1. Add -1\n        // 2. Add the last placed rectangle (may duplicate -1)\n        // 3. Add ONE random earlier rectangle (no duplicate check)\n        vector<int> refs;\n        refs.push_back(-1);\n        if (!placedIdx.empty()) {\n            refs.push_back(placedIdx.back());   // last placed\n            // one random earlier rectangle\n            int r = placedIdx[uniform_int_distribution<int>(0, (int)placedIdx.size() - 1)(rng)];\n            refs.push_back(r);\n        }\n\n        // ----- try all rotations, directions, references ----------\n        for (int rot : {0, 1}) {\n            ll w = rot ? mh[i] : mw[i];\n            ll h = rot ? mw[i] : mh[i];\n            for (char dir : {'U', 'L'}) {\n                for (int ref : refs) {\n                    ll nx, ny;\n                    if (dir == 'U') {\n                        ll left = (ref == -1) ? 0 : X[ref] + W[ref];\n                        ll highest = 0;\n                        for (int k : placedIdx) {\n                            if (X[k] < left + w && X[k] + W[k] > left) {\n                                highest = max(highest, Y[k] + H[k]);\n                            }\n                        }\n                        nx = left;\n                        ny = highest;                 // may be 0\n                    } else { // dir == 'L' (CORRECTED: uses left edge)\n                        ll top = (ref == -1) ? 0 : Y[ref] + H[ref];\n                        ll leftmost = LLONG_MAX;\n                        for (int k : placedIdx) {\n                            if (Y[k] < top + h && Y[k] + H[k] > top) {\n                                leftmost = min(leftmost, X[k]); // CORRECTED: should be X[k]\n                            }\n                        }\n                        if (leftmost == LLONG_MAX) nx = 0;\n                        else nx = max(0LL, leftmost - w);\n                        ny = top;\n                    }\n                    ll nw = max(curW, nx + w);\n                    ll nh = max(curH, ny + h);\n                    ll sc = nw + nh + penalty;\n                    cand.push_back({false, rot, dir, ref, sc, nx, ny, w, h});\n                }\n            }\n        }\n\n        // ----- choose a candidate (random among the best TOP_K) --\n        sort(cand.begin(), cand.end(),\n             [](const Candidate& a, const Candidate& b){ return a.sum < b.sum; });\n        int bestCnt = min(TOP_K, (int)cand.size());\n        int chosen = uniform_int_distribution<int>(0, bestCnt - 1)(rng);\n        const Candidate& c = cand[chosen];\n\n        // place it\n        ans.emplace_back(i, c.rot, c.dir, c.ref);\n        placed[i] = 1;\n        X[i] = c.x;  Y[i] = c.y;  W[i] = c.rw;  H[i] = c.rh;\n        placedIdx.push_back(i);\n        curW = max(curW, c.x + c.rw);\n        curH = max(curH, c.y + c.rh);\n    }\n}\n\n/* ------------------------------------------------------------- */\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> T >> sigma_)) return 0;\n    mw.resize(N);\n    mh.resize(N);\n    for (int i = 0; i < N; ++i) cin >> mw[i] >> mh[i];\n\n    for (int turn = 0; turn < T; ++turn) {\n        vector<tuple<int,int,char,int>> ans;\n        vector<char> placed;\n        build_one_placement(ans, placed);   // single run per turn\n\n        // output the placement of this turn\n        cout << ans.size() << '\\n';\n        for (auto &tp : ans) {\n            int p, r; char d; int b;\n            tie(p, r, d, b) = tp;\n            cout << p << ' ' << r << ' ' << d << ' ' << b << '\\n';\n        }\n        cout.flush();\n\n        // read the noisy measurement (not used)\n        ll Wobs, Hobs;\n        cin >> Wobs >> Hobs;\n    }\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\n#include <random>\n#include <chrono>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, H;\n    if (!(cin >> N >> M >> H)) return 0;\n    vector<int> A(N);\n    for (int i = 0; i < N; ++i) cin >> A[i];\n    vector<pair<int,int>> edges(M);\n    for (int i = 0; i < M; ++i) {\n        int u, v; cin >> u >> v;\n        edges[i] = {u, v};\n    }\n    // coordinates - not needed\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n    }\n\n    // Build adjacency\n    vector<vector<int>> adj(N);\n    for (auto [u,v] : edges) {\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n\n    // Compute depths from parent array\n    auto compute_depths = [&](const vector<int>& parent) -> vector<int> {\n        vector<int> depth(N, -1);\n        queue<int> q;\n        for (int v = 0; v < N; ++v) {\n            if (parent[v] == -1) {\n                depth[v] = 0;\n                q.push(v);\n            }\n        }\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            for (int u : adj[v]) {\n                if (parent[u] == v && depth[u] == -1) {\n                    depth[u] = depth[v] + 1;\n                    q.push(u);\n                }\n            }\n        }\n        return depth;\n    };\n\n    auto compute_score = [&](const vector<int>& parent) -> long long {\n        long long score = 0;\n        vector<int> depth = compute_depths(parent);\n        for (int v = 0; v < N; ++v) {\n            if (depth[v] == -1) continue;\n            score += (long long)(depth[v] + 1) * A[v];\n        }\n        return score;\n    };\n\n    // Build solution with different parent selection strategies\n    auto build_solution = [&](const vector<int>& order, int mode) -> pair<vector<int>, long long> {\n        vector<int> parent(N, -2);\n        vector<int> depth(N, -1);\n        \n        for (int v : order) {\n            int best_depth = -1;\n            int best_parent = -1;\n            int best_criteria = (mode == 1) ? 1000 : -1;\n            \n            for (int d = H; d >= 0; --d) {\n                if (d == 0) {\n                    best_depth = 0;\n                    best_parent = -1;\n                    break;\n                }\n                \n                for (int u : adj[v]) {\n                    if (depth[u] == d - 1) {\n                        if (mode == 0) {\n                            if (A[u] > best_criteria) {\n                                best_depth = d;\n                                best_parent = u;\n                                best_criteria = A[u];\n                            }\n                        } else if (mode == 1) {\n                            if (A[u] < best_criteria) {\n                                best_depth = d;\n                                best_parent = u;\n                                best_criteria = A[u];\n                            }\n                        } else {\n                            // mode == 2: prefer parent with more neighbors (can support more children)\n                            int criteria2 = adj[u].size();\n                            if (best_parent == -1 || criteria2 > best_criteria) {\n                                best_depth = d;\n                                best_parent = u;\n                                best_criteria = criteria2;\n                            }\n                        }\n                    }\n                }\n                if (best_depth != -1) break;\n            }\n            \n            depth[v] = best_depth;\n            parent[v] = best_parent;\n        }\n        \n        return {parent, compute_score(parent)};\n    };\n\n    vector<int> best_parent(N, -1);\n    long long best_score = -1;\n    \n    // Base orderings\n    vector<vector<int>> base_orders;\n    \n    // Order 1: by beauty descending\n    vector<int> order1(N);\n    iota(order1.begin(), order1.end(), 0);\n    sort(order1.begin(), order1.end(), [&](int a, int b) {\n        return A[a] > A[b];\n    });\n    base_orders.push_back(order1);\n    \n    // Order 2: by beauty/degree\n    vector<int> order2(N);\n    iota(order2.begin(), order2.end(), 0);\n    sort(order2.begin(), order2.end(), [&](int a, int b) {\n        double ra = (double)A[a] / adj[a].size();\n        double rb = (double)A[b] / adj[b].size();\n        return ra > rb;\n    });\n    base_orders.push_back(order2);\n    \n    // Order 3: by beauty*degree\n    vector<int> order3(N);\n    iota(order3.begin(), order3.end(), 0);\n    sort(order3.begin(), order3.end(), [&](int a, int b) {\n        long long ra = (long long)A[a] * adj[a].size();\n        long long rb = (long long)A[b] * adj[b].size();\n        return ra > rb;\n    });\n    base_orders.push_back(order3);\n    \n    // Order 4: by beauty ascending\n    vector<int> order4 = order1;\n    reverse(order4.begin(), order4.end());\n    base_orders.push_back(order4);\n    \n    // Order 5-8: various random orders\n    for (int seed_val = 0; seed_val < 4; ++seed_val) {\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        shuffle(order.begin(), order.end(), mt19937(seed_val * 1000 + 42));\n        base_orders.push_back(order);\n    }\n    \n    unsigned seed = chrono::steady_clock::now().time_since_epoch().count();\n    default_random_engine gen(seed);\n    \n    // Try different parent selection modes\n    for (int mode = 0; mode < 3; ++mode) {\n        for (const auto& base_order : base_orders) {\n            auto [parent, score] = build_solution(base_order, mode);\n            if (score > best_score) {\n                best_score = score;\n                best_parent = parent;\n            }\n            \n            for (int iter = 0; iter < 800; ++iter) {\n                vector<int> order = base_order;\n                int num_swaps = 10 + (iter % 70);\n                for (int i = 0; i < num_swaps; ++i) {\n                    int a = uniform_int_distribution<int>(0, N-1)(gen);\n                    int b = uniform_int_distribution<int>(0, N-1)(gen);\n                    swap(order[a], order[b]);\n                }\n                auto [p, s] = build_solution(order, mode);\n                if (s > best_score) {\n                    best_score = s;\n                    best_parent = p;\n                }\n            }\n        }\n    }\n    \n    // Random orders\n    for (int iter = 0; iter < 250; ++iter) {\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        shuffle(order.begin(), order.end(), gen);\n        auto [p, s] = build_solution(order, 0);\n        if (s > best_score) {\n            best_score = s;\n            best_parent = p;\n        }\n    }\n    \n    // Output\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << best_parent[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Set {\n    bool isRow;          // true \u2192 row, false \u2192 column\n    int idx;             // row number or column number\n    char dir;            // 'L','R','U','D'\n    uint64_t mask;       // bitmask of Oni indices contained in the set\n    int cost;            // number of shifts\n};\n\nint N;                                     // board size (20)\nvector<string> board;                      // input board\nint oniIdx[20][20];                        // index of Oni, -1 if none\nbool fuku[20][20];                         // true if Fukunokami\n\nint leftMostF[20], rightMostF[20];\nint topMostF[20], bottomMostF[20];\n\nvector<Set> sets;\nvector<vector<int>> oniToSets;             // for each Oni, list of set ids\n\nint M;                                     // number of Oni\nuint64_t allMask;\n\nint bestCost;\nvector<int> bestSets;\nvector<int> curSets;\nbool rowUsed[20] = {false};\nbool colUsed[20] = {false};\n\nvoid dfs(uint64_t mask, int cost) {\n    if (mask == allMask) {\n        if (cost < bestCost) {\n            bestCost = cost;\n            bestSets = curSets;\n        }\n        return;\n    }\n    if (cost >= bestCost) return;\n    int remain = __builtin_popcountll(~mask & allMask);\n    if (cost + remain >= bestCost) return; // even with 1 per oni we cannot beat\n\n    // choose uncovered Oni with smallest number of candidate sets\n    uint64_t rem = ~mask & allMask;\n    int chosenOni = -1;\n    int minOpts = 100;\n    for (uint64_t sub = rem; sub; sub &= sub - 1) {\n        int idx = __builtin_ctzll(sub);\n        int opts = 0;\n        for (int sid : oniToSets[idx]) {\n            const Set &s = sets[sid];\n            if (s.isRow && rowUsed[s.idx]) continue;\n            if (!s.isRow && colUsed[s.idx]) continue;\n            if (mask & s.mask) continue;          // already covered by chosen sets\n            ++opts;\n        }\n        if (opts == 0) return;                     // dead end (should not happen)\n        if (opts < minOpts) {\n            minOpts = opts;\n            chosenOni = idx;\n            if (minOpts == 1) break;\n        }\n    }\n    if (chosenOni == -1) return;                  // cannot cover\n\n    for (int sid : oniToSets[chosenOni]) {\n        const Set &s = sets[sid];\n        if (s.isRow && rowUsed[s.idx]) continue;\n        if (!s.isRow && colUsed[s.idx]) continue;\n        if (mask & s.mask) continue;              // overlap \u2013 already covered\n        // choose this set\n        if (s.isRow) rowUsed[s.idx] = true;\n        else         colUsed[s.idx] = true;\n        curSets.push_back(sid);\n        dfs(mask | s.mask, cost + s.cost);\n        curSets.pop_back();\n        if (s.isRow) rowUsed[s.idx] = false;\n        else         colUsed[s.idx] = false;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N;\n    board.resize(N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n\n    // locate Oni and Fukunokami, initialise arrays\n    memset(oniIdx, -1, sizeof(oniIdx));\n    memset(fuku, 0, sizeof(fuku));\n    vector<pair<int,int>> oniPos;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 'x')\n                oniIdx[i][j] = (int)oniPos.size(),\n                oniPos.emplace_back(i, j);\n            else if (board[i][j] == 'o')\n                fuku[i][j] = true;\n        }\n    M = (int)oniPos.size();                // = 2\u00b7N\n    allMask = (M == 64) ? ~0ULL : ((1ULL<<M) - 1ULL);\n\n    // left / right most Fukunokami in each row\n    const int INF = N+5;\n    for (int i = 0; i < N; ++i) {\n        leftMostF[i] = INF; rightMostF[i] = -1;\n        for (int j = 0; j < N; ++j)\n            if (fuku[i][j]) {\n                leftMostF[i] = min(leftMostF[i], j);\n                rightMostF[i] = max(rightMostF[i], j);\n            }\n    }\n    // top / bottom most Fukunokami in each column\n    for (int j = 0; j < N; ++j) {\n        topMostF[j] = INF; bottomMostF[j] = -1;\n        for (int i = 0; i < N; ++i)\n            if (fuku[i][j]) {\n                topMostF[j] = min(topMostF[j], i);\n                bottomMostF[j] = max(bottomMostF[j], i);\n            }\n    }\n\n    // build the sets\n    for (int i = 0; i < N; ++i) {\n        vector<int> idsL, idsR;\n        int maxJ = -1, minJ = INF;\n        for (int j = 0; j < N; ++j) {\n            int id = oniIdx[i][j];\n            if (id == -1) continue;\n            bool leftClear = (leftMostF[i] == INF) || (leftMostF[i] > j);\n            bool rightClear = (rightMostF[i] == -1) || (rightMostF[i] < j);\n            if (leftClear) {\n                idsL.push_back(id);\n                maxJ = max(maxJ, j);\n            }\n            if (rightClear) {\n                idsR.push_back(id);\n                minJ = min(minJ, j);\n            }\n        }\n        if (!idsL.empty()) {\n            Set s; s.isRow = true; s.idx = i; s.dir = 'L';\n            s.cost = maxJ + 1;\n            s.mask = 0;\n            for (int id : idsL) s.mask |= (1ULL<<id);\n            sets.push_back(s);\n        }\n        if (!idsR.empty()) {\n            Set s; s.isRow = true; s.idx = i; s.dir = 'R';\n            s.cost = N - minJ;\n            s.mask = 0;\n            for (int id : idsR) s.mask |= (1ULL<<id);\n            sets.push_back(s);\n        }\n    }\n    for (int j = 0; j < N; ++j) {\n        vector<int> idsU, idsD;\n        int maxI = -1, minI = INF;\n        for (int i = 0; i < N; ++i) {\n            int id = oniIdx[i][j];\n            if (id == -1) continue;\n            bool upClear   = (topMostF[j] == INF) || (topMostF[j] > i);\n            bool downClear = (bottomMostF[j] == -1) || (bottomMostF[j] < i);\n            if (upClear) {\n                idsU.push_back(id);\n                maxI = max(maxI, i);\n            }\n            if (downClear) {\n                idsD.push_back(id);\n                minI = min(minI, i);\n            }\n        }\n        if (!idsU.empty()) {\n            Set s; s.isRow = false; s.idx = j; s.dir = 'U';\n            s.cost = maxI + 1;\n            s.mask = 0;\n            for (int id : idsU) s.mask |= (1ULL<<id);\n            sets.push_back(s);\n        }\n        if (!idsD.empty()) {\n            Set s; s.isRow = false; s.idx = j; s.dir = 'D';\n            s.cost = N - minI;\n            s.mask = 0;\n            for (int id : idsD) s.mask |= (1ULL<<id);\n            sets.push_back(s);\n        }\n    }\n\n    // mapping Oni -> sets\n    oniToSets.assign(M, {});\n    for (int sid = 0; sid < (int)sets.size(); ++sid) {\n        uint64_t m = sets[sid].mask;\n        while (m) {\n            int b = __builtin_ctzll(m);\n            oniToSets[b].push_back(sid);\n            m &= m-1;\n        }\n    }\n    // sort by cost (ascending) \u2013 helps the search\n    for (auto &vec : oniToSets) {\n        sort(vec.begin(), vec.end(),\n             [&](int a, int b){ return sets[a].cost < sets[b].cost; });\n    }\n\n    // upper bound = sum of individual minima (one\u2011by\u2011one removal)\n    int upper = 0;\n    for (int id = 0; id < M; ++id) {\n        int i = oniPos[id].first;\n        int j = oniPos[id].second;\n        int best = N+5;\n        bool leftClear = (leftMostF[i] == INF) || (leftMostF[i] > j);\n        bool rightClear= (rightMostF[i]==-1) || (rightMostF[i] < j);\n        bool upClear   = (topMostF[j] == INF) || (topMostF[j] > i);\n        bool downClear = (bottomMostF[j]==-1)|| (bottomMostF[j] < i);\n        if (leftClear)  best = min(best, j+1);\n        if (rightClear) best = min(best, N-j);\n        if (upClear)    best = min(best, i+1);\n        if (downClear)  best = min(best, N-i);\n        upper += best;\n    }\n    bestCost = upper;\n    // start search\n    dfs(0ULL, 0);\n\n    // produce output \u2013 column sets first, then row sets\n    vector<int> colSetIds, rowSetIds;\n    for (int sid : bestSets) {\n        if (!sets[sid].isRow) colSetIds.push_back(sid);\n        else                  rowSetIds.push_back(sid);\n    }\n\n    // output moves\n    ostringstream out;\n    for (int sid : colSetIds) {\n        const Set &s = sets[sid];\n        for (int k = 0; k < s.cost; ++k)\n            out << s.dir << ' ' << s.idx << '\\n';\n    }\n    for (int sid : rowSetIds) {\n        const Set &s = sets[sid];\n        for (int k = 0; k < s.cost; ++k)\n            out << s.dir << ' ' << s.idx << '\\n';\n    }\n    cout << out.str();\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    long long L;\n    if (!(cin >> N >> L)) return 0;\n    vector<int> T(N);\n    for (int i = 0; i < N; ++i) cin >> T[i];\n\n    // -------- adjust T[0] = 0  (error 2 is optimal) ----------\n    vector<int> t = T;\n    if (t[0] == 0) {\n        int j = -1;\n        for (int i = 1; i < N; ++i) if (t[i] > 0) { j = i; break; }\n        // there must be such j because sum = L > 0\n        t[0] = 1;\n        t[j]--;\n    }\n\n    // ----- pre\u2011compute how many odd / even edges each vertex has -----\n    vector<int> oddWeight(N), evenWeight(N);\n    for (int i = 0; i < N; ++i) {\n        oddWeight[i]  = (t[i] + 1) / 2;          // ceil\n        evenWeight[i] = t[i] / 2;                // floor\n    }\n\n    // ----- data for the walk construction -----\n    vector<int> need = t;                       // remaining indegrees\n    vector<int> vis(N, 0);                       // how many times a vertex has been visited\n    vector<int> a(N, -1), b(N, -1);              // targets, -1 = not fixed yet\n    vector<int> usedOdd(N, 0), usedEven(N, 0);   // how many edges of each kind have already been used\n\n    int cur = 0;\n    vis[0] = 1;\n    need[0]--;                                   // first week\n\n    for (long long week = 2; week <= L; ++week) {\n        // decide which kind of edge is needed now\n        bool odd = (vis[cur] % 2 == 1);          // after vis[cur] visits, parity is odd \u2192 need odd edge\n        if (odd) {\n            if (a[cur] == -1) {\n                // choose a target with enough remaining capacity\n                int target = -1;\n                for (int i = 0; i < N; ++i) {\n                    if (need[i] >= oddWeight[cur]) {\n                        target = i;\n                        break;\n                    }\n                }\n                // target must exist\n                a[cur] = target;\n            }\n            cur = a[cur];\n        } else {\n            if (b[cur] == -1) {\n                int target = -1;\n                for (int i = 0; i < N; ++i) {\n                    if (need[i] >= evenWeight[cur]) {\n                        target = i;\n                        break;\n                    }\n                }\n                b[cur] = target;\n            }\n            cur = b[cur];\n        }\n        ++vis[cur];\n        --need[cur];\n    }\n\n    // set default values for edges that never had to be fixed\n    for (int i = 0; i < N; ++i) {\n        if (a[i] == -1) a[i] = i;   // never used odd edge \u2192 self loop\n        if (b[i] == -1) b[i] = i;   // never used even edge \u2192 self loop\n    }\n\n    // --------------- output --------------------\n    for (int i = 0; i < N; ++i) {\n        cout << a[i] << ' ' << b[i] << \"\\n\";\n    }\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v;\n    int approx;\n};\n\nint N, M, Q, L, W;\nvector<int> G;\nvector<int> lx, rx, ly, ry;\nvector<int> cx, cy;\nvector<vector<int>> approxDist;\n\nvector<vector<Edge>> candEdges;\n\nvoid query(const vector<int>& nodes, int gid) {\n    int sz = (int)nodes.size();\n    cout << \"? \" << sz;\n    for (int v : nodes) cout << ' ' << v;\n    cout << \"\\n\";\n    cout.flush();\n\n    for (int i = 0; i < sz - 1; ++i) {\n        int a, b;\n        cin >> a >> b;\n        Edge e{a, b, approxDist[a][b]};\n        candEdges[gid].push_back(e);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    lx.resize(N); rx.resize(N); ly.resize(N); ry.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n    }\n\n    cx.resize(N); cy.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cx[i] = (lx[i] + rx[i]) / 2;\n        cy[i] = (ly[i] + ry[i]) / 2;\n    }\n\n    // Center-based distance matrix\n    approxDist.assign(N, vector<int>(N, 0));\n    for (int i = 0; i < N; ++i) {\n        for (int j = i + 1; j < N; ++j) {\n            long long dx = (long long)cx[i] - cx[j];\n            long long dy = (long long)cy[i] - cy[j];\n            int d = (int)floor(sqrt((double)dx * dx + (double)dy * dy) + 1e-9);\n            approxDist[i][j] = approxDist[j][i] = d;\n        }\n    }\n\n    // Group by center - try sorting by (x+y) for better locality\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(),\n         [&](int a, int b) {\n             long long sa = (long long)cx[a] + cy[a];\n             long long sb = (long long)cx[b] + cy[b];\n             if (sa != sb) return sa < sb;\n             return cx[a] < cx[b];\n         });\n\n    vector<vector<int>> groups(M);\n    int pos = 0;\n    for (int g = 0; g < M; ++g) {\n        groups[g].reserve(G[g]);\n        for (int i = 0; i < G[g]; ++i) groups[g].push_back(order[pos++]);\n    }\n\n    candEdges.assign(M, {});\n    int used = 0;\n\n    // Baseline queries - sliding window\n    for (int gid = 0; gid < M; ++gid) {\n        int sz = (int)groups[gid].size();\n        if (sz <= 1) continue;\n        if (sz == 2) continue;\n        if (sz <= L) {\n            query(groups[gid], gid);\n            ++used;\n        } else {\n            int i = 0;\n            while (i + L <= sz) {\n                vector<int> sub(L);\n                for (int j = 0; j < L; ++j) sub[j] = groups[gid][i + j];\n                query(sub, gid);\n                ++used;\n                i += L - 1;\n            }\n            if (i < sz - 1) {\n                int rem = sz - i;\n                vector<int> sub(rem);\n                for (int j = 0; j < rem; ++j) sub[j] = groups[gid][i + j];\n                query(sub, gid);\n                ++used;\n            }\n        }\n    }\n\n    // Extra queries - closest cities selection\n    int leftover = Q - used;\n    \n    vector<pair<long long, int>> groupPriority;\n    for (int gid = 0; gid < M; ++gid) {\n        int sz = (int)groups[gid].size();\n        if (sz >= 3) {\n            long long potential = 1LL * sz * sz;\n            groupPriority.emplace_back(potential, gid);\n        }\n    }\n    sort(groupPriority.rbegin(), groupPriority.rend());\n    \n    std::mt19937 rng(111111);\n    int idx = 0;\n    while (leftover > 0 && !groupPriority.empty()) {\n        int gid = groupPriority[idx % groupPriority.size()].second;\n        int gsz = (int)groups[gid].size();\n        int qsz = min(L, gsz);\n        \n        // Pick random start, then closest cities\n        int start = uniform_int_distribution<int>(0, gsz - 1)(rng);\n        vector<int> candidates;\n        candidates.push_back(groups[gid][start]);\n        \n        vector<pair<int, int>> dists;\n        for (int i = 0; i < gsz; ++i) {\n            if (i == start) continue;\n            dists.emplace_back(approxDist[groups[gid][start]][groups[gid][i]], i);\n        }\n        sort(dists.begin(), dists.end());\n        for (int i = 0; i < qsz - 1 && i < (int)dists.size(); ++i) {\n            candidates.push_back(groups[gid][dists[i].second]);\n        }\n        \n        while ((int)candidates.size() < qsz) {\n            int r = uniform_int_distribution<int>(0, gsz - 1)(rng);\n            int city = groups[gid][r];\n            if (find(candidates.begin(), candidates.end(), city) == candidates.end()) {\n                candidates.push_back(city);\n            }\n        }\n        \n        shuffle(candidates.begin(), candidates.end(), rng);\n        vector<int> sub(candidates.begin(), candidates.begin() + qsz);\n        \n        query(sub, gid);\n        ++used;\n        --leftover;\n        ++idx;\n    }\n\n    // Build final trees\n    vector<vector<pair<int,int>>> answerEdges(M);\n\n    for (int gid = 0; gid < M; ++gid) {\n        int sz = (int)groups[gid].size();\n        if (sz <= 1) continue;\n        if (sz == 2) {\n            answerEdges[gid].push_back({groups[gid][0], groups[gid][1]});\n            continue;\n        }\n\n        auto &edges = candEdges[gid];\n        if (edges.empty()) {\n            for (int i = 0; i < sz - 1; ++i) {\n                answerEdges[gid].push_back({groups[gid][i], groups[gid][i+1]});\n            }\n            continue;\n        }\n\n        // Sort by approx distance\n        sort(edges.begin(), edges.end(),\n             [&](const Edge& a, const Edge& b) {\n                 if (a.approx != b.approx) return a.approx < b.approx;\n                 return a.u < b.u || (a.u == b.u && a.v < b.v);\n             });\n\n        // Kruskal\n        vector<int> localId(N, -1);\n        for (int i = 0; i < sz; ++i) localId[groups[gid][i]] = i;\n\n        vector<int> parent(sz), rankv(sz, 0);\n        iota(parent.begin(), parent.end(), 0);\n        function<int(int)> find = [&](int x) {\n            while (parent[x] != x) {\n                parent[x] = parent[parent[x]];\n                x = parent[x];\n            }\n            return x;\n        };\n        auto unite = [&](int a, int b) -> bool {\n            a = find(a); b = find(b);\n            if (a == b) return false;\n            if (rankv[a] < rankv[b]) swap(a, b);\n            parent[b] = a;\n            if (rankv[a] == rankv[b]) ++rankv[a];\n            return true;\n        };\n\n        for (const Edge& e : edges) {\n            int u = localId[e.u];\n            int v = localId[e.v];\n            if (unite(u, v)) {\n                answerEdges[gid].push_back({e.u, e.v});\n                if ((int)answerEdges[gid].size() == sz - 1) break;\n            }\n        }\n    }\n\n    cout << \"!\\n\";\n    for (int gid = 0; gid < M; ++gid) {\n        for (size_t i = 0; i < groups[gid].size(); ++i) {\n            if (i) cout << ' ';\n            cout << groups[gid][i];\n        }\n        cout << \"\\n\";\n        for (auto &e : answerEdges[gid]) {\n            cout << e.first << ' ' << e.second << \"\\n\";\n        }\n    }\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* --------------------------------------------------------------- */\n/*  constants                                                       */\nconstexpr int MAX_N = 20;\nconstexpr int MAX_POS = MAX_N * MAX_N;          // 400\nconstexpr int NUM_BLOCKS = MAX_POS + 1;         // 401\nconstexpr int NO_BLOCK = MAX_POS;               // 400 -> means \u201cno block\u201d\nconstexpr int TOTAL_STATES = MAX_POS * NUM_BLOCKS;\nconstexpr int INF = 1e9;\nconstexpr int K = 2;                            // keep K best blocks per target\n\nint N = MAX_N;\nint M;\n\n/* --------------------------------------------------------------- */\n/*  directions                                                     */\nint dr[4] = {-1, 1, 0, 0};\nint dc[4] = {0, 0, -1, 1};\nchar dirChar[4] = {'U','D','L','R'};\n\ninline int posIdx(int r, int c) { return r * N + c; }\ninline int encodeState(int pos, int block) { return pos * NUM_BLOCKS + block; }\n\n/* --------------------------------------------------------------- */\n/*  BFS that returns shortest distances to all possible blocks   */\nvoid bfs_distance(int sr, int sc, int blockIdx,\n                  int tr, int tc,\n                  vector<int> &distBlock)\n{\n    fill(distBlock.begin(), distBlock.end(), INF);\n    int startPos = sr * N + sc;\n    int targetPos = tr * N + tc;\n    int startState = encodeState(startPos, blockIdx);\n\n    static vector<int> d;\n    d.assign(TOTAL_STATES, -1);\n    queue<int> q;\n    d[startState] = 0;\n    q.push(startState);\n\n    while (!q.empty()) {\n        int cur = q.front(); q.pop();\n\n        int pos = cur / NUM_BLOCKS;\n        int block = cur % NUM_BLOCKS;\n        int curDist = d[cur];\n\n        if (pos == targetPos && block != targetPos) {\n            if (distBlock[block] > curDist)\n                distBlock[block] = curDist;\n        }\n\n        int r = pos / N;\n        int c = pos % N;\n\n        /* ---- Move ------------------------------------------------*/\n        for (int dirc = 0; dirc < 4; ++dirc) {\n            int nr = r + dr[dirc];\n            int nc = c + dc[dirc];\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n            int nPos = nr * N + nc;\n            if (block != NO_BLOCK && nPos == block) continue; // blocked\n            int ns = encodeState(nPos, block);\n            if (d[ns] == -1) {\n                d[ns] = curDist + 1;\n                q.push(ns);\n            }\n        }\n\n        /* ---- Slide ----------------------------------------------*/\n        for (int dirc = 0; dirc < 4; ++dirc) {\n            int rr = r, cc = c;\n            while (true) {\n                int nr = rr + dr[dirc];\n                int nc = cc + dc[dirc];\n                if (nr < 0 || nr >= N || nc < 0 || nc >= N) break;\n                int nPos = nr * N + nc;\n                if (block != NO_BLOCK && nPos == block) break;\n                rr = nr; cc = nc;\n            }\n            int destPos = rr * N + cc;\n            int ns = encodeState(destPos, block);\n            if (d[ns] == -1) {\n                d[ns] = curDist + 1;\n                q.push(ns);\n            }\n        }\n\n        /* ---- Alter (place / remove block) ------------------------*/\n        for (int dirc = 0; dirc < 4; ++dirc) {\n            int nr = r + dr[dirc];\n            int nc = c + dc[dirc];\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n            int neighPos = nr * N + nc;\n            int newBlock;\n            if (block == NO_BLOCK) {\n                newBlock = neighPos;                 // place\n            } else if (block == neighPos) {\n                newBlock = NO_BLOCK;                 // remove\n            } else {\n                continue;                             // a block elsewhere\n            }\n            int ns = encodeState(pos, newBlock);\n            if (d[ns] == -1) {\n                d[ns] = curDist + 1;\n                q.push(ns);\n            }\n        }\n    }\n}\n\n/* --------------------------------------------------------------- */\n/*  BFS that also stores parent / action, stops when target is reached */\nvector<pair<char,char>> bfs_reconstruct(int sr, int sc, int blockIdx,\n                                        int tr, int tc, int targetBlock)\n{\n    vector<pair<char,char>> actions;\n    int startPos = sr * N + sc;\n    int targetPos = tr * N + tc;\n    if (startPos == targetPos && blockIdx != targetBlock) {\n        return actions;                     // empty\n    }\n    int startState = encodeState(startPos, blockIdx);\n    int targetState = encodeState(targetPos, targetBlock);\n\n    static vector<int> d;\n    static vector<int> parent;\n    static vector<pair<char,char>> act;\n    d.assign(TOTAL_STATES, -1);\n    parent.assign(TOTAL_STATES, -1);\n    act.assign(TOTAL_STATES, {'?', '?'});\n\n    queue<int> q;\n    d[startState] = 0;\n    q.push(startState);\n\n    while (!q.empty()) {\n        int cur = q.front(); q.pop();\n        if (cur == targetState) break;\n\n        int pos = cur / NUM_BLOCKS;\n        int block = cur % NUM_BLOCKS;\n        int r = pos / N;\n        int c = pos % N;\n\n        /* ---- Move ------------------------------------------------*/\n        for (int dirc = 0; dirc < 4; ++dirc) {\n            int nr = r + dr[dirc];\n            int nc = c + dc[dirc];\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n            int nPos = nr * N + nc;\n            if (block != NO_BLOCK && nPos == block) continue;\n            int ns = encodeState(nPos, block);\n            if (d[ns] == -1) {\n                d[ns] = d[cur] + 1;\n                parent[ns] = cur;\n                act[ns] = {'M', dirChar[dirc]};\n                q.push(ns);\n            }\n        }\n\n        /* ---- Slide ----------------------------------------------*/\n        for (int dirc = 0; dirc < 4; ++dirc) {\n            int rr = r, cc = c;\n            while (true) {\n                int nr = rr + dr[dirc];\n                int nc = cc + dc[dirc];\n                if (nr < 0 || nr >= N || nc < 0 || nc >= N) break;\n                int nPos = nr * N + nc;\n                if (block != NO_BLOCK && nPos == block) break;\n                rr = nr; cc = nc;\n            }\n            int destPos = rr * N + cc;\n            int ns = encodeState(destPos, block);\n            if (d[ns] == -1) {\n                d[ns] = d[cur] + 1;\n                parent[ns] = cur;\n                act[ns] = {'S', dirChar[dirc]};\n                q.push(ns);\n            }\n        }\n\n        /* ---- Alter ----------------------------------------------*/\n        for (int dirc = 0; dirc < 4; ++dirc) {\n            int nr = r + dr[dirc];\n            int nc = c + dc[dirc];\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n            int neighPos = nr * N + nc;\n            int newBlock;\n            if (block == NO_BLOCK) {\n                newBlock = neighPos;\n            } else if (block == neighPos) {\n                newBlock = NO_BLOCK;\n            } else {\n                continue;\n            }\n            int ns = encodeState(pos, newBlock);\n            if (d[ns] == -1) {\n                d[ns] = d[cur] + 1;\n                parent[ns] = cur;\n                act[ns] = {'A', dirChar[dirc]};\n                q.push(ns);\n            }\n        }\n    }\n\n    // reconstruct path\n    int cur = targetState;\n    while (parent[cur] != -1) {\n        actions.push_back(act[cur]);\n        cur = parent[cur];\n    }\n    reverse(actions.begin(), actions.end());\n    return actions;\n}\n\n/* --------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N >> M;               // N = 20 , M = 40\n    vector<pair<int,int>> pt(M + 1);\n    for (int i = 0; i <= M; ++i) cin >> pt[i].first >> pt[i].second;\n\n    /* ---------- DP tables --------------------------------------- */\n    vector<array<int, NUM_BLOCKS>> dp(M + 1);\n    vector<array<int, NUM_BLOCKS>> prevBlock(M + 1);\n    for (int i = 0; i <= M; ++i) {\n        dp[i].fill(INF);\n        prevBlock[i].fill(-1);\n    }\n\n    vector<int> distBlock(NUM_BLOCKS);\n\n    /* ---------- segment 1: start -> target 1 -------------------- */\n    bfs_distance(pt[0].first, pt[0].second, NO_BLOCK,\n                 pt[1].first, pt[1].second, distBlock);\n    int target1Pos = posIdx(pt[1].first, pt[1].second);\n    for (int b = 0; b < NUM_BLOCKS; ++b) {\n        if (b == target1Pos) continue;\n        if (distBlock[b] < INF) {\n            dp[1][b] = distBlock[b];\n            prevBlock[1][b] = -1;\n        }\n    }\n\n    /* ---------- helper: keep best K blocks ---------------------- */\n    auto getBestBlocks = [&](int idx) -> vector<int> {\n        vector<pair<int,int>> cand;\n        for (int b = 0; b < NUM_BLOCKS; ++b) {\n            if (dp[idx][b] < INF) cand.emplace_back(b, dp[idx][b]);\n        }\n        sort(cand.begin(), cand.end(),\n             [](const auto& a, const auto& b){ return a.second < b.second; });\n        vector<int> res;\n        for (int i = 0; i < min((int)cand.size(), K); ++i)\n            res.push_back(cand[i].first);\n        return res;\n    };\n\n    vector<vector<int>> bestBlocks(M + 1);\n    bestBlocks[1] = getBestBlocks(1);\n\n    /* ---------- segments 2 .. M -------------------------------- */\n    for (int i = 2; i <= M; ++i) {\n        dp[i].fill(INF);\n        prevBlock[i].fill(-1);\n\n        for (int startBlock : bestBlocks[i-1]) {\n            bfs_distance(pt[i-1].first, pt[i-1].second, startBlock,\n                         pt[i].first, pt[i].second, distBlock);\n            int targetPos = posIdx(pt[i].first, pt[i].second);\n            for (int b = 0; b < NUM_BLOCKS; ++b) {\n                if (b == targetPos) continue;\n                if (distBlock[b] >= INF) continue;\n                int newDist = dp[i-1][startBlock] + distBlock[b];\n                if (newDist < dp[i][b]) {\n                    dp[i][b] = newDist;\n                    prevBlock[i][b] = startBlock;\n                }\n            }\n        }\n        bestBlocks[i] = getBestBlocks(i);\n    }\n\n    /* ---------- find best final block --------------------------- */\n    int bestBlock = -1, bestDist = INF;\n    for (int b = 0; b < NUM_BLOCKS; ++b) {\n        if (b == posIdx(pt[M].first, pt[M].second)) continue;\n        if (dp[M][b] < bestDist) {\n            bestDist = dp[M][b];\n            bestBlock = b;\n        }\n    }\n\n    /* ---------- reconstruct the path ----------------------------- */\n    vector<int> blockAfter(M + 1);\n    int curB = bestBlock;\n    for (int i = M; i >= 1; --i) {\n        blockAfter[i] = curB;\n        curB = prevBlock[i][curB];\n    }\n\n    /* ---------- generate actions -------------------------------- */\n    vector<string> answer;\n    int curR = pt[0].first, curC = pt[0].second;\n    int curBlock = NO_BLOCK;\n\n    for (int i = 1; i <= M; ++i) {\n        int tr = pt[i].first, tc = pt[i].second;\n        int finalBlock = blockAfter[i];\n        vector<pair<char,char>> seq = bfs_reconstruct(curR, curC, curBlock,\n                                                       tr, tc, finalBlock);\n        for (auto &p : seq) {\n            string line;\n            line.push_back(p.first);\n            line.push_back(' ');\n            line.push_back(p.second);\n            answer.emplace_back(line);\n        }\n        curR = tr; curC = tc;\n        curBlock = finalBlock;\n    }\n\n    if ((int)answer.size() > 2 * N * M) {\n        cerr << \"Too many actions!\\n\";\n    }\n\n    for (auto &ln : answer) cout << ln << '\\n';\n    return 0;\n}"}}}