{"model_name":"kimi-k2-thinking","codes":{"1":{"ahc001":"","ahc002":"","ahc003":"","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 20;                 // matrix size (fixed in the task)\nconstexpr int MAXLEN = 12;            // maximal string length\nconstexpr int ALPH = 8;               // letters A .. H\n\n/* ---------- placement of one string ---------- */\nstruct Placement {\n    uint16_t cell[MAXLEN];   // indices of the cells (0 \u2026 N*N-1)\n    uint8_t  let[MAXLEN];    // required letters (0 \u2026 7)\n    uint8_t  len;            // length of the string ( \u2264 12 )\n};\n\n/* ---------- global data for one test case ---------- */\nvector<vector<int>> strLetters;                 // letters of each unique string\nvector<vector<Placement>> placements;           // all placements of each string\n\n/* ---------- current working solution ---------- */\narray<int, N * N> curLetter;        // -1 = empty, 0..7 = letter\narray<int, N * N> curUse;           // how many placements occupy the cell\nint curUsedCells;                    // #cells with curUse > 0\nvector<int> curIdx;                  // for each string: index of used placement, -1 = none\n\n/* ---------- auxiliary ---------- */\ninline int cellId(int r, int c) { return r * N + c; }\n\n/* check whether placement p can be put into the current grid */\ninline bool canPlace(const Placement& p) {\n    for (int i = 0; i < p.len; ++i) {\n        int c = p.cell[i];\n        if (curUse[c] > 0 && curLetter[c] != (int)p.let[i]) return false;\n    }\n    return true;\n}\n\n/* cost of a placement = number of empty cells it would occupy */\ninline int placeCost(const Placement& p) {\n    int cost = 0;\n    for (int i = 0; i < p.len; ++i)\n        if (curUse[p.cell[i]] == 0) ++cost;\n    return cost;\n}\n\n/* put a placement into the grid */\ninline void place(const Placement& p) {\n    for (int i = 0; i < p.len; ++i) {\n        int c = p.cell[i];\n        if (curUse[c] == 0) {\n            curLetter[c] = p.let[i];\n            ++curUsedCells;\n        }\n        ++curUse[c];\n    }\n}\n\n/* remove a placement from the grid */\ninline void unplace(const Placement& p) {\n    for (int i = 0; i < p.len; ++i) {\n        int c = p.cell[i];\n        --curUse[c];\n        if (curUse[c] == 0) {\n            curLetter[c] = -1;\n            --curUsedCells;\n        }\n    }\n}\n\n/* test whether a given string (index s) is already a subsequence of the grid */\nbool isPresent(int s) {\n    for (const Placement& p : placements[s]) {\n        bool ok = true;\n        for (int i = 0; i < p.len; ++i) {\n            int c = p.cell[i];\n            if (curLetter[c] != (int)p.let[i]) { ok = false; break; }\n        }\n        if (ok) return true;\n    }\n    return false;\n}\n\n/* --------------------------------------------------------------- */\n/* ---------- main solving routine ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int Ninput, Minput;\n    if (!(cin >> Ninput >> Minput)) return 0;\n\n    vector<string> allStr(Minput);\n    for (int i = 0; i < Minput; ++i) cin >> allStr[i];\n\n    /* ---- delete duplicates ---- */\n    unordered_map<string, int> seen;\n    vector<string> uniqStr;\n    for (const string& x : allStr) {\n        if (seen.find(x) == seen.end()) {\n            seen[x] = 1;\n            uniqStr.push_back(x);\n        }\n    }\n    int M = (int)uniqStr.size();            // number of different strings\n\n    /* ---- convert strings to integers ---- */\n    strLetters.resize(M);\n    for (int i = 0; i < M; ++i) {\n        for (char ch : uniqStr[i])\n            strLetters[i].push_back(ch - 'A');\n    }\n\n    /* ---- pre\u2011compute all placements ---- */\n    placements.assign(M, {});\n    for (int sid = 0; sid < M; ++sid) {\n        const vector<int>& L = strLetters[sid];\n        int len = (int)L.size();\n        // horizontal\n        for (int row = 0; row < N; ++row) {\n            for (int startCol = 0; startCol < N; ++startCol) {\n                Placement p;\n                p.len = (uint8_t)len;\n                for (int off = 0; off < len; ++off) {\n                    int col = (startCol + off) % N;\n                    p.cell[off] = (uint16_t)cellId(row, col);\n                    p.let[off] = (uint8_t)L[off];\n                }\n                placements[sid].push_back(p);\n            }\n        }\n        // vertical\n        for (int col = 0; col < N; ++col) {\n            for (int startRow = 0; startRow < N; ++startRow) {\n                Placement p;\n                p.len = (uint8_t)len;\n                for (int off = 0; off < len; ++off) {\n                    int row = (startRow + off) % N;\n                    p.cell[off] = (uint16_t)cellId(row, col);\n                    p.let[off] = (uint8_t)L[off];\n                }\n                placements[sid].push_back(p);\n            }\n        }\n    }\n\n    /* ---------- containers for the best solution found ---------- */\n    array<int, N * N> bestLetter;\n    int bestUsed = INT_MAX;\n    int bestPlaced = -1;\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    const double TIME_LIMIT = 2.8;                 // seconds\n    auto start = chrono::steady_clock::now();\n\n    /* ---------- phase 1 : many greedy restarts ---------- */\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > 0.60 * TIME_LIMIT) break;    // 60 % of time\n\n        /* ---- initialise empty grid ---- */\n        curLetter.fill(-1);\n        curUse.fill(0);\n        curUsedCells = 0;\n        curIdx.assign(M, -1);\n\n        // random order of strings\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        shuffle(order.begin(), order.end(), rng);\n\n        int placed = 0;\n\n        for (int sid : order) {\n            const vector<Placement>& cand = placements[sid];\n            int bestCost = INT_MAX;\n            vector<int> bestIdx;               // placement indices with that cost\n            for (int pid = 0; pid < (int)cand.size(); ++pid) {\n                const Placement& p = cand[pid];\n                if (!canPlace(p)) continue;\n                int c = placeCost(p);\n                if (c < bestCost) {\n                    bestCost = c;\n                    bestIdx.clear();\n                    bestIdx.push_back(pid);\n                } else if (c == bestCost) {\n                    bestIdx.push_back(pid);\n                }\n            }\n            if (bestIdx.empty()) continue;     // cannot place this string now\n            int chosen = bestIdx[uniform_int_distribution<int>(0, (int)bestIdx.size() - 1)(rng)];\n            place(cand[chosen]);\n            curIdx[sid] = chosen;\n            ++placed;\n        }\n\n        /* ---- try to delete redundant strings ---- */\n        if (placed == M) {\n            vector<int> perm = order;                     // reuse any permutation\n            shuffle(perm.begin(), perm.end(), rng);\n            for (int sid : perm) {\n                if (curIdx[sid] == -1) continue;\n                const Placement& p = placements[sid][curIdx[sid]];\n                unplace(p);                               // remove it\n                if (isPresent(sid)) {\n                    curIdx[sid] = -1;                     // keep removed\n                } else {\n                    place(p);                             // put it back\n                }\n            }\n        }\n\n        /* ---- evaluate this solution ---- */\n        if (placed > bestPlaced ||\n            (placed == bestPlaced && curUsedCells < bestUsed)) {\n            bestPlaced = placed;\n            bestUsed   = curUsedCells;\n            bestLetter = curLetter;                       // copy the whole grid (400 ints)\n        }\n    }   // end of restarts\n\n    /* ---- nothing found ? output empty matrix (worst case) ---- */\n    if (bestPlaced == -1) {\n        for (int i = 0; i < N; ++i) {\n            cout << string(N, '.') << '\\n';\n        }\n        return 0;\n    }\n\n    // reload the best solution into the working arrays (needed for the optional hill climbing)\n    curLetter = bestLetter;\n    curUse.fill(0);\n    curUsedCells = 0;\n    for (int i = 0; i < N * N; ++i)\n        if (curLetter[i] != -1) {\n            curUse[i] = 1;\n            ++curUsedCells;\n        }\n    // we do not know the exact placement indices any more \u2013 they are not needed for output\n\n    /* ---------- phase 2 : simple hill climbing (use remaining time) ---------- */\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > TIME_LIMIT - 0.05) break;   // stop a bit before the limit\n\n        // pick a random string that is currently placed\n        int sid = uniform_int_distribution<int>(0, M - 1)(rng);\n        if (curIdx[sid] == -1) continue;          // was removed as redundant \u2013 skip\n        const Placement& oldPl = placements[sid][curIdx[sid]];\n\n        // pick a random different placement\n        const vector<Placement>& cand = placements[sid];\n        int pid = uniform_int_distribution<int>(0, (int)cand.size() - 1)(rng);\n        if (pid == curIdx[sid]) continue;\n        const Placement& newPl = cand[pid];\n        if (!canPlace(newPl)) continue;           // would conflict with fixed letters\n\n        // compute \u0394 = newCellsUsed - cellsFreed\n        int freed = 0;\n        for (int i = 0; i < oldPl.len; ++i) {\n            int c = oldPl.cell[i];\n            if (curUse[c] == 1) {\n                bool inNew = false;\n                for (int j = 0; j < newPl.len; ++j)\n                    if (newPl.cell[j] == c) { inNew = true; break; }\n                if (!inNew) ++freed;\n            }\n        }\n        int newlyUsed = 0;\n        for (int i = 0; i < newPl.len; ++i) {\n            int c = newPl.cell[i];\n            if (curUse[c] == 0) {\n                bool inOld = false;\n                for (int j = 0; j < oldPl.len; ++j)\n                    if (oldPl.cell[j] == c) { inOld = true; break; }\n                if (!inOld) ++newlyUsed;\n            }\n        }\n        int delta = newlyUsed - freed;\n        if (delta < 0) {                         // strict improvement\n            // really perform the move\n            unplace(oldPl);\n            place(newPl);\n            curIdx[sid] = pid;\n            if (curUsedCells < bestUsed) {\n                bestUsed = curUsedCells;\n                bestLetter = curLetter;\n            }\n        }\n    }\n\n    /* ---------- output the best matrix ---------- */\n    for (int r = 0; r < N; ++r) {\n        string line;\n        for (int c = 0; c < N; ++c) {\n            int cell = cellId(r, c);\n            if (bestLetter[cell] == -1) line += '.';\n            else                       line += char('A' + bestLetter[cell]);\n        }\n        cout << line << '\\n';\n    }\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXV = 5005;                 // maximal number of cells (N\u226469 \u2192 < 5000)\n\nstruct Edge {\n    int u, v, w;\n    bool operator<(Edge const& other) const { return w < other.w; }\n};\n\nstruct DSU {\n    vector<int> p, r;\n    DSU(int n = 0) { init(n); }\n    void init(int n) { p.resize(n); r.assign(n,0); iota(p.begin(),p.end(),0); }\n    int find(int x){ return p[x]==x?x:p[x]=find(p[x]); }\n    bool unite(int a,int b){\n        a=find(a); b=find(b);\n        if(a==b) return false;\n        if(r[a]<r[b]) swap(a,b);\n        p[b]=a;\n        if(r[a]==r[b]) ++r[a];\n        return true;\n    }\n};\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    // --- 1. give an id to every road cell, store its weight and coordinates ----------\n    vector<vector<int>> id(N, vector<int>(N,-1));\n    vector<int> weight; weight.reserve(N*N);\n    vector<int> iOf, jOf; iOf.reserve(N*N); jOf.reserve(N*N);\n    int V = 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] = V++;\n                weight.push_back(g[i][j]-'0');\n                iOf.push_back(i);\n                jOf.push_back(j);\n            }\n        }\n    }\n    const int startIdx = id[si][sj];\n\n    // --- 2. row and column segment ids ------------------------------------------------\n    vector<int> rowId(V,-1), colId(V,-1);\n    int rowSegCnt = 0;\n    for(int i=0;i<N;++i){\n        int cur = -1;\n        for(int j=0;j<N;++j){\n            if(g[i][j]!='#'){\n                if(j==0 || g[i][j-1]=='#') cur = rowSegCnt++;\n                rowId[id[i][j]] = cur;\n            }\n        }\n    }\n    int colSegCnt = 0;\n    for(int j=0;j<N;++j){\n        int cur = -1;\n        for(int i=0;i<N;++i){\n            if(g[i][j]!='#'){\n                if(i==0 || g[i-1][j]=='#') cur = colSegCnt++;\n                colId[id[i][j]] = cur;\n            }\n        }\n    }\n\n    // decide which side to cover\n    bool useRow = rowSegCnt <= colSegCnt;\n    vector<int> segId = useRow ? rowId : colId;\n    int segCnt = useRow ? rowSegCnt : colSegCnt;\n\n    // --- 3. build edge list (only right / down, undirected) ----------------------------\n    vector<Edge> edges;\n    edges.reserve(4*V);\n    const int di[4] = {-1,1,0,0};\n    const int dj[4] = {0,0,-1,1};\n    for(int i=0;i<N;++i){\n        for(int j=0;j<N;++j){\n            if(g[i][j]=='#') continue;\n            int u = id[i][j];\n            // right neighbour\n            if(j+1<N && g[i][j+1]!='#'){\n                int v = id[i][j+1];\n                if(u<v) edges.push_back({u,v,weight[u]+weight[v]});\n            }\n            // down neighbour\n            if(i+1<N && g[i+1][j]!='#'){\n                int v = id[i+1][j];\n                if(u<v) edges.push_back({u,v,weight[u]+weight[v]});\n            }\n        }\n    }\n\n    // --- 4. MST with Kruskal ---------------------------------------------------------\n    sort(edges.begin(), edges.end());\n    DSU dsu(V);\n    vector<vector<int>> mstAdj(V);\n    int added = 0;\n    for(const auto& e: edges){\n        if(dsu.unite(e.u, e.v)){\n            mstAdj[e.u].push_back(e.v);\n            mstAdj[e.v].push_back(e.u);\n            if(++added == V-1) break;\n        }\n    }\n\n    // --- 5. root the tree in the start cell -----------------------------------------\n    vector<int> parent(V,-1);\n    vector<vector<int>> children(V);\n    vector<int> order; order.reserve(V);\n    // iterative stack for rooting\n    vector<int> st; st.push_back(startIdx);\n    parent[startIdx] = startIdx;\n    while(!st.empty()){\n        int u = st.back(); st.pop_back();\n        order.push_back(u);\n        for(int v: mstAdj[u]){\n            if(v==parent[u]) continue;\n            parent[v] = u;\n            children[u].push_back(v);\n            st.push_back(v);\n        }\n    }\n\n    // --- 6. subtree masks of segment ids --------------------------------------------\n    using Mask = bitset<MAXV>;\n    vector<Mask> subMask(V);\n    vector<int> subCnt(V,0);\n    // post\u2011order (reverse of the order we obtained above, because every parent appears after its children)\n    for(int i=(int)order.size()-1;i>=0;--i){\n        int u = order[i];\n        subMask[u].reset();\n        subMask[u].set(segId[u]);\n        for(int v: children[u]){\n            subMask[u] |= subMask[v];\n        }\n        subCnt[u] = (int)subMask[u].count();\n    }\n\n    // --- 7. sort children by number of different segments in their subtree ----------\n    for(int u=0;u<V;++u){\n        sort(children[u].begin(), children[u].end(),\n            [&](int a, int b){ return subCnt[a] > subCnt[b]; });\n    }\n\n    // --- 8. depth\u2011first walk, but only when a subtree still contains uncovered segments\n    Mask coveredMask;\n    coveredMask.reset();\n    coveredMask.set(segId[startIdx]);          // start segment already visited\n\n    string answer; answer.reserve(2*V);\n    function<void(int,int)> dfsWalk = [&](int u, int p)->void{\n        for(int v: children[u]){\n            // if nothing uncovered in this subtree \u2013 skip it\n            if ( (subMask[v] & ~coveredMask).none() ) continue;\n            // move u -> v\n            if(iOf[v]==iOf[u]-1 && jOf[v]==jOf[u]) answer.push_back('U');\n            else if(iOf[v]==iOf[u]+1 && jOf[v]==jOf[u]) answer.push_back('D');\n            else if(iOf[v]==iOf[u] && jOf[v]==jOf[u]-1) answer.push_back('L');\n            else if(iOf[v]==iOf[u] && jOf[v]==jOf[u]+1) answer.push_back('R');\n            else { /* should never happen */ }\n\n            coveredMask.set(segId[v]);          // v itself is visited now\n            dfsWalk(v, u);\n            // return v -> u\n            if(iOf[v]==iOf[u]-1 && jOf[v]==jOf[u]) answer.push_back('D');\n            else if(iOf[v]==iOf[u]+1 && jOf[v]==jOf[u]) answer.push_back('U');\n            else if(iOf[v]==iOf[u] && jOf[v]==jOf[u]-1) answer.push_back('R');\n            else if(iOf[v]==iOf[u] && jOf[v]==jOf[u]+1) answer.push_back('L');\n            else { /* should never happen */ }\n        }\n    };\n    dfsWalk(startIdx, -1);\n\n    // --- 9. output ------------------------------------------------------------------\n    cout << answer << '\\n';\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ---------- data structures ---------- */\n\nstruct Task {\n    vector<int> d;          // skill requirements, size K\n    int indegree = 0;       // number of unfinished predecessors\n    int status = -1;        // -1 : not started, 0 : in progress, 1 : completed\n    int start_day = -1;     // day on which the task was started\n    int assigned_to = -1;   // member id (0\u2011based) or -1\n    int total_req = 0;      // \u03a3_k d[k]  (used for a cheap difficulty estimate)\n};\n\nstruct Member {\n    vector<int> s_est;          // not used by the final algorithm, kept for symmetry\n    double avg_time_per_unit = 1.0;   // average observed  (time / total_requirement)\n    int total_processed = 0;    // number of tasks finished by this member\n    int total_time = 0;         // sum of their processing times\n};\n\n/* ---------- main ---------- */\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---- read prior information ---- */\n    int N, M, K, R;\n    if (!(cin >> N >> M >> K >> R)) return 0;\n\n    vector<Task> tasks(N);\n    for (int i = 0; i < N; ++i) {\n        tasks[i].d.resize(K);\n        tasks[i].total_req = 0;\n        for (int k = 0; k < K; ++k) {\n            cin >> tasks[i].d[k];\n            tasks[i].total_req += tasks[i].d[k];\n        }\n    }\n\n    vector<vector<int>> graph(N);          // edge u \u2192 v  (u must be done before v)\n    for (int i = 0; i < R; ++i) {\n        int u, v;  cin >> u >> v;  --u; --v;\n        graph[u].push_back(v);\n        ++tasks[v].indegree;\n    }\n\n    vector<Member> members(M);\n    for (int j = 0; j < M; ++j) members[j].s_est.assign(K, 0);\n\n    vector<int> member_status(M, -1);               // -1 \u2192 idle, otherwise task id\n    unordered_map<int,int> in_progress;             // taskid \u2192 start_day\n\n    int day = 0;\n\n    /* ---- day loop ---- */\n    while (true) {\n        ++day;\n        if (day > 2000) break;                     // safety, should never trigger\n\n        /* -- 1. available tasks -- */\n        vector<int> available;\n        for (int i = 0; i < N; ++i)\n            if (tasks[i].status == -1 && tasks[i].indegree == 0)\n                available.push_back(i);\n\n        sort(available.begin(), available.end(),\n             [&](int a, int b){ return tasks[a].total_req < tasks[b].total_req; });\n\n        /* -- 2. idle members -- */\n        vector<int> idle_members;\n        for (int j = 0; j < M; ++j)\n            if (member_status[j] == -1) idle_members.push_back(j);\n\n        /* -- 3. greedy matching -- */\n        vector<pair<int,int>> assignments;           // (member , task)\n        for (int j : idle_members) {\n            if (available.empty()) break;\n\n            int   best_task = -1;\n            double best_pred = 1e99;\n\n            for (size_t pos = 0; pos < available.size(); ++pos) {\n                int i = available[pos];\n                double pred = members[j].avg_time_per_unit * tasks[i].total_req;\n                if (pred < best_pred) {\n                    best_pred = pred;\n                    best_task = i;\n                }\n            }\n\n            if (best_task != -1) {\n                assignments.emplace_back(j, best_task);\n                // remove the chosen task from the vector (swap with back)\n                auto it = find(available.begin(), available.end(), best_task);\n                *it = available.back();\n                available.pop_back();\n            }\n        }\n\n        /* -- 4. output -- */\n        cout << assignments.size();\n        for (auto [mem, t] : assignments)\n            cout << ' ' << (mem + 1) << ' ' << (t + 1);\n        cout << '\\n';\n        cout.flush();\n\n        /* -- 5. update internal state -- */\n        for (auto [mem, t] : assignments) {\n            tasks[t].status = 0;\n            tasks[t].start_day = day;\n            tasks[t].assigned_to = mem;\n            member_status[mem] = t;\n            in_progress[t] = day;\n        }\n\n        /* -- 6. read completions -- */\n        int num_compl;  cin >> num_compl;\n        if (num_compl == -1) break;                 // finished or time limit\n\n        for (int i = 0; i < num_compl; ++i) {\n            int mem;  cin >> mem;  --mem;\n            int task = member_status[mem];\n            if (task == -1) continue;                // should never happen\n\n            int start_day = in_progress[task];\n            int t = day - start_day;                 // real processing time\n\n            Member &m = members[mem];\n            ++m.total_processed;\n            m.total_time += t;\n\n            // update average time per unit (exponential moving average)\n            int req = tasks[task].total_req;\n            if (req > 0) {\n                double this_avg = static_cast<double>(t) / req;\n                constexpr double alpha = 0.2;         // learning rate\n                m.avg_time_per_unit = (1.0 - alpha) * m.avg_time_per_unit\n                                      + alpha * this_avg;\n            }\n\n            // mark task completed\n            tasks[task].status = 1;\n            tasks[task].assigned_to = -1;\n            member_status[mem] = -1;\n            in_progress.erase(task);\n\n            // make dependent tasks available\n            for (int child : graph[task]) {\n                if (--tasks[child].indegree == 0) {\n                    // will be collected in the next day\n                }\n            }\n        }\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 1000;               // number of orders in the input\nconst int M = 50;                 // orders that have to be chosen\nconst int CENTER_X = 400;\nconst int CENTER_Y = 400;\n\n/*  order data  */\nint a[N], b[N], c_[N], d_[N];\nint internalDist[N];\nint startDist[N];\nint endDist[N];\nint between[N][N];                // delivery i -> pickup j\n\n/*  Manhattan distance  */\ninline int manh(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n/*  cost between two orders, -1 stands for the centre  */\ninline int costBetween(int from, int to) {\n    if (from == -1 && to == -1) return 0;\n    if (from == -1) return startDist[to];\n    if (to   == -1) return endDist[from];\n    return between[from][to];\n}\n\n/*  total travel time of a permutation (block order)  */\nint computeCost(const vector<int>& perm) {\n    int sum = 0;\n    for (int id : perm) sum += internalDist[id];\n    sum += startDist[perm[0]];\n    for (int i = 0; i + 1 < (int)perm.size(); ++i)\n        sum += between[perm[i]][perm[i + 1]];\n    sum += endDist[perm.back()];\n    return sum;\n}\n\n/* -------------------------------------------------------------\n   Greedy insertion \u2013 returns a feasible permutation\n   -------------------------------------------------------------\n*/\nvector<int> greedyInsertion(mt19937& rng) {\n    vector<int> path;                     // current permutation of orders\n    path.reserve(M);\n    vector<char> used(N, 0);               // order already taken ?\n\n    while ((int)path.size() < M) {\n        int bestTotal = INT_MAX;\n        int bestOrder = -1;\n        int bestPos   = -1;\n\n        for (int i = 0; i < N; ++i) if (!used[i]) {\n            int bestDelta = INT_MAX;\n            int bestPos_i = -1;\n            int sz = (int)path.size();\n            for (int pos = 0; pos <= sz; ++pos) {\n                int prev = (pos == 0) ? -1 : path[pos - 1];\n                int nxt  = (pos == sz) ? -1 : path[pos];\n                int delta = costBetween(prev, i) + costBetween(i, nxt)\n                            - costBetween(prev, nxt);\n                if (delta < bestDelta) {\n                    bestDelta = delta;\n                    bestPos_i = pos;\n                }\n            }\n            int totalIncrease = bestDelta + internalDist[i];\n            // random tie\u2011break\n            if (totalIncrease < bestTotal ||\n                (totalIncrease == bestTotal && (rng() & 1))) {\n                bestTotal = totalIncrease;\n                bestOrder = i;\n                bestPos   = bestPos_i;\n            }\n        }\n        // insert the chosen order\n        path.insert(path.begin() + bestPos, bestOrder);\n        used[bestOrder] = 1;\n    }\n    return path;\n}\n\n/* -------------------------------------------------------------\n   Simulated annealing on a permutation (keeps the set of orders)\n   -------------------------------------------------------------\n*/\nvector<int> simulatedAnnealing(const vector<int>& startPerm,\n                               mt19937& rng,\n                               double timeLimit)\n{\n    const double initTemp = 1000.0;\n    const int    movesPerStep = 2000;\n\n    vector<int> cur = startPerm;\n    vector<char> used(N, 0);\n    for (int v : cur) used[v] = 1;\n    int curCost = computeCost(cur);\n    int bestCost = curCost;\n    vector<int> best = cur;\n\n    double start = (double)clock() / CLOCKS_PER_SEC;\n    uniform_real_distribution<double> uni01(0.0, 1.0);\n    uniform_int_distribution<int> posDist(0, M - 1);\n    uniform_int_distribution<int> orderDist(0, N - 1);\n\n    while (true) {\n        double elapsed = (double)clock() / CLOCKS_PER_SEC - start;\n        if (elapsed > timeLimit) break;\n        double temperature = initTemp * (1.0 - elapsed / timeLimit);\n        if (temperature <= 0.0) break;\n\n        for (int step = 0; step < movesPerStep; ++step) {\n            int move = rng() % 4;                     // 0 swap,1 move,2 reverse,3 replace\n            vector<int> nxt = cur;\n            vector<char> nxtUsed = used;\n\n            if (move == 0) {                         // swap two positions\n                int i = posDist(rng), j = posDist(rng);\n                if (i == j) continue;\n                swap(nxt[i], nxt[j]);\n            }\n            else if (move == 1) {                    // move one order\n                int i = posDist(rng), j = posDist(rng);\n                if (i == j) continue;\n                int v = nxt[i];\n                nxt.erase(nxt.begin() + i);\n                nxt.insert(nxt.begin() + j, v);\n            }\n            else if (move == 2) {                    // reverse a segment\n                int i = posDist(rng), j = posDist(rng);\n                if (i >= j) continue;\n                reverse(nxt.begin() + i, nxt.begin() + j + 1);\n            }\n            else {                                    // replace one order\n                int i = posDist(rng);\n                int oldId = nxt[i];\n                int newId;\n                do { newId = orderDist(rng); } while (nxtUsed[newId]);\n                nxt[i] = newId;\n                nxtUsed[oldId] = 0;\n                nxtUsed[newId] = 1;\n            }\n\n            int nxtCost = computeCost(nxt);\n            int delta   = nxtCost - curCost;\n            double prob = (delta < 0) ? 1.0 : exp(-delta / temperature);\n            if (prob > uni01(rng)) {\n                cur.swap(nxt);\n                used.swap(nxtUsed);\n                curCost = nxtCost;\n                if (curCost < bestCost) {\n                    bestCost = curCost;\n                    best = cur;\n                }\n            }\n        }\n    }\n    return best;\n}\n\n/* -------------------------------------------------------------\n   Simple deterministic hill\u2011climbing (reverse / swap)\n   -------------------------------------------------------------\n*/\nvector<int> localImprove(vector<int> perm) {\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        // try to reverse a segment\n        for (int i = 0; i < M; ++i)\n            for (int j = i + 1; j < M; ++j) {\n                vector<int> cand = perm;\n                reverse(cand.begin() + i, cand.begin() + j + 1);\n                int candCost = computeCost(cand);\n                int curCost  = computeCost(perm);\n                if (candCost < curCost) {\n                    perm.swap(cand);\n                    improved = true;\n                    goto nextLoop;               // start again\n                }\n            }\n        // try to swap two positions\n        for (int i = 0; i < M; ++i)\n            for (int j = i + 1; j < M; ++j) {\n                vector<int> cand = perm;\n                swap(cand[i], cand[j]);\n                int candCost = computeCost(cand);\n                int curCost  = computeCost(perm);\n                if (candCost < curCost) {\n                    perm.swap(cand);\n                    improved = true;\n                    goto nextLoop;\n                }\n            }\n    nextLoop: ;\n    }\n    return perm;\n}\n\n/* -------------------------------------------------------------\n   Main\n   -------------------------------------------------------------\n*/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---- read input --------------------------------------------------- */\n    for (int i = 0; i < N; ++i) {\n        if (!(cin >> a[i] >> b[i] >> c_[i] >> d_[i])) return 0;\n    }\n\n    /* ---- pre\u2011compute all distances ------------------------------------ */\n    for (int i = 0; i < N; ++i) {\n        internalDist[i] = manh(a[i], b[i], c_[i], d_[i]);\n        startDist[i]    = manh(CENTER_X, CENTER_Y, a[i], b[i]);\n        endDist[i]      = manh(c_[i], d_[i], CENTER_X, CENTER_Y);\n        for (int j = 0; j < N; ++j)\n            between[i][j] = manh(c_[i], d_[i], a[j], b[j]);\n    }\n\n    /* ---- random generator -------------------------------------------- */\n    std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count());\n\n    /* ---- several runs ------------------------------------------------- */\n    const int runs = 3;\n    const double timePerRun = 1.8 / runs;\n\n    vector<int> bestOverall;\n    int bestOverallCost = INT_MAX;\n\n    for (int r = 0; r < runs; ++r) {\n        vector<int> init = greedyInsertion(rng);\n        vector<int> afterSA = simulatedAnnealing(init, rng, timePerRun);\n        vector<int> afterLocal = localImprove(afterSA);\n        int cost = computeCost(afterLocal);\n        if (cost < bestOverallCost) {\n            bestOverallCost = cost;\n            bestOverall = afterLocal;\n        }\n    }\n\n    /* ---- output ------------------------------------------------------- */\n    cout << \"50\";\n    for (int id : bestOverall) cout << ' ' << id + 1;\n    cout << '\\n';\n\n    cout << \"102 400 400\";\n    for (int id : bestOverall) {\n        cout << ' ' << a[id] << ' ' << b[id] << ' '\n             << c_[id] << ' ' << d_[id];\n    }\n    cout << \" 400 400\\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);\n        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\nstruct Edge {\n    int u, v;\n    int d; // rounded distance\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<pair<int,int>> coords(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    // Read edges and compute d_i\n    vector<Edge> edges(M);\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        cin >> u >> v;\n        edges[i].u = u;\n        edges[i].v = v;\n        long long dx = (long long)coords[u].first - coords[v].first;\n        long long dy = (long long)coords[u].second - coords[v].second;\n        double dist = sqrt((double)dx * dx + (double)dy * dy);\n        edges[i].d = (int)llround(dist);\n    }\n    \n    DSU dsu(N);\n    int components = N;\n    \n    for (int i = 0; i < M; ++i) {\n        int l;\n        cin >> l;\n        \n        int u = edges[i].u;\n        int v = edges[i].v;\n        \n        // If already connected, no need for this edge\n        if (components == 1) {\n            cout << 0 << endl;\n            continue;\n        }\n        \n        int ru = dsu.find(u);\n        int rv = dsu.find(v);\n        \n        // Edge creates a cycle, reject\n        if (ru == rv) {\n            cout << 0 << endl;\n            continue;\n        }\n        \n        // Compute rank of l_i in [d_i, 3*d_i]\n        double d = edges[i].d;\n        double rank = (l - d) / (2.0 * d);\n        \n        // Dynamic threshold: increases from 0.3 to 1.0\n        double progress = (double)i / (M - 1);\n        double threshold = 0.3 + 0.7 * progress;\n        \n        // Accept if rank is good enough, or if we're near the end\n        bool accept = (rank <= threshold) || (i >= M - 50);\n        \n        if (accept) {\n            dsu.unite(ru, rv);\n            --components;\n            cout << 1 << endl;\n        } else {\n            cout << 0 << endl;\n        }\n    }\n    \n    return 0;\n}","ahc008":"","ahc009":"","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Problem constants\nconst int H = 30, W = 30;\nconst int N = H * W; // 900\nconst int DIR = 4;\nconst int NODE_COUNT = N * DIR; // 3600\n\n// to[t][d]: exit direction when entering tile type t from direction d (-1 if no connection)\nconst int TO[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1}\n};\n\n// Direction vectors: left, up, right, down\nconst int DI[4] = {0, -1, 0, 1};\nconst int DJ[4] = {-1, 0, 1, 0};\n\n// Rotation mapping: rotate_map[t][r] = effective type after r rotations\nint ROTATE_MAP[8][4];\n\n// Initialize rotation mapping\nvoid init_rotate_map() {\n    // One rotation mapping (given in problem statement)\n    const int ROT1[8] = {1, 2, 3, 0, 5, 4, 7, 6};\n    for (int t = 0; t < 8; ++t) {\n        ROTATE_MAP[t][0] = t;\n        int cur = t;\n        for (int r = 1; r < 4; ++r) {\n            cur = ROT1[cur];\n            ROTATE_MAP[t][r] = cur;\n        }\n    }\n}\n\n// Compute score for a given rotation assignment\npair<int, int> compute_score(const array<int, N>& rot, const array<int, N>& tiles) {\n    // Build next array for functional graph\n    array<int, NODE_COUNT> nxt;\n    nxt.fill(-1);\n    \n    for (int i = 0; i < H; ++i) {\n        for (int j = 0; j < W; ++j) {\n            int idx = i * W + j;\n            int t = tiles[idx];\n            int r = rot[idx];\n            int eff_type = ROTATE_MAP[t][r];\n            \n            for (int d = 0; d < DIR; ++d) {\n                int d2 = TO[eff_type][d];\n                if (d2 == -1) {\n                    nxt[idx * DIR + d] = -1;\n                    continue;\n                }\n                int ni = i + DI[d2];\n                int nj = j + DJ[d2];\n                if (ni < 0 || ni >= H || nj < 0 || nj >= W) {\n                    nxt[idx * DIR + d] = -1;\n                    continue;\n                }\n                int nidx = ni * W + nj;\n                int nd = (d2 + 2) % DIR; // entry direction for next tile\n                nxt[idx * DIR + d] = nidx * DIR + nd;\n            }\n        }\n    }\n    \n    // Find cycles in functional graph\n    array<char, NODE_COUNT> state; // 0=unvisited, 1=visiting, 2=done\n    state.fill(0);\n    vector<int> cycle_lens;\n    cycle_lens.reserve(NODE_COUNT);\n    \n    vector<int> path;\n    path.reserve(NODE_COUNT);\n    \n    for (int s = 0; s < NODE_COUNT; ++s) {\n        if (state[s] != 0) continue;\n        \n        int cur = s;\n        path.clear();\n        // Traverse until we hit visited node or dead end\n        while (cur != -1 && state[cur] == 0) {\n            state[cur] = 1;\n            path.push_back(cur);\n            cur = nxt[cur];\n        }\n        \n        if (cur != -1 && state[cur] == 1) {\n            // Found a cycle - find its length\n            int start_idx = -1;\n            for (int i = 0; i < (int)path.size(); ++i) {\n                if (path[i] == cur) {\n                    start_idx = i;\n                    break;\n                }\n            }\n            if (start_idx != -1) {\n                int len = (int)path.size() - start_idx;\n                cycle_lens.push_back(len);\n            }\n        }\n        \n        // Mark all visited nodes as done\n        for (int node : path) {\n            state[node] = 2;\n        }\n    }\n    \n    // Get top two cycle lengths\n    sort(cycle_lens.begin(), cycle_lens.end(), greater<int>());\n    int L1 = 0, L2 = 0;\n    if (!cycle_lens.empty()) L1 = cycle_lens[0];\n    if (cycle_lens.size() >= 2) L2 = cycle_lens[1];\n    \n    return {L1, L2};\n}\n\n// Simulated annealing to find good rotation assignments\npair<array<int, N>, long long> simulated_annealing(const array<int, N>& tiles) {\n    const double TIME_LIMIT = 1.85; // seconds\n    auto start_time = chrono::high_resolution_clock::now();\n    \n    // Random initialization\n    random_device rd;\n    mt19937 rng(rd());\n    uniform_int_distribution<int> dist_rot(0, 3);\n    \n    array<int, N> rot;\n    for (int i = 0; i < N; ++i) {\n        rot[i] = dist_rot(rng);\n    }\n    \n    // Evaluate initial solution\n    auto [L1, L2] = compute_score(rot, tiles);\n    long long best_score = (long long)L1 * L2;\n    array<int, N> best_rot = rot;\n    \n    // Simulated annealing parameters\n    double temp = 1.0;\n    const double COOLING = 0.995;\n    const double MIN_TEMP = 0.001;\n    \n    uniform_int_distribution<int> dist_tile(0, N-1);\n    uniform_real_distribution<double> dist_prob(0.0, 1.0);\n    \n    int iterations = 0;\n    \n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > TIME_LIMIT) break;\n        \n        // Cooling schedule\n        temp *= COOLING;\n        if (temp < MIN_TEMP) temp = MIN_TEMP;\n        \n        // Randomly select a tile and change its rotation\n        int tile = dist_tile(rng);\n        int old_rot = rot[tile];\n        int new_rot;\n        do {\n            new_rot = dist_rot(rng);\n        } while (new_rot == old_rot);\n        \n        // Apply change\n        rot[tile] = new_rot;\n        auto [new_L1, new_L2] = compute_score(rot, tiles);\n        long long new_score = (long long)new_L1 * new_L2;\n        \n        // Acceptance decision\n        double delta = new_score - best_score;\n        bool accept = false;\n        if (delta > 0) {\n            accept = true;\n        } else {\n            // Accept with probability exp(delta/temp)\n            double prob = exp(delta / temp);\n            if (dist_prob(rng) < prob) accept = true;\n        }\n        \n        if (accept) {\n            if (new_score > best_score) {\n                best_score = new_score;\n                best_rot = rot;\n            }\n        } else {\n            // Revert change\n            rot[tile] = old_rot;\n        }\n        \n        ++iterations;\n    }\n    \n    return {best_rot, best_score};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    init_rotate_map();\n    \n    // Read input\n    array<int, N> tiles;\n    for (int i = 0; i < H; ++i) {\n        string line;\n        if (!(cin >> line)) return 0;\n        for (int j = 0; j < W; ++j) {\n            tiles[i * W + j] = line[j] - '0';\n        }\n    }\n    \n    // Run multiple restarts to improve solution\n    const int RESTARTS = 5;\n    long long global_best_score = 0;\n    array<int, N> global_best_rot;\n    \n    for (int r = 0; r < RESTARTS; ++r) {\n        auto [rot, score] = simulated_annealing(tiles);\n        if (score > global_best_score) {\n            global_best_score = score;\n            global_best_rot = rot;\n        }\n    }\n    \n    // Output best rotation as 900-digit string\n    for (int i = 0; i < N; ++i) {\n        cout << global_best_rot[i];\n    }\n    cout << '\\n';\n    \n    return 0;\n}","ahc011":"","ahc012":"","ahc014":"struct Point { int x, y; };\nstruct Op { Point p[4]; }; // p[0] is new dot\n\nvector<vector<bool>> has_dot;          // Dot presence\nvector<vector<array<bool,4>>> edge;    // edge[x][y][dir] = used\nvector<vector<int>> weight;            // Precomputed weights\nvector<Op> operations;                 // Solution","ahc015":"","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    const double epsilon = eps;\n    const bool noiseless = (epsilon < 1e-12);\n    int N;                     // number of vertices\n\n    // ----- choose N -------------------------------------------------\n    if (noiseless) {\n        // N = 5 is enough: 2^(10) = 1024 > 100\n        N = 5;\n    } else {\n        double I = log2(max(2, M));          // bits to transmit\n        double H = -epsilon * log2(epsilon) - (1.0 - epsilon) * log2(1.0 - epsilon);\n        double C = 1.0 - H;                  // capacity per edge\n        double need = (I + 3.0) / C;         // a few redundant bits\n        int needEdges = (int)ceil(need);\n        // solve N(N-1)/2 >= needEdges\n        double disc = 1.0 + 8.0 * needEdges;\n        double sq = sqrt(disc);\n        N = (int)ceil((1.0 + sq) / 2.0);\n        if (N < 4) N = 4;\n        if (N > 100) N = 100;\n    }\n\n    const int n = N;\n    const int tot = n * (n - 1) / 2;\n\n    // ----- generate all graphs --------------------------------------\n    // adjacency: G[i][u][v]  (0/1)\n    vector<vector<vector<char>>> G(M,\n        vector<vector<char>>(n, vector<char>(n, 0)));\n\n    // sorted degree sequences, will be used for decoding\n    vector<vector<int>> sortedDeg(M, vector<int>(n));\n\n    for (int i = 0; i < M; ++i) {\n        // deterministic seed depending on i, M, n\n        mt19937 rng(i * 10007 + M * 12345 + n * 6789 + 42);\n        uniform_int_distribution<int> dist(0, 1);\n\n        for (int u = 0; u < n; ++u)\n            for (int v = u + 1; v < n; ++v) {\n                char e = (char)dist(rng);   // 0 or 1\n                G[i][u][v] = G[i][v][u] = e;\n            }\n\n        // degree of each vertex\n        vector<int> deg(n, 0);\n        for (int u = 0; u < n; ++u) {\n            int s = 0;\n            for (int v = 0; v < n; ++v) if (u != v) s += G[i][u][v];\n            deg[u] = s;\n        }\n        // sorted in decreasing order\n        vector<int> sd = deg;\n        sort(sd.begin(), sd.end(), greater<int>());\n        sortedDeg[i] = sd;\n    }\n\n    // ----- output the graphs ----------------------------------------\n    cout << n << '\\n';\n    for (int i = 0; i < M; ++i) {\n        string line;\n        line.reserve(tot);\n        for (int u = 0; u < n; ++u)\n            for (int v = u + 1; v < n; ++v)\n                line.push_back(G[i][u][v] ? '1' : '0');\n        cout << line << '\\n';\n    }\n    cout.flush();\n\n    // ----- pre\u2011compute all permutations (only needed for noiseless) ---\n    vector<vector<int>> perms;\n    if (noiseless) {\n        vector<int> p(n);\n        iota(p.begin(), p.end(), 0);\n        do {\n            perms.push_back(p);\n        } while (next_permutation(p.begin(), p.end()));\n    }\n\n    // ----- process the 100 queries ----------------------------------\n    for (int q = 0; q < 100; ++q) {\n        string Hstr;\n        cin >> Hstr;\n\n        // adjacency of H (needed only for noiseless case)\n        vector<vector<char>> B(n, vector<char>(n, 0));\n        vector<int> degH(n, 0);\n        int pos = 0;\n        for (int u = 0; u < n; ++u) {\n            for (int v = u + 1; v < n; ++v) {\n                char c = (char)(Hstr[pos++] - '0');\n                B[u][v] = B[v][u] = c;\n                if (c) {\n                    ++degH[u];\n                    ++degH[v];\n                }\n            }\n        }\n\n        int answer = 0;\n\n        if (noiseless) {\n            // exact isomorphism test, N \u2264 5  \u2192 at most 120 permutations\n            bool found = false;\n            for (int i = 0; i < M && !found; ++i) {\n                for (const auto &perm : perms) {\n                    bool ok = true;\n                    for (int u = 0; u < n && ok; ++u) {\n                        int pu = perm[u];\n                        for (int v = u + 1; v < n; ++v) {\n                            int pv = perm[v];\n                            if (G[i][u][v] != B[pu][pv]) {\n                                ok = false;\n                                break;\n                            }\n                        }\n                    }\n                    if (ok) {\n                        answer = i;\n                        found = true;\n                        break;\n                    }\n                }\n            }\n        } else {\n            // compare sorted degree sequences\n            vector<int> sdH = degH;\n            sort(sdH.begin(), sdH.end(), greater<int>());\n\n            int bestDist = INT_MAX;\n            for (int i = 0; i < M; ++i) {\n                int d = 0;\n                for (int k = 0; k < n; ++k) {\n                    d += abs(sortedDeg[i][k] - sdH[k]);\n                    if (d >= bestDist) break; // early cut\n                }\n                if (d < bestDist) {\n                    bestDist = d;\n                    answer = i;\n                }\n            }\n        }\n\n        cout << answer << '\\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    long long w;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n\n    vector<Edge> edges(M);\n    vector<vector<pair<int,int>>> adj(N);          // (to , edge id)\n    for (int i = 0; i < M; ++i) {\n        int a, b;\n        long long w;\n        cin >> a >> b >> w;\n        --a; --b;\n        edges[i] = {a, b, w};\n        adj[a].push_back({b, i});\n        adj[b].push_back({a, i});\n    }\n    // read the coordinates, they are not needed\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        (void)x; (void)y;\n    }\n\n    const long long INF = (1LL << 60);\n\n    /* ----------------------------------------------------------\n       1.  Edge betweenness centrality (Brandes, weighted)\n       ---------------------------------------------------------- */\n    vector<double> ebc(M, 0.0);\n    vector<long long> dist(N);\n    vector<double> sigma(N), delta(N);\n    vector<vector<pair<int,int>>> pred(N);\n    vector<int> order(N);\n\n    for (int s = 0; s < N; ++s) {\n        fill(dist.begin(), dist.end(), INF);\n        fill(sigma.begin(), sigma.end(), 0.0);\n        for (int i = 0; i < N; ++i) pred[i].clear();\n\n        priority_queue<pair<long long,int>, vector<pair<long long,int>>, greater<pair<long long,int>>> pq;\n        dist[s] = 0;\n        sigma[s] = 1.0;\n        pq.emplace(0, s);\n\n        while (!pq.empty()) {\n            auto [d, v] = pq.top(); pq.pop();\n            if (d != dist[v]) continue;\n            for (auto [to, eid] : adj[v]) {\n                long long nd = d + edges[eid].w;\n                if (dist[to] > nd) {\n                    dist[to] = nd;\n                    sigma[to] = sigma[v];\n                    pred[to].clear();\n                    pred[to].emplace_back(v, eid);\n                    pq.emplace(nd, to);\n                } else if (dist[to] == nd) {\n                    sigma[to] += sigma[v];\n                    pred[to].emplace_back(v, eid);\n                }\n            }\n        }\n\n        // vertices in decreasing order of distance\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(),\n             [&](int a, int b){ return dist[a] > dist[b]; });\n\n        fill(delta.begin(), delta.end(), 0.0);\n\n        for (int v : order) {\n            if (dist[v] == INF) continue;\n            for (auto [u, eid] : pred[v]) {\n                double coeff = sigma[u] / sigma[v];\n                double contrib = coeff * (1.0 + delta[v]);\n                ebc[eid] += contrib;\n                delta[u] += contrib;\n            }\n        }\n    }\n\n    for (int i = 0; i < M; ++i) ebc[i] *= 0.5;          // undirected\n\n    /* ----------------------------------------------------------\n       2.  Score of an edge (here only betweenness)\n       ---------------------------------------------------------- */\n    vector<double> score(M);\n    for (int i = 0; i < M; ++i) score[i] = ebc[i];      // * edges[i].w possible\n\n    /* ----------------------------------------------------------\n       3.  Greedy LPT assignment, several random restarts\n       ---------------------------------------------------------- */\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    vector<int> best_assign(M);\n    double best_obj = 1e100;\n    vector<int> order_edges(M);\n    iota(order_edges.begin(), order_edges.end(), 0);\n\n    int restarts = 5;                     // enough, can be increased if time permits\n    for (int rep = 0; rep < restarts; ++rep) {\n        shuffle(order_edges.begin(), order_edges.end(), rng);\n        vector<int> assign(M, -1);\n        vector<double> day_sum(D, 0.0);\n        vector<int> day_cnt(D, 0);\n\n        for (int eid : order_edges) {\n            // choose a day with free capacity and minimal current sum\n            int best_day = -1;\n            double best_val = 1e200;\n            for (int d = 0; d < D; ++d) {\n                if (day_cnt[d] >= K) continue;\n                if (day_sum[d] < best_val) {\n                    best_val = day_sum[d];\n                    best_day = d;\n                }\n            }\n            // it is guaranteed that such a day exists\n            assign[eid] = best_day;\n            day_sum[best_day] += score[eid];\n            day_cnt[best_day]++;\n        }\n\n        double obj = 0.0;\n        for (int d = 0; d < D; ++d) obj += day_sum[d] * day_sum[d];\n        if (obj < best_obj) {\n            best_obj = obj;\n            best_assign = assign;\n        }\n    }\n\n    /* ----------------------------------------------------------\n       4.  Simple hill climbing (improves the surrogate)\n       ---------------------------------------------------------- */\n    vector<int> assign = best_assign;\n    vector<double> day_sum(D, 0.0);\n    vector<int> day_cnt(D, 0);\n    for (int e = 0; e < M; ++e) {\n        int d = assign[e];\n        day_sum[d] += score[e];\n        day_cnt[d]++;\n    }\n\n    uniform_int_distribution<int> edge_dist(0, M - 1);\n    uniform_int_distribution<int> day_dist(0, D - 1);\n    const int HILL_ITER = 20000;          // works well, can be tuned\n    for (int it = 0; it < HILL_ITER; ++it) {\n        int e = edge_dist(rng);\n        int cur = assign[e];\n        if (day_cnt[cur] == 0) continue; // should never happen\n\n        // look for a different day with free capacity\n        int nd = day_dist(rng);\n        if (nd == cur || day_cnt[nd] >= K) continue;\n\n        double cur_sum = day_sum[cur];\n        double new_sum = day_sum[nd];\n        double old_contrib = cur_sum * cur_sum + new_sum * new_sum;\n        double new_contrib = (cur_sum - score[e]) * (cur_sum - score[e]) +\n                             (new_sum + score[e]) * (new_sum + score[e]);\n        if (new_contrib < old_contrib - 1e-12) {\n            // accept move\n            assign[e] = nd;\n            day_sum[cur] -= score[e];\n            day_sum[nd] += score[e];\n            day_cnt[cur]--;\n            day_cnt[nd]++;\n        }\n    }\n\n    /* ----------------------------------------------------------\n       5.  Output\n       ---------------------------------------------------------- */\n    for (int i = 0; i < M; ++i) {\n        if (i) cout << ' ';\n        cout << assign[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    \n    int D;\n    if (!(cin >> D)) return 0;\n    const int MAXD = 14;\n    vector<string> f[2], r[2];\n    f[0].resize(D); f[1].resize(D);\n    r[0].resize(D); r[1].resize(D);\n    for (int i = 0; i < 2; ++i)\n        for (int z = 0; z < D; ++z) cin >> f[i][z];\n    for (int i = 0; i < 2; ++i)\n        for (int z = 0; z < D; ++z) cin >> r[i][z];\n\n    // data for both objects\n    vector<vector<int>> X[2], Y[2];\n    vector<vector<pair<int,int>>> intX[2], intY[2];\n    for (int i = 0; i < 2; ++i) {\n        X[i].assign(D, {});\n        Y[i].assign(D, {});\n        intX[i].assign(D, {});\n        intY[i].assign(D, {});\n        for (int z = 0; z < D; ++z) {\n            // collect X and Y\n            for (int x = 0; x < D; ++x)\n                if (f[i][z][x] == '1') X[i][z].push_back(x);\n            for (int y = 0; y < D; ++y)\n                if (r[i][z][y] == '1') Y[i][z].push_back(y);\n            // intervals of 1s in f\n            const string &sf = f[i][z];\n            for (int x = 0; x < D; ) {\n                if (sf[x] == '0') { ++x; continue; }\n                int s = x;\n                while (x < D && sf[x] == '1') ++x;\n                int e = x - 1;\n                intX[i][z].push_back({s, e});\n            }\n            // intervals of 1s in r\n            const string &sr = r[i][z];\n            for (int y = 0; y < D; ) {\n                if (sr[y] == '0') { ++y; continue; }\n                int s = y;\n                while (y < D && sr[y] == '1') ++y;\n                int e = y - 1;\n                intY[i][z].push_back({s, e});\n            }\n        }\n    }\n\n    // count bars for each orientation\n    vector<int> cntV[2], cntH[2];\n    cntV[0].assign(D+1, 0); cntV[1].assign(D+1, 0);\n    cntH[0].assign(D+1, 0); cntH[1].assign(D+1, 0);\n    for (int i = 0; i < 2; ++i) {\n        for (int z = 0; z < D; ++z) {\n            // vertical bars (use Y intervals)\n            for (auto &pr : intY[i][z]) {\n                int len = pr.second - pr.first + 1;\n                cntV[i][len] += (int)X[i][z].size();\n            }\n            // horizontal bars (use X intervals)\n            for (auto &pr : intX[i][z]) {\n                int len = pr.second - pr.first + 1;\n                cntH[i][len] += (int)Y[i][z].size();\n            }\n        }\n    }\n\n    // choose best orientation\n    double bestScore = 1e100;\n    int bestO1 = -1, bestO2 = -1;\n    for (int o1 = 0; o1 < 2; ++o1) {\n        for (int o2 = 0; o2 < 2; ++o2) {\n            const vector<int> &a = (o1 ? cntH[0] : cntV[0]);\n            const vector<int> &b = (o2 ? cntH[1] : cntV[1]);\n            double score = 0.0;\n            for (int L = 1; L <= D; ++L) {\n                int s = min(a[L], b[L]);\n                int diff = abs(a[L] - b[L]);\n                score += diff * L + (double)s / L;\n            }\n            if (score < bestScore) {\n                bestScore = score;\n                bestO1 = o1;\n                bestO2 = o2;\n            }\n        }\n    }\n\n    // final counts according to the chosen orientation\n    vector<int> aCnt = (bestO1 ? cntH[0] : cntV[0]);\n    vector<int> bCnt = (bestO2 ? cntH[1] : cntV[1]);\n\n    // create block IDs\n    vector<vector<int>> sharedId(D+1), only1Id(D+1), only2Id(D+1);\n    int totalBlocks = 0;\n    for (int L = 1; L <= D; ++L) {\n        int s = min(aCnt[L], bCnt[L]);\n        for (int k = 0; k < s; ++k) sharedId[L].push_back(++totalBlocks);\n        for (int k = 0; k < aCnt[L] - s; ++k) only1Id[L].push_back(++totalBlocks);\n        for (int k = 0; k < bCnt[L] - s; ++k) only2Id[L].push_back(++totalBlocks);\n    }\n\n    // 3D output arrays (flat)\n    vector<int> b1(D*D*D, 0), b2(D*D*D, 0);\n    auto index = [&](int x, int y, int z) { return x*D*D + y*D + z; };\n\n    // ----- place object 1 -----\n    vector<int> ptrS(D+1, 0), ptr1(D+1, 0);\n    if (bestO1 == 0) { // vertical\n        for (int z = 0; z < D; ++z) {\n            for (auto &pr : intY[0][z]) {\n                int len = pr.second - pr.first + 1;\n                int y1 = pr.first, y2 = pr.second;\n                for (int x : X[0][z]) {\n                    int id;\n                    if (ptrS[len] < (int)sharedId[len].size())\n                        id = sharedId[len][ptrS[len]++];\n                    else\n                        id = only1Id[len][ptr1[len]++];\n                    for (int y = y1; y <= y2; ++y)\n                        b1[index(x, y, z)] = id;\n                }\n            }\n        }\n    } else { // horizontal\n        for (int z = 0; z < D; ++z) {\n            for (auto &pr : intX[0][z]) {\n                int len = pr.second - pr.first + 1;\n                int x1 = pr.first, x2 = pr.second;\n                for (int y : Y[0][z]) {\n                    int id;\n                    if (ptrS[len] < (int)sharedId[len].size())\n                        id = sharedId[len][ptrS[len]++];\n                    else\n                        id = only1Id[len][ptr1[len]++];\n                    for (int x = x1; x <= x2; ++x)\n                        b1[index(x, y, z)] = id;\n                }\n            }\n        }\n    }\n\n    // ----- place object 2 -----\n    vector<int> ptrS2(D+1, 0), ptr2(D+1, 0);\n    if (bestO2 == 0) { // vertical\n        for (int z = 0; z < D; ++z) {\n            for (auto &pr : intY[1][z]) {\n                int len = pr.second - pr.first + 1;\n                int y1 = pr.first, y2 = pr.second;\n                for (int x : X[1][z]) {\n                    int id;\n                    if (ptrS2[len] < (int)sharedId[len].size())\n                        id = sharedId[len][ptrS2[len]++];\n                    else\n                        id = only2Id[len][ptr2[len]++];\n                    for (int y = y1; y <= y2; ++y)\n                        b2[index(x, y, z)] = id;\n                }\n            }\n        }\n    } else { // horizontal\n        for (int z = 0; z < D; ++z) {\n            for (auto &pr : intX[1][z]) {\n                int len = pr.second - pr.first + 1;\n                int x1 = pr.first, x2 = pr.second;\n                for (int y : Y[1][z]) {\n                    int id;\n                    if (ptrS2[len] < (int)sharedId[len].size())\n                        id = sharedId[len][ptrS2[len]++];\n                    else\n                        id = only2Id[len][ptr2[len]++];\n                    for (int x = x1; x <= x2; ++x)\n                        b2[index(x, y, z)] = id;\n                }\n            }\n        }\n    }\n\n    // ----- output -----\n    cout << totalBlocks << '\\n';\n    for (int i = 0; i < D*D*D; ++i) {\n        if (i) cout << ' ';\n        cout << b1[i];\n    }\n    cout << '\\n';\n    for (int i = 0; i < D*D*D; ++i) {\n        if (i) cout << ' ';\n        cout << b2[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v;\n    long long w;\n    double dist;\n};\n\nstruct Station {\n    long long x, y;\n};\n\nstruct Resident {\n    long long a, b;\n};\n\nstruct DSU {\n    vector<int> p, r;\n    DSU(int n) : p(n), r(n, 0) { iota(p.begin(), p.end(), 0); }\n    int find(int x) { return p[x] == x ? x : p[x] = find(p[x]); }\n    bool unite(int a, int b) {\n        a = find(a);\n        b = find(b);\n        if (a == b) return false;\n        if (r[a] < r[b]) swap(a, b);\n        p[b] = a;\n        if (r[a] == r[b]) r[a]++;\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n    \n    vector<Station> stations(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> stations[i].x >> stations[i].y;\n    }\n    \n    vector<Edge> edges(M);\n    vector<vector<pair<int, int>>> adj(N);\n    for (int j = 0; j < M; ++j) {\n        cin >> edges[j].u >> edges[j].v >> edges[j].w;\n        edges[j].u--;\n        edges[j].v--;\n        long long dx = stations[edges[j].u].x - stations[edges[j].v].x;\n        long long dy = stations[edges[j].u].y - stations[edges[j].v].y;\n        edges[j].dist = sqrt((double)dx * dx + (double)dy * dy);\n        adj[edges[j].u].push_back({edges[j].v, j});\n        adj[edges[j].v].push_back({edges[j].u, j});\n    }\n    \n    vector<Resident> residents(K);\n    for (int k = 0; k < K; ++k) {\n        cin >> residents[k].a >> residents[k].b;\n    }\n    \n    // Precompute distances from each resident to each station\n    // resident_stations[k] is sorted by distance\n    vector<vector<pair<double, int>>> resident_stations(K);\n    for (int k = 0; k < K; ++k) {\n        resident_stations[k].reserve(N);\n        for (int i = 0; i < N; ++i) {\n            long long dx = residents[k].a - stations[i].x;\n            long long dy = residents[k].b - stations[i].y;\n            double dist = sqrt((double)dx * dx + (double)dy * dy);\n            resident_stations[k].push_back({dist, i});\n        }\n        sort(resident_stations[k].begin(), resident_stations[k].end(),\n            [](const pair<double, int>& a, const pair<double, int>& b) {\n                return a.first < b.first;\n            });\n    }\n    \n    // Generate candidate spanning trees\n    vector<vector<int>> candidate_trees;\n    \n    // Candidate 1: Standard MST using edge weight w\n    {\n        DSU dsu(N);\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int i, int j) {\n            return edges[i].w < edges[j].w;\n        });\n        \n        vector<int> tree_edges;\n        for (int idx : order) {\n            if (dsu.unite(edges[idx].u, edges[idx].v)) {\n                tree_edges.push_back(idx);\n                if ((int)tree_edges.size() == N - 1) break;\n            }\n        }\n        if ((int)tree_edges.size() == N - 1) {\n            candidate_trees.push_back(tree_edges);\n        }\n    }\n    \n    // Candidate 2: MST using weight = w / (dist + 1)\n    {\n        DSU dsu(N);\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int i, int j) {\n            double wi = (double)edges[i].w / (edges[i].dist + 1.0);\n            double wj = (double)edges[j].w / (edges[j].dist + 1.0);\n            return wi < wj;\n        });\n        \n        vector<int> tree_edges;\n        for (int idx : order) {\n            if (dsu.unite(edges[idx].u, edges[idx].v)) {\n                tree_edges.push_back(idx);\n                if ((int)tree_edges.size() == N - 1) break;\n            }\n        }\n        if ((int)tree_edges.size() == N - 1) {\n            candidate_trees.push_back(tree_edges);\n        }\n    }\n    \n    // Candidate 3: MST using weight = w * dist\n    {\n        DSU dsu(N);\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int i, int j) {\n            double wi = (double)edges[i].w * edges[i].dist;\n            double wj = (double)edges[j].w * edges[j].dist;\n            return wi < wj;\n        });\n        \n        vector<int> tree_edges;\n        for (int idx : order) {\n            if (dsu.unite(edges[idx].u, edges[idx].v)) {\n                tree_edges.push_back(idx);\n                if ((int)tree_edges.size() == N - 1) break;\n            }\n        }\n        if ((int)tree_edges.size() == N - 1) {\n            candidate_trees.push_back(tree_edges);\n        }\n    }\n    \n    // Candidate 4: Shortest path tree from station 1\n    {\n        vector<int> tree_edges;\n        vector<long long> dist(N, LLONG_MAX);\n        vector<int> prev_edge(N, -1);\n        dist[0] = 0;\n        using Node = pair<long long, int>;\n        priority_queue<Node, vector<Node>, greater<Node>> pq;\n        pq.push({0, 0});\n        vector<bool> visited(N, false);\n        \n        while (!pq.empty()) {\n            auto [d, u] = pq.top();\n            pq.pop();\n            if (visited[u]) continue;\n            visited[u] = true;\n            \n            if (prev_edge[u] != -1) {\n                tree_edges.push_back(prev_edge[u]);\n            }\n            \n            for (auto [v, eid] : adj[u]) {\n                if (!visited[v] && d + edges[eid].w < dist[v]) {\n                    dist[v] = d + edges[eid].w;\n                    prev_edge[v] = eid;\n                    pq.push({dist[v], v});\n                }\n            }\n        }\n        \n        if ((int)tree_edges.size() == N - 1) {\n            candidate_trees.push_back(tree_edges);\n        }\n    }\n    \n    // Fallback: BFS tree if no spanning tree was generated\n    if (candidate_trees.empty()) {\n        vector<int> tree_edges;\n        vector<bool> visited(N, false);\n        queue<int> q;\n        q.push(0);\n        visited[0] = true;\n        \n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            for (auto [v, eid] : adj[u]) {\n                if (!visited[v]) {\n                    visited[v] = true;\n                    tree_edges.push_back(eid);\n                    q.push(v);\n                    if ((int)tree_edges.size() == N - 1) break;\n                }\n            }\n            if ((int)tree_edges.size() == N - 1) break;\n        }\n        candidate_trees.push_back(tree_edges);\n    }\n    \n    // Evaluate each candidate tree and keep the best solution\n    long long best_cost = LLONG_MAX;\n    vector<int> best_P(N, 0);\n    vector<int> best_B(M, 0);\n    \n    for (const auto& tree_edge_indices : candidate_trees) {\n        // Determine which stations are in the tree (should be all N for spanning trees)\n        vector<bool> in_tree(N, false);\n        in_tree[0] = true; // Station 1 is always active\n        for (int idx : tree_edge_indices) {\n            in_tree[edges[idx].u] = true;\n            in_tree[edges[idx].v] = true;\n        }\n        \n        // Assign residents to nearest active station\n        vector<int> resident_station(K, -1);\n        vector<double> station_max_radius(N, 0.0);\n        \n        for (int k = 0; k < K; ++k) {\n            for (auto [dist, station_id] : resident_stations[k]) {\n                if (in_tree[station_id]) {\n                    resident_station[k] = station_id;\n                    station_max_radius[station_id] = max(station_max_radius[station_id], dist);\n                    break;\n                }\n            }\n        }\n        \n        // Compute output power for each station (capped at 5000)\n        vector<int> P(N, 0);\n        for (int i = 0; i < N; ++i) {\n            if (station_max_radius[i] > 0) {\n                int radius = (int)ceil(station_max_radius[i]);\n                P[i] = min(5000, radius);\n            }\n        }\n        \n        // Build edge selection vector\n        vector<int> B(M, 0);\n        for (int idx : tree_edge_indices) {\n            B[idx] = 1;\n        }\n        \n        // Calculate total cost\n        long long edge_cost = 0;\n        for (int j = 0; j < M; ++j) {\n            if (B[j] == 1) edge_cost += edges[j].w;\n        }\n        long long vertex_cost = 0;\n        for (int i = 0; i < N; ++i) {\n            vertex_cost += (long long)P[i] * P[i];\n        }\n        long long total_cost = edge_cost + vertex_cost;\n        \n        // Verify all residents can be covered\n        bool all_covered = true;\n        for (int k = 0; k < K; ++k) {\n            if (resident_station[k] == -1) {\n                all_covered = false;\n                break;\n            }\n        }\n        \n        // Update best solution if this one is better\n        if (all_covered && total_cost < best_cost) {\n            best_cost = total_cost;\n            best_P = P;\n            best_B = B;\n        }\n    }\n    \n    // Output the best solution\n    for (int i = 0; i < N; ++i) {\n        if (i > 0) cout << \" \";\n        cout << best_P[i];\n    }\n    cout << \"\\n\";\n    for (int j = 0; j < M; ++j) {\n        if (j > 0) cout << \" \";\n        cout << best_B[j];\n    }\n    cout << \"\\n\";\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    \n    const int N = 30;\n    // a[x][y] : value of ball (x,y), invalid entries stay -1\n    vector<vector<int>> a(N, vector<int>(N, -1));\n\n    for (int x = 0; x < N; ++x) {\n        for (int y = 0; y <= x; ++y) {\n            if (!(cin >> a[x][y])) return 0;\n        }\n    }\n\n    struct Swap {\n        int x1, y1, x2, y2;\n    };\n    vector<Swap> swaps;\n    swaps.reserve(5000);\n\n    auto doSwap = [&](int x1, int y1, int x2, int y2) {\n        swap(a[x1][y1], a[x2][y2]);\n        swaps.push_back({x1, y1, x2, y2});\n    };\n\n    // process rows from bottom to top\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 cur has at least one child\n            while (curX < N - 1) {\n                int leftX  = curX + 1;\n                int leftY  = curY;\n                int rightX = curX + 1;\n                int rightY = curY + 1;\n\n                // the smaller child\n                int childX, childY;\n                if (a[leftX][leftY] < a[rightX][rightY]) {\n                    childX = leftX; childY = leftY;\n                } else {\n                    childX = rightX; childY = rightY;\n                }\n\n                if (a[childX][childY] < a[curX][curY]) {\n                    // swap and continue downwards\n                    doSwap(curX, curY, childX, childY);\n                    curX = childX;\n                    curY = childY;\n                } else {\n                    break; // cur is already smaller than both children\n                }\n            }\n        }\n    }\n\n    // output\n    cout << swaps.size() << '\\n';\n    for (const auto &s : swaps) {\n        cout << s.x1 << ' ' << s.y1 << ' '\n             << s.x2 << ' ' << s.y2 << '\\n';\n    }\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\nconst int D = 9;                     // fixed board size\n\n/* global data */\nint M;                               // number of containers\nvector<vector<bool>> obstacle;       // true for an obstacle\nvector<vector<bool>> occupied;       // true if a container is present\nvector<vector<int>> value;           // transport number, -1 if none\n\n/* auxiliary directions */\nconst int dr[4] = {1, -1, 0, 0};\nconst int dc[4] = {0, 0, 1, -1};\n\n/* --------------------------------------------------------------- */\n/* BFS from entrance over empty squares.\n   fills reachable[][] , dist[][] and returns number of reachable empty squares\n   (entrance is counted as empty).                                 */\nint bfs_reachable(vector<vector<bool>>& reachable,\n                  vector<vector<int>>& dist,\n                  const vector<vector<bool>>& occupied_grid)\n{\n    reachable.assign(D, vector<bool>(D, false));\n    dist.assign(D, vector<int>(D, -1));\n    queue<pair<int,int>> q;\n\n    int ent_r = 0, ent_c = (D-1)/2;\n    reachable[ent_r][ent_c] = true;\n    dist[ent_r][ent_c] = 0;\n    q.emplace(ent_r, ent_c);\n    int cnt = 1;                     // entrance itself\n\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];\n            int nc = c + dc[d];\n            if (nr<0||nr>=D||nc<0||nc>=D) continue;\n            if (obstacle[nr][nc]) continue;\n            if (occupied_grid[nr][nc]) continue;      // not empty\n            if (!reachable[nr][nc]){\n                reachable[nr][nc] = true;\n                dist[nr][nc] = dist[r][c] + 1;\n                ++cnt;\n                q.emplace(nr,nc);\n            }\n        }\n    }\n    return cnt;          // total empty squares reachable (including entrance)\n}\n\n/* --------------------------------------------------------------- */\n/* test whether a reachable empty square (tr,tc) is a cut vertex\n   (i.e. after occupying it the remaining empty squares stay connected) */\nbool is_safe(int tr, int tc,\n             const vector<vector<bool>>& occupied_grid,\n             int total_empty,\n             const vector<vector<bool>>& reachable)\n{\n    // a second BFS, this time treating (tr,tc) as blocked\n    vector<vector<bool>> reach2(D, vector<bool>(D,false));\n    queue<pair<int,int>> q;\n    int ent_r = 0, ent_c = (D-1)/2;\n    reach2[ent_r][ent_c] = true;\n    q.emplace(ent_r, ent_c);\n    int cnt = 1;\n\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];\n            int nc = c + dc[d];\n            if (nr<0||nr>=D||nc<0||nc>=D) continue;\n            if (obstacle[nr][nc]) continue;\n            if (occupied_grid[nr][nc]) continue;\n            if (nr==tr && nc==tc) continue;          // the blocked cell\n            if (!reach2[nr][nc]){\n                reach2[nr][nc] = true;\n                ++cnt;\n                q.emplace(nr,nc);\n            }\n        }\n    }\n    // after blocking (tr,tc) we must still reach all other empties\n    return cnt == total_empty - 1;\n}\n\n/* --------------------------------------------------------------- */\n/* pick a square for the next container */\npair<int,int> choose_square(const vector<vector<bool>>& occupied_grid)\n{\n    vector<vector<bool>> reachable;\n    vector<vector<int>> dist;\n    int total_empty = bfs_reachable(reachable, dist, occupied_grid);\n\n    vector<pair<int,int>> safe_list;\n    int best_dist = -1;\n    pair<int,int> best{-1,-1};\n\n    for (int r=0; r<D; ++r){\n        for (int c=0; c<D; ++c){\n            if (!reachable[r][c]) continue;               // not reachable\n            if (occupied_grid[r][c]) continue;             // already occupied\n            if (r==0 && c==(D-1)/2) continue;              // entrance\n            // articulation test\n            if (!is_safe(r,c,occupied_grid,total_empty,reachable)) continue;\n            safe_list.emplace_back(r,c);\n            if (dist[r][c] > best_dist){\n                best_dist = dist[r][c];\n                best = {r,c};\n            }\n            else if (dist[r][c]==best_dist && best.first!=-1){\n                // tie\u2011break by smaller row, then column\n                if (r < best.first || (r==best.first && c < best.second))\n                    best = {r,c};\n            }\n        }\n    }\n\n    // normally safe_list is non\u2011empty \u2013 otherwise we would be stuck.\n    if (!safe_list.empty()) return best;\n\n    // fallback: any reachable cell (should not happen)\n    for (int r=0; r<D; ++r)\n        for (int c=0; c<D; ++c)\n            if (reachable[r][c] && !occupied_grid[r][c] && !(r==0 && c==(D-1)/2))\n                return {r,c};\n    return {-1,-1}; // never reached\n}\n\n/* --------------------------------------------------------------- */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if(!(cin>>D>>N)) return 0;\n    obstacle.assign(D, vector<bool>(D,false));\n    for (int i=0;i<N;++i){\n        int ri,rj; cin>>ri>>rj;\n        obstacle[ri][rj]=true;\n    }\n\n    occupied.assign(D, vector<bool>(D,false));\n    value.assign(D, vector<int>(D,-1));\n\n    int ent_r=0, ent_c=(D-1)/2;\n    M = D*D - 1 - N;\n\n    vector<pair<int,int>> container_position(M);   // by transport number\n\n    /* ---------- placement ---------- */\n    for (int step=0; step<M; ++step){\n        int t; cin>>t;\n        auto pos = choose_square(occupied);\n        int r = pos.first, c = pos.second;\n        // place the container\n        occupied[r][c] = true;\n        value[r][c] = t;\n        container_position[t] = {r,c};\n        cout << r << ' ' << c << '\\n';\n        cout.flush();\n    }\n\n    /* ---------- removal ---------- */\n    vector<pair<int,int>> removal_order;\n    removal_order.reserve(M);\n    int removed = 0;\n    while (removed < M){\n        vector<vector<bool>> reachableEmpty;\n        vector<vector<int>> dummy;\n        bfs_reachable(reachableEmpty, dummy, occupied);   // empty squares only\n\n        // collect removable containers\n        int best_val = INF;\n        int br=-1, bc=-1;\n        for (int r=0; r<D; ++r){\n            for (int c=0; c<D; ++c){\n                if (!occupied[r][c]) continue;               // no container here\n                // is it reachable ?   (any neighbour reachableEmpty)\n                bool ok = false;\n                for (int d=0; d<4; ++d){\n                    int nr = r+dr[d];\n                    int nc = c+dc[d];\n                    if (nr<0||nr>=D||nc<0||nc>=D) continue;\n                    if (reachableEmpty[nr][nc]) { ok=true; break; }\n                }\n                if (!ok) continue;\n                if (value[r][c] < best_val){\n                    best_val = value[r][c];\n                    br=r; bc=c;\n                }\n            }\n        }\n        // remove the chosen container\n        removal_order.emplace_back(br,bc);\n        occupied[br][bc] = false;\n        value[br][bc] = -1;\n        ++removed;\n    }\n\n    for (auto [r,c] : removal_order){\n        cout << r << ' ' << c << '\\n';\n    }\n    cout.flush();\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 50;\nconst int M = 100;\n\nint n, m;\nint orig[N][N];\n\n/* --------------------------------------------------------------- */\n/*  adjacency of the original map (including colour 0)            */\nbool orig_adj[M + 1][M + 1];                 // symmetric, 0..m\nvector<array<int,5>> adj_pairs;               // c,d, i_c,j_c,i_d,j_d  (both >0)\n\n/* --------------------------------------------------------------- */\n/*  colour sets                                                   */\nvector<pair<int,int>> cells_of_color[M + 1];   // 1..m\nbool is_border_colour[M + 1];\nbool is_interior_colour[M + 1];\n\n/* --------------------------------------------------------------- */\n/*  required cells for each colour (see section 2)                */\nbool required_pos[N][N];\nvector<pair<int,int>> required[M + 1];\n\n/* --------------------------------------------------------------- */\n/*  cells that finally stay coloured                              */\nbool keep[N][N];\n\n/* --------------------------------------------------------------- */\n/*  utility: neighbour directions                                  */\nconst int dy[4] = { -1, 1, 0, 0 };\nconst int dx[4] = { 0, 0, -1, 1 };\n\n/* --------------------------------------------------------------- */\n/*  full validation of a produced map                            */\nbool validate(const int out[N][N])\n{\n    /* 1. each colour appears at least once and is connected       */\n    int cnt_colour[M+1];\n    fill(begin(cnt_colour), end(cnt_colour), 0);\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++) {\n        int c = out[i][j];\n        if (c<0 || c>m) return false;\n        ++cnt_colour[c];\n    }\n    for (int c=1;c<=m;c++) if (cnt_colour[c]==0) return false;\n\n    // BFS for each colour\n    bool visited[N][N];\n    for (int c=1;c<=m;c++) {\n        memset(visited,0,sizeof(visited));\n        // find first cell of this colour\n        int sx=-1,sy=-1;\n        for (int i=0;i<n && sx==-1;i++) for (int j=0;j<n;j++)\n            if (out[i][j]==c) { sx=i; sy=j; break; }\n        if (sx==-1) return false;               // should not happen\n        queue<pair<int,int>> q;\n        q.emplace(sx,sy);\n        visited[sx][sy]=true;\n        int reach=0;\n        while(!q.empty()){\n            auto [y,x]=q.front(); q.pop();\n            ++reach;\n            for (int dir=0;dir<4;dir++){\n                int ny=y+dy[dir], nx=x+dx[dir];\n                if (ny<0||ny>=n||nx<0||nx>=n) continue;\n                if (out[ny][nx]==c && !visited[ny][nx]){\n                    visited[ny][nx]=true;\n                    q.emplace(ny,nx);\n                }\n            }\n        }\n        if (reach!=cnt_colour[c]) return false;   // not connected\n    }\n\n    /* 2. zero cells are connected with the outside               */\n    memset(visited,0,sizeof(visited));\n    queue<pair<int,int>> qz;\n    // start from every border zero cell\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++) {\n        if (out[i][j]==0 &&\n            (i==0||i==n-1||j==0||j==n-1)){\n            visited[i][j]=true;\n            qz.emplace(i,j);\n        }\n    }\n    while(!qz.empty()){\n        auto [y,x]=qz.front(); qz.pop();\n        for (int dir=0;dir<4;dir++){\n            int ny=y+dy[dir], nx=x+dx[dir];\n            if (ny<0||ny>=n||nx<0||nx>=n) continue;\n            if (out[ny][nx]==0 && !visited[ny][nx]){\n                visited[ny][nx]=true;\n                qz.emplace(ny,nx);\n            }\n        }\n    }\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++)\n        if (out[i][j]==0 && !visited[i][j]) return false;   // isolated zero\n\n    /* 3. adjacency matrix exactly the original one                */\n    bool out_adj[M+1][M+1];\n    memset(out_adj,0,sizeof(out_adj));\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++) {\n        int c = out[i][j];\n        for (int dir=0;dir<4;dir++){\n            int ni=i+dy[dir], nj=j+dx[dir];\n            if (ni<0||ni>=n||nj<0||nj>=n){\n                // neighbour = outside -> colour 0\n                out_adj[c][0]=out_adj[0][c]=true;\n                continue;\n            }\n            int d = out[ni][nj];\n            if (c!=d){\n                out_adj[c][d]=out_adj[d][c]=true;\n            }\n        }\n    }\n    for (int c=0;c<=m;c++) for (int d=c;d<=m;d++)\n        if (orig_adj[c][d]!=out_adj[c][d]) return false;\n\n    return true;\n}\n\n/* --------------------------------------------------------------- */\n/*  connect the already kept cells of one border colour            */\nvoid connect_border_colour(int col)\n{\n    // region = all cells of this colour in the original map\n    static bool inRegion[N][N];\n    for (auto &p : cells_of_color[col]) inRegion[p.first][p.second]=true;\n\n    // components of currently kept cells\n    static int comp[N][N];\n    memset(comp, -1, sizeof(comp));\n    int compCnt = 0;\n    queue<pair<int,int>> qq;\n    for (auto &p : cells_of_color[col]) {\n        int y=p.first, x=p.second;\n        if (keep[y][x] && comp[y][x]==-1){\n            qq.emplace(y,x);\n            comp[y][x]=compCnt;\n            while(!qq.empty()){\n                auto [cy,cx]=qq.front(); qq.pop();\n                for (int dir=0;dir<4;dir++){\n                    int ny=cy+dy[dir], nx=cx+dx[dir];\n                    if (ny<0||ny>=n||nx<0||nx>=n) continue;\n                    if (!inRegion[ny][nx]) continue;\n                    if (keep[ny][nx] && comp[ny][nx]==-1){\n                        comp[ny][nx]=compCnt;\n                        qq.emplace(ny,nx);\n                    }\n                }\n            }\n            ++compCnt;\n        }\n    }\n\n    while (compCnt>1){\n        // find two cells belonging to different components\n        int y1=-1,x1=-1,y2=-1,x2=-1;\n        for (auto &p : cells_of_color[col]){\n            int y=p.first, x=p.second;\n            if (!keep[y][x]) continue;\n            if (y1==-1) { y1=y; x1=x; continue; }\n            if (comp[y][x]!=comp[y1][x1]){ y2=y; x2=x; break; }\n        }\n        // BFS inside the whole region to find a shortest path\n        static int pred_y[N][N], pred_x[N][N];\n        static bool seen[N][N];\n        memset(seen,0,sizeof(seen));\n        queue<pair<int,int>> q;\n        q.emplace(y1,x1);\n        seen[y1][x1]=true;\n        pred_y[y1][x1]=pred_x[y1][x1]=-1;\n        while(!q.empty()){\n            auto [cy,cx]=q.front(); q.pop();\n            if (cy==y2 && cx==x2) break;\n            for (int dir=0;dir<4;dir++){\n                int ny=cy+dy[dir], nx=cx+dx[dir];\n                if (ny<0||ny>=n||nx<0||nx>=n) continue;\n                if (!inRegion[ny][nx]) continue;\n                if (!seen[ny][nx]){\n                    seen[ny][nx]=true;\n                    pred_y[ny][nx]=cy;\n                    pred_x[ny][nx]=cx;\n                    q.emplace(ny,nx);\n                }\n            }\n        }\n        // mark the whole path as kept\n        int yy=y2, xx=x2;\n        while(!(yy==y1&&xx==x1)){\n            keep[yy][xx]=true;\n            int py=pred_y[yy][px];\n            int px=pred_x[yy][px];\n            yy=py; xx=px;\n        }\n        keep[y1][x1]=true;\n\n        // recompute components (simplest: start again)\n        memset(comp,-1,sizeof(comp));\n        compCnt=0;\n        for (auto &p : cells_of_color[col]){\n            int y=p.first, x=p.second;\n            if (keep[y][x] && comp[y][x]==-1){\n                qq.emplace(y,x);\n                comp[y][x]=compCnt;\n                while(!qq.empty()){\n                    auto [cy,cx]=qq.front(); qq.pop();\n                    for (int dir=0;dir<4;dir++){\n                        int ny=cy+dy[dir], nx=cx+dx[dir];\n                        if (ny<0||ny>=n||nx<0||nx>=n) continue;\n                        if (!inRegion[ny][nx]) continue;\n                        if (keep[ny][nx] && comp[ny][nx]==-1){\n                            comp[ny][nx]=compCnt;\n                            qq.emplace(ny,nx);\n                        }\n                    }\n                }\n                ++compCnt;\n            }\n        }\n    }\n\n    // clear inRegion for next call\n    for (auto &p : cells_of_color[col]) inRegion[p.first][p.second]=false;\n}\n\n/* --------------------------------------------------------------- */\n/*  greedy deletion of non\u2011required cells                         */\nvoid greedy_deletion(int out_grid[N][N])\n{\n    mt19937 rng(123456);\n    bool changed=true;\n    int passes=0;\n    while (changed && passes<5){\n        changed=false;\n        vector<pair<int,int>> cand;\n        for (int i=0;i<n;i++) for (int j=0;j<n;j++)\n            if (keep[i][j] && !required_pos[i][j])\n                cand.emplace_back(i,j);\n        shuffle(cand.begin(), cand.end(), rng);\n        for (auto [y,x] : cand){\n            int oldcol = orig[y][x];\n            // try delete\n            out_grid[y][x]=0;\n            keep[y][x]=false;\n            if (validate(out_grid)){\n                changed=true;\n            } else {\n                // revert\n                out_grid[y][x]=oldcol;\n                keep[y][x]=true;\n            }\n        }\n        ++passes;\n    }\n}\n\n/* --------------------------------------------------------------- */\n/*  repair isolated zero pools                                   */\nvoid repair_isolated_zeros(int out_grid[N][N])\n{\n    bool visited[N][N];\n    memset(visited,0,sizeof(visited));\n    queue<pair<int,int>> q;\n    // start from border zeros\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++){\n        if (out_grid[i][j]==0 && (i==0||i==n-1||j==0||j==n-1)){\n            visited[i][j]=true;\n            q.emplace(i,j);\n        }\n    }\n    while(!q.empty()){\n        auto [y,x]=q.front(); q.pop();\n        for (int dir=0;dir<4;dir++){\n            int ny=y+dy[dir], nx=x+dx[dir];\n            if (ny<0||ny>=n||nx<0||nx>=n) continue;\n            if (out_grid[ny][nx]==0 && !visited[ny][nx]){\n                visited[ny][nx]=true;\n                q.emplace(ny,nx);\n            }\n        }\n    }\n    // revert isolated zeros\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++){\n        if (out_grid[i][j]==0 && !visited[i][j]){\n            out_grid[i][j]=orig[i][j];\n            keep[i][j]=true;          // not used any more, but keep consistent\n        }\n    }\n}\n\n/* --------------------------------------------------------------- */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if(!(cin>>n>>m)) return 0;\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++){\n        cin>>orig[i][j];\n        cells_of_color[orig[i][j]].push_back({i,j});\n        if (i==0||i==n-1||j==0||j==n-1) is_border_colour[orig[i][j]]=true;\n    }\n\n    /* ---- original adjacency ------------------------------------ */\n    memset(orig_adj,0,sizeof(orig_adj));\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++){\n        int c = orig[i][j];\n        for (int dir=0;dir<4;dir++){\n            int ni=i+dy[dir], nj=j+dx[dir];\n            if (ni<0||ni>=n||nj<0||nj>=n){\n                // outside -> colour 0\n                orig_adj[c][0]=orig_adj[0][c]=true;\n                continue;\n            }\n            int d = orig[ni][nj];\n            if (c!=d){\n                orig_adj[c][d]=orig_adj[d][c]=true;\n                if (c<d)  // store only once, but we need both cell positions\n                    adj_pairs.push_back({c,d,i,j,ni,nj});\n                else\n                    adj_pairs.push_back({d,c,ni,nj,i,j});\n            }\n        }\n    }\n\n    /* ---- interior / border colours ----------------------------- */\n    for (int c=1;c<=m;c++) is_interior_colour[c]=!is_border_colour[c];\n\n    /* ---- must_keep: cells that may not become zero -------------- */\n    bool must_keep[N][N];\n    memset(must_keep,0,sizeof(must_keep));\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++){\n        if (is_interior_colour[orig[i][j]]){\n            must_keep[i][j]=true;\n            for (int dir=0;dir<4;dir++){\n                int ni=i+dy[dir], nj=j+dx[dir];\n                if (ni<0||ni>=n||nj<0||nj>=n) continue;\n                must_keep[ni][nj]=true;\n            }\n        }\n    }\n\n    /* ---- required cells for border colours ---------------------- */\n    memset(required_pos,0,sizeof(required_pos));\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++){\n        int c = orig[i][j];\n        if (is_border_colour[c] && must_keep[i][j]){\n            required[c].push_back({i,j});\n            required_pos[i][j]=true;\n        }\n    }\n    // at least one border cell for each border colour\n    for (int c=1;c<=m;c++) if (is_border_colour[c]){\n        bool has=false;\n        for (auto &p : cells_of_color[c]){\n            int y=p.first, x=p.second;\n            if (y==0||y==n-1||x==0||x==n-1){\n                if (!required_pos[y][x]){\n                    required[c].push_back({y,x});\n                    required_pos[y][x]=true;\n                }\n                has=true;\n                break;\n            }\n        }\n        // border colour must have at least one border cell \u2013 guaranteed by input\n    }\n    // one pair for each border\u2011border edge\n    bool edge_used[M+1][M+1];\n    memset(edge_used,0,sizeof(edge_used));\n    for (auto &e : adj_pairs){\n        int a=e[0], b=e[1];\n        if (!is_border_colour[a] || !is_border_colour[b]) continue;\n        int c=min(a,b), d=max(a,b);\n        if (edge_used[c][d]) continue;\n        // store both cells as required\n        int c1=e[0], y1=e[2], x1=e[3];\n        int c2=e[1], y2=e[4], x2=e[5];\n        if (!required_pos[y1][x1]){\n            required[c1].push_back({y1,x1});\n            required_pos[y1][x1]=true;\n        }\n        if (!required_pos[y2][x2]){\n            required[c2].push_back({y2,x2});\n            required_pos[y2][x2]=true;\n        }\n        edge_used[c][d]=true;\n    }\n\n    /* ---- initial keep set -------------------------------------- */\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++) keep[i][j]=must_keep[i][j];\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++)\n        if (required_pos[i][j]) keep[i][j]=true;\n\n    /* ---- connect every border colour ---------------------------- */\n    for (int c=1;c<=m;c++) if (is_border_colour[c])\n        connect_border_colour(c);\n\n    /* ---- build a first valid output map ------------------------ */\n    int out_grid[N][N];\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++)\n        out_grid[i][j] = keep[i][j] ? orig[i][j] : 0;\n\n    /* ---- try to delete more cells greedily --------------------- */\n    greedy_deletion(out_grid);\n\n    /* ---- repair isolated zero pools ---------------------------- */\n    repair_isolated_zeros(out_grid);\n\n    /* ---- final output ------------------------------------------ */\n    for (int i=0;i<n;i++){\n        for (int j=0;j<n;j++){\n            if (j) cout << ' ';\n            cout << out_grid[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    // comparison_matrix[i][j]: 1 if i > j, -1 if i < j, 0 if unknown, 2 if equal\n    vector<vector<int>> comparison_matrix(N, vector<int>(N, 0));\n    vector<int> comparison_count(N, 0);\n    \n    for (int query = 0; query < Q; query++) {\n        // Find item with minimum comparisons\n        int i = min_element(comparison_count.begin(), comparison_count.end()) - comparison_count.begin();\n        \n        // Find another item to compare with, preferring not yet compared\n        int j = -1;\n        int min_other_count = INT_MAX;\n        \n        // First try: find an item not yet compared with i\n        for (int k = 0; k < N; k++) {\n            if (k != i && comparison_matrix[i][k] == 0 && comparison_count[k] < min_other_count) {\n                min_other_count = comparison_count[k];\n                j = k;\n            }\n        }\n        \n        // Second try: if no new pair, find any item with minimal comparisons\n        if (j == -1) {\n            for (int k = 0; k < N; k++) {\n                if (k != i && comparison_count[k] < min_other_count) {\n                    min_other_count = comparison_count[k];\n                    j = k;\n                }\n            }\n        }\n        \n        // Final fallback\n        if (j == -1) {\n            j = (i + 1) % N;\n            if (j == i) j = (i + 2) % N; // Ensure different items\n        }\n        \n        // Output query: compare single items\n        cout << \"1 1 \" << i << \" \" << j << endl;\n        cout.flush();\n        \n        string result;\n        cin >> result;\n        \n        // Update matrix\n        if (result == \">\") {\n            comparison_matrix[i][j] = 1;\n            comparison_matrix[j][i] = -1;\n        } else if (result == \"<\") {\n            comparison_matrix[i][j] = -1;\n            comparison_matrix[j][i] = 1;\n        } else { // \"=\"\n            comparison_matrix[i][j] = 2; // Equal\n            comparison_matrix[j][i] = 2;\n        }\n        \n        comparison_count[i]++;\n        comparison_count[j]++;\n    }\n    \n    // Calculate score for each item: wins - losses\n    vector<int> score(N, 0);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (i == j) continue;\n            if (comparison_matrix[i][j] == 1) {\n                score[i]++; // i beats j\n            } else if (comparison_matrix[i][j] == -1) {\n                score[i]--; // i loses to j\n            }\n        }\n    }\n    \n    // Create order: items sorted by score descending\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        return score[a] > score[b];\n    });\n    \n    // Assign to D groups using snake pattern for balanced distribution\n    vector<int> assignment(N);\n    for (int pos = 0; pos < N; pos++) {\n        int item = order[pos];\n        int cycle = pos / D;\n        int offset = pos % D;\n        \n        int target_group = (cycle % 2 == 0) ? offset : (D - 1 - offset);\n        assignment[item] = target_group;\n    }\n    \n    // Output assignment\n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << assignment[i];\n    }\n    cout << endl;\n    cout.flush();\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    int h = n / m;                     // height of each stack, fixed to 20\n    vector<vector<int>> st(m);          // stacks, bottom -> top\n    for (int i = 0; i < m; ++i) {\n        st[i].reserve(h);\n        for (int j = 0; j < h; ++j) {\n            int x; cin >> x;\n            st[i].push_back(x);\n        }\n    }\n\n    vector<pair<int,int>> ops;          // answer sequence\n    ops.reserve(5000);\n    long long total_energy = 0;         // only for self check, not output\n\n    // helper: find box v, return (stack index, position inside stack)\n    auto locate = [&](int v, int &si, int &pos){\n        for (int i = 0; i < m; ++i) {\n            for (int j = 0; j < (int)st[i].size(); ++j) {\n                if (st[i][j] == v) {\n                    si = i;\n                    pos = j;\n                    return;\n                }\n            }\n        }\n        // should never happen\n        cerr << \"box \" << v << \" not found!\\n\";\n        exit(1);\n    };\n\n    for (int v = 1; v <= n; ++v) {\n        int si, pos;\n        locate(v, si, pos);\n\n        // if v already on the top -> carry out directly\n        if (pos == (int)st[si].size() - 1) {\n            ops.emplace_back(v, 0);\n            st[si].pop_back();               // remove v\n            continue;\n        }\n\n        // box directly above v\n        int w = st[si][pos + 1];\n\n        // choose a destination stack (different from si)\n        int dest = -1;\n        // 1) any empty stack ?\n        for (int i = 0; i < m; ++i) if (i != si && st[i].empty()) {\n            dest = i; break;\n        }\n        // 2) otherwise the non\u2011empty stack with the largest top number\n        if (dest == -1) {\n            int best_top = -1;\n            for (int i = 0; i < m; ++i) if (i != si && !st[i].empty()) {\n                int cur_top = st[i].back();\n                if (cur_top > best_top) {\n                    best_top = cur_top;\n                    dest = i;\n                }\n            }\n        }\n        // sanity check\n        if (dest == -1) {\n            // should never happen (there is at least one other stack)\n            dest = (si + 1) % m;\n        }\n\n        // ---- move the block w .. top of si to dest ----\n        int start = pos + 1;                         // first element to move\n        vector<int> suffix(st[si].begin() + start, st[si].end());\n        int k = (int)suffix.size();                 // number of moved boxes\n        total_energy += k + 1;\n\n        // erase from source\n        st[si].erase(st[si].begin() + start, st[si].end());\n        // append to destination\n        st[dest].insert(st[dest].end(), suffix.begin(), suffix.end());\n\n        ops.emplace_back(w, dest + 1);               // operation 1\n\n        // ---- now v is on the top of si, carry it out ----\n        ops.emplace_back(v, 0);\n        st[si].pop_back();                           // remove v\n    }\n\n    // ---- output ---------------------------------------------------------\n    for (auto [a, b] : ops) {\n        cout << a << ' ' << b << '\\n';\n    }\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> h, v;                // walls\nvector<vector<int>> d;              // dirt factor\nvector<vector<bool>> visited;\nvector<vector<int>> extra;          // extra round\u2011trips per cell\nstring path;\nconst int MAX_MOVES = 100000;\n\n/* ------------------------------------------------------------------ */\n// can we walk from (i,j) to (ni,nj) ?\ninline bool can_move(int i, int j, int ni, int nj) {\n    if (ni == i - 1 && i > 0)          return h[i - 1][j] == '0'; // up\n    if (ni == i + 1 && i < N - 1)      return h[i][j]     == '0'; // down\n    if (nj == j - 1 && j > 0)          return v[i][j - 1] == '0'; // left\n    if (nj == j + 1 && j < N - 1)      return v[i][j]     == '0'; // right\n    return false;\n}\n\n/* ------------------------------------------------------------------ */\n// append one step to the global walk\ninline void add_move(int di, int dj) {\n    if ((int)path.size() >= MAX_MOVES) return;\n    if (di == -1) path.push_back('U');\n    else if (di == 1) path.push_back('D');\n    else if (dj == -1) path.push_back('L');\n    else if (dj == 1) path.push_back('R');\n}\n\n/* ------------------------------------------------------------------ */\n// depth\u2011first walk with extra round\u2011trips\nvoid dfs(int i, int j) {\n    if ((int)path.size() >= MAX_MOVES) return;\n    visited[i][j] = true;\n\n    const int DIRS[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n    vector<pair<int,pair<int,int>>> neigh;          // ( -d , (x,y) )\n\n    // neighbours, sorted by decreasing d (minus sign for ascending sort)\n    for (auto [di,dj] : DIRS) {\n        int ni = i + di, nj = j + dj;\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n        if (can_move(i,j,ni,nj) && !visited[ni][nj])\n            neigh.push_back({ -d[ni][nj], {ni,nj} });\n    }\n    sort(neigh.begin(), neigh.end());\n\n    // ordinary tree traversal\n    for (auto [_,c] : neigh) {\n        int ni = c.first, nj = c.second;\n        if (!visited[ni][nj]) {\n            add_move(ni - i, nj - j);\n            dfs(ni, nj);\n            add_move(i - ni, j - nj);\n        }\n    }\n\n    // insert the extra round\u2011trips belonging to this cell\n    while (extra[i][j] > 0 && (int)path.size() + 2 <= MAX_MOVES) {\n        bool ok = false;\n        for (auto [di,dj] : DIRS) {\n            int ni = i + di, nj = j + dj;\n            if (ni >= 0 && ni < N && nj >= 0 && nj < N && can_move(i,j,ni,nj)) {\n                add_move(di, dj);\n                add_move(-di, -dj);\n                ok = true;\n                --extra[i][j];\n                break;\n            }\n        }\n        if (!ok) {               // no neighbour \u2013 should never happen\n            extra[i][j] = 0;\n            break;\n        }\n    }\n}\n\n/* ------------------------------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // ---- read input -------------------------------------------------\n    cin >> N;\n    h.resize(N-1);\n    for (int i=0;i<N-1;i++) cin >> h[i];\n    v.resize(N);\n    for (int i=0;i<N;i++)   cin >> v[i];\n    d.assign(N, vector<int>(N));\n    for (int i=0;i<N;i++)\n        for (int j=0;j<N;j++) cin >> d[i][j];\n\n    // ---- distribute extra visits ------------------------------------\n    int V = N * N;\n    int base   = 2 * (V - 1);                 // length of the pure DFS tour\n    int budget = MAX_MOVES - base;            // free moves we may spend\n    if (budget < 0) budget = 0;               // safety, never happens for the limits\n\n    double sumSqrt = 0.0;\n    vector<vector<double>> sqrtd(N, vector<double>(N));\n    for (int i=0;i<N;i++)\n        for (int j=0;j<N;j++) {\n            sqrtd[i][j] = sqrt(d[i][j]);\n            sumSqrt += sqrtd[i][j];\n        }\n\n    extra.assign(N, vector<int>(N, 0));\n    if (sumSqrt > 0) {\n        const double COST_PER_EXTRA = 2.0;    // one round\u2011trip = two moves\n        for (int i=0;i<N;i++)\n            for (int j=0;j<N;j++) {\n                double ratio = sqrtd[i][j] / sumSqrt;\n                extra[i][j] = max(0, int(budget * ratio / COST_PER_EXTRA));\n            }\n    }\n\n    // ---- build the walk ---------------------------------------------\n    visited.assign(N, vector<bool>(N, false));\n    dfs(0,0);\n\n    // ---- if length limit not reached, pad with round\u2011trips from (0,0)\n    const int DIRS[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n    while ((int)path.size() + 2 <= MAX_MOVES) {\n        bool done = false;\n        for (auto [di,dj] : DIRS) {\n            int ni = di, nj = dj;                 // relative to (0,0)\n            if (ni>=0 && ni<N && nj>=0 && nj<N && can_move(0,0,ni,nj)) {\n                add_move(di,dj);\n                add_move(-di,-dj);\n                done = true; break;\n            }\n        }\n        if (!done) break;     // no neighbour \u2013 cannot extend any more\n    }\n\n    cout << path << '\\n';\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\n\nint N, M;\nint si, sj;\nint startId;                     // linear index of the start cell\nvector<string> board;\nvector<string> pat;              // patterns, length M, each length 5\n\n// for every letter \u2013 list of cell ids that contain this letter\nvector<vector<int>> letterPos;   // size 26\n\n// Manhattan distance between any two cells\nint distCell[225][225];\n// coordinates of a cell id\nint row[225], col[225];\n\n/* -------------------------------------------------------------\n   compute the cheapest sum of Manhattan distances for a fixed\n   sequence of letters (vector<int> seq containing 0..25)\n   ------------------------------------------------------------- */\nint movementDist(const vector<int> &seq) {\n    // first character\n    const vector<int> *prevCand = &letterPos[seq[0]];\n    vector<int> dpPrev(prevCand->size());\n    for (int i = 0; i < (int)prevCand->size(); ++i)\n        dpPrev[i] = distCell[startId][(*prevCand)[i]];\n\n    for (size_t idx = 1; idx < seq.size(); ++idx) {\n        const vector<int> *curCand = &letterPos[seq[idx]];\n        vector<int> dpCur(curCand->size(), INF);\n        for (int ci = 0; ci < (int)curCand->size(); ++ci) {\n            int cur = (*curCand)[ci];\n            int best = INF;\n            for (int pi = 0; pi < (int)prevCand->size(); ++pi) {\n                int cand = (*prevCand)[pi];\n                int val = dpPrev[pi] + distCell[cand][cur];\n                if (val < best) best = val;\n            }\n            dpCur[ci] = best;\n        }\n        dpPrev.swap(dpCur);\n        prevCand = curCand;\n    }\n    int best = INF;\n    for (int v : dpPrev) if (v < best) best = v;\n    return best;\n}\n\n/* -------------------------------------------------------------\n   build the overlapped string for a given order of patterns,\n   store it into seq, return total price = movement + length\n   ------------------------------------------------------------- */\nint priceOfOrder(const vector<int> &order, vector<int> &seq) {\n    seq.clear(); seq.reserve(5 * M);\n    for (int id : order) {\n        const string &p = pat[id];\n        int maxOL = min((int)seq.size(), 5);\n        int overlap = 0;\n        for (int k = maxOL; k > 0; --k) {\n            bool ok = true;\n            for (int i = 0; i < k; ++i)\n                if (seq[seq.size() - k + i] != p[i] - 'A') { ok = false; break; }\n            if (ok) { overlap = k; break; }\n        }\n        for (int i = overlap; i < 5; ++i) seq.push_back(p[i] - 'A');\n    }\n    int move = movementDist(seq);\n    return move + (int)seq.size();          // total price\n}\n\n/* -------------------------------------------------------------\n   reconstruct the concrete walk for the best order\n   ------------------------------------------------------------- */\nvector<int> reconstructWalk(const vector<int> &order) {\n    vector<int> seq; seq.reserve(5 * M);\n    for (int id : order) {\n        const string &p = pat[id];\n        int maxOL = min((int)seq.size(), 5);\n        int overlap = 0;\n        for (int k = maxOL; k > 0; --k) {\n            bool ok = true;\n            for (int i = 0; i < k; ++i)\n                if (seq[seq.size() - k + i] != p[i] - 'A') { ok = false; break; }\n            if (ok) { overlap = k; break; }\n        }\n        for (int i = overlap; i < 5; ++i) seq.push_back(p[i] - 'A');\n    }\n    int L = (int)seq.size();\n\n    struct Step {\n        const vector<int> *cells;\n        vector<int> dp;\n        vector<int> pred;          // index inside previous layer\n    };\n    vector<Step> step(L);\n\n    // first layer\n    step[0].cells = &letterPos[seq[0]];\n    step[0].dp.resize(step[0].cells->size());\n    step[0].pred.assign(step[0].cells->size(), -1);\n    for (int i = 0; i < (int)step[0].cells->size(); ++i)\n        step[0].dp[i] = distCell[startId][(*step[0].cells)[i]];\n\n    for (int i = 1; i < L; ++i) {\n        step[i].cells = &letterPos[seq[i]];\n        const vector<int> &prevCells = *step[i - 1].cells;\n        const vector<int> &curCells  = *step[i].cells;\n        step[i].dp.assign(curCells.size(), INF);\n        step[i].pred.assign(curCells.size(), -1);\n        for (int ci = 0; ci < (int)curCells.size(); ++ci) {\n            int cur = curCells[ci];\n            int best = INF, bestIdx = -1;\n            for (int pi = 0; pi < (int)prevCells.size(); ++pi) {\n                int val = step[i - 1].dp[pi] + distCell[prevCells[pi]][cur];\n                if (val < best) {\n                    best = val;\n                    bestIdx = pi;\n                }\n            }\n            step[i].dp[ci] = best;\n            step[i].pred[ci] = bestIdx;\n        }\n    }\n\n    // find cheapest last cell\n    const vector<int> &lastCells = *step[L - 1].cells;\n    int bestCost = INF, bestIdx = -1;\n    for (int i = 0; i < (int)lastCells.size(); ++i)\n        if (step[L - 1].dp[i] < bestCost) {\n            bestCost = step[L - 1].dp[i];\n            bestIdx = i;\n        }\n\n    // backtrack\n    vector<int> walk(L);\n    int idx = bestIdx;\n    for (int i = L - 1; i >= 0; --i) {\n        walk[i] = (*step[i].cells)[idx];\n        if (i > 0) idx = step[i].pred[idx];\n    }\n    return walk;\n}\n\n\n/* ------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M)) return 0;\n    cin >> si >> sj;\n    startId = si * N + sj;\n    board.resize(N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n    pat.resize(M);\n    for (int i = 0; i < M; ++i) cin >> pat[i];\n\n    // ---- build letterPos and coordinates -----------------------\n    letterPos.assign(26, {});\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            int id = i * N + j;\n            char c = board[i][j];\n            letterPos[c - 'A'].push_back(id);\n            row[id] = i; col[id] = j;\n        }\n\n    // ---- all pairwise Manhattan distances ----------------------\n    int C = N * N;\n    for (int a = 0; a < C; ++a)\n        for (int b = 0; b < C; ++b)\n            distCell[a][b] = abs(row[a] - row[b]) + abs(col[a] - col[b]);\n\n    // ---- initial order (0..M-1) and its price ----------------\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    vector<int> seq;\n    int bestPrice = priceOfOrder(order, seq);\n    vector<int> bestOrder = order;\n\n    // ---- random search ----------------------------------------\n    const double TIME_LIMIT = 1.8;           // seconds\n    auto start = chrono::high_resolution_clock::now();\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    int iterations = 0;\n    while (true) {\n        if (iterations % 500 == 0) {\n            auto now = chrono::high_resolution_clock::now();\n            if (chrono::duration<double>(now - start).count() > TIME_LIMIT)\n                break;\n        }\n        shuffle(order.begin(), order.end(), rng);\n        int curPrice = priceOfOrder(order, seq);\n        if (curPrice < bestPrice) {\n            bestPrice = curPrice;\n            bestOrder = order;\n        }\n        ++iterations;\n    }\n\n    // ---- output the walk for the best order --------------------\n    vector<int> walk = reconstructWalk(bestOrder);\n    for (int cell : walk) {\n        int i = cell / N;\n        int j = cell % N;\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<pair<int,int>>> shapes;          // oil\u2011field shapes (not used in the basic version)\n\n/* ------------------------------------------------------------------ */\n/*   communication helpers                                            */\nint query_single(int i, int j) {\n    cout << \"q 1 \" << i << ' ' << j << endl;\n    int ret; cin >> ret;\n    return ret;\n}\n\nint query_set(const vector<pair<int,int>>& cells) {\n    int k = (int)cells.size();\n    cout << \"q \" << k;\n    for (auto [i, j] : cells) cout << ' ' << i << ' ' << j;\n    cout << endl;\n    int ret; cin >> ret;\n    return ret;\n}\n\n/* ------------------------------------------------------------------ */\n/*   estimate true sum v(S) from a noisy answer                       */\ninline double est_sum(int answer, int k) {\n    // answer \u2248 round( max(0, x) ),   x ~ N( k\u00b7\u03b5 + (1\u20112\u03b5)\u00b7v(S) , k\u00b7\u03b5\u00b7(1\u2011\u03b5) )\n    double mu = answer;                     // treat answer as the observed mean\n    return (mu - k * eps) / (1.0 - 2.0 * eps);\n}\n\n/* ------------------------------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---- read description ---------------------------------------- */\n    if (!(cin >> N >> M >> eps)) return 0;\n    shapes.resize(M);\n    for (int k = 0; k < M; ++k) {\n        int d; cin >> d;\n        shapes[k].resize(d);\n        for (int i = 0; i < d; ++i) {\n            int x, y; cin >> x >> y;\n            shapes[k][i] = {x, y};\n        }\n    }\n\n    /* ---- data structures ----------------------------------------- */\n    // 0 = unknown, 1 = oil, 2 = no oil\n    vector<char> row_flag(N, 0), col_flag(N, 0);\n    vector<vector<char>> cell_flag(N, vector<char>(N, 0));\n\n    /* ---- Phase 1 : rows ------------------------------------------ */\n    for (int r = 0; r < N; ++r) {\n        vector<pair<int,int>> cells;\n        cells.reserve(N);\n        for (int c = 0; c < N; ++c) cells.emplace_back(r, c);\n\n        int ans = query_set(cells);\n        double v_est = est_sum(ans, N);\n\n        if (v_est > 0.5) {                     // probably contains oil\n            row_flag[r] = 1;\n        } else {                               // probably empty\n            row_flag[r] = 2;\n            for (int c = 0; c < N; ++c) cell_flag[r][c] = 2;\n        }\n    }\n\n    /* ---- Phase 2 : columns --------------------------------------- */\n    for (int c = 0; c < N; ++c) {\n        vector<pair<int,int>> cells;\n        cells.reserve(N);\n        for (int r = 0; r < N; ++r) cells.emplace_back(r, c);\n\n        int ans = query_set(cells);\n        double v_est = est_sum(ans, N);\n\n        if (v_est > 0.5) {\n            col_flag[c] = 1;\n        } else {\n            col_flag[c] = 2;\n            for (int r = 0; r < N; ++r) cell_flag[r][c] = 2;\n        }\n    }\n\n    /* ---- Phase 3 : collect candidates ---------------------------- */\n    vector<pair<int,int>> cand;\n    for (int r = 0; r < N; ++r) if (row_flag[r] == 1)\n        for (int c = 0; c < N; ++c)\n            if (col_flag[c] == 1 && cell_flag[r][c] == 0)\n                cand.emplace_back(r, c);\n\n    /* ---- Phase 4 : exact drill of all candidates --------------- */\n    vector<pair<int,int>> answer;\n    for (auto [r, c] : cand) {\n        int v = query_single(r, c);\n        if (v > 0) {\n            answer.emplace_back(r, c);\n            cell_flag[r][c] = 1;\n        } else {\n            cell_flag[r][c] = 2;\n        }\n    }\n\n    /* ---- first final answer -------------------------------------- */\n    cout << \"a \" << answer.size();\n    for (auto [r, c] : answer) cout << ' ' << r << ' ' << c;\n    cout << endl;\n\n    int ok;  cin >> ok;\n    if (ok == 1) return 0;                     // success\n\n    /* ---- Fallback \u2013 should happen only rarely -------------------- */\n    // every cell that stayed \"dry\" is rechecked\n    for (int r = 0; r < N; ++r)\n        for (int c = 0; c < N; ++c)\n            if (cell_flag[r][c] == 2) {\n                int v = query_single(r, c);\n                if (v > 0) answer.emplace_back(r, c);\n            }\n\n    cout << \"a \" << answer.size();\n    for (auto [r, c] : answer) cout << ' ' << r << ' ' << c;\n    cout << endl;\n    cin >> ok;                                 // we trust it is correct now\n\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXW = 1000;                 // W is fixed to 1000 in the problem\n\n/*------------------------------------------------------------*/\n/*  geometry structures                                       */\n\nstruct Rect {\n    int x0, y0, x1, y1;               // (x0,y0) top\u2011left, (x1,y1) bottom\u2011right\n};\n\nstruct Region {\n    int x, y, w, h;                    // top\u2011left corner, width, height\n    int area() const { return w * h; }\n};\n\n/*------------------------------------------------------------*/\n/*  packing of one day                                       */\n\nstatic vector<Rect> pack_day(const vector<int>& request, int W,\n                             int N){\n    // request[k] = a[d][k]\n    vector<pair<int,int>> ord;          // (area , original index)\n    ord.reserve(N);\n    for(int k=0;k<N;k++) ord.emplace_back(request[k], k);\n    sort(ord.begin(), ord.end(),\n         [](const pair<int,int>& A, const pair<int,int>& B){\n             return A.first > B.first;           // decreasing area\n         });\n\n    vector<Region> freeReg;\n    freeReg.push_back({0,0,W,W});                // the whole hall\n\n    vector<Rect> answer(N);\n\n    for(auto [area, idx] : ord){\n        // ---- choose a free region that can contain the rectangle\n        int sel = -1;\n        for(int i=0;i<(int)freeReg.size();i++){\n            if(freeReg[i].area() >= area){\n                if(sel==-1 || freeReg[i].area() < freeReg[sel].area())\n                    sel = i;\n            }\n        }\n        // (the problem guarantees that such a region exists)\n        Region R = freeReg[sel];\n        // ---- choose size of the rectangle\n        int w = min(R.w, max(1, (int)std::sqrt((double)area)));\n        int h = (area + w - 1) / w;               // ceil\n        if(h > R.h){\n            // does not fit, use the whole width of the region\n            w = R.w;\n            h = (area + w - 1) / w;\n        }\n        // ---- store rectangle\n        answer[idx] = {R.x, R.y, R.x + w, R.y + h};\n\n        // ---- create the two leftover regions (guillotine split)\n        // right part (if any)\n        if(w < R.w){\n            freeReg.push_back({R.x + w, R.y, R.w - w, R.h});\n        }\n        // bottom part of the left strip (if any)\n        if(h < R.h){\n            freeReg.push_back({R.x, R.y + h, w, R.h - h});\n        }\n        // delete the used region (swap with last)\n        freeReg[sel] = freeReg.back();\n        freeReg.pop_back();\n    }\n    return answer;\n}\n\n/*------------------------------------------------------------*/\n/*  edge matrices                                             */\n\nstruct EdgeMatrices{\n    vector<vector<char>> H;   // H[i][j] : horizontal edge (i,0..W-1)  i=1..W-1\n    vector<vector<char>> V;   // V[i][j] : vertical   edge (0..W-1,j)  j=1..W-1\n    EdgeMatrices(int W){\n        H.assign(W+1, vector<char>(W, 0));\n        V.assign(W, vector<char>(W+1, 0));\n    }\n    void clear(){\n        for(auto &row : H) fill(row.begin(), row.end(), 0);\n        for(auto &row : V) fill(row.begin(), row.end(), 0);\n    }\n};\n\nvoid mark_edges(const vector<Rect>& rects, int W, EdgeMatrices& em){\n    em.clear();\n    for(const Rect& r : rects){\n        // top side\n        if(r.x0 > 0){\n            for(int j = r.y0; j < r.y1; ++j) em.H[r.x0][j] = 1;\n        }\n        // bottom side\n        if(r.x1 < W){\n            for(int j = r.y0; j < r.y1; ++j) em.H[r.x1][j] = 1;\n        }\n        // left side\n        if(r.y0 > 0){\n            for(int i = r.x0; i < r.x1; ++i) em.V[i][r.y0] = 1;\n        }\n        // right side\n        if(r.y1 < W){\n            for(int i = r.x0; i < r.x1; ++i) em.V[i][r.y1] = 1;\n        }\n    }\n}\n\n/*------------------------------------------------------------*/\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\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\n    vector<vector<Rect>> allRects(D, vector<Rect>(N));\n    EdgeMatrices prev(W), cur(W);\n    long long totalCost = 0;               // only for debugging, not needed for output\n\n    for(int d=0; d<D; ++d){\n        // ----- pack the day\n        allRects[d] = pack_day(a[d], W, N);\n        // ----- build edge matrices\n        mark_edges(allRects[d], W, cur);\n        // ----- compute transition cost (L0 = 0 is special)\n        if(d > 0){\n            long long Ld = 0;\n            for(int i=1;i<W;i++)\n                for(int j=0;j<W;j++)\n                    Ld += (prev.H[i][j] != cur.H[i][j]);\n            for(int i=0;i<W;i++)\n                for(int j=1;j<W;j++)\n                    Ld += (prev.V[i][j] != cur.V[i][j]);\n            totalCost += Ld;\n        }\n        // ----- store current matrices as previous for the next day\n        prev.H.swap(cur.H);\n        prev.V.swap(cur.V);\n    }\n\n    // ----- output\n    for(int d=0; d<D; ++d){\n        for(int k=0; k<N; ++k){\n            const Rect& r = allRects[d][k];\n            cout << r.x0 << ' ' << r.y0 << ' ' << r.x1 << ' ' << r.y1 << '\\n';\n        }\n    }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MOD = 998244353;\n\nstruct Op {\n    int m;\n    int p;\n    int q;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n    vector<vector<int>> initialBoard(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> initialBoard[i][j];\n    \n    vector<vector<vector<int>>> stamp(M, vector<vector<int>>(3, vector<int>(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                cin >> stamp[m][i][j];\n    \n    // Precompute all possible placements (operation types)\n    vector<Op> allOps;\n    for (int m = 0; m < M; ++m)\n        for (int p = 0; p <= N - 3; ++p)\n            for (int q = 0; q <= N - 3; ++q)\n                allOps.push_back({m, p, q});\n    \n    // Utility functions\n    auto boardScore = [&](const vector<vector<int>>& b) -> long long {\n        long long s = 0;\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                s += b[i][j];\n        return s;\n    };\n    \n    auto computeAddDelta = [&](const vector<vector<int>>& b, const Op& op) -> long long {\n        const auto& s = stamp[op.m];\n        long long delta = 0;\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                int old = b[op.p + i][op.q + j];\n                int add = s[i][j];\n                int sum = old + add;\n                if (sum >= MOD) delta += add - MOD;\n                else delta += add;\n            }\n        }\n        return delta;\n    };\n    \n    auto computeRemoveDelta = [&](const vector<vector<int>>& b, const Op& op) -> long long {\n        const auto& s = stamp[op.m];\n        long long delta = 0;\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                int old = b[op.p + i][op.q + j];\n                int sv = s[i][j];\n                int newMod = (old >= sv) ? old - sv : old + MOD - sv;\n                delta += newMod - old;\n            }\n        }\n        return delta;\n    };\n    \n    auto applyAdd = [&](vector<vector<int>>& b, long long& score, const Op& op) {\n        const auto& s = stamp[op.m];\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                int old = b[op.p + i][op.q + j];\n                int add = s[i][j];\n                int sum = old + add;\n                int newMod = (sum >= MOD) ? sum - MOD : sum;\n                b[op.p + i][op.q + j] = newMod;\n                score += newMod - old;\n            }\n        }\n    };\n    \n    auto applyRemove = [&](vector<vector<int>>& b, long long& score, const Op& op) {\n        const auto& s = stamp[op.m];\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                int old = b[op.p + i][op.q + j];\n                int sv = s[i][j];\n                int newMod = (old >= sv) ? old - sv : old + MOD - sv;\n                b[op.p + i][op.q + j] = newMod;\n                score += newMod - old;\n            }\n        }\n    };\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    long long bestScore = -1;\n    vector<Op> bestOps;\n    \n    const double TIME_LIMIT = 1.8;\n    auto startTime = chrono::steady_clock::now();\n    \n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - startTime).count();\n        if (elapsed > TIME_LIMIT) break;\n        \n        // Reset to initial board\n        vector<vector<int>> curBoard = initialBoard;\n        long long curScore = boardScore(curBoard);\n        vector<Op> curOps;\n        \n        // Outer loop: alternate addition and removal until stable\n        while (true) {\n            // ----- Addition phase -----\n            bool added = false;\n            while ((int)curOps.size() < K) {\n                // random order for scanning candidates\n                vector<Op> shuffled = allOps;\n                shuffle(shuffled.begin(), shuffled.end(), rng);\n                long long bestDelta = 0;\n                vector<Op> bestCandidates;\n                for (const Op& op : shuffled) {\n                    long long d = computeAddDelta(curBoard, op);\n                    if (d > bestDelta) {\n                        bestDelta = d;\n                        bestCandidates.clear();\n                        bestCandidates.push_back(op);\n                    } else if (d == bestDelta && d > 0) {\n                        bestCandidates.push_back(op);\n                    }\n                }\n                if (bestDelta <= 0) break;\n                const Op& chosen = bestCandidates[rng() % bestCandidates.size()];\n                applyAdd(curBoard, curScore, chosen);\n                curOps.push_back(chosen);\n                added = true;\n            }\n            \n            // ----- Removal phase -----\n            bool removed = false;\n            while (true) {\n                long long bestRemoveDelta = 0;\n                vector<int> idxCandidates;\n                for (int i = 0; i < (int)curOps.size(); ++i) {\n                    long long d = computeRemoveDelta(curBoard, curOps[i]);\n                    if (d > bestRemoveDelta) {\n                        bestRemoveDelta = d;\n                        idxCandidates.clear();\n                        idxCandidates.push_back(i);\n                    } else if (d == bestRemoveDelta && d > 0) {\n                        idxCandidates.push_back(i);\n                    }\n                }\n                if (bestRemoveDelta <= 0) break;\n                int idx = idxCandidates[rng() % idxCandidates.size()];\n                Op op = curOps[idx];\n                applyRemove(curBoard, curScore, op);\n                // remove from vector\n                curOps[idx] = curOps.back();\n                curOps.pop_back();\n                removed = true;\n            }\n            \n            if (!added && !removed) break;\n        }\n        \n        if (curScore > bestScore) {\n            bestScore = curScore;\n            bestOps = curOps;\n        }\n    }\n    \n    cout << bestOps.size() << \"\\n\";\n    for (auto &op : bestOps) {\n        cout << op.m << \" \" << op.p << \" \" << op.q << \"\\n\";\n    }\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos {\n    int r = -1, c = -1;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n    const int TOTAL = N * N;\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) cin >> A[i][j];\n\n    // for every container remember the row where it appears\n    vector<int> sourceRow(TOTAL);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            sourceRow[A[i][j]] = i;\n\n    // grid: id of container or -1\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    // position of each container while it is on the grid\n    vector<Pos> contPos(TOTAL, Pos());\n\n    // how many containers of each row have already appeared\n    vector<int> recCnt(N, 0);\n    // how many containers have been dispatched\n    int dispatched = 0;\n\n    // the only active crane \u2013 the large one\n    struct Crane {\n        int r = 0, c = 0;\n        bool holding = false;\n        int holdId = -1;\n    } large;\n\n    // output strings, one per row\n    vector<string> out(N);\n\n    int turn = 0;\n    const int LIMIT = 10000;\n\n    while (dispatched < TOTAL && turn < LIMIT) {\n        /* ---- step 1 : containers appear at receiving gates ---- */\n        for (int i = 0; i < N; ++i) {\n            if (recCnt[i] >= N) continue;               // no more containers for this row\n            if (grid[i][0] != -1) continue;              // square already occupied\n            // a crane holding a container blocks the square\n            bool blocked = (large.r == i && large.c == 0 && large.holding);\n            if (!blocked) {\n                int cid = A[i][recCnt[i]];\n                grid[i][0] = cid;\n                contPos[cid] = {i, 0};\n                ++recCnt[i];\n            }\n        }\n\n        /* ---- step 2 : actions of the cranes ---- */\n        // small cranes : bomb in the first turn, afterwards only '.'\n        for (int i = 1; i < N; ++i) {\n            if (turn == 0) out[i].push_back('B');\n            else           out[i].push_back('.');\n        }\n\n        // large crane (row 0)\n        char act = '.';\n        if (large.holding) {\n            int targetRow = large.holdId / N;\n            int targetCol = N - 1;\n            if (large.r != targetRow) {                 // vertical move\n                int dr = (targetRow > large.r) ? 1 : -1;\n                act = (dr == 1) ? 'D' : 'U';\n                large.r += dr;\n            } else if (large.c != targetCol) {          // horizontal move to the right\n                act = 'R';\n                large.c += 1;\n            } else {                                    // on the dispatch gate -> drop\n                grid[large.r][large.c] = large.holdId;\n                contPos[large.holdId] = {large.r, large.c};\n                large.holding = false;\n                large.holdId = -1;\n                act = 'Q';\n            }\n        } else { // not holding \u2013 try to pick a waiting container\n            int targetRow = -1;\n            for (int i = 0; i < N; ++i) {\n                if (grid[i][0] != -1) { targetRow = i; break; }\n            }\n            if (targetRow == -1) {                      // nothing to do\n                act = '.';\n            } else {\n                if (large.r != targetRow) {             // vertical move\n                    int dr = (targetRow > large.r) ? 1 : -1;\n                    act = (dr == 1) ? 'D' : 'U';\n                    large.r += dr;\n                } else if (large.c != 0) {              // move left to column 0\n                    act = 'L';\n                    large.c -= 1;\n                } else {                                // we are on the container, pick it\n                    int cid = grid[large.r][large.c];\n                    // a container must be here\n                    large.holding = true;\n                    large.holdId = cid;\n                    grid[large.r][large.c] = -1;\n                    contPos[cid] = Pos();\n                    act = 'P';\n                }\n            }\n        }\n        out[0].push_back(act);\n\n        /* ---- step 3 : containers leave the dispatch gates ---- */\n        for (int i = 0; i < N; ++i) {\n            int cid = grid[i][N - 1];\n            if (cid != -1) {\n                ++dispatched;\n                grid[i][N - 1] = -1;\n                contPos[cid] = Pos();\n            }\n        }\n\n        ++turn;\n    }\n\n    // all rows must have strings of the same length (= number of turns)\n    for (int i = 0; i < N; ++i) {\n        if ((int)out[i].size() < turn) out[i] += string(turn - out[i].size(), '.');\n        cout << out[i] << '\\n';\n    }\n    return 0;\n}","ahc034":"#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    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    // working copy of the heights\n    vector<vector<int>> rem = h;\n\n    int curR = 0, curC = 0;      // truck position\n    int load = 0;                // soil on the truck\n    vector<string> ops;          // list of operations\n\n    auto pushMove = [&](char dir) {\n        ops.emplace_back(string(1, dir));\n    };\n    auto pushLoad = [&](int d) {\n        ops.emplace_back(\"+\" + to_string(d));\n        load += d;\n    };\n    auto pushUnload = [&](int d) {\n        ops.emplace_back(\"-\" + to_string(d));\n        load -= d;\n    };\n\n    // move the truck to (tr,tc) along a Manhattan path\n    auto moveTo = [&](int tr, int tc) {\n        int dr = tr - curR;\n        int dc = tc - curC;\n        while (dr != 0) {\n            int step = (dr > 0) ? 1 : -1;\n            char dir = (dr > 0) ? 'D' : 'U';\n            pushMove(dir);\n            curR += step;\n            dr -= step;\n        }\n        while (dc != 0) {\n            int step = (dc > 0) ? 1 : -1;\n            char dir = (dc > 0) ? 'R' : 'L';\n            pushMove(dir);\n            curC += step;\n            dc -= step;\n        }\n    };\n\n    // find the nearest cell that satisfies a predicate\n    auto nearest = [&](auto pred) -> pair<int,int> {\n        int bestDist = INT_MAX;\n        pair<int,int> best(-1,-1);\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (!pred(i,j)) continue;\n                int dist = abs(i - curR) + abs(j - curC);\n                if (dist < bestDist) {\n                    bestDist = dist;\n                    best = {i,j};\n                }\n            }\n        }\n        return best;\n    };\n\n    while (true) {\n        // nearest hill (positive remaining height)\n        auto hill = nearest([&](int i,int j){ return rem[i][j] > 0; });\n        if (hill.first == -1) break;                 // no hill left -> finished\n\n        // go there and load everything\n        moveTo(hill.first, hill.second);\n        int d = rem[hill.first][hill.second];        // >0\n        pushLoad(d);\n        rem[hill.first][hill.second] = 0;\n\n        // deliver the whole load to holes\n        while (load > 0) {\n            auto hole = nearest([&](int i,int j){ return rem[i][j] < 0; });\n            // there must be a hole, otherwise the input would be inconsistent\n            moveTo(hole.first, hole.second);\n            int demand = -rem[hole.first][hole.second]; // positive\n            int unload = min(load, demand);\n            pushUnload(unload);\n            rem[hole.first][hole.second] += unload;    // still \u2264 0\n        }\n    }\n\n    // (optional) safety \u2013 should never be needed because sums are zero\n    while (load > 0) {\n        auto hole = nearest([&](int i,int j){ return rem[i][j] < 0; });\n        if (hole.first == -1) break;\n        moveTo(hole.first, hole.second);\n        int demand = -rem[hole.first][hole.second];\n        int unload = min(load, demand);\n        pushUnload(unload);\n        rem[hole.first][hole.second] += unload;\n    }\n\n    // output all operations\n    for (auto &s : ops) cout << s << '\\n';\n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int N = 6;               // fixed in the statement\n    const int M = 15;              // fixed in the statement\n    const int T = 10;              // fixed in the statement\n    const int SEED_CNT = 2 * N * (N - 1);   // 60\n    const int CELL_CNT = N * N;            // 36\n    const int EDGE_CNT = 2 * N * (N - 1);   // 60\n\n    // ---------- read initial data ----------\n    int tmpN, tmpM, tmpT;\n    if (!(cin >> tmpN >> tmpM >> tmpT)) return 0;\n    // the values are the same as the constants above, ignore them\n\n    vector<vector<int>> seed(SEED_CNT, vector<int>(M));\n    vector<int> seedSum(SEED_CNT, 0);\n    vector<int> X(M, 0);                 // per\u2011dimension maxima of the initial seeds\n\n    for (int i = 0; i < SEED_CNT; ++i) {\n        int s = 0;\n        for (int j = 0; j < M; ++j) {\n            int x; cin >> x;\n            seed[i][j] = x;\n            s += x;\n            X[j] = max(X[j], x);\n        }\n        seedSum[i] = s;\n    }\n\n    // build list of edges (neighbour pairs) once\n    vector<pair<int,int>> edges;\n    edges.reserve(EDGE_CNT);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            int p = i * N + j;\n            if (i + 1 < N) edges.emplace_back(p, (i + 1) * N + j);\n            if (j + 1 < N) edges.emplace_back(p, i * N + (j + 1));\n        }\n\n    // helper: best possible child of two seeds\n    auto best_possible = [&](int a, int b)->int{\n        int ret = 0;\n        const auto &A = seed[a];\n        const auto &B = seed[b];\n        for (int i = 0; i < M; ++i) ret += max(A[i], B[i]);\n        return ret;\n    };\n\n    // helper: evaluate a whole placement\n    // returns {total_sum_of_best , max_best}\n    auto evaluate = [&](const vector<int> &grid)->pair<int,int>{\n        int total = 0, mx = 0;\n        for (auto [u,v] : edges) {\n            int val = best_possible(grid[u], grid[v]);\n            total += val;\n            mx = max(mx, val);\n        }\n        return {total, mx};\n    };\n\n    // ---------- round loop ----------\n    for (int round = 0; round < T; ++round) {\n        // ---- choose the initial 36 seeds: the 36 with largest sum ----\n        vector<int> allIdx(SEED_CNT);\n        iota(allIdx.begin(), allIdx.end(), 0);\n        sort(allIdx.begin(), allIdx.end(),\n             [&](int a, int b){ return seedSum[a] > seedSum[b]; });\n        vector<int> selectedIdx(allIdx.begin(), allIdx.begin() + CELL_CNT);   // 36 seeds\n\n        // best placement found in this round\n        vector<int> bestGrid;\n        long long bestObj = -(1LL<<60);\n\n        // ---- several restarts of hill climbing ----\n        const int RESTARTS = 3;\n        const int ITERATIONS = 2000;\n        const int WEIGHT_MAX = 1000;          // max_best is multiplied by this\n\n        for (int rep = 0; rep < RESTARTS; ++rep) {\n            // current placement: random permutation of the 36 selected seeds\n            vector<int> grid = selectedIdx;\n            shuffle(grid.begin(), grid.end(), mt19937{ random_device{}() });\n\n            // current used / unused lists\n            vector<char> used(SEED_CNT, 0);\n            for (int id : grid) used[id] = 1;\n            vector<int> unused;\n            unused.reserve(SEED_CNT - CELL_CNT);\n            for (int i = 0; i < SEED_CNT; ++i) if (!used[i]) unused.push_back(i);\n\n            // evaluate starting placement\n            auto [totalSum, maxBest] = evaluate(grid);\n            long long curObj = (long long)maxBest * WEIGHT_MAX + totalSum;\n\n            // hill climbing\n            for (int it = 0; it < ITERATIONS; ++it) {\n                bool moveWithUnused = false;\n                if (!unused.empty() && (rand() % 2)) moveWithUnused = true;\n\n                if (moveWithUnused) {\n                    // exchange a planted seed with an unused one\n                    int pos = rand() % CELL_CNT;\n                    int oldSeed = grid[pos];\n                    int idx = rand() % unused.size();\n                    int newSeed = unused[idx];\n                    // temporarily place newSeed\n                    grid[pos] = newSeed;\n                    auto [newSum, newMax] = evaluate(grid);\n                    long long newObj = (long long)newMax * WEIGHT_MAX + newSum;\n                    if (newObj > curObj) {               // accept\n                        used[oldSeed] = 0;\n                        used[newSeed] = 1;\n                        unused[idx] = oldSeed;            // replace\n                        curObj = newObj;\n                        // totalSum, maxBest are already updated by evaluate\n                    } else {\n                        grid[pos] = oldSeed;               // revert\n                    }\n                } else {\n                    // swap two positions\n                    int p = rand() % CELL_CNT;\n                    int q = rand() % CELL_CNT;\n                    if (p == q) continue;\n                    swap(grid[p], grid[q]);\n                    auto [newSum, newMax] = evaluate(grid);\n                    long long newObj = (long long)newMax * WEIGHT_MAX + newSum;\n                    if (newObj > curObj) {               // accept\n                        curObj = newObj;\n                    } else {\n                        swap(grid[p], grid[q]);           // revert\n                    }\n                }\n            } // end of iterations\n\n            // keep the best placement among the restarts\n            if (curObj > bestObj) {\n                bestObj = curObj;\n                bestGrid = grid;\n            }\n        } // restarts\n\n        // ---- output the best grid ----\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (j) cout << ' ';\n                cout << bestGrid[i * N + j];\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n\n        // ---- read the children, they become the seed pool for the next round ----\n        for (int i = 0; i < SEED_CNT; ++i) {\n            int s = 0;\n            for (int j = 0; j < M; ++j) {\n                int x; cin >> x;\n                seed[i][j] = x;\n                s += x;\n            }\n            seedSum[i] = s;\n        }\n    } // round loop\n\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\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> s(N), t(N);\n    for (int i = 0; i < N; ++i) cin >> s[i];\n    for (int i = 0; i < N; ++i) cin >> t[i];\n\n    // ----- board description -----\n    vector<vector<char>> is_src(N, vector<char>(N, 0));\n    vector<vector<char>> is_tgt(N, vector<char>(N, 0));\n    vector<vector<char>> occupied(N, vector<char>(N, 0));\n    int src_rem = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            occupied[i][j] = (s[i][j] == '1');\n            if (s[i][j] == '1' && t[i][j] == '0') {\n                is_src[i][j] = 1;\n                ++src_rem;\n            }\n            if (t[i][j] == '1' && s[i][j] == '0') {\n                is_tgt[i][j] = 1;\n            }\n        }\n    }\n\n    // ----- arm geometry -----\n    const int Vout = 5;                     // root + 4 leaves, always \u2264 V\n    const int C = 4;                        // number of leaves we really use\n    // directions: 0 = east, 1 = north, 2 = west, 3 = south\n    const int dx[4] = {0, -1, 0, +1};\n    const int dy[4] = {+1, 0, -1, 0};\n\n    // leaves are numbered 1..C, direction after the two initial turns\n    vector<int> dir(C + 1, 0);               // currently all east\n    vector<char> loaded(C + 1, 0);           // initially empty\n    int loaded_cnt = 0;\n\n    // root initial position\n    int rx = 0, ry = 0;\n\n    // ----- output: tree description -----\n    cout << Vout << '\\n';\n    for (int i = 1; i < Vout; ++i) cout << 0 << ' ' << 1 << '\\n';\n    cout << rx << ' ' << ry << '\\n';\n\n    // ----- containers for the operation strings -----\n    vector<string> ops;\n\n    // ----- first two turns : rotate leaves to the four directions -----\n    // turn 0 : . L L R   (leaf 2,3,4 are rotated)\n    {\n        string op;\n        op.push_back('.');                 // root\n        op.push_back('.');                 // leaf 1\n        op.push_back('L');                 // leaf 2\n        op.push_back('L');                 // leaf 3\n        op.push_back('R');                 // leaf 4\n        for (int i = 0; i < Vout; ++i) op.push_back('.'); // actions\n        ops.push_back(op);\n        // apply rotations\n        dir[2] = (dir[2] + 1) & 3;          // L -> +1\n        dir[3] = (dir[3] + 1) & 3;          // L\n        dir[4] = (dir[4] + 3) & 3;          // R -> +3\n    }\n    // turn 1 : . . L .   (leaf 3 gets its second rotation)\n    {\n        string op;\n        op.push_back('.');                 // root\n        op.push_back('.');                 // leaf 1\n        op.push_back('.');                 // leaf 2\n        op.push_back('L');                 // leaf 3\n        op.push_back('.');                 // leaf 4\n        for (int i = 0; i < Vout; ++i) op.push_back('.');\n        ops.push_back(op);\n        // apply rotation\n        dir[3] = (dir[3] + 1) & 3;          // now leaf 3 points west\n    }\n\n    // ----- helper: evaluate a candidate root move -----\n    auto evaluate_move = [&](int nx, int ny, int &actions, int &dist, int mode) {\n        actions = 0;\n        // count possible actions\n        for (int i = 1; i <= C; ++i) {\n            int d = dir[i];\n            int cx = nx + dx[d];\n            int cy = ny + dy[d];\n            if (cx < 0 || cx >= N || cy < 0 || cy >= N) continue;\n            if (!loaded[i] && is_src[cx][cy] && occupied[cx][cy]) ++actions;\n            else if (loaded[i] && is_tgt[cx][cy] && !occupied[cx][cy]) ++actions;\n        }\n\n        // distance to the nearest needed square (mode : 0 = pickup, 1 = delivery)\n        dist = INF;\n        if (mode == 0) { // pickup\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) if (is_src[i][j] && occupied[i][j]) {\n                    for (int d = 0; d < 4; ++d) {\n                        int ni = i + dx[d];\n                        int nj = j + dy[d];\n                        if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                        int ddist = abs(nx - ni) + abs(ny - nj);\n                        dist = min(dist, ddist);\n                    }\n                }\n            }\n        } else if (mode == 1) { // delivery\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) if (is_tgt[i][j] && !occupied[i][j]) {\n                    for (int d = 0; d < 4; ++d) {\n                        int ni = i + dx[d];\n                        int nj = j + dy[d];\n                        if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                        int ddist = abs(nx - ni) + abs(ny - nj);\n                        dist = min(dist, ddist);\n                    }\n                }\n            }\n        }\n    };\n\n    // ----- main simulation loop -----\n    const vector<char> move_chars = {'U','D','L','R','.'};\n    const vector<int> mv_dx = {-1, +1, 0, 0, 0};\n    const vector<int> mv_dy = {0, 0, -1, +1, 0};\n\n    while (src_rem > 0 || loaded_cnt > 0) {\n        // decide mode\n        bool have_empty = false;\n        for (int i = 1; i <= C; ++i) if (!loaded[i]) { have_empty = true; break; }\n        int mode = -1;  // 0 = pickup, 1 = delivery\n        if (src_rem > 0 && have_empty) mode = 0;\n        else if (loaded_cnt > 0) mode = 1;\n        else break; // finished\n\n        // try all 5 moves\n        int best_move = -1, best_actions = -1, best_dist = INF;\n        for (int m = 0; m < 5; ++m) {\n            char mc = move_chars[m];\n            int nx = rx + mv_dx[m];\n            int ny = ry + mv_dy[m];\n            if (mc != '.' && (nx < 0 || nx >= N || ny < 0 || ny >= N)) continue;\n            int actions, dist;\n            evaluate_move(nx, ny, actions, dist, mode);\n            if (actions > best_actions ||\n                (actions == best_actions && dist < best_dist)) {\n                best_move = m;\n                best_actions = actions;\n                best_dist = dist;\n            }\n        }\n        // if nothing is possible, still move closer (any move)\n        if (best_move == -1) {\n            for (int m = 0; m < 5; ++m) {\n                char mc = move_chars[m];\n                int nx = rx + mv_dx[m];\n                int ny = ry + mv_dy[m];\n                if (mc != '.' && (nx < 0 || nx >= N || ny < 0 || ny >= N)) continue;\n                best_move = m; break;\n            }\n        }\n\n        // apply the chosen move and build the operation string\n        char mv = move_chars[best_move];\n        int nx = rx + mv_dx[best_move];\n        int ny = ry + mv_dy[best_move];\n        string op;\n        op.push_back(mv);                     // root movement\n        for (int i = 1; i < Vout; ++i) op.push_back('.'); // no rotations\n\n        // actions, processed in vertex order 0..V'-1\n        op.push_back('.');                    // root never acts\n        for (int i = 1; i <= C; ++i) {\n            int d = dir[i];\n            int cx = nx + dx[d];\n            int cy = ny + dy[d];\n            bool can = false;\n            if (!loaded[i] && cx >= 0 && cx < N && cy >= 0 && cy < N &&\n                is_src[cx][cy] && occupied[cx][cy]) can = true;\n            else if (loaded[i] && cx >= 0 && cx < N && cy >= 0 && cy < N &&\n                     is_tgt[cx][cy] && !occupied[cx][cy]) can = true;\n\n            if (can) {\n                op.push_back('P');\n                if (!loaded[i]) { // pick\n                    occupied[cx][cy] = 0;\n                    loaded[i] = 1;\n                    --src_rem;\n                    ++loaded_cnt;\n                } else { // deliver\n                    occupied[cx][cy] = 1;\n                    loaded[i] = 0;\n                    --loaded_cnt;\n                }\n            } else {\n                op.push_back('.');\n            }\n        }\n        ops.push_back(op);\n\n        // update root position\n        rx = nx; ry = ny;\n\n        // safety: never exceed 100\u202f000 turns\n        if ((int)ops.size() > 100000) break;\n    }\n\n    // ----- output all operations -----\n    for (const string &s : ops) cout << s << '\\n';\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int x, y;          // original coordinates\n    int xi, yi;        // compressed indices\n    int w;             // +1 for mackerel, -1 for sardine\n};\n\nstruct Node {\n    int sum;           // total sum of interval\n    int pref;          // max prefix sum (non empty)\n    int pref_r;        // right end of that prefix\n    int suff;          // max suffix sum (non empty)\n    int suff_l;        // left start of that suffix\n    int best;          // max sub\u2011array sum (non empty)\n    int best_l, best_r;// borders of that sub\u2011array\n};\n\nstatic inline Node combine(const Node &L, const Node &R) {\n    Node C;\n    C.sum = L.sum + R.sum;\n\n    // prefix\n    if (L.pref > L.sum + R.pref) {\n        C.pref = L.pref;\n        C.pref_r = L.pref_r;\n    } else {\n        C.pref = L.sum + R.pref;\n        C.pref_r = R.pref_r;\n    }\n\n    // suffix\n    if (R.suff > R.sum + L.suff) {\n        C.suff = R.suff;\n        C.suff_l = R.suff_l;\n    } else {\n        C.suff = R.sum + L.suff;\n        C.suff_l = L.suff_l;\n    }\n\n    // best\n    C.best = L.best;\n    C.best_l = L.best_l;\n    C.best_r = L.best_r;\n\n    if (R.best > C.best) {\n        C.best = R.best;\n        C.best_l = R.best_l;\n        C.best_r = R.best_r;\n    }\n\n    int cross = L.suff + R.pref;\n    if (cross > C.best) {\n        C.best = cross;\n        C.best_l = L.suff_l;\n        C.best_r = R.pref_r;\n    }\n    return 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<Point> pts;\n    pts.reserve(2 * N);\n    vector<int> xs, ys;\n    for (int i = 0; i < 2 * N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        pts.push_back({x, y, -1, -1, (i < N ? +1 : -1)});\n        xs.push_back(x);\n        ys.push_back(y);\n    }\n\n    // coordinate compression\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    int X = (int)xs.size();\n    int Y = (int)ys.size();\n\n    for (auto &p : pts) {\n        p.xi = lower_bound(xs.begin(), xs.end(), p.x) - xs.begin();\n        p.yi = lower_bound(ys.begin(), ys.end(), p.y) - ys.begin();\n    }\n\n    // points per column\n    vector<vector<pair<int,int>>> byX(X);   // (y_idx , weight)\n    for (const auto &p : pts) {\n        byX[p.xi].push_back({p.yi, p.w});\n    }\n\n    // segment tree for y\u2011direction\n    int M = 1;\n    while (M < Y) M <<= 1;\n    vector<Node> seg(2 * M);\n\n    auto tree_build = [&]() {\n        for (int i = 0; i < Y; ++i) {\n            seg[M + i].sum = 0;\n            seg[M + i].pref = seg[M + i].suff = seg[M + i].best = 0;\n            seg[M + i].pref_r = seg[M + i].suff_l = seg[M + i].best_l = seg[M + i].best_r = i;\n        }\n        for (int i = Y; i < M; ++i) {\n            seg[M + i].sum = 0;\n            seg[M + i].pref = seg[M + i].suff = seg[M + i].best = 0;\n            seg[M + i].pref_r = seg[M + i].suff_l = seg[M + i].best_l = seg[M + i].best_r = i;\n        }\n        for (int i = M - 1; i >= 1; --i)\n            seg[i] = combine(seg[i << 1], seg[i << 1 | 1]);\n    };\n\n    auto tree_reset = [&]() {\n        for (int i = 0; i < Y; ++i) {\n            seg[M + i].sum = 0;\n            seg[M + i].pref = seg[M + i].suff = seg[M + i].best = 0;\n            // positions stay unchanged\n        }\n        for (int i = M - 1; i >= 1; --i)\n            seg[i] = combine(seg[i << 1], seg[i << 1 | 1]);\n    };\n\n    auto tree_add = [&](int y_idx, int delta) {\n        int p = M + y_idx;\n        seg[p].sum += delta;\n        int ns = seg[p].sum;\n        seg[p].pref = seg[p].suff = seg[p].best = ns;\n        // the indices already stored for the leaf stay correct\n        for (p >>= 1; p; p >>= 1)\n            seg[p] = combine(seg[p << 1], seg[p << 1 | 1]);\n    };\n\n    // sweep\n    int bestValue = -1;          // -1 means \u201cnot found\u201d\n    int best_left = -1, best_right = -1;\n    int best_bottom = -1, best_top = -1;\n\n    for (int left = 0; left < X; ++left) {\n        tree_reset();\n        for (int right = left; right < X; ++right) {\n            // add column 'right'\n            for (auto &pr : byX[right]) {\n                tree_add(pr.first, pr.second);\n            }\n            const Node &root = seg[1];\n            int cur = root.best;\n            if (cur > bestValue) {\n                bestValue = cur;\n                best_left = left;\n                best_right = right;\n                best_bottom = root.best_l;\n                best_top    = root.best_r;\n            }\n        }\n    }\n\n    // -----------------------------------------------------------------\n    // build the final rectangle\n    int leftX, rightX, bottomY, topY;\n    // arrays to know which coordinates are occupied (for the \u201cempty\u201d extension)\n    vector<char> usedX(100001, 0), usedY(100001, 0);\n    for (auto &p : pts) {\n        usedX[p.x] = 1;\n        usedY[p.y] = 1;\n    }\n\n    auto unused_coord = [&](const vector<char> &used, int after) {\n        for (int v = after + 1; v <= 100000; ++v)\n            if (!used[v]) return v;\n        for (int v = after - 1; v >= 0; --v)\n            if (!used[v]) return v;\n        return -1; // never happens\n    };\n\n    if (bestValue <= 0) {               // no positive rectangle \u2013 use empty one\n        // pick two unused x\u2011coordinates and two unused y\u2011coordinates\n        int ux1 = -1, ux2 = -1;\n        for (int x = 0; x <= 100000; ++x) if (!usedX[x]) { ux1 = x; break; }\n        for (int x = ux1 + 1; x <= 100000; ++x) if (!usedX[x]) { ux2 = x; break; }\n        int uy1 = -1, uy2 = -1;\n        for (int y = 0; y <= 100000; ++y) if (!usedY[y]) { uy1 = y; break; }\n        for (int y = uy1 + 1; y <= 100000; ++y) if (!usedY[y]) { uy2 = y; break; }\n        leftX = ux1; rightX = ux2;\n        bottomY = uy1; topY = uy2;\n    } else {\n        leftX   = xs[best_left];\n        rightX  = xs[best_right];\n        bottomY = ys[best_bottom];\n        topY    = ys[best_top];\n\n        // ensure width > 0, height > 0 using only empty columns / rows\n        if (leftX == rightX) {\n            int nx = unused_coord(usedX, leftX);\n            if (nx > leftX) rightX = nx;\n            else {\n                rightX = leftX;\n                leftX = nx;\n            }\n        }\n        if (bottomY == topY) {\n            int ny = unused_coord(usedY, bottomY);\n            if (ny > bottomY) topY = ny;\n            else {\n                topY = bottomY;\n                bottomY = ny;\n            }\n        }\n    }\n\n    // -----------------------------------------------------------------\n    // output the rectangle (counter\u2011clockwise order)\n    cout << 4 << \"\\n\";\n    cout << leftX   << \" \" << bottomY << \"\\n\";\n    cout << leftX   << \" \" << topY    << \"\\n\";\n    cout << rightX  << \" \" << topY    << \"\\n\";\n    cout << rightX  << \" \" << bottomY << \"\\n\";\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rectangle {\n    int width, height;\n    int x, y; // top-left corner\n};\n\nstruct Placement {\n    int p; // index\n    int r; // rotation\n    char d; // direction 'U' or 'L'\n    int b; // reference rectangle index\n};\n\nclass Packer {\nprivate:\n    int N;\n    vector<int> w, h;\n    vector<Rectangle> placed;\n    vector<Placement> sequence;\n    \n    // Check if two rectangles overlap\n    bool overlap(const Rectangle& a, const Rectangle& b) {\n        return a.x < b.x + b.width && a.x + a.width > b.x &&\n               a.y < b.y + b.height && a.y + a.height > b.y;\n    }\n    \n    // Simulate placing a rectangle with given parameters\n    // Returns the rectangle with final position\n    Rectangle simulatePlace(int idx, int rot, char dir, int ref) {\n        int width = (rot == 0) ? w[idx] : h[idx];\n        int height = (rot == 0) ? h[idx] : w[idx];\n        \n        Rectangle rect;\n        rect.width = width;\n        rect.height = height;\n        \n        if (dir == 'U') {\n            // Align left edge\n            if (ref == -1) {\n                rect.x = 0;\n            } else {\n                rect.x = placed[ref].x + placed[ref].width;\n            }\n            \n            // Start from bottom and slide up (decrease y)\n            // Find the highest position where it doesn't overlap\n            int best_y = 0;\n            // Check all placed rectangles\n            for (const auto& other : placed) {\n                // Check horizontal overlap\n                if (rect.x < other.x + other.width && rect.x + rect.width > other.x) {\n                    // This rectangle blocks upward movement\n                    best_y = max(best_y, other.y + other.height);\n                }\n            }\n            rect.y = best_y;\n        } else { // 'L'\n            // Align top edge\n            if (ref == -1) {\n                rect.y = 0;\n            } else {\n                rect.y = placed[ref].y + placed[ref].height;\n            }\n            \n            // Start from far right and slide left (decrease x)\n            int best_x = 0;\n            // Check all placed rectangles\n            for (const auto& other : placed) {\n                // Check vertical overlap\n                if (rect.y < other.y + other.height && rect.y + rect.height > other.y) {\n                    // This rectangle blocks leftward movement\n                    best_x = max(best_x, other.x + other.width);\n                }\n            }\n            rect.x = best_x;\n        }\n        \n        return rect;\n    }\n    \npublic:\n    Packer(const vector<int>& w, const vector<int>& h) \n        : N(w.size()), w(w), h(h) {}\n    \n    // Generate a random placement sequence\n    pair<vector<Placement>, long long> generateRandom(mt19937& rng) {\n        placed.clear();\n        sequence.clear();\n        \n        // Randomly decide which rectangles to place\n        // For now, try to place all\n        vector<int> placed_indices;\n        long long totalWH = 0;\n        \n        for (int i = 0; i < N; i++) {\n            // Randomly decide to place or skip\n            uniform_real_distribution<double> dist(0.0, 1.0);\n            bool place = dist(rng) < 0.9; // 90% chance to place\n            \n            if (!place) {\n                totalWH += w[i] + h[i];\n                continue;\n            }\n            \n            // Random rotation, direction, reference\n            uniform_int_distribution<int> rot_dist(0, 1);\n            uniform_int_distribution<int> dir_dist(0, 1);\n            uniform_int_distribution<int> ref_dist(-1, (int)placed_indices.size() - 1);\n            \n            int r = rot_dist(rng);\n            char d = (dir_dist(rng) == 0) ? 'U' : 'L';\n            int b = ref_dist(rng);\n            \n            // Simulate placement\n            Rectangle rect = simulatePlace(i, r, d, b);\n            \n            // Check for overlap (shouldn't happen with our algorithm)\n            bool overlaps = false;\n            for (const auto& other : placed) {\n                if (overlap(rect, other)) {\n                    overlaps = true;\n                    break;\n                }\n            }\n            \n            if (overlaps) {\n                // Fallback: skip this rectangle\n                totalWH += w[i] + h[i];\n                continue;\n            }\n            \n            // Add to placed\n            placed.push_back(rect);\n            placed_indices.push_back(i);\n            \n            // Record placement\n            Placement p;\n            p.p = i;\n            p.r = r;\n            p.d = d;\n            p.b = b;\n            sequence.push_back(p);\n        }\n        \n        // Calculate bounding box\n        int maxX = 0, maxY = 0;\n        for (const auto& rect : placed) {\n            maxX = max(maxX, rect.x + rect.width);\n            maxY = max(maxY, rect.y + rect.height);\n        }\n        \n        long long score = (long long)maxX + maxY + totalWH;\n        return {sequence, score};\n    }\n    \n    // Generate a greedy placement sequence\n    pair<vector<Placement>, long long> generateGreedy() {\n        placed.clear();\n        sequence.clear();\n        long long totalWH = 0;\n        \n        for (int i = 0; i < N; i++) {\n            // Try to place rectangle i\n            int best_r = 0;\n            char best_d = 'U';\n            int best_b = -1;\n            long long bestScore = LLONG_MAX;\n            Rectangle bestRect;\n            \n            // Try all combinations\n            for (int r = 0; r <= 1; r++) {\n                for (char d : {'U', 'L'}) {\n                    // Try references: -1 and all previously placed\n                    vector<int> refs;\n                    refs.push_back(-1);\n                    for (int j = 0; j < (int)placed.size(); j++) {\n                        refs.push_back(j);\n                    }\n                    \n                    for (int b : refs) {\n                        Rectangle rect = simulatePlace(i, r, d, b);\n                        \n                        // Check overlap\n                        bool overlaps = false;\n                        for (const auto& other : placed) {\n                            if (overlap(rect, other)) {\n                                overlaps = true;\n                                break;\n                            }\n                        }\n                        if (overlaps) continue;\n                        \n                        // Calculate new bounding box with this rectangle\n                        int maxX = 0, maxY = 0;\n                        for (const auto& p : placed) {\n                            maxX = max(maxX, p.x + p.width);\n                            maxY = max(maxY, p.y + p.height);\n                        }\n                        maxX = max(maxX, rect.x + rect.width);\n                        maxY = max(maxY, rect.y + rect.height);\n                        \n                        long long score = (long long)maxX + maxY;\n                        \n                        if (score < bestScore) {\n                            bestScore = score;\n                            best_r = r;\n                            best_d = d;\n                            best_b = b;\n                            bestRect = rect;\n                        }\n                    }\n                }\n            }\n            \n            // Decide whether to place or skip\n            // Calculate current bounding box\n            int curMaxX = 0, curMaxY = 0;\n            for (const auto& p : placed) {\n                curMaxX = max(curMaxX, p.x + p.width);\n                curMaxY = max(curMaxY, p.y + p.height);\n            }\n            long long curScore = (long long)curMaxX + curMaxY;\n            \n            if (bestScore > curScore + w[i] + h[i]) {\n                // Skip this rectangle\n                totalWH += w[i] + h[i];\n            } else {\n                // Place it\n                placed.push_back(bestRect);\n                Placement p;\n                p.p = i;\n                p.r = best_r;\n                p.d = best_d;\n                p.b = best_b;\n                sequence.push_back(p);\n            }\n        }\n        \n        // Calculate final bounding box\n        int maxX = 0, maxY = 0;\n        for (const auto& rect : placed) {\n            maxX = max(maxX, rect.x + rect.width);\n            maxY = max(maxY, rect.y + rect.height);\n        }\n        \n        long long score = (long long)maxX + maxY + totalWH;\n        return {sequence, score};\n    }\n    \n    // Get the best sequence found so far (for repeated output)\n    const vector<Placement>& getBestSequence() const {\n        return sequence;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, T, sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n    \n    vector<int> w(N), h(N);\n    for (int i = 0; i < N; i++) {\n        cin >> w[i] >> h[i];\n    }\n    \n    Packer packer(w, h);\n    \n    // Random number generator\n    random_device rd;\n    mt19937 rng(rd());\n    \n    // Try to find a good solution first\n    long long bestScore = LLONG_MAX;\n    vector<Placement> bestSequence;\n    \n    // Spend some time finding a good solution\n    // We'll try greedy first\n    auto [greedySeq, greedyScore] = packer.generateGreedy();\n    if (greedyScore < bestScore) {\n        bestScore = greedyScore;\n        bestSequence = greedySeq;\n    }\n    \n    // Then try random improvements\n    int attempts = min(T, 50); // Use up to 50 attempts for search\n    for (int attempt = 0; attempt < attempts; attempt++) {\n        auto [seq, score] = packer.generateRandom(rng);\n        if (score < bestScore) {\n            bestScore = score;\n            bestSequence = seq;\n        }\n    }\n    \n    // Output placements for each turn\n    for (int turn = 0; turn < T; turn++) {\n        // Output best sequence we found\n        cout << bestSequence.size() << \"\\n\";\n        for (const auto& p : bestSequence) {\n            cout << p.p << \" \" << p.r << \" \" << p.d << \" \" << p.b << \"\\n\";\n        }\n        cout << flush;\n        \n        // Read measured W' and H'\n        int Wp, Hp;\n        cin >> Wp >> Hp;\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Tree {\n    int N;                                 // number of vertices\n    int H;                                 // maximal depth (given as 10)\n    const vector<int> &A;                  // beauty values\n    const vector<vector<int>> &adj;        // graph\n    long long sumAAll;                     // \u03a3 A[v]  (constant part of score)\n\n    vector<int> parent;                    // parent[v]  ( -1 for a root )\n    vector<int> depth;                     // depth[v]   (0 \u2026 H)\n    vector<int> sumA;                      // S[v]  \u2013 sum of beauties in subtree\n    vector<int> high;                      // H[v]  \u2013 longest distance to a leaf\n    vector<vector<int>> children;          // children of each vertex\n    long long totalDepthSum;               // \u03a3 depth[v] * A[v]\n\n    // ---------- constructor (all roots) ----------\n    Tree(int N_, int H_, const vector<int> &A_, const vector<vector<int>> &adj_)\n        : N(N_), H(H_), A(A_), adj(adj_) {\n        sumAAll = 0;\n        for (int x : A) sumAAll += x;\n        parent.assign(N, -1);\n        depth.assign(N, 0);\n        sumA = A;                 // each subtree consists only of the vertex itself\n        high.assign(N, 0);\n        children.assign(N, {});\n        totalDepthSum = 0;\n    }\n\n    // ---------- utility ----------\n    bool isDescendant(int anc, int desc) const {\n        int cur = desc;\n        while (cur != -1) {\n            if (cur == anc) return true;\n            cur = parent[cur];\n        }\n        return false;\n    }\n\n    void detach(int v) {\n        int p = parent[v];\n        if (p != -1) {\n            auto &vec = children[p];\n            for (size_t i = 0; i < vec.size(); ++i) {\n                if (vec[i] == v) {\n                    vec.erase(vec.begin() + i);\n                    break;\n                }\n            }\n        }\n        parent[v] = -1;                 // v becomes a root of its own tree\n    }\n\n    void attach(int v, int newParent) {\n        parent[v] = newParent;\n        if (newParent != -1) children[newParent].push_back(v);\n    }\n\n    void applyDepthDelta(int v, int delta) {\n        depth[v] += delta;\n        for (int c : children[v]) applyDepthDelta(c, delta);\n    }\n\n    // recompute sumA and high on the path from v upwards (at most H steps)\n    void recomputeUpward(int v) {\n        while (v != -1) {\n            int s = A[v];\n            int h = 0;\n            for (int c : children[v]) {\n                s += sumA[c];\n                h = max(h, high[c] + 1);\n            }\n            sumA[v] = s;\n            high[v] = h;\n            v = parent[v];\n        }\n    }\n\n    // evaluate a possible move of subtree v to newParent ( -1 = root )\n    // returns {newDepth, gain}  ; gain = -inf if illegal\n    pair<int,long long> evaluateMove(int v, int newParent) const {\n        if (newParent == parent[v]) return {depth[v], 0};          // no change\n        if (newParent != -1 && isDescendant(v, newParent))\n            return {0, LLONG_MIN};                               // would create a cycle\n\n        int newDepth = (newParent == -1 ? 0 : depth[newParent] + 1);\n        if (newDepth + high[v] > H) return {0, LLONG_MIN};       // height violation\n\n        long long delta = (long long)newDepth - (long long)depth[v];\n        long long gain = delta * (long long)sumA[v];\n        return {newDepth, gain};\n    }\n\n    // really perform a move (already known to be legal)\n    void performMove(int v, int newParent, int newDepth) {\n        int oldParent = parent[v];\n        int oldDepth  = depth[v];\n\n        // detach\n        detach(v);\n        if (oldParent != -1) recomputeUpward(oldParent);\n\n        // attach\n        attach(v, newParent);\n\n        // shift depths inside the subtree\n        int delta = newDepth - oldDepth;\n        if (delta != 0) applyDepthDelta(v, delta);\n\n        // update sums on the new side\n        if (newParent != -1) recomputeUpward(newParent);\n        else                 recomputeUpward(v);   // v became a root\n\n        totalDepthSum += (long long)delta * (long long)sumA[v];\n    }\n\n    // ---------- greedy hill climbing ----------\n    void greedyPhase(mt19937 &rng) {\n        bool improved = true;\n        int passes = 0;\n        while (improved && passes < 20) {          // limit the number of full passes\n            improved = false;\n            vector<int> order(N);\n            iota(order.begin(), order.end(), 0);\n            shuffle(order.begin(), order.end(), rng);\n            for (int v : order) {\n                // try all neighbours\n                int bestParent = -2;\n                int bestDepth  = depth[v];\n                long long bestGain = 0;\n                // also try to become a root (only possible gain is negative \u2192 not tried here)\n                for (int u : adj[v]) {\n                    if (u == parent[v]) continue;\n                    auto [newDepth, gain] = evaluateMove(v, u);\n                    if (gain > bestGain) {\n                        bestGain = gain;\n                        bestParent = u;\n                        bestDepth  = newDepth;\n                    }\n                }\n                if (bestGain > 0) {\n                    performMove(v, bestParent, bestDepth);\n                    improved = true;\n                }\n            }\n            ++passes;\n        }\n    }\n\n    // ---------- simulated annealing ----------\n    void annealingPhase(mt19937 &rng, double timeLimit) {\n        const double START_TEMP = 1e6;\n        const double END_TEMP   = 1.0;\n        auto start = chrono::steady_clock::now();\n\n        double temp = START_TEMP;\n        uniform_int_distribution<int> VertDist(0, N-1);\n        uniform_real_distribution<double> ProbDist(0.0, 1.0);\n\n        while (true) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - start).count();\n            if (elapsed > timeLimit) break;\n\n            // cooling schedule (linear in time)\n            double progress = elapsed / timeLimit;                 // 0 \u2026 1\n            temp = START_TEMP * (1.0 - progress) + END_TEMP * progress;\n\n            int v = VertDist(rng);\n            if (adj[v].empty()) continue;   // never happens (graph is connected)\n\n            // choose new parent: root or a random neighbour\n            int newParent;\n            if (ProbDist(rng) < 0.1) {      // 10\u202f% chance to try becoming a root\n                newParent = -1;\n            } else {\n                int idx = uniform_int_distribution<int>(0, (int)adj[v].size() - 1)(rng);\n                newParent = adj[v][idx];\n            }\n\n            auto [newDepth, gain] = evaluateMove(v, newParent);\n            if (gain == LLONG_MIN) continue;   // illegal\n\n            bool accept = false;\n            if (gain > 0) accept = true;\n            else if (temp > 1e-12) {\n                double prob = exp(gain / temp);\n                if (prob > ProbDist(rng)) accept = true;\n            }\n            if (!accept) continue;\n\n            // perform the move\n            performMove(v, newParent, newDepth);\n        }\n    }\n\n    // current total attractiveness\n    long long totalScore() const {\n        return sumAAll + totalDepthSum;\n    }\n};\n\n// -----------------------------------------------------------------------\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, H;\n    if (!(cin >> N >> M >> H)) return 0;\n\n    vector<int> A(N);\n    for (int i = 0; i < N; ++i) cin >> A[i];\n\n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; ++i) {\n        int u, v; cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    // the coordinates are ignored \u2013 they are not needed for the algorithm\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n    }\n\n    // random generator\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    // best solution ever found\n    vector<int> bestParent(N, -1);\n    long long bestScore = 0;   // at least the sum of all beauties\n    {\n        Tree tree(N, H, A, adj);\n        bestScore = tree.totalScore();\n        bestParent = tree.parent;\n    }\n\n    // ---------------------------------------------------------------\n    // 1) greedy hill climbing (several passes, random order)\n    {\n        Tree tree(N, H, A, adj);\n        tree.greedyPhase(rng);\n        long long cur = tree.totalScore();\n        if (cur > bestScore) {\n            bestScore = cur;\n            bestParent = tree.parent;\n        }\n    }\n\n    // ---------------------------------------------------------------\n    // 2) simulated annealing, started from the greedy solution,\n    //    runs until the time limit (\u2248 1.8\u202fs)\n    {\n        Tree tree(N, H, A, adj);\n        // copy the greedy result into the start of annealing\n        tree.parent = bestParent;\n        // rebuild derived structures from parent array\n        for (int i = 0; i < N; ++i) {\n            int p = tree.parent[i];\n            if (p != -1) tree.children[p].push_back(i);\n        }\n        // recompute depth, sumA, high for the whole forest\n        for (int i = 0; i < N; ++i) if (tree.parent[i] == -1) {\n            // depth is already 0, recompute sums and high bottom\u2011up\n            // We do a tiny DFS for each root \u2013 N is only 1000.\n            vector<int> stack = {i};\n            while (!stack.empty()) {\n                int v = stack.back(); stack.pop_back();\n                for (int c : tree.children[v]) {\n                    tree.depth[c] = tree.depth[v] + 1;\n                    stack.push_back(c);\n                }\n            }\n        }\n        // recompute sumA and high for all vertices (bottom\u2011up)\n        // we need them in topological order (descendants first).\n        // Because depth \u2264 H \u2264 10 a simple recursion is safe.\n        function<void(int)> dfs = [&](int v) {\n            int s = A[v];\n            int h = 0;\n            for (int c : tree.children[v]) {\n                dfs(c);\n                s += tree.sumA[c];\n                h = max(h, tree.high[c] + 1);\n            }\n            tree.sumA[v] = s;\n            tree.high[v] = h;\n        };\n        for (int i = 0; i < N; ++i)\n            if (tree.parent[i] == -1) dfs(i);\n\n        // totalDepthSum must be recomputed from the depths\n        tree.totalDepthSum = 0;\n        for (int i = 0; i < N; ++i)\n            tree.totalDepthSum += (long long)tree.depth[i] * (long long)A[i];\n\n        // annealing itself\n        double timeLeft = 1.85; // seconds \u2013 a little safety margin\n        tree.annealingPhase(rng, timeLeft);\n\n        long long cur = tree.totalScore();\n        if (cur > bestScore) {\n            bestScore = cur;\n            bestParent = tree.parent;\n        }\n    }\n\n    // ---------------------------------------------------------------\n    // output the best parent array\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << bestParent[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Oni {\n    int i, j;                 // position\n    bool upSafe, downSafe, leftSafe, rightSafe;\n    int upDist, downDist, leftDist, rightDist;\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<string> board(N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n\n    const int INF = 1e9;\n\n    // -----------------------------------------------------------------\n    // locate Oni and Fuku, compute safety flags\n    vector<Oni> onis;\n    vector<vector<bool>> fuku(N, vector<bool>(N, false));\n    vector<vector<bool>> isOni(N, vector<bool>(N, false));\n\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (board[i][j] == 'o') fuku[i][j] = true;\n            else if (board[i][j] == 'x') isOni[i][j] = true;\n\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (isOni[i][j]) {\n                Oni o;\n                o.i = i; o.j = j;\n                // distances\n                o.upDist    = i + 1;\n                o.downDist  = N - i;\n                o.leftDist  = j + 1;\n                o.rightDist = N - j;\n\n                // safety flags\n                o.upSafe = true;\n                for (int ii = 0; ii < i; ++ii) if (fuku[ii][j]) { o.upSafe = false; break; }\n\n                o.downSafe = true;\n                for (int ii = i + 1; ii < N; ++ii) if (fuku[ii][j]) { o.downSafe = false; break; }\n\n                o.leftSafe = true;\n                for (int jj = 0; jj < j; ++jj) if (fuku[i][jj]) { o.leftSafe = false; break; }\n\n                o.rightSafe = true;\n                for (int jj = j + 1; jj < N; ++jj) if (fuku[i][jj]) { o.rightSafe = false; break; }\n\n                onis.push_back(o);\n            }\n\n    const int M = (int)onis.size();               // = 2*N\n\n    // -----------------------------------------------------------------\n    // helper: simulate one ordering, produce move list and its length\n    auto simulate = [&](bool columnsFirst) -> pair<int, vector<pair<char,int>>> {\n        vector<bool> removed(M, false);\n        vector<pair<char,int>> moves;\n        // helper lambda: add a block of identical moves\n        auto addBlock = [&](char dir, int idx, int cnt){\n            for (int k = 0; k < cnt; ++k) moves.emplace_back(dir, idx);\n        };\n\n        if (columnsFirst) {\n            // ----- columns first (up, then down) -----\n            for (int col = 0; col < N; ++col) {\n                // up\u2011safe Oni of this column\n                int dmax = 0;\n                for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].j == col && onis[id].upSafe)\n                    dmax = max(dmax, onis[id].upDist);\n                if (dmax > 0) {\n                    addBlock('U', col, dmax);\n                    addBlock('D', col, dmax);\n                    // mark them removed\n                    for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].j == col && onis[id].upSafe)\n                        removed[id] = true;\n                }\n                // down\u2011safe Oni still in this column\n                dmax = 0;\n                for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].j == col && onis[id].downSafe)\n                    dmax = max(dmax, onis[id].downDist);\n                if (dmax > 0) {\n                    addBlock('D', col, dmax);\n                    addBlock('U', col, dmax);\n                    for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].j == col && onis[id].downSafe)\n                        removed[id] = true;\n                }\n            }\n            // ----- rows second (left, then right) -----\n            for (int row = 0; row < N; ++row) {\n                // left\u2011safe Oni of this row\n                int dmax = 0;\n                for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].i == row && onis[id].leftSafe)\n                    dmax = max(dmax, onis[id].leftDist);\n                if (dmax > 0) {\n                    addBlock('L', row, dmax);\n                    addBlock('R', row, dmax);\n                    for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].i == row && onis[id].leftSafe)\n                        removed[id] = true;\n                }\n                // right\u2011safe Oni still in this row\n                dmax = 0;\n                for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].i == row && onis[id].rightSafe)\n                    dmax = max(dmax, onis[id].rightDist);\n                if (dmax > 0) {\n                    addBlock('R', row, dmax);\n                    addBlock('L', row, dmax);\n                    for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].i == row && onis[id].rightSafe)\n                        removed[id] = true;\n                }\n            }\n        } else {\n            // ----- rows first (left, then right) -----\n            for (int row = 0; row < N; ++row) {\n                int dmax = 0;\n                for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].i == row && onis[id].leftSafe)\n                    dmax = max(dmax, onis[id].leftDist);\n                if (dmax > 0) {\n                    addBlock('L', row, dmax);\n                    addBlock('R', row, dmax);\n                    for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].i == row && onis[id].leftSafe)\n                        removed[id] = true;\n                }\n                dmax = 0;\n                for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].i == row && onis[id].rightSafe)\n                    dmax = max(dmax, onis[id].rightDist);\n                if (dmax > 0) {\n                    addBlock('R', row, dmax);\n                    addBlock('L', row, dmax);\n                    for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].i == row && onis[id].rightSafe)\n                        removed[id] = true;\n                }\n            }\n            // ----- columns second (up, then down) -----\n            for (int col = 0; col < N; ++col) {\n                int dmax = 0;\n                for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].j == col && onis[id].upSafe)\n                    dmax = max(dmax, onis[id].upDist);\n                if (dmax > 0) {\n                    addBlock('U', col, dmax);\n                    addBlock('D', col, dmax);\n                    for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].j == col && onis[id].upSafe)\n                        removed[id] = true;\n                }\n                dmax = 0;\n                for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].j == col && onis[id].downSafe)\n                    dmax = max(dmax, onis[id].downDist);\n                if (dmax > 0) {\n                    addBlock('D', col, dmax);\n                    addBlock('U', col, dmax);\n                    for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].j == col && onis[id].downSafe)\n                        removed[id] = true;\n                }\n            }\n        }\n\n        // all Oni must be removed now\n        int remaining = 0;\n        for (bool b : removed) if (!b) ++remaining;\n        // (remaining should be 0, otherwise the input violated the promise)\n\n        return { (int)moves.size(), moves };\n    };\n\n    // -----------------------------------------------------------------\n    // evaluate both orders\n    auto [len1, moves1] = simulate(true);   // columns first\n    auto [len2, moves2] = simulate(false);  // rows first\n\n    const vector<pair<char,int>>& bestMoves = (len1 <= len2) ? moves1 : moves2;\n\n    // -----------------------------------------------------------------\n    // output the chosen sequence\n    for (auto [dir, idx] : bestMoves) {\n        cout << dir << ' ' << idx << '\\n';\n    }\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    \n    const int N = 100;\n    const long long L = 500000;\n    const long long AVG = L / N; // 5000\n    const long long STEP = 2500;  // Half of average\n    \n    vector<long long> T(N);\n    int n_input;\n    long long l_input;\n    if (!(cin >> n_input >> l_input)) return 0;\n    for (int i = 0; i < N; ++i) {\n        cin >> T[i];\n    }\n    \n    const long long INF = (1LL << 60);\n    long long best_error = INF;\n    vector<int> best_x(N);\n    \n    // Try both possible values for x_0\n    for (int x0 = 0; x0 <= 1; ++x0) {\n        // dp[i][x_curr] = min error up to employee i, with x_i = x_curr\n        // parent[i][x_curr] = x_{i-1} that achieves the minimum\n        array<long long, 2> dp_prev, dp_curr;\n        array<int, 2> parent_prev, parent_curr;\n        \n        // Initialize for i = 0\n        dp_prev[0] = dp_prev[1] = INF;\n        dp_prev[x0] = 0;\n        parent_prev[0] = parent_prev[1] = -1;\n        parent_prev[x0] = -1;\n        \n        // Process employees 1 to N-1\n        for (int i = 1; i < N; ++i) {\n            dp_curr[0] = dp_curr[1] = INF;\n            parent_curr[0] = parent_curr[1] = -1;\n            \n            for (int x_curr = 0; x_curr <= 1; ++x_curr) {\n                for (int x_prev = 0; x_prev <= 1; ++x_prev) {\n                    if (dp_prev[x_prev] == INF) continue;\n                    \n                    long long visits = AVG + STEP * (x_curr - x_prev);\n                    long long error = llabs(T[i] - visits);\n                    long long total_error = dp_prev[x_prev] + error;\n                    \n                    if (total_error < dp_curr[x_curr]) {\n                        dp_curr[x_curr] = total_error;\n                        parent_curr[x_curr] = x_prev;\n                    }\n                }\n            }\n            \n            dp_prev = dp_curr;\n            parent_prev = parent_curr;\n        }\n        \n        // Handle employee 0 with wrap-around\n        for (int x_last = 0; x_last <= 1; ++x_last) {\n            if (dp_prev[x_last] == INF) continue;\n            \n            long long visits = AVG + STEP * (x0 - x_last);\n            long long error = llabs(T[0] - visits);\n            long long total_error = dp_prev[x_last] + error;\n            \n            if (total_error < best_error) {\n                best_error = total_error;\n                \n                // Reconstruct the x sequence\n                best_x[0] = x0;\n                int curr_x = x_last;\n                for (int i = N - 1; i >= 1; --i) {\n                    best_x[i] = curr_x;\n                    curr_x = parent_prev[curr_x];\n                }\n                // Verify consistency: curr_x should equal x0\n                // (this ensures the cycle is consistent)\n            }\n        }\n    }\n    \n    // Construct the answer\n    vector<int> a(N), b(N);\n    for (int i = 0; i < N; ++i) {\n        if (best_x[i] == 1) {\n            a[i] = i;  // Self-loop on odd count\n        } else {\n            a[i] = (i + 1) % N;  // Point to next employee\n        }\n        b[i] = (i + 1) % N;  // Always point to next employee on even count\n    }\n    \n    // Output\n    for (int i = 0; i < N; ++i) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ---------- integer square root, floor(sqrt(x)) ---------- */\nint isqrt_ll(long long x) {\n    int r = (int)std::sqrt((long double)x);\n    while ((long long)(r + 1) * (r + 1) <= x) ++r;\n    while ((long long)r * r > x) --r;\n    return r;\n}\n\n/* ---------- DSU ---------- */\nstruct DSU {\n    vector<int> parent, sz;\n    int comps;\n    DSU(int n = 0) { init(n); }\n    void init(int n) {\n        parent.resize(n);\n        sz.assign(n, 1);\n        iota(parent.begin(), parent.end(), 0);\n        comps = n;\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 (sz[a] < sz[b]) swap(a, b);\n        parent[b] = a;\n        sz[a] += sz[b];\n        --comps;\n        return true;\n    }\n};\n\n/* ---------- lower bound distance between two rectangles ---------- */\nint lowerDistRect(int i, int j,\n                  const vector<int>& lx, const vector<int>& rx,\n                  const vector<int>& ly, const vector<int>& ry) {\n    long long dx = 0, dy = 0;\n    if (rx[i] < lx[j]) dx = (long long)lx[j] - rx[i];\n    else if (rx[j] < lx[i]) dx = (long long)lx[i] - rx[j];\n    else dx = 0;\n\n    if (ry[i] < ly[j]) dy = (long long)ly[j] - ry[i];\n    else if (ry[j] < ly[i]) dy = (long long)ly[i] - ry[j];\n    else dy = 0;\n\n    long long sq = dx * dx + dy * dy;\n    return isqrt_ll(sq);\n}\n\n/* ---------- main ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, Q, L, W;\n    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    vector<int> lx(N), rx(N), ly(N), ry(N);\n    for (int i = 0; i < N; ++i) cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n\n    /* ----- all lower bounds ----- */\n    vector<vector<int>> low(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        low[i][i] = 0;\n        for (int j = i + 1; j < N; ++j) {\n            int d = lowerDistRect(i, j, lx, rx, ly, ry);\n            low[i][j] = low[j][i] = d;\n        }\n    }\n\n    /* ----- build groups greedily (Prim like) ----- */\n    vector<bool> used(N, false);\n    vector<vector<int>> groups(M);\n    for (int gi = 0; gi < M; ++gi) {\n        int need = G[gi];\n        // seed = first unused city\n        int seed = -1;\n        for (int c = 0; c < N; ++c) if (!used[c]) { seed = c; break; }\n        groups[gi].push_back(seed);\n        used[seed] = true;\n\n        vector<int> bestDist(N, INT_MAX);\n        for (int c = 0; c < N; ++c)\n            if (!used[c]) bestDist[c] = low[seed][c];\n\n        while ((int)groups[gi].size() < need) {\n            int bestCity = -1, bestD = INT_MAX;\n            for (int c = 0; c < N; ++c)\n                if (!used[c] && bestDist[c] < bestD) {\n                    bestD = bestDist[c];\n                    bestCity = c;\n                }\n            groups[gi].push_back(bestCity);\n            used[bestCity] = true;\n            for (int c = 0; c < N; ++c)\n                if (!used[c]) {\n                    int d = low[bestCity][c];\n                    if (d < bestDist[c]) bestDist[c] = d;\n                }\n        }\n    }\n\n    /* ----- auxiliary data ----- */\n    vector<int> group_of(N, -1);          // global -> group id\n    vector<int> local_idx(N, -1);         // global -> index inside its group\n    for (int i = 0; i < M; ++i) {\n        for (int pos = 0; pos < (int)groups[i].size(); ++pos) {\n            int city = groups[i][pos];\n            group_of[city] = i;\n            local_idx[city] = pos;\n        }\n    }\n\n    vector<DSU> dsu(M);\n    for (int i = 0; i < M; ++i) dsu[i].init((int)groups[i].size());\n\n    vector<vector<pair<int,int>>> group_edges(M);\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    /* ----- query phase ----- */\n    int queries_used = 0;\n    while (queries_used < Q) {\n        // choose a group with most components left\n        int best_g = -1, best_comp = 0;\n        for (int i = 0; i < M; ++i) {\n            if (dsu[i].comps > best_comp) {\n                best_comp = dsu[i].comps;\n                best_g = i;\n            }\n        }\n        if (best_g == -1 || best_comp <= 1) break; // all finished\n\n        // representatives of the components of best_g\n        unordered_map<int,int> rep;   // DSU root -> city id\n        for (int city : groups[best_g]) {\n            int lid = local_idx[city];\n            int root = dsu[best_g].find(lid);\n            if (!rep.count(root)) rep[root] = city;\n        }\n        vector<int> reps;\n        reps.reserve(rep.size());\n        for (auto &kv : rep) reps.push_back(kv.second);\n\n        // build the subset for the query\n        vector<int> subset;\n        if ((int)reps.size() <= L) {\n            subset = reps;\n        } else {\n            shuffle(reps.begin(), reps.end(), rng);\n            subset.assign(reps.begin(), reps.begin() + L);\n        }\n\n        int l = (int)subset.size();\n        cout << \"? \" << l;\n        for (int v : subset) cout << ' ' << v;\n        cout << '\\n';\n        cout.flush();\n\n        // read the l-1 edges of the MST of the subset\n        for (int i = 0; i < l - 1; ++i) {\n            int a, b;\n            cin >> a >> b;\n            if (group_of[a] != group_of[b]) continue; // should not happen\n            int g = group_of[a];\n            int la = local_idx[a];\n            int lb = local_idx[b];\n            if (dsu[g].unite(la, lb)) {\n                group_edges[g].push_back({a, b});\n            }\n        }\n        ++queries_used;\n    }\n\n    /* ----- finish groups that are still disconnected ----- */\n    for (int g = 0; g < M; ++g) {\n        if (dsu[g].comps == 1) continue;   // already finished\n\n        struct Edge {int u, v, w;};\n        vector<Edge> edges;\n        int sz = (int)groups[g].size();\n        edges.reserve(sz * (sz - 1) / 2);\n        for (int i = 0; i < sz; ++i) {\n            int u = groups[g][i];\n            int lu = i;\n            for (int j = i + 1; j < sz; ++j) {\n                int v = groups[g][j];\n                int lv = j;\n                if (dsu[g].find(lu) == dsu[g].find(lv)) continue;\n                int w = low[u][v];\n                edges.push_back({u, v, w});\n            }\n        }\n        sort(edges.begin(), edges.end(),\n             [](const Edge& a, const Edge& b) {\n                 if (a.w != b.w) return a.w < b.w;\n                 if (a.u != b.u) return a.u < b.u;\n                 return a.v < b.v;\n             });\n        for (const Edge &e : edges) {\n            int lu = local_idx[e.u];\n            int lv = local_idx[e.v];\n            if (dsu[g].unite(lu, lv)) {\n                group_edges[g].push_back({e.u, e.v});\n                if (dsu[g].comps == 1) break;\n            }\n        }\n    }\n\n    /* ----- output ----- */\n    cout << \"!\\n\";\n    for (int g = 0; g < M; ++g) {\n        // list of cities\n        for (size_t i = 0; i < groups[g].size(); ++i) {\n            if (i) cout << ' ';\n            cout << groups[g][i];\n        }\n        cout << '\\n';\n        // roads (exactly G[g]-1 edges)\n        for (auto &e : group_edges[g])\n            cout << e.first << ' ' << e.second << '\\n';\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint 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>> p(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> p[i].first >> p[i].second;\n    }\n\n    // start position is the first given square\n    pair<int,int> cur = p[0];\n    // targets are the remaining M-1 squares\n    for (int idx = 1; idx < M; ++idx) {\n        pair<int,int> target = p[idx];\n        while (cur != target) {\n            char dir;\n            if (cur.first < target.first) {\n                dir = 'D';          // move down\n                ++cur.first;\n            } else if (cur.first > target.first) {\n                dir = 'U';          // move up\n                --cur.first;\n            } else if (cur.second < target.second) {\n                dir = 'R';          // move right\n                ++cur.second;\n            } else {\n                dir = 'L';          // move left\n                --cur.second;\n            }\n            cout << \"M \" << dir << '\\n';\n        }\n        // now cur == target, proceed to the next one\n    }\n    return 0;\n}"},"2":{"ahc001":"","ahc002":"","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\n////////////////////  parameters  ////////////////////\n\nstruct EdgeWeights {\n    double h[30][29]; // horizontal edges (i , j) -> (i , j+1)\n    double v[29][30]; // vertical   edges (i , j) -> (i+1 , j)\n};\n\n////////////////////  Dijkstra & path reconstruction  ////////////////////\n\nstruct State {\n    double dist;\n    int node;               // node id = i*30 + j\n    bool operator<(const State& other) const {\n        return dist > other.dist; // reversed for min\u2011heap\n    }\n};\n\n/*  run Dijkstra from (si,sj) to (ti,tj) using the given weight matrices.\n    returns the path as a string of U/D/L/R.                           */\nstring dijkstra_path(int si, int sj, int ti, int tj,\n                     const EdgeWeights& w,\n                     double* path_len = nullptr) {\n    const int N = 30 * 30;\n    const int s = si * 30 + sj;\n    const int t = ti * 30 + tj;\n\n    vector<double> dist(N, 1e100);\n    vector<int> prev(N, -1);\n    vector<char> pdir(N, 0);\n\n    priority_queue<State> pq;\n    dist[s] = 0.0;\n    pq.push({0.0, s});\n\n    while (!pq.empty()) {\n        auto cur = pq.top(); pq.pop();\n        int u = cur.node;\n        double d = cur.dist;\n        if (d > dist[u] + 1e-12) continue;\n        if (u == t) break; // we already know the shortest distance to t\n\n        int ui = u / 30, uj = u % 30;\n\n        // ----- up -----\n        if (ui > 0) {\n            int v = (ui - 1) * 30 + uj;\n            double nd = d + w.v[ui - 1][uj];\n            if (nd + 1e-12 < dist[v]) {\n                dist[v] = nd;\n                prev[v] = u;\n                pdir[v] = 'U';\n                pq.push({nd, v});\n            }\n        }\n        // ----- down -----\n        if (ui < 29) {\n            int v = (ui + 1) * 30 + uj;\n            double nd = d + w.v[ui][uj];\n            if (nd + 1e-12 < dist[v]) {\n                dist[v] = nd;\n                prev[v] = u;\n                pdir[v] = 'D';\n                pq.push({nd, v});\n            }\n        }\n        // ----- left -----\n        if (uj > 0) {\n            int v = ui * 30 + (uj - 1);\n            double nd = d + w.h[ui][uj - 1];\n            if (nd + 1e-12 < dist[v]) {\n                dist[v] = nd;\n                prev[v] = u;\n                pdir[v] = 'L';\n                pq.push({nd, v});\n            }\n        }\n        // ----- right -----\n        if (uj < 29) {\n            int v = ui * 30 + (uj + 1);\n            double nd = d + w.h[ui][uj];\n            if (nd + 1e-12 < dist[v]) {\n                dist[v] = nd;\n                prev[v] = u;\n                pdir[v] = 'R';\n                pq.push({nd, v});\n            }\n        }\n    }\n\n    // reconstruct the path from t to s\n    string path;\n    for (int cur = t; cur != s; cur = prev[cur]) {\n        path.push_back(pdir[cur]);\n    }\n    reverse(path.begin(), path.end());\n\n    if (path_len) *path_len = dist[t];\n    return path;\n}\n\n////////////////////  main  ////////////////////\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    random_device rd;\n    mt19937 rng(rd());\n\n    uniform_real_distribution<double> urd_noise(-500.0, 500.0);\n    bernoulli_distribution bernoulli(0.5); // temporary, will change each query\n\n    // initialise edge weights (mid\u2011range guess)\n    EdgeWeights w;\n    for (int i = 0; i < 30; ++i)\n        for (int j = 0; j < 29; ++j)\n            w.h[i][j] = 5000.0;\n    for (int i = 0; i < 29; ++i)\n        for (int j = 0; j < 30; ++j)\n            w.v[i][j] = 5000.0;\n\n    for (int query = 0; query < 1000; ++query) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) return 0; // no more input\n\n        // --------- exploration / exploitation decision ----------\n        double eps = 0.5 * exp(-query / 150.0);\n        bernoulli_distribution choose_explore(eps);\n        bool explore = choose_explore(rng);\n\n        string path;\n        EdgeWeights w_tmp = w; // copy current weights\n        if (explore) {\n            // add temporary noise\n            for (int i = 0; i < 30; ++i)\n                for (int j = 0; j < 29; ++j)\n                    w_tmp.h[i][j] += urd_noise(rng);\n            for (int i = 0; i < 29; ++i)\n                for (int j = 0; j < 30; ++j)\n                    w_tmp.v[i][j] += urd_noise(rng);\n            path = dijkstra_path(si, sj, ti, tj, w_tmp);\n        } else {\n            path = dijkstra_path(si, sj, ti, tj, w);\n        }\n\n        // --------- output ----------\n        cout << path << '\\n';\n        cout.flush();\n\n        // --------- read noisy observation ----------\n        long long y;\n        cin >> y;\n\n        // --------- accumulate predicted length (using true weights) ----------\n        double pred_len = 0.0;\n        int i = si, j = sj;\n        for (char c : path) {\n            if (c == 'U') {\n                pred_len += w.v[i - 1][j];\n                --i;\n            } else if (c == 'D') {\n                pred_len += w.v[i][j];\n                ++i;\n            } else if (c == 'L') {\n                pred_len += w.h[i][j - 1];\n                --j;\n            } else if (c == 'R') {\n                pred_len += w.h[i][j];\n                ++j;\n            }\n        }\n\n        // --------- update weights (stochastic gradient descent) ----------\n        double err = double(y) - pred_len;\n        double lr = 0.01 / sqrt(query + 1);   // slowly decreasing step size\n        double delta = lr * err / double(path.size());\n\n        i = si; j = sj;\n        for (char c : path) {\n            if (c == 'U') {\n                w.v[i - 1][j] += delta;\n                --i;\n            } else if (c == 'D') {\n                w.v[i][j] += delta;\n                ++i;\n            } else if (c == 'L') {\n                w.h[i][j - 1] += delta;\n                --j;\n            } else if (c == 'R') {\n                w.h[i][j] += delta;\n                ++j;\n            }\n        }\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 20;                 // matrix size (fixed in the statement)\nconstexpr int MAXLEN = 12;            // maximal length of an input string\nconstexpr int ALPH = 8;               // letters A \u2026 H\n\n/* --------------------------------------------------------------- */\n/* ---------- placement of one string ---------- */\nstruct Placement {\n    uint16_t cell[MAXLEN];   // cell indices (0 \u2026 N*N-1)\n    uint8_t  let[MAXLEN];    // required letters (0 \u2026 7)\n    uint8_t  len;            // actual length ( \u2264 12 )\n};\n\n/* ---------- global data for the whole test case ---------- */\nint Muniq;                                           // number of different strings\nvector<vector<int>> strLetters;                     // letters of each unique string\nvector<vector<Placement>> placements;               // all placements of each string\n\n/* ---------- current working solution ---------- */\narray<int, N * N> curLetter;        // -1 = empty, 0..7 = letter\narray<int, N * N> curUse;           // how many placements occupy the cell\nint curUsedCells;                    // #cells with curUse > 0\nvector<int> curIdx;                  // for each string: chosen placement index, -1 = none\n\n/* --------------------------------------------------------------- */\ninline int cellId(int r, int c) { return r * N + c; }\n\n/* check whether placement p can be inserted into the current grid */\ninline bool canPlace(const Placement& p) {\n    for (int i = 0; i < p.len; ++i) {\n        int c = p.cell[i];\n        if (curUse[c] > 0 && curLetter[c] != (int)p.let[i]) return false;\n    }\n    return true;\n}\n\n/* compute the number of empty cells that placement p would occupy */\ninline int placeCost(const Placement& p) {\n    int cost = 0;\n    for (int i = 0; i < p.len; ++i)\n        if (curUse[p.cell[i]] == 0) ++cost;\n    return cost;\n}\n\n/* insert a placement into the grid */\ninline void place(const Placement& p) {\n    for (int i = 0; i < p.len; ++i) {\n        int c = p.cell[i];\n        if (curUse[c] == 0) {\n            curLetter[c] = p.let[i];\n            ++curUsedCells;\n        }\n        ++curUse[c];\n    }\n}\n\n/* remove a placement from the grid */\ninline void unplace(const Placement& p) {\n    for (int i = 0; i < p.len; ++i) {\n        int c = p.cell[i];\n        --curUse[c];\n        if (curUse[c] == 0) {\n            curLetter[c] = -1;\n            --curUsedCells;\n        }\n    }\n}\n\n/* test whether string s (index) is a subsequence of the current matrix */\ninline bool isPresent(int s) {\n    for (const Placement& p : placements[s]) {\n        bool ok = true;\n        for (int i = 0; i < p.len; ++i) {\n            int c = p.cell[i];\n            if (curLetter[c] != (int)p.let[i]) { ok = false; break; }\n        }\n        if (ok) return true;\n    }\n    return false;\n}\n\n/* --------------------------------------------------------------- */\n/* ---------- main ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int Ninput, Minput;\n    if (!(cin >> Ninput >> Minput)) return 0;\n    vector<string> allStr(Minput);\n    for (int i = 0; i < Minput; ++i) cin >> allStr[i];\n\n    /* ---- delete duplicate strings (one occurrence is sufficient) ---- */\n    unordered_map<string, int> seen;\n    vector<string> uniqStr;\n    for (const string& x : allStr) {\n        if (seen.find(x) == seen.end()) {\n            seen[x] = 1;\n            uniqStr.push_back(x);\n        }\n    }\n    Muniq = (int)uniqStr.size();                 // number of different strings\n\n    /* ---- convert strings to integer letters ---- */\n    strLetters.resize(Muniq);\n    for (int i = 0; i < Muniq; ++i)\n        for (char ch : uniqStr[i])\n            strLetters[i].push_back(ch - 'A');\n\n    /* ---- pre\u2011compute all placements of each string ---- */\n    placements.assign(Muniq, {});\n    for (int sid = 0; sid < Muniq; ++sid) {\n        const vector<int>& L = strLetters[sid];\n        int len = (int)L.size();\n        // horizontal\n        for (int row = 0; row < N; ++row)\n            for (int startCol = 0; startCol < N; ++startCol) {\n                Placement p;\n                p.len = (uint8_t)len;\n                for (int off = 0; off < len; ++off) {\n                    int col = (startCol + off) % N;\n                    p.cell[off] = (uint16_t)cellId(row, col);\n                    p.let[off] = (uint8_t)L[off];\n                }\n                placements[sid].push_back(p);\n            }\n        // vertical\n        for (int col = 0; col < N; ++col)\n            for (int startRow = 0; startRow < N; ++startRow) {\n                Placement p;\n                p.len = (uint8_t)len;\n                for (int off = 0; off < len; ++off) {\n                    int row = (startRow + off) % N;\n                    p.cell[off] = (uint16_t)cellId(row, col);\n                    p.let[off] = (uint8_t)L[off];\n                }\n                placements[sid].push_back(p);\n            }\n    }\n\n    /* ---------- containers for the best solution found ---------- */\n    array<int, N * N> bestLetter;\n    int bestUsed = INT_MAX;\n    int bestPlaced = -1;\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    const double TIME_LIMIT = 2.8;                 // seconds\n    auto start = chrono::steady_clock::now();\n\n    /* ---------- phase 1 : many greedy restarts + light backtracking ---------- */\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > 0.60 * TIME_LIMIT) break;    // 60\u202f% of total time\n\n        /* ---- start with an empty grid ---- */\n        curLetter.fill(-1);\n        curUse.fill(0);\n        curUsedCells = 0;\n        curIdx.assign(Muniq, -1);\n\n        vector<int> order(Muniq);\n        iota(order.begin(), order.end(), 0);\n        shuffle(order.begin(), order.end(), rng);\n\n        int placed = 0;\n\n        for (int sid : order) {\n            const vector<Placement>& cand = placements[sid];\n            int bestCost = INT_MAX;\n            vector<int> bestIdx;\n            for (int pid = 0; pid < (int)cand.size(); ++pid) {\n                const Placement& p = cand[pid];\n                if (!canPlace(p)) continue;\n                int c = placeCost(p);\n                if (c < bestCost) {\n                    bestCost = c;\n                    bestIdx.clear();\n                    bestIdx.push_back(pid);\n                } else if (c == bestCost) {\n                    bestIdx.push_back(pid);\n                }\n            }\n            if (bestIdx.empty()) continue;          // cannot place now\n            int chosen = bestIdx[uniform_int_distribution<int>(0, (int)bestIdx.size() - 1)(rng)];\n            place(cand[chosen]);\n            curIdx[sid] = chosen;\n            ++placed;\n        }\n\n        /* ---- light backtracking for the still missing strings ---- */\n        if (placed < Muniq) {\n            // collect not yet placed strings\n            vector<int> missing;\n            for (int i = 0; i < Muniq; ++i)\n                if (curIdx[i] == -1) missing.push_back(i);\n            // try a few rounds of \"remove one, insert one\"\n            const int BACKTRACK_TRIES = 50;\n            for (int attempt = 0; attempt < BACKTRACK_TRIES && !missing.empty(); ++attempt) {\n                int sid = missing.back();                     // take one missing string\n                // try all its placements, maybe one fits now\n                bool ok = false;\n                for (const Placement& p : placements[sid]) {\n                    if (canPlace(p)) {\n                        place(p);\n                        curIdx[sid] = &p - &placements[sid][0]; // store index (rough but enough)\n                        missing.pop_back();\n                        ok = true;\n                        ++placed;\n                        break;\n                    }\n                }\n                if (ok) continue;                            // success \u2013 continue with next missing\n                // otherwise remove a random already placed string and try again\n                vector<int> placedIds;\n                for (int i = 0; i < Muniq; ++i)\n                    if (curIdx[i] != -1) placedIds.push_back(i);\n                if (placedIds.empty()) continue;\n                int victim = placedIds[uniform_int_distribution<int>(0, (int)placedIds.size() - 1)(rng)];\n                const Placement& vp = placements[victim][curIdx[victim]];\n                unplace(vp);\n                curIdx[victim] = -1;\n                --placed;\n            }\n        }\n\n        /* ---- remove redundant strings (they are already present) ---- */\n        if (placed == Muniq) {\n            vector<int> perm = order;\n            shuffle(perm.begin(), perm.end(), rng);\n            for (int sid : perm) {\n                if (curIdx[sid] == -1) continue;\n                const Placement& p = placements[sid][curIdx[sid]];\n                unplace(p);\n                if (isPresent(sid)) {\n                    curIdx[sid] = -1;          // keep it removed\n                } else {\n                    place(p);                  // put it back\n                }\n            }\n        }\n\n        /* ---- remember the best solution of this restart ---- */\n        if (placed > bestPlaced ||\n            (placed == bestPlaced && curUsedCells < bestUsed)) {\n            bestPlaced = placed;\n            bestUsed   = curUsedCells;\n            bestLetter = curLetter;               // copy the whole grid (400 ints)\n        }\n    }   // end of restarts\n\n    /* ---- nothing feasible found ? output empty matrix (worst case) ---- */\n    if (bestPlaced == -1) {\n        for (int i = 0; i < N; ++i)\n            cout << string(N, '.') << '\\n';\n        return 0;\n    }\n\n    /* ---- reload the best solution into the working arrays ---- */\n    curLetter = bestLetter;\n    curUse.fill(0);\n    curUsedCells = 0;\n    for (int i = 0; i < N * N; ++i)\n        if (curLetter[i] != -1) {\n            curUse[i] = 1;\n            ++curUsedCells;\n        }\n    curIdx.assign(Muniq, -1);       // we do not know the exact indices any more\n\n    /* ---------- phase 2 : simple hill climbing (use remaining time) ---------- */\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > TIME_LIMIT - 0.05) break;    // stop a little before the hard limit\n\n        // pick a random placed string (ignore strings that are not placed)\n        vector<int> placedIds;\n        for (int i = 0; i < Muniq; ++i)\n            if (curIdx[i] != -1) placedIds.push_back(i);\n        if (placedIds.empty()) continue;\n        int sid = placedIds[uniform_int_distribution<int>(0, (int)placedIds.size() - 1)(rng)];\n        const Placement& oldPl = placements[sid][curIdx[sid]];\n\n        // pick a random different placement\n        const vector<Placement>& cand = placements[sid];\n        int pid = uniform_int_distribution<int>(0, (int)cand.size() - 1)(rng);\n        if (pid == curIdx[sid]) continue;\n        const Placement& newPl = cand[pid];\n        if (!canPlace(newPl)) continue;           // would conflict\n\n        // compute \u0394 = newCellsUsed - cellsFreed\n        int freed = 0;\n        for (int i = 0; i < oldPl.len; ++i) {\n            int c = oldPl.cell[i];\n            if (curUse[c] == 1) {\n                bool inNew = false;\n                for (int j = 0; j < newPl.len; ++j)\n                    if (newPl.cell[j] == c) { inNew = true; break; }\n                if (!inNew) ++freed;\n            }\n        }\n        int newlyUsed = 0;\n        for (int i = 0; i < newPl.len; ++i) {\n            int c = newPl.cell[i];\n            if (curUse[c] == 0) {\n                bool inOld = false;\n                for (int j = 0; j < oldPl.len; ++j)\n                    if (oldPl.cell[j] == c) { inOld = true; break; }\n                if (!inOld) ++newlyUsed;\n            }\n        }\n        int delta = newlyUsed - freed;\n        if (delta < 0) {                           // strict improvement\n            unplace(oldPl);\n            place(newPl);\n            curIdx[sid] = pid;\n            if (curUsedCells < bestUsed) {\n                bestUsed = curUsedCells;\n                bestLetter = curLetter;\n            }\n        }\n    }\n\n    /* ---------- output the best matrix ---------- */\n    for (int r = 0; r < N; ++r) {\n        string line;\n        for (int c = 0; c < N; ++c) {\n            int id = cellId(r, c);\n            if (bestLetter[id] == -1) line += '.';\n            else                       line += char('A' + bestLetter[id]);\n        }\n        cout << line << '\\n';\n    }\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXV = 5005;                 // maximal number of cells (N\u226469 \u2192 < 5000)\n\nstruct Edge {\n    int u, v, w;\n    bool operator<(Edge const& other) const { return w < other.w; }\n};\n\nstruct DSU {\n    vector<int> p, r;\n    DSU(int n = 0) { init(n); }\n    void init(int n) { p.resize(n); r.assign(n,0); iota(p.begin(),p.end(),0); }\n    int find(int x){ return p[x]==x?x:p[x]=find(p[x]); }\n    bool unite(int a,int b){\n        a=find(a); b=find(b);\n        if(a==b) return false;\n        if(r[a]<r[b]) swap(a,b);\n        p[b]=a;\n        if(r[a]==r[b]) ++r[a];\n        return true;\n    }\n};\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    // --- 1. give an id to every road cell, store its weight and coordinates ----------\n    vector<vector<int>> id(N, vector<int>(N,-1));\n    vector<int> weight; weight.reserve(N*N);\n    vector<int> iOf, jOf; iOf.reserve(N*N); jOf.reserve(N*N);\n    int V = 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] = V++;\n                weight.push_back(g[i][j]-'0');\n                iOf.push_back(i);\n                jOf.push_back(j);\n            }\n        }\n    }\n    const int startIdx = id[si][sj];\n\n    // --- 2. row and column segment ids ------------------------------------------------\n    vector<int> rowId(V,-1), colId(V,-1);\n    int rowSegCnt = 0;\n    for(int i=0;i<N;++i){\n        int cur = -1;\n        for(int j=0;j<N;++j){\n            if(g[i][j]!='#'){\n                if(j==0 || g[i][j-1]=='#') cur = rowSegCnt++;\n                rowId[id[i][j]] = cur;\n            }\n        }\n    }\n    int colSegCnt = 0;\n    for(int j=0;j<N;++j){\n        int cur = -1;\n        for(int i=0;i<N;++i){\n            if(g[i][j]!='#'){\n                if(i==0 || g[i-1][j]=='#') cur = colSegCnt++;\n                colId[id[i][j]] = cur;\n            }\n        }\n    }\n\n    // decide which side to cover\n    bool useRow = rowSegCnt <= colSegCnt;\n    vector<int> segId = useRow ? rowId : colId;\n    int segCnt = useRow ? rowSegCnt : colSegCnt;\n\n    // --- 3. build edge list (only right / down, undirected) ----------------------------\n    vector<Edge> edges;\n    edges.reserve(4*V);\n    const int di[4] = {-1,1,0,0};\n    const int dj[4] = {0,0,-1,1};\n    for(int i=0;i<N;++i){\n        for(int j=0;j<N;++j){\n            if(g[i][j]=='#') continue;\n            int u = id[i][j];\n            // right neighbour\n            if(j+1<N && g[i][j+1]!='#'){\n                int v = id[i][j+1];\n                if(u<v) edges.push_back({u,v,weight[u]+weight[v]});\n            }\n            // down neighbour\n            if(i+1<N && g[i+1][j]!='#'){\n                int v = id[i+1][j];\n                if(u<v) edges.push_back({u,v,weight[u]+weight[v]});\n            }\n        }\n    }\n\n    // --- 4. MST with Kruskal ---------------------------------------------------------\n    sort(edges.begin(), edges.end());\n    DSU dsu(V);\n    vector<vector<int>> mstAdj(V);\n    int added = 0;\n    for(const auto& e: edges){\n        if(dsu.unite(e.u, e.v)){\n            mstAdj[e.u].push_back(e.v);\n            mstAdj[e.v].push_back(e.u);\n            if(++added == V-1) break;\n        }\n    }\n\n    // --- 5. root the tree in the start cell -----------------------------------------\n    vector<int> parent(V,-1);\n    vector<vector<int>> children(V);\n    vector<int> order; order.reserve(V);\n    // iterative stack for rooting\n    vector<int> st; st.push_back(startIdx);\n    parent[startIdx] = startIdx;\n    while(!st.empty()){\n        int u = st.back(); st.pop_back();\n        order.push_back(u);\n        for(int v: mstAdj[u]){\n            if(v==parent[u]) continue;\n            parent[v] = u;\n            children[u].push_back(v);\n            st.push_back(v);\n        }\n    }\n\n    // --- 6. subtree masks of segment ids --------------------------------------------\n    using Mask = bitset<MAXV>;\n    vector<Mask> subMask(V);\n    vector<int> subCnt(V,0);\n    // post\u2011order (reverse of the order we obtained above, because every parent appears after its children)\n    for(int i=(int)order.size()-1;i>=0;--i){\n        int u = order[i];\n        subMask[u].reset();\n        subMask[u].set(segId[u]);\n        for(int v: children[u]){\n            subMask[u] |= subMask[v];\n        }\n        subCnt[u] = (int)subMask[u].count();\n    }\n\n    // --- 7. sort children by number of different segments in their subtree ----------\n    for(int u=0;u<V;++u){\n        sort(children[u].begin(), children[u].end(),\n            [&](int a, int b){ return subCnt[a] > subCnt[b]; });\n    }\n\n    // --- 8. depth\u2011first walk, but only when a subtree still contains uncovered segments\n    Mask coveredMask;\n    coveredMask.reset();\n    coveredMask.set(segId[startIdx]);          // start segment already visited\n\n    string answer; answer.reserve(2*V);\n    function<void(int,int)> dfsWalk = [&](int u, int p)->void{\n        for(int v: children[u]){\n            // if nothing uncovered in this subtree \u2013 skip it\n            if ( (subMask[v] & ~coveredMask).none() ) continue;\n            // move u -> v\n            if(iOf[v]==iOf[u]-1 && jOf[v]==jOf[u]) answer.push_back('U');\n            else if(iOf[v]==iOf[u]+1 && jOf[v]==jOf[u]) answer.push_back('D');\n            else if(iOf[v]==iOf[u] && jOf[v]==jOf[u]-1) answer.push_back('L');\n            else if(iOf[v]==iOf[u] && jOf[v]==jOf[u]+1) answer.push_back('R');\n            else { /* should never happen */ }\n\n            coveredMask.set(segId[v]);          // v itself is visited now\n            dfsWalk(v, u);\n            // return v -> u\n            if(iOf[v]==iOf[u]-1 && jOf[v]==jOf[u]) answer.push_back('D');\n            else if(iOf[v]==iOf[u]+1 && jOf[v]==jOf[u]) answer.push_back('U');\n            else if(iOf[v]==iOf[u] && jOf[v]==jOf[u]-1) answer.push_back('R');\n            else if(iOf[v]==iOf[u] && jOf[v]==jOf[u]+1) answer.push_back('L');\n            else { /* should never happen */ }\n        }\n    };\n    dfsWalk(startIdx, -1);\n\n    // --- 9. output ------------------------------------------------------------------\n    cout << answer << '\\n';\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ---------- data structures ---------- */\n\nstruct Task {\n    vector<int> d;          // skill requirements, size K\n    int indegree = 0;       // number of unfinished predecessors\n    int status = -1;        // -1 : not started, 0 : in progress, 1 : completed\n    int start_day = -1;     // day on which the task was started\n    int assigned_to = -1;   // member id (0\u2011based) or -1\n    int total_req = 0;      // \u03a3_k d[k]  (used for a cheap difficulty estimate)\n};\n\nstruct Member {\n    vector<int> s_est;          // not used by the final algorithm, kept for symmetry\n    double avg_time_per_unit = 1.0;   // average observed  (time / total_requirement)\n    int total_processed = 0;    // number of tasks finished by this member\n    int total_time = 0;         // sum of their processing times\n};\n\n/* ---------- main ---------- */\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---- read prior information ---- */\n    int N, M, K, R;\n    if (!(cin >> N >> M >> K >> R)) return 0;\n\n    vector<Task> tasks(N);\n    for (int i = 0; i < N; ++i) {\n        tasks[i].d.resize(K);\n        tasks[i].total_req = 0;\n        for (int k = 0; k < K; ++k) {\n            cin >> tasks[i].d[k];\n            tasks[i].total_req += tasks[i].d[k];\n        }\n    }\n\n    vector<vector<int>> graph(N);          // edge u \u2192 v  (u must be done before v)\n    for (int i = 0; i < R; ++i) {\n        int u, v;  cin >> u >> v;  --u; --v;\n        graph[u].push_back(v);\n        ++tasks[v].indegree;\n    }\n\n    vector<Member> members(M);\n    for (int j = 0; j < M; ++j) members[j].s_est.assign(K, 0);\n\n    vector<int> member_status(M, -1);               // -1 \u2192 idle, otherwise task id\n    unordered_map<int,int> in_progress;             // taskid \u2192 start_day\n\n    int day = 0;\n\n    /* ---- day loop ---- */\n    while (true) {\n        ++day;\n        if (day > 2000) break;                     // safety, should never trigger\n\n        /* -- 1. available tasks -- */\n        vector<int> available;\n        for (int i = 0; i < N; ++i)\n            if (tasks[i].status == -1 && tasks[i].indegree == 0)\n                available.push_back(i);\n\n        sort(available.begin(), available.end(),\n             [&](int a, int b){ return tasks[a].total_req < tasks[b].total_req; });\n\n        /* -- 2. idle members -- */\n        vector<int> idle_members;\n        for (int j = 0; j < M; ++j)\n            if (member_status[j] == -1) idle_members.push_back(j);\n\n        /* -- 3. greedy matching -- */\n        vector<pair<int,int>> assignments;           // (member , task)\n        for (int j : idle_members) {\n            if (available.empty()) break;\n\n            int   best_task = -1;\n            double best_pred = 1e99;\n\n            for (size_t pos = 0; pos < available.size(); ++pos) {\n                int i = available[pos];\n                double pred = members[j].avg_time_per_unit * tasks[i].total_req;\n                if (pred < best_pred) {\n                    best_pred = pred;\n                    best_task = i;\n                }\n            }\n\n            if (best_task != -1) {\n                assignments.emplace_back(j, best_task);\n                // remove the chosen task from the vector (swap with back)\n                auto it = find(available.begin(), available.end(), best_task);\n                *it = available.back();\n                available.pop_back();\n            }\n        }\n\n        /* -- 4. output -- */\n        cout << assignments.size();\n        for (auto [mem, t] : assignments)\n            cout << ' ' << (mem + 1) << ' ' << (t + 1);\n        cout << '\\n';\n        cout.flush();\n\n        /* -- 5. update internal state -- */\n        for (auto [mem, t] : assignments) {\n            tasks[t].status = 0;\n            tasks[t].start_day = day;\n            tasks[t].assigned_to = mem;\n            member_status[mem] = t;\n            in_progress[t] = day;\n        }\n\n        /* -- 6. read completions -- */\n        int num_compl;  cin >> num_compl;\n        if (num_compl == -1) break;                 // finished or time limit\n\n        for (int i = 0; i < num_compl; ++i) {\n            int mem;  cin >> mem;  --mem;\n            int task = member_status[mem];\n            if (task == -1) continue;                // should never happen\n\n            int start_day = in_progress[task];\n            int t = day - start_day;                 // real processing time\n\n            Member &m = members[mem];\n            ++m.total_processed;\n            m.total_time += t;\n\n            // update average time per unit (exponential moving average)\n            int req = tasks[task].total_req;\n            if (req > 0) {\n                double this_avg = static_cast<double>(t) / req;\n                constexpr double alpha = 0.2;         // learning rate\n                m.avg_time_per_unit = (1.0 - alpha) * m.avg_time_per_unit\n                                      + alpha * this_avg;\n            }\n\n            // mark task completed\n            tasks[task].status = 1;\n            tasks[task].assigned_to = -1;\n            member_status[mem] = -1;\n            in_progress.erase(task);\n\n            // make dependent tasks available\n            for (int child : graph[task]) {\n                if (--tasks[child].indegree == 0) {\n                    // will be collected in the next day\n                }\n            }\n        }\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 1000;               // number of orders in the input\nconst int M = 50;                 // orders that have to be chosen\nconst int CENTER_X = 400;\nconst int CENTER_Y = 400;\n\n/*  order data  */\nint a[N], b[N], c_[N], d_[N];\nint internalDist[N];\nint startDist[N];\nint endDist[N];\nint between[N][N];                // delivery i -> pickup j\n\n/*  Manhattan distance  */\ninline int manh(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n/*  cost between two orders, -1 stands for the centre  */\ninline int costBetween(int from, int to) {\n    if (from == -1 && to == -1) return 0;\n    if (from == -1) return startDist[to];\n    if (to   == -1) return endDist[from];\n    return between[from][to];\n}\n\n/*  total travel time of a permutation (block order)  */\nint computeCost(const vector<int>& perm) {\n    int sum = 0;\n    for (int id : perm) sum += internalDist[id];\n    sum += startDist[perm[0]];\n    for (int i = 0; i + 1 < (int)perm.size(); ++i)\n        sum += between[perm[i]][perm[i + 1]];\n    sum += endDist[perm.back()];\n    return sum;\n}\n\n/* -------------------------------------------------------------\n   Greedy insertion \u2013 returns a feasible permutation\n   -------------------------------------------------------------\n*/\nvector<int> greedyInsertion(mt19937& rng) {\n    vector<int> path;                     // current permutation of orders\n    path.reserve(M);\n    vector<char> used(N, 0);               // order already taken ?\n\n    while ((int)path.size() < M) {\n        int bestTotal = INT_MAX;\n        int bestOrder = -1;\n        int bestPos   = -1;\n\n        for (int i = 0; i < N; ++i) if (!used[i]) {\n            int bestDelta = INT_MAX;\n            int bestPos_i = -1;\n            int sz = (int)path.size();\n            for (int pos = 0; pos <= sz; ++pos) {\n                int prev = (pos == 0) ? -1 : path[pos - 1];\n                int nxt  = (pos == sz) ? -1 : path[pos];\n                int delta = costBetween(prev, i) + costBetween(i, nxt)\n                            - costBetween(prev, nxt);\n                if (delta < bestDelta) {\n                    bestDelta = delta;\n                    bestPos_i = pos;\n                }\n            }\n            int totalIncrease = bestDelta + internalDist[i];\n            // random tie\u2011break\n            if (totalIncrease < bestTotal ||\n                (totalIncrease == bestTotal && (rng() & 1))) {\n                bestTotal = totalIncrease;\n                bestOrder = i;\n                bestPos   = bestPos_i;\n            }\n        }\n        // insert the chosen order\n        path.insert(path.begin() + bestPos, bestOrder);\n        used[bestOrder] = 1;\n    }\n    return path;\n}\n\n/* -------------------------------------------------------------\n   Simulated annealing on a permutation (keeps the set of orders)\n   -------------------------------------------------------------\n*/\nvector<int> simulatedAnnealing(const vector<int>& startPerm,\n                               mt19937& rng,\n                               double timeLimit)\n{\n    const double initTemp = 1000.0;\n    const int    movesPerStep = 2000;\n\n    vector<int> cur = startPerm;\n    vector<char> used(N, 0);\n    for (int v : cur) used[v] = 1;\n    int curCost = computeCost(cur);\n    int bestCost = curCost;\n    vector<int> best = cur;\n\n    double start = (double)clock() / CLOCKS_PER_SEC;\n    uniform_real_distribution<double> uni01(0.0, 1.0);\n    uniform_int_distribution<int> posDist(0, M - 1);\n    uniform_int_distribution<int> orderDist(0, N - 1);\n\n    while (true) {\n        double elapsed = (double)clock() / CLOCKS_PER_SEC - start;\n        if (elapsed > timeLimit) break;\n        double temperature = initTemp * (1.0 - elapsed / timeLimit);\n        if (temperature <= 0.0) break;\n\n        for (int step = 0; step < movesPerStep; ++step) {\n            int move = rng() % 4;                     // 0 swap,1 move,2 reverse,3 replace\n            vector<int> nxt = cur;\n            vector<char> nxtUsed = used;\n\n            if (move == 0) {                         // swap two positions\n                int i = posDist(rng), j = posDist(rng);\n                if (i == j) continue;\n                swap(nxt[i], nxt[j]);\n            }\n            else if (move == 1) {                    // move one order\n                int i = posDist(rng), j = posDist(rng);\n                if (i == j) continue;\n                int v = nxt[i];\n                nxt.erase(nxt.begin() + i);\n                nxt.insert(nxt.begin() + j, v);\n            }\n            else if (move == 2) {                    // reverse a segment\n                int i = posDist(rng), j = posDist(rng);\n                if (i >= j) continue;\n                reverse(nxt.begin() + i, nxt.begin() + j + 1);\n            }\n            else {                                    // replace one order\n                int i = posDist(rng);\n                int oldId = nxt[i];\n                int newId;\n                do { newId = orderDist(rng); } while (nxtUsed[newId]);\n                nxt[i] = newId;\n                nxtUsed[oldId] = 0;\n                nxtUsed[newId] = 1;\n            }\n\n            int nxtCost = computeCost(nxt);\n            int delta   = nxtCost - curCost;\n            double prob = (delta < 0) ? 1.0 : exp(-delta / temperature);\n            if (prob > uni01(rng)) {\n                cur.swap(nxt);\n                used.swap(nxtUsed);\n                curCost = nxtCost;\n                if (curCost < bestCost) {\n                    bestCost = curCost;\n                    best = cur;\n                }\n            }\n        }\n    }\n    return best;\n}\n\n/* -------------------------------------------------------------\n   Simple deterministic hill\u2011climbing (reverse / swap)\n   -------------------------------------------------------------\n*/\nvector<int> localImprove(vector<int> perm) {\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        // try to reverse a segment\n        for (int i = 0; i < M; ++i)\n            for (int j = i + 1; j < M; ++j) {\n                vector<int> cand = perm;\n                reverse(cand.begin() + i, cand.begin() + j + 1);\n                int candCost = computeCost(cand);\n                int curCost  = computeCost(perm);\n                if (candCost < curCost) {\n                    perm.swap(cand);\n                    improved = true;\n                    goto nextLoop;               // start again\n                }\n            }\n        // try to swap two positions\n        for (int i = 0; i < M; ++i)\n            for (int j = i + 1; j < M; ++j) {\n                vector<int> cand = perm;\n                swap(cand[i], cand[j]);\n                int candCost = computeCost(cand);\n                int curCost  = computeCost(perm);\n                if (candCost < curCost) {\n                    perm.swap(cand);\n                    improved = true;\n                    goto nextLoop;\n                }\n            }\n    nextLoop: ;\n    }\n    return perm;\n}\n\n/* -------------------------------------------------------------\n   Main\n   -------------------------------------------------------------\n*/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---- read input --------------------------------------------------- */\n    for (int i = 0; i < N; ++i) {\n        if (!(cin >> a[i] >> b[i] >> c_[i] >> d_[i])) return 0;\n    }\n\n    /* ---- pre\u2011compute all distances ------------------------------------ */\n    for (int i = 0; i < N; ++i) {\n        internalDist[i] = manh(a[i], b[i], c_[i], d_[i]);\n        startDist[i]    = manh(CENTER_X, CENTER_Y, a[i], b[i]);\n        endDist[i]      = manh(c_[i], d_[i], CENTER_X, CENTER_Y);\n        for (int j = 0; j < N; ++j)\n            between[i][j] = manh(c_[i], d_[i], a[j], b[j]);\n    }\n\n    /* ---- random generator -------------------------------------------- */\n    std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count());\n\n    /* ---- several runs ------------------------------------------------- */\n    const int runs = 3;\n    const double timePerRun = 1.8 / runs;\n\n    vector<int> bestOverall;\n    int bestOverallCost = INT_MAX;\n\n    for (int r = 0; r < runs; ++r) {\n        vector<int> init = greedyInsertion(rng);\n        vector<int> afterSA = simulatedAnnealing(init, rng, timePerRun);\n        vector<int> afterLocal = localImprove(afterSA);\n        int cost = computeCost(afterLocal);\n        if (cost < bestOverallCost) {\n            bestOverallCost = cost;\n            bestOverall = afterLocal;\n        }\n    }\n\n    /* ---- output ------------------------------------------------------- */\n    cout << \"50\";\n    for (int id : bestOverall) cout << ' ' << id + 1;\n    cout << '\\n';\n\n    cout << \"102 400 400\";\n    for (int id : bestOverall) {\n        cout << ' ' << a[id] << ' ' << b[id] << ' '\n             << c_[id] << ' ' << d_[id];\n    }\n    cout << \" 400 400\\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);\n        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\nstruct Edge {\n    int u, v;\n    int d; // rounded distance\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<pair<int,int>> coords(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    // Read edges and compute d_i\n    vector<Edge> edges(M);\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        cin >> u >> v;\n        edges[i].u = u;\n        edges[i].v = v;\n        long long dx = (long long)coords[u].first - coords[v].first;\n        long long dy = (long long)coords[u].second - coords[v].second;\n        double dist = sqrt((double)dx * dx + (double)dy * dy);\n        edges[i].d = (int)llround(dist);\n    }\n    \n    DSU dsu(N);\n    int components = N;\n    \n    for (int i = 0; i < M; ++i) {\n        int l;\n        cin >> l;\n        \n        int u = edges[i].u;\n        int v = edges[i].v;\n        \n        // If already connected, no need for this edge\n        if (components == 1) {\n            cout << 0 << endl;\n            continue;\n        }\n        \n        int ru = dsu.find(u);\n        int rv = dsu.find(v);\n        \n        // Edge creates a cycle, reject\n        if (ru == rv) {\n            cout << 0 << endl;\n            continue;\n        }\n        \n        // Compute rank of l_i in [d_i, 3*d_i]\n        double d = edges[i].d;\n        double rank = (l - d) / (2.0 * d);\n        \n        // Dynamic threshold: increases from 0.3 to 1.0\n        double progress = (double)i / (M - 1);\n        double threshold = 0.3 + 0.7 * progress;\n        \n        // Accept if rank is good enough, or if we're near the end\n        bool accept = (rank <= threshold) || (i >= M - 50);\n        \n        if (accept) {\n            dsu.unite(ru, rv);\n            --components;\n            cout << 1 << endl;\n        } else {\n            cout << 0 << endl;\n        }\n    }\n    \n    return 0;\n}","ahc008":"","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 20;\nconst int W = 20;\nconst int N = H * W;\nconst int INF = 1e9;\n\n/* ---------- global data ---------- */\nint start, target;\ndouble forgetP;                     // probability of forgetting a character\n\narray<array<int,4>,N> neighbour;   // neighbour[v][dir], dir = 0(U),1(D),2(L),3(R)\narray<char,4> dirChar{'U','D','L','R'};\narray<int,256> dirIdx;              // char -> 0..3, -1 = invalid\n\nvector<int> bfsDist;                // shortest deterministic distance to target\n\n/* ---------- evaluation of a route ---------- */\ndouble evaluate(const string &s) {\n    static vector<double> prob, nxt;\n    prob.assign(N, 0.0);\n    nxt.assign(N, 0.0);\n    prob[start] = 1.0;\n    double expected = 0.0;\n    int L = (int)s.size();\n\n    for (int turn = 1; turn <= L; ++turn) {\n        fill(nxt.begin(), nxt.end(), 0.0);\n        int d = dirIdx[(unsigned char)s[turn-1]];\n        double arrival = 0.0;\n\n        for (int v = 0; v < N; ++v) {\n            double cur = prob[v];\n            if (cur == 0.0) continue;\n            double stayProb = cur * forgetP;\n            double moveProb = cur * (1.0 - forgetP);\n            int w = neighbour[v][d];\n            if (w == target) arrival += moveProb;\n            else               nxt[w] += moveProb;\n            nxt[v] += stayProb;\n        }\n        expected += arrival * (401 - turn);\n        prob.swap(nxt);\n    }\n    return expected;\n}\n\n/* ---------- BFS on the grid (ignoring staying) ---------- */\nvector<int> bfs_from(int src) {\n    vector<int> dist(N, INF);\n    queue<int> q;\n    dist[src] = 0;\n    q.push(src);\n    while (!q.empty()) {\n        int v = q.front(); q.pop();\n        int d = dist[v];\n        for (int dir = 0; dir < 4; ++dir) {\n            int w = neighbour[v][dir];\n            if (w == v) continue;               // blocked by wall\n            if (dist[w] == INF) {\n                dist[w] = d + 1;\n                q.push(w);\n            }\n        }\n    }\n    return dist;\n}\n\n/* ---------- shortest deterministic path from S to T ---------- */\nvector<char> shortestPath() {\n    vector<int> parent(N, -1);\n    vector<char> pdir(N, 0);\n    vector<int> dist(N, -1);\n    queue<int> q;\n    q.push(start);\n    dist[start] = 0;\n    while (!q.empty()) {\n        int v = q.front(); q.pop();\n        if (v == target) break;\n        for (int dir = 0; dir < 4; ++dir) {\n            int w = neighbour[v][dir];\n            if (w == v) continue;\n            if (dist[w] == -1) {\n                dist[w] = dist[v] + 1;\n                parent[w] = v;\n                pdir[w] = dirChar[dir];\n                q.push(w);\n            }\n        }\n    }\n    vector<char> path;\n    int cur = target;\n    while (cur != start) {\n        path.push_back(pdir[cur]);\n        cur = parent[cur];\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n/* ---------- greedy construction (length = 200) ---------- */\nstring greedyRoute() {\n    const int L = 200;\n    string s;\n    s.reserve(L);\n    vector<double> prob(N, 0.0), nxt(N, 0.0);\n    prob[start] = 1.0;\n\n    for (int turn = 1; turn <= L; ++turn) {\n        double bestVal = -1e100;\n        int bestDir = -1;\n        vector<double> bestNxt(N, 0.0);\n        double bestArr = 0.0;\n\n        for (int dir = 0; dir < 4; ++dir) {\n            fill(nxt.begin(), nxt.end(), 0.0);\n            double arrival = 0.0;\n\n            for (int v = 0; v < N; ++v) {\n                double cur = prob[v];\n                if (cur == 0.0) continue;\n                double stayProb = cur * forgetP;\n                double moveProb = cur * (1.0 - forgetP);\n                int w = neighbour[v][dir];\n                if (w == target) arrival += moveProb;\n                else            nxt[w] += moveProb;\n                nxt[v] += stayProb;\n            }\n            // expected remaining BFS distance\n            double expDist = 0.0;\n            for (int v = 0; v < N; ++v) expDist += nxt[v] * bfsDist[v];\n\n            double value = arrival * (401 - turn) - expDist;\n            if (value > bestVal) {\n                bestVal = value;\n                bestDir = dir;\n                bestArr = arrival;\n                bestNxt.swap(nxt);\n            }\n        }\n        s.push_back(dirChar[bestDir]);\n        prob.swap(bestNxt);\n    }\n    return s;\n}\n\n/* ---------- random modification of a route ---------- */\nstring modify(const string &cur, int minLen, mt19937 &rng) {\n    string nxt = cur;\n    int L = (int)nxt.size();\n    uniform_int_distribution<int> opDist(0, 9);\n    int op = opDist(rng);\n    if (op < 7) { // replace\n        uniform_int_distribution<int> posDist(0, L - 1);\n        uniform_int_distribution<int> dirDist(0, 3);\n        int pos = posDist(rng);\n        nxt[pos] = dirChar[dirDist(rng)];\n    } else if (op < 9) { // insert\n        if (L < 200) {\n            uniform_int_distribution<int> posDist(0, L);\n            uniform_int_distribution<int> dirDist(0, 3);\n            int pos = posDist(rng);\n            nxt.insert(nxt.begin() + pos, dirChar[dirDist(rng)]);\n        } else { // replace instead\n            uniform_int_distribution<int> posDist(0, L - 1);\n            uniform_int_distribution<int> dirDist(0, 3);\n            int pos = posDist(rng);\n            nxt[pos] = dirChar[dirDist(rng)];\n        }\n    } else { // delete\n        if (L > minLen) {\n            uniform_int_distribution<int> posDist(0, L - 1);\n            int pos = posDist(rng);\n            nxt.erase(nxt.begin() + pos);\n        } else { // replace instead\n            uniform_int_distribution<int> posDist(0, L - 1);\n            uniform_int_distribution<int> dirDist(0, 3);\n            int pos = posDist(rng);\n            nxt[pos] = dirChar[dirDist(rng)];\n        }\n    }\n    return nxt;\n}\n\n/* ---------- main ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    /* ---- read input ---- */\n    int si, sj, ti, tj;\n    double p;\n    if (!(cin >> si >> sj >> ti >> tj >> p)) return 0;\n    start = si * W + sj;\n    target = ti * W + tj;\n    forgetP = p;\n\n    vector<string> h(H, string(W - 1, '0'));\n    for (int i = 0; i < H; ++i) cin >> h[i];\n    vector<string> v(H - 1, string(W, '0'));\n    for (int i = 0; i < H - 1; ++i) cin >> v[i];\n\n    /* ---- build neighbour table ---- */\n    for (int i = 0; i < H; ++i) {\n        for (int j = 0; j < W; ++j) {\n            int id = i * W + j;\n            // up\n            if (i == 0) neighbour[id][0] = id;\n            else if (v[i-1][j] == '1') neighbour[id][0] = id;\n            else neighbour[id][0] = (i-1) * W + j;\n            // down\n            if (i == H-1) neighbour[id][1] = id;\n            else if (v[i][j] == '1') neighbour[id][1] = id;\n            else neighbour[id][1] = (i+1) * W + j;\n            // left\n            if (j == 0) neighbour[id][2] = id;\n            else if (h[i][j-1] == '1') neighbour[id][2] = id;\n            else neighbour[id][2] = i * W + (j-1);\n            // right\n            if (j == W-1) neighbour[id][3] = id;\n            else if (h[i][j] == '1') neighbour[id][3] = id;\n            else neighbour[id][3] = i * W + (j+1);\n        }\n    }\n\n    // dirIdx\n    fill(dirIdx.begin(), dirIdx.end(), -1);\n    for (int d = 0; d < 4; ++d) dirIdx[(unsigned char)dirChar[d]] = d;\n\n    /* ---- BFS distances from target ---- */\n    bfsDist = bfs_from(target);\n\n    /* ---- build candidate routes ---- */\n    vector<string> candidates;\n    // 1) shortest path (maybe repeated twice)\n    vector<char> sp = shortestPath();\n    int spLen = (int)sp.size();\n    string cand1;\n    int repeat = (spLen * 2 <= 200) ? 2 : 1;\n    for (char c : sp) {\n        for (int i = 0; i < repeat; ++i) cand1.push_back(c);\n    }\n    candidates.push_back(cand1);\n    // 2) greedy route\n    candidates.push_back(greedyRoute());\n    // 3) random route (optional)\n    {\n        string rnd(200, 'U');\n        mt19937 rng(0);\n        uniform_int_distribution<int> dirDist(0,3);\n        for (char &c : rnd) c = dirChar[dirDist(rng)];\n        candidates.push_back(rnd);\n    }\n\n    /* ---- evaluate all candidates, keep the best ---- */\n    double bestScore = -1.0;\n    string bestRoute = candidates[0];\n    for (const string &cand : candidates) {\n        double sc = evaluate(cand);\n        if (sc > bestScore) {\n            bestScore = sc;\n            bestRoute = cand;\n        }\n    }\n\n    /* ---- hill climbing / simulated annealing ---- */\n    const double TIME_LIMIT = 1.8; // seconds\n    auto startTime = chrono::high_resolution_clock::now();\n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n\n    string cur = bestRoute;\n    double curScore = bestScore;\n    double temperature = 1.0;\n    int minLen = spLen; // we never delete below the original shortest\u2011path length\n\n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - startTime).count();\n        if (elapsed > TIME_LIMIT) break;\n\n        temperature *= 0.999;\n\n        string cand = modify(cur, minLen, rng);\n        double candScore = evaluate(cand);\n\n        double delta = candScore - curScore;\n        bool accept = (delta > 0.0);\n        if (!accept) {\n            uniform_real_distribution<double> uni(0.0, 1.0);\n            if (uni(rng) < exp(delta / temperature)) accept = true;\n        }\n        if (accept) {\n            cur = cand;\n            curScore = candScore;\n        }\n        if (candScore > bestScore) {\n            bestScore = candScore;\n            bestRoute = cand;\n        }\n    }\n\n    /* ---- output ---- */\n    cout << bestRoute << '\\n';\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Problem constants\nconst int H = 30, W = 30;\nconst int N = H * W; // 900\nconst int DIR = 4;\nconst int NODE_COUNT = N * DIR; // 3600\n\n// to[t][d]: exit direction when entering tile type t from direction d (-1 if no connection)\nconst int TO[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1}\n};\n\n// Direction vectors: left, up, right, down\nconst int DI[4] = {0, -1, 0, 1};\nconst int DJ[4] = {-1, 0, 1, 0};\n\n// Rotation mapping: rotate_map[t][r] = effective type after r rotations\nint ROTATE_MAP[8][4];\n\n// Initialize rotation mapping\nvoid init_rotate_map() {\n    // One rotation mapping (given in problem statement)\n    const int ROT1[8] = {1, 2, 3, 0, 5, 4, 7, 6};\n    for (int t = 0; t < 8; ++t) {\n        ROTATE_MAP[t][0] = t;\n        int cur = t;\n        for (int r = 1; r < 4; ++r) {\n            cur = ROT1[cur];\n            ROTATE_MAP[t][r] = cur;\n        }\n    }\n}\n\n// Compute score for a given rotation assignment\npair<int, int> compute_score(const array<int, N>& rot, const array<int, N>& tiles) {\n    // Build next array for functional graph\n    array<int, NODE_COUNT> nxt;\n    nxt.fill(-1);\n    \n    for (int i = 0; i < H; ++i) {\n        for (int j = 0; j < W; ++j) {\n            int idx = i * W + j;\n            int t = tiles[idx];\n            int r = rot[idx];\n            int eff_type = ROTATE_MAP[t][r];\n            \n            for (int d = 0; d < DIR; ++d) {\n                int d2 = TO[eff_type][d];\n                if (d2 == -1) {\n                    nxt[idx * DIR + d] = -1;\n                    continue;\n                }\n                int ni = i + DI[d2];\n                int nj = j + DJ[d2];\n                if (ni < 0 || ni >= H || nj < 0 || nj >= W) {\n                    nxt[idx * DIR + d] = -1;\n                    continue;\n                }\n                int nidx = ni * W + nj;\n                int nd = (d2 + 2) % DIR; // entry direction for next tile\n                nxt[idx * DIR + d] = nidx * DIR + nd;\n            }\n        }\n    }\n    \n    // Find cycles in functional graph\n    array<char, NODE_COUNT> state; // 0=unvisited, 1=visiting, 2=done\n    state.fill(0);\n    vector<int> cycle_lens;\n    cycle_lens.reserve(NODE_COUNT);\n    \n    vector<int> path;\n    path.reserve(NODE_COUNT);\n    \n    for (int s = 0; s < NODE_COUNT; ++s) {\n        if (state[s] != 0) continue;\n        \n        int cur = s;\n        path.clear();\n        // Traverse until we hit visited node or dead end\n        while (cur != -1 && state[cur] == 0) {\n            state[cur] = 1;\n            path.push_back(cur);\n            cur = nxt[cur];\n        }\n        \n        if (cur != -1 && state[cur] == 1) {\n            // Found a cycle - find its length\n            int start_idx = -1;\n            for (int i = 0; i < (int)path.size(); ++i) {\n                if (path[i] == cur) {\n                    start_idx = i;\n                    break;\n                }\n            }\n            if (start_idx != -1) {\n                int len = (int)path.size() - start_idx;\n                cycle_lens.push_back(len);\n            }\n        }\n        \n        // Mark all visited nodes as done\n        for (int node : path) {\n            state[node] = 2;\n        }\n    }\n    \n    // Get top two cycle lengths\n    sort(cycle_lens.begin(), cycle_lens.end(), greater<int>());\n    int L1 = 0, L2 = 0;\n    if (!cycle_lens.empty()) L1 = cycle_lens[0];\n    if (cycle_lens.size() >= 2) L2 = cycle_lens[1];\n    \n    return {L1, L2};\n}\n\n// Simulated annealing to find good rotation assignments\npair<array<int, N>, long long> simulated_annealing(const array<int, N>& tiles) {\n    const double TIME_LIMIT = 1.85; // seconds\n    auto start_time = chrono::high_resolution_clock::now();\n    \n    // Random initialization\n    random_device rd;\n    mt19937 rng(rd());\n    uniform_int_distribution<int> dist_rot(0, 3);\n    \n    array<int, N> rot;\n    for (int i = 0; i < N; ++i) {\n        rot[i] = dist_rot(rng);\n    }\n    \n    // Evaluate initial solution\n    auto [L1, L2] = compute_score(rot, tiles);\n    long long best_score = (long long)L1 * L2;\n    array<int, N> best_rot = rot;\n    \n    // Simulated annealing parameters\n    double temp = 1.0;\n    const double COOLING = 0.995;\n    const double MIN_TEMP = 0.001;\n    \n    uniform_int_distribution<int> dist_tile(0, N-1);\n    uniform_real_distribution<double> dist_prob(0.0, 1.0);\n    \n    int iterations = 0;\n    \n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > TIME_LIMIT) break;\n        \n        // Cooling schedule\n        temp *= COOLING;\n        if (temp < MIN_TEMP) temp = MIN_TEMP;\n        \n        // Randomly select a tile and change its rotation\n        int tile = dist_tile(rng);\n        int old_rot = rot[tile];\n        int new_rot;\n        do {\n            new_rot = dist_rot(rng);\n        } while (new_rot == old_rot);\n        \n        // Apply change\n        rot[tile] = new_rot;\n        auto [new_L1, new_L2] = compute_score(rot, tiles);\n        long long new_score = (long long)new_L1 * new_L2;\n        \n        // Acceptance decision\n        double delta = new_score - best_score;\n        bool accept = false;\n        if (delta > 0) {\n            accept = true;\n        } else {\n            // Accept with probability exp(delta/temp)\n            double prob = exp(delta / temp);\n            if (dist_prob(rng) < prob) accept = true;\n        }\n        \n        if (accept) {\n            if (new_score > best_score) {\n                best_score = new_score;\n                best_rot = rot;\n            }\n        } else {\n            // Revert change\n            rot[tile] = old_rot;\n        }\n        \n        ++iterations;\n    }\n    \n    return {best_rot, best_score};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    init_rotate_map();\n    \n    // Read input\n    array<int, N> tiles;\n    for (int i = 0; i < H; ++i) {\n        string line;\n        if (!(cin >> line)) return 0;\n        for (int j = 0; j < W; ++j) {\n            tiles[i * W + j] = line[j] - '0';\n        }\n    }\n    \n    // Run multiple restarts to improve solution\n    const int RESTARTS = 5;\n    long long global_best_score = 0;\n    array<int, N> global_best_rot;\n    \n    for (int r = 0; r < RESTARTS; ++r) {\n        auto [rot, score] = simulated_annealing(tiles);\n        if (score > global_best_score) {\n            global_best_score = score;\n            global_best_rot = rot;\n        }\n    }\n    \n    // Output best rotation as 900-digit string\n    for (int i = 0; i < N; ++i) {\n        cout << global_best_rot[i];\n    }\n    cout << '\\n';\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Direction bit masks\nconst int DIR_LEFT = 1;   // 0001\nconst int DIR_UP = 2;     // 0010\nconst int DIR_RIGHT = 4;  // 0100\nconst int DIR_DOWN = 8;   // 1000\n\n// Movement vectors for [UP, DOWN, LEFT, RIGHT]\nconst int DR[4] = {-1, 1, 0, 0};\nconst int DC[4] = {0, 0, -1, 1};\nconst char MOVE_CHAR[4] = {'U', 'D', 'L', 'R'};\n\nclass SlidingTreePuzzle {\nprivate:\n    int N, T;\n    vector<int> board;  // 1D board representation\n    int emptyPos;       // Position of empty square\n    \n    // Check if tile has a line in specific direction\n    bool hasLine(int tile, int direction) {\n        return (tile & direction) != 0;\n    }\n    \n    // Get opposite direction\n    int opposite(int dir) {\n        switch(dir) {\n            case DIR_LEFT: return DIR_RIGHT;\n            case DIR_RIGHT: return DIR_LEFT;\n            case DIR_UP: return DIR_DOWN;\n            case DIR_DOWN: return DIR_UP;\n            default: return 0;\n        }\n    }\n    \n    // Convert 2D coordinates to 1D index\n    inline int idx(int r, int c) {\n        return r * N + c;\n    }\n    \n    // Check if position is within board bounds\n    inline bool inBounds(int r, int c) {\n        return r >= 0 && r < N && c >= 0 && c < N;\n    }\n    \n    // Evaluate board: returns size of largest tree component\n    int evaluate() {\n        vector<int> comp(N*N, -1);\n        vector<int> compSize;\n        vector<int> compEdges;\n        int compCount = 0;\n        \n        // Build adjacency list based on matching lines\n        vector<vector<int>> adj(N*N);\n        \n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                int pos = idx(r, c);\n                int tile = board[pos];\n                if (tile == 0) continue; // Skip empty square\n                \n                // Check right neighbor\n                if (c + 1 < N) {\n                    int npos = idx(r, c+1);\n                    int ntile = board[npos];\n                    if (ntile != 0 && hasLine(tile, DIR_RIGHT) && hasLine(ntile, DIR_LEFT)) {\n                        adj[pos].push_back(npos);\n                        adj[npos].push_back(pos);\n                    }\n                }\n                \n                // Check down neighbor\n                if (r + 1 < N) {\n                    int npos = idx(r+1, c);\n                    int ntile = board[npos];\n                    if (ntile != 0 && hasLine(tile, DIR_DOWN) && hasLine(ntile, DIR_UP)) {\n                        adj[pos].push_back(npos);\n                        adj[npos].push_back(pos);\n                    }\n                }\n            }\n        }\n        \n        // Find connected components using BFS\n        for (int i = 0; i < N*N; i++) {\n            if (board[i] == 0 || comp[i] != -1) continue;\n            \n            queue<int> q;\n            q.push(i);\n            comp[i] = compCount;\n            int size = 0;\n            \n            while (!q.empty()) {\n                int cur = q.front();\n                q.pop();\n                size++;\n                \n                for (int nxt : adj[cur]) {\n                    if (comp[nxt] == -1) {\n                        comp[nxt] = compCount;\n                        q.push(nxt);\n                    }\n                }\n            }\n            \n            compSize.push_back(size);\n            compEdges.push_back(0);\n            compCount++;\n        }\n        \n        // Count edges in each component (each edge counted once)\n        for (int i = 0; i < N*N; i++) {\n            if (board[i] == 0) continue;\n            for (int j : adj[i]) {\n                if (i < j) {\n                    int cid = comp[i];\n                    compEdges[cid]++;\n                }\n            }\n        }\n        \n        // Find largest tree component (edges == vertices - 1)\n        int best = 0;\n        for (int i = 0; i < compCount; i++) {\n            if (compEdges[i] == compSize[i] - 1) {\n                best = max(best, compSize[i]);\n            }\n        }\n        \n        return best;\n    }\n    \n    // Make a move in given direction, return move character\n    char makeMove(int dir) {\n        int r = emptyPos / N;\n        int c = emptyPos % N;\n        int nr = r + DR[dir];\n        int nc = c + DC[dir];\n        \n        if (!inBounds(nr, nc)) return '\\0';\n        \n        int npos = idx(nr, nc);\n        swap(board[emptyPos], board[npos]);\n        emptyPos = npos;\n        return MOVE_CHAR[dir];\n    }\n    \n    // Undo a move\n    void undoMove(int dir) {\n        int oppositeDir = (dir % 2 == 0) ? dir + 1 : dir - 1;\n        makeMove(oppositeDir);\n    }\n    \npublic:\n    // Solve the puzzle and return move sequence\n    string solve(int N_, int T_, const vector<int>& initialBoard) {\n        N = N_;\n        T = T_;\n        board = initialBoard;\n        \n        // Find empty position\n        for (int i = 0; i < N*N; i++) {\n            if (board[i] == 0) {\n                emptyPos = i;\n                break;\n            }\n        }\n        \n        // Initialize best solution tracking\n        vector<int> bestBoard = board;\n        int bestScore = evaluate();\n        string bestMoves = \"\";\n        string currentMoves = \"\";\n        \n        // Hill climbing with random restarts\n        double startTime = clock();\n        double timeLimit = 2.8; // Leave 0.2 sec margin\n        \n        int steps = 0;\n        while ((clock() - startTime) / CLOCKS_PER_SEC < timeLimit) {\n            // Periodically restart from initial state to escape local maxima\n            if (steps % 500 == 0 && steps > 0) {\n                board = initialBoard;\n                for (int i = 0; i < N*N; i++) {\n                    if (board[i] == 0) {\n                        emptyPos = i;\n                        break;\n                    }\n                }\n                currentMoves = \"\";\n            }\n            \n            // Try all 4 possible moves and select the best one\n            int bestDir = -1;\n            int bestMoveScore = -1;\n            \n            for (int dir = 0; dir < 4; dir++) {\n                int r = emptyPos / N;\n                int c = emptyPos % N;\n                int nr = r + DR[dir];\n                int nc = c + DC[dir];\n                \n                if (!inBounds(nr, nc)) continue;\n                \n                // Simulate the move\n                char moveChar = makeMove(dir);\n                int score = evaluate();\n                \n                // Select move if it improves score or randomly if equal\n                if (score > bestMoveScore || (score == bestMoveScore && rand() % 3 == 0)) {\n                    bestMoveScore = score;\n                    bestDir = dir;\n                }\n                \n                // Undo the move\n                undoMove(dir);\n            }\n            \n            // Apply the best move if it maintains or improves score\n            if (bestDir != -1 && bestMoveScore >= evaluate()) {\n                char moveChar = makeMove(bestDir);\n                currentMoves += moveChar;\n                \n                // Update best solution found\n                if (bestMoveScore > bestScore) {\n                    bestScore = bestMoveScore;\n                    bestBoard = board;\n                    bestMoves = currentMoves;\n                    \n                    // Early exit if full tree achieved\n                    if (bestScore == N*N - 1) {\n                        return bestMoves;\n                    }\n                }\n            } else {\n                // No improving move available, make a random move\n                vector<int> validDirs;\n                for (int dir = 0; dir < 4; dir++) {\n                    int r = emptyPos / N;\n                    int c = emptyPos % N;\n                    int nr = r + DR[dir];\n                    int nc = c + DC[dir];\n                    if (inBounds(nr, nc)) {\n                        validDirs.push_back(dir);\n                    }\n                }\n                \n                if (!validDirs.empty()) {\n                    int dir = validDirs[rand() % validDirs.size()];\n                    char moveChar = makeMove(dir);\n                    currentMoves += moveChar;\n                }\n            }\n            \n            steps++;\n            \n            // Reset if we exceed move limit\n            if ((int)currentMoves.size() > T) {\n                board = initialBoard;\n                for (int i = 0; i < N*N; i++) {\n                    if (board[i] == 0) {\n                        emptyPos = i;\n                        break;\n                    }\n                }\n                currentMoves = \"\";\n            }\n        }\n        \n        return bestMoves;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, T;\n    if (!(cin >> N >> T)) return 0;\n    \n    vector<int> board(N*N);\n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            char c = line[j];\n            if (c == '0') {\n                board[i*N + j] = 0;\n            } else {\n                // Parse hexadecimal digit (1-9, a-f)\n                int val = (c >= 'a') ? (c - 'a' + 10) : (c - '0');\n                board[i*N + j] = val;\n            }\n        }\n    }\n    \n    // Solve the puzzle\n    SlidingTreePuzzle solver;\n    string moves = solver.solve(N, T, board);\n    \n    // Output the move sequence\n    cout << moves << '\\n';\n    \n    return 0;\n}","ahc012":"","ahc014":"struct Point { int x, y; };\nstruct Op { Point p[4]; }; // p[0] is new dot\n\nvector<vector<bool>> has_dot;          // Dot presence\nvector<vector<array<bool,4>>> edge;    // edge[x][y][dir] = used\nvector<vector<int>> weight;            // Precomputed weights\nvector<Op> operations;                 // Solution","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct UnionFind {\n    vector<int> parent, size;\n    UnionFind(int n = 0) { init(n); }\n    \n    void init(int n) {\n        parent.resize(n);\n        size.assign(n, 1);\n        iota(parent.begin(), parent.end(), 0);\n    }\n    \n    int find(int x) {\n        if (parent[x] == x) return x;\n        return parent[x] = find(parent[x]);\n    }\n    \n    void unite(int x, int y) {\n        x = find(x);\n        y = find(y);\n        if (x == y) return;\n        if (size[x] < size[y]) swap(x, y);\n        parent[y] = x;\n        size[x] += size[y];\n    }\n    \n    int getSize(int x) {\n        return size[find(x)];\n    }\n};\n\nclass CandyBox {\n    static const int H = 10;\n    static const int W = 10;\n    static const int N = H * W;\n    \n    array<array<int, W>, H> grid;\n    array<array<int, W>, H> tmpGrid;\n    \npublic:\n    CandyBox() {\n        for (int i = 0; i < H; i++)\n            grid[i].fill(0);\n    }\n    \n    // Place candy at p-th empty cell (1-indexed, row-major)\n    void placeCandy(int flavor, int p) {\n        int cnt = 0;\n        for (int i = 0; i < H; i++) {\n            for (int j = 0; j < W; j++) {\n                if (grid[i][j] == 0) {\n                    cnt++;\n                    if (cnt == p) {\n                        grid[i][j] = flavor;\n                        return;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Simulate tilting in direction d: 0=F, 1=B, 2=L, 3=R\n    void simulateTilt(int d, array<array<int, W>, H>& result) {\n        result = grid;\n        \n        if (d == 0) { // Forward (up)\n            for (int j = 0; j < W; j++) {\n                int writePos = 0;\n                for (int i = 0; i < H; i++) {\n                    if (result[i][j] != 0) {\n                        if (i != writePos) {\n                            result[writePos][j] = result[i][j];\n                            result[i][j] = 0;\n                        }\n                        writePos++;\n                    }\n                }\n            }\n        } else if (d == 1) { // Backward (down)\n            for (int j = 0; j < W; j++) {\n                int writePos = H - 1;\n                for (int i = H - 1; i >= 0; i--) {\n                    if (result[i][j] != 0) {\n                        if (i != writePos) {\n                            result[writePos][j] = result[i][j];\n                            result[i][j] = 0;\n                        }\n                        writePos--;\n                    }\n                }\n            }\n        } else if (d == 2) { // Left\n            for (int i = 0; i < H; i++) {\n                int writePos = 0;\n                for (int j = 0; j < W; j++) {\n                    if (result[i][j] != 0) {\n                        if (j != writePos) {\n                            result[i][writePos] = result[i][j];\n                            result[i][j] = 0;\n                        }\n                        writePos++;\n                    }\n                }\n            }\n        } else { // Right\n            for (int i = 0; i < H; i++) {\n                int writePos = W - 1;\n                for (int j = W - 1; j >= 0; j--) {\n                    if (result[i][j] != 0) {\n                        if (j != writePos) {\n                            result[i][writePos] = result[i][j];\n                            result[i][j] = 0;\n                        }\n                        writePos--;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Calculate score (sum of squares of component sizes) for a grid\n    long long calculateScore(const array<array<int, W>, H>& g) {\n        UnionFind uf(N);\n        int id[H][W];\n        int curId = 0;\n        \n        // Assign IDs to occupied cells\n        for (int i = 0; i < H; i++) {\n            for (int j = 0; j < W; j++) {\n                if (g[i][j] != 0) {\n                    id[i][j] = curId++;\n                } else {\n                    id[i][j] = -1;\n                }\n            }\n        }\n        \n        // Union adjacent same-flavor cells\n        const int dr[4] = {-1, 1, 0, 0};\n        const int dc[4] = {0, 0, -1, 1};\n        \n        for (int i = 0; i < H; i++) {\n            for (int j = 0; j < W; j++) {\n                if (id[i][j] == -1) continue;\n                for (int dir = 0; dir < 4; dir++) {\n                    int ni = i + dr[dir];\n                    int nj = j + dc[dir];\n                    if (ni >= 0 && ni < H && nj >= 0 && nj < W && id[ni][nj] != -1) {\n                        if (g[i][j] == g[ni][nj]) {\n                            uf.unite(id[i][j], id[ni][nj]);\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Calculate sum of squares of component sizes\n        long long score = 0;\n        vector<char> visited(curId, 0);\n        for (int i = 0; i < curId; i++) {\n            int root = uf.find(i);\n            if (!visited[root]) {\n                int size = uf.getSize(root);\n                score += 1LL * size * size;\n                visited[root] = 1;\n            }\n        }\n        return score;\n    }\n    \n    // Choose best direction based on simulation\n    char chooseDirection() {\n        long long bestScore = -1;\n        int bestDir = 0;\n        \n        for (int d = 0; d < 4; d++) {\n            simulateTilt(d, tmpGrid);\n            long long score = calculateScore(tmpGrid);\n            if (score > bestScore) {\n                bestScore = score;\n                bestDir = d;\n            }\n        }\n        \n        // Apply best tilt to actual grid\n        simulateTilt(bestDir, grid);\n        \n        const char dirChar[4] = {'F', 'B', 'L', 'R'};\n        return dirChar[bestDir];\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read flavors\n    vector<int> flavors(100);\n    for (int i = 0; i < 100; i++) {\n        if (!(cin >> flavors[i])) return 0;\n    }\n    \n    CandyBox box;\n    \n    for (int step = 0; step < 100; step++) {\n        int p;\n        cin >> p;\n        \n        box.placeCandy(flavors[step], p);\n        \n        char dir = box.chooseDirection();\n        cout << dir << endl;\n    }\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    const double epsilon = eps;\n    const bool noiseless = (epsilon < 1e-12);\n    int N;                     // number of vertices\n\n    // ----- choose N -------------------------------------------------\n    if (noiseless) {\n        // N = 5 is enough: 2^(10) = 1024 > 100\n        N = 5;\n    } else {\n        double I = log2(max(2, M));          // bits to transmit\n        double H = -epsilon * log2(epsilon) - (1.0 - epsilon) * log2(1.0 - epsilon);\n        double C = 1.0 - H;                  // capacity per edge\n        double need = (I + 3.0) / C;         // a few redundant bits\n        int needEdges = (int)ceil(need);\n        // solve N(N-1)/2 >= needEdges\n        double disc = 1.0 + 8.0 * needEdges;\n        double sq = sqrt(disc);\n        N = (int)ceil((1.0 + sq) / 2.0);\n        if (N < 4) N = 4;\n        if (N > 100) N = 100;\n    }\n\n    const int n = N;\n    const int tot = n * (n - 1) / 2;\n\n    // ----- generate all graphs --------------------------------------\n    // adjacency: G[i][u][v]  (0/1)\n    vector<vector<vector<char>>> G(M,\n        vector<vector<char>>(n, vector<char>(n, 0)));\n\n    // sorted degree sequences, will be used for decoding\n    vector<vector<int>> sortedDeg(M, vector<int>(n));\n\n    for (int i = 0; i < M; ++i) {\n        // deterministic seed depending on i, M, n\n        mt19937 rng(i * 10007 + M * 12345 + n * 6789 + 42);\n        uniform_int_distribution<int> dist(0, 1);\n\n        for (int u = 0; u < n; ++u)\n            for (int v = u + 1; v < n; ++v) {\n                char e = (char)dist(rng);   // 0 or 1\n                G[i][u][v] = G[i][v][u] = e;\n            }\n\n        // degree of each vertex\n        vector<int> deg(n, 0);\n        for (int u = 0; u < n; ++u) {\n            int s = 0;\n            for (int v = 0; v < n; ++v) if (u != v) s += G[i][u][v];\n            deg[u] = s;\n        }\n        // sorted in decreasing order\n        vector<int> sd = deg;\n        sort(sd.begin(), sd.end(), greater<int>());\n        sortedDeg[i] = sd;\n    }\n\n    // ----- output the graphs ----------------------------------------\n    cout << n << '\\n';\n    for (int i = 0; i < M; ++i) {\n        string line;\n        line.reserve(tot);\n        for (int u = 0; u < n; ++u)\n            for (int v = u + 1; v < n; ++v)\n                line.push_back(G[i][u][v] ? '1' : '0');\n        cout << line << '\\n';\n    }\n    cout.flush();\n\n    // ----- pre\u2011compute all permutations (only needed for noiseless) ---\n    vector<vector<int>> perms;\n    if (noiseless) {\n        vector<int> p(n);\n        iota(p.begin(), p.end(), 0);\n        do {\n            perms.push_back(p);\n        } while (next_permutation(p.begin(), p.end()));\n    }\n\n    // ----- process the 100 queries ----------------------------------\n    for (int q = 0; q < 100; ++q) {\n        string Hstr;\n        cin >> Hstr;\n\n        // adjacency of H (needed only for noiseless case)\n        vector<vector<char>> B(n, vector<char>(n, 0));\n        vector<int> degH(n, 0);\n        int pos = 0;\n        for (int u = 0; u < n; ++u) {\n            for (int v = u + 1; v < n; ++v) {\n                char c = (char)(Hstr[pos++] - '0');\n                B[u][v] = B[v][u] = c;\n                if (c) {\n                    ++degH[u];\n                    ++degH[v];\n                }\n            }\n        }\n\n        int answer = 0;\n\n        if (noiseless) {\n            // exact isomorphism test, N \u2264 5  \u2192 at most 120 permutations\n            bool found = false;\n            for (int i = 0; i < M && !found; ++i) {\n                for (const auto &perm : perms) {\n                    bool ok = true;\n                    for (int u = 0; u < n && ok; ++u) {\n                        int pu = perm[u];\n                        for (int v = u + 1; v < n; ++v) {\n                            int pv = perm[v];\n                            if (G[i][u][v] != B[pu][pv]) {\n                                ok = false;\n                                break;\n                            }\n                        }\n                    }\n                    if (ok) {\n                        answer = i;\n                        found = true;\n                        break;\n                    }\n                }\n            }\n        } else {\n            // compare sorted degree sequences\n            vector<int> sdH = degH;\n            sort(sdH.begin(), sdH.end(), greater<int>());\n\n            int bestDist = INT_MAX;\n            for (int i = 0; i < M; ++i) {\n                int d = 0;\n                for (int k = 0; k < n; ++k) {\n                    d += abs(sortedDeg[i][k] - sdH[k]);\n                    if (d >= bestDist) break; // early cut\n                }\n                if (d < bestDist) {\n                    bestDist = d;\n                    answer = i;\n                }\n            }\n        }\n\n        cout << answer << '\\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    long long w;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n\n    vector<Edge> edges(M);\n    vector<vector<pair<int,int>>> adj(N);          // (to , edge id)\n    for (int i = 0; i < M; ++i) {\n        int a, b;\n        long long w;\n        cin >> a >> b >> w;\n        --a; --b;\n        edges[i] = {a, b, w};\n        adj[a].push_back({b, i});\n        adj[b].push_back({a, i});\n    }\n    // read the coordinates, they are not needed\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        (void)x; (void)y;\n    }\n\n    const long long INF = (1LL << 60);\n\n    /* ----------------------------------------------------------\n       1.  Edge betweenness centrality (Brandes, weighted)\n       ---------------------------------------------------------- */\n    vector<double> ebc(M, 0.0);\n    vector<long long> dist(N);\n    vector<double> sigma(N), delta(N);\n    vector<vector<pair<int,int>>> pred(N);\n    vector<int> order(N);\n\n    for (int s = 0; s < N; ++s) {\n        fill(dist.begin(), dist.end(), INF);\n        fill(sigma.begin(), sigma.end(), 0.0);\n        for (int i = 0; i < N; ++i) pred[i].clear();\n\n        priority_queue<pair<long long,int>, vector<pair<long long,int>>, greater<pair<long long,int>>> pq;\n        dist[s] = 0;\n        sigma[s] = 1.0;\n        pq.emplace(0, s);\n\n        while (!pq.empty()) {\n            auto [d, v] = pq.top(); pq.pop();\n            if (d != dist[v]) continue;\n            for (auto [to, eid] : adj[v]) {\n                long long nd = d + edges[eid].w;\n                if (dist[to] > nd) {\n                    dist[to] = nd;\n                    sigma[to] = sigma[v];\n                    pred[to].clear();\n                    pred[to].emplace_back(v, eid);\n                    pq.emplace(nd, to);\n                } else if (dist[to] == nd) {\n                    sigma[to] += sigma[v];\n                    pred[to].emplace_back(v, eid);\n                }\n            }\n        }\n\n        // vertices in decreasing order of distance\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(),\n             [&](int a, int b){ return dist[a] > dist[b]; });\n\n        fill(delta.begin(), delta.end(), 0.0);\n\n        for (int v : order) {\n            if (dist[v] == INF) continue;\n            for (auto [u, eid] : pred[v]) {\n                double coeff = sigma[u] / sigma[v];\n                double contrib = coeff * (1.0 + delta[v]);\n                ebc[eid] += contrib;\n                delta[u] += contrib;\n            }\n        }\n    }\n\n    for (int i = 0; i < M; ++i) ebc[i] *= 0.5;          // undirected\n\n    /* ----------------------------------------------------------\n       2.  Score of an edge (here only betweenness)\n       ---------------------------------------------------------- */\n    vector<double> score(M);\n    for (int i = 0; i < M; ++i) score[i] = ebc[i];      // * edges[i].w possible\n\n    /* ----------------------------------------------------------\n       3.  Greedy LPT assignment, several random restarts\n       ---------------------------------------------------------- */\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    vector<int> best_assign(M);\n    double best_obj = 1e100;\n    vector<int> order_edges(M);\n    iota(order_edges.begin(), order_edges.end(), 0);\n\n    int restarts = 5;                     // enough, can be increased if time permits\n    for (int rep = 0; rep < restarts; ++rep) {\n        shuffle(order_edges.begin(), order_edges.end(), rng);\n        vector<int> assign(M, -1);\n        vector<double> day_sum(D, 0.0);\n        vector<int> day_cnt(D, 0);\n\n        for (int eid : order_edges) {\n            // choose a day with free capacity and minimal current sum\n            int best_day = -1;\n            double best_val = 1e200;\n            for (int d = 0; d < D; ++d) {\n                if (day_cnt[d] >= K) continue;\n                if (day_sum[d] < best_val) {\n                    best_val = day_sum[d];\n                    best_day = d;\n                }\n            }\n            // it is guaranteed that such a day exists\n            assign[eid] = best_day;\n            day_sum[best_day] += score[eid];\n            day_cnt[best_day]++;\n        }\n\n        double obj = 0.0;\n        for (int d = 0; d < D; ++d) obj += day_sum[d] * day_sum[d];\n        if (obj < best_obj) {\n            best_obj = obj;\n            best_assign = assign;\n        }\n    }\n\n    /* ----------------------------------------------------------\n       4.  Simple hill climbing (improves the surrogate)\n       ---------------------------------------------------------- */\n    vector<int> assign = best_assign;\n    vector<double> day_sum(D, 0.0);\n    vector<int> day_cnt(D, 0);\n    for (int e = 0; e < M; ++e) {\n        int d = assign[e];\n        day_sum[d] += score[e];\n        day_cnt[d]++;\n    }\n\n    uniform_int_distribution<int> edge_dist(0, M - 1);\n    uniform_int_distribution<int> day_dist(0, D - 1);\n    const int HILL_ITER = 20000;          // works well, can be tuned\n    for (int it = 0; it < HILL_ITER; ++it) {\n        int e = edge_dist(rng);\n        int cur = assign[e];\n        if (day_cnt[cur] == 0) continue; // should never happen\n\n        // look for a different day with free capacity\n        int nd = day_dist(rng);\n        if (nd == cur || day_cnt[nd] >= K) continue;\n\n        double cur_sum = day_sum[cur];\n        double new_sum = day_sum[nd];\n        double old_contrib = cur_sum * cur_sum + new_sum * new_sum;\n        double new_contrib = (cur_sum - score[e]) * (cur_sum - score[e]) +\n                             (new_sum + score[e]) * (new_sum + score[e]);\n        if (new_contrib < old_contrib - 1e-12) {\n            // accept move\n            assign[e] = nd;\n            day_sum[cur] -= score[e];\n            day_sum[nd] += score[e];\n            day_cnt[cur]--;\n            day_cnt[nd]++;\n        }\n    }\n\n    /* ----------------------------------------------------------\n       5.  Output\n       ---------------------------------------------------------- */\n    for (int i = 0; i < M; ++i) {\n        if (i) cout << ' ';\n        cout << assign[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    \n    int D;\n    if (!(cin >> D)) return 0;\n    const int MAXD = 14;\n    vector<string> f[2], r[2];\n    f[0].resize(D); f[1].resize(D);\n    r[0].resize(D); r[1].resize(D);\n    for (int i = 0; i < 2; ++i)\n        for (int z = 0; z < D; ++z) cin >> f[i][z];\n    for (int i = 0; i < 2; ++i)\n        for (int z = 0; z < D; ++z) cin >> r[i][z];\n\n    // data for both objects\n    vector<vector<int>> X[2], Y[2];\n    vector<vector<pair<int,int>>> intX[2], intY[2];\n    for (int i = 0; i < 2; ++i) {\n        X[i].assign(D, {});\n        Y[i].assign(D, {});\n        intX[i].assign(D, {});\n        intY[i].assign(D, {});\n        for (int z = 0; z < D; ++z) {\n            // collect X and Y\n            for (int x = 0; x < D; ++x)\n                if (f[i][z][x] == '1') X[i][z].push_back(x);\n            for (int y = 0; y < D; ++y)\n                if (r[i][z][y] == '1') Y[i][z].push_back(y);\n            // intervals of 1s in f\n            const string &sf = f[i][z];\n            for (int x = 0; x < D; ) {\n                if (sf[x] == '0') { ++x; continue; }\n                int s = x;\n                while (x < D && sf[x] == '1') ++x;\n                int e = x - 1;\n                intX[i][z].push_back({s, e});\n            }\n            // intervals of 1s in r\n            const string &sr = r[i][z];\n            for (int y = 0; y < D; ) {\n                if (sr[y] == '0') { ++y; continue; }\n                int s = y;\n                while (y < D && sr[y] == '1') ++y;\n                int e = y - 1;\n                intY[i][z].push_back({s, e});\n            }\n        }\n    }\n\n    // count bars for each orientation\n    vector<int> cntV[2], cntH[2];\n    cntV[0].assign(D+1, 0); cntV[1].assign(D+1, 0);\n    cntH[0].assign(D+1, 0); cntH[1].assign(D+1, 0);\n    for (int i = 0; i < 2; ++i) {\n        for (int z = 0; z < D; ++z) {\n            // vertical bars (use Y intervals)\n            for (auto &pr : intY[i][z]) {\n                int len = pr.second - pr.first + 1;\n                cntV[i][len] += (int)X[i][z].size();\n            }\n            // horizontal bars (use X intervals)\n            for (auto &pr : intX[i][z]) {\n                int len = pr.second - pr.first + 1;\n                cntH[i][len] += (int)Y[i][z].size();\n            }\n        }\n    }\n\n    // choose best orientation\n    double bestScore = 1e100;\n    int bestO1 = -1, bestO2 = -1;\n    for (int o1 = 0; o1 < 2; ++o1) {\n        for (int o2 = 0; o2 < 2; ++o2) {\n            const vector<int> &a = (o1 ? cntH[0] : cntV[0]);\n            const vector<int> &b = (o2 ? cntH[1] : cntV[1]);\n            double score = 0.0;\n            for (int L = 1; L <= D; ++L) {\n                int s = min(a[L], b[L]);\n                int diff = abs(a[L] - b[L]);\n                score += diff * L + (double)s / L;\n            }\n            if (score < bestScore) {\n                bestScore = score;\n                bestO1 = o1;\n                bestO2 = o2;\n            }\n        }\n    }\n\n    // final counts according to the chosen orientation\n    vector<int> aCnt = (bestO1 ? cntH[0] : cntV[0]);\n    vector<int> bCnt = (bestO2 ? cntH[1] : cntV[1]);\n\n    // create block IDs\n    vector<vector<int>> sharedId(D+1), only1Id(D+1), only2Id(D+1);\n    int totalBlocks = 0;\n    for (int L = 1; L <= D; ++L) {\n        int s = min(aCnt[L], bCnt[L]);\n        for (int k = 0; k < s; ++k) sharedId[L].push_back(++totalBlocks);\n        for (int k = 0; k < aCnt[L] - s; ++k) only1Id[L].push_back(++totalBlocks);\n        for (int k = 0; k < bCnt[L] - s; ++k) only2Id[L].push_back(++totalBlocks);\n    }\n\n    // 3D output arrays (flat)\n    vector<int> b1(D*D*D, 0), b2(D*D*D, 0);\n    auto index = [&](int x, int y, int z) { return x*D*D + y*D + z; };\n\n    // ----- place object 1 -----\n    vector<int> ptrS(D+1, 0), ptr1(D+1, 0);\n    if (bestO1 == 0) { // vertical\n        for (int z = 0; z < D; ++z) {\n            for (auto &pr : intY[0][z]) {\n                int len = pr.second - pr.first + 1;\n                int y1 = pr.first, y2 = pr.second;\n                for (int x : X[0][z]) {\n                    int id;\n                    if (ptrS[len] < (int)sharedId[len].size())\n                        id = sharedId[len][ptrS[len]++];\n                    else\n                        id = only1Id[len][ptr1[len]++];\n                    for (int y = y1; y <= y2; ++y)\n                        b1[index(x, y, z)] = id;\n                }\n            }\n        }\n    } else { // horizontal\n        for (int z = 0; z < D; ++z) {\n            for (auto &pr : intX[0][z]) {\n                int len = pr.second - pr.first + 1;\n                int x1 = pr.first, x2 = pr.second;\n                for (int y : Y[0][z]) {\n                    int id;\n                    if (ptrS[len] < (int)sharedId[len].size())\n                        id = sharedId[len][ptrS[len]++];\n                    else\n                        id = only1Id[len][ptr1[len]++];\n                    for (int x = x1; x <= x2; ++x)\n                        b1[index(x, y, z)] = id;\n                }\n            }\n        }\n    }\n\n    // ----- place object 2 -----\n    vector<int> ptrS2(D+1, 0), ptr2(D+1, 0);\n    if (bestO2 == 0) { // vertical\n        for (int z = 0; z < D; ++z) {\n            for (auto &pr : intY[1][z]) {\n                int len = pr.second - pr.first + 1;\n                int y1 = pr.first, y2 = pr.second;\n                for (int x : X[1][z]) {\n                    int id;\n                    if (ptrS2[len] < (int)sharedId[len].size())\n                        id = sharedId[len][ptrS2[len]++];\n                    else\n                        id = only2Id[len][ptr2[len]++];\n                    for (int y = y1; y <= y2; ++y)\n                        b2[index(x, y, z)] = id;\n                }\n            }\n        }\n    } else { // horizontal\n        for (int z = 0; z < D; ++z) {\n            for (auto &pr : intX[1][z]) {\n                int len = pr.second - pr.first + 1;\n                int x1 = pr.first, x2 = pr.second;\n                for (int y : Y[1][z]) {\n                    int id;\n                    if (ptrS2[len] < (int)sharedId[len].size())\n                        id = sharedId[len][ptrS2[len]++];\n                    else\n                        id = only2Id[len][ptr2[len]++];\n                    for (int x = x1; x <= x2; ++x)\n                        b2[index(x, y, z)] = id;\n                }\n            }\n        }\n    }\n\n    // ----- output -----\n    cout << totalBlocks << '\\n';\n    for (int i = 0; i < D*D*D; ++i) {\n        if (i) cout << ' ';\n        cout << b1[i];\n    }\n    cout << '\\n';\n    for (int i = 0; i < D*D*D; ++i) {\n        if (i) cout << ' ';\n        cout << b2[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v;\n    long long w;\n    double dist;\n};\n\nstruct Station {\n    long long x, y;\n};\n\nstruct Resident {\n    long long a, b;\n};\n\nstruct DSU {\n    vector<int> p, r;\n    DSU(int n) : p(n), r(n, 0) { iota(p.begin(), p.end(), 0); }\n    int find(int x) { return p[x] == x ? x : p[x] = find(p[x]); }\n    bool unite(int a, int b) {\n        a = find(a);\n        b = find(b);\n        if (a == b) return false;\n        if (r[a] < r[b]) swap(a, b);\n        p[b] = a;\n        if (r[a] == r[b]) r[a]++;\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n    \n    vector<Station> stations(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> stations[i].x >> stations[i].y;\n    }\n    \n    vector<Edge> edges(M);\n    vector<vector<pair<int, int>>> adj(N);\n    for (int j = 0; j < M; ++j) {\n        cin >> edges[j].u >> edges[j].v >> edges[j].w;\n        edges[j].u--;\n        edges[j].v--;\n        long long dx = stations[edges[j].u].x - stations[edges[j].v].x;\n        long long dy = stations[edges[j].u].y - stations[edges[j].v].y;\n        edges[j].dist = sqrt((double)dx * dx + (double)dy * dy);\n        adj[edges[j].u].push_back({edges[j].v, j});\n        adj[edges[j].v].push_back({edges[j].u, j});\n    }\n    \n    vector<Resident> residents(K);\n    for (int k = 0; k < K; ++k) {\n        cin >> residents[k].a >> residents[k].b;\n    }\n    \n    // Precompute distances from each resident to each station\n    // resident_stations[k] is sorted by distance\n    vector<vector<pair<double, int>>> resident_stations(K);\n    for (int k = 0; k < K; ++k) {\n        resident_stations[k].reserve(N);\n        for (int i = 0; i < N; ++i) {\n            long long dx = residents[k].a - stations[i].x;\n            long long dy = residents[k].b - stations[i].y;\n            double dist = sqrt((double)dx * dx + (double)dy * dy);\n            resident_stations[k].push_back({dist, i});\n        }\n        sort(resident_stations[k].begin(), resident_stations[k].end(),\n            [](const pair<double, int>& a, const pair<double, int>& b) {\n                return a.first < b.first;\n            });\n    }\n    \n    // Generate candidate spanning trees\n    vector<vector<int>> candidate_trees;\n    \n    // Candidate 1: Standard MST using edge weight w\n    {\n        DSU dsu(N);\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int i, int j) {\n            return edges[i].w < edges[j].w;\n        });\n        \n        vector<int> tree_edges;\n        for (int idx : order) {\n            if (dsu.unite(edges[idx].u, edges[idx].v)) {\n                tree_edges.push_back(idx);\n                if ((int)tree_edges.size() == N - 1) break;\n            }\n        }\n        if ((int)tree_edges.size() == N - 1) {\n            candidate_trees.push_back(tree_edges);\n        }\n    }\n    \n    // Candidate 2: MST using weight = w / (dist + 1)\n    {\n        DSU dsu(N);\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int i, int j) {\n            double wi = (double)edges[i].w / (edges[i].dist + 1.0);\n            double wj = (double)edges[j].w / (edges[j].dist + 1.0);\n            return wi < wj;\n        });\n        \n        vector<int> tree_edges;\n        for (int idx : order) {\n            if (dsu.unite(edges[idx].u, edges[idx].v)) {\n                tree_edges.push_back(idx);\n                if ((int)tree_edges.size() == N - 1) break;\n            }\n        }\n        if ((int)tree_edges.size() == N - 1) {\n            candidate_trees.push_back(tree_edges);\n        }\n    }\n    \n    // Candidate 3: MST using weight = w * dist\n    {\n        DSU dsu(N);\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int i, int j) {\n            double wi = (double)edges[i].w * edges[i].dist;\n            double wj = (double)edges[j].w * edges[j].dist;\n            return wi < wj;\n        });\n        \n        vector<int> tree_edges;\n        for (int idx : order) {\n            if (dsu.unite(edges[idx].u, edges[idx].v)) {\n                tree_edges.push_back(idx);\n                if ((int)tree_edges.size() == N - 1) break;\n            }\n        }\n        if ((int)tree_edges.size() == N - 1) {\n            candidate_trees.push_back(tree_edges);\n        }\n    }\n    \n    // Candidate 4: Shortest path tree from station 1\n    {\n        vector<int> tree_edges;\n        vector<long long> dist(N, LLONG_MAX);\n        vector<int> prev_edge(N, -1);\n        dist[0] = 0;\n        using Node = pair<long long, int>;\n        priority_queue<Node, vector<Node>, greater<Node>> pq;\n        pq.push({0, 0});\n        vector<bool> visited(N, false);\n        \n        while (!pq.empty()) {\n            auto [d, u] = pq.top();\n            pq.pop();\n            if (visited[u]) continue;\n            visited[u] = true;\n            \n            if (prev_edge[u] != -1) {\n                tree_edges.push_back(prev_edge[u]);\n            }\n            \n            for (auto [v, eid] : adj[u]) {\n                if (!visited[v] && d + edges[eid].w < dist[v]) {\n                    dist[v] = d + edges[eid].w;\n                    prev_edge[v] = eid;\n                    pq.push({dist[v], v});\n                }\n            }\n        }\n        \n        if ((int)tree_edges.size() == N - 1) {\n            candidate_trees.push_back(tree_edges);\n        }\n    }\n    \n    // Fallback: BFS tree if no spanning tree was generated\n    if (candidate_trees.empty()) {\n        vector<int> tree_edges;\n        vector<bool> visited(N, false);\n        queue<int> q;\n        q.push(0);\n        visited[0] = true;\n        \n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            for (auto [v, eid] : adj[u]) {\n                if (!visited[v]) {\n                    visited[v] = true;\n                    tree_edges.push_back(eid);\n                    q.push(v);\n                    if ((int)tree_edges.size() == N - 1) break;\n                }\n            }\n            if ((int)tree_edges.size() == N - 1) break;\n        }\n        candidate_trees.push_back(tree_edges);\n    }\n    \n    // Evaluate each candidate tree and keep the best solution\n    long long best_cost = LLONG_MAX;\n    vector<int> best_P(N, 0);\n    vector<int> best_B(M, 0);\n    \n    for (const auto& tree_edge_indices : candidate_trees) {\n        // Determine which stations are in the tree (should be all N for spanning trees)\n        vector<bool> in_tree(N, false);\n        in_tree[0] = true; // Station 1 is always active\n        for (int idx : tree_edge_indices) {\n            in_tree[edges[idx].u] = true;\n            in_tree[edges[idx].v] = true;\n        }\n        \n        // Assign residents to nearest active station\n        vector<int> resident_station(K, -1);\n        vector<double> station_max_radius(N, 0.0);\n        \n        for (int k = 0; k < K; ++k) {\n            for (auto [dist, station_id] : resident_stations[k]) {\n                if (in_tree[station_id]) {\n                    resident_station[k] = station_id;\n                    station_max_radius[station_id] = max(station_max_radius[station_id], dist);\n                    break;\n                }\n            }\n        }\n        \n        // Compute output power for each station (capped at 5000)\n        vector<int> P(N, 0);\n        for (int i = 0; i < N; ++i) {\n            if (station_max_radius[i] > 0) {\n                int radius = (int)ceil(station_max_radius[i]);\n                P[i] = min(5000, radius);\n            }\n        }\n        \n        // Build edge selection vector\n        vector<int> B(M, 0);\n        for (int idx : tree_edge_indices) {\n            B[idx] = 1;\n        }\n        \n        // Calculate total cost\n        long long edge_cost = 0;\n        for (int j = 0; j < M; ++j) {\n            if (B[j] == 1) edge_cost += edges[j].w;\n        }\n        long long vertex_cost = 0;\n        for (int i = 0; i < N; ++i) {\n            vertex_cost += (long long)P[i] * P[i];\n        }\n        long long total_cost = edge_cost + vertex_cost;\n        \n        // Verify all residents can be covered\n        bool all_covered = true;\n        for (int k = 0; k < K; ++k) {\n            if (resident_station[k] == -1) {\n                all_covered = false;\n                break;\n            }\n        }\n        \n        // Update best solution if this one is better\n        if (all_covered && total_cost < best_cost) {\n            best_cost = total_cost;\n            best_P = P;\n            best_B = B;\n        }\n    }\n    \n    // Output the best solution\n    for (int i = 0; i < N; ++i) {\n        if (i > 0) cout << \" \";\n        cout << best_P[i];\n    }\n    cout << \"\\n\";\n    for (int j = 0; j < M; ++j) {\n        if (j > 0) cout << \" \";\n        cout << best_B[j];\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 30;                     // number of rows\nusing Grid = array<array<int, N>, N>;     // only the lower\u2011triangular part is used\n\nstruct Swap {\n    int x1, y1, x2, y2;\n};\n\n/* -------------------------------------------------------------\n   perform the sift\u2011down algorithm on a given grid;\n   the inner order of a row is given by the vector `order`.\n   ------------------------------------------------------------- */\nvoid siftDown(Grid &g, vector<Swap> &out,\n              int row, const vector<int> &order) {\n    for (int y : order) {\n        int curX = row, curY = y;\n        while (curX < N - 1) {                     // while cur has children\n            int leftX  = curX + 1;\n            int leftY  = curY;\n            int rightX = curX + 1;\n            int rightY = curY + 1;\n\n            // the smaller child\n            int childX, childY;\n            if (g[leftX][leftY] < g[rightX][rightY]) {\n                childX = leftX; childY = leftY;\n            } else {\n                childX = rightX; childY = rightY;\n            }\n\n            if (g[childX][childY] < g[curX][curY]) {\n                // swap and continue downwards\n                swap(g[curX][curY], g[childX][childY]);\n                out.push_back({curX, curY, childX, childY});\n                curX = childX;\n                curY = childY;\n            } else {\n                break; // already smaller than both children\n            }\n        }\n    }\n}\n\n/* -------------------------------------------------------------\n   count how many parent\u2011child pairs violate the required order\n   ------------------------------------------------------------- */\nint countViolations(const Grid &g) {\n    int bad = 0;\n    for (int x = 0; x < N - 1; ++x) {\n        for (int y = 0; y <= x; ++y) {\n            int v = g[x][y];\n            if (v > g[x + 1][y])   ++bad;\n            if (v > g[x + 1][y + 1]) ++bad;\n        }\n    }\n    return bad;\n}\n\n/* -------------------------------------------------------------\n   one deterministic run (left\u2011to\u2011right)\n   ------------------------------------------------------------- */\nvoid runBaseline(const Grid &init, Grid &cur, vector<Swap> &out) {\n    cur = init;\n    out.clear();\n    for (int x = N - 2; x >= 0; --x) {\n        vector<int> order(x + 1);\n        iota(order.begin(), order.end(), 0);               // 0..x\n        siftDown(cur, out, x, order);\n    }\n}\n\n/* -------------------------------------------------------------\n   deterministic run \u2013 nodes with larger violation first\n   ------------------------------------------------------------- */\nvoid runSorted(const Grid &init, Grid &cur, vector<Swap> &out) {\n    cur = init;\n    out.clear();\n    for (int x = N - 2; x >= 0; --x) {\n        // compute the violation size for each node in this row\n        vector<pair<int,int>> diffY; // (diff , y)\n        diffY.reserve(x + 1);\n        for (int y = 0; y <= x; ++y) {\n            int left  = cur[x + 1][y];\n            int right = cur[x + 1][y + 1];\n            int mn = min(left, right);\n            int diff = cur[x][y] - mn;               // >0  \u2192 violation\n            diffY.emplace_back(diff, y);\n        }\n        sort(diffY.begin(), diffY.end(),\n             [](const auto &a, const auto &b){ return a.first > b.first; });\n        vector<int> order;\n        order.reserve(x + 1);\n        for (auto &p : diffY) order.push_back(p.second);\n        siftDown(cur, out, x, order);\n    }\n}\n\n/* -------------------------------------------------------------\n   one random run \u2013 each row is processed in a random order\n   ------------------------------------------------------------- */\nvoid runRandom(const Grid &init, Grid &cur, vector<Swap> &out,\n               mt19937 &rng) {\n    cur = init;\n    out.clear();\n    for (int x = N - 2; x >= 0; --x) {\n        vector<int> order(x + 1);\n        iota(order.begin(), order.end(), 0);\n        shuffle(order.begin(), order.end(), rng);\n        siftDown(cur, out, x, order);\n    }\n}\n\n/* ------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    Grid orig{};\n    for (int x = 0; x < N; ++x)\n        for (int y = 0; y <= x; ++y)\n            cin >> orig[x][y];\n\n    vector<Swap> bestSwaps;\n    int bestK = 1000000;               // larger than any possible length\n\n    Grid cur;\n    vector<Swap> curSwaps;\n\n    // ---- baseline deterministic run ----\n    runBaseline(orig, cur, curSwaps);\n    if (countViolations(cur) == 0 && (int)curSwaps.size() < bestK) {\n        bestK = (int)curSwaps.size();\n        bestSwaps = curSwaps;\n    }\n\n    // ---- deterministic \u201clargest violation first\u201d ----\n    runSorted(orig, cur, curSwaps);\n    if (countViolations(cur) == 0 && (int)curSwaps.size() < bestK) {\n        bestK = (int)curSwaps.size();\n        bestSwaps = curSwaps;\n    }\n\n    // ---- many random runs -------------------------------------------------\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    for (int iter = 0; iter < 200; ++iter) {\n        runRandom(orig, cur, curSwaps, rng);\n        if (countViolations(cur) == 0 && (int)curSwaps.size() < bestK) {\n            bestK = (int)curSwaps.size();\n            bestSwaps = curSwaps;\n            if (bestK <= 2000) break;          // good enough, stop early\n        }\n    }\n\n    // ---- output the best sequence found ----------------------------------\n    cout << bestK << '\\n';\n    for (const auto &s : bestSwaps)\n        cout << s.x1 << ' ' << s.y1 << ' ' << s.x2 << ' ' << s.y2 << '\\n';\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int SZ = 9;                     // board size, fixed by the statement\n\n/* global data */\nint M;                                 // number of containers\nvector<vector<bool>> obstacle;         // true for an obstacle\nvector<vector<bool>> occupied;         // true if a container is stored here\nvector<vector<int>> value;             // transport number, -1 if none\n\n/* auxiliary directions */\nconst int dr[4] = {1, -1, 0, 0};\nconst int dc[4] = {0, 0, 1, -1};\n\n/* --------------------------------------------------------------- */\n/* BFS from the entrance over empty squares.\n   fills reachable[][] , dist[][] and returns the number of reachable empty squares\n   (entrance is counted as empty).                                 */\nint bfs_reachable(vector<vector<bool>>& reachable,\n                  vector<vector<int>>& dist,\n                  const vector<vector<bool>>& occ)\n{\n    reachable.assign(SZ, vector<bool>(SZ, false));\n    dist.assign(SZ, vector<int>(SZ, -1));\n    queue<pair<int,int>> q;\n\n    int ent_r = 0, ent_c = (SZ-1)/2;\n    reachable[ent_r][ent_c] = true;\n    dist[ent_r][ent_c] = 0;\n    q.emplace(ent_r, ent_c);\n    int cnt = 1;                     // entrance itself\n\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];\n            int nc = c + dc[d];\n            if (nr<0||nr>=SZ||nc<0||nc>=SZ) continue;\n            if (obstacle[nr][nc]) continue;\n            if (occ[nr][nc]) continue;                 // not empty\n            if (!reachable[nr][nc]){\n                reachable[nr][nc] = true;\n                dist[nr][nc] = dist[r][c] + 1;\n                ++cnt;\n                q.emplace(nr,nc);\n            }\n        }\n    }\n    return cnt;          // total empty squares reachable (including entrance)\n}\n\n/* --------------------------------------------------------------- */\n/* test whether a reachable empty square (tr,tc) is a cut vertex\n   (i.e. after occupying it the remaining empty squares stay connected) */\nbool is_safe(int tr, int tc,\n             const vector<vector<bool>>& occ,\n             int total_empty)\n{\n    // a second BFS, this time treating (tr,tc) as blocked\n    vector<vector<bool>> reach2(SZ, vector<bool>(SZ,false));\n    queue<pair<int,int>> q;\n    int ent_r = 0, ent_c = (SZ-1)/2;\n    reach2[ent_r][ent_c] = true;\n    q.emplace(ent_r, ent_c);\n    int cnt = 1;\n\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];\n            int nc = c + dc[d];\n            if (nr<0||nr>=SZ||nc<0||nc>=SZ) continue;\n            if (obstacle[nr][nc]) continue;\n            if (occ[nr][nc]) continue;\n            if (nr==tr && nc==tc) continue;          // the blocked cell\n            if (!reach2[nr][nc]){\n                reach2[nr][nc] = true;\n                ++cnt;\n                q.emplace(nr,nc);\n            }\n        }\n    }\n    // after blocking (tr,tc) we must still reach all other empties\n    return cnt == total_empty - 1;\n}\n\n/* --------------------------------------------------------------- */\n/* pick a square for the next container */\npair<int,int> choose_square(const vector<vector<bool>>& occ)\n{\n    vector<vector<bool>> reachable;\n    vector<vector<int>> dist;\n    int total_empty = bfs_reachable(reachable, dist, occ);\n\n    vector<pair<int,int>> safe_list;\n    int best_dist = -1;\n    pair<int,int> best{-1,-1};\n\n    for (int r=0; r<SZ; ++r){\n        for (int c=0; c<SZ; ++c){\n            if (!reachable[r][c]) continue;               // not reachable\n            if (occ[r][c]) continue;                       // already occupied\n            if (r==0 && c==(SZ-1)/2) continue;              // entrance\n            // articulation test\n            if (!is_safe(r,c, occ, total_empty)) continue;\n            safe_list.emplace_back(r,c);\n            if (dist[r][c] > best_dist){\n                best_dist = dist[r][c];\n                best = {r,c};\n            }\n            else if (dist[r][c]==best_dist && best.first!=-1){\n                // tie\u2011break by smaller row, then column\n                if (r < best.first || (r==best.first && c < best.second))\n                    best = {r,c};\n            }\n        }\n    }\n\n    // normally safe_list is non\u2011empty \u2013 otherwise we would be stuck.\n    if (!safe_list.empty()) return best;\n\n    // fallback: any reachable cell (should never happen)\n    for (int r=0; r<SZ; ++r)\n        for (int c=0; c<SZ; ++c)\n            if (reachable[r][c] && !occ[r][c] && !(r==0 && c==(SZ-1)/2))\n                return {r,c};\n    return {-1,-1}; // never reached\n}\n\n/* --------------------------------------------------------------- */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D_input, N;\n    if(!(cin>>D_input>>N)) return 0;       // D_input is always 9, we ignore it\n    obstacle.assign(SZ, vector<bool>(SZ,false));\n    for (int i=0;i<N;++i){\n        int ri,rj; cin>>ri>>rj;\n        obstacle[ri][rj]=true;\n    }\n\n    occupied.assign(SZ, vector<bool>(SZ,false));\n    value.assign(SZ, vector<int>(SZ,-1));\n\n    M = SZ*SZ - 1 - N;\n\n    vector<pair<int,int>> container_position(M);   // by transport number\n\n    /* ---------- placement ---------- */\n    for (int step=0; step<M; ++step){\n        int t; cin>>t;\n        auto pos = choose_square(occupied);\n        int r = pos.first, c = pos.second;\n        // place the container\n        occupied[r][c] = true;\n        value[r][c] = t;\n        container_position[t] = {r,c};\n        cout << r << ' ' << c << '\\n';\n        cout.flush();\n    }\n\n    /* ---------- removal ---------- */\n    vector<pair<int,int>> removal_order;\n    removal_order.reserve(M);\n    int removed = 0;\n    while (removed < M){\n        vector<vector<bool>> reachableEmpty;\n        vector<vector<int>> dummy;\n        bfs_reachable(reachableEmpty, dummy, occupied);   // empty squares only\n\n        // collect removable containers\n        int best_val = INT_MAX;\n        int br=-1, bc=-1;\n        for (int r=0; r<SZ; ++r){\n            for (int c=0; c<SZ; ++c){\n                if (!occupied[r][c]) continue;               // no container here\n                // is it reachable ?   (any neighbour reachableEmpty)\n                bool ok = false;\n                for (int d=0; d<4; ++d){\n                    int nr = r+dr[d];\n                    int nc = c+dc[d];\n                    if (nr<0||nr>=SZ||nc<0||nc>=SZ) continue;\n                    if (reachableEmpty[nr][nc]) { ok=true; break; }\n                }\n                if (!ok) continue;\n                if (value[r][c] < best_val){\n                    best_val = value[r][c];\n                    br=r; bc=c;\n                }\n            }\n        }\n        // remove the chosen container\n        removal_order.emplace_back(br,bc);\n        occupied[br][bc] = false;\n        value[br][bc] = -1;\n        ++removed;\n    }\n\n    for (auto [r,c] : removal_order){\n        cout << r << ' ' << c << '\\n';\n    }\n    cout.flush();\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\n#include <array>\nusing namespace std;\n\nconst int N = 50;\nconst int M = 100;\n\nint n, m;\nint orig[N][N];\n\n/* --------------------------------------------------------------- */\n/*  adjacency of the original map (including colour 0)            */\nbool orig_adj[M + 1][M + 1];                 // symmetric, 0..m\nvector<array<int,6>> adj_pairs;               // c,d,i1,j1,i2,j2  (both >0)\n\n/* --------------------------------------------------------------- */\n/*  colour sets                                                   */\nvector<pair<int,int>> cells_of_color[M + 1];   // 1..m\nbool is_border_colour[M + 1];\nbool is_interior_colour[M + 1];\n\n/* --------------------------------------------------------------- */\n/*  required cells for each colour (see section 2)                */\nbool required_pos[N][N];\nvector<pair<int,int>> required[M + 1];\n\n/* --------------------------------------------------------------- */\n/*  cells that finally stay coloured                              */\nbool keep[N][N];\n\n/* --------------------------------------------------------------- */\n/*  utility: neighbour directions                                  */\nconst int dy[4] = { -1, 1, 0, 0 };\nconst int dx[4] = { 0, 0, -1, 1 };\n\n/* --------------------------------------------------------------- */\n/*  full validation of a produced map                            */\nbool validate(const int out[N][N])\n{\n    /* 1. each colour appears at least once and is connected       */\n    int cnt_colour[M+1];\n    fill(begin(cnt_colour), end(cnt_colour), 0);\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++) {\n        int c = out[i][j];\n        if (c<0 || c>m) return false;\n        ++cnt_colour[c];\n    }\n    for (int c=1;c<=m;c++) if (cnt_colour[c]==0) return false;\n\n    // BFS for each colour\n    bool visited[N][N];\n    for (int c=1;c<=m;c++) {\n        memset(visited,0,sizeof(visited));\n        // find first cell of this colour\n        int sx=-1,sy=-1;\n        for (int i=0;i<n && sx==-1;i++) for (int j=0;j<n;j++)\n            if (out[i][j]==c) { sx=i; sy=j; break; }\n        if (sx==-1) return false;               // should not happen\n        queue<pair<int,int>> q;\n        q.emplace(sx,sy);\n        visited[sx][sy]=true;\n        int reach=0;\n        while(!q.empty()){\n            auto [y,x]=q.front(); q.pop();\n            ++reach;\n            for (int dir=0;dir<4;dir++){\n                int ny=y+dy[dir], nx=x+dx[dir];\n                if (ny<0||ny>=n||nx<0||nx>=n) continue;\n                if (out[ny][nx]==c && !visited[ny][nx]){\n                    visited[ny][nx]=true;\n                    q.emplace(ny,nx);\n                }\n            }\n        }\n        if (reach!=cnt_colour[c]) return false;   // not connected\n    }\n\n    /* 2. zero cells are connected with the outside               */\n    memset(visited,0,sizeof(visited));\n    queue<pair<int,int>> qz;\n    // start from every border zero cell\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++) {\n        if (out[i][j]==0 &&\n            (i==0||i==n-1||j==0||j==n-1)){\n            visited[i][j]=true;\n            qz.emplace(i,j);\n        }\n    }\n    while(!qz.empty()){\n        auto [y,x]=qz.front(); qz.pop();\n        for (int dir=0;dir<4;dir++){\n            int ny=y+dy[dir], nx=x+dx[dir];\n            if (ny<0||ny>=n||nx<0||nx>=n) continue;\n            if (out[ny][nx]==0 && !visited[ny][nx]){\n                visited[ny][nx]=true;\n                qz.emplace(ny,nx);\n            }\n        }\n    }\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++)\n        if (out[i][j]==0 && !visited[i][j]) return false;   // isolated zero\n\n    /* 3. adjacency matrix exactly the original one                */\n    bool out_adj[M+1][M+1];\n    memset(out_adj,0,sizeof(out_adj));\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++) {\n        int c = out[i][j];\n        for (int dir=0;dir<4;dir++){\n            int ni=i+dy[dir], nj=j+dx[dir];\n            if (ni<0||ni>=n||nj<0||nj>=n){\n                // outside -> colour 0\n                out_adj[c][0]=out_adj[0][c]=true;\n                continue;\n            }\n            int d = out[ni][nj];\n            if (c!=d){\n                out_adj[c][d]=out_adj[d][c]=true;\n            }\n        }\n    }\n    for (int c=0;c<=m;c++) for (int d=c;d<=m;d++)\n        if (orig_adj[c][d]!=out_adj[c][d]) return false;\n\n    return true;\n}\n\n/* --------------------------------------------------------------- */\n/*  connect the already kept cells of one border colour            */\nvoid connect_border_colour(int col)\n{\n    // region = all cells of this colour in the original map\n    static bool inRegion[N][N];\n    for (auto &p : cells_of_color[col]) inRegion[p.first][p.second]=true;\n\n    // components of currently kept cells\n    static int comp[N][N];\n    memset(comp, -1, sizeof(comp));\n    int compCnt = 0;\n    queue<pair<int,int>> qq;\n    for (auto &p : cells_of_color[col]) {\n        int y=p.first, x=p.second;\n        if (keep[y][x] && comp[y][x]==-1){\n            qq.emplace(y,x);\n            comp[y][x]=compCnt;\n            while(!qq.empty()){\n                auto [cy,cx]=qq.front(); qq.pop();\n                for (int dir=0;dir<4;dir++){\n                    int ny=cy+dy[dir], nx=cx+dx[dir];\n                    if (ny<0||ny>=n||nx<0||nx>=n) continue;\n                    if (!inRegion[ny][nx]) continue;\n                    if (keep[ny][nx] && comp[ny][nx]==-1){\n                        comp[ny][nx]=compCnt;\n                        qq.emplace(ny,nx);\n                    }\n                }\n            }\n            ++compCnt;\n        }\n    }\n\n    while (compCnt>1){\n        // find two cells belonging to different components\n        int y1=-1,x1=-1,y2=-1,x2=-1;\n        for (auto &p : cells_of_color[col]){\n            int y=p.first, x=p.second;\n            if (!keep[y][x]) continue;\n            if (y1==-1) { y1=y; x1=x; continue; }\n            if (comp[y][x]!=comp[y1][x1]){ y2=y; x2=x; break; }\n        }\n        // BFS inside the whole region to find a shortest path\n        static int pred_y[N][N], pred_x[N][N];\n        static bool seen[N][N];\n        memset(seen,0,sizeof(seen));\n        queue<pair<int,int>> q;\n        q.emplace(y1,x1);\n        seen[y1][x1]=true;\n        pred_y[y1][x1]=pred_x[y1][x1]=-1;\n        while(!q.empty()){\n            auto [cy,cx]=q.front(); q.pop();\n            if (cy==y2 && cx==x2) break;\n            for (int dir=0;dir<4;dir++){\n                int ny=cy+dy[dir], nx=cx+dx[dir];\n                if (ny<0||ny>=n||nx<0||nx>=n) continue;\n                if (!inRegion[ny][nx]) continue;\n                if (!seen[ny][nx]){\n                    seen[ny][nx]=true;\n                    pred_y[ny][nx]=cy;\n                    pred_x[ny][nx]=cx;\n                    q.emplace(ny,nx);\n                }\n            }\n        }\n        // mark the whole path as kept\n        int yy=y2, xx=x2;\n        while(!(yy==y1&&xx==x1)){\n            keep[yy][xx]=true;\n            int py = pred_y[yy][xx];\n            int px = pred_x[yy][xx];\n            yy=py; xx=px;\n        }\n        keep[y1][x1]=true;\n\n        // recompute components (simplest: start again)\n        memset(comp,-1,sizeof(comp));\n        compCnt=0;\n        for (auto &p : cells_of_color[col]){\n            int y=p.first, x=p.second;\n            if (keep[y][x] && comp[y][x]==-1){\n                qq.emplace(y,x);\n                comp[y][x]=compCnt;\n                while(!qq.empty()){\n                    auto [cy,cx]=qq.front(); qq.pop();\n                    for (int dir=0;dir<4;dir++){\n                        int ny=cy+dy[dir], nx=cx+dx[dir];\n                        if (ny<0||ny>=n||nx<0||nx>=n) continue;\n                        if (!inRegion[ny][nx]) continue;\n                        if (keep[ny][nx] && comp[ny][nx]==-1){\n                            comp[ny][nx]=compCnt;\n                            qq.emplace(ny,nx);\n                        }\n                    }\n                }\n                ++compCnt;\n            }\n        }\n    }\n\n    // clear inRegion for next call\n    for (auto &p : cells_of_color[col]) inRegion[p.first][p.second]=false;\n}\n\n/* --------------------------------------------------------------- */\n/*  greedy deletion of non\u2011required cells                         */\nvoid greedy_deletion(int out_grid[N][N])\n{\n    mt19937 rng(123456);\n    bool changed=true;\n    int passes=0;\n    while (changed && passes<5){\n        changed=false;\n        vector<pair<int,int>> cand;\n        for (int i=0;i<n;i++) for (int j=0;j<n;j++)\n            if (keep[i][j] && !required_pos[i][j])\n                cand.emplace_back(i,j);\n        shuffle(cand.begin(), cand.end(), rng);\n        for (auto [y,x] : cand){\n            int oldcol = orig[y][x];\n            // try delete\n            out_grid[y][x]=0;\n            keep[y][x]=false;\n            if (validate(out_grid)){\n                changed=true;\n            } else {\n                // revert\n                out_grid[y][x]=oldcol;\n                keep[y][x]=true;\n            }\n        }\n        ++passes;\n    }\n}\n\n/* --------------------------------------------------------------- */\n/*  repair isolated zero pools                                   */\nvoid repair_isolated_zeros(int out_grid[N][N])\n{\n    bool visited[N][N];\n    memset(visited,0,sizeof(visited));\n    queue<pair<int,int>> q;\n    // start from border zeros\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++){\n        if (out_grid[i][j]==0 && (i==0||i==n-1||j==0||j==n-1)){\n            visited[i][j]=true;\n            q.emplace(i,j);\n        }\n    }\n    while(!q.empty()){\n        auto [y,x]=q.front(); q.pop();\n        for (int dir=0;dir<4;dir++){\n            int ny=y+dy[dir], nx=x+dx[dir];\n            if (ny<0||ny>=n||nx<0||nx>=n) continue;\n            if (out_grid[ny][nx]==0 && !visited[ny][nx]){\n                visited[ny][nx]=true;\n                q.emplace(ny,nx);\n            }\n        }\n    }\n    // revert isolated zeros\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++){\n        if (out_grid[i][j]==0 && !visited[i][j]){\n            out_grid[i][j]=orig[i][j];\n            keep[i][j]=true;          // not used any more, but keep consistent\n        }\n    }\n}\n\n/* --------------------------------------------------------------- */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if(!(cin>>n>>m)) return 0;\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++){\n        cin>>orig[i][j];\n        cells_of_color[orig[i][j]].push_back({i,j});\n        if (i==0||i==n-1||j==0||j==n-1) is_border_colour[orig[i][j]]=true;\n    }\n\n    /* ---- original adjacency ------------------------------------ */\n    memset(orig_adj,0,sizeof(orig_adj));\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++){\n        int c = orig[i][j];\n        for (int dir=0;dir<4;dir++){\n            int ni=i+dy[dir], nj=j+dx[dir];\n            if (ni<0||ni>=n||nj<0||nj>=n){\n                // outside -> colour 0\n                orig_adj[c][0]=orig_adj[0][c]=true;\n                continue;\n            }\n            int d = orig[ni][nj];\n            if (c!=d){\n                orig_adj[c][d]=orig_adj[d][c]=true;\n                // store pair (c,d) together with both cell positions\n                if (c<d)\n                    adj_pairs.push_back({{c,d,i,j,ni,nj}});\n                else\n                    adj_pairs.push_back({{d,c,ni,nj,i,j}});\n            }\n        }\n    }\n\n    /* ---- interior / border colours ----------------------------- */\n    for (int c=1;c<=m;c++) is_interior_colour[c]=!is_border_colour[c];\n\n    /* ---- must_keep: cells that may not become zero -------------- */\n    bool must_keep[N][N];\n    memset(must_keep,0,sizeof(must_keep));\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++){\n        if (is_interior_colour[orig[i][j]]){\n            must_keep[i][j]=true;\n            for (int dir=0;dir<4;dir++){\n                int ni=i+dy[dir], nj=j+dx[dir];\n                if (ni<0||ni>=n||nj<0||nj>=n) continue;\n                must_keep[ni][nj]=true;\n            }\n        }\n    }\n\n    /* ---- required cells for border colours ---------------------- */\n    memset(required_pos,0,sizeof(required_pos));\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++){\n        int c = orig[i][j];\n        if (is_border_colour[c] && must_keep[i][j]){\n            required[c].push_back({i,j});\n            required_pos[i][j]=true;\n        }\n    }\n    // at least one border cell for each border colour\n    for (int c=1;c<=m;c++) if (is_border_colour[c]){\n        bool has=false;\n        for (auto &p : cells_of_color[c]){\n            int y=p.first, x=p.second;\n            if (y==0||y==n-1||x==0||x==n-1){\n                if (!required_pos[y][x]){\n                    required[c].push_back({y,x});\n                    required_pos[y][x]=true;\n                }\n                has=true;\n                break;\n            }\n        }\n        // border colour must have at least one border cell \u2013 guaranteed by input\n    }\n    // one pair for each border\u2011border edge\n    bool edge_used[M+1][M+1];\n    memset(edge_used,0,sizeof(edge_used));\n    for (auto &e : adj_pairs){\n        int a=e[0], b=e[1];\n        if (!is_border_colour[a] || !is_border_colour[b]) continue;\n        int c=min(a,b), d=max(a,b);\n        if (edge_used[c][d]) continue;\n        // store both cells as required\n        int c1=e[0], y1=e[2], x1=e[3];\n        int c2=e[1], y2=e[4], x2=e[5];\n        if (!required_pos[y1][x1]){\n            required[c1].push_back({y1,x1});\n            required_pos[y1][x1]=true;\n        }\n        if (!required_pos[y2][x2]){\n            required[c2].push_back({y2,x2});\n            required_pos[y2][x2]=true;\n        }\n        edge_used[c][d]=true;\n    }\n\n    /* ---- initial keep set -------------------------------------- */\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++) keep[i][j]=must_keep[i][j];\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++)\n        if (required_pos[i][j]) keep[i][j]=true;\n\n    /* ---- connect every border colour ---------------------------- */\n    for (int c=1;c<=m;c++) if (is_border_colour[c])\n        connect_border_colour(c);\n\n    /* ---- build a first valid output map ------------------------ */\n    int out_grid[N][N];\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++)\n        out_grid[i][j] = keep[i][j] ? orig[i][j] : 0;\n\n    /* ---- try to delete more cells greedily --------------------- */\n    greedy_deletion(out_grid);\n\n    /* ---- repair isolated zero pools ---------------------------- */\n    repair_isolated_zeros(out_grid);\n\n    /* ---- final output ------------------------------------------ */\n    for (int i=0;i<n;i++){\n        for (int j=0;j<n;j++){\n            if (j) cout << ' ';\n            cout << out_grid[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    // comparison_matrix[i][j]: 1 if i > j, -1 if i < j, 0 if unknown, 2 if equal\n    vector<vector<int>> comparison_matrix(N, vector<int>(N, 0));\n    vector<int> comparison_count(N, 0);\n    \n    for (int query = 0; query < Q; query++) {\n        // Find item with minimum comparisons\n        int i = min_element(comparison_count.begin(), comparison_count.end()) - comparison_count.begin();\n        \n        // Find another item to compare with, preferring not yet compared\n        int j = -1;\n        int min_other_count = INT_MAX;\n        \n        // First try: find an item not yet compared with i\n        for (int k = 0; k < N; k++) {\n            if (k != i && comparison_matrix[i][k] == 0 && comparison_count[k] < min_other_count) {\n                min_other_count = comparison_count[k];\n                j = k;\n            }\n        }\n        \n        // Second try: if no new pair, find any item with minimal comparisons\n        if (j == -1) {\n            for (int k = 0; k < N; k++) {\n                if (k != i && comparison_count[k] < min_other_count) {\n                    min_other_count = comparison_count[k];\n                    j = k;\n                }\n            }\n        }\n        \n        // Final fallback\n        if (j == -1) {\n            j = (i + 1) % N;\n            if (j == i) j = (i + 2) % N; // Ensure different items\n        }\n        \n        // Output query: compare single items\n        cout << \"1 1 \" << i << \" \" << j << endl;\n        cout.flush();\n        \n        string result;\n        cin >> result;\n        \n        // Update matrix\n        if (result == \">\") {\n            comparison_matrix[i][j] = 1;\n            comparison_matrix[j][i] = -1;\n        } else if (result == \"<\") {\n            comparison_matrix[i][j] = -1;\n            comparison_matrix[j][i] = 1;\n        } else { // \"=\"\n            comparison_matrix[i][j] = 2; // Equal\n            comparison_matrix[j][i] = 2;\n        }\n        \n        comparison_count[i]++;\n        comparison_count[j]++;\n    }\n    \n    // Calculate score for each item: wins - losses\n    vector<int> score(N, 0);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (i == j) continue;\n            if (comparison_matrix[i][j] == 1) {\n                score[i]++; // i beats j\n            } else if (comparison_matrix[i][j] == -1) {\n                score[i]--; // i loses to j\n            }\n        }\n    }\n    \n    // Create order: items sorted by score descending\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        return score[a] > score[b];\n    });\n    \n    // Assign to D groups using snake pattern for balanced distribution\n    vector<int> assignment(N);\n    for (int pos = 0; pos < N; pos++) {\n        int item = order[pos];\n        int cycle = pos / D;\n        int offset = pos % D;\n        \n        int target_group = (cycle % 2 == 0) ? offset : (D - 1 - offset);\n        assignment[item] = target_group;\n    }\n    \n    // Output assignment\n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << assignment[i];\n    }\n    cout << endl;\n    cout.flush();\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    int h = n / m;                     // height of each stack, fixed to 20\n    vector<vector<int>> st(m);          // stacks, bottom -> top\n    for (int i = 0; i < m; ++i) {\n        st[i].reserve(h);\n        for (int j = 0; j < h; ++j) {\n            int x; cin >> x;\n            st[i].push_back(x);\n        }\n    }\n\n    vector<pair<int,int>> ops;          // answer sequence\n    ops.reserve(5000);\n    long long total_energy = 0;         // only for self check, not output\n\n    // helper: find box v, return (stack index, position inside stack)\n    auto locate = [&](int v, int &si, int &pos){\n        for (int i = 0; i < m; ++i) {\n            for (int j = 0; j < (int)st[i].size(); ++j) {\n                if (st[i][j] == v) {\n                    si = i;\n                    pos = j;\n                    return;\n                }\n            }\n        }\n        // should never happen\n        cerr << \"box \" << v << \" not found!\\n\";\n        exit(1);\n    };\n\n    for (int v = 1; v <= n; ++v) {\n        int si, pos;\n        locate(v, si, pos);\n\n        // if v already on the top -> carry out directly\n        if (pos == (int)st[si].size() - 1) {\n            ops.emplace_back(v, 0);\n            st[si].pop_back();               // remove v\n            continue;\n        }\n\n        // box directly above v\n        int w = st[si][pos + 1];\n\n        // choose a destination stack (different from si)\n        int dest = -1;\n        // 1) any empty stack ?\n        for (int i = 0; i < m; ++i) if (i != si && st[i].empty()) {\n            dest = i; break;\n        }\n        // 2) otherwise the non\u2011empty stack with the largest top number\n        if (dest == -1) {\n            int best_top = -1;\n            for (int i = 0; i < m; ++i) if (i != si && !st[i].empty()) {\n                int cur_top = st[i].back();\n                if (cur_top > best_top) {\n                    best_top = cur_top;\n                    dest = i;\n                }\n            }\n        }\n        // sanity check\n        if (dest == -1) {\n            // should never happen (there is at least one other stack)\n            dest = (si + 1) % m;\n        }\n\n        // ---- move the block w .. top of si to dest ----\n        int start = pos + 1;                         // first element to move\n        vector<int> suffix(st[si].begin() + start, st[si].end());\n        int k = (int)suffix.size();                 // number of moved boxes\n        total_energy += k + 1;\n\n        // erase from source\n        st[si].erase(st[si].begin() + start, st[si].end());\n        // append to destination\n        st[dest].insert(st[dest].end(), suffix.begin(), suffix.end());\n\n        ops.emplace_back(w, dest + 1);               // operation 1\n\n        // ---- now v is on the top of si, carry it out ----\n        ops.emplace_back(v, 0);\n        st[si].pop_back();                           // remove v\n    }\n\n    // ---- output ---------------------------------------------------------\n    for (auto [a, b] : ops) {\n        cout << a << ' ' << b << '\\n';\n    }\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\nvector<vector<bool>> visited;\nvector<vector<int>> extra_flutters;          // remaining extra round\u2011trips\nvector<vector<pair<int,int>>> best_nb;       // cached best neighbour per cell\nstring path;\nconst int MAX_MOVES = 100000;\n\n/* --------------------------------------------------------------- */\n// wall\u2011aware move test\ninline bool can_move(int i, int j, int ni, int nj) {\n    if (ni == i - 1 && i > 0)      return h[i - 1][j] == '0';\n    if (ni == i + 1 && i < N - 1)  return h[i][j]     == '0';\n    if (nj == j - 1 && j > 0)      return v[i][j - 1] == '0';\n    if (nj == j + 1 && j < N - 1)  return v[i][j]     == '0';\n    return false;\n}\n\n/* --------------------------------------------------------------- */\n// append one step to the walk\ninline void add_move(int di, int dj) {\n    if ((int)path.size() >= MAX_MOVES) return;\n    if (di == -1) path.push_back('U');\n    else if (di == 1) path.push_back('D');\n    else if (dj == -1) path.push_back('L');\n    else if (dj == 1) path.push_back('R');\n}\n\n/* --------------------------------------------------------------- */\n// depth\u2011first walk with interleaved extra round\u2011trips\nvoid dfs(int i, int j) {\n    if ((int)path.size() >= MAX_MOVES) return;\n    visited[i][j] = true;\n\n    const int DIRS[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n    vector<pair<int,pair<int,int>>> neigh;          // (\u2011d , (x,y))\n\n    // neighbours, sorted by decreasing dirt factor\n    for (auto [di,dj] : DIRS) {\n        int ni = i + di, nj = j + dj;\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N &&\n            can_move(i,j,ni,nj) && !visited[ni][nj])\n            neigh.push_back({-d[ni][nj], {ni,nj}});\n    }\n    sort(neigh.begin(), neigh.end());\n\n    // process children\n    for (auto [_,c] : neigh) {\n        int ni = c.first, nj = c.second;\n        if (!visited[ni][nj]) {\n            add_move(ni - i, nj - j);\n            dfs(ni, nj);\n            add_move(i - ni, j - nj);\n\n            // insert one flutter now \u2192 intervals are spread\n            if (extra_flutters[i][j] > 0 && (int)path.size() + 2 <= MAX_MOVES) {\n                auto [di,dj] = best_nb[i][j];\n                if (di != 0 || dj != 0) {\n                    add_move(di, dj);\n                    add_move(-di, -dj);\n                    --extra_flutters[i][j];\n                }\n            }\n        }\n    }\n\n    // remaining flutters for this cell (when it has few children)\n    while (extra_flutters[i][j] > 0 && (int)path.size() + 2 <= MAX_MOVES) {\n        auto [di,dj] = best_nb[i][j];\n        if (di != 0 || dj != 0) {\n            add_move(di, dj);\n            add_move(-di, -dj);\n            --extra_flutters[i][j];\n        } else break;\n    }\n}\n\n/* --------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // ---- read input -------------------------------------------------\n    cin >> N;\n    h.resize(N-1);\n    for (int i=0;i<N-1;i++) cin >> h[i];\n    v.resize(N);\n    for (int i=0;i<N;i++)   cin >> v[i];\n    d.assign(N, vector<int>(N));\n    for (int i=0;i<N;i++)\n        for (int j=0;j<N;j++) cin >> d[i][j];\n\n    // ---- cache best neighbours --------------------------------------\n    best_nb.assign(N, vector<pair<int,int>>(N, {0,0}));\n    const int DIRS[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n    for (int i=0;i<N;i++)\n        for (int j=0;j<N;j++) {\n            int bestVal = -1, bestDi = 0, bestDj = 0;\n            for (auto [di,dj] : DIRS) {\n                int ni = i + di, nj = j + dj;\n                if (ni>=0 && ni<N && nj>=0 && nj<N && can_move(i,j,ni,nj))\n                    if (d[ni][nj] > bestVal) {\n                        bestVal = d[ni][nj];\n                        bestDi = di; bestDj = dj;\n                    }\n            }\n            best_nb[i][j] = {bestDi, bestDj};\n        }\n\n    // ---- distribute extra round\u2011trips --------------------------------\n    int V = N * N;\n    int base   = 2 * (V - 1);                 // pure DFS length\n    int budget = MAX_MOVES - base;            // free moves\n    if (budget < 0) budget = 0;\n    int reserve = budget / 10;                // keep 10\u202f% for padding\n    budget -= reserve;\n\n    double sumSqrt = 0.0;\n    vector<vector<double>> sqrtD(N, vector<double>(N));\n    for (int i=0;i<N;i++)\n        for (int j=0;j<N;j++) {\n            sqrtD[i][j] = sqrt(d[i][j]);\n            sumSqrt += sqrtD[i][j];\n        }\n\n    extra_flutters.assign(N, vector<int>(N, 0));\n    if (sumSqrt > 0) {\n        const double COST_PER_EXTRA = 2.0;    // one round\u2011trip = two moves\n        for (int i=0;i<N;i++)\n            for (int j=0;j<N;j++) {\n                double ratio = sqrtD[i][j] / sumSqrt;\n                extra_flutters[i][j] = max(0, int(budget * ratio / COST_PER_EXTRA));\n            }\n    }\n\n    // ---- build walk --------------------------------------------------\n    visited.assign(N, vector<bool>(N, false));\n    dfs(0,0);\n\n    // ---- final padding if length limit not reached -------------------\n    while ((int)path.size() + 2 <= MAX_MOVES) {\n        bool ok = false;\n        for (auto [di,dj] : DIRS) {\n            int ni = di, nj = dj;               // relative to (0,0)\n            if (ni>=0 && ni<N && nj>=0 && nj<N && can_move(0,0,ni,nj)) {\n                add_move(di, dj);\n                add_move(-di, -dj);\n                ok = true; break;\n            }\n        }\n        if (!ok) break;\n    }\n\n    cout << path << '\\n';\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\n\nint N, M;\nint si, sj;\nint startId;                     // linear index of the start cell\nvector<string> board;\nvector<string> pat;              // patterns, length M, each length 5\n\n// for every letter \u2013 list of cell ids that contain this letter\nvector<vector<int>> letterPos;   // size 26\n\n// Manhattan distance between any two cells\nint distCell[225][225];\n// coordinates of a cell id\nint row[225], col[225];\n\n/* -------------------------------------------------------------\n   compute the cheapest sum of Manhattan distances for a fixed\n   sequence of letters (vector<int> seq containing 0..25)\n   ------------------------------------------------------------- */\nint movementDist(const vector<int> &seq) {\n    // first character\n    const vector<int> *prevCand = &letterPos[seq[0]];\n    vector<int> dpPrev(prevCand->size());\n    for (int i = 0; i < (int)prevCand->size(); ++i)\n        dpPrev[i] = distCell[startId][(*prevCand)[i]];\n\n    for (size_t idx = 1; idx < seq.size(); ++idx) {\n        const vector<int> *curCand = &letterPos[seq[idx]];\n        vector<int> dpCur(curCand->size(), INF);\n        for (int ci = 0; ci < (int)curCand->size(); ++ci) {\n            int cur = (*curCand)[ci];\n            int best = INF;\n            for (int pi = 0; pi < (int)prevCand->size(); ++pi) {\n                int cand = (*prevCand)[pi];\n                int val = dpPrev[pi] + distCell[cand][cur];\n                if (val < best) best = val;\n            }\n            dpCur[ci] = best;\n        }\n        dpPrev.swap(dpCur);\n        prevCand = curCand;\n    }\n    int best = INF;\n    for (int v : dpPrev) if (v < best) best = v;\n    return best;\n}\n\n/* -------------------------------------------------------------\n   build the overlapped string for a given order of patterns,\n   store it into seq, return total price = movement + length\n   ------------------------------------------------------------- */\nint priceOfOrder(const vector<int> &order, vector<int> &seq) {\n    seq.clear(); seq.reserve(5 * M);\n    for (int id : order) {\n        const string &p = pat[id];\n        int maxOL = min((int)seq.size(), 5);\n        int overlap = 0;\n        for (int k = maxOL; k > 0; --k) {\n            bool ok = true;\n            for (int i = 0; i < k; ++i)\n                if (seq[seq.size() - k + i] != p[i] - 'A') { ok = false; break; }\n            if (ok) { overlap = k; break; }\n        }\n        for (int i = overlap; i < 5; ++i) seq.push_back(p[i] - 'A');\n    }\n    int move = movementDist(seq);\n    return move + (int)seq.size();          // total price\n}\n\n/* -------------------------------------------------------------\n   reconstruct the concrete walk for the best order\n   ------------------------------------------------------------- */\nvector<int> reconstructWalk(const vector<int> &order) {\n    vector<int> seq; seq.reserve(5 * M);\n    for (int id : order) {\n        const string &p = pat[id];\n        int maxOL = min((int)seq.size(), 5);\n        int overlap = 0;\n        for (int k = maxOL; k > 0; --k) {\n            bool ok = true;\n            for (int i = 0; i < k; ++i)\n                if (seq[seq.size() - k + i] != p[i] - 'A') { ok = false; break; }\n            if (ok) { overlap = k; break; }\n        }\n        for (int i = overlap; i < 5; ++i) seq.push_back(p[i] - 'A');\n    }\n    int L = (int)seq.size();\n\n    struct Step {\n        const vector<int> *cells;\n        vector<int> dp;\n        vector<int> pred;          // index inside previous layer\n    };\n    vector<Step> step(L);\n\n    // first layer\n    step[0].cells = &letterPos[seq[0]];\n    step[0].dp.resize(step[0].cells->size());\n    step[0].pred.assign(step[0].cells->size(), -1);\n    for (int i = 0; i < (int)step[0].cells->size(); ++i)\n        step[0].dp[i] = distCell[startId][(*step[0].cells)[i]];\n\n    for (int i = 1; i < L; ++i) {\n        step[i].cells = &letterPos[seq[i]];\n        const vector<int> &prevCells = *step[i - 1].cells;\n        const vector<int> &curCells  = *step[i].cells;\n        step[i].dp.assign(curCells.size(), INF);\n        step[i].pred.assign(curCells.size(), -1);\n        for (int ci = 0; ci < (int)curCells.size(); ++ci) {\n            int cur = curCells[ci];\n            int best = INF, bestIdx = -1;\n            for (int pi = 0; pi < (int)prevCells.size(); ++pi) {\n                int val = step[i - 1].dp[pi] + distCell[prevCells[pi]][cur];\n                if (val < best) {\n                    best = val;\n                    bestIdx = pi;\n                }\n            }\n            step[i].dp[ci] = best;\n            step[i].pred[ci] = bestIdx;\n        }\n    }\n\n    // find cheapest last cell\n    const vector<int> &lastCells = *step[L - 1].cells;\n    int bestCost = INF, bestIdx = -1;\n    for (int i = 0; i < (int)lastCells.size(); ++i)\n        if (step[L - 1].dp[i] < bestCost) {\n            bestCost = step[L - 1].dp[i];\n            bestIdx = i;\n        }\n\n    // backtrack\n    vector<int> walk(L);\n    int idx = bestIdx;\n    for (int i = L - 1; i >= 0; --i) {\n        walk[i] = (*step[i].cells)[idx];\n        if (i > 0) idx = step[i].pred[idx];\n    }\n    return walk;\n}\n\n\n/* ------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M)) return 0;\n    cin >> si >> sj;\n    startId = si * N + sj;\n    board.resize(N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n    pat.resize(M);\n    for (int i = 0; i < M; ++i) cin >> pat[i];\n\n    // ---- build letterPos and coordinates -----------------------\n    letterPos.assign(26, {});\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            int id = i * N + j;\n            char c = board[i][j];\n            letterPos[c - 'A'].push_back(id);\n            row[id] = i; col[id] = j;\n        }\n\n    // ---- all pairwise Manhattan distances ----------------------\n    int C = N * N;\n    for (int a = 0; a < C; ++a)\n        for (int b = 0; b < C; ++b)\n            distCell[a][b] = abs(row[a] - row[b]) + abs(col[a] - col[b]);\n\n    // ---- initial order (0..M-1) and its price ----------------\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    vector<int> seq;\n    int bestPrice = priceOfOrder(order, seq);\n    vector<int> bestOrder = order;\n\n    // ---- random search ----------------------------------------\n    const double TIME_LIMIT = 1.8;           // seconds\n    auto start = chrono::high_resolution_clock::now();\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    int iterations = 0;\n    while (true) {\n        if (iterations % 500 == 0) {\n            auto now = chrono::high_resolution_clock::now();\n            if (chrono::duration<double>(now - start).count() > TIME_LIMIT)\n                break;\n        }\n        shuffle(order.begin(), order.end(), rng);\n        int curPrice = priceOfOrder(order, seq);\n        if (curPrice < bestPrice) {\n            bestPrice = curPrice;\n            bestOrder = order;\n        }\n        ++iterations;\n    }\n\n    // ---- output the walk for the best order --------------------\n    vector<int> walk = reconstructWalk(bestOrder);\n    for (int cell : walk) {\n        int i = cell / N;\n        int j = cell % N;\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<pair<int,int>>> shapes;          // not needed in the basic version\n\n/* -------------------- communication -------------------------------- */\nint query_single(int i, int j) {\n    cout << \"q 1 \" << i << ' ' << j << endl;\n    int ret; cin >> ret;\n    return ret;\n}\nint query_set(const vector<pair<int,int>>& cells) {\n    int k = (int)cells.size();\n    cout << \"q \" << k;\n    for (auto [i, j] : cells) cout << ' ' << i << ' ' << j;\n    cout << endl;\n    int ret; cin >> ret;\n    return ret;\n}\n\n/* -------------------- estimation ---------------------------------- */\ninline double est_sum(int answer, int k) {\n    double mu = answer;                     // treat the rounded answer as \u03bc\n    return (mu - k * eps) / (1.0 - 2.0 * eps);\n}\n\n/* -------------------- main ---------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---- read description --------------------------------------- */\n    if (!(cin >> N >> M >> eps)) return 0;\n    shapes.resize(M);\n    for (int k = 0; k < M; ++k) {\n        int d; cin >> d;\n        shapes[k].resize(d);\n        for (int i = 0; i < d; ++i) {\n            int x, y; cin >> x >> y;\n            shapes[k][i] = {x, y};\n        }\n    }\n\n    /* ---- data structures ---------------------------------------- */\n    // 0 = unknown, 1 = oil, 2 = no oil\n    vector<char> row_flag(N, 0), col_flag(N, 0);\n    vector<vector<char>> cell_flag(N, vector<char>(N, 0));\n\n    /* ---------- Phase 1 : rows ---------------------------------- */\n    for (int r = 0; r < N; ++r) {\n        vector<pair<int,int>> cells;\n        cells.reserve(N);\n        for (int c = 0; c < N; ++c) cells.emplace_back(r, c);\n        int ans = query_set(cells);\n        double v_est = est_sum(ans, N);\n        if (v_est > 0.5) row_flag[r] = 1;\n        else {\n            row_flag[r] = 2;\n            for (int c = 0; c < N; ++c) cell_flag[r][c] = 2;\n        }\n    }\n\n    /* ---------- Phase 2 : columns ------------------------------- */\n    for (int c = 0; c < N; ++c) {\n        vector<pair<int,int>> cells;\n        cells.reserve(N);\n        for (int r = 0; r < N; ++r) cells.emplace_back(r, c);\n        int ans = query_set(cells);\n        double v_est = est_sum(ans, N);\n        if (v_est > 0.5) col_flag[c] = 1;\n        else {\n            col_flag[c] = 2;\n            for (int r = 0; r < N; ++r) cell_flag[r][c] = 2;\n        }\n    }\n\n    /* ---------- Phase 3 : blocks -------------------------------- */\n    int B = max(2, N / 5);                     // block side length\n    int nb = (N + B - 1) / B;                  // number of blocks per dimension\n    vector<vector<char>> block_flag(nb, vector<char>(nb, 0));\n\n    for (int bi = 0; bi < nb; ++bi)\n        for (int bj = 0; bj < nb; ++bj) {\n            // does the block intersect an oily row and an oily column?\n            bool oily_row = false, oily_col = false;\n            for (int i = bi * B; i < min(N, (bi + 1) * B) && !oily_row; ++i)\n                if (row_flag[i] == 1) oily_row = true;\n            for (int j = bj * B; j < min(N, (bj + 1) * B) && !oily_col; ++j)\n                if (col_flag[j] == 1) oily_col = true;\n\n            if (!oily_row || !oily_col) {       // cannot contain oil\n                block_flag[bi][bj] = 2;\n                for (int i = bi * B; i < min(N, (bi + 1) * B); ++i)\n                    for (int j = bj * B; j < min(N, (bj + 1) * B); ++j)\n                        if (cell_flag[i][j] == 0) cell_flag[i][j] = 2;\n                continue;\n            }\n\n            // build the list of still unknown cells inside this block\n            vector<pair<int,int>> block_cells;\n            for (int i = bi * B; i < min(N, (bi + 1) * B); ++i)\n                for (int j = bj * B; j < min(N, (bj + 1) * B); ++j)\n                    if (cell_flag[i][j] == 0) block_cells.emplace_back(i, j);\n\n            if (block_cells.empty()) {          // nothing left to test\n                block_flag[bi][bj] = 2;\n                continue;\n            }\n\n            int ans = query_set(block_cells);\n            double v_est = est_sum(ans, (int)block_cells.size());\n\n            if (v_est > 0.5) block_flag[bi][bj] = 1;   // keep cells unknown\n            else {\n                block_flag[bi][bj] = 2;                // whole block is dry\n                for (auto [i, j] : block_cells) cell_flag[i][j] = 2;\n            }\n        }\n\n    /* ---------- Phase 4 : single cells -------------------------- */\n    vector<pair<int,int>> answer;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (cell_flag[i][j] == 0) {\n                int v = query_single(i, j);\n                if (v > 0) answer.emplace_back(i, j);\n            }\n\n    /* ---------- final answer ------------------------------------ */\n    cout << \"a \" << answer.size();\n    for (auto [i, j] : answer) cout << ' ' << i << ' ' << j;\n    cout << endl;\n\n    int ok; cin >> ok;\n    if (ok == 1) return 0;                    // success \u2013 normal exit\n\n    /* ---------- Fallback \u2013 should be extremely rare ------------- */\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (cell_flag[i][j] == 2) {       // every cell once declared dry\n                int v = query_single(i, j);\n                if (v > 0) answer.emplace_back(i, j);\n            }\n\n    cout << \"a \" << answer.size();\n    for (auto [i, j] : answer) cout << ' ' << i << ' ' << j;\n    cout << endl;\n    cin >> ok;                                 // now it must be correct\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXW = 1000;                 // W is fixed to 1000 in the problem\n\n/*------------------------------------------------------------*/\n/*  geometry structures                                       */\n\nstruct Rect {\n    int x0, y0, x1, y1;               // top\u2011left (x0,y0), bottom\u2011right (x1,y1)\n};\n\nstruct Region {\n    int x, y, w, h;                    // top\u2011left corner, width, height\n    int area() const { return w * h; }\n};\n\n/*------------------------------------------------------------*/\n/*  packing of one day                                       */\n\nstatic vector<Rect> pack_day(const vector<int>& request, int W, int N) {\n    // request[k] = a[d][k]\n    vector<pair<int, int>> ord;        // (area , original index)\n    ord.reserve(N);\n    for (int k = 0; k < N; ++k) ord.emplace_back(request[k], k);\n    sort(ord.begin(), ord.end(),\n         [](const pair<int, int>& A, const pair<int, int>& B) {\n             return A.first > B.first;               // decreasing area\n         });\n\n    vector<Region> freeReg;\n    freeReg.push_back({0, 0, W, W});                 // whole hall\n\n    vector<Rect> answer(N);\n\n    for (auto [area, idx] : ord) {\n        // ---- find a region that can contain the rectangle\n        int sel = -1;          // region with area >= request\n        int best = -1;         // region with the largest area (used when no region fits)\n        int bestArea = -1;\n\n        for (int i = 0; i < (int)freeReg.size(); ++i) {\n            int a = freeReg[i].area();\n            if (a >= area) {\n                if (sel == -1 || a < freeReg[sel].area()) sel = i;\n            }\n            if (a > bestArea) {\n                bestArea = a;\n                best = i;\n            }\n        }\n\n        Region R;\n        bool fits = (sel != -1);\n        if (fits) R = freeReg[sel];\n        else      R = freeReg[best];                  // we will pay a penalty\n\n        // ---- choose the size of the rectangle\n        int w, h;\n        if (fits) {\n            // try orientation 1 (prefer a square)\n            int w1 = min(R.w, max(1, (int)std::sqrt((double)area)));\n            int h1 = (area + w1 - 1) / w1;               // ceil\n            if (h1 <= R.h) {\n                w = w1;  h = h1;\n            } else {\n                // orientation 2 (swap roles)\n                int h2 = min(R.h, max(1, (int)std::sqrt((double)area)));\n                int w2 = (area + h2 - 1) / h2;\n                if (w2 <= R.w) {\n                    w = w2;  h = h2;\n                } else {\n                    // fallback \u2013 use whole width of the region\n                    w = R.w;\n                    h = (area + w - 1) / w;\n                }\n            }\n        } else {\n            // we cannot satisfy the area \u2013 fill the whole region (penalty)\n            w = R.w;\n            h = R.h;\n        }\n\n        // ---- store the rectangle\n        answer[idx] = {R.x, R.y, R.x + w, R.y + h};\n\n        // ---- create the two leftover parts (guillotine cut)\n        if (w < R.w) {\n            freeReg.push_back({R.x + w, R.y, R.w - w, R.h});\n        }\n        if (h < R.h) {\n            freeReg.push_back({R.x, R.y + h, w, R.h - h});\n        }\n\n        // ---- delete the used region (swap with last element)\n        if (fits) {\n            freeReg[sel] = freeReg.back();\n            freeReg.pop_back();\n        } else {\n            freeReg[best] = freeReg.back();\n            freeReg.pop_back();\n        }\n    }\n    return answer;\n}\n\n/*------------------------------------------------------------*/\n/*  edge matrices                                             */\n\nstruct EdgeMatrices {\n    vector<vector<char>> H;   // H[i][j] : horizontal edge (i,0..W-1)  i=1..W-1\n    vector<vector<char>> V;   // V[i][j] : vertical   edge (0..W-1,j)  j=1..W-1\n    EdgeMatrices(int W) {\n        H.assign(W + 1, vector<char>(W, 0));\n        V.assign(W, vector<char>(W + 1, 0));\n    }\n    void clear() {\n        for (auto &row : H) fill(row.begin(), row.end(), 0);\n        for (auto &row : V) fill(row.begin(), row.end(), 0);\n    }\n};\n\nvoid mark_edges(const vector<Rect>& rects, int W, EdgeMatrices& em) {\n    em.clear();\n    for (const Rect& r : rects) {\n        if (r.x0 > 0) {\n            for (int j = r.y0; j < r.y1; ++j) em.H[r.x0][j] = 1;\n        }\n        if (r.x1 < W) {\n            for (int j = r.y0; j < r.y1; ++j) em.H[r.x1][j] = 1;\n        }\n        if (r.y0 > 0) {\n            for (int i = r.x0; i < r.x1; ++i) em.V[i][r.y0] = 1;\n        }\n        if (r.y1 < W) {\n            for (int i = r.x0; i < r.x1; ++i) em.V[i][r.y1] = 1;\n        }\n    }\n}\n\n/*------------------------------------------------------------*/\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\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    vector<vector<Rect>> allRects(D, vector<Rect>(N));\n    EdgeMatrices prev(W), cur(W);\n    long long totalCost = 0;               // only for debugging, not needed for output\n\n    for (int d = 0; d < D; ++d) {\n        // ----- pack the day\n        allRects[d] = pack_day(a[d], W, N);\n        // ----- build edge matrices\n        mark_edges(allRects[d], W, cur);\n        // ----- compute transition cost (L0 = 0 is special)\n        if (d > 0) {\n            long long Ld = 0;\n            for (int i = 1; i < W; ++i)\n                for (int j = 0; j < W; ++j)\n                    Ld += (prev.H[i][j] != cur.H[i][j]);\n            for (int i = 0; i < W; ++i)\n                for (int j = 1; j < W; ++j)\n                    Ld += (prev.V[i][j] != cur.V[i][j]);\n            totalCost += Ld;\n        }\n        // ----- store current matrices as previous for the next day\n        prev.H.swap(cur.H);\n        prev.V.swap(cur.V);\n    }\n\n    // ----- output\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            const Rect& r = allRects[d][k];\n            cout << r.x0 << ' ' << r.y0 << ' ' << r.x1 << ' ' << r.y1 << '\\n';\n        }\n    }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MOD = 998244353;\n\nstruct Op {\n    int m;\n    int p;\n    int q;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n    vector<vector<int>> initialBoard(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> initialBoard[i][j];\n    \n    vector<vector<vector<int>>> stamp(M, vector<vector<int>>(3, vector<int>(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                cin >> stamp[m][i][j];\n    \n    // Precompute all possible placements (operation types)\n    vector<Op> allOps;\n    for (int m = 0; m < M; ++m)\n        for (int p = 0; p <= N - 3; ++p)\n            for (int q = 0; q <= N - 3; ++q)\n                allOps.push_back({m, p, q});\n    \n    // Utility functions\n    auto boardScore = [&](const vector<vector<int>>& b) -> long long {\n        long long s = 0;\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                s += b[i][j];\n        return s;\n    };\n    \n    auto computeAddDelta = [&](const vector<vector<int>>& b, const Op& op) -> long long {\n        const auto& s = stamp[op.m];\n        long long delta = 0;\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                int old = b[op.p + i][op.q + j];\n                int add = s[i][j];\n                int sum = old + add;\n                if (sum >= MOD) delta += add - MOD;\n                else delta += add;\n            }\n        }\n        return delta;\n    };\n    \n    auto computeRemoveDelta = [&](const vector<vector<int>>& b, const Op& op) -> long long {\n        const auto& s = stamp[op.m];\n        long long delta = 0;\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                int old = b[op.p + i][op.q + j];\n                int sv = s[i][j];\n                int newMod = (old >= sv) ? old - sv : old + MOD - sv;\n                delta += newMod - old;\n            }\n        }\n        return delta;\n    };\n    \n    auto applyAdd = [&](vector<vector<int>>& b, long long& score, const Op& op) {\n        const auto& s = stamp[op.m];\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                int old = b[op.p + i][op.q + j];\n                int add = s[i][j];\n                int sum = old + add;\n                int newMod = (sum >= MOD) ? sum - MOD : sum;\n                b[op.p + i][op.q + j] = newMod;\n                score += newMod - old;\n            }\n        }\n    };\n    \n    auto applyRemove = [&](vector<vector<int>>& b, long long& score, const Op& op) {\n        const auto& s = stamp[op.m];\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                int old = b[op.p + i][op.q + j];\n                int sv = s[i][j];\n                int newMod = (old >= sv) ? old - sv : old + MOD - sv;\n                b[op.p + i][op.q + j] = newMod;\n                score += newMod - old;\n            }\n        }\n    };\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    long long bestScore = -1;\n    vector<Op> bestOps;\n    \n    const double TIME_LIMIT = 1.8;\n    auto startTime = chrono::steady_clock::now();\n    \n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - startTime).count();\n        if (elapsed > TIME_LIMIT) break;\n        \n        // Reset to initial board\n        vector<vector<int>> curBoard = initialBoard;\n        long long curScore = boardScore(curBoard);\n        vector<Op> curOps;\n        \n        // Outer loop: alternate addition and removal until stable\n        while (true) {\n            // ----- Addition phase -----\n            bool added = false;\n            while ((int)curOps.size() < K) {\n                // random order for scanning candidates\n                vector<Op> shuffled = allOps;\n                shuffle(shuffled.begin(), shuffled.end(), rng);\n                long long bestDelta = 0;\n                vector<Op> bestCandidates;\n                for (const Op& op : shuffled) {\n                    long long d = computeAddDelta(curBoard, op);\n                    if (d > bestDelta) {\n                        bestDelta = d;\n                        bestCandidates.clear();\n                        bestCandidates.push_back(op);\n                    } else if (d == bestDelta && d > 0) {\n                        bestCandidates.push_back(op);\n                    }\n                }\n                if (bestDelta <= 0) break;\n                const Op& chosen = bestCandidates[rng() % bestCandidates.size()];\n                applyAdd(curBoard, curScore, chosen);\n                curOps.push_back(chosen);\n                added = true;\n            }\n            \n            // ----- Removal phase -----\n            bool removed = false;\n            while (true) {\n                long long bestRemoveDelta = 0;\n                vector<int> idxCandidates;\n                for (int i = 0; i < (int)curOps.size(); ++i) {\n                    long long d = computeRemoveDelta(curBoard, curOps[i]);\n                    if (d > bestRemoveDelta) {\n                        bestRemoveDelta = d;\n                        idxCandidates.clear();\n                        idxCandidates.push_back(i);\n                    } else if (d == bestRemoveDelta && d > 0) {\n                        idxCandidates.push_back(i);\n                    }\n                }\n                if (bestRemoveDelta <= 0) break;\n                int idx = idxCandidates[rng() % idxCandidates.size()];\n                Op op = curOps[idx];\n                applyRemove(curBoard, curScore, op);\n                // remove from vector\n                curOps[idx] = curOps.back();\n                curOps.pop_back();\n                removed = true;\n            }\n            \n            if (!added && !removed) break;\n        }\n        \n        if (curScore > bestScore) {\n            bestScore = curScore;\n            bestOps = curOps;\n        }\n    }\n    \n    cout << bestOps.size() << \"\\n\";\n    for (auto &op : bestOps) {\n        cout << op.m << \" \" << op.p << \" \" << op.q << \"\\n\";\n    }\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos {\n    int r = -1, c = -1;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n    const int TOTAL = N * N;\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) cin >> A[i][j];\n\n    // which row each container comes from (not needed further)\n    vector<int> sourceRow(TOTAL);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            sourceRow[A[i][j]] = i;\n\n    // grid: container id or -1\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    // how many containers of each row already appeared\n    vector<int> recCnt(N, 0);\n    // how many containers already dispatched\n    int dispatched = 0;\n\n    // the large crane\n    struct Crane {\n        int r = 0, c = 0;\n        bool holding = false;\n        int holdId = -1;\n    } large;\n\n    // output strings, one per row\n    vector<string> out(N);\n\n    int turn = 0;\n    const int LIMIT = 10000;\n\n    while (dispatched < TOTAL && turn < LIMIT) {\n        /* ---- step 1 : containers appear ---- */\n        for (int i = 0; i < N; ++i) {\n            if (recCnt[i] >= N) continue;               // row finished\n            if (grid[i][0] != -1) continue;              // square occupied\n            // a crane holding a container blocks the square\n            bool blocked = (large.r == i && large.c == 0 && large.holding);\n            if (!blocked) {\n                int cid = A[i][recCnt[i]];\n                grid[i][0] = cid;\n                ++recCnt[i];\n            }\n        }\n\n        /* ---- step 2 : crane actions ---- */\n        // small cranes: bomb on turn 0, then only '.'\n        for (int i = 1; i < N; ++i) {\n            if (turn == 0) out[i].push_back('B');\n            else           out[i].push_back('.');\n        }\n\n        // large crane (row 0)\n        char act = '.';\n        if (large.holding) {\n            int targetRow = large.holdId / N;\n            int targetCol = N - 1;\n            if (large.r != targetRow) {                 // vertical move\n                int dr = (targetRow > large.r) ? 1 : -1;\n                act = (dr == 1) ? 'D' : 'U';\n                large.r += dr;\n            } else if (large.c != targetCol) {          // move right\n                act = 'R';\n                large.c += 1;\n            } else {                                    // drop on dispatch gate\n                grid[large.r][large.c] = large.holdId;\n                large.holding = false;\n                large.holdId = -1;\n                act = 'Q';\n            }\n        } else {\n            // not holding \u2013 pick the smallest waiting container\n            int bestRow = -1;\n            int bestId = INT_MAX;\n            for (int i = 0; i < N; ++i) {\n                if (grid[i][0] != -1 && grid[i][0] < bestId) {\n                    bestId = grid[i][0];\n                    bestRow = i;\n                }\n            }\n            if (bestRow == -1) {                        // nothing to do\n                act = '.';\n            } else {\n                if (large.r != bestRow) {               // vertical move\n                    int dr = (bestRow > large.r) ? 1 : -1;\n                    act = (dr == 1) ? 'D' : 'U';\n                    large.r += dr;\n                } else if (large.c != 0) {              // move left to column 0\n                    act = 'L';\n                    large.c -= 1;\n                } else {                                // pick up\n                    int cid = grid[large.r][large.c];\n                    large.holding = true;\n                    large.holdId = cid;\n                    grid[large.r][large.c] = -1;\n                    act = 'P';\n                }\n            }\n        }\n        out[0].push_back(act);\n\n        /* ---- step 3 : dispatch ---- */\n        for (int i = 0; i < N; ++i) {\n            int cid = grid[i][N - 1];\n            if (cid != -1) {\n                ++dispatched;\n                grid[i][N - 1] = -1;\n            }\n        }\n\n        ++turn;\n    }\n\n    // all rows must have the same length (pad with '.')\n    for (int i = 0; i < N; ++i) {\n        if ((int)out[i].size() < turn) out[i] += string(turn - out[i].size(), '.');\n        cout << out[i] << '\\n';\n    }\n    return 0;\n}","ahc034":"#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    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    // working copy of the heights\n    vector<vector<int>> rem = h;\n\n    int curR = 0, curC = 0;      // truck position\n    int load = 0;                // soil on the truck\n    vector<string> ops;          // list of operations\n\n    auto pushMove = [&](char dir) {\n        ops.emplace_back(string(1, dir));\n    };\n    auto pushLoad = [&](int d) {\n        ops.emplace_back(\"+\" + to_string(d));\n        load += d;\n    };\n    auto pushUnload = [&](int d) {\n        ops.emplace_back(\"-\" + to_string(d));\n        load -= d;\n    };\n\n    // move the truck to (tr,tc) along a Manhattan path\n    auto moveTo = [&](int tr, int tc) {\n        int dr = tr - curR;\n        int dc = tc - curC;\n        while (dr != 0) {\n            int step = (dr > 0) ? 1 : -1;\n            char dir = (dr > 0) ? 'D' : 'U';\n            pushMove(dir);\n            curR += step;\n            dr -= step;\n        }\n        while (dc != 0) {\n            int step = (dc > 0) ? 1 : -1;\n            char dir = (dc > 0) ? 'R' : 'L';\n            pushMove(dir);\n            curC += step;\n            dc -= step;\n        }\n    };\n\n    // find the nearest cell that satisfies a predicate\n    auto nearest = [&](auto pred) -> pair<int,int> {\n        int bestDist = INT_MAX;\n        pair<int,int> best(-1,-1);\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (!pred(i,j)) continue;\n                int dist = abs(i - curR) + abs(j - curC);\n                if (dist < bestDist) {\n                    bestDist = dist;\n                    best = {i,j};\n                }\n            }\n        }\n        return best;\n    };\n\n    while (true) {\n        // nearest hill (positive remaining height)\n        auto hill = nearest([&](int i,int j){ return rem[i][j] > 0; });\n        if (hill.first == -1) break;                 // no hill left -> finished\n\n        // go there and load everything\n        moveTo(hill.first, hill.second);\n        int d = rem[hill.first][hill.second];        // >0\n        pushLoad(d);\n        rem[hill.first][hill.second] = 0;\n\n        // deliver the whole load to holes\n        while (load > 0) {\n            auto hole = nearest([&](int i,int j){ return rem[i][j] < 0; });\n            // there must be a hole, otherwise the input would be inconsistent\n            moveTo(hole.first, hole.second);\n            int demand = -rem[hole.first][hole.second]; // positive\n            int unload = min(load, demand);\n            pushUnload(unload);\n            rem[hole.first][hole.second] += unload;    // still \u2264 0\n        }\n    }\n\n    // (optional) safety \u2013 should never be needed because sums are zero\n    while (load > 0) {\n        auto hole = nearest([&](int i,int j){ return rem[i][j] < 0; });\n        if (hole.first == -1) break;\n        moveTo(hole.first, hole.second);\n        int demand = -rem[hole.first][hole.second];\n        int unload = min(load, demand);\n        pushUnload(unload);\n        rem[hole.first][hole.second] += unload;\n    }\n\n    // output all operations\n    for (auto &s : ops) cout << s << '\\n';\n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int N = 6;               // fixed in the statement\n    const int M = 15;              // fixed in the statement\n    const int T = 10;              // fixed in the statement\n    const int SEED_CNT = 2 * N * (N - 1);   // 60\n    const int CELL_CNT = N * N;            // 36\n    const int EDGE_CNT = 2 * N * (N - 1);   // 60\n\n    // ---------- read initial data ----------\n    int tmpN, tmpM, tmpT;\n    if (!(cin >> tmpN >> tmpM >> tmpT)) return 0;\n    // the values are the same as the constants above, ignore them\n\n    vector<vector<int>> seed(SEED_CNT, vector<int>(M));\n    vector<int> seedSum(SEED_CNT, 0);\n    vector<int> X(M, 0);                 // per\u2011dimension maxima of the initial seeds\n\n    for (int i = 0; i < SEED_CNT; ++i) {\n        int s = 0;\n        for (int j = 0; j < M; ++j) {\n            int x; cin >> x;\n            seed[i][j] = x;\n            s += x;\n            X[j] = max(X[j], x);\n        }\n        seedSum[i] = s;\n    }\n\n    // build list of edges (neighbour pairs) once\n    vector<pair<int,int>> edges;\n    edges.reserve(EDGE_CNT);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            int p = i * N + j;\n            if (i + 1 < N) edges.emplace_back(p, (i + 1) * N + j);\n            if (j + 1 < N) edges.emplace_back(p, i * N + (j + 1));\n        }\n\n    // helper: best possible child of two seeds\n    auto best_possible = [&](int a, int b)->int{\n        int ret = 0;\n        const auto &A = seed[a];\n        const auto &B = seed[b];\n        for (int i = 0; i < M; ++i) ret += max(A[i], B[i]);\n        return ret;\n    };\n\n    // helper: evaluate a whole placement\n    // returns {total_sum_of_best , max_best}\n    auto evaluate = [&](const vector<int> &grid)->pair<int,int>{\n        int total = 0, mx = 0;\n        for (auto [u,v] : edges) {\n            int val = best_possible(grid[u], grid[v]);\n            total += val;\n            mx = max(mx, val);\n        }\n        return {total, mx};\n    };\n\n    // ---------- round loop ----------\n    for (int round = 0; round < T; ++round) {\n        // ---- choose the initial 36 seeds: the 36 with largest sum ----\n        vector<int> allIdx(SEED_CNT);\n        iota(allIdx.begin(), allIdx.end(), 0);\n        sort(allIdx.begin(), allIdx.end(),\n             [&](int a, int b){ return seedSum[a] > seedSum[b]; });\n        vector<int> selectedIdx(allIdx.begin(), allIdx.begin() + CELL_CNT);   // 36 seeds\n\n        // best placement found in this round\n        vector<int> bestGrid;\n        long long bestObj = -(1LL<<60);\n\n        // ---- several restarts of hill climbing ----\n        const int RESTARTS = 3;\n        const int ITERATIONS = 2000;\n        const int WEIGHT_MAX = 1000;          // max_best is multiplied by this\n\n        for (int rep = 0; rep < RESTARTS; ++rep) {\n            // current placement: random permutation of the 36 selected seeds\n            vector<int> grid = selectedIdx;\n            shuffle(grid.begin(), grid.end(), mt19937{ random_device{}() });\n\n            // current used / unused lists\n            vector<char> used(SEED_CNT, 0);\n            for (int id : grid) used[id] = 1;\n            vector<int> unused;\n            unused.reserve(SEED_CNT - CELL_CNT);\n            for (int i = 0; i < SEED_CNT; ++i) if (!used[i]) unused.push_back(i);\n\n            // evaluate starting placement\n            auto [totalSum, maxBest] = evaluate(grid);\n            long long curObj = (long long)maxBest * WEIGHT_MAX + totalSum;\n\n            // hill climbing\n            for (int it = 0; it < ITERATIONS; ++it) {\n                bool moveWithUnused = false;\n                if (!unused.empty() && (rand() % 2)) moveWithUnused = true;\n\n                if (moveWithUnused) {\n                    // exchange a planted seed with an unused one\n                    int pos = rand() % CELL_CNT;\n                    int oldSeed = grid[pos];\n                    int idx = rand() % unused.size();\n                    int newSeed = unused[idx];\n                    // temporarily place newSeed\n                    grid[pos] = newSeed;\n                    auto [newSum, newMax] = evaluate(grid);\n                    long long newObj = (long long)newMax * WEIGHT_MAX + newSum;\n                    if (newObj > curObj) {               // accept\n                        used[oldSeed] = 0;\n                        used[newSeed] = 1;\n                        unused[idx] = oldSeed;            // replace\n                        curObj = newObj;\n                        // totalSum, maxBest are already updated by evaluate\n                    } else {\n                        grid[pos] = oldSeed;               // revert\n                    }\n                } else {\n                    // swap two positions\n                    int p = rand() % CELL_CNT;\n                    int q = rand() % CELL_CNT;\n                    if (p == q) continue;\n                    swap(grid[p], grid[q]);\n                    auto [newSum, newMax] = evaluate(grid);\n                    long long newObj = (long long)newMax * WEIGHT_MAX + newSum;\n                    if (newObj > curObj) {               // accept\n                        curObj = newObj;\n                    } else {\n                        swap(grid[p], grid[q]);           // revert\n                    }\n                }\n            } // end of iterations\n\n            // keep the best placement among the restarts\n            if (curObj > bestObj) {\n                bestObj = curObj;\n                bestGrid = grid;\n            }\n        } // restarts\n\n        // ---- output the best grid ----\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (j) cout << ' ';\n                cout << bestGrid[i * N + j];\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n\n        // ---- read the children, they become the seed pool for the next round ----\n        for (int i = 0; i < SEED_CNT; ++i) {\n            int s = 0;\n            for (int j = 0; j < M; ++j) {\n                int x; cin >> x;\n                seed[i][j] = x;\n                s += x;\n            }\n            seedSum[i] = s;\n        }\n    } // round loop\n\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\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> s(N), t(N);\n    for (int i = 0; i < N; ++i) cin >> s[i];\n    for (int i = 0; i < N; ++i) cin >> t[i];\n\n    /* ----------------------------------------------------------\n       board description\n       ---------------------------------------------------------- */\n    vector<vector<char>> is_src(N, vector<char>(N, 0));\n    vector<vector<char>> is_tgt(N, vector<char>(N, 0));\n    vector<vector<char>> occupied(N, vector<char>(N, 0));\n    int src_rem = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            occupied[i][j] = (s[i][j] == '1');\n            if (s[i][j] == '1' && t[i][j] == '0') {\n                is_src[i][j] = 1;\n                ++src_rem;\n            }\n            if (t[i][j] == '1' && s[i][j] == '0') {\n                is_tgt[i][j] = 1;\n            }\n        }\n    }\n\n    /* ----------------------------------------------------------\n       arm geometry \u2013 we always use exactly 5 vertices\n       ---------------------------------------------------------- */\n    const int Vout = 5;                     // root + 4 leaves, always \u2264 V\n    const int C = 4;                        // number of useful leaves\n\n    // directions: 0 = east, 1 = north, 2 = west, 3 = south\n    const int dx[4] = {0, -1, 0, +1};\n    const int dy[4] = {+1, 0, -1, 0};\n\n    // leaf directions after the two initial rotation turns\n    vector<int> dir(C + 1, 0);               // 1\u2011based, initially all east\n    vector<char> loaded(C + 1, 0);           // initially empty\n    int loaded_cnt = 0;\n\n    // root initial position\n    int rx = 0, ry = 0;\n\n    /* ----------------------------------------------------------\n       output the designed tree\n       ---------------------------------------------------------- */\n    cout << Vout << '\\n';\n    for (int i = 1; i < Vout; ++i) cout << 0 << ' ' << 1 << '\\n';\n    cout << rx << ' ' << ry << '\\n';\n\n    /* ----------------------------------------------------------\n       containers for the operation strings\n       ---------------------------------------------------------- */\n    vector<string> ops;\n\n    /* ----------------------------------------------------------\n       first two turns \u2013 rotate three leaves to the remaining directions\n       ---------------------------------------------------------- */\n    // turn 0 : . L L R   (leaf 2,3,4 are rotated)\n    {\n        string op;\n        op.push_back('.');                 // root\n        op.push_back('.');                 // leaf 1\n        op.push_back('L');                 // leaf 2\n        op.push_back('L');                 // leaf 3\n        op.push_back('R');                 // leaf 4\n        for (int i = 0; i < Vout; ++i) op.push_back('.'); // actions\n        ops.push_back(op);\n        // apply rotations\n        dir[2] = (dir[2] + 1) & 3;          // L -> +1 (mod 4)\n        dir[3] = (dir[3] + 1) & 3;          // L\n        dir[4] = (dir[4] + 3) & 3;          // R -> +3 (mod 4)\n    }\n    // turn 1 : . . L .   (leaf 3 gets its second rotation)\n    {\n        string op;\n        op.push_back('.');                 // root\n        op.push_back('.');                 // leaf 1\n        op.push_back('.');                 // leaf 2\n        op.push_back('L');                 // leaf 3\n        op.push_back('.');                 // leaf 4\n        for (int i = 0; i < Vout; ++i) op.push_back('.');\n        ops.push_back(op);\n        // apply rotation\n        dir[3] = (dir[3] + 1) & 3;          // now leaf 3 points west\n    }\n\n    /* ----------------------------------------------------------\n       helper: evaluate a candidate root move\n       ---------------------------------------------------------- */\n    auto evaluate_move = [&](int nx, int ny, int &actions, int &dist, int mode) {\n        actions = 0;\n        // count possible actions\n        for (int i = 1; i <= C; ++i) {\n            int d = dir[i];\n            int cx = nx + dx[d];\n            int cy = ny + dy[d];\n            if (cx < 0 || cx >= N || cy < 0 || cy >= N) continue;\n            if (!loaded[i] && is_src[cx][cy] && occupied[cx][cy]) ++actions;\n            else if (loaded[i] && is_tgt[cx][cy] && !occupied[cx][cy]) ++actions;\n        }\n\n        // distance to the nearest still needed square (mode: 0 = pickup, 1 = delivery)\n        dist = INF;\n        if (mode == 0) { // pickup\n            for (int i = 0; i < N; ++i)\n                for (int j = 0; j < N; ++j)\n                    if (is_src[i][j] && occupied[i][j])\n                        for (int d = 0; d < 4; ++d) {\n                            int ni = i + dx[d];\n                            int nj = j + dy[d];\n                            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                            int ddist = abs(nx - ni) + abs(ny - nj);\n                            dist = min(dist, ddist);\n                        }\n        } else if (mode == 1) { // delivery\n            for (int i = 0; i < N; ++i)\n                for (int j = 0; j < N; ++j)\n                    if (is_tgt[i][j] && !occupied[i][j])\n                        for (int d = 0; d < 4; ++d) {\n                            int ni = i + dx[d];\n                            int nj = j + dy[d];\n                            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                            int ddist = abs(nx - ni) + abs(ny - nj);\n                            dist = min(dist, ddist);\n                        }\n        }\n    };\n\n    /* ----------------------------------------------------------\n       main simulation loop \u2013 stop after 100\u202f000 turns\n       ---------------------------------------------------------- */\n    const vector<char> move_chars = {'U','D','L','R','.'};\n    const vector<int> mv_dx = {-1, +1, 0, 0, 0};\n    const vector<int> mv_dy = {0, 0, -1, +1, 0};\n\n    while ((src_rem > 0 || loaded_cnt > 0) && (int)ops.size() < 100000) {\n        // decide the current mode\n        bool have_empty = false;\n        for (int i = 1; i <= C; ++i) if (!loaded[i]) { have_empty = true; break; }\n        int mode = -1;  // 0 = pickup, 1 = delivery\n        if (src_rem > 0 && have_empty) mode = 0;\n        else if (loaded_cnt > 0) mode = 1;\n        else break; // finished\n\n        // try all five possible root moves\n        int best_move = -1, best_actions = -1, best_dist = INF;\n        for (int m = 0; m < 5; ++m) {\n            char mc = move_chars[m];\n            int nx = rx + mv_dx[m];\n            int ny = ry + mv_dy[m];\n            if (mc != '.' && (nx < 0 || nx >= N || ny < 0 || ny >= N)) continue;\n            int actions, dist;\n            evaluate_move(nx, ny, actions, dist, mode);\n            if (actions > best_actions ||\n                (actions == best_actions && dist < best_dist)) {\n                best_move = m;\n                best_actions = actions;\n                best_dist = dist;\n            }\n        }\n        // if nothing is possible, still move the root somewhere (any legal move)\n        if (best_move == -1) {\n            for (int m = 0; m < 5; ++m) {\n                char mc = move_chars[m];\n                int nx = rx + mv_dx[m];\n                int ny = ry + mv_dy[m];\n                if (mc != '.' && (nx < 0 || nx >= N || ny < 0 || ny >= N)) continue;\n                best_move = m; break;\n            }\n        }\n\n        // apply the chosen move and build the operation string\n        char mv = move_chars[best_move];\n        int nx = rx + mv_dx[best_move];\n        int ny = ry + mv_dy[best_move];\n        string op;\n        op.push_back(mv);                     // root movement\n        for (int i = 1; i < Vout; ++i) op.push_back('.'); // no rotations\n\n        // actions \u2013 root never acts\n        op.push_back('.');\n        for (int i = 1; i <= C; ++i) {\n            int d = dir[i];\n            int cx = nx + dx[d];\n            int cy = ny + dy[d];\n            bool can = false;\n            if (!loaded[i] && cx >= 0 && cx < N && cy >= 0 && cy < N &&\n                is_src[cx][cy] && occupied[cx][cy]) can = true;\n            else if (loaded[i] && cx >= 0 && cx < N && cy >= 0 && cy < N &&\n                     is_tgt[cx][cy] && !occupied[cx][cy]) can = true;\n\n            if (can) {\n                op.push_back('P');\n                if (!loaded[i]) { // pick\n                    occupied[cx][cy] = 0;\n                    loaded[i] = 1;\n                    --src_rem;\n                    ++loaded_cnt;\n                } else { // deliver\n                    occupied[cx][cy] = 1;\n                    loaded[i] = 0;\n                    --loaded_cnt;\n                }\n            } else {\n                op.push_back('.');\n            }\n        }\n        ops.push_back(op);\n        // update root position\n        rx = nx; ry = ny;\n    }\n\n    // ----- output all operation strings -----\n    for (const string &s : ops) cout << s << '\\n';\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int x, y;          // original coordinates\n    int xi, yi;        // compressed indices\n    int w;             // +1 for mackerel, -1 for sardine\n};\n\nstruct Node {\n    int sum;           // total sum of interval\n    int pref;          // max prefix sum (non empty)\n    int pref_r;        // right end of that prefix\n    int suff;          // max suffix sum (non empty)\n    int suff_l;        // left start of that suffix\n    int best;          // max sub\u2011array sum (non empty)\n    int best_l, best_r;// borders of that sub\u2011array\n};\n\nstatic inline Node combine(const Node &L, const Node &R) {\n    Node C;\n    C.sum = L.sum + R.sum;\n\n    // prefix\n    if (L.pref > L.sum + R.pref) {\n        C.pref = L.pref;\n        C.pref_r = L.pref_r;\n    } else {\n        C.pref = L.sum + R.pref;\n        C.pref_r = R.pref_r;\n    }\n\n    // suffix\n    if (R.suff > R.sum + L.suff) {\n        C.suff = R.suff;\n        C.suff_l = R.suff_l;\n    } else {\n        C.suff = R.sum + L.suff;\n        C.suff_l = L.suff_l;\n    }\n\n    // best\n    C.best = L.best;\n    C.best_l = L.best_l;\n    C.best_r = L.best_r;\n\n    if (R.best > C.best) {\n        C.best = R.best;\n        C.best_l = R.best_l;\n        C.best_r = R.best_r;\n    }\n\n    int cross = L.suff + R.pref;\n    if (cross > C.best) {\n        C.best = cross;\n        C.best_l = L.suff_l;\n        C.best_r = R.pref_r;\n    }\n    return 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<Point> pts;\n    pts.reserve(2 * N);\n    vector<int> xs, ys;\n    for (int i = 0; i < 2 * N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        pts.push_back({x, y, -1, -1, (i < N ? +1 : -1)});\n        xs.push_back(x);\n        ys.push_back(y);\n    }\n\n    // coordinate compression\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    int X = (int)xs.size();\n    int Y = (int)ys.size();\n\n    for (auto &p : pts) {\n        p.xi = lower_bound(xs.begin(), xs.end(), p.x) - xs.begin();\n        p.yi = lower_bound(ys.begin(), ys.end(), p.y) - ys.begin();\n    }\n\n    // points per column\n    vector<vector<pair<int,int>>> byX(X);   // (y_idx , weight)\n    for (const auto &p : pts) {\n        byX[p.xi].push_back({p.yi, p.w});\n    }\n\n    // segment tree for y\u2011direction\n    int M = 1;\n    while (M < Y) M <<= 1;\n    vector<Node> seg(2 * M);\n\n    auto tree_build = [&]() {\n        for (int i = 0; i < Y; ++i) {\n            seg[M + i].sum = 0;\n            seg[M + i].pref = seg[M + i].suff = seg[M + i].best = 0;\n            seg[M + i].pref_r = seg[M + i].suff_l = seg[M + i].best_l = seg[M + i].best_r = i;\n        }\n        for (int i = Y; i < M; ++i) {\n            seg[M + i].sum = 0;\n            seg[M + i].pref = seg[M + i].suff = seg[M + i].best = 0;\n            seg[M + i].pref_r = seg[M + i].suff_l = seg[M + i].best_l = seg[M + i].best_r = i;\n        }\n        for (int i = M - 1; i >= 1; --i)\n            seg[i] = combine(seg[i << 1], seg[i << 1 | 1]);\n    };\n\n    auto tree_reset = [&]() {\n        for (int i = 0; i < Y; ++i) {\n            seg[M + i].sum = 0;\n            seg[M + i].pref = seg[M + i].suff = seg[M + i].best = 0;\n            // positions stay unchanged\n        }\n        for (int i = M - 1; i >= 1; --i)\n            seg[i] = combine(seg[i << 1], seg[i << 1 | 1]);\n    };\n\n    auto tree_add = [&](int y_idx, int delta) {\n        int p = M + y_idx;\n        seg[p].sum += delta;\n        int ns = seg[p].sum;\n        seg[p].pref = seg[p].suff = seg[p].best = ns;\n        // the indices already stored for the leaf stay correct\n        for (p >>= 1; p; p >>= 1)\n            seg[p] = combine(seg[p << 1], seg[p << 1 | 1]);\n    };\n\n    // sweep\n    int bestValue = -1;          // -1 means \u201cnot found\u201d\n    int best_left = -1, best_right = -1;\n    int best_bottom = -1, best_top = -1;\n\n    for (int left = 0; left < X; ++left) {\n        tree_reset();\n        for (int right = left; right < X; ++right) {\n            // add column 'right'\n            for (auto &pr : byX[right]) {\n                tree_add(pr.first, pr.second);\n            }\n            const Node &root = seg[1];\n            int cur = root.best;\n            if (cur > bestValue) {\n                bestValue = cur;\n                best_left = left;\n                best_right = right;\n                best_bottom = root.best_l;\n                best_top    = root.best_r;\n            }\n        }\n    }\n\n    // -----------------------------------------------------------------\n    // build the final rectangle\n    int leftX, rightX, bottomY, topY;\n    // arrays to know which coordinates are occupied (for the \u201cempty\u201d extension)\n    vector<char> usedX(100001, 0), usedY(100001, 0);\n    for (auto &p : pts) {\n        usedX[p.x] = 1;\n        usedY[p.y] = 1;\n    }\n\n    auto unused_coord = [&](const vector<char> &used, int after) {\n        for (int v = after + 1; v <= 100000; ++v)\n            if (!used[v]) return v;\n        for (int v = after - 1; v >= 0; --v)\n            if (!used[v]) return v;\n        return -1; // never happens\n    };\n\n    if (bestValue <= 0) {               // no positive rectangle \u2013 use empty one\n        // pick two unused x\u2011coordinates and two unused y\u2011coordinates\n        int ux1 = -1, ux2 = -1;\n        for (int x = 0; x <= 100000; ++x) if (!usedX[x]) { ux1 = x; break; }\n        for (int x = ux1 + 1; x <= 100000; ++x) if (!usedX[x]) { ux2 = x; break; }\n        int uy1 = -1, uy2 = -1;\n        for (int y = 0; y <= 100000; ++y) if (!usedY[y]) { uy1 = y; break; }\n        for (int y = uy1 + 1; y <= 100000; ++y) if (!usedY[y]) { uy2 = y; break; }\n        leftX = ux1; rightX = ux2;\n        bottomY = uy1; topY = uy2;\n    } else {\n        leftX   = xs[best_left];\n        rightX  = xs[best_right];\n        bottomY = ys[best_bottom];\n        topY    = ys[best_top];\n\n        // ensure width > 0, height > 0 using only empty columns / rows\n        if (leftX == rightX) {\n            int nx = unused_coord(usedX, leftX);\n            if (nx > leftX) rightX = nx;\n            else {\n                rightX = leftX;\n                leftX = nx;\n            }\n        }\n        if (bottomY == topY) {\n            int ny = unused_coord(usedY, bottomY);\n            if (ny > bottomY) topY = ny;\n            else {\n                topY = bottomY;\n                bottomY = ny;\n            }\n        }\n    }\n\n    // -----------------------------------------------------------------\n    // output the rectangle (counter\u2011clockwise order)\n    cout << 4 << \"\\n\";\n    cout << leftX   << \" \" << bottomY << \"\\n\";\n    cout << leftX   << \" \" << topY    << \"\\n\";\n    cout << rightX  << \" \" << topY    << \"\\n\";\n    cout << rightX  << \" \" << bottomY << \"\\n\";\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rectangle {\n    int width, height;\n    int x, y; // top-left corner\n};\n\nstruct Placement {\n    int p; // index\n    int r; // rotation\n    char d; // direction 'U' or 'L'\n    int b; // reference rectangle index\n};\n\nclass Packer {\nprivate:\n    int N;\n    vector<int> w, h;\n    vector<Rectangle> placed;\n    vector<Placement> sequence;\n    \n    // Check if two rectangles overlap\n    bool overlap(const Rectangle& a, const Rectangle& b) {\n        return a.x < b.x + b.width && a.x + a.width > b.x &&\n               a.y < b.y + b.height && a.y + a.height > b.y;\n    }\n    \n    // Simulate placing a rectangle with given parameters\n    // Returns the rectangle with final position\n    Rectangle simulatePlace(int idx, int rot, char dir, int ref) {\n        int width = (rot == 0) ? w[idx] : h[idx];\n        int height = (rot == 0) ? h[idx] : w[idx];\n        \n        Rectangle rect;\n        rect.width = width;\n        rect.height = height;\n        \n        if (dir == 'U') {\n            // Align left edge\n            if (ref == -1) {\n                rect.x = 0;\n            } else {\n                rect.x = placed[ref].x + placed[ref].width;\n            }\n            \n            // Start from bottom and slide up (decrease y)\n            // Find the highest position where it doesn't overlap\n            int best_y = 0;\n            // Check all placed rectangles\n            for (const auto& other : placed) {\n                // Check horizontal overlap\n                if (rect.x < other.x + other.width && rect.x + rect.width > other.x) {\n                    // This rectangle blocks upward movement\n                    best_y = max(best_y, other.y + other.height);\n                }\n            }\n            rect.y = best_y;\n        } else { // 'L'\n            // Align top edge\n            if (ref == -1) {\n                rect.y = 0;\n            } else {\n                rect.y = placed[ref].y + placed[ref].height;\n            }\n            \n            // Start from far right and slide left (decrease x)\n            int best_x = 0;\n            // Check all placed rectangles\n            for (const auto& other : placed) {\n                // Check vertical overlap\n                if (rect.y < other.y + other.height && rect.y + rect.height > other.y) {\n                    // This rectangle blocks leftward movement\n                    best_x = max(best_x, other.x + other.width);\n                }\n            }\n            rect.x = best_x;\n        }\n        \n        return rect;\n    }\n    \npublic:\n    Packer(const vector<int>& w, const vector<int>& h) \n        : N(w.size()), w(w), h(h) {}\n    \n    // Generate a random placement sequence\n    pair<vector<Placement>, long long> generateRandom(mt19937& rng) {\n        placed.clear();\n        sequence.clear();\n        \n        // Randomly decide which rectangles to place\n        // For now, try to place all\n        vector<int> placed_indices;\n        long long totalWH = 0;\n        \n        for (int i = 0; i < N; i++) {\n            // Randomly decide to place or skip\n            uniform_real_distribution<double> dist(0.0, 1.0);\n            bool place = dist(rng) < 0.9; // 90% chance to place\n            \n            if (!place) {\n                totalWH += w[i] + h[i];\n                continue;\n            }\n            \n            // Random rotation, direction, reference\n            uniform_int_distribution<int> rot_dist(0, 1);\n            uniform_int_distribution<int> dir_dist(0, 1);\n            uniform_int_distribution<int> ref_dist(-1, (int)placed_indices.size() - 1);\n            \n            int r = rot_dist(rng);\n            char d = (dir_dist(rng) == 0) ? 'U' : 'L';\n            int b = ref_dist(rng);\n            \n            // Simulate placement\n            Rectangle rect = simulatePlace(i, r, d, b);\n            \n            // Check for overlap (shouldn't happen with our algorithm)\n            bool overlaps = false;\n            for (const auto& other : placed) {\n                if (overlap(rect, other)) {\n                    overlaps = true;\n                    break;\n                }\n            }\n            \n            if (overlaps) {\n                // Fallback: skip this rectangle\n                totalWH += w[i] + h[i];\n                continue;\n            }\n            \n            // Add to placed\n            placed.push_back(rect);\n            placed_indices.push_back(i);\n            \n            // Record placement\n            Placement p;\n            p.p = i;\n            p.r = r;\n            p.d = d;\n            p.b = b;\n            sequence.push_back(p);\n        }\n        \n        // Calculate bounding box\n        int maxX = 0, maxY = 0;\n        for (const auto& rect : placed) {\n            maxX = max(maxX, rect.x + rect.width);\n            maxY = max(maxY, rect.y + rect.height);\n        }\n        \n        long long score = (long long)maxX + maxY + totalWH;\n        return {sequence, score};\n    }\n    \n    // Generate a greedy placement sequence\n    pair<vector<Placement>, long long> generateGreedy() {\n        placed.clear();\n        sequence.clear();\n        long long totalWH = 0;\n        \n        for (int i = 0; i < N; i++) {\n            // Try to place rectangle i\n            int best_r = 0;\n            char best_d = 'U';\n            int best_b = -1;\n            long long bestScore = LLONG_MAX;\n            Rectangle bestRect;\n            \n            // Try all combinations\n            for (int r = 0; r <= 1; r++) {\n                for (char d : {'U', 'L'}) {\n                    // Try references: -1 and all previously placed\n                    vector<int> refs;\n                    refs.push_back(-1);\n                    for (int j = 0; j < (int)placed.size(); j++) {\n                        refs.push_back(j);\n                    }\n                    \n                    for (int b : refs) {\n                        Rectangle rect = simulatePlace(i, r, d, b);\n                        \n                        // Check overlap\n                        bool overlaps = false;\n                        for (const auto& other : placed) {\n                            if (overlap(rect, other)) {\n                                overlaps = true;\n                                break;\n                            }\n                        }\n                        if (overlaps) continue;\n                        \n                        // Calculate new bounding box with this rectangle\n                        int maxX = 0, maxY = 0;\n                        for (const auto& p : placed) {\n                            maxX = max(maxX, p.x + p.width);\n                            maxY = max(maxY, p.y + p.height);\n                        }\n                        maxX = max(maxX, rect.x + rect.width);\n                        maxY = max(maxY, rect.y + rect.height);\n                        \n                        long long score = (long long)maxX + maxY;\n                        \n                        if (score < bestScore) {\n                            bestScore = score;\n                            best_r = r;\n                            best_d = d;\n                            best_b = b;\n                            bestRect = rect;\n                        }\n                    }\n                }\n            }\n            \n            // Decide whether to place or skip\n            // Calculate current bounding box\n            int curMaxX = 0, curMaxY = 0;\n            for (const auto& p : placed) {\n                curMaxX = max(curMaxX, p.x + p.width);\n                curMaxY = max(curMaxY, p.y + p.height);\n            }\n            long long curScore = (long long)curMaxX + curMaxY;\n            \n            if (bestScore > curScore + w[i] + h[i]) {\n                // Skip this rectangle\n                totalWH += w[i] + h[i];\n            } else {\n                // Place it\n                placed.push_back(bestRect);\n                Placement p;\n                p.p = i;\n                p.r = best_r;\n                p.d = best_d;\n                p.b = best_b;\n                sequence.push_back(p);\n            }\n        }\n        \n        // Calculate final bounding box\n        int maxX = 0, maxY = 0;\n        for (const auto& rect : placed) {\n            maxX = max(maxX, rect.x + rect.width);\n            maxY = max(maxY, rect.y + rect.height);\n        }\n        \n        long long score = (long long)maxX + maxY + totalWH;\n        return {sequence, score};\n    }\n    \n    // Get the best sequence found so far (for repeated output)\n    const vector<Placement>& getBestSequence() const {\n        return sequence;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, T, sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n    \n    vector<int> w(N), h(N);\n    for (int i = 0; i < N; i++) {\n        cin >> w[i] >> h[i];\n    }\n    \n    Packer packer(w, h);\n    \n    // Random number generator\n    random_device rd;\n    mt19937 rng(rd());\n    \n    // Try to find a good solution first\n    long long bestScore = LLONG_MAX;\n    vector<Placement> bestSequence;\n    \n    // Spend some time finding a good solution\n    // We'll try greedy first\n    auto [greedySeq, greedyScore] = packer.generateGreedy();\n    if (greedyScore < bestScore) {\n        bestScore = greedyScore;\n        bestSequence = greedySeq;\n    }\n    \n    // Then try random improvements\n    int attempts = min(T, 50); // Use up to 50 attempts for search\n    for (int attempt = 0; attempt < attempts; attempt++) {\n        auto [seq, score] = packer.generateRandom(rng);\n        if (score < bestScore) {\n            bestScore = score;\n            bestSequence = seq;\n        }\n    }\n    \n    // Output placements for each turn\n    for (int turn = 0; turn < T; turn++) {\n        // Output best sequence we found\n        cout << bestSequence.size() << \"\\n\";\n        for (const auto& p : bestSequence) {\n            cout << p.p << \" \" << p.r << \" \" << p.d << \" \" << p.b << \"\\n\";\n        }\n        cout << flush;\n        \n        // Read measured W' and H'\n        int Wp, Hp;\n        cin >> Wp >> Hp;\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Tree {\n    int N;                                 // number of vertices\n    int H;                                 // maximal depth (given as 10)\n    const vector<int> &A;                  // beauty values\n    const vector<vector<int>> &adj;        // graph\n    long long sumAAll;                     // \u03a3 A[v]  (constant part of score)\n\n    vector<int> parent;                    // parent[v]  ( -1 for a root )\n    vector<int> depth;                     // depth[v]   (0 \u2026 H)\n    vector<int> sumA;                      // S[v]  \u2013 sum of beauties in subtree\n    vector<int> high;                      // H[v]  \u2013 longest distance to a leaf\n    vector<vector<int>> children;          // children of each vertex\n    long long totalDepthSum;               // \u03a3 depth[v] * A[v]\n\n    // ---------- constructor (all roots) ----------\n    Tree(int N_, int H_, const vector<int> &A_, const vector<vector<int>> &adj_)\n        : N(N_), H(H_), A(A_), adj(adj_) {\n        sumAAll = 0;\n        for (int x : A) sumAAll += x;\n        parent.assign(N, -1);\n        depth.assign(N, 0);\n        sumA = A;                 // each subtree consists only of the vertex itself\n        high.assign(N, 0);\n        children.assign(N, {});\n        totalDepthSum = 0;\n    }\n\n    // ---------- utility ----------\n    bool isDescendant(int anc, int desc) const {\n        int cur = desc;\n        while (cur != -1) {\n            if (cur == anc) return true;\n            cur = parent[cur];\n        }\n        return false;\n    }\n\n    void detach(int v) {\n        int p = parent[v];\n        if (p != -1) {\n            auto &vec = children[p];\n            for (size_t i = 0; i < vec.size(); ++i) {\n                if (vec[i] == v) {\n                    vec.erase(vec.begin() + i);\n                    break;\n                }\n            }\n        }\n        parent[v] = -1;                 // v becomes a root of its own tree\n    }\n\n    void attach(int v, int newParent) {\n        parent[v] = newParent;\n        if (newParent != -1) children[newParent].push_back(v);\n    }\n\n    void applyDepthDelta(int v, int delta) {\n        depth[v] += delta;\n        for (int c : children[v]) applyDepthDelta(c, delta);\n    }\n\n    // recompute sumA and high on the path from v upwards (at most H steps)\n    void recomputeUpward(int v) {\n        while (v != -1) {\n            int s = A[v];\n            int h = 0;\n            for (int c : children[v]) {\n                s += sumA[c];\n                h = max(h, high[c] + 1);\n            }\n            sumA[v] = s;\n            high[v] = h;\n            v = parent[v];\n        }\n    }\n\n    // evaluate a possible move of subtree v to newParent ( -1 = root )\n    // returns {newDepth, gain}  ; gain = -inf if illegal\n    pair<int,long long> evaluateMove(int v, int newParent) const {\n        if (newParent == parent[v]) return {depth[v], 0};          // no change\n        if (newParent != -1 && isDescendant(v, newParent))\n            return {0, LLONG_MIN};                               // would create a cycle\n\n        int newDepth = (newParent == -1 ? 0 : depth[newParent] + 1);\n        if (newDepth + high[v] > H) return {0, LLONG_MIN};       // height violation\n\n        long long delta = (long long)newDepth - (long long)depth[v];\n        long long gain = delta * (long long)sumA[v];\n        return {newDepth, gain};\n    }\n\n    // really perform a move (already known to be legal)\n    void performMove(int v, int newParent, int newDepth) {\n        int oldParent = parent[v];\n        int oldDepth  = depth[v];\n\n        // detach\n        detach(v);\n        if (oldParent != -1) recomputeUpward(oldParent);\n\n        // attach to new parent\n        attach(v, newParent);\n\n        // shift depths inside the whole subtree\n        int delta = newDepth - oldDepth;\n        if (delta != 0) applyDepthDelta(v, delta);\n\n        // recompute sums on the new side\n        if (newParent != -1) recomputeUpward(newParent);\n        else                 recomputeUpward(v);\n\n        totalDepthSum += (long long)delta * (long long)sumA[v];\n    }\n\n    // ---------- greedy hill climbing ----------\n    void greedyPhase(mt19937 &rng, int maxPasses = 30) {\n        bool improved = true;\n        int passes = 0;\n        while (improved && passes < maxPasses) {\n            improved = false;\n            vector<int> order(N);\n            iota(order.begin(), order.end(), 0);\n            shuffle(order.begin(), order.end(), rng);\n            for (int v : order) {\n                int bestParent = -2;\n                int bestDepth  = depth[v];\n                long long bestGain = 0;\n                // try all neighbours\n                for (int u : adj[v]) {\n                    if (u == parent[v]) continue;\n                    auto [newDepth, gain] = evaluateMove(v, u);\n                    if (gain > bestGain) {\n                        bestGain = gain;\n                        bestParent = u;\n                        bestDepth  = newDepth;\n                    }\n                }\n                // also try becoming a root (gain is never positive here)\n                if (bestGain > 0) {\n                    performMove(v, bestParent, bestDepth);\n                    improved = true;\n                }\n            }\n            ++passes;\n        }\n    }\n\n    // ---------- simulated annealing ----------\n    void annealingPhase(mt19937 &rng, double timeLimit) {\n        const double START_TEMP = 2e6;          // a bit larger than maximal possible gain\n        const double END_TEMP   = 1.0;\n        auto start = chrono::steady_clock::now();\n\n        double temp = START_TEMP;\n        uniform_int_distribution<int> VertDist(0, N - 1);\n        uniform_real_distribution<double> ProbDist(0.0, 1.0);\n\n        // iterate until the time budget is exhausted\n        while (true) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - start).count();\n            if (elapsed > timeLimit) break;\n\n            // cooling schedule \u2013 exponential, slower than linear\n            double progress = elapsed / timeLimit;                 // 0 \u2026 1\n            temp = START_TEMP * pow(END_TEMP / START_TEMP, progress);\n\n            int v = VertDist(rng);\n            if (adj[v].empty()) continue;   // never happens (graph is connected)\n\n            // with probability 0.25 try to make the vertex a root,\n            // otherwise pick a random neighbour as new parent\n            int newParent;\n            if (ProbDist(rng) < 0.25) {\n                newParent = -1;\n            } else {\n                int idx = uniform_int_distribution<int>(0, (int)adj[v].size() - 1)(rng);\n                newParent = adj[v][idx];\n            }\n\n            auto [newDepth, gain] = evaluateMove(v, newParent);\n            if (gain == LLONG_MIN) continue;   // illegal\n\n            bool accept = false;\n            if (gain > 0) accept = true;\n            else if (temp > 1e-12) {\n                double prob = exp(gain / temp);\n                if (prob > ProbDist(rng)) accept = true;\n            }\n            if (!accept) continue;\n\n            performMove(v, newParent, newDepth);\n        }\n    }\n\n    long long totalScore() const {\n        return sumAAll + totalDepthSum;\n    }\n};\n\n// -----------------------------------------------------------------------\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, H;\n    if (!(cin >> N >> M >> H)) return 0;\n\n    vector<int> A(N);\n    for (int i = 0; i < N; ++i) cin >> A[i];\n\n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; ++i) {\n        int u, v; cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    // read and discard coordinates\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n    }\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    long long bestScore = 0;\n    vector<int> bestParent(N, -1);\n    {\n        Tree tree(N, H, A, adj);\n        bestScore = tree.totalScore();\n        bestParent = tree.parent;\n    }\n\n    auto start = chrono::steady_clock::now();\n\n    // ---- several restarts (as long as time permits) ----\n    int rounds = 0;\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > 1.85) break;          // total time limit\n\n        Tree tree(N, H, A, adj);\n        tree.greedyPhase(rng, 30);           // up to 30 passes\n\n        // a short but intensive annealing phase\n        double timeLeft = 1.85 - elapsed;\n        if (timeLeft > 0.3) {\n            tree.annealingPhase(rng, timeLeft * 0.75);\n            // final polishing greedy pass\n            tree.greedyPhase(rng, 10);\n        }\n\n        long long cur = tree.totalScore();\n        if (cur > bestScore) {\n            bestScore = cur;\n            bestParent = tree.parent;\n        }\n        ++rounds;\n    }\n\n    // ---------------------------------------------------------------\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << bestParent[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Oni {\n    int i, j;                 // position\n    bool upSafe, downSafe, leftSafe, rightSafe;\n    int upDist, downDist, leftDist, rightDist;\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<string> board(N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n\n    const int INF = 1e9;\n\n    // -----------------------------------------------------------------\n    // locate Oni and Fuku, compute safety flags\n    vector<Oni> onis;\n    vector<vector<bool>> fuku(N, vector<bool>(N, false));\n    vector<vector<bool>> isOni(N, vector<bool>(N, false));\n\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (board[i][j] == 'o') fuku[i][j] = true;\n            else if (board[i][j] == 'x') isOni[i][j] = true;\n\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (isOni[i][j]) {\n                Oni o;\n                o.i = i; o.j = j;\n                // distances\n                o.upDist    = i + 1;\n                o.downDist  = N - i;\n                o.leftDist  = j + 1;\n                o.rightDist = N - j;\n\n                // safety flags\n                o.upSafe = true;\n                for (int ii = 0; ii < i; ++ii) if (fuku[ii][j]) { o.upSafe = false; break; }\n\n                o.downSafe = true;\n                for (int ii = i + 1; ii < N; ++ii) if (fuku[ii][j]) { o.downSafe = false; break; }\n\n                o.leftSafe = true;\n                for (int jj = 0; jj < j; ++jj) if (fuku[i][jj]) { o.leftSafe = false; break; }\n\n                o.rightSafe = true;\n                for (int jj = j + 1; jj < N; ++jj) if (fuku[i][jj]) { o.rightSafe = false; break; }\n\n                onis.push_back(o);\n            }\n\n    const int M = (int)onis.size();               // = 2*N\n\n    // -----------------------------------------------------------------\n    // helper: simulate one ordering, produce move list and its length\n    auto simulate = [&](bool columnsFirst) -> pair<int, vector<pair<char,int>>> {\n        vector<bool> removed(M, false);\n        vector<pair<char,int>> moves;\n        // helper lambda: add a block of identical moves\n        auto addBlock = [&](char dir, int idx, int cnt){\n            for (int k = 0; k < cnt; ++k) moves.emplace_back(dir, idx);\n        };\n\n        if (columnsFirst) {\n            // ----- columns first (up, then down) -----\n            for (int col = 0; col < N; ++col) {\n                // up\u2011safe Oni of this column\n                int dmax = 0;\n                for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].j == col && onis[id].upSafe)\n                    dmax = max(dmax, onis[id].upDist);\n                if (dmax > 0) {\n                    addBlock('U', col, dmax);\n                    addBlock('D', col, dmax);\n                    // mark them removed\n                    for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].j == col && onis[id].upSafe)\n                        removed[id] = true;\n                }\n                // down\u2011safe Oni still in this column\n                dmax = 0;\n                for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].j == col && onis[id].downSafe)\n                    dmax = max(dmax, onis[id].downDist);\n                if (dmax > 0) {\n                    addBlock('D', col, dmax);\n                    addBlock('U', col, dmax);\n                    for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].j == col && onis[id].downSafe)\n                        removed[id] = true;\n                }\n            }\n            // ----- rows second (left, then right) -----\n            for (int row = 0; row < N; ++row) {\n                // left\u2011safe Oni of this row\n                int dmax = 0;\n                for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].i == row && onis[id].leftSafe)\n                    dmax = max(dmax, onis[id].leftDist);\n                if (dmax > 0) {\n                    addBlock('L', row, dmax);\n                    addBlock('R', row, dmax);\n                    for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].i == row && onis[id].leftSafe)\n                        removed[id] = true;\n                }\n                // right\u2011safe Oni still in this row\n                dmax = 0;\n                for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].i == row && onis[id].rightSafe)\n                    dmax = max(dmax, onis[id].rightDist);\n                if (dmax > 0) {\n                    addBlock('R', row, dmax);\n                    addBlock('L', row, dmax);\n                    for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].i == row && onis[id].rightSafe)\n                        removed[id] = true;\n                }\n            }\n        } else {\n            // ----- rows first (left, then right) -----\n            for (int row = 0; row < N; ++row) {\n                int dmax = 0;\n                for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].i == row && onis[id].leftSafe)\n                    dmax = max(dmax, onis[id].leftDist);\n                if (dmax > 0) {\n                    addBlock('L', row, dmax);\n                    addBlock('R', row, dmax);\n                    for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].i == row && onis[id].leftSafe)\n                        removed[id] = true;\n                }\n                dmax = 0;\n                for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].i == row && onis[id].rightSafe)\n                    dmax = max(dmax, onis[id].rightDist);\n                if (dmax > 0) {\n                    addBlock('R', row, dmax);\n                    addBlock('L', row, dmax);\n                    for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].i == row && onis[id].rightSafe)\n                        removed[id] = true;\n                }\n            }\n            // ----- columns second (up, then down) -----\n            for (int col = 0; col < N; ++col) {\n                int dmax = 0;\n                for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].j == col && onis[id].upSafe)\n                    dmax = max(dmax, onis[id].upDist);\n                if (dmax > 0) {\n                    addBlock('U', col, dmax);\n                    addBlock('D', col, dmax);\n                    for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].j == col && onis[id].upSafe)\n                        removed[id] = true;\n                }\n                dmax = 0;\n                for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].j == col && onis[id].downSafe)\n                    dmax = max(dmax, onis[id].downDist);\n                if (dmax > 0) {\n                    addBlock('D', col, dmax);\n                    addBlock('U', col, dmax);\n                    for (int id = 0; id < M; ++id) if (!removed[id] && onis[id].j == col && onis[id].downSafe)\n                        removed[id] = true;\n                }\n            }\n        }\n\n        // all Oni must be removed now\n        int remaining = 0;\n        for (bool b : removed) if (!b) ++remaining;\n        // (remaining should be 0, otherwise the input violated the promise)\n\n        return { (int)moves.size(), moves };\n    };\n\n    // -----------------------------------------------------------------\n    // evaluate both orders\n    auto [len1, moves1] = simulate(true);   // columns first\n    auto [len2, moves2] = simulate(false);  // rows first\n\n    const vector<pair<char,int>>& bestMoves = (len1 <= len2) ? moves1 : moves2;\n\n    // -----------------------------------------------------------------\n    // output the chosen sequence\n    for (auto [dir, idx] : bestMoves) {\n        cout << dir << ' ' << idx << '\\n';\n    }\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    \n    const int N = 100;\n    const long long L = 500000;\n    const long long AVG = L / N; // 5000\n    const long long STEP = 2500;  // Half of average\n    \n    vector<long long> T(N);\n    int n_input;\n    long long l_input;\n    if (!(cin >> n_input >> l_input)) return 0;\n    for (int i = 0; i < N; ++i) {\n        cin >> T[i];\n    }\n    \n    const long long INF = (1LL << 60);\n    long long best_error = INF;\n    vector<int> best_x(N);\n    \n    // Try both possible values for x_0\n    for (int x0 = 0; x0 <= 1; ++x0) {\n        // dp[i][x_curr] = min error up to employee i, with x_i = x_curr\n        // parent[i][x_curr] = x_{i-1} that achieves the minimum\n        array<long long, 2> dp_prev, dp_curr;\n        array<int, 2> parent_prev, parent_curr;\n        \n        // Initialize for i = 0\n        dp_prev[0] = dp_prev[1] = INF;\n        dp_prev[x0] = 0;\n        parent_prev[0] = parent_prev[1] = -1;\n        parent_prev[x0] = -1;\n        \n        // Process employees 1 to N-1\n        for (int i = 1; i < N; ++i) {\n            dp_curr[0] = dp_curr[1] = INF;\n            parent_curr[0] = parent_curr[1] = -1;\n            \n            for (int x_curr = 0; x_curr <= 1; ++x_curr) {\n                for (int x_prev = 0; x_prev <= 1; ++x_prev) {\n                    if (dp_prev[x_prev] == INF) continue;\n                    \n                    long long visits = AVG + STEP * (x_curr - x_prev);\n                    long long error = llabs(T[i] - visits);\n                    long long total_error = dp_prev[x_prev] + error;\n                    \n                    if (total_error < dp_curr[x_curr]) {\n                        dp_curr[x_curr] = total_error;\n                        parent_curr[x_curr] = x_prev;\n                    }\n                }\n            }\n            \n            dp_prev = dp_curr;\n            parent_prev = parent_curr;\n        }\n        \n        // Handle employee 0 with wrap-around\n        for (int x_last = 0; x_last <= 1; ++x_last) {\n            if (dp_prev[x_last] == INF) continue;\n            \n            long long visits = AVG + STEP * (x0 - x_last);\n            long long error = llabs(T[0] - visits);\n            long long total_error = dp_prev[x_last] + error;\n            \n            if (total_error < best_error) {\n                best_error = total_error;\n                \n                // Reconstruct the x sequence\n                best_x[0] = x0;\n                int curr_x = x_last;\n                for (int i = N - 1; i >= 1; --i) {\n                    best_x[i] = curr_x;\n                    curr_x = parent_prev[curr_x];\n                }\n                // Verify consistency: curr_x should equal x0\n                // (this ensures the cycle is consistent)\n            }\n        }\n    }\n    \n    // Construct the answer\n    vector<int> a(N), b(N);\n    for (int i = 0; i < N; ++i) {\n        if (best_x[i] == 1) {\n            a[i] = i;  // Self-loop on odd count\n        } else {\n            a[i] = (i + 1) % N;  // Point to next employee\n        }\n        b[i] = (i + 1) % N;  // Always point to next employee on even count\n    }\n    \n    // Output\n    for (int i = 0; i < N; ++i) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ---------- integer square root, floor(sqrt(x)) ---------- */\nint isqrt_ll(long long x) {\n    int r = (int)std::sqrt((long double)x);\n    while ((long long)(r + 1) * (r + 1) <= x) ++r;\n    while ((long long)r * r > x) --r;\n    return r;\n}\n\n/* ---------- DSU ---------- */\nstruct DSU {\n    vector<int> parent, sz;\n    int comps;\n    DSU(int n = 0) { init(n); }\n    void init(int n) {\n        parent.resize(n);\n        sz.assign(n, 1);\n        iota(parent.begin(), parent.end(), 0);\n        comps = n;\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 (sz[a] < sz[b]) swap(a, b);\n        parent[b] = a;\n        sz[a] += sz[b];\n        --comps;\n        return true;\n    }\n};\n\n/* ---------- Hilbert order (2D -> 1D) ---------- */\n// rotate/flip a quadrant appropriately\nvoid rot(int &x, int &y, int rx, int ry, int s) {\n    if (ry == 0) {\n        if (rx == 1) {\n            x = s - 1 - x;\n            y = s - 1 - y;\n        }\n        swap(x, y);\n    }\n}\n\n// Hilbert curve value for (x,y) of order N (2^N x 2^N grid)\nint hilbert(int x, int y, int N = 21) {\n    int h = 0, s = 1 << N;\n    for (int rx, ry, s2; s > 1; s = s2) {\n        s2 = s / 2;\n        rx = (x & s2) ? 1 : 0;\n        ry = (y & s2) ? 1 : 0;\n        h += s2 * s2 * ((3 * rx) ^ ry);\n        rot(x, y, rx, ry, s2);\n    }\n    return h;\n}\n\n/* ---------- lower bound distance between two rectangles ---------- */\nint lowerDistRect(int i, int j,\n                  const vector<int>& lx, const vector<int>& rx,\n                  const vector<int>& ly, const vector<int>& ry) {\n    long long dx = 0, dy = 0;\n    if (rx[i] < lx[j]) dx = (long long)lx[j] - rx[i];\n    else if (rx[j] < lx[i]) dx = (long long)lx[i] - rx[j];\n    else dx = 0;\n\n    if (ry[i] < ly[j]) dy = (long long)ly[j] - ry[i];\n    else if (ry[j] < ly[i]) dy = (long long)ly[i] - ry[j];\n    else dy = 0;\n\n    long long sq = dx * dx + dy * dy;\n    return isqrt_ll(sq);\n}\n\n/* ---------- main ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, Q, L, W;\n    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    vector<int> lx(N), rx(N), ly(N), ry(N);\n    for (int i = 0; i < N; ++i) cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n\n    /* ----- all lower bounds ----- */\n    vector<vector<int>> low(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        low[i][i] = 0;\n        for (int j = i + 1; j < N; ++j) {\n            int d = lowerDistRect(i, j, lx, rx, ly, ry);\n            low[i][j] = low[j][i] = d;\n        }\n    }\n\n    /* ----- grouping by Hilbert order of centres ----- */\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    vector<int> cx(N), cy(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    sort(order.begin(), order.end(),\n         [&](int a, int b) {\n             return hilbert(cx[a], cy[a]) < hilbert(cx[b], cy[b]);\n         });\n\n    vector<vector<int>> groups(M);\n    int pos = 0;\n    for (int i = 0; i < M; ++i) {\n        groups[i].reserve(G[i]);\n        for (int j = 0; j < G[i]; ++j) {\n            groups[i].push_back(order[pos++]);\n        }\n    }\n\n    /* ----- auxiliary data ----- */\n    vector<int> group_of(N, -1);\n    vector<int> local_idx(N, -1);\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < (int)groups[i].size(); ++j) {\n            int city = groups[i][j];\n            group_of[city] = i;\n            local_idx[city] = j;\n        }\n    }\n\n    vector<DSU> dsu(M);\n    for (int i = 0; i < M; ++i) dsu[i].init((int)groups[i].size());\n\n    vector<vector<pair<int,int>>> group_edges(M);\n\n    /* ----- query phase (deterministic) ----- */\n    int queries_used = 0;\n    while (queries_used < Q) {\n        int best_g = -1, best_comp = 0;\n        for (int i = 0; i < M; ++i) {\n            if (dsu[i].comps > best_comp) {\n                best_comp = dsu[i].comps;\n                best_g = i;\n            }\n        }\n        if (best_g == -1 || best_comp <= 1) break; // all finished\n\n        // representatives of the components of best_g, sorted by city id\n        unordered_map<int,int> rep;   // DSU root -> city id\n        for (int city : groups[best_g]) {\n            int lid = local_idx[city];\n            int root = dsu[best_g].find(lid);\n            if (!rep.count(root)) rep[root] = city;\n        }\n        vector<int> reps;\n        reps.reserve(rep.size());\n        for (auto &kv : rep) reps.push_back(kv.second);\n        sort(reps.begin(), reps.end());   // deterministic order\n\n        vector<int> subset;\n        if ((int)reps.size() <= L) {\n            subset = reps;\n        } else {\n            subset.assign(reps.begin(), reps.begin() + L);\n        }\n\n        int l = (int)subset.size();\n        cout << \"? \" << l;\n        for (int v : subset) cout << ' ' << v;\n        cout << '\\n';\n        cout.flush();\n\n        for (int i = 0; i < l - 1; ++i) {\n            int a, b;\n            cin >> a >> b;\n            if (group_of[a] != group_of[b]) continue; // safety\n            int g = group_of[a];\n            int la = local_idx[a];\n            int lb = local_idx[b];\n            if (dsu[g].unite(la, lb)) {\n                group_edges[g].push_back({a, b});\n            }\n        }\n        ++queries_used;\n    }\n\n    /* ----- finish groups that are still disconnected ----- */\n    for (int g = 0; g < M; ++g) {\n        if (dsu[g].comps == 1) continue;\n        struct Edge {int u, v, w;};\n        vector<Edge> edges;\n        int sz = (int)groups[g].size();\n        edges.reserve(sz * (sz - 1) / 2);\n        for (int i = 0; i < sz; ++i) {\n            int u = groups[g][i];\n            int lu = i;\n            for (int j = i + 1; j < sz; ++j) {\n                int v = groups[g][j];\n                int lv = j;\n                if (dsu[g].find(lu) == dsu[g].find(lv)) continue;\n                int w = low[u][v];\n                edges.push_back({u, v, w});\n            }\n        }\n        sort(edges.begin(), edges.end(),\n             [](const Edge& a, const Edge& b) {\n                 if (a.w != b.w) return a.w < b.w;\n                 if (a.u != b.u) return a.u < b.u;\n                 return a.v < b.v;\n             });\n        for (const Edge &e : edges) {\n            int lu = local_idx[e.u];\n            int lv = local_idx[e.v];\n            if (dsu[g].unite(lu, lv)) {\n                group_edges[g].push_back({e.u, e.v});\n                if (dsu[g].comps == 1) break;\n            }\n        }\n    }\n\n    /* ----- output ----- */\n    cout << \"!\\n\";\n    for (int g = 0; g < M; ++g) {\n        for (size_t i = 0; i < groups[g].size(); ++i) {\n            if (i) cout << ' ';\n            cout << groups[g][i];\n        }\n        cout << '\\n';\n        for (auto &e : group_edges[g])\n            cout << e.first << ' ' << e.second << '\\n';\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint 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>> p(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> p[i].first >> p[i].second;\n    }\n\n    pair<int,int> cur = p[0];                 // start position\n    for (int idx = 1; idx < M; ++idx) {\n        const pair<int,int> tgt = p[idx];\n\n        /* slide to every border that the target touches */\n        if (tgt.first == 0 && cur.first != 0) {\n            cout << \"S U\\n\";\n            cur.first = 0;\n        } else if (tgt.first == N-1 && cur.first != N-1) {\n            cout << \"S D\\n\";\n            cur.first = N-1;\n        }\n\n        if (tgt.second == 0 && cur.second != 0) {\n            cout << \"S L\\n\";\n            cur.second = 0;\n        } else if (tgt.second == N-1 && cur.second != N-1) {\n            cout << \"S R\\n\";\n            cur.second = N-1;\n        }\n\n        /* finish the remaining distance with ordinary moves */\n        while (cur.first < tgt.first) {\n            cout << \"M D\\n\";\n            ++cur.first;\n        }\n        while (cur.first > tgt.first) {\n            cout << \"M U\\n\";\n            --cur.first;\n        }\n        while (cur.second < tgt.second) {\n            cout << \"M R\\n\";\n            ++cur.second;\n        }\n        while (cur.second > tgt.second) {\n            cout << \"M L\\n\";\n            --cur.second;\n        }\n    }\n    return 0;\n}"},"4":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Company {\n    int x, y;\n    long long r;\n    int a, b, c, d;\n};\n\nstruct Region {\n    int x1, y1, x2, y2;\n    vector<int> points;\n};\n\nclass PartitionSolver {\nprivate:\n    vector<Company> &comp;\n    const int W = 10000;\n    const int H = 10000;\n    \n    double satisfaction(long long r, long long s) {\n        if (s == 0) return 0.0;\n        double ratio = min(r, s) / (double)max(r, s);\n        return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n    }\n    \n    bool findBestSplit(const Region &reg, const vector<int> &pts, bool vertical,\n                       int &best_split, int &best_cut, double &best_score) {\n        vector<int> sorted = pts;\n        if (vertical) {\n            sort(sorted.begin(), sorted.end(), [&](int i, int j) {\n                return comp[i].x < comp[j].x;\n            });\n        } else {\n            sort(sorted.begin(), sorted.end(), [&](int i, int j) {\n                return comp[i].y < comp[j].y;\n            });\n        }\n        \n        best_score = -1;\n        long long total_r = 0;\n        for (int i : pts) total_r += comp[i].r;\n        \n        // Try all possible split positions\n        for (int split = 1; split < sorted.size(); split++) {\n            long long sum_r_left = 0;\n            for (int i = 0; i < split; i++) sum_r_left += comp[sorted[i]].r;\n            \n            // Find feasible cut position range\n            int min_cut, max_cut;\n            if (vertical) {\n                int max_x_left = -1;\n                for (int i = 0; i < split; i++) {\n                    max_x_left = max(max_x_left, comp[sorted[i]].x);\n                }\n                int min_x_right = W;\n                for (int i = split; i < sorted.size(); i++) {\n                    min_x_right = min(min_x_right, comp[sorted[i]].x);\n                }\n                min_cut = max_x_left + 1;\n                max_cut = min_x_right;\n            } else {\n                int max_y_left = -1;\n                for (int i = 0; i < split; i++) {\n                    max_y_left = max(max_y_left, comp[sorted[i]].y);\n                }\n                int min_y_right = H;\n                for (int i = split; i < sorted.size(); i++) {\n                    min_y_right = min(min_y_right, comp[sorted[i]].y);\n                }\n                min_cut = max_y_left + 1;\n                max_cut = min_y_right;\n            }\n            \n            if (min_cut > max_cut) continue; // Not feasible\n            \n            // Target cut based on area proportion\n            int target_cut;\n            if (vertical) {\n                double ratio = (double)sum_r_left / (reg.y2 - reg.y1);\n                target_cut = reg.x1 + (int)ratio;\n            } else {\n                double ratio = (double)sum_r_left / (reg.x2 - reg.x1);\n                target_cut = reg.y1 + (int)ratio;\n            }\n            \n            // Choose closest feasible cut\n            int cut = min_cut;\n            if (target_cut > min_cut && target_cut < max_cut) cut = target_cut;\n            else if (target_cut > max_cut) cut = max_cut;\n            \n            // Calculate areas and score\n            long long area_left, area_right;\n            if (vertical) {\n                area_left = (long long)(cut - reg.x1) * (reg.y2 - reg.y1);\n                area_right = (long long)(reg.x2 - cut) * (reg.y2 - reg.y1);\n            } else {\n                area_left = (long long)(reg.x2 - reg.x1) * (cut - reg.y1);\n                area_right = (long long)(reg.x2 - reg.x1) * (reg.y2 - cut);\n            }\n            \n            double score = satisfaction(sum_r_left, area_left) + \n                          satisfaction(total_r - sum_r_left, area_right);\n            \n            if (score > best_score) {\n                best_score = score;\n                best_split = split;\n                best_cut = cut;\n            }\n        }\n        return best_score >= 0;\n    }\n    \n    void solveRegion(Region &reg) {\n        if (reg.points.size() <= 1) {\n            if (reg.points.size() == 1) {\n                int idx = reg.points[0];\n                comp[idx].a = reg.x1;\n                comp[idx].b = reg.y1;\n                comp[idx].c = reg.x2;\n                comp[idx].d = reg.y2;\n            }\n            return;\n        }\n        \n        // Choose orientation: split along longer dimension\n        bool vertical = (reg.x2 - reg.x1) > (reg.y2 - reg.y1);\n        \n        int best_split, best_cut;\n        double best_score;\n        \n        if (!findBestSplit(reg, reg.points, vertical, best_split, best_cut, best_score)) {\n            // Fallback: median split\n            best_split = reg.points.size() / 2;\n            best_cut = vertical ? (reg.x1 + reg.x2) / 2 : (reg.y1 + reg.y2) / 2;\n        }\n        \n        // Sort points for splitting\n        vector<int> sorted = reg.points;\n        if (vertical) {\n            sort(sorted.begin(), sorted.end(), [&](int i, int j) {\n                return comp[i].x < comp[j].x;\n            });\n        } else {\n            sort(sorted.begin(), sorted.end(), [&](int i, int j) {\n                return comp[i].y < comp[j].y;\n            });\n        }\n        \n        // Create sub-regions\n        Region left = reg;\n        Region right = reg;\n        left.points.clear();\n        right.points.clear();\n        \n        if (vertical) {\n            left.x2 = best_cut;\n            right.x1 = best_cut;\n        } else {\n            left.y2 = best_cut;\n            right.y1 = best_cut;\n        }\n        \n        for (int i = 0; i < sorted.size(); i++) {\n            if (i < best_split) left.points.push_back(sorted[i]);\n            else right.points.push_back(sorted[i]);\n        }\n        \n        solveRegion(left);\n        solveRegion(right);\n    }\n    \npublic:\n    PartitionSolver(vector<Company> &c) : comp(c) {}\n    \n    void solve() {\n        Region root{0, 0, W, H};\n        for (int i = 0; i < comp.size(); i++) root.points.push_back(i);\n        solveRegion(root);\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<Company> comp(n);\n    for (int i = 0; i < n; i++) cin >> comp[i].x >> comp[i].y >> comp[i].r;\n    \n    PartitionSolver solver(comp);\n    solver.solve();\n    \n    for (auto &c : comp) {\n        cout << c.a << \" \" << c.b << \" \" << c.c << \" \" << c.d << \"\\n\";\n    }\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Cell {\n    int value;\n    int tile_id;\n    vector<int> neighbors;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 50;\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    const char dir_char[4] = {'U', 'D', 'L', 'R'};\n    \n    int si, sj;\n    \n    // Process each test case until EOF\n    while (cin >> si >> sj) {\n        // Read tile IDs\n        vector<vector<int>> t(N, vector<int>(N));\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cin >> t[i][j];\n            }\n        }\n        \n        // Read values\n        vector<vector<int>> p(N, vector<int>(N));\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cin >> p[i][j];\n            }\n        }\n        \n        // Build cells\n        vector<Cell> cells(N * N);\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int idx = i * N + j;\n                cells[idx].value = p[i][j];\n                cells[idx].tile_id = t[i][j];\n            }\n        }\n        \n        // Build adjacency (exclude same-tile neighbors)\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int idx = i * N + j;\n                for (int dir = 0; dir < 4; dir++) {\n                    int ni = i + dx[dir];\n                    int nj = j + dy[dir];\n                    if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                    int nidx = ni * N + nj;\n                    if (cells[idx].tile_id != cells[nidx].tile_id) {\n                        cells[idx].neighbors.push_back(nidx);\n                    }\n                }\n            }\n        }\n        \n        // Try multiple greedy runs with randomization\n        string best_moves;\n        int best_score = -1;\n        \n        // Random generator\n        mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n        \n        for (int attempt = 0; attempt < 10; attempt++) {\n            string current_moves;\n            vector<int> current_cells;\n            vector<bool> visited_tile(N * N * 2, false); // Upper bound for tile IDs\n            \n            int start_idx = si * N + sj;\n            current_cells.push_back(start_idx);\n            visited_tile[cells[start_idx].tile_id] = true;\n            int current_score = cells[start_idx].value;\n            \n            int current_cell = start_idx;\n            \n            while (true) {\n                // Find all valid neighbors\n                vector<int> valid_neighbors;\n                for (int neighbor : cells[current_cell].neighbors) {\n                    if (!visited_tile[cells[neighbor].tile_id]) {\n                        valid_neighbors.push_back(neighbor);\n                    }\n                }\n                \n                if (valid_neighbors.empty()) break;\n                \n                // Sort by value (descending) with random tie-breaking\n                shuffle(valid_neighbors.begin(), valid_neighbors.end(), rng);\n                sort(valid_neighbors.begin(), valid_neighbors.end(), \n                     [&](int a, int b) {\n                         return cells[a].value > cells[b].value;\n                     });\n                \n                // Choose the best neighbor\n                int next_cell = valid_neighbors[0];\n                \n                // Determine direction\n                int cur_i = current_cell / N;\n                int cur_j = current_cell % N;\n                int next_i = next_cell / N;\n                int next_j = next_cell % N;\n                \n                if (next_i == cur_i - 1) current_moves.push_back('U');\n                else if (next_i == cur_i + 1) current_moves.push_back('D');\n                else if (next_j == cur_j - 1) current_moves.push_back('L');\n                else if (next_j == cur_j + 1) current_moves.push_back('R');\n                \n                // Update state\n                current_cell = next_cell;\n                current_cells.push_back(current_cell);\n                visited_tile[cells[current_cell].tile_id] = true;\n                current_score += cells[current_cell].value;\n            }\n            \n            // Update best if needed\n            if (current_score > best_score) {\n                best_score = current_score;\n                best_moves = current_moves;\n            }\n        }\n        \n        // Output the best path found\n        cout << best_moves << \"\\n\";\n    }\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\n////////////////////  parameters  ////////////////////\n\nstruct EdgeWeights {\n    double h[30][29]; // horizontal edges (i , j) -> (i , j+1)\n    double v[29][30]; // vertical   edges (i , j) -> (i+1 , j)\n};\n\n////////////////////  Dijkstra & path reconstruction  ////////////////////\n\nstruct State {\n    double dist;\n    int node;               // node id = i*30 + j\n    bool operator<(const State& other) const {\n        return dist > other.dist; // reversed for min\u2011heap\n    }\n};\n\n/*  run Dijkstra from (si,sj) to (ti,tj) using the given weight matrices.\n    returns the path as a string of U/D/L/R.                           */\nstring dijkstra_path(int si, int sj, int ti, int tj,\n                     const EdgeWeights& w,\n                     double* path_len = nullptr) {\n    const int N = 30 * 30;\n    const int s = si * 30 + sj;\n    const int t = ti * 30 + tj;\n\n    vector<double> dist(N, 1e100);\n    vector<int> prev(N, -1);\n    vector<char> pdir(N, 0);\n\n    priority_queue<State> pq;\n    dist[s] = 0.0;\n    pq.push({0.0, s});\n\n    while (!pq.empty()) {\n        auto cur = pq.top(); pq.pop();\n        int u = cur.node;\n        double d = cur.dist;\n        if (d > dist[u] + 1e-12) continue;\n        if (u == t) break; // we already know the shortest distance to t\n\n        int ui = u / 30, uj = u % 30;\n\n        // ----- up -----\n        if (ui > 0) {\n            int v = (ui - 1) * 30 + uj;\n            double nd = d + w.v[ui - 1][uj];\n            if (nd + 1e-12 < dist[v]) {\n                dist[v] = nd;\n                prev[v] = u;\n                pdir[v] = 'U';\n                pq.push({nd, v});\n            }\n        }\n        // ----- down -----\n        if (ui < 29) {\n            int v = (ui + 1) * 30 + uj;\n            double nd = d + w.v[ui][uj];\n            if (nd + 1e-12 < dist[v]) {\n                dist[v] = nd;\n                prev[v] = u;\n                pdir[v] = 'D';\n                pq.push({nd, v});\n            }\n        }\n        // ----- left -----\n        if (uj > 0) {\n            int v = ui * 30 + (uj - 1);\n            double nd = d + w.h[ui][uj - 1];\n            if (nd + 1e-12 < dist[v]) {\n                dist[v] = nd;\n                prev[v] = u;\n                pdir[v] = 'L';\n                pq.push({nd, v});\n            }\n        }\n        // ----- right -----\n        if (uj < 29) {\n            int v = ui * 30 + (uj + 1);\n            double nd = d + w.h[ui][uj];\n            if (nd + 1e-12 < dist[v]) {\n                dist[v] = nd;\n                prev[v] = u;\n                pdir[v] = 'R';\n                pq.push({nd, v});\n            }\n        }\n    }\n\n    // reconstruct the path from t to s\n    string path;\n    for (int cur = t; cur != s; cur = prev[cur]) {\n        path.push_back(pdir[cur]);\n    }\n    reverse(path.begin(), path.end());\n\n    if (path_len) *path_len = dist[t];\n    return path;\n}\n\n////////////////////  main  ////////////////////\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    random_device rd;\n    mt19937 rng(rd());\n\n    uniform_real_distribution<double> urd_noise(-500.0, 500.0);\n    bernoulli_distribution bernoulli(0.5); // temporary, will change each query\n\n    // initialise edge weights (mid\u2011range guess)\n    EdgeWeights w;\n    for (int i = 0; i < 30; ++i)\n        for (int j = 0; j < 29; ++j)\n            w.h[i][j] = 5000.0;\n    for (int i = 0; i < 29; ++i)\n        for (int j = 0; j < 30; ++j)\n            w.v[i][j] = 5000.0;\n\n    for (int query = 0; query < 1000; ++query) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) return 0; // no more input\n\n        // --------- exploration / exploitation decision ----------\n        double eps = 0.5 * exp(-query / 150.0);\n        bernoulli_distribution choose_explore(eps);\n        bool explore = choose_explore(rng);\n\n        string path;\n        EdgeWeights w_tmp = w; // copy current weights\n        if (explore) {\n            // add temporary noise\n            for (int i = 0; i < 30; ++i)\n                for (int j = 0; j < 29; ++j)\n                    w_tmp.h[i][j] += urd_noise(rng);\n            for (int i = 0; i < 29; ++i)\n                for (int j = 0; j < 30; ++j)\n                    w_tmp.v[i][j] += urd_noise(rng);\n            path = dijkstra_path(si, sj, ti, tj, w_tmp);\n        } else {\n            path = dijkstra_path(si, sj, ti, tj, w);\n        }\n\n        // --------- output ----------\n        cout << path << '\\n';\n        cout.flush();\n\n        // --------- read noisy observation ----------\n        long long y;\n        cin >> y;\n\n        // --------- accumulate predicted length (using true weights) ----------\n        double pred_len = 0.0;\n        int i = si, j = sj;\n        for (char c : path) {\n            if (c == 'U') {\n                pred_len += w.v[i - 1][j];\n                --i;\n            } else if (c == 'D') {\n                pred_len += w.v[i][j];\n                ++i;\n            } else if (c == 'L') {\n                pred_len += w.h[i][j - 1];\n                --j;\n            } else if (c == 'R') {\n                pred_len += w.h[i][j];\n                ++j;\n            }\n        }\n\n        // --------- update weights (stochastic gradient descent) ----------\n        double err = double(y) - pred_len;\n        double lr = 0.01 / sqrt(query + 1);   // slowly decreasing step size\n        double delta = lr * err / double(path.size());\n\n        i = si; j = sj;\n        for (char c : path) {\n            if (c == 'U') {\n                w.v[i - 1][j] += delta;\n                --i;\n            } else if (c == 'D') {\n                w.v[i][j] += delta;\n                ++i;\n            } else if (c == 'L') {\n                w.h[i][j - 1] += delta;\n                --j;\n            } else if (c == 'R') {\n                w.h[i][j] += delta;\n                ++j;\n            }\n        }\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 20;                 // matrix size (fixed in the statement)\nconstexpr int MAXLEN = 12;            // maximal length of an input string\nconstexpr int ALPH = 8;               // letters A \u2026 H\n\n/* --------------------------------------------------------------- */\n/* ---------- placement of one string ---------- */\nstruct Placement {\n    uint16_t cell[MAXLEN];   // cell indices (0 \u2026 N*N-1)\n    uint8_t  let[MAXLEN];    // required letters (0 \u2026 7)\n    uint8_t  len;            // actual length ( \u2264 12 )\n};\n\n/* ---------- global data for the whole test case ---------- */\nint Muniq;                                           // number of different strings\nvector<vector<int>> strLetters;                     // letters of each unique string\nvector<vector<Placement>> placements;               // all placements of each string\n\n/* ---------- current working solution ---------- */\narray<int, N * N> curLetter;        // -1 = empty, 0..7 = letter\narray<int, N * N> curUse;           // how many placements occupy the cell\nint curUsedCells;                    // #cells with curUse > 0\nvector<int> curIdx;                  // for each string: chosen placement index, -1 = none\n\n/* --------------------------------------------------------------- */\ninline int cellId(int r, int c) { return r * N + c; }\n\n/* check whether placement p can be inserted into the current grid */\ninline bool canPlace(const Placement& p) {\n    for (int i = 0; i < p.len; ++i) {\n        int c = p.cell[i];\n        if (curUse[c] > 0 && curLetter[c] != (int)p.let[i]) return false;\n    }\n    return true;\n}\n\n/* compute the number of empty cells that placement p would occupy */\ninline int placeCost(const Placement& p) {\n    int cost = 0;\n    for (int i = 0; i < p.len; ++i)\n        if (curUse[p.cell[i]] == 0) ++cost;\n    return cost;\n}\n\n/* insert a placement into the grid */\ninline void place(const Placement& p) {\n    for (int i = 0; i < p.len; ++i) {\n        int c = p.cell[i];\n        if (curUse[c] == 0) {\n            curLetter[c] = p.let[i];\n            ++curUsedCells;\n        }\n        ++curUse[c];\n    }\n}\n\n/* remove a placement from the grid */\ninline void unplace(const Placement& p) {\n    for (int i = 0; i < p.len; ++i) {\n        int c = p.cell[i];\n        --curUse[c];\n        if (curUse[c] == 0) {\n            curLetter[c] = -1;\n            --curUsedCells;\n        }\n    }\n}\n\n/* test whether string s (index) is a subsequence of the current matrix */\ninline bool isPresent(int s) {\n    for (const Placement& p : placements[s]) {\n        bool ok = true;\n        for (int i = 0; i < p.len; ++i) {\n            int c = p.cell[i];\n            if (curLetter[c] != (int)p.let[i]) { ok = false; break; }\n        }\n        if (ok) return true;\n    }\n    return false;\n}\n\n/* --------------------------------------------------------------- */\n/* ---------- main ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int Ninput, Minput;\n    if (!(cin >> Ninput >> Minput)) return 0;\n    vector<string> allStr(Minput);\n    for (int i = 0; i < Minput; ++i) cin >> allStr[i];\n\n    /* ---- delete duplicate strings (one occurrence is sufficient) ---- */\n    unordered_map<string, int> seen;\n    vector<string> uniqStr;\n    for (const string& x : allStr) {\n        if (seen.find(x) == seen.end()) {\n            seen[x] = 1;\n            uniqStr.push_back(x);\n        }\n    }\n    Muniq = (int)uniqStr.size();                 // number of different strings\n\n    /* ---- convert strings to integer letters ---- */\n    strLetters.resize(Muniq);\n    for (int i = 0; i < Muniq; ++i)\n        for (char ch : uniqStr[i])\n            strLetters[i].push_back(ch - 'A');\n\n    /* ---- pre\u2011compute all placements of each string ---- */\n    placements.assign(Muniq, {});\n    for (int sid = 0; sid < Muniq; ++sid) {\n        const vector<int>& L = strLetters[sid];\n        int len = (int)L.size();\n        // horizontal\n        for (int row = 0; row < N; ++row)\n            for (int startCol = 0; startCol < N; ++startCol) {\n                Placement p;\n                p.len = (uint8_t)len;\n                for (int off = 0; off < len; ++off) {\n                    int col = (startCol + off) % N;\n                    p.cell[off] = (uint16_t)cellId(row, col);\n                    p.let[off] = (uint8_t)L[off];\n                }\n                placements[sid].push_back(p);\n            }\n        // vertical\n        for (int col = 0; col < N; ++col)\n            for (int startRow = 0; startRow < N; ++startRow) {\n                Placement p;\n                p.len = (uint8_t)len;\n                for (int off = 0; off < len; ++off) {\n                    int row = (startRow + off) % N;\n                    p.cell[off] = (uint16_t)cellId(row, col);\n                    p.let[off] = (uint8_t)L[off];\n                }\n                placements[sid].push_back(p);\n            }\n    }\n\n    /* ---------- containers for the best solution found ---------- */\n    array<int, N * N> bestLetter;\n    int bestUsed = INT_MAX;\n    int bestPlaced = -1;\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    const double TIME_LIMIT = 2.8;                 // seconds\n    auto start = chrono::steady_clock::now();\n\n    /* ---------- phase 1 : many greedy restarts + light backtracking ---------- */\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > 0.60 * TIME_LIMIT) break;    // 60\u202f% of total time\n\n        /* ---- start with an empty grid ---- */\n        curLetter.fill(-1);\n        curUse.fill(0);\n        curUsedCells = 0;\n        curIdx.assign(Muniq, -1);\n\n        vector<int> order(Muniq);\n        iota(order.begin(), order.end(), 0);\n        shuffle(order.begin(), order.end(), rng);\n\n        int placed = 0;\n\n        for (int sid : order) {\n            const vector<Placement>& cand = placements[sid];\n            int bestCost = INT_MAX;\n            vector<int> bestIdx;\n            for (int pid = 0; pid < (int)cand.size(); ++pid) {\n                const Placement& p = cand[pid];\n                if (!canPlace(p)) continue;\n                int c = placeCost(p);\n                if (c < bestCost) {\n                    bestCost = c;\n                    bestIdx.clear();\n                    bestIdx.push_back(pid);\n                } else if (c == bestCost) {\n                    bestIdx.push_back(pid);\n                }\n            }\n            if (bestIdx.empty()) continue;          // cannot place now\n            int chosen = bestIdx[uniform_int_distribution<int>(0, (int)bestIdx.size() - 1)(rng)];\n            place(cand[chosen]);\n            curIdx[sid] = chosen;\n            ++placed;\n        }\n\n        /* ---- light backtracking for the still missing strings ---- */\n        if (placed < Muniq) {\n            // collect not yet placed strings\n            vector<int> missing;\n            for (int i = 0; i < Muniq; ++i)\n                if (curIdx[i] == -1) missing.push_back(i);\n            // try a few rounds of \"remove one, insert one\"\n            const int BACKTRACK_TRIES = 50;\n            for (int attempt = 0; attempt < BACKTRACK_TRIES && !missing.empty(); ++attempt) {\n                int sid = missing.back();                     // take one missing string\n                // try all its placements, maybe one fits now\n                bool ok = false;\n                for (const Placement& p : placements[sid]) {\n                    if (canPlace(p)) {\n                        place(p);\n                        curIdx[sid] = &p - &placements[sid][0]; // store index (rough but enough)\n                        missing.pop_back();\n                        ok = true;\n                        ++placed;\n                        break;\n                    }\n                }\n                if (ok) continue;                            // success \u2013 continue with next missing\n                // otherwise remove a random already placed string and try again\n                vector<int> placedIds;\n                for (int i = 0; i < Muniq; ++i)\n                    if (curIdx[i] != -1) placedIds.push_back(i);\n                if (placedIds.empty()) continue;\n                int victim = placedIds[uniform_int_distribution<int>(0, (int)placedIds.size() - 1)(rng)];\n                const Placement& vp = placements[victim][curIdx[victim]];\n                unplace(vp);\n                curIdx[victim] = -1;\n                --placed;\n            }\n        }\n\n        /* ---- remove redundant strings (they are already present) ---- */\n        if (placed == Muniq) {\n            vector<int> perm = order;\n            shuffle(perm.begin(), perm.end(), rng);\n            for (int sid : perm) {\n                if (curIdx[sid] == -1) continue;\n                const Placement& p = placements[sid][curIdx[sid]];\n                unplace(p);\n                if (isPresent(sid)) {\n                    curIdx[sid] = -1;          // keep it removed\n                } else {\n                    place(p);                  // put it back\n                }\n            }\n        }\n\n        /* ---- remember the best solution of this restart ---- */\n        if (placed > bestPlaced ||\n            (placed == bestPlaced && curUsedCells < bestUsed)) {\n            bestPlaced = placed;\n            bestUsed   = curUsedCells;\n            bestLetter = curLetter;               // copy the whole grid (400 ints)\n        }\n    }   // end of restarts\n\n    /* ---- nothing feasible found ? output empty matrix (worst case) ---- */\n    if (bestPlaced == -1) {\n        for (int i = 0; i < N; ++i)\n            cout << string(N, '.') << '\\n';\n        return 0;\n    }\n\n    /* ---- reload the best solution into the working arrays ---- */\n    curLetter = bestLetter;\n    curUse.fill(0);\n    curUsedCells = 0;\n    for (int i = 0; i < N * N; ++i)\n        if (curLetter[i] != -1) {\n            curUse[i] = 1;\n            ++curUsedCells;\n        }\n    curIdx.assign(Muniq, -1);       // we do not know the exact indices any more\n\n    /* ---------- phase 2 : simple hill climbing (use remaining time) ---------- */\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > TIME_LIMIT - 0.05) break;    // stop a little before the hard limit\n\n        // pick a random placed string (ignore strings that are not placed)\n        vector<int> placedIds;\n        for (int i = 0; i < Muniq; ++i)\n            if (curIdx[i] != -1) placedIds.push_back(i);\n        if (placedIds.empty()) continue;\n        int sid = placedIds[uniform_int_distribution<int>(0, (int)placedIds.size() - 1)(rng)];\n        const Placement& oldPl = placements[sid][curIdx[sid]];\n\n        // pick a random different placement\n        const vector<Placement>& cand = placements[sid];\n        int pid = uniform_int_distribution<int>(0, (int)cand.size() - 1)(rng);\n        if (pid == curIdx[sid]) continue;\n        const Placement& newPl = cand[pid];\n        if (!canPlace(newPl)) continue;           // would conflict\n\n        // compute \u0394 = newCellsUsed - cellsFreed\n        int freed = 0;\n        for (int i = 0; i < oldPl.len; ++i) {\n            int c = oldPl.cell[i];\n            if (curUse[c] == 1) {\n                bool inNew = false;\n                for (int j = 0; j < newPl.len; ++j)\n                    if (newPl.cell[j] == c) { inNew = true; break; }\n                if (!inNew) ++freed;\n            }\n        }\n        int newlyUsed = 0;\n        for (int i = 0; i < newPl.len; ++i) {\n            int c = newPl.cell[i];\n            if (curUse[c] == 0) {\n                bool inOld = false;\n                for (int j = 0; j < oldPl.len; ++j)\n                    if (oldPl.cell[j] == c) { inOld = true; break; }\n                if (!inOld) ++newlyUsed;\n            }\n        }\n        int delta = newlyUsed - freed;\n        if (delta < 0) {                           // strict improvement\n            unplace(oldPl);\n            place(newPl);\n            curIdx[sid] = pid;\n            if (curUsedCells < bestUsed) {\n                bestUsed = curUsedCells;\n                bestLetter = curLetter;\n            }\n        }\n    }\n\n    /* ---------- output the best matrix ---------- */\n    for (int r = 0; r < N; ++r) {\n        string line;\n        for (int c = 0; c < N; ++c) {\n            int id = cellId(r, c);\n            if (bestLetter[id] == -1) line += '.';\n            else                       line += char('A' + bestLetter[id]);\n        }\n        cout << line << '\\n';\n    }\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXV = 5005;                 // maximal number of cells (N\u226469 \u2192 < 5000)\n\nstruct Edge {\n    int u, v, w;\n    bool operator<(Edge const& other) const { return w < other.w; }\n};\n\nstruct DSU {\n    vector<int> p, r;\n    DSU(int n = 0) { init(n); }\n    void init(int n) { p.resize(n); r.assign(n,0); iota(p.begin(),p.end(),0); }\n    int find(int x){ return p[x]==x?x:p[x]=find(p[x]); }\n    bool unite(int a,int b){\n        a=find(a); b=find(b);\n        if(a==b) return false;\n        if(r[a]<r[b]) swap(a,b);\n        p[b]=a;\n        if(r[a]==r[b]) ++r[a];\n        return true;\n    }\n};\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    // --- 1. give an id to every road cell, store its weight and coordinates ----------\n    vector<vector<int>> id(N, vector<int>(N,-1));\n    vector<int> weight; weight.reserve(N*N);\n    vector<int> iOf, jOf; iOf.reserve(N*N); jOf.reserve(N*N);\n    int V = 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] = V++;\n                weight.push_back(g[i][j]-'0');\n                iOf.push_back(i);\n                jOf.push_back(j);\n            }\n        }\n    }\n    const int startIdx = id[si][sj];\n\n    // --- 2. row and column segment ids ------------------------------------------------\n    vector<int> rowId(V,-1), colId(V,-1);\n    int rowSegCnt = 0;\n    for(int i=0;i<N;++i){\n        int cur = -1;\n        for(int j=0;j<N;++j){\n            if(g[i][j]!='#'){\n                if(j==0 || g[i][j-1]=='#') cur = rowSegCnt++;\n                rowId[id[i][j]] = cur;\n            }\n        }\n    }\n    int colSegCnt = 0;\n    for(int j=0;j<N;++j){\n        int cur = -1;\n        for(int i=0;i<N;++i){\n            if(g[i][j]!='#'){\n                if(i==0 || g[i-1][j]=='#') cur = colSegCnt++;\n                colId[id[i][j]] = cur;\n            }\n        }\n    }\n\n    // decide which side to cover\n    bool useRow = rowSegCnt <= colSegCnt;\n    vector<int> segId = useRow ? rowId : colId;\n    int segCnt = useRow ? rowSegCnt : colSegCnt;\n\n    // --- 3. build edge list (only right / down, undirected) ----------------------------\n    vector<Edge> edges;\n    edges.reserve(4*V);\n    const int di[4] = {-1,1,0,0};\n    const int dj[4] = {0,0,-1,1};\n    for(int i=0;i<N;++i){\n        for(int j=0;j<N;++j){\n            if(g[i][j]=='#') continue;\n            int u = id[i][j];\n            // right neighbour\n            if(j+1<N && g[i][j+1]!='#'){\n                int v = id[i][j+1];\n                if(u<v) edges.push_back({u,v,weight[u]+weight[v]});\n            }\n            // down neighbour\n            if(i+1<N && g[i+1][j]!='#'){\n                int v = id[i+1][j];\n                if(u<v) edges.push_back({u,v,weight[u]+weight[v]});\n            }\n        }\n    }\n\n    // --- 4. MST with Kruskal ---------------------------------------------------------\n    sort(edges.begin(), edges.end());\n    DSU dsu(V);\n    vector<vector<int>> mstAdj(V);\n    int added = 0;\n    for(const auto& e: edges){\n        if(dsu.unite(e.u, e.v)){\n            mstAdj[e.u].push_back(e.v);\n            mstAdj[e.v].push_back(e.u);\n            if(++added == V-1) break;\n        }\n    }\n\n    // --- 5. root the tree in the start cell -----------------------------------------\n    vector<int> parent(V,-1);\n    vector<vector<int>> children(V);\n    vector<int> order; order.reserve(V);\n    // iterative stack for rooting\n    vector<int> st; st.push_back(startIdx);\n    parent[startIdx] = startIdx;\n    while(!st.empty()){\n        int u = st.back(); st.pop_back();\n        order.push_back(u);\n        for(int v: mstAdj[u]){\n            if(v==parent[u]) continue;\n            parent[v] = u;\n            children[u].push_back(v);\n            st.push_back(v);\n        }\n    }\n\n    // --- 6. subtree masks of segment ids --------------------------------------------\n    using Mask = bitset<MAXV>;\n    vector<Mask> subMask(V);\n    vector<int> subCnt(V,0);\n    // post\u2011order (reverse of the order we obtained above, because every parent appears after its children)\n    for(int i=(int)order.size()-1;i>=0;--i){\n        int u = order[i];\n        subMask[u].reset();\n        subMask[u].set(segId[u]);\n        for(int v: children[u]){\n            subMask[u] |= subMask[v];\n        }\n        subCnt[u] = (int)subMask[u].count();\n    }\n\n    // --- 7. sort children by number of different segments in their subtree ----------\n    for(int u=0;u<V;++u){\n        sort(children[u].begin(), children[u].end(),\n            [&](int a, int b){ return subCnt[a] > subCnt[b]; });\n    }\n\n    // --- 8. depth\u2011first walk, but only when a subtree still contains uncovered segments\n    Mask coveredMask;\n    coveredMask.reset();\n    coveredMask.set(segId[startIdx]);          // start segment already visited\n\n    string answer; answer.reserve(2*V);\n    function<void(int,int)> dfsWalk = [&](int u, int p)->void{\n        for(int v: children[u]){\n            // if nothing uncovered in this subtree \u2013 skip it\n            if ( (subMask[v] & ~coveredMask).none() ) continue;\n            // move u -> v\n            if(iOf[v]==iOf[u]-1 && jOf[v]==jOf[u]) answer.push_back('U');\n            else if(iOf[v]==iOf[u]+1 && jOf[v]==jOf[u]) answer.push_back('D');\n            else if(iOf[v]==iOf[u] && jOf[v]==jOf[u]-1) answer.push_back('L');\n            else if(iOf[v]==iOf[u] && jOf[v]==jOf[u]+1) answer.push_back('R');\n            else { /* should never happen */ }\n\n            coveredMask.set(segId[v]);          // v itself is visited now\n            dfsWalk(v, u);\n            // return v -> u\n            if(iOf[v]==iOf[u]-1 && jOf[v]==jOf[u]) answer.push_back('D');\n            else if(iOf[v]==iOf[u]+1 && jOf[v]==jOf[u]) answer.push_back('U');\n            else if(iOf[v]==iOf[u] && jOf[v]==jOf[u]-1) answer.push_back('R');\n            else if(iOf[v]==iOf[u] && jOf[v]==jOf[u]+1) answer.push_back('L');\n            else { /* should never happen */ }\n        }\n    };\n    dfsWalk(startIdx, -1);\n\n    // --- 9. output ------------------------------------------------------------------\n    cout << answer << '\\n';\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ---------- data structures ---------- */\n\nstruct Task {\n    vector<int> d;          // skill requirements, size K\n    int indegree = 0;       // number of unfinished predecessors\n    int status = -1;        // -1 : not started, 0 : in progress, 1 : completed\n    int start_day = -1;     // day on which the task was started\n    int assigned_to = -1;   // member id (0\u2011based) or -1\n    int total_req = 0;      // \u03a3_k d[k]  (used for a cheap difficulty estimate)\n};\n\nstruct Member {\n    vector<int> s_est;          // not used by the final algorithm, kept for symmetry\n    double avg_time_per_unit = 1.0;   // average observed  (time / total_requirement)\n    int total_processed = 0;    // number of tasks finished by this member\n    int total_time = 0;         // sum of their processing times\n};\n\n/* ---------- main ---------- */\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---- read prior information ---- */\n    int N, M, K, R;\n    if (!(cin >> N >> M >> K >> R)) return 0;\n\n    vector<Task> tasks(N);\n    for (int i = 0; i < N; ++i) {\n        tasks[i].d.resize(K);\n        tasks[i].total_req = 0;\n        for (int k = 0; k < K; ++k) {\n            cin >> tasks[i].d[k];\n            tasks[i].total_req += tasks[i].d[k];\n        }\n    }\n\n    vector<vector<int>> graph(N);          // edge u \u2192 v  (u must be done before v)\n    for (int i = 0; i < R; ++i) {\n        int u, v;  cin >> u >> v;  --u; --v;\n        graph[u].push_back(v);\n        ++tasks[v].indegree;\n    }\n\n    vector<Member> members(M);\n    for (int j = 0; j < M; ++j) members[j].s_est.assign(K, 0);\n\n    vector<int> member_status(M, -1);               // -1 \u2192 idle, otherwise task id\n    unordered_map<int,int> in_progress;             // taskid \u2192 start_day\n\n    int day = 0;\n\n    /* ---- day loop ---- */\n    while (true) {\n        ++day;\n        if (day > 2000) break;                     // safety, should never trigger\n\n        /* -- 1. available tasks -- */\n        vector<int> available;\n        for (int i = 0; i < N; ++i)\n            if (tasks[i].status == -1 && tasks[i].indegree == 0)\n                available.push_back(i);\n\n        sort(available.begin(), available.end(),\n             [&](int a, int b){ return tasks[a].total_req < tasks[b].total_req; });\n\n        /* -- 2. idle members -- */\n        vector<int> idle_members;\n        for (int j = 0; j < M; ++j)\n            if (member_status[j] == -1) idle_members.push_back(j);\n\n        /* -- 3. greedy matching -- */\n        vector<pair<int,int>> assignments;           // (member , task)\n        for (int j : idle_members) {\n            if (available.empty()) break;\n\n            int   best_task = -1;\n            double best_pred = 1e99;\n\n            for (size_t pos = 0; pos < available.size(); ++pos) {\n                int i = available[pos];\n                double pred = members[j].avg_time_per_unit * tasks[i].total_req;\n                if (pred < best_pred) {\n                    best_pred = pred;\n                    best_task = i;\n                }\n            }\n\n            if (best_task != -1) {\n                assignments.emplace_back(j, best_task);\n                // remove the chosen task from the vector (swap with back)\n                auto it = find(available.begin(), available.end(), best_task);\n                *it = available.back();\n                available.pop_back();\n            }\n        }\n\n        /* -- 4. output -- */\n        cout << assignments.size();\n        for (auto [mem, t] : assignments)\n            cout << ' ' << (mem + 1) << ' ' << (t + 1);\n        cout << '\\n';\n        cout.flush();\n\n        /* -- 5. update internal state -- */\n        for (auto [mem, t] : assignments) {\n            tasks[t].status = 0;\n            tasks[t].start_day = day;\n            tasks[t].assigned_to = mem;\n            member_status[mem] = t;\n            in_progress[t] = day;\n        }\n\n        /* -- 6. read completions -- */\n        int num_compl;  cin >> num_compl;\n        if (num_compl == -1) break;                 // finished or time limit\n\n        for (int i = 0; i < num_compl; ++i) {\n            int mem;  cin >> mem;  --mem;\n            int task = member_status[mem];\n            if (task == -1) continue;                // should never happen\n\n            int start_day = in_progress[task];\n            int t = day - start_day;                 // real processing time\n\n            Member &m = members[mem];\n            ++m.total_processed;\n            m.total_time += t;\n\n            // update average time per unit (exponential moving average)\n            int req = tasks[task].total_req;\n            if (req > 0) {\n                double this_avg = static_cast<double>(t) / req;\n                constexpr double alpha = 0.2;         // learning rate\n                m.avg_time_per_unit = (1.0 - alpha) * m.avg_time_per_unit\n                                      + alpha * this_avg;\n            }\n\n            // mark task completed\n            tasks[task].status = 1;\n            tasks[task].assigned_to = -1;\n            member_status[mem] = -1;\n            in_progress.erase(task);\n\n            // make dependent tasks available\n            for (int child : graph[task]) {\n                if (--tasks[child].indegree == 0) {\n                    // will be collected in the next day\n                }\n            }\n        }\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 1000;               // number of orders in the input\nconst int M = 50;                 // orders that have to be chosen\nconst int CENTER_X = 400;\nconst int CENTER_Y = 400;\n\n/*  order data  */\nint a[N], b[N], c_[N], d_[N];\nint internalDist[N];\nint startDist[N];\nint endDist[N];\nint between[N][N];                // delivery i -> pickup j\n\n/*  Manhattan distance  */\ninline int manh(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n/*  cost between two orders, -1 stands for the centre  */\ninline int costBetween(int from, int to) {\n    if (from == -1 && to == -1) return 0;\n    if (from == -1) return startDist[to];\n    if (to   == -1) return endDist[from];\n    return between[from][to];\n}\n\n/*  total travel time of a permutation (block order)  */\nint computeCost(const vector<int>& perm) {\n    int sum = 0;\n    for (int id : perm) sum += internalDist[id];\n    sum += startDist[perm[0]];\n    for (int i = 0; i + 1 < (int)perm.size(); ++i)\n        sum += between[perm[i]][perm[i + 1]];\n    sum += endDist[perm.back()];\n    return sum;\n}\n\n/* -------------------------------------------------------------\n   Greedy insertion \u2013 returns a feasible permutation\n   -------------------------------------------------------------\n*/\nvector<int> greedyInsertion(mt19937& rng) {\n    vector<int> path;                     // current permutation of orders\n    path.reserve(M);\n    vector<char> used(N, 0);               // order already taken ?\n\n    while ((int)path.size() < M) {\n        int bestTotal = INT_MAX;\n        int bestOrder = -1;\n        int bestPos   = -1;\n\n        for (int i = 0; i < N; ++i) if (!used[i]) {\n            int bestDelta = INT_MAX;\n            int bestPos_i = -1;\n            int sz = (int)path.size();\n            for (int pos = 0; pos <= sz; ++pos) {\n                int prev = (pos == 0) ? -1 : path[pos - 1];\n                int nxt  = (pos == sz) ? -1 : path[pos];\n                int delta = costBetween(prev, i) + costBetween(i, nxt)\n                            - costBetween(prev, nxt);\n                if (delta < bestDelta) {\n                    bestDelta = delta;\n                    bestPos_i = pos;\n                }\n            }\n            int totalIncrease = bestDelta + internalDist[i];\n            // random tie\u2011break\n            if (totalIncrease < bestTotal ||\n                (totalIncrease == bestTotal && (rng() & 1))) {\n                bestTotal = totalIncrease;\n                bestOrder = i;\n                bestPos   = bestPos_i;\n            }\n        }\n        // insert the chosen order\n        path.insert(path.begin() + bestPos, bestOrder);\n        used[bestOrder] = 1;\n    }\n    return path;\n}\n\n/* -------------------------------------------------------------\n   Simulated annealing on a permutation (keeps the set of orders)\n   -------------------------------------------------------------\n*/\nvector<int> simulatedAnnealing(const vector<int>& startPerm,\n                               mt19937& rng,\n                               double timeLimit)\n{\n    const double initTemp = 1000.0;\n    const int    movesPerStep = 2000;\n\n    vector<int> cur = startPerm;\n    vector<char> used(N, 0);\n    for (int v : cur) used[v] = 1;\n    int curCost = computeCost(cur);\n    int bestCost = curCost;\n    vector<int> best = cur;\n\n    double start = (double)clock() / CLOCKS_PER_SEC;\n    uniform_real_distribution<double> uni01(0.0, 1.0);\n    uniform_int_distribution<int> posDist(0, M - 1);\n    uniform_int_distribution<int> orderDist(0, N - 1);\n\n    while (true) {\n        double elapsed = (double)clock() / CLOCKS_PER_SEC - start;\n        if (elapsed > timeLimit) break;\n        double temperature = initTemp * (1.0 - elapsed / timeLimit);\n        if (temperature <= 0.0) break;\n\n        for (int step = 0; step < movesPerStep; ++step) {\n            int move = rng() % 4;                     // 0 swap,1 move,2 reverse,3 replace\n            vector<int> nxt = cur;\n            vector<char> nxtUsed = used;\n\n            if (move == 0) {                         // swap two positions\n                int i = posDist(rng), j = posDist(rng);\n                if (i == j) continue;\n                swap(nxt[i], nxt[j]);\n            }\n            else if (move == 1) {                    // move one order\n                int i = posDist(rng), j = posDist(rng);\n                if (i == j) continue;\n                int v = nxt[i];\n                nxt.erase(nxt.begin() + i);\n                nxt.insert(nxt.begin() + j, v);\n            }\n            else if (move == 2) {                    // reverse a segment\n                int i = posDist(rng), j = posDist(rng);\n                if (i >= j) continue;\n                reverse(nxt.begin() + i, nxt.begin() + j + 1);\n            }\n            else {                                    // replace one order\n                int i = posDist(rng);\n                int oldId = nxt[i];\n                int newId;\n                do { newId = orderDist(rng); } while (nxtUsed[newId]);\n                nxt[i] = newId;\n                nxtUsed[oldId] = 0;\n                nxtUsed[newId] = 1;\n            }\n\n            int nxtCost = computeCost(nxt);\n            int delta   = nxtCost - curCost;\n            double prob = (delta < 0) ? 1.0 : exp(-delta / temperature);\n            if (prob > uni01(rng)) {\n                cur.swap(nxt);\n                used.swap(nxtUsed);\n                curCost = nxtCost;\n                if (curCost < bestCost) {\n                    bestCost = curCost;\n                    best = cur;\n                }\n            }\n        }\n    }\n    return best;\n}\n\n/* -------------------------------------------------------------\n   Simple deterministic hill\u2011climbing (reverse / swap)\n   -------------------------------------------------------------\n*/\nvector<int> localImprove(vector<int> perm) {\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        // try to reverse a segment\n        for (int i = 0; i < M; ++i)\n            for (int j = i + 1; j < M; ++j) {\n                vector<int> cand = perm;\n                reverse(cand.begin() + i, cand.begin() + j + 1);\n                int candCost = computeCost(cand);\n                int curCost  = computeCost(perm);\n                if (candCost < curCost) {\n                    perm.swap(cand);\n                    improved = true;\n                    goto nextLoop;               // start again\n                }\n            }\n        // try to swap two positions\n        for (int i = 0; i < M; ++i)\n            for (int j = i + 1; j < M; ++j) {\n                vector<int> cand = perm;\n                swap(cand[i], cand[j]);\n                int candCost = computeCost(cand);\n                int curCost  = computeCost(perm);\n                if (candCost < curCost) {\n                    perm.swap(cand);\n                    improved = true;\n                    goto nextLoop;\n                }\n            }\n    nextLoop: ;\n    }\n    return perm;\n}\n\n/* -------------------------------------------------------------\n   Main\n   -------------------------------------------------------------\n*/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---- read input --------------------------------------------------- */\n    for (int i = 0; i < N; ++i) {\n        if (!(cin >> a[i] >> b[i] >> c_[i] >> d_[i])) return 0;\n    }\n\n    /* ---- pre\u2011compute all distances ------------------------------------ */\n    for (int i = 0; i < N; ++i) {\n        internalDist[i] = manh(a[i], b[i], c_[i], d_[i]);\n        startDist[i]    = manh(CENTER_X, CENTER_Y, a[i], b[i]);\n        endDist[i]      = manh(c_[i], d_[i], CENTER_X, CENTER_Y);\n        for (int j = 0; j < N; ++j)\n            between[i][j] = manh(c_[i], d_[i], a[j], b[j]);\n    }\n\n    /* ---- random generator -------------------------------------------- */\n    std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count());\n\n    /* ---- several runs ------------------------------------------------- */\n    const int runs = 3;\n    const double timePerRun = 1.8 / runs;\n\n    vector<int> bestOverall;\n    int bestOverallCost = INT_MAX;\n\n    for (int r = 0; r < runs; ++r) {\n        vector<int> init = greedyInsertion(rng);\n        vector<int> afterSA = simulatedAnnealing(init, rng, timePerRun);\n        vector<int> afterLocal = localImprove(afterSA);\n        int cost = computeCost(afterLocal);\n        if (cost < bestOverallCost) {\n            bestOverallCost = cost;\n            bestOverall = afterLocal;\n        }\n    }\n\n    /* ---- output ------------------------------------------------------- */\n    cout << \"50\";\n    for (int id : bestOverall) cout << ' ' << id + 1;\n    cout << '\\n';\n\n    cout << \"102 400 400\";\n    for (int id : bestOverall) {\n        cout << ' ' << a[id] << ' ' << b[id] << ' '\n             << c_[id] << ' ' << d_[id];\n    }\n    cout << \" 400 400\\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);\n        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\nstruct Edge {\n    int u, v;\n    int d;\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<pair<int,int>> coords(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    // Read edges and compute d_i\n    vector<Edge> edges(M);\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        cin >> u >> v;\n        edges[i].u = u;\n        edges[i].v = v;\n        long long dx = (long long)coords[u].first - coords[v].first;\n        long long dy = (long long)coords[u].second - coords[v].second;\n        double dist = sqrt((double)dx * dx + (double)dy * dy);\n        edges[i].d = (int)llround(dist);\n    }\n    \n    // Precompute T0: MST based on d_i\n    vector<int> edge_ids(M);\n    iota(edge_ids.begin(), edge_ids.end(), 0);\n    sort(edge_ids.begin(), edge_ids.end(), [&](int a, int b) {\n        return edges[a].d < edges[b].d;\n    });\n    \n    DSU dsu_t0(N);\n    vector<char> inT0(M, 0);\n    for (int idx : edge_ids) {\n        if (dsu_t0.unite(edges[idx].u, edges[idx].v)) {\n            inT0[idx] = 1;\n        }\n    }\n    \n    // Process edges online\n    DSU dsu(N);\n    int components = N;\n    \n    for (int i = 0; i < M; ++i) {\n        int l;\n        cin >> l;\n        \n        // If already connected, reject remaining edges\n        if (components == 1) {\n            cout << 0 << endl;\n            continue;\n        }\n        \n        int u = edges[i].u;\n        int v = edges[i].v;\n        \n        int ru = dsu.find(u);\n        int rv = dsu.find(v);\n        \n        // If edge creates a cycle, reject\n        if (ru == rv) {\n            cout << 0 << endl;\n            continue;\n        }\n        \n        // Always accept edges from T0 (guarantees connectivity)\n        bool accept = inT0[i];\n        \n        // For non-T0 edges, use rank-based selection\n        if (!accept) {\n            double d = edges[i].d;\n            double rank = (l - d) / (2.0 * d);\n            \n            // Clamp rank to [0,1] for safety\n            if (rank < 0.0) rank = 0.0;\n            if (rank > 1.0) rank = 1.0;\n            \n            // Dynamic threshold: 0.1 to 1.0\n            double progress = (double)i / (M - 1);\n            double threshold = 0.1 + 0.9 * progress;\n            \n            accept = (rank <= threshold);\n        }\n        \n        if (accept) {\n            dsu.unite(u, v);\n            --components;\n            cout << 1 << endl;\n        } else {\n            cout << 0 << endl;\n        }\n    }\n    \n    return 0;\n}","ahc008":"","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 20;\nconst int W = 20;\nconst int N = H * W;\nconst int INF = 1e9;\n\n/* ---------- global data ---------- */\nint start, target;\ndouble forgetP;                     // probability of forgetting a character\n\narray<array<int,4>,N> neighbour;   // neighbour[v][dir], dir = 0(U),1(D),2(L),3(R)\narray<char,4> dirChar{'U','D','L','R'};\narray<int,256> dirIdx;              // char -> 0..3, -1 = invalid\n\nvector<int> bfsDist;                // shortest deterministic distance to target\n\n/* ---------- evaluation of a route ---------- */\ndouble evaluate(const string &s) {\n    static vector<double> prob, nxt;\n    prob.assign(N, 0.0);\n    nxt.assign(N, 0.0);\n    prob[start] = 1.0;\n    double expected = 0.0;\n    int L = (int)s.size();\n\n    for (int turn = 1; turn <= L; ++turn) {\n        fill(nxt.begin(), nxt.end(), 0.0);\n        int d = dirIdx[(unsigned char)s[turn-1]];\n        double arrival = 0.0;\n\n        for (int v = 0; v < N; ++v) {\n            double cur = prob[v];\n            if (cur == 0.0) continue;\n            double stayProb = cur * forgetP;\n            double moveProb = cur * (1.0 - forgetP);\n            int w = neighbour[v][d];\n            if (w == target) arrival += moveProb;\n            else               nxt[w] += moveProb;\n            nxt[v] += stayProb;\n        }\n        expected += arrival * (401 - turn);\n        prob.swap(nxt);\n    }\n    return expected;\n}\n\n/* ---------- BFS on the grid (ignoring staying) ---------- */\nvector<int> bfs_from(int src) {\n    vector<int> dist(N, INF);\n    queue<int> q;\n    dist[src] = 0;\n    q.push(src);\n    while (!q.empty()) {\n        int v = q.front(); q.pop();\n        int dv = dist[v];\n        for (int dir = 0; dir < 4; ++dir) {\n            int w = neighbour[v][dir];\n            if (w == v) continue;               // blocked by wall\n            if (dist[w] == INF) {\n                dist[w] = dv + 1;\n                q.push(w);\n            }\n        }\n    }\n    return dist;\n}\n\n/* ---------- shortest deterministic path from S to T ---------- */\nvector<char> shortestPath() {\n    vector<int> parent(N, -1);\n    vector<char> pdir(N, 0);\n    vector<int> dist(N, -1);\n    queue<int> q;\n    q.push(start);\n    dist[start] = 0;\n    while (!q.empty()) {\n        int v = q.front(); q.pop();\n        if (v == target) break;\n        for (int dir = 0; dir < 4; ++dir) {\n            int w = neighbour[v][dir];\n            if (w == v) continue;\n            if (dist[w] == -1) {\n                dist[w] = dist[v] + 1;\n                parent[w] = v;\n                pdir[w] = dirChar[dir];\n                q.push(w);\n            }\n        }\n    }\n    vector<char> path;\n    int cur = target;\n    while (cur != start) {\n        path.push_back(pdir[cur]);\n        cur = parent[cur];\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n/* ---------- greedy construction (length = 200) ---------- */\nstring greedyRoute() {\n    const int L = 200;\n    string s;\n    s.reserve(L);\n    vector<double> prob(N, 0.0), nxt(N, 0.0);\n    prob[start] = 1.0;\n\n    for (int turn = 1; turn <= L; ++turn) {\n        double bestVal = -1e100;\n        int bestDir = -1;\n        vector<double> bestNxt(N, 0.0);\n        double bestArr = 0.0;\n\n        for (int dir = 0; dir < 4; ++dir) {\n            fill(nxt.begin(), nxt.end(), 0.0);\n            double arrival = 0.0;\n\n            for (int v = 0; v < N; ++v) {\n                double cur = prob[v];\n                if (cur == 0.0) continue;\n                double stayProb = cur * forgetP;\n                double moveProb = cur * (1.0 - forgetP);\n                int w = neighbour[v][dir];\n                if (w == target) arrival += moveProb;\n                else               nxt[w] += moveProb;\n                nxt[v] += stayProb;\n            }\n            double expDist = 0.0;\n            for (int v = 0; v < N; ++v) expDist += nxt[v] * bfsDist[v];\n\n            double value = arrival * (401 - turn) - expDist;\n            if (value > bestVal) {\n                bestVal = value;\n                bestDir = dir;\n                bestArr = arrival;\n                bestNxt.swap(nxt);\n            }\n        }\n        s.push_back(dirChar[bestDir]);\n        prob.swap(bestNxt);\n    }\n    return s;\n}\n\n/* ---------- random modification of a route ---------- */\nstring modify(const string &cur, int minLen, mt19937 &rng) {\n    string nxt = cur;\n    int L = (int)nxt.size();\n    uniform_int_distribution<int> opDist(0, 9);\n    int op = opDist(rng);\n    if (op < 7) { // replace\n        uniform_int_distribution<int> posDist(0, L - 1);\n        uniform_int_distribution<int> dirDist(0, 3);\n        int pos = posDist(rng);\n        nxt[pos] = dirChar[dirDist(rng)];\n    } else if (op < 9) { // insert\n        if (L < 200) {\n            uniform_int_distribution<int> posDist(0, L);\n            uniform_int_distribution<int> dirDist(0, 3);\n            int pos = posDist(rng);\n            nxt.insert(nxt.begin() + pos, dirChar[dirDist(rng)]);\n        } else {\n            uniform_int_distribution<int> posDist(0, L - 1);\n            uniform_int_distribution<int> dirDist(0, 3);\n            int pos = posDist(rng);\n            nxt[pos] = dirChar[dirDist(rng)];\n        }\n    } else { // delete\n        if (L > minLen) {\n            uniform_int_distribution<int> posDist(0, L - 1);\n            int pos = posDist(rng);\n            nxt.erase(nxt.begin() + pos);\n        } else {\n            uniform_int_distribution<int> posDist(0, L - 1);\n            uniform_int_distribution<int> dirDist(0, 3);\n            int pos = posDist(rng);\n            nxt[pos] = dirChar[dirDist(rng)];\n        }\n    }\n    return nxt;\n}\n\n/* ---------- main ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    /* ---- read input ---- */\n    int si, sj, ti, tj;\n    double p;\n    if (!(cin >> si >> sj >> ti >> tj >> p)) return 0;\n    start = si * W + sj;\n    target = ti * W + tj;\n    forgetP = p;\n\n    vector<string> h(H, string(W - 1, '0'));\n    for (int i = 0; i < H; ++i) cin >> h[i];\n    vector<string> v(H - 1, string(W, '0'));\n    for (int i = 0; i < H - 1; ++i) cin >> v[i];\n\n    /* ---- build neighbour table ---- */\n    for (int i = 0; i < H; ++i) {\n        for (int j = 0; j < W; ++j) {\n            int id = i * W + j;\n            // up\n            if (i == 0) neighbour[id][0] = id;\n            else if (v[i-1][j] == '1') neighbour[id][0] = id;\n            else neighbour[id][0] = (i-1) * W + j;\n            // down\n            if (i == H-1) neighbour[id][1] = id;\n            else if (v[i][j] == '1') neighbour[id][1] = id;\n            else neighbour[id][1] = (i+1) * W + j;\n            // left\n            if (j == 0) neighbour[id][2] = id;\n            else if (h[i][j-1] == '1') neighbour[id][2] = id;\n            else neighbour[id][2] = i * W + (j-1);\n            // right\n            if (j == W-1) neighbour[id][3] = id;\n            else if (h[i][j] == '1') neighbour[id][3] = id;\n            else neighbour[id][3] = i * W + (j+1);\n        }\n    }\n\n    // dirIdx\n    fill(dirIdx.begin(), dirIdx.end(), -1);\n    for (int d = 0; d < 4; ++d) dirIdx[(unsigned char)dirChar[d]] = d;\n\n    /* ---- BFS distances from target ---- */\n    bfsDist = bfs_from(target);\n\n    /* ---- build candidate routes ---- */\n    vector<string> candidates;\n    // 1) shortest path (maybe repeated twice)\n    vector<char> sp = shortestPath();\n    int spLen = (int)sp.size();\n    string cand1;\n    int repeat = (spLen * 2 <= 200) ? 2 : 1;\n    for (char c : sp) {\n        for (int i = 0; i < repeat; ++i) cand1.push_back(c);\n    }\n    candidates.push_back(cand1);\n    // 2) greedy route\n    candidates.push_back(greedyRoute());\n    // 3) random route (optional)\n    {\n        string rnd(200, 'U');\n        mt19937 rng(0);\n        uniform_int_distribution<int> dirDist(0,3);\n        for (char &c : rnd) c = dirChar[dirDist(rng)];\n        candidates.push_back(rnd);\n    }\n\n    /* ---- evaluate all candidates, keep the best ---- */\n    double bestScore = -1.0;\n    string bestRoute = candidates[0];\n    for (const string &cand : candidates) {\n        double sc = evaluate(cand);\n        if (sc > bestScore) {\n            bestScore = sc;\n            bestRoute = cand;\n        }\n    }\n\n    /* ---- hill climbing / simulated annealing ---- */\n    const double TIME_LIMIT = 1.8; // seconds\n    auto startTime = chrono::high_resolution_clock::now();\n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n\n    string cur = bestRoute;\n    double curScore = bestScore;\n    double temperature = 1.0;\n    int minLen = spLen; // we never delete below the original shortest\u2011path length\n\n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - startTime).count();\n        if (elapsed > TIME_LIMIT) break;\n\n        temperature *= 0.999;\n\n        string cand = modify(cur, minLen, rng);\n        double candScore = evaluate(cand);\n\n        double delta = candScore - curScore;\n        bool accept = (delta > 0.0);\n        if (!accept) {\n            uniform_real_distribution<double> uni(0.0, 1.0);\n            if (uni(rng) < exp(delta / temperature)) accept = true;\n        }\n        if (accept) {\n            cur = cand;\n            curScore = candScore;\n        }\n        if (candScore > bestScore) {\n            bestScore = candScore;\n            bestRoute = cand;\n        }\n    }\n\n    /* ---- output ---- */\n    cout << bestRoute << '\\n';\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Constants\nconst int H = 30, W = 30;\nconst int N = H * W;\nconst int DIR = 4;\nconst int NODE_COUNT = N * DIR;\n\n// Tile connection table: TO[t][d] = exit direction when entering tile type t from direction d\nconst int TO[8][4] = {\n    {1, 0, -1, -1},  // 0: left-up curve\n    {3, -1, -1, 0},  // 1: left-down curve\n    {-1, -1, 3, 2},  // 2: right-down curve\n    {-1, 2, 1, -1},  // 3: right-up curve\n    {1, 0, 3, 2},    // 4: double curve (left-up + right-down)\n    {3, 2, 1, 0},    // 5: double curve (left-down + right-up)\n    {2, -1, 0, -1},  // 6: horizontal line\n    {-1, 3, -1, 1}   // 7: vertical line\n};\n\n// Direction vectors: 0=left, 1=up, 2=right, 3=down\nconst int DI[4] = {0, -1, 0, 1};\nconst int DJ[4] = {-1, 0, 1, 0};\n\n// Rotation mapping: ROTATE_MAP[t][r] = effective type after r rotations\nint ROTATE_MAP[8][4];\n\nvoid init_rotate_map() {\n    const int ROT1[8] = {1, 2, 3, 0, 5, 4, 7, 6};\n    for (int t = 0; t < 8; ++t) {\n        ROTATE_MAP[t][0] = t;\n        int cur = t;\n        for (int r = 1; r < 4; ++r) {\n            cur = ROT1[cur];\n            ROTATE_MAP[t][r] = cur;\n        }\n    }\n}\n\n// Fast cycle detection for functional graph\npair<int, int> compute_score(const array<int, N>& rot, const array<int, N>& tiles) {\n    static array<int, NODE_COUNT> nxt;\n    static array<char, NODE_COUNT> state;\n    static vector<int> cycle_lens;\n    \n    // Build next array: for each node (cell, entry_dir), where does it go next?\n    for (int i = 0; i < H; ++i) {\n        for (int j = 0; j < W; ++j) {\n            int idx = i * W + j;\n            int t = tiles[idx];\n            int r = rot[idx];\n            int eff_type = ROTATE_MAP[t][r];\n            \n            int base = idx * DIR;\n            for (int d = 0; d < DIR; ++d) {\n                int d2 = TO[eff_type][d];\n                if (d2 == -1) {\n                    nxt[base + d] = -1;\n                    continue;\n                }\n                int ni = i + DI[d2];\n                int nj = j + DJ[d2];\n                if (ni < 0 || ni >= H || nj < 0 || nj >= W) {\n                    nxt[base + d] = -1;\n                    continue;\n                }\n                int nidx = ni * W + nj;\n                int nd = (d2 + 2) % DIR;\n                nxt[base + d] = nidx * DIR + nd;\n            }\n        }\n    }\n    \n    // Reset state\n    state.fill(0);\n    cycle_lens.clear();\n    \n    // Find cycles using DFS\n    vector<int> path;\n    path.reserve(NODE_COUNT);\n    \n    for (int s = 0; s < NODE_COUNT; ++s) {\n        if (state[s] != 0) continue;\n        \n        int cur = s;\n        path.clear();\n        \n        // Follow path\n        while (cur != -1 && state[cur] == 0) {\n            state[cur] = 1;\n            path.push_back(cur);\n            cur = nxt[cur];\n        }\n        \n        // Check if we found a cycle\n        if (cur != -1 && state[cur] == 1) {\n            // Find cycle start in path\n            int start_idx = -1;\n            for (int i = 0; i < (int)path.size(); ++i) {\n                if (path[i] == cur) {\n                    start_idx = i;\n                    break;\n                }\n            }\n            if (start_idx != -1) {\n                int len = (int)path.size() - start_idx;\n                cycle_lens.push_back(len);\n            }\n        }\n        \n        // Mark all visited nodes as done\n        for (int node : path) {\n            state[node] = 2;\n        }\n    }\n    \n    // Get top two cycle lengths\n    int L1 = 0, L2 = 0;\n    if (!cycle_lens.empty()) {\n        sort(cycle_lens.begin(), cycle_lens.end(), greater<int>());\n        L1 = cycle_lens[0];\n        if (cycle_lens.size() >= 2) L2 = cycle_lens[1];\n    }\n    \n    return {L1, L2};\n}\n\n// Greedy initialization: maximize local connections\nvoid greedy_init(array<int, N>& rot, const array<int, N>& tiles) {\n    for (int i = 0; i < H; ++i) {\n        for (int j = 0; j < W; ++j) {\n            int idx = i * W + j;\n            int t = tiles[idx];\n            int best_rot = 0;\n            int best_connections = -1;\n            \n            for (int r = 0; r < 4; ++r) {\n                int eff_type = ROTATE_MAP[t][r];\n                int connections = 0;\n                \n                // Count how many sides have valid connections\n                for (int d = 0; d < DIR; ++d) {\n                    int d2 = TO[eff_type][d];\n                    if (d2 == -1) continue;\n                    int ni = i + DI[d2];\n                    int nj = j + DJ[d2];\n                    if (ni >= 0 && ni < H && nj >= 0 && nj < W) {\n                        connections++;\n                    }\n                }\n                \n                if (connections > best_connections) {\n                    best_connections = connections;\n                    best_rot = r;\n                }\n            }\n            \n            rot[idx] = best_rot;\n        }\n    }\n}\n\n// Fast hill climbing with time limit\npair<array<int, N>, long long> hill_climbing(const array<int, N>& tiles) {\n    const double TIME_LIMIT = 1.9; // seconds (leave margin)\n    auto start_time = chrono::high_resolution_clock::now();\n    \n    random_device rd;\n    mt19937 rng(rd());\n    uniform_int_distribution<int> dist_tile(0, N-1);\n    uniform_int_distribution<int> dist_rot(0, 3);\n    \n    // Initialize with greedy solution\n    array<int, N> rot;\n    greedy_init(rot, tiles);\n    \n    // Evaluate initial solution\n    auto [L1, L2] = compute_score(rot, tiles);\n    long long best_score = (long long)L1 * L2;\n    array<int, N> best_rot = rot;\n    \n    // Hill climbing parameters\n    const int MAX_STALL = 5000; // Give up after this many non-improving moves\n    int stall_counter = 0;\n    long long current_score = best_score;\n    \n    while (true) {\n        // Check time limit\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > TIME_LIMIT) break;\n        \n        // Random restart if stuck\n        if (stall_counter > MAX_STALL) {\n            for (int i = 0; i < N; ++i) {\n                rot[i] = dist_rot(rng);\n            }\n            auto [new_L1, new_L2] = compute_score(rot, tiles);\n            current_score = (long long)new_L1 * new_L2;\n            if (current_score > best_score) {\n                best_score = current_score;\n                best_rot = rot;\n            }\n            stall_counter = 0;\n            continue;\n        }\n        \n        // Try flipping a random tile\n        int tile = dist_tile(rng);\n        int old_rot = rot[tile];\n        int new_rot;\n        do {\n            new_rot = dist_rot(rng);\n        } while (new_rot == old_rot);\n        \n        // Apply change\n        rot[tile] = new_rot;\n        auto [new_L1, new_L2] = compute_score(rot, tiles);\n        long long new_score = (long long)new_L1 * new_L2;\n        \n        // Acceptance decision (only if improving)\n        if (new_score > current_score) {\n            current_score = new_score;\n            stall_counter = 0;\n            if (new_score > best_score) {\n                best_score = new_score;\n                best_rot = rot;\n            }\n        } else {\n            // Revert change\n            rot[tile] = old_rot;\n            stall_counter++;\n        }\n    }\n    \n    return {best_rot, best_score};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    init_rotate_map();\n    \n    // Read input\n    array<int, N> tiles;\n    for (int i = 0; i < H; ++i) {\n        string line;\n        if (!(cin >> line)) return 0;\n        for (int j = 0; j < W; ++j) {\n            tiles[i * W + j] = line[j] - '0';\n        }\n    }\n    \n    // Run hill climbing\n    auto [best_rot, best_score] = hill_climbing(tiles);\n    \n    // Output result as 900-digit string\n    for (int i = 0; i < N; ++i) {\n        cout << best_rot[i];\n    }\n    cout << '\\n';\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Direction bit masks\nconst int DIR_LEFT = 1;   // 0001\nconst int DIR_UP = 2;     // 0010\nconst int DIR_RIGHT = 4;  // 0100\nconst int DIR_DOWN = 8;   // 1000\n\n// Movement vectors for [UP, DOWN, LEFT, RIGHT]\nconst int DR[4] = {-1, 1, 0, 0};\nconst int DC[4] = {0, 0, -1, 1};\nconst char MOVE_CHAR[4] = {'U', 'D', 'L', 'R'};\n\nclass SlidingTreePuzzle {\nprivate:\n    int N, T;\n    vector<int> board;  // 1D board representation\n    int emptyPos;       // Position of empty square\n    \n    // Check if tile has a line in specific direction\n    bool hasLine(int tile, int direction) {\n        return (tile & direction) != 0;\n    }\n    \n    // Get opposite direction\n    int opposite(int dir) {\n        switch(dir) {\n            case DIR_LEFT: return DIR_RIGHT;\n            case DIR_RIGHT: return DIR_LEFT;\n            case DIR_UP: return DIR_DOWN;\n            case DIR_DOWN: return DIR_UP;\n            default: return 0;\n        }\n    }\n    \n    // Convert 2D coordinates to 1D index\n    inline int idx(int r, int c) {\n        return r * N + c;\n    }\n    \n    // Check if position is within board bounds\n    inline bool inBounds(int r, int c) {\n        return r >= 0 && r < N && c >= 0 && c < N;\n    }\n    \n    // Evaluate board: returns size of largest tree component\n    int evaluate() {\n        vector<int> comp(N*N, -1);\n        vector<int> compSize;\n        vector<int> compEdges;\n        int compCount = 0;\n        \n        // Build adjacency list based on matching lines\n        vector<vector<int>> adj(N*N);\n        \n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                int pos = idx(r, c);\n                int tile = board[pos];\n                if (tile == 0) continue; // Skip empty square\n                \n                // Check right neighbor\n                if (c + 1 < N) {\n                    int npos = idx(r, c+1);\n                    int ntile = board[npos];\n                    if (ntile != 0 && hasLine(tile, DIR_RIGHT) && hasLine(ntile, DIR_LEFT)) {\n                        adj[pos].push_back(npos);\n                        adj[npos].push_back(pos);\n                    }\n                }\n                \n                // Check down neighbor\n                if (r + 1 < N) {\n                    int npos = idx(r+1, c);\n                    int ntile = board[npos];\n                    if (ntile != 0 && hasLine(tile, DIR_DOWN) && hasLine(ntile, DIR_UP)) {\n                        adj[pos].push_back(npos);\n                        adj[npos].push_back(pos);\n                    }\n                }\n            }\n        }\n        \n        // Find connected components using BFS\n        for (int i = 0; i < N*N; i++) {\n            if (board[i] == 0 || comp[i] != -1) continue;\n            \n            queue<int> q;\n            q.push(i);\n            comp[i] = compCount;\n            int size = 0;\n            \n            while (!q.empty()) {\n                int cur = q.front();\n                q.pop();\n                size++;\n                \n                for (int nxt : adj[cur]) {\n                    if (comp[nxt] == -1) {\n                        comp[nxt] = compCount;\n                        q.push(nxt);\n                    }\n                }\n            }\n            \n            compSize.push_back(size);\n            compEdges.push_back(0);\n            compCount++;\n        }\n        \n        // Count edges in each component (each edge counted once)\n        for (int i = 0; i < N*N; i++) {\n            if (board[i] == 0) continue;\n            for (int j : adj[i]) {\n                if (i < j) {\n                    int cid = comp[i];\n                    compEdges[cid]++;\n                }\n            }\n        }\n        \n        // Find largest tree component (edges == vertices - 1)\n        int best = 0;\n        for (int i = 0; i < compCount; i++) {\n            if (compEdges[i] == compSize[i] - 1) {\n                best = max(best, compSize[i]);\n            }\n        }\n        \n        return best;\n    }\n    \n    // Make a move in given direction, return move character\n    char makeMove(int dir) {\n        int r = emptyPos / N;\n        int c = emptyPos % N;\n        int nr = r + DR[dir];\n        int nc = c + DC[dir];\n        \n        if (!inBounds(nr, nc)) return '\\0';\n        \n        int npos = idx(nr, nc);\n        swap(board[emptyPos], board[npos]);\n        emptyPos = npos;\n        return MOVE_CHAR[dir];\n    }\n    \n    // Undo a move\n    void undoMove(int dir) {\n        int oppositeDir = (dir % 2 == 0) ? dir + 1 : dir - 1;\n        makeMove(oppositeDir);\n    }\n    \npublic:\n    // Solve the puzzle and return move sequence\n    string solve(int N_, int T_, const vector<int>& initialBoard) {\n        N = N_;\n        T = T_;\n        board = initialBoard;\n        \n        // Find empty position\n        for (int i = 0; i < N*N; i++) {\n            if (board[i] == 0) {\n                emptyPos = i;\n                break;\n            }\n        }\n        \n        // Initialize best solution tracking\n        vector<int> bestBoard = board;\n        int bestScore = evaluate();\n        string bestMoves = \"\";\n        string currentMoves = \"\";\n        \n        // Hill climbing with random restarts\n        double startTime = clock();\n        double timeLimit = 2.8; // Leave 0.2 sec margin\n        \n        int steps = 0;\n        while ((clock() - startTime) / CLOCKS_PER_SEC < timeLimit) {\n            // Periodically restart from initial state to escape local maxima\n            if (steps % 500 == 0 && steps > 0) {\n                board = initialBoard;\n                for (int i = 0; i < N*N; i++) {\n                    if (board[i] == 0) {\n                        emptyPos = i;\n                        break;\n                    }\n                }\n                currentMoves = \"\";\n            }\n            \n            // Try all 4 possible moves and select the best one\n            int bestDir = -1;\n            int bestMoveScore = -1;\n            \n            for (int dir = 0; dir < 4; dir++) {\n                int r = emptyPos / N;\n                int c = emptyPos % N;\n                int nr = r + DR[dir];\n                int nc = c + DC[dir];\n                \n                if (!inBounds(nr, nc)) continue;\n                \n                // Simulate the move\n                char moveChar = makeMove(dir);\n                int score = evaluate();\n                \n                // Select move if it improves score or randomly if equal\n                if (score > bestMoveScore || (score == bestMoveScore && rand() % 3 == 0)) {\n                    bestMoveScore = score;\n                    bestDir = dir;\n                }\n                \n                // Undo the move\n                undoMove(dir);\n            }\n            \n            // Apply the best move if it maintains or improves score\n            if (bestDir != -1 && bestMoveScore >= evaluate()) {\n                char moveChar = makeMove(bestDir);\n                currentMoves += moveChar;\n                \n                // Update best solution found\n                if (bestMoveScore > bestScore) {\n                    bestScore = bestMoveScore;\n                    bestBoard = board;\n                    bestMoves = currentMoves;\n                    \n                    // Early exit if full tree achieved\n                    if (bestScore == N*N - 1) {\n                        return bestMoves;\n                    }\n                }\n            } else {\n                // No improving move available, make a random move\n                vector<int> validDirs;\n                for (int dir = 0; dir < 4; dir++) {\n                    int r = emptyPos / N;\n                    int c = emptyPos % N;\n                    int nr = r + DR[dir];\n                    int nc = c + DC[dir];\n                    if (inBounds(nr, nc)) {\n                        validDirs.push_back(dir);\n                    }\n                }\n                \n                if (!validDirs.empty()) {\n                    int dir = validDirs[rand() % validDirs.size()];\n                    char moveChar = makeMove(dir);\n                    currentMoves += moveChar;\n                }\n            }\n            \n            steps++;\n            \n            // Reset if we exceed move limit\n            if ((int)currentMoves.size() > T) {\n                board = initialBoard;\n                for (int i = 0; i < N*N; i++) {\n                    if (board[i] == 0) {\n                        emptyPos = i;\n                        break;\n                    }\n                }\n                currentMoves = \"\";\n            }\n        }\n        \n        return bestMoves;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, T;\n    if (!(cin >> N >> T)) return 0;\n    \n    vector<int> board(N*N);\n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            char c = line[j];\n            if (c == '0') {\n                board[i*N + j] = 0;\n            } else {\n                // Parse hexadecimal digit (1-9, a-f)\n                int val = (c >= 'a') ? (c - 'a' + 10) : (c - '0');\n                board[i*N + j] = val;\n            }\n        }\n    }\n    \n    // Solve the puzzle\n    SlidingTreePuzzle solver;\n    string moves = solver.solve(N, T, board);\n    \n    // Output the move sequence\n    cout << moves << '\\n';\n    \n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nstruct Point { int x, y; };\nstruct Line {\n    long long A, B, C, x1, y1, x2, y2;\n    Line(long long a, long long b, long long c, long long d)\n        : x1(a), y1(b), x2(c), y2(d) {\n        A = y2 - y1;\n        B = x1 - x2;\n        C = -(A * x1 + B * y1);\n        long long g = std::gcd(std::gcd(abs(A), abs(B)), abs(C));\n        if (g > 0) { A /= g; B /= g; C /= g; }\n        if (A < 0 || (A == 0 && B < 0)) { A = -A; B = -B; C = -C; }\n    }\n    long long eval(const Point& p) const { return A * p.x + B * p.y + C; }\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    \n    vector<int> a(11);\n    for (int d = 1; d <= 10; d++) cin >> a[d];\n    \n    vector<Point> points(N);\n    for (int i = 0; i < N; i++) cin >> points[i].x >> points[i].y;\n    \n    vector<Line> lines;\n    vector<unsigned long long> signatures(N, 0);\n    vector<char> dead(N, 0);\n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<long long> dist(-1000000000LL, 1000000000LL);\n    \n    const int CANDIDATES = 25; // Drastically reduced for speed\n    \n    for (int iter = 0; iter < K; iter++) {\n        double best_score = -1;\n        Line best_line(0, 0, 1, 1);\n        \n        for (int c = 0; c < CANDIDATES; c++) {\n            // Generate random line\n            long long x1 = dist(rng), y1 = dist(rng);\n            long long x2 = dist(rng), y2 = dist(rng);\n            if (x1 == x2 && y1 == y2) x2++;\n            Line candidate(x1, y1, x2, y2);\n            \n            // Fast scoring with pre-allocated hash map\n            unordered_map<unsigned long long, int> groups;\n            groups.reserve(N / 2);\n            \n            for (int i = 0; i < N; i++) {\n                if (dead[i]) continue;\n                long long val = candidate.eval(points[i]);\n                if (val == 0) continue;\n                unsigned long long sig = signatures[i];\n                if (val > 0) sig |= (1ULL << iter);\n                groups[sig]++;\n            }\n            \n            int cnt[11] = {0};\n            for (auto& [sig, sz] : groups) {\n                if (sz >= 1 && sz <= 10) cnt[sz]++;\n            }\n            \n            double score = 0;\n            for (int d = 1; d <= 10; d++) score += min(a[d], cnt[d]);\n            \n            if (score > best_score) {\n                best_score = score;\n                best_line = candidate;\n            }\n        }\n        \n        // Apply best line\n        for (int i = 0; i < N; i++) {\n            if (dead[i]) continue;\n            long long val = best_line.eval(points[i]);\n            if (val == 0) dead[i] = 1;\n            else if (val > 0) signatures[i] |= (1ULL << iter);\n        }\n        lines.push_back(best_line);\n    }\n    \n    cout << lines.size() << \"\\n\";\n    for (auto& line : lines) {\n        auto clamp = [](long long v) {\n            return max(-1000000000LL, min(1000000000LL, v));\n        };\n        cout << clamp(line.x1) << \" \" << clamp(line.y1) << \" \"\n             << clamp(line.x2) << \" \" << clamp(line.y2) << \"\\n\";\n    }\n    return 0;\n}","ahc014":"struct Point { int x, y; };\nstruct Op { Point p[4]; }; // p[0] is new dot\n\nvector<vector<bool>> has_dot;          // Dot presence\nvector<vector<array<bool,4>>> edge;    // edge[x][y][dir] = used\nvector<vector<int>> weight;            // Precomputed weights\nvector<Op> operations;                 // Solution","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct UnionFind {\n    vector<int> parent, size;\n    UnionFind(int n = 0) { init(n); }\n    \n    void init(int n) {\n        parent.resize(n);\n        size.assign(n, 1);\n        iota(parent.begin(), parent.end(), 0);\n    }\n    \n    int find(int x) {\n        if (parent[x] == x) return x;\n        return parent[x] = find(parent[x]);\n    }\n    \n    void unite(int x, int y) {\n        x = find(x);\n        y = find(y);\n        if (x == y) return;\n        if (size[x] < size[y]) swap(x, y);\n        parent[y] = x;\n        size[x] += size[y];\n    }\n    \n    int getSize(int x) {\n        return size[find(x)];\n    }\n};\n\nclass CandyBox {\n    static const int H = 10;\n    static const int W = 10;\n    static const int N = H * W;\n    static const int SIM_COUNT = 25; // Monte Carlo simulations per direction\n    \n    array<array<int, W>, H> grid;\n    array<array<int, W>, H> tmpGrid;\n    mt19937 rng;\n    \npublic:\n    CandyBox() : rng(chrono::steady_clock::now().time_since_epoch().count()) {\n        for (int i = 0; i < H; i++)\n            grid[i].fill(0);\n    }\n    \n    // Place candy at p-th empty cell (1-indexed, row-major)\n    void placeCandy(int flavor, int p) {\n        int cnt = 0;\n        for (int i = 0; i < H; i++) {\n            for (int j = 0; j < W; j++) {\n                if (grid[i][j] == 0) {\n                    cnt++;\n                    if (cnt == p) {\n                        grid[i][j] = flavor;\n                        return;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Simulate tilting in direction d: 0=F, 1=B, 2=L, 3=R\n    void simulateTilt(int d, const array<array<int, W>, H>& src, array<array<int, W>, H>& dst) {\n        dst = src;\n        \n        if (d == 0) { // Forward (up)\n            for (int j = 0; j < W; j++) {\n                int writePos = 0;\n                for (int i = 0; i < H; i++) {\n                    if (dst[i][j] != 0) {\n                        if (i != writePos) {\n                            dst[writePos][j] = dst[i][j];\n                            dst[i][j] = 0;\n                        }\n                        writePos++;\n                    }\n                }\n            }\n        } else if (d == 1) { // Backward (down)\n            for (int j = 0; j < W; j++) {\n                int writePos = H - 1;\n                for (int i = H - 1; i >= 0; i--) {\n                    if (dst[i][j] != 0) {\n                        if (i != writePos) {\n                            dst[writePos][j] = dst[i][j];\n                            dst[i][j] = 0;\n                        }\n                        writePos--;\n                    }\n                }\n            }\n        } else if (d == 2) { // Left\n            for (int i = 0; i < H; i++) {\n                int writePos = 0;\n                for (int j = 0; j < W; j++) {\n                    if (dst[i][j] != 0) {\n                        if (j != writePos) {\n                            dst[i][writePos] = dst[i][j];\n                            dst[i][j] = 0;\n                        }\n                        writePos++;\n                    }\n                }\n            }\n        } else { // Right\n            for (int i = 0; i < H; i++) {\n                int writePos = W - 1;\n                for (int j = W - 1; j >= 0; j--) {\n                    if (dst[i][j] != 0) {\n                        if (j != writePos) {\n                            dst[i][writePos] = dst[i][j];\n                            dst[i][j] = 0;\n                        }\n                        writePos--;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Calculate score (sum of squares of component sizes) for a grid\n    long long calculateScore(const array<array<int, W>, H>& g) {\n        UnionFind uf(N);\n        int id[H][W];\n        int curId = 0;\n        \n        // Assign IDs to occupied cells\n        for (int i = 0; i < H; i++) {\n            for (int j = 0; j < W; j++) {\n                if (g[i][j] != 0) {\n                    id[i][j] = curId++;\n                } else {\n                    id[i][j] = -1;\n                }\n            }\n        }\n        \n        // Union adjacent same-flavor cells\n        const int dr[4] = {-1, 1, 0, 0};\n        const int dc[4] = {0, 0, -1, 1};\n        \n        for (int i = 0; i < H; i++) {\n            for (int j = 0; j < W; j++) {\n                if (id[i][j] == -1) continue;\n                for (int dir = 0; dir < 4; dir++) {\n                    int ni = i + dr[dir];\n                    int nj = j + dc[dir];\n                    if (ni >= 0 && ni < H && nj >= 0 && nj < W && id[ni][nj] != -1) {\n                        if (g[i][j] == g[ni][nj]) {\n                            uf.unite(id[i][j], id[ni][nj]);\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Calculate sum of squares of component sizes\n        long long score = 0;\n        vector<char> visited(curId, 0);\n        for (int i = 0; i < curId; i++) {\n            int root = uf.find(i);\n            if (!visited[root]) {\n                int size = uf.getSize(root);\n                score += 1LL * size * size;\n                visited[root] = 1;\n            }\n        }\n        return score;\n    }\n    \n    // Run Monte Carlo simulation for a given direction\n    long long simulateMonteCarlo(int initialDir, const vector<int>& flavors, int currentStep) {\n        long long totalScore = 0;\n        array<array<int, W>, H> simGrid;\n        \n        // Apply initial tilt\n        simulateTilt(initialDir, grid, simGrid);\n        \n        // Simulate remaining steps multiple times\n        for (int sim = 0; sim < SIM_COUNT; sim++) {\n            array<array<int, W>, H> copy = simGrid;\n            \n            // Simulate remaining placements and tilts\n            for (int step = currentStep + 1; step < 100; step++) {\n                // Count empty cells\n                vector<pair<int, int>> emptyCells;\n                for (int i = 0; i < H; i++) {\n                    for (int j = 0; j < W; j++) {\n                        if (copy[i][j] == 0) {\n                            emptyCells.emplace_back(i, j);\n                        }\n                    }\n                }\n                \n                if (emptyCells.empty()) break;\n                \n                // Place candy at random empty position\n                int pos = rng() % emptyCells.size();\n                copy[emptyCells[pos].first][emptyCells[pos].second] = flavors[step];\n                \n                // Tilt (skip last step)\n                if (step < 99) {\n                    int dir = rng() % 4; // Random tilt for simulation\n                    array<array<int, W>, H> newGrid;\n                    simulateTilt(dir, copy, newGrid);\n                    copy = newGrid;\n                }\n            }\n            \n            totalScore += calculateScore(copy);\n        }\n        \n        return totalScore / SIM_COUNT;\n    }\n    \n    // Choose best direction with Monte Carlo lookahead for early steps\n    char chooseDirection(const vector<int>& flavors, int currentStep) {\n        // For early steps, use Monte Carlo to look ahead\n        // For later steps, use greedy (less future to consider)\n        if (currentStep < 75) {\n            long long mcScores[4];\n            for (int d = 0; d < 4; d++) {\n                mcScores[d] = simulateMonteCarlo(d, flavors, currentStep);\n            }\n            \n            // Choose direction with best MC score\n            int bestDir = 0;\n            for (int d = 1; d < 4; d++) {\n                if (mcScores[d] > mcScores[bestDir]) {\n                    bestDir = d;\n                }\n            }\n            \n            // Apply best tilt\n            simulateTilt(bestDir, grid, grid);\n            const char dirChar[4] = {'F', 'B', 'L', 'R'};\n            return dirChar[bestDir];\n        } else {\n            // Use greedy for later steps\n            long long bestScore = -1;\n            int bestDir = 0;\n            \n            for (int d = 0; d < 4; d++) {\n                simulateTilt(d, grid, tmpGrid);\n                long long score = calculateScore(tmpGrid);\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestDir = d;\n                }\n            }\n            \n            // Apply best tilt\n            simulateTilt(bestDir, grid, grid);\n            const char dirChar[4] = {'F', 'B', 'L', 'R'};\n            return dirChar[bestDir];\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read flavors\n    vector<int> flavors(100);\n    for (int i = 0; i < 100; i++) {\n        if (!(cin >> flavors[i])) return 0;\n    }\n    \n    CandyBox box;\n    \n    for (int step = 0; step < 100; step++) {\n        int p;\n        cin >> p;\n        \n        box.placeCandy(flavors[step], p);\n        \n        char dir = box.chooseDirection(flavors, step);\n        cout << dir << endl;\n    }\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    const double epsilon = eps;\n    const bool noiseless = (epsilon < 1e-12);\n    int N;                     // number of vertices\n\n    /* -------------------------------------------------------------\n       choose N\n       ------------------------------------------------------------- */\n    if (noiseless) {\n        // N = 5 is enough: 2^10 = 1024 > 100\n        N = 5;\n    } else {\n        double I = log2(max(2, M));          // bits to transmit\n        double H = -epsilon * log2(epsilon) - (1.0 - epsilon) * log2(1.0 - epsilon);\n        double C = 1.0 - H;                  // capacity per edge\n        double need = (I + 5.0) / C;         // a few redundant bits (5 instead of 3)\n        int needEdges = (int)ceil(need);\n        // solve N(N-1)/2 >= needEdges\n        double disc = 1.0 + 8.0 * needEdges;\n        double sq = sqrt(disc);\n        N = (int)ceil((1.0 + sq) / 2.0);\n        if (N < 4) N = 4;\n        if (N > 100) N = 100;\n    }\n\n    const int n = N;\n    const int tot = n * (n - 1) / 2;\n\n    /* -------------------------------------------------------------\n       generate the M graphs (deterministic)\n       ------------------------------------------------------------- */\n    // adjacency matrix G[i][u][v] (0/1)\n    vector<vector<vector<char>>> G(M,\n        vector<vector<char>>(n, vector<char>(n, 0)));\n\n    // vertex order sorted by degree (used for alignment in noiseless case)\n    vector<vector<int>> orderG(M, vector<int>(n));\n    // sorted degree sequences (decreasing)\n    vector<vector<int>> sortedDeg(M, vector<int>(n));\n    // triangle count\n    vector<int> tri(M, 0);\n\n    for (int i = 0; i < M; ++i) {\n        mt19937 rng(i * 10007 + M * 12345 + n * 6789 + 42);\n        uniform_int_distribution<int> dist(0, 1);\n\n        for (int u = 0; u < n; ++u)\n            for (int v = u + 1; v < n; ++v) {\n                char e = (char)dist(rng);\n                G[i][u][v] = G[i][v][u] = e;\n            }\n\n        // degree of each vertex\n        vector<int> deg(n, 0);\n        for (int u = 0; u < n; ++u) {\n            int s = 0;\n            for (int v = 0; v < n; ++v) if (u != v) s += G[i][u][v];\n            deg[u] = s;\n        }\n\n        // order by decreasing degree, tie\u2011break by index\n        vector<int> idx(n);\n        iota(idx.begin(), idx.end(), 0);\n        sort(idx.begin(), idx.end(),\n             [&](int a, int b) {\n                 if (deg[a] != deg[b]) return deg[a] > deg[b];\n                 return a < b;\n             });\n        orderG[i] = idx;\n\n        // sorted degree sequence (decreasing)\n        vector<int> sd = deg;\n        sort(sd.begin(), sd.end(), greater<int>());\n        sortedDeg[i] = sd;\n\n        // count triangles\n        int t = 0;\n        for (int u = 0; u < n; ++u)\n            for (int v = u + 1; v < n; ++v) if (G[i][u][v])\n                for (int w = v + 1; w < n; ++w)\n                    if (G[i][u][w] && G[i][v][w]) ++t;\n        tri[i] = t;\n    }\n\n    /* -------------------------------------------------------------\n       output the graphs\n       ------------------------------------------------------------- */\n    cout << n << '\\n';\n    for (int i = 0; i < M; ++i) {\n        string line;\n        line.reserve(tot);\n        for (int u = 0; u < n; ++u)\n            for (int v = u + 1; v < n; ++v)\n                line.push_back(G[i][u][v] ? '1' : '0');\n        cout << line << '\\n';\n    }\n    cout.flush();\n\n    /* -------------------------------------------------------------\n       pre\u2011compute all permutations (only needed for noiseless case)\n       ------------------------------------------------------------- */\n    vector<vector<int>> perms;\n    if (noiseless) {\n        vector<int> p(n);\n        iota(p.begin(), p.end(), 0);\n        do {\n            perms.push_back(p);\n        } while (next_permutation(p.begin(), p.end()));\n    }\n\n    /* -------------------------------------------------------------\n       answer the 100 queries\n       ------------------------------------------------------------- */\n    for (int q = 0; q < 100; ++q) {\n        string Hstr;\n        cin >> Hstr;\n\n        // adjacency of H (only needed for noiseless case)\n        vector<vector<char>> B(n, vector<char>(n, 0));\n        vector<int> degH(n, 0);\n        int pos = 0;\n        for (int u = 0; u < n; ++u) {\n            for (int v = u + 1; v < n; ++v) {\n                char c = (char)(Hstr[pos++] - '0');\n                B[u][v] = B[v][u] = c;\n                if (c) {\n                    ++degH[u];\n                    ++degH[v];\n                }\n            }\n        }\n\n        int answer = 0;\n\n        if (noiseless) {\n            // exact isomorphism test (N \u2264 5 \u2192 at most 120 permutations)\n            bool found = false;\n            for (int i = 0; i < M && !found; ++i) {\n                for (const auto &perm : perms) {\n                    bool ok = true;\n                    for (int u = 0; u < n && ok; ++u) {\n                        int pu = perm[u];\n                        for (int v = u + 1; v < n; ++v) {\n                            int pv = perm[v];\n                            if (G[i][u][v] != B[pu][pv]) {\n                                ok = false;\n                                break;\n                            }\n                        }\n                    }\n                    if (ok) {\n                        answer = i;\n                        found = true;\n                        break;\n                    }\n                }\n            }\n        } else {\n            // ----- permutation\u2011invariant features -----\n            // sorted degree sequence of H\n            vector<int> sdH = degH;\n            sort(sdH.begin(), sdH.end(), greater<int>());\n\n            // triangle count of H\n            int triH = 0;\n            for (int u = 0; u < n; ++u)\n                for (int v = u + 1; v < n; ++v) if (B[u][v])\n                    for (int w = v + 1; w < n; ++w)\n                        if (B[u][w] && B[v][w]) ++triH;\n\n            // distance to every code word\n            int bestDist = INT_MAX;\n            for (int i = 0; i < M; ++i) {\n                // L1 distance of sorted degree sequences\n                int d = 0;\n                for (int k = 0; k < n; ++k) {\n                    d += abs(sortedDeg[i][k] - sdH[k]);\n                    if (d >= bestDist) break;\n                }\n                // add triangle difference (weighted by n to make it comparable)\n                d += n * abs(tri[i] - triH);\n                if (d < bestDist) {\n                    bestDist = d;\n                    answer = i;\n                }\n            }\n        }\n\n        cout << answer << '\\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    long long w;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n\n    vector<Edge> edges(M);\n    vector<vector<pair<int,int>>> adj(N);          // (to , edge id)\n    for (int i = 0; i < M; ++i) {\n        int a, b;\n        long long w;\n        cin >> a >> b >> w;\n        --a; --b;\n        edges[i] = {a, b, w};\n        adj[a].push_back({b, i});\n        adj[b].push_back({a, i});\n    }\n    // read the coordinates, they are not needed\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        (void)x; (void)y;\n    }\n\n    const long long INF = (1LL << 60);\n\n    /* ----------------------------------------------------------\n       1.  Edge betweenness centrality (Brandes, weighted)\n       ---------------------------------------------------------- */\n    vector<double> ebc(M, 0.0);\n    vector<long long> dist(N);\n    vector<double> sigma(N), delta(N);\n    vector<vector<pair<int,int>>> pred(N);\n    vector<int> order(N);\n\n    for (int s = 0; s < N; ++s) {\n        fill(dist.begin(), dist.end(), INF);\n        fill(sigma.begin(), sigma.end(), 0.0);\n        for (int i = 0; i < N; ++i) pred[i].clear();\n\n        priority_queue<pair<long long,int>, vector<pair<long long,int>>, greater<pair<long long,int>>> pq;\n        dist[s] = 0;\n        sigma[s] = 1.0;\n        pq.emplace(0, s);\n\n        while (!pq.empty()) {\n            auto [d, v] = pq.top(); pq.pop();\n            if (d != dist[v]) continue;\n            for (auto [to, eid] : adj[v]) {\n                long long nd = d + edges[eid].w;\n                if (dist[to] > nd) {\n                    dist[to] = nd;\n                    sigma[to] = sigma[v];\n                    pred[to].clear();\n                    pred[to].emplace_back(v, eid);\n                    pq.emplace(nd, to);\n                } else if (dist[to] == nd) {\n                    sigma[to] += sigma[v];\n                    pred[to].emplace_back(v, eid);\n                }\n            }\n        }\n\n        // vertices in decreasing order of distance\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(),\n             [&](int a, int b){ return dist[a] > dist[b]; });\n\n        fill(delta.begin(), delta.end(), 0.0);\n\n        for (int v : order) {\n            if (dist[v] == INF) continue;\n            for (auto [u, eid] : pred[v]) {\n                double coeff = sigma[u] / sigma[v];\n                double contrib = coeff * (1.0 + delta[v]);\n                ebc[eid] += contrib;\n                delta[u] += contrib;\n            }\n        }\n    }\n\n    for (int i = 0; i < M; ++i) ebc[i] *= 0.5;          // undirected\n\n    /* ----------------------------------------------------------\n       2.  Score of an edge (here only betweenness)\n       ---------------------------------------------------------- */\n    vector<double> score(M);\n    for (int i = 0; i < M; ++i) score[i] = ebc[i];      // * edges[i].w possible\n\n    /* ----------------------------------------------------------\n       3.  Greedy LPT assignment, several random restarts\n       ---------------------------------------------------------- */\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    vector<int> best_assign(M);\n    double best_obj = 1e100;\n    vector<int> order_edges(M);\n    iota(order_edges.begin(), order_edges.end(), 0);\n\n    int restarts = 5;                     // enough, can be increased if time permits\n    for (int rep = 0; rep < restarts; ++rep) {\n        shuffle(order_edges.begin(), order_edges.end(), rng);\n        vector<int> assign(M, -1);\n        vector<double> day_sum(D, 0.0);\n        vector<int> day_cnt(D, 0);\n\n        for (int eid : order_edges) {\n            // choose a day with free capacity and minimal current sum\n            int best_day = -1;\n            double best_val = 1e200;\n            for (int d = 0; d < D; ++d) {\n                if (day_cnt[d] >= K) continue;\n                if (day_sum[d] < best_val) {\n                    best_val = day_sum[d];\n                    best_day = d;\n                }\n            }\n            // it is guaranteed that such a day exists\n            assign[eid] = best_day;\n            day_sum[best_day] += score[eid];\n            day_cnt[best_day]++;\n        }\n\n        double obj = 0.0;\n        for (int d = 0; d < D; ++d) obj += day_sum[d] * day_sum[d];\n        if (obj < best_obj) {\n            best_obj = obj;\n            best_assign = assign;\n        }\n    }\n\n    /* ----------------------------------------------------------\n       4.  Simple hill climbing (improves the surrogate)\n       ---------------------------------------------------------- */\n    vector<int> assign = best_assign;\n    vector<double> day_sum(D, 0.0);\n    vector<int> day_cnt(D, 0);\n    for (int e = 0; e < M; ++e) {\n        int d = assign[e];\n        day_sum[d] += score[e];\n        day_cnt[d]++;\n    }\n\n    uniform_int_distribution<int> edge_dist(0, M - 1);\n    uniform_int_distribution<int> day_dist(0, D - 1);\n    const int HILL_ITER = 20000;          // works well, can be tuned\n    for (int it = 0; it < HILL_ITER; ++it) {\n        int e = edge_dist(rng);\n        int cur = assign[e];\n        if (day_cnt[cur] == 0) continue; // should never happen\n\n        // look for a different day with free capacity\n        int nd = day_dist(rng);\n        if (nd == cur || day_cnt[nd] >= K) continue;\n\n        double cur_sum = day_sum[cur];\n        double new_sum = day_sum[nd];\n        double old_contrib = cur_sum * cur_sum + new_sum * new_sum;\n        double new_contrib = (cur_sum - score[e]) * (cur_sum - score[e]) +\n                             (new_sum + score[e]) * (new_sum + score[e]);\n        if (new_contrib < old_contrib - 1e-12) {\n            // accept move\n            assign[e] = nd;\n            day_sum[cur] -= score[e];\n            day_sum[nd] += score[e];\n            day_cnt[cur]--;\n            day_cnt[nd]++;\n        }\n    }\n\n    /* ----------------------------------------------------------\n       5.  Output\n       ---------------------------------------------------------- */\n    for (int i = 0; i < M; ++i) {\n        if (i) cout << ' ';\n        cout << assign[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    \n    int D;\n    if (!(cin >> D)) return 0;\n\n    // read silhouettes in the correct order\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    // assign to arrays f[2] and r[2]\n    vector<string> f[2], r[2];\n    f[0] = f1; r[0] = r1;\n    f[1] = f2; r[1] = r2;\n\n    // data for both objects\n    vector<vector<int>> X[2], Y[2];\n    vector<vector<pair<int,int>>> intX[2], intY[2];\n    for (int i = 0; i < 2; ++i) {\n        X[i].assign(D, {});\n        Y[i].assign(D, {});\n        intX[i].assign(D, {});\n        intY[i].assign(D, {});\n        for (int z = 0; z < D; ++z) {\n            for (int x = 0; x < D; ++x)\n                if (f[i][z][x] == '1') X[i][z].push_back(x);\n            for (int y = 0; y < D; ++y)\n                if (r[i][z][y] == '1') Y[i][z].push_back(y);\n            // intervals of 1s in f\n            const string &sf = f[i][z];\n            for (int x = 0; x < D; ) {\n                if (sf[x] == '0') { ++x; continue; }\n                int s = x;\n                while (x < D && sf[x] == '1') ++x;\n                int e = x - 1;\n                intX[i][z].push_back({s, e});\n            }\n            // intervals of 1s in r\n            const string &sr = r[i][z];\n            for (int y = 0; y < D; ) {\n                if (sr[y] == '0') { ++y; continue; }\n                int s = y;\n                while (y < D && sr[y] == '1') ++y;\n                int e = y - 1;\n                intY[i][z].push_back({s, e});\n            }\n        }\n    }\n\n    // count bars for each orientation\n    vector<int> cntV[2], cntH[2];\n    cntV[0].assign(D+1, 0); cntV[1].assign(D+1, 0);\n    cntH[0].assign(D+1, 0); cntH[1].assign(D+1, 0);\n    for (int i = 0; i < 2; ++i) {\n        for (int z = 0; z < D; ++z) {\n            // vertical bars (use Y intervals)\n            for (auto &pr : intY[i][z]) {\n                int len = pr.second - pr.first + 1;\n                cntV[i][len] += (int)X[i][z].size();\n            }\n            // horizontal bars (use X intervals)\n            for (auto &pr : intX[i][z]) {\n                int len = pr.second - pr.first + 1;\n                cntH[i][len] += (int)Y[i][z].size();\n            }\n        }\n    }\n\n    // choose the best orientation (both objects must use the same)\n    double bestScore = 1e100;\n    int bestO = -1; // 0 = vertical, 1 = horizontal\n    for (int o = 0; o < 2; ++o) {\n        const vector<int> &a = (o ? cntH[0] : cntV[0]);\n        const vector<int> &b = (o ? cntH[1] : cntV[1]);\n        double score = 0.0;\n        for (int L = 1; L <= D; ++L) {\n            int s = min(a[L], b[L]);\n            int diff = abs(a[L] - b[L]);\n            score += diff * L + (double)s / L;\n        }\n        if (score < bestScore) {\n            bestScore = score;\n            bestO = o;\n        }\n    }\n\n    // final counts according to the chosen orientation\n    vector<int> aCnt = (bestO ? cntH[0] : cntV[0]);\n    vector<int> bCnt = (bestO ? cntH[1] : cntV[1]);\n\n    // create block IDs\n    vector<vector<int>> sharedId(D+1), only1Id(D+1), only2Id(D+1);\n    int totalBlocks = 0;\n    for (int L = 1; L <= D; ++L) {\n        int s = min(aCnt[L], bCnt[L]);\n        for (int k = 0; k < s; ++k) sharedId[L].push_back(++totalBlocks);\n        for (int k = 0; k < aCnt[L] - s; ++k) only1Id[L].push_back(++totalBlocks);\n        for (int k = 0; k < bCnt[L] - s; ++k) only2Id[L].push_back(++totalBlocks);\n    }\n\n    // 3D output arrays (flat)\n    vector<int> b1(D*D*D, 0), b2(D*D*D, 0);\n    auto index = [&](int x, int y, int z) { return x*D*D + y*D + z; };\n\n    // ----- place object 1 -----\n    vector<int> ptrS(D+1, 0), ptr1(D+1, 0);\n    if (bestO == 0) { // vertical\n        for (int z = 0; z < D; ++z) {\n            for (auto &pr : intY[0][z]) {\n                int len = pr.second - pr.first + 1;\n                int y1 = pr.first, y2 = pr.second;\n                for (int x : X[0][z]) {\n                    int id;\n                    if (ptrS[len] < (int)sharedId[len].size())\n                        id = sharedId[len][ptrS[len]++];\n                    else\n                        id = only1Id[len][ptr1[len]++];\n                    for (int y = y1; y <= y2; ++y)\n                        b1[index(x, y, z)] = id;\n                }\n            }\n        }\n    } else { // horizontal\n        for (int z = 0; z < D; ++z) {\n            for (auto &pr : intX[0][z]) {\n                int len = pr.second - pr.first + 1;\n                int x1 = pr.first, x2 = pr.second;\n                for (int y : Y[0][z]) {\n                    int id;\n                    if (ptrS[len] < (int)sharedId[len].size())\n                        id = sharedId[len][ptrS[len]++];\n                    else\n                        id = only1Id[len][ptr1[len]++];\n                    for (int x = x1; x <= x2; ++x)\n                        b1[index(x, y, z)] = id;\n                }\n            }\n        }\n    }\n\n    // ----- place object 2 (same orientation as object 1) -----\n    vector<int> ptrS2(D+1, 0), ptr2(D+1, 0);\n    if (bestO == 0) { // vertical\n        for (int z = 0; z < D; ++z) {\n            for (auto &pr : intY[1][z]) {\n                int len = pr.second - pr.first + 1;\n                int y1 = pr.first, y2 = pr.second;\n                for (int x : X[1][z]) {\n                    int id;\n                    if (ptrS2[len] < (int)sharedId[len].size())\n                        id = sharedId[len][ptrS2[len]++];\n                    else\n                        id = only2Id[len][ptr2[len]++];\n                    for (int y = y1; y <= y2; ++y)\n                        b2[index(x, y, z)] = id;\n                }\n            }\n        }\n    } else { // horizontal\n        for (int z = 0; z < D; ++z) {\n            for (auto &pr : intX[1][z]) {\n                int len = pr.second - pr.first + 1;\n                int x1 = pr.first, x2 = pr.second;\n                for (int y : Y[1][z]) {\n                    int id;\n                    if (ptrS2[len] < (int)sharedId[len].size())\n                        id = sharedId[len][ptrS2[len]++];\n                    else\n                        id = only2Id[len][ptr2[len]++];\n                    for (int x = x1; x <= x2; ++x)\n                        b2[index(x, y, z)] = id;\n                }\n            }\n        }\n    }\n\n    // ----- output -----\n    cout << totalBlocks << '\\n';\n    for (int i = 0; i < D*D*D; ++i) {\n        if (i) cout << ' ';\n        cout << b1[i];\n    }\n    cout << '\\n';\n    for (int i = 0; i < D*D*D; ++i) {\n        if (i) cout << ' ';\n        cout << b2[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v;\n    long long w;\n    double dist;\n};\n\nstruct Station {\n    long long x, y;\n};\n\nstruct Resident {\n    long long a, b;\n};\n\nstruct DSU {\n    vector<int> p, r;\n    DSU(int n) : p(n), r(n, 0) { iota(p.begin(), p.end(), 0); }\n    int find(int x) { return p[x] == x ? x : p[x] = find(p[x]); }\n    bool unite(int a, int b) {\n        a = find(a);\n        b = find(b);\n        if (a == b) return false;\n        if (r[a] < r[b]) swap(a, b);\n        p[b] = a;\n        if (r[a] == r[b]) r[a]++;\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n    \n    vector<Station> stations(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> stations[i].x >> stations[i].y;\n    }\n    \n    vector<Edge> edges(M);\n    vector<vector<pair<int, int>>> adj(N);\n    for (int j = 0; j < M; ++j) {\n        cin >> edges[j].u >> edges[j].v >> edges[j].w;\n        edges[j].u--;\n        edges[j].v--;\n        long long dx = stations[edges[j].u].x - stations[edges[j].v].x;\n        long long dy = stations[edges[j].u].y - stations[edges[j].v].y;\n        edges[j].dist = sqrt((double)dx * dx + (double)dy * dy);\n        adj[edges[j].u].push_back({edges[j].v, j});\n        adj[edges[j].v].push_back({edges[j].u, j});\n    }\n    \n    vector<Resident> residents(K);\n    for (int k = 0; k < K; ++k) {\n        cin >> residents[k].a >> residents[k].b;\n    }\n    \n    // Precompute distances from each resident to each station\n    // resident_stations[k] is sorted by distance\n    vector<vector<pair<double, int>>> resident_stations(K);\n    for (int k = 0; k < K; ++k) {\n        resident_stations[k].reserve(N);\n        for (int i = 0; i < N; ++i) {\n            long long dx = residents[k].a - stations[i].x;\n            long long dy = residents[k].b - stations[i].y;\n            double dist = sqrt((double)dx * dx + (double)dy * dy);\n            resident_stations[k].push_back({dist, i});\n        }\n        sort(resident_stations[k].begin(), resident_stations[k].end(),\n            [](const pair<double, int>& a, const pair<double, int>& b) {\n                return a.first < b.first;\n            });\n    }\n    \n    // Generate candidate spanning trees\n    vector<vector<int>> candidate_trees;\n    \n    // Candidate 1: Standard MST using edge weight w\n    {\n        DSU dsu(N);\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int i, int j) {\n            return edges[i].w < edges[j].w;\n        });\n        \n        vector<int> tree_edges;\n        for (int idx : order) {\n            if (dsu.unite(edges[idx].u, edges[idx].v)) {\n                tree_edges.push_back(idx);\n                if ((int)tree_edges.size() == N - 1) break;\n            }\n        }\n        if ((int)tree_edges.size() == N - 1) {\n            candidate_trees.push_back(tree_edges);\n        }\n    }\n    \n    // Candidate 2: MST using weight = w / (dist + 1)\n    {\n        DSU dsu(N);\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int i, int j) {\n            double wi = (double)edges[i].w / (edges[i].dist + 1.0);\n            double wj = (double)edges[j].w / (edges[j].dist + 1.0);\n            return wi < wj;\n        });\n        \n        vector<int> tree_edges;\n        for (int idx : order) {\n            if (dsu.unite(edges[idx].u, edges[idx].v)) {\n                tree_edges.push_back(idx);\n                if ((int)tree_edges.size() == N - 1) break;\n            }\n        }\n        if ((int)tree_edges.size() == N - 1) {\n            candidate_trees.push_back(tree_edges);\n        }\n    }\n    \n    // Candidate 3: MST using weight = w * dist\n    {\n        DSU dsu(N);\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int i, int j) {\n            double wi = (double)edges[i].w * edges[i].dist;\n            double wj = (double)edges[j].w * edges[j].dist;\n            return wi < wj;\n        });\n        \n        vector<int> tree_edges;\n        for (int idx : order) {\n            if (dsu.unite(edges[idx].u, edges[idx].v)) {\n                tree_edges.push_back(idx);\n                if ((int)tree_edges.size() == N - 1) break;\n            }\n        }\n        if ((int)tree_edges.size() == N - 1) {\n            candidate_trees.push_back(tree_edges);\n        }\n    }\n    \n    // Candidate 4: Shortest path tree from station 1\n    {\n        vector<int> tree_edges;\n        vector<long long> dist(N, LLONG_MAX);\n        vector<int> prev_edge(N, -1);\n        dist[0] = 0;\n        using Node = pair<long long, int>;\n        priority_queue<Node, vector<Node>, greater<Node>> pq;\n        pq.push({0, 0});\n        vector<bool> visited(N, false);\n        \n        while (!pq.empty()) {\n            auto [d, u] = pq.top();\n            pq.pop();\n            if (visited[u]) continue;\n            visited[u] = true;\n            \n            if (prev_edge[u] != -1) {\n                tree_edges.push_back(prev_edge[u]);\n            }\n            \n            for (auto [v, eid] : adj[u]) {\n                if (!visited[v] && d + edges[eid].w < dist[v]) {\n                    dist[v] = d + edges[eid].w;\n                    prev_edge[v] = eid;\n                    pq.push({dist[v], v});\n                }\n            }\n        }\n        \n        if ((int)tree_edges.size() == N - 1) {\n            candidate_trees.push_back(tree_edges);\n        }\n    }\n    \n    // Fallback: BFS tree if no spanning tree was generated\n    if (candidate_trees.empty()) {\n        vector<int> tree_edges;\n        vector<bool> visited(N, false);\n        queue<int> q;\n        q.push(0);\n        visited[0] = true;\n        \n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            for (auto [v, eid] : adj[u]) {\n                if (!visited[v]) {\n                    visited[v] = true;\n                    tree_edges.push_back(eid);\n                    q.push(v);\n                    if ((int)tree_edges.size() == N - 1) break;\n                }\n            }\n            if ((int)tree_edges.size() == N - 1) break;\n        }\n        candidate_trees.push_back(tree_edges);\n    }\n    \n    // Evaluate each candidate tree and keep the best solution\n    long long best_cost = LLONG_MAX;\n    vector<int> best_P(N, 0);\n    vector<int> best_B(M, 0);\n    \n    for (const auto& tree_edge_indices : candidate_trees) {\n        // Determine which stations are in the tree (should be all N for spanning trees)\n        vector<bool> in_tree(N, false);\n        in_tree[0] = true; // Station 1 is always active\n        for (int idx : tree_edge_indices) {\n            in_tree[edges[idx].u] = true;\n            in_tree[edges[idx].v] = true;\n        }\n        \n        // Assign residents to nearest active station\n        vector<int> resident_station(K, -1);\n        vector<double> station_max_radius(N, 0.0);\n        \n        for (int k = 0; k < K; ++k) {\n            for (auto [dist, station_id] : resident_stations[k]) {\n                if (in_tree[station_id]) {\n                    resident_station[k] = station_id;\n                    station_max_radius[station_id] = max(station_max_radius[station_id], dist);\n                    break;\n                }\n            }\n        }\n        \n        // Compute output power for each station (capped at 5000)\n        vector<int> P(N, 0);\n        for (int i = 0; i < N; ++i) {\n            if (station_max_radius[i] > 0) {\n                int radius = (int)ceil(station_max_radius[i]);\n                P[i] = min(5000, radius);\n            }\n        }\n        \n        // Build edge selection vector\n        vector<int> B(M, 0);\n        for (int idx : tree_edge_indices) {\n            B[idx] = 1;\n        }\n        \n        // Calculate total cost\n        long long edge_cost = 0;\n        for (int j = 0; j < M; ++j) {\n            if (B[j] == 1) edge_cost += edges[j].w;\n        }\n        long long vertex_cost = 0;\n        for (int i = 0; i < N; ++i) {\n            vertex_cost += (long long)P[i] * P[i];\n        }\n        long long total_cost = edge_cost + vertex_cost;\n        \n        // Verify all residents can be covered\n        bool all_covered = true;\n        for (int k = 0; k < K; ++k) {\n            if (resident_station[k] == -1) {\n                all_covered = false;\n                break;\n            }\n        }\n        \n        // Update best solution if this one is better\n        if (all_covered && total_cost < best_cost) {\n            best_cost = total_cost;\n            best_P = P;\n            best_B = B;\n        }\n    }\n    \n    // Output the best solution\n    for (int i = 0; i < N; ++i) {\n        if (i > 0) cout << \" \";\n        cout << best_P[i];\n    }\n    cout << \"\\n\";\n    for (int j = 0; j < M; ++j) {\n        if (j > 0) cout << \" \";\n        cout << best_B[j];\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 30;                     // number of rows\nusing Grid = array<array<int, N>, N>;\n\nstruct Swap {\n    int x1, y1, x2, y2;\n};\n\n/* -------------------------------------------------------------\n   perform the sift\u2011down algorithm on one row using the given order.\n   out : list of performed swaps.\n   ------------------------------------------------------------- */\nvoid siftDown(Grid &g, vector<Swap> &out,\n              int row, const vector<int> &order) {\n    for (int y : order) {\n        int curX = row, curY = y;\n        while (curX < N - 1) {                     // while cur has children\n            int leftX  = curX + 1;\n            int leftY  = curY;\n            int rightX = curX + 1;\n            int rightY = curY + 1;\n\n            // the smaller child\n            int childX, childY;\n            if (g[leftX][leftY] < g[rightX][rightY]) {\n                childX = leftX; childY = leftY;\n            } else {\n                childX = rightX; childY = rightY;\n            }\n\n            if (g[childX][childY] < g[curX][curY]) {\n                // swap and continue downwards\n                swap(g[curX][curY], g[childX][childY]);\n                out.push_back({curX, curY, childX, childY});\n                curX = childX;\n                curY = childY;\n            } else {\n                break; // already smaller than both children\n            }\n        }\n    }\n}\n\n/* -------------------------------------------------------------\n   count how many parent\u2011child pairs violate the required order\n   ------------------------------------------------------------- */\nint countViolations(const Grid &g) {\n    int bad = 0;\n    for (int x = 0; x < N - 1; ++x)\n        for (int y = 0; y <= x; ++y) {\n            int v = g[x][y];\n            if (v > g[x + 1][y])   ++bad;\n            if (v > g[x + 1][y + 1]) ++bad;\n        }\n    return bad;\n}\n\n/* -------------------------------------------------------------\n   run the heapify algorithm with a given row ordering.\n   orderRows : for each row (index = row) a permutation of 0..row.\n   ------------------------------------------------------------- */\nvoid runWithOrders(const Grid &init, Grid &cur,\n                   vector<Swap> &out,\n                   const vector<vector<int>> &orderRows) {\n    cur = init;\n    out.clear();\n    for (int x = N - 2; x >= 0; --x)\n        siftDown(cur, out, x, orderRows[x]);\n}\n\n/* ------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    Grid orig{};\n    for (int x = 0; x < N; ++x)\n        for (int y = 0; y <= x; ++y)\n            cin >> orig[x][y];\n\n    vector<Swap> bestSwaps;\n    int bestK = 1'000'000;               // larger than any possible length\n\n    Grid cur;\n    vector<Swap> curSwaps;\n\n    // ---- 1) deterministic left\u2011to\u2011right (baseline) -----------------------\n    {\n        vector<vector<int>> orderRows(N);\n        for (int x = 0; x < N; ++x) {\n            orderRows[x].resize(x + 1);\n            iota(orderRows[x].begin(), orderRows[x].end(), 0);\n        }\n        runWithOrders(orig, cur, curSwaps, orderRows);\n        if (countViolations(cur) == 0 && (int)curSwaps.size() < bestK) {\n            bestK = (int)curSwaps.size();\n            bestSwaps = curSwaps;\n        }\n    }\n\n    // ---- 2) deterministic \u201clargest violation first\u201d -----------------------\n    {\n        vector<vector<int>> orderRows(N);\n        for (int x = 0; x < N; ++x) orderRows[x].resize(x + 1);\n        cur = orig;\n        curSwaps.clear();\n        for (int x = N - 2; x >= 0; --x) {\n            vector<pair<int,int>> diffY; // (diff , y)\n            diffY.reserve(x + 1);\n            for (int y = 0; y <= x; ++y) {\n                int left  = cur[x + 1][y];\n                int right = cur[x + 1][y + 1];\n                int mn    = min(left, right);\n                int diff  = cur[x][y] - mn;\n                diffY.emplace_back(diff, y);\n            }\n            sort(diffY.begin(), diffY.end(),\n                 [](const auto &a, const auto &b){ return a.first > b.first; });\n            orderRows[x].clear();\n            for (auto &p : diffY) orderRows[x].push_back(p.second);\n            siftDown(cur, curSwaps, x, orderRows[x]);\n        }\n        if (countViolations(cur) == 0 && (int)curSwaps.size() < bestK) {\n            bestK = (int)curSwaps.size();\n            bestSwaps = curSwaps;\n        }\n    }\n\n    // ---- 3) many random runs ---------------------------------------------\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    for (int iter = 0; iter < 300; ++iter) {\n        vector<vector<int>> orderRows(N);\n        for (int x = 0; x < N; ++x) {\n            orderRows[x].resize(x + 1);\n            iota(orderRows[x].begin(), orderRows[x].end(), 0);\n            if (x <= N - 2)                     // rows that really need a shuffle\n                shuffle(orderRows[x].begin(), orderRows[x].end(), rng);\n        }\n        runWithOrders(orig, cur, curSwaps, orderRows);\n        if (countViolations(cur) == 0 && (int)curSwaps.size() < bestK) {\n            bestK = (int)curSwaps.size();\n            bestSwaps = curSwaps;\n        }\n        if (bestK <= 2000) break;   // very good solution \u2013 stop early\n    }\n\n    // ---- output ------------------------------------------------------------\n    cout << bestK << '\\n';\n    for (const auto &s : bestSwaps)\n        cout << s.x1 << ' ' << s.y1 << ' ' << s.x2 << ' ' << s.y2 << '\\n';\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int SZ = 9;                     // board size, fixed by the statement\n\n/* global data */\nint M;                                 // number of containers\nvector<vector<bool>> obstacle;         // true for an obstacle\nvector<vector<bool>> occupied;         // true if a container is stored here\nvector<vector<int>> value;             // transport number, -1 if none\n\n/* auxiliary directions */\nconst int dr[4] = {1, -1, 0, 0};\nconst int dc[4] = {0, 0, 1, -1};\n\n/* --------------------------------------------------------------- */\n/* count empty neighbours of a cell (not obstacles, not occupied) */\nint count_empty_neighbors(int r, int c, const vector<vector<bool>>& occ){\n    int cnt = 0;\n    for (int d=0; d<4; ++d){\n        int nr = r + dr[d];\n        int nc = c + dc[d];\n        if (nr<0||nr>=SZ||nc<0||nc>=SZ) continue;\n        if (obstacle[nr][nc]) continue;\n        if (occ[nr][nc]) continue;\n        ++cnt;\n    }\n    return cnt;\n}\n\n/* --------------------------------------------------------------- */\n/* BFS from the entrance over empty squares.\n   fills reachable[][] , dist[][] and returns the number of reachable empty squares\n   (entrance is counted as empty).                                 */\nint bfs_reachable(vector<vector<bool>>& reachable,\n                  vector<vector<int>>& dist,\n                  const vector<vector<bool>>& occ)\n{\n    reachable.assign(SZ, vector<bool>(SZ, false));\n    dist.assign(SZ, vector<int>(SZ, -1));\n    queue<pair<int,int>> q;\n\n    int ent_r = 0, ent_c = (SZ-1)/2;\n    reachable[ent_r][ent_c] = true;\n    dist[ent_r][ent_c] = 0;\n    q.emplace(ent_r, ent_c);\n    int cnt = 1;                     // entrance itself\n\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];\n            int nc = c + dc[d];\n            if (nr<0||nr>=SZ||nc<0||nc>=SZ) continue;\n            if (obstacle[nr][nc]) continue;\n            if (occ[nr][nc]) continue;                 // not empty\n            if (!reachable[nr][nc]){\n                reachable[nr][nc] = true;\n                dist[nr][nc] = dist[r][c] + 1;\n                ++cnt;\n                q.emplace(nr,nc);\n            }\n        }\n    }\n    return cnt;          // total empty squares reachable (including entrance)\n}\n\n/* --------------------------------------------------------------- */\n/* test whether a reachable empty square (tr,tc) is a cut vertex\n   (i.e. after occupying it the remaining empty squares stay connected) */\nbool is_safe(int tr, int tc,\n             const vector<vector<bool>>& occ,\n             int total_empty)\n{\n    // a second BFS, this time treating (tr,tc) as blocked\n    vector<vector<bool>> reach2(SZ, vector<bool>(SZ,false));\n    queue<pair<int,int>> q;\n    int ent_r = 0, ent_c = (SZ-1)/2;\n    reach2[ent_r][ent_c] = true;\n    q.emplace(ent_r, ent_c);\n    int cnt = 1;\n\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];\n            int nc = c + dc[d];\n            if (nr<0||nr>=SZ||nc<0||nc>=SZ) continue;\n            if (obstacle[nr][nc]) continue;\n            if (occ[nr][nc]) continue;\n            if (nr==tr && nc==tc) continue;          // the blocked cell\n            if (!reach2[nr][nc]){\n                reach2[nr][nc] = true;\n                ++cnt;\n                q.emplace(nr,nc);\n            }\n        }\n    }\n    // after blocking (tr,tc) we must still reach all other empties\n    return cnt == total_empty - 1;\n}\n\n/* --------------------------------------------------------------- */\n/* pick a square for the next container \u2013 prefer leaves (degree\u202f1) */\npair<int,int> choose_square(const vector<vector<bool>>& occ)\n{\n    vector<vector<bool>> reachable;\n    vector<vector<int>> dist;\n    int total_empty = bfs_reachable(reachable, dist, occ);\n\n    vector<pair<int,int>> safe_list, leaf_list;\n\n    for (int r=0; r<SZ; ++r){\n        for (int c=0; c<SZ; ++c){\n            if (!reachable[r][c]) continue;               // not reachable\n            if (occ[r][c]) continue;                       // already occupied\n            if (r==0 && c==(SZ-1)/2) continue;              // entrance\n            // articulation test\n            if (!is_safe(r,c, occ, total_empty)) continue;\n            safe_list.emplace_back(r,c);\n            if (count_empty_neighbors(r,c, occ) == 1)\n                leaf_list.emplace_back(r,c);\n        }\n    }\n\n    const vector<pair<int,int>>& src = leaf_list.empty() ? safe_list : leaf_list;\n    int best_dist = -1;\n    pair<int,int> best{-1,-1};\n    for (auto [r,c] : src){\n        if (dist[r][c] > best_dist){\n            best_dist = dist[r][c];\n            best = {r,c};\n        } else if (dist[r][c]==best_dist && best.first!=-1){\n            if (r < best.first || (r==best.first && c < best.second))\n                best = {r,c};\n        }\n    }\n\n    // normally src is non\u2011empty \u2013 otherwise a fallback (should not happen)\n    if (!src.empty()) return best;\n    // ultimate fallback: any reachable cell\n    for (int r=0; r<SZ; ++r)\n        for (int c=0; c<SZ; ++c)\n            if (reachable[r][c] && !occ[r][c] && !(r==0 && c==(SZ-1)/2))\n                return {r,c};\n    return {-1,-1}; // never reached\n}\n\n/* --------------------------------------------------------------- */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D_input, N;\n    if(!(cin>>D_input>>N)) return 0;       // D_input is always 9, we ignore it\n    obstacle.assign(SZ, vector<bool>(SZ,false));\n    for (int i=0;i<N;++i){\n        int ri,rj; cin>>ri>>rj;\n        obstacle[ri][rj]=true;\n    }\n\n    occupied.assign(SZ, vector<bool>(SZ,false));\n    value.assign(SZ, vector<int>(SZ,-1));\n\n    M = SZ*SZ - 1 - N;\n\n    vector<pair<int,int>> container_position(M);   // by transport number\n\n    /* ---------- placement ---------- */\n    for (int step=0; step<M; ++step){\n        int t; cin>>t;\n        auto pos = choose_square(occupied);\n        int r = pos.first, c = pos.second;\n        // place the container\n        occupied[r][c] = true;\n        value[r][c] = t;\n        container_position[t] = {r,c};\n        cout << r << ' ' << c << '\\n';\n        cout.flush();\n    }\n\n    /* ---------- removal ---------- */\n    vector<pair<int,int>> removal_order;\n    removal_order.reserve(M);\n    int removed = 0;\n    while (removed < M){\n        vector<vector<bool>> reachableEmpty;\n        vector<vector<int>> dummy;\n        bfs_reachable(reachableEmpty, dummy, occupied);   // empty squares only\n\n        // collect removable containers\n        int best_val = INT_MAX;\n        int br=-1, bc=-1;\n        for (int r=0; r<SZ; ++r){\n            for (int c=0; c<SZ; ++c){\n                if (!occupied[r][c]) continue;               // no container here\n                // is it reachable ?   (any neighbour reachableEmpty)\n                bool ok = false;\n                for (int d=0; d<4; ++d){\n                    int nr = r+dr[d];\n                    int nc = c+dc[d];\n                    if (nr<0||nr>=SZ||nc<0||nc>=SZ) continue;\n                    if (reachableEmpty[nr][nc]) { ok=true; break; }\n                }\n                if (!ok) continue;\n                if (value[r][c] < best_val){\n                    best_val = value[r][c];\n                    br=r; bc=c;\n                }\n            }\n        }\n        // remove the chosen container\n        removal_order.emplace_back(br,bc);\n        occupied[br][bc] = false;\n        value[br][bc] = -1;\n        ++removed;\n    }\n\n    for (auto [r,c] : removal_order){\n        cout << r << ' ' << c << '\\n';\n    }\n    cout.flush();\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\n#include <array>\nusing namespace std;\n\nconst int N = 50;\nconst int M = 100;\n\nint n, m;\nint orig[N][N];\n\n/* --------------------------------------------------------------- */\n/*  adjacency of the original map (including colour 0)            */\nbool orig_adj[M + 1][M + 1];                 // symmetric, 0..m\nvector<array<int,6>> adj_pairs;               // c,d,i1,j1,i2,j2  (both >0)\n\n/* --------------------------------------------------------------- */\n/*  colour sets                                                   */\nvector<pair<int,int>> cells_of_color[M + 1];   // 1..m\nbool is_border_colour[M + 1];\nbool is_interior_colour[M + 1];\n\n/* --------------------------------------------------------------- */\n/*  required cells for each colour (see section 2)                */\nbool required_pos[N][N];\nvector<pair<int,int>> required[M + 1];\n\n/* --------------------------------------------------------------- */\n/*  cells that finally stay coloured                              */\nbool keep[N][N];\n\n/* --------------------------------------------------------------- */\n/*  utility: neighbour directions                                  */\nconst int dy[4] = { -1, 1, 0, 0 };\nconst int dx[4] = { 0, 0, -1, 1 };\n\n/* --------------------------------------------------------------- */\n/*  full validation of a produced map                            */\nbool validate(const int out[N][N])\n{\n    /* 1. each colour appears at least once and is connected       */\n    int cnt_colour[M+1];\n    fill(begin(cnt_colour), end(cnt_colour), 0);\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++) {\n        int c = out[i][j];\n        if (c<0 || c>m) return false;\n        ++cnt_colour[c];\n    }\n    for (int c=1;c<=m;c++) if (cnt_colour[c]==0) return false;\n\n    // BFS for each colour\n    bool visited[N][N];\n    for (int c=1;c<=m;c++) {\n        memset(visited,0,sizeof(visited));\n        // find first cell of this colour\n        int sx=-1,sy=-1;\n        for (int i=0;i<n && sx==-1;i++) for (int j=0;j<n;j++)\n            if (out[i][j]==c) { sx=i; sy=j; break; }\n        if (sx==-1) return false;               // should not happen\n        queue<pair<int,int>> q;\n        q.emplace(sx,sy);\n        visited[sx][sy]=true;\n        int reach=0;\n        while(!q.empty()){\n            auto [y,x]=q.front(); q.pop();\n            ++reach;\n            for (int dir=0;dir<4;dir++){\n                int ny=y+dy[dir], nx=x+dx[dir];\n                if (ny<0||ny>=n||nx<0||nx>=n) continue;\n                if (out[ny][nx]==c && !visited[ny][nx]){\n                    visited[ny][nx]=true;\n                    q.emplace(ny,nx);\n                }\n            }\n        }\n        if (reach!=cnt_colour[c]) return false;   // not connected\n    }\n\n    /* 2. zero cells are connected with the outside               */\n    memset(visited,0,sizeof(visited));\n    queue<pair<int,int>> qz;\n    // start from every border zero cell\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++) {\n        if (out[i][j]==0 &&\n            (i==0||i==n-1||j==0||j==n-1)){\n            visited[i][j]=true;\n            qz.emplace(i,j);\n        }\n    }\n    while(!qz.empty()){\n        auto [y,x]=qz.front(); qz.pop();\n        for (int dir=0;dir<4;dir++){\n            int ny=y+dy[dir], nx=x+dx[dir];\n            if (ny<0||ny>=n||nx<0||nx>=n) continue;\n            if (out[ny][nx]==0 && !visited[ny][nx]){\n                visited[ny][nx]=true;\n                qz.emplace(ny,nx);\n            }\n        }\n    }\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++)\n        if (out[i][j]==0 && !visited[i][j]) return false;   // isolated zero\n\n    /* 3. adjacency matrix exactly the original one                */\n    bool out_adj[M+1][M+1];\n    memset(out_adj,0,sizeof(out_adj));\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++) {\n        int c = out[i][j];\n        for (int dir=0;dir<4;dir++){\n            int ni=i+dy[dir], nj=j+dx[dir];\n            if (ni<0||ni>=n||nj<0||nj>=n){\n                // outside -> colour 0\n                out_adj[c][0]=out_adj[0][c]=true;\n                continue;\n            }\n            int d = out[ni][nj];\n            if (c!=d){\n                out_adj[c][d]=out_adj[d][c]=true;\n            }\n        }\n    }\n    for (int c=0;c<=m;c++) for (int d=c;d<=m;d++)\n        if (orig_adj[c][d]!=out_adj[c][d]) return false;\n\n    return true;\n}\n\n/* --------------------------------------------------------------- */\n/*  connect the already kept cells of one border colour            */\nvoid connect_border_colour(int col)\n{\n    // region = all cells of this colour in the original map\n    static bool inRegion[N][N];\n    for (auto &p : cells_of_color[col]) inRegion[p.first][p.second]=true;\n\n    // components of currently kept cells\n    static int comp[N][N];\n    memset(comp, -1, sizeof(comp));\n    int compCnt = 0;\n    queue<pair<int,int>> qq;\n    for (auto &p : cells_of_color[col]) {\n        int y=p.first, x=p.second;\n        if (keep[y][x] && comp[y][x]==-1){\n            qq.emplace(y,x);\n            comp[y][x]=compCnt;\n            while(!qq.empty()){\n                auto [cy,cx]=qq.front(); qq.pop();\n                for (int dir=0;dir<4;dir++){\n                    int ny=cy+dy[dir], nx=cx+dx[dir];\n                    if (ny<0||ny>=n||nx<0||nx>=n) continue;\n                    if (!inRegion[ny][nx]) continue;\n                    if (keep[ny][nx] && comp[ny][nx]==-1){\n                        comp[ny][nx]=compCnt;\n                        qq.emplace(ny,nx);\n                    }\n                }\n            }\n            ++compCnt;\n        }\n    }\n\n    while (compCnt>1){\n        // find two cells belonging to different components\n        int y1=-1,x1=-1,y2=-1,x2=-1;\n        for (auto &p : cells_of_color[col]){\n            int y=p.first, x=p.second;\n            if (!keep[y][x]) continue;\n            if (y1==-1) { y1=y; x1=x; continue; }\n            if (comp[y][x]!=comp[y1][x1]){ y2=y; x2=x; break; }\n        }\n        // BFS inside the whole region to find a shortest path\n        static int pred_y[N][N], pred_x[N][N];\n        static bool seen[N][N];\n        memset(seen,0,sizeof(seen));\n        queue<pair<int,int>> q;\n        q.emplace(y1,x1);\n        seen[y1][x1]=true;\n        pred_y[y1][x1]=pred_x[y1][x1]=-1;\n        while(!q.empty()){\n            auto [cy,cx]=q.front(); q.pop();\n            if (cy==y2 && cx==x2) break;\n            for (int dir=0;dir<4;dir++){\n                int ny=cy+dy[dir], nx=cx+dx[dir];\n                if (ny<0||ny>=n||nx<0||nx>=n) continue;\n                if (!inRegion[ny][nx]) continue;\n                if (!seen[ny][nx]){\n                    seen[ny][nx]=true;\n                    pred_y[ny][nx]=cy;\n                    pred_x[ny][nx]=cx;\n                    q.emplace(ny,nx);\n                }\n            }\n        }\n        // mark the whole path as kept\n        int yy=y2, xx=x2;\n        while(!(yy==y1&&xx==x1)){\n            keep[yy][xx]=true;\n            int py = pred_y[yy][xx];\n            int px = pred_x[yy][xx];\n            yy=py; xx=px;\n        }\n        keep[y1][x1]=true;\n\n        // recompute components (simplest: start again)\n        memset(comp,-1,sizeof(comp));\n        compCnt=0;\n        for (auto &p : cells_of_color[col]){\n            int y=p.first, x=p.second;\n            if (keep[y][x] && comp[y][x]==-1){\n                qq.emplace(y,x);\n                comp[y][x]=compCnt;\n                while(!qq.empty()){\n                    auto [cy,cx]=qq.front(); qq.pop();\n                    for (int dir=0;dir<4;dir++){\n                        int ny=cy+dy[dir], nx=cx+dx[dir];\n                        if (ny<0||ny>=n||nx<0||nx>=n) continue;\n                        if (!inRegion[ny][nx]) continue;\n                        if (keep[ny][nx] && comp[ny][nx]==-1){\n                            comp[ny][nx]=compCnt;\n                            qq.emplace(ny,nx);\n                        }\n                    }\n                }\n                ++compCnt;\n            }\n        }\n    }\n\n    // clear inRegion for next call\n    for (auto &p : cells_of_color[col]) inRegion[p.first][p.second]=false;\n}\n\n/* --------------------------------------------------------------- */\n/*  greedy deletion of non\u2011required cells                         */\nvoid greedy_deletion(int out_grid[N][N])\n{\n    mt19937 rng(123456);\n    bool changed=true;\n    int passes=0;\n    while (changed && passes<5){\n        changed=false;\n        vector<pair<int,int>> cand;\n        for (int i=0;i<n;i++) for (int j=0;j<n;j++)\n            if (keep[i][j] && !required_pos[i][j])\n                cand.emplace_back(i,j);\n        shuffle(cand.begin(), cand.end(), rng);\n        for (auto [y,x] : cand){\n            int oldcol = orig[y][x];\n            // try delete\n            out_grid[y][x]=0;\n            keep[y][x]=false;\n            if (validate(out_grid)){\n                changed=true;\n            } else {\n                // revert\n                out_grid[y][x]=oldcol;\n                keep[y][x]=true;\n            }\n        }\n        ++passes;\n    }\n}\n\n/* --------------------------------------------------------------- */\n/*  repair isolated zero pools                                   */\nvoid repair_isolated_zeros(int out_grid[N][N])\n{\n    bool visited[N][N];\n    memset(visited,0,sizeof(visited));\n    queue<pair<int,int>> q;\n    // start from border zeros\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++){\n        if (out_grid[i][j]==0 && (i==0||i==n-1||j==0||j==n-1)){\n            visited[i][j]=true;\n            q.emplace(i,j);\n        }\n    }\n    while(!q.empty()){\n        auto [y,x]=q.front(); q.pop();\n        for (int dir=0;dir<4;dir++){\n            int ny=y+dy[dir], nx=x+dx[dir];\n            if (ny<0||ny>=n||nx<0||nx>=n) continue;\n            if (out_grid[ny][nx]==0 && !visited[ny][nx]){\n                visited[ny][nx]=true;\n                q.emplace(ny,nx);\n            }\n        }\n    }\n    // revert isolated zeros\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++){\n        if (out_grid[i][j]==0 && !visited[i][j]){\n            out_grid[i][j]=orig[i][j];\n            keep[i][j]=true;          // not used any more, but keep consistent\n        }\n    }\n}\n\n/* --------------------------------------------------------------- */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if(!(cin>>n>>m)) return 0;\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++){\n        cin>>orig[i][j];\n        cells_of_color[orig[i][j]].push_back({i,j});\n        if (i==0||i==n-1||j==0||j==n-1) is_border_colour[orig[i][j]]=true;\n    }\n\n    /* ---- original adjacency ------------------------------------ */\n    memset(orig_adj,0,sizeof(orig_adj));\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++){\n        int c = orig[i][j];\n        for (int dir=0;dir<4;dir++){\n            int ni=i+dy[dir], nj=j+dx[dir];\n            if (ni<0||ni>=n||nj<0||nj>=n){\n                // outside -> colour 0\n                orig_adj[c][0]=orig_adj[0][c]=true;\n                continue;\n            }\n            int d = orig[ni][nj];\n            if (c!=d){\n                orig_adj[c][d]=orig_adj[d][c]=true;\n                // store pair (c,d) together with both cell positions\n                if (c<d)\n                    adj_pairs.push_back({{c,d,i,j,ni,nj}});\n                else\n                    adj_pairs.push_back({{d,c,ni,nj,i,j}});\n            }\n        }\n    }\n\n    /* ---- interior / border colours ----------------------------- */\n    for (int c=1;c<=m;c++) is_interior_colour[c]=!is_border_colour[c];\n\n    /* ---- must_keep: cells that may not become zero -------------- */\n    bool must_keep[N][N];\n    memset(must_keep,0,sizeof(must_keep));\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++){\n        if (is_interior_colour[orig[i][j]]){\n            must_keep[i][j]=true;\n            for (int dir=0;dir<4;dir++){\n                int ni=i+dy[dir], nj=j+dx[dir];\n                if (ni<0||ni>=n||nj<0||nj>=n) continue;\n                must_keep[ni][nj]=true;\n            }\n        }\n    }\n\n    /* ---- required cells for border colours ---------------------- */\n    memset(required_pos,0,sizeof(required_pos));\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++){\n        int c = orig[i][j];\n        if (is_border_colour[c] && must_keep[i][j]){\n            required[c].push_back({i,j});\n            required_pos[i][j]=true;\n        }\n    }\n    // at least one border cell for each border colour\n    for (int c=1;c<=m;c++) if (is_border_colour[c]){\n        bool has=false;\n        for (auto &p : cells_of_color[c]){\n            int y=p.first, x=p.second;\n            if (y==0||y==n-1||x==0||x==n-1){\n                if (!required_pos[y][x]){\n                    required[c].push_back({y,x});\n                    required_pos[y][x]=true;\n                }\n                has=true;\n                break;\n            }\n        }\n        // border colour must have at least one border cell \u2013 guaranteed by input\n    }\n    // one pair for each border\u2011border edge\n    bool edge_used[M+1][M+1];\n    memset(edge_used,0,sizeof(edge_used));\n    for (auto &e : adj_pairs){\n        int a=e[0], b=e[1];\n        if (!is_border_colour[a] || !is_border_colour[b]) continue;\n        int c=min(a,b), d=max(a,b);\n        if (edge_used[c][d]) continue;\n        // store both cells as required\n        int c1=e[0], y1=e[2], x1=e[3];\n        int c2=e[1], y2=e[4], x2=e[5];\n        if (!required_pos[y1][x1]){\n            required[c1].push_back({y1,x1});\n            required_pos[y1][x1]=true;\n        }\n        if (!required_pos[y2][x2]){\n            required[c2].push_back({y2,x2});\n            required_pos[y2][x2]=true;\n        }\n        edge_used[c][d]=true;\n    }\n\n    /* ---- initial keep set -------------------------------------- */\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++) keep[i][j]=must_keep[i][j];\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++)\n        if (required_pos[i][j]) keep[i][j]=true;\n\n    /* ---- connect every border colour ---------------------------- */\n    for (int c=1;c<=m;c++) if (is_border_colour[c])\n        connect_border_colour(c);\n\n    /* ---- build a first valid output map ------------------------ */\n    int out_grid[N][N];\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++)\n        out_grid[i][j] = keep[i][j] ? orig[i][j] : 0;\n\n    /* ---- try to delete more cells greedily --------------------- */\n    greedy_deletion(out_grid);\n\n    /* ---- repair isolated zero pools ---------------------------- */\n    repair_isolated_zeros(out_grid);\n\n    /* ---- final output ------------------------------------------ */\n    for (int i=0;i<n;i++){\n        for (int j=0;j<n;j++){\n            if (j) cout << ' ';\n            cout << out_grid[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    // comparison_matrix[i][j]: 1 if i > j, -1 if i < j, 0 if unknown, 2 if equal\n    vector<vector<int>> comparison_matrix(N, vector<int>(N, 0));\n    vector<int> comparison_count(N, 0);\n    \n    for (int query = 0; query < Q; query++) {\n        // Find item with minimum comparisons\n        int i = min_element(comparison_count.begin(), comparison_count.end()) - comparison_count.begin();\n        \n        // Find another item to compare with, preferring not yet compared\n        int j = -1;\n        int min_other_count = INT_MAX;\n        \n        // First try: find an item not yet compared with i\n        for (int k = 0; k < N; k++) {\n            if (k != i && comparison_matrix[i][k] == 0 && comparison_count[k] < min_other_count) {\n                min_other_count = comparison_count[k];\n                j = k;\n            }\n        }\n        \n        // Second try: if no new pair, find any item with minimal comparisons\n        if (j == -1) {\n            for (int k = 0; k < N; k++) {\n                if (k != i && comparison_count[k] < min_other_count) {\n                    min_other_count = comparison_count[k];\n                    j = k;\n                }\n            }\n        }\n        \n        // Final fallback\n        if (j == -1) {\n            j = (i + 1) % N;\n            if (j == i) j = (i + 2) % N; // Ensure different items\n        }\n        \n        // Output query: compare single items\n        cout << \"1 1 \" << i << \" \" << j << endl;\n        cout.flush();\n        \n        string result;\n        cin >> result;\n        \n        // Update matrix\n        if (result == \">\") {\n            comparison_matrix[i][j] = 1;\n            comparison_matrix[j][i] = -1;\n        } else if (result == \"<\") {\n            comparison_matrix[i][j] = -1;\n            comparison_matrix[j][i] = 1;\n        } else { // \"=\"\n            comparison_matrix[i][j] = 2; // Equal\n            comparison_matrix[j][i] = 2;\n        }\n        \n        comparison_count[i]++;\n        comparison_count[j]++;\n    }\n    \n    // Calculate score for each item: wins - losses\n    vector<int> score(N, 0);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (i == j) continue;\n            if (comparison_matrix[i][j] == 1) {\n                score[i]++; // i beats j\n            } else if (comparison_matrix[i][j] == -1) {\n                score[i]--; // i loses to j\n            }\n        }\n    }\n    \n    // Create order: items sorted by score descending\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        return score[a] > score[b];\n    });\n    \n    // Assign to D groups using snake pattern for balanced distribution\n    vector<int> assignment(N);\n    for (int pos = 0; pos < N; pos++) {\n        int item = order[pos];\n        int cycle = pos / D;\n        int offset = pos % D;\n        \n        int target_group = (cycle % 2 == 0) ? offset : (D - 1 - offset);\n        assignment[item] = target_group;\n    }\n    \n    // Output assignment\n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << assignment[i];\n    }\n    cout << endl;\n    cout.flush();\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    int h = n / m;                     // height of each stack, fixed to 20\n    vector<vector<int>> st(m);          // stacks, bottom -> top\n    for (int i = 0; i < m; ++i) {\n        st[i].reserve(h);\n        for (int j = 0; j < h; ++j) {\n            int x; cin >> x;\n            st[i].push_back(x);\n        }\n    }\n\n    vector<pair<int,int>> ops;          // answer sequence\n    ops.reserve(5000);\n    long long total_energy = 0;         // only for self check, not output\n\n    // helper: find box v, return (stack index, position inside stack)\n    auto locate = [&](int v, int &si, int &pos){\n        for (int i = 0; i < m; ++i) {\n            for (int j = 0; j < (int)st[i].size(); ++j) {\n                if (st[i][j] == v) {\n                    si = i;\n                    pos = j;\n                    return;\n                }\n            }\n        }\n        // should never happen\n        cerr << \"box \" << v << \" not found!\\n\";\n        exit(1);\n    };\n\n    for (int v = 1; v <= n; ++v) {\n        int si, pos;\n        locate(v, si, pos);\n\n        // if v already on the top -> carry out directly\n        if (pos == (int)st[si].size() - 1) {\n            ops.emplace_back(v, 0);\n            st[si].pop_back();               // remove v\n            continue;\n        }\n\n        // box directly above v\n        int w = st[si][pos + 1];\n\n        // choose a destination stack (different from si)\n        int dest = -1;\n        // 1) any empty stack ?\n        for (int i = 0; i < m; ++i) if (i != si && st[i].empty()) {\n            dest = i; break;\n        }\n        // 2) otherwise the non\u2011empty stack with the largest top number\n        if (dest == -1) {\n            int best_top = -1;\n            for (int i = 0; i < m; ++i) if (i != si && !st[i].empty()) {\n                int cur_top = st[i].back();\n                if (cur_top > best_top) {\n                    best_top = cur_top;\n                    dest = i;\n                }\n            }\n        }\n        // sanity check\n        if (dest == -1) {\n            // should never happen (there is at least one other stack)\n            dest = (si + 1) % m;\n        }\n\n        // ---- move the block w .. top of si to dest ----\n        int start = pos + 1;                         // first element to move\n        vector<int> suffix(st[si].begin() + start, st[si].end());\n        int k = (int)suffix.size();                 // number of moved boxes\n        total_energy += k + 1;\n\n        // erase from source\n        st[si].erase(st[si].begin() + start, st[si].end());\n        // append to destination\n        st[dest].insert(st[dest].end(), suffix.begin(), suffix.end());\n\n        ops.emplace_back(w, dest + 1);               // operation 1\n\n        // ---- now v is on the top of si, carry it out ----\n        ops.emplace_back(v, 0);\n        st[si].pop_back();                           // remove v\n    }\n\n    // ---- output ---------------------------------------------------------\n    for (auto [a, b] : ops) {\n        cout << a << ' ' << b << '\\n';\n    }\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\nvector<vector<bool>> visited;\nvector<vector<int>> last;                // time of last visit\nstring path;\nconst int MAX_MOVES = 100000;\n\n/* --------------------------------------------------------------- */\ninline bool can_move(int i, int j, int ni, int nj) {\n    if (ni == i - 1 && i > 0)      return h[i - 1][j] == '0';\n    if (ni == i + 1 && i < N - 1)  return h[i][j]     == '0';\n    if (nj == j - 1 && j > 0)      return v[i][j - 1] == '0';\n    if (nj == j + 1 && j < N - 1)  return v[i][j]     == '0';\n    return false;\n}\n\n/* --------------------------------------------------------------- */\ninline void add_move(int di, int dj) {\n    if ((int)path.size() >= MAX_MOVES) return;\n    if (di == -1) path.push_back('U');\n    else if (di == 1) path.push_back('D');\n    else if (dj == -1) path.push_back('L');\n    else if (dj == 1) path.push_back('R');\n}\n\n/* --------------------------------------------------------------- */\n// urgency of cell (i,j) at current time t\ninline double urgency(int i, int j, int t) {\n    int dt = t - last[i][j];\n    if (dt <= 0) return -1.0;           // just visited \u2192 ignore\n    return d[i][j] * dt;                // d\u00b7\u0394t\n}\n\n/* --------------------------------------------------------------- */\n// find the globally most urgent cell\npair<int,int> most_urgent(int t) {\n    const int DIRS[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n    double best = -1.0;\n    int bi = -1, bj = -1;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            double u = urgency(i,j,t);\n            if (u > best) {\n                best = u; bi = i; bj = j;\n            }\n        }\n    return {bi,bj};\n}\n\n/* --------------------------------------------------------------- */\n// one step toward target (ni,nj); if blocked, any legal step\npair<int,int> step_toward(int i, int j, int ni, int nj) {\n    const int DIRS[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n    int di = 0, dj = 0;\n    if (ni < i) di = -1; else if (ni > i) di = 1;\n    else if (nj < j) dj = -1; else if (nj > j) dj = 1;\n    \n    if (can_move(i,j,i+di,j+dj)) return {i+di,j+dj};\n    for (auto [dii,djj] : DIRS) {\n        int ii = i+dii, jj = j+djj;\n        if (ii>=0 && ii<N && jj>=0 && jj<N && can_move(i,j,ii,jj))\n            return {ii,jj};\n    }\n    return {i,j};                           // nowhere to go\n}\n\n/* --------------------------------------------------------------- */\n// Phase\u202f1: DFS skeleton (guarantees completeness)\nvoid dfs_skeleton(int i, int j) {\n    if ((int)path.size() >= MAX_MOVES) return;\n    visited[i][j] = true;\n    last[i][j] = (int)path.size();\n\n    const int DIRS[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n    vector<pair<int,pair<int,int>>> neigh;\n    for (auto [di,dj] : DIRS) {\n        int ni = i+di, nj = j+dj;\n        if (ni>=0 && ni<N && nj>=0 && nj<N && can_move(i,j,ni,nj) && !visited[ni][nj])\n            neigh.push_back({-d[ni][nj], {ni,nj}});\n    }\n    sort(neigh.begin(), neigh.end());\n\n    for (auto [_,c] : neigh) {\n        int ni = c.first, nj = c.second;\n        if (!visited[ni][nj]) {\n            add_move(ni-i, nj-j);\n            dfs_skeleton(ni,nj);\n            add_move(i-ni, j-nj);\n        }\n    }\n}\n\n/* --------------------------------------------------------------- */\n// Phase\u202f2: greedy insertions (never delete, only add)\nvoid greedy_insertions() {\n    const int DIRS[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n    // we need a mutable copy of the walk to insert detours\n    string base = path;\n    path.clear();\n\n    int pos = 0, i = 0, j = 0, t = 0;\n\n    while (pos < (int)base.size() && (int)path.size() + 10 < MAX_MOVES) {\n        char mv = base[pos++];\n        // replay the original step\n        path.push_back(mv);\n        i += (mv=='U'?-1: mv=='D'?1:0);\n        j += (mv=='L'?-1: mv=='R'?1:0);\n        ++t;\n        last[i][j] = t;\n\n        // is there a more urgent cell than the one we just stepped on?\n        auto [ui,uj] = most_urgent(t);\n        if (ui == i && uj == j) continue;      // we are already on the best cell\n\n        // insert a short detour (go to urgent cell and immediately return)\n        // we move one step toward it, step back, costing 2 moves\n        auto [ni,nj] = step_toward(i,j,ui,uj);\n        if (ni==i && nj==j) continue;           // cannot move\n        int di = ni-i, dj = nj-j;\n        add_move(di, dj);                       // detour out\n        ++t; last[ni][nj] = t;\n\n        // step back to original cell\n        add_move(-di, -dj);\n        ++t; last[i][j] = t;\n    }\n}\n\n/* --------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // ---- read input -------------------------------------------------\n    cin >> N;\n    h.resize(N-1); for (int i=0;i<N-1;++i) cin >> h[i];\n    v.resize(N);   for (int i=0;i<N;++i)   cin >> v[i];\n    d.assign(N, vector<int>(N));\n    for (int i=0;i<N;++i)\n        for (int j=0;j<N;++j) cin >> d[i][j];\n\n    // ---- initialise -------------------------------------------------\n    visited.assign(N, vector<bool>(N, false));\n    last.assign(N, vector<int>(N, -1e9));\n\n    // ---- Phase\u202f1: guaranteed complete walk -------------------------\n    dfs_skeleton(0,0);\n\n    // ---- Phase\u202f2: enrich with greedy insertions --------------------\n    greedy_insertions();\n\n    cout << path << '\\n';\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\n\nint N, M;\nint si, sj;\nint startId;                     // linear index of the start cell\nvector<string> board;\nvector<string> pat;              // patterns, length M, each length 5\n\n// for every letter \u2013 list of cell ids that contain this letter\nvector<vector<int>> letterPos;   // size 26\n\n// Manhattan distance between any two cells\nint distCell[225][225];\n// coordinates of a cell id\nint row[225], col[225];\n\n/* -------------------------------------------------------------\n   compute the cheapest sum of Manhattan distances for a fixed\n   sequence of letters (vector<int> seq containing 0..25)\n   ------------------------------------------------------------- */\nint movementDist(const vector<int> &seq) {\n    const vector<int> *prevCand = &letterPos[seq[0]];\n    vector<int> dpPrev(prevCand->size());\n    for (int i = 0; i < (int)prevCand->size(); ++i)\n        dpPrev[i] = distCell[startId][(*prevCand)[i]];\n\n    for (size_t idx = 1; idx < seq.size(); ++idx) {\n        const vector<int> *curCand = &letterPos[seq[idx]];\n        vector<int> dpCur(curCand->size(), INF);\n        for (int ci = 0; ci < (int)curCand->size(); ++ci) {\n            int cur = (*curCand)[ci];\n            int best = INF;\n            for (int pi = 0; pi < (int)prevCand->size(); ++pi) {\n                int cand = (*prevCand)[pi];\n                int val = dpPrev[pi] + distCell[cand][cur];\n                if (val < best) best = val;\n            }\n            dpCur[ci] = best;\n        }\n        dpPrev.swap(dpCur);\n        prevCand = curCand;\n    }\n    int best = INF;\n    for (int v : dpPrev) if (v < best) best = v;\n    return best;\n}\n\n/* -------------------------------------------------------------\n   build the overlapped string for a given order of patterns,\n   store it into seq, return total price = movement + length\n   seq is reused to avoid allocations\n   ------------------------------------------------------------- */\nint priceOfOrder(const vector<int> &order, vector<int> &seq) {\n    seq.clear(); seq.reserve(5 * M);\n    for (int id : order) {\n        const string &p = pat[id];\n        int maxOL = min((int)seq.size(), 5);\n        int overlap = 0;\n        for (int k = maxOL; k > 0; --k) {\n            bool ok = true;\n            for (int i = 0; i < k; ++i)\n                if (seq[seq.size() - k + i] != p[i] - 'A') { ok = false; break; }\n            if (ok) { overlap = k; break; }\n        }\n        for (int i = overlap; i < 5; ++i) seq.push_back(p[i] - 'A');\n    }\n    int move = movementDist(seq);\n    return move + (int)seq.size();\n}\n\n/* -------------------------------------------------------------\n   reconstruct the concrete walk for the best order\n   ------------------------------------------------------------- */\nvector<int> reconstructWalk(const vector<int> &order) {\n    vector<int> seq; seq.reserve(5 * M);\n    for (int id : order) {\n        const string &p = pat[id];\n        int maxOL = min((int)seq.size(), 5);\n        int overlap = 0;\n        for (int k = maxOL; k > 0; --k) {\n            bool ok = true;\n            for (int i = 0; i < k; ++i)\n                if (seq[seq.size() - k + i] != p[i] - 'A') { ok = false; break; }\n            if (ok) { overlap = k; break; }\n        }\n        for (int i = overlap; i < 5; ++i) seq.push_back(p[i] - 'A');\n    }\n    int L = (int)seq.size();\n\n    struct Step {\n        const vector<int> *cells;\n        vector<int> dp;\n        vector<int> pred;\n    };\n    vector<Step> step(L);\n\n    // first layer\n    step[0].cells = &letterPos[seq[0]];\n    step[0].dp.resize(step[0].cells->size());\n    step[0].pred.assign(step[0].cells->size(), -1);\n    for (int i = 0; i < (int)step[0].cells->size(); ++i)\n        step[0].dp[i] = distCell[startId][(*step[0].cells)[i]];\n\n    for (int i = 1; i < L; ++i) {\n        step[i].cells = &letterPos[seq[i]];\n        const vector<int> &prevCells = *step[i - 1].cells;\n        const vector<int> &curCells  = *step[i].cells;\n        step[i].dp.assign(curCells.size(), INF);\n        step[i].pred.assign(curCells.size(), -1);\n        for (int ci = 0; ci < (int)curCells.size(); ++ci) {\n            int cur = curCells[ci];\n            int best = INF, bestIdx = -1;\n            for (int pi = 0; pi < (int)prevCells.size(); ++pi) {\n                int val = step[i - 1].dp[pi] + distCell[prevCells[pi]][cur];\n                if (val < best) {\n                    best = val;\n                    bestIdx = pi;\n                }\n            }\n            step[i].dp[ci] = best;\n            step[i].pred[ci] = bestIdx;\n        }\n    }\n\n    // find cheapest last cell\n    const vector<int> &lastCells = *step[L - 1].cells;\n    int bestCost = INF, bestIdx = -1;\n    for (int i = 0; i < (int)lastCells.size(); ++i)\n        if (step[L - 1].dp[i] < bestCost) {\n            bestCost = step[L - 1].dp[i];\n            bestIdx = i;\n        }\n\n    // backtrack\n    vector<int> walk(L);\n    int idx = bestIdx;\n    for (int i = L - 1; i >= 0; --i) {\n        walk[i] = (*step[i].cells)[idx];\n        if (i > 0) idx = step[i].pred[idx];\n    }\n    return walk;\n}\n\n\n/* ------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M)) return 0;\n    cin >> si >> sj;\n    startId = si * N + sj;\n    board.resize(N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n    pat.resize(M);\n    for (int i = 0; i < M; ++i) cin >> pat[i];\n\n    // ---- build letterPos and coordinates -----------------------\n    letterPos.assign(26, {});\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            int id = i * N + j;\n            char c = board[i][j];\n            letterPos[c - 'A'].push_back(id);\n            row[id] = i; col[id] = j;\n        }\n\n    // ---- all pairwise Manhattan distances ----------------------\n    int C = N * N;\n    for (int a = 0; a < C; ++a)\n        for (int b = 0; b < C; ++b)\n            distCell[a][b] = abs(row[a] - row[b]) + abs(col[a] - col[b]);\n\n    // ---- greedy initial order ---------------------------------\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    // sort by distance of the first character from the start\n    sort(order.begin(), order.end(),\n         [&](int a, int b) {\n             const string &pa = pat[a], &pb = pat[b];\n             int da = distCell[startId][letterPos[pa[0] - 'A'][0]];\n             int db = distCell[startId][letterPos[pb[0] - 'A'][0]];\n             return da < db;\n         });\n\n    vector<int> seq;          // reused buffer\n    int bestPrice = priceOfOrder(order, seq);\n    vector<int> bestOrder = order;\n\n    // ---- aggressive random search with insertions --------------\n    const int TOTAL_TRIALS = 4000;           // enough for good exploration\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    for (int trial = 0; trial < TOTAL_TRIALS; ++trial) {\n        // create a neighbour by applying 3 random insertions\n        vector<int> nxt = bestOrder;\n        for (int k = 0; k < 3; ++k) {\n            int src = rng() % M;\n            int dst = rng() % M;\n            if (src < dst) {\n                // move element src to position dst (after insertion)\n                int val = nxt[src];\n                nxt.erase(nxt.begin() + src);\n                nxt.insert(nxt.begin() + dst, val);\n            } else if (src > dst) {\n                int val = nxt[src];\n                nxt.erase(nxt.begin() + src);\n                nxt.insert(nxt.begin() + dst, val);\n            }\n        }\n\n        int curPrice = priceOfOrder(nxt, seq);\n        if (curPrice < bestPrice) {\n            bestPrice = curPrice;\n            bestOrder = nxt;\n        }\n    }\n\n    // ---- output the walk for the best order --------------------\n    vector<int> walk = reconstructWalk(bestOrder);\n    for (int cell : walk) {\n        int i = cell / N;\n        int j = cell % N;\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<pair<int,int>>> shapes;          // input shapes (not used for the CS part)\n\n/* ------------------------------------------------------------------ */\n/*   bit\u2011mask helpers                                                */\ninline int idx(int i, int j) { return i * N + j; }\n\n/* ------------------------------------------------------------------ */\n/*   data structures for the CSP                                      */\nvector< vector< bitset<400> > > placements;   // placements[s][p] = cells covered by placement p of shape s\nvector< vector< pair<int,int> > > cell_to_placements; // cell \u2192 list of (shape,placement) that cover it\nbitset<400> known_dry, known_oil, unknown;\nvector<int> placement_score;                  // for each placement: how many still\u2011unknown cells it covers\n\n/* ------------------------------------------------------------------ */\nint query_single(int i, int j) {\n    cout << \"q 1 \" << i << ' ' << j << endl;\n    int ret; cin >> ret;\n    return ret;\n}\n\n/* ------------------------------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---- read input -------------------------------------------- */\n    if (!(cin >> N >> M >> eps)) return 0;\n    shapes.resize(M);\n    for (int k = 0; k < M; ++k) {\n        int d; cin >> d;\n        shapes[k].resize(d);\n        for (int i = 0; i < d; ++i) {\n            int x, y; cin >> x >> y;\n            shapes[k][i] = {x, y};\n        }\n    }\n\n    /* ---- generate all placements -------------------------------- */\n    placements.resize(M);\n    cell_to_placements.assign(N * N, {});\n    const int MAXC = N * N;\n\n    for (int s = 0; s < M; ++s) {\n        // normalize shape: shift so that min i,j = 0\n        int min_i = INT_MAX, min_j = INT_MAX;\n        for (auto [i, j] : shapes[s]) {\n            min_i = min(min_i, i);\n            min_j = min(min_j, j);\n        }\n        vector<pair<int,int>> norm_shape;\n        for (auto [i, j] : shapes[s])\n            norm_shape.emplace_back(i - min_i, j - min_j);\n\n        // size of the shape\n        int h = 0, w = 0;\n        for (auto [i, j] : norm_shape) {\n            h = max(h, i + 1);\n            w = max(w, j + 1);\n        }\n\n        // try every translation\n        for (int di = 0; di + h <= N; ++di)\n            for (int dj = 0; dj + w <= N; ++dj) {\n                bitset<400> mask;\n                bool conflict = false;\n                for (auto [i, j] : norm_shape) {\n                    int r = di + i, c = dj + j;\n                    mask.set(idx(r, c));\n                }\n                // store the placement\n                int pid = placements[s].size();\n                placements[s].push_back(mask);\n                // update reverse index\n                for (int i = 0; i < MAXC; ++i)\n                    if (mask[i]) cell_to_placements[i].push_back({s, pid});\n            }\n    }\n\n    /* ---- initialise CSP status ---------------------------------- */\n    known_dry.reset();\n    known_oil.reset();\n    unknown.reset();\n    for (int i = 0; i < MAXC; ++i) unknown.set(i);\n    placement_score.assign(M, 0);   // not used \u2013 we recompute the coverage on the fly\n\n    /* ---- main loop : at most 2\u00b7N\u00b2 iterations -------------------- */\n    int iterations = 0;\n    const int LIMIT = 2 * N * N;\n\n    while (iterations < LIMIT && unknown.any()) {\n        ++iterations;\n\n        /* ---- 1. prune placements that hit known_dry ---------- */\n        for (int s = 0; s < M; ++s) {\n            vector<bitset<400>> keep;\n            for (auto &pl : placements[s])\n                if ((pl & known_dry).none()) keep.push_back(pl);\n            placements[s].swap(keep);\n        }\n\n        /* ---- 2. deduce forced cells --------------------------- */\n        vector<int> newly_dry, newly_oil;\n        for (int i = 0; i < MAXC; ++i) if (unknown[i]) {\n            bool can_be_oil = false, can_be_dry = false;\n            // check if any placement still covers i\n            for (auto [s, pid] : cell_to_placements[i]) {\n                // we have to check if pid is still alive for shape s\n                bool alive = false;\n                for (auto &pl : placements[s])\n                    if (pl[idx(i/N, i%N)]) { alive = true; break; }\n                if (alive) { can_be_oil = true; break; }\n            }\n            if (!can_be_oil) newly_dry.push_back(i);\n        }\n\n        for (int i : newly_dry) {\n            known_dry.set(i);\n            unknown.reset(i);\n        }\n\n        /* ---- 3. choose the most informative cell -------------- */\n        // simple heuristic: cell covered by the most remaining placements\n        int best_cell = -1, best_cov = 0;\n        for (int i = 0; i < MAXC; ++i) if (unknown[i]) {\n            int cov = 0;\n            for (auto [s, pid] : cell_to_placements[i])\n                for (auto &pl : placements[s])\n                    if (pl[idx(i/N, i%N)]) { ++cov; break; }\n            if (cov > best_cov) {\n                best_cov = cov;\n                best_cell = i;\n            }\n        }\n\n        if (best_cell == -1) break;   // nothing left to test\n\n        int r = best_cell / N, c = best_cell % N;\n        int v = query_single(r, c);\n        if (v > 0) {\n            known_oil.set(best_cell);\n            unknown.reset(best_cell);\n        } else {\n            known_dry.set(best_cell);\n            unknown.reset(best_cell);\n        }\n    }\n\n    /* ---- output answer ------------------------------------------ */\n    vector<pair<int,int>> answer;\n    for (int i = 0; i < MAXC; ++i)\n        if (known_oil[i]) answer.emplace_back(i / N, i % N);\n\n    cout << \"a \" << answer.size();\n    for (auto [r, c] : answer) cout << ' ' << r << ' ' << c;\n    cout << endl;\n\n    int ok; cin >> ok;\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXW = 1000;                 // W is fixed to 1000 in the problem\n\n/*------------------------------------------------------------*/\n/*  geometry structures                                       */\n\nstruct Rect {\n    int x0, y0, x1, y1;               // top\u2011left (x0,y0), bottom\u2011right (x1,y1)\n};\n\nstruct Region {\n    int x, y, w, h;                    // top\u2011left corner, width, height\n    int area() const { return w * h; }\n};\n\n/*------------------------------------------------------------*/\n/*  packing of one day                                       */\n\nstatic vector<Rect> pack_day(const vector<int>& request, int W, int N) {\n    // request[k] = a[d][k]\n    vector<pair<int, int>> ord;        // (area , original index)\n    ord.reserve(N);\n    for (int k = 0; k < N; ++k) ord.emplace_back(request[k], k);\n    sort(ord.begin(), ord.end(),\n         [](const pair<int, int>& A, const pair<int, int>& B) {\n             return A.first > B.first;               // decreasing area\n         });\n\n    vector<Region> freeReg;\n    freeReg.push_back({0, 0, W, W});                 // whole hall\n\n    vector<Rect> answer(N);\n\n    for (auto [area, idx] : ord) {\n        // ---- find a region that can contain the rectangle\n        int sel = -1;          // region with area >= request\n        int best = -1;         // region with the largest area (used when no region fits)\n        int bestArea = -1;\n\n        for (int i = 0; i < (int)freeReg.size(); ++i) {\n            int a = freeReg[i].area();\n            if (a >= area) {\n                if (sel == -1 || a < freeReg[sel].area()) sel = i;\n            }\n            if (a > bestArea) {\n                bestArea = a;\n                best = i;\n            }\n        }\n\n        Region R;\n        bool fits = (sel != -1);\n        if (fits) R = freeReg[sel];\n        else      R = freeReg[best];                  // we will pay a penalty\n\n        // ---- choose the size of the rectangle\n        int w, h;\n        if (fits) {\n            // try orientation 1 (prefer a square)\n            int w1 = min(R.w, max(1, (int)std::sqrt((double)area)));\n            int h1 = (area + w1 - 1) / w1;               // ceil\n            if (h1 <= R.h) {\n                w = w1;  h = h1;\n            } else {\n                // orientation 2 (swap roles)\n                int h2 = min(R.h, max(1, (int)std::sqrt((double)area)));\n                int w2 = (area + h2 - 1) / h2;\n                if (w2 <= R.w) {\n                    w = w2;  h = h2;\n                } else {\n                    // fallback \u2013 use whole width of the region\n                    w = R.w;\n                    h = (area + w - 1) / w;\n                }\n            }\n        } else {\n            // we cannot satisfy the area \u2013 fill the whole region (penalty)\n            w = R.w;\n            h = R.h;\n        }\n\n        // ---- store the rectangle\n        answer[idx] = {R.x, R.y, R.x + w, R.y + h};\n\n        // ---- create the two leftover parts (guillotine cut)\n        if (w < R.w) {\n            freeReg.push_back({R.x + w, R.y, R.w - w, R.h});\n        }\n        if (h < R.h) {\n            freeReg.push_back({R.x, R.y + h, w, R.h - h});\n        }\n\n        // ---- delete the used region (swap with last element)\n        if (fits) {\n            freeReg[sel] = freeReg.back();\n            freeReg.pop_back();\n        } else {\n            freeReg[best] = freeReg.back();\n            freeReg.pop_back();\n        }\n    }\n    return answer;\n}\n\n/*------------------------------------------------------------*/\n/*  edge matrices                                             */\n\nstruct EdgeMatrices {\n    vector<vector<char>> H;   // H[i][j] : horizontal edge (i,0..W-1)  i=1..W-1\n    vector<vector<char>> V;   // V[i][j] : vertical   edge (0..W-1,j)  j=1..W-1\n    EdgeMatrices(int W) {\n        H.assign(W + 1, vector<char>(W, 0));\n        V.assign(W, vector<char>(W + 1, 0));\n    }\n    void clear() {\n        for (auto &row : H) fill(row.begin(), row.end(), 0);\n        for (auto &row : V) fill(row.begin(), row.end(), 0);\n    }\n};\n\nvoid mark_edges(const vector<Rect>& rects, int W, EdgeMatrices& em) {\n    em.clear();\n    for (const Rect& r : rects) {\n        if (r.x0 > 0) {\n            for (int j = r.y0; j < r.y1; ++j) em.H[r.x0][j] = 1;\n        }\n        if (r.x1 < W) {\n            for (int j = r.y0; j < r.y1; ++j) em.H[r.x1][j] = 1;\n        }\n        if (r.y0 > 0) {\n            for (int i = r.x0; i < r.x1; ++i) em.V[i][r.y0] = 1;\n        }\n        if (r.y1 < W) {\n            for (int i = r.x0; i < r.x1; ++i) em.V[i][r.y1] = 1;\n        }\n    }\n}\n\n/*------------------------------------------------------------*/\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\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    vector<vector<Rect>> allRects(D, vector<Rect>(N));\n    EdgeMatrices prev(W), cur(W);\n    long long totalCost = 0;               // only for debugging, not needed for output\n\n    for (int d = 0; d < D; ++d) {\n        // ----- pack the day\n        allRects[d] = pack_day(a[d], W, N);\n        // ----- build edge matrices\n        mark_edges(allRects[d], W, cur);\n        // ----- compute transition cost (L0 = 0 is special)\n        if (d > 0) {\n            long long Ld = 0;\n            for (int i = 1; i < W; ++i)\n                for (int j = 0; j < W; ++j)\n                    Ld += (prev.H[i][j] != cur.H[i][j]);\n            for (int i = 0; i < W; ++i)\n                for (int j = 1; j < W; ++j)\n                    Ld += (prev.V[i][j] != cur.V[i][j]);\n            totalCost += Ld;\n        }\n        // ----- store current matrices as previous for the next day\n        prev.H.swap(cur.H);\n        prev.V.swap(cur.V);\n    }\n\n    // ----- output\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            const Rect& r = allRects[d][k];\n            cout << r.x0 << ' ' << r.y0 << ' ' << r.x1 << ' ' << r.y1 << '\\n';\n        }\n    }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MOD = 998244353;\n\nstruct Op {\n    int m;\n    int p;\n    int q;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n    vector<vector<int>> initialBoard(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> initialBoard[i][j];\n    \n    vector<vector<vector<int>>> stamp(M, vector<vector<int>>(3, vector<int>(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                cin >> stamp[m][i][j];\n    \n    // Precompute all possible placements (operation types)\n    vector<Op> allOps;\n    for (int m = 0; m < M; ++m)\n        for (int p = 0; p <= N - 3; ++p)\n            for (int q = 0; q <= N - 3; ++q)\n                allOps.push_back({m, p, q});\n    \n    // Utility functions\n    auto boardScore = [&](const vector<vector<int>>& b) -> long long {\n        long long s = 0;\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                s += b[i][j];\n        return s;\n    };\n    \n    auto computeAddDelta = [&](const vector<vector<int>>& b, const Op& op) -> long long {\n        const auto& s = stamp[op.m];\n        long long delta = 0;\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                int old = b[op.p + i][op.q + j];\n                int add = s[i][j];\n                int sum = old + add;\n                if (sum >= MOD) delta += add - MOD;\n                else delta += add;\n            }\n        }\n        return delta;\n    };\n    \n    auto computeRemoveDelta = [&](const vector<vector<int>>& b, const Op& op) -> long long {\n        const auto& s = stamp[op.m];\n        long long delta = 0;\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                int old = b[op.p + i][op.q + j];\n                int sv = s[i][j];\n                int newMod = (old >= sv) ? old - sv : old + MOD - sv;\n                delta += newMod - old;\n            }\n        }\n        return delta;\n    };\n    \n    auto applyAdd = [&](vector<vector<int>>& b, long long& score, const Op& op) {\n        const auto& s = stamp[op.m];\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                int old = b[op.p + i][op.q + j];\n                int add = s[i][j];\n                int sum = old + add;\n                int newMod = (sum >= MOD) ? sum - MOD : sum;\n                b[op.p + i][op.q + j] = newMod;\n                score += newMod - old;\n            }\n        }\n    };\n    \n    auto applyRemove = [&](vector<vector<int>>& b, long long& score, const Op& op) {\n        const auto& s = stamp[op.m];\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                int old = b[op.p + i][op.q + j];\n                int sv = s[i][j];\n                int newMod = (old >= sv) ? old - sv : old + MOD - sv;\n                b[op.p + i][op.q + j] = newMod;\n                score += newMod - old;\n            }\n        }\n    };\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    long long bestScore = -1;\n    vector<Op> bestOps;\n    \n    const double TIME_LIMIT = 1.8;\n    auto startTime = chrono::steady_clock::now();\n    \n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - startTime).count();\n        if (elapsed > TIME_LIMIT) break;\n        \n        // Reset to initial board\n        vector<vector<int>> curBoard = initialBoard;\n        long long curScore = boardScore(curBoard);\n        vector<Op> curOps;\n        \n        // Outer loop: alternate addition and removal until stable\n        while (true) {\n            // ----- Addition phase -----\n            bool added = false;\n            while ((int)curOps.size() < K) {\n                // random order for scanning candidates\n                vector<Op> shuffled = allOps;\n                shuffle(shuffled.begin(), shuffled.end(), rng);\n                long long bestDelta = 0;\n                vector<Op> bestCandidates;\n                for (const Op& op : shuffled) {\n                    long long d = computeAddDelta(curBoard, op);\n                    if (d > bestDelta) {\n                        bestDelta = d;\n                        bestCandidates.clear();\n                        bestCandidates.push_back(op);\n                    } else if (d == bestDelta && d > 0) {\n                        bestCandidates.push_back(op);\n                    }\n                }\n                if (bestDelta <= 0) break;\n                const Op& chosen = bestCandidates[rng() % bestCandidates.size()];\n                applyAdd(curBoard, curScore, chosen);\n                curOps.push_back(chosen);\n                added = true;\n            }\n            \n            // ----- Removal phase -----\n            bool removed = false;\n            while (true) {\n                long long bestRemoveDelta = 0;\n                vector<int> idxCandidates;\n                for (int i = 0; i < (int)curOps.size(); ++i) {\n                    long long d = computeRemoveDelta(curBoard, curOps[i]);\n                    if (d > bestRemoveDelta) {\n                        bestRemoveDelta = d;\n                        idxCandidates.clear();\n                        idxCandidates.push_back(i);\n                    } else if (d == bestRemoveDelta && d > 0) {\n                        idxCandidates.push_back(i);\n                    }\n                }\n                if (bestRemoveDelta <= 0) break;\n                int idx = idxCandidates[rng() % idxCandidates.size()];\n                Op op = curOps[idx];\n                applyRemove(curBoard, curScore, op);\n                // remove from vector\n                curOps[idx] = curOps.back();\n                curOps.pop_back();\n                removed = true;\n            }\n            \n            if (!added && !removed) break;\n        }\n        \n        if (curScore > bestScore) {\n            bestScore = curScore;\n            bestOps = curOps;\n        }\n    }\n    \n    cout << bestOps.size() << \"\\n\";\n    for (auto &op : bestOps) {\n        cout << op.m << \" \" << op.p << \" \" << op.q << \"\\n\";\n    }\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos {\n    int r = -1, c = -1;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n    const int TOTAL = N * N;\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) cin >> A[i][j];\n\n    // which row each container comes from (not needed further)\n    vector<int> sourceRow(TOTAL);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            sourceRow[A[i][j]] = i;\n\n    // grid: container id or -1\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    // how many containers of each row already appeared\n    vector<int> recCnt(N, 0);\n    // how many containers already dispatched\n    int dispatched = 0;\n\n    // the large crane\n    struct Crane {\n        int r = 0, c = 0;\n        bool holding = false;\n        int holdId = -1;\n    } large;\n\n    // output strings, one per row\n    vector<string> out(N);\n\n    int turn = 0;\n    const int LIMIT = 10000;\n\n    while (dispatched < TOTAL && turn < LIMIT) {\n        /* ---- step 1 : containers appear ---- */\n        for (int i = 0; i < N; ++i) {\n            if (recCnt[i] >= N) continue;               // row finished\n            if (grid[i][0] != -1) continue;              // square occupied\n            // a crane holding a container blocks the square\n            bool blocked = (large.r == i && large.c == 0 && large.holding);\n            if (!blocked) {\n                int cid = A[i][recCnt[i]];\n                grid[i][0] = cid;\n                ++recCnt[i];\n            }\n        }\n\n        /* ---- step 2 : crane actions ---- */\n        // small cranes: bomb on turn 0, then only '.'\n        for (int i = 1; i < N; ++i) {\n            if (turn == 0) out[i].push_back('B');\n            else           out[i].push_back('.');\n        }\n\n        // large crane (row 0)\n        char act = '.';\n        if (large.holding) {\n            int targetRow = large.holdId / N;\n            int targetCol = N - 1;\n            if (large.r != targetRow) {                 // vertical move\n                int dr = (targetRow > large.r) ? 1 : -1;\n                act = (dr == 1) ? 'D' : 'U';\n                large.r += dr;\n            } else if (large.c != targetCol) {          // move right\n                act = 'R';\n                large.c += 1;\n            } else {                                    // drop on dispatch gate\n                grid[large.r][large.c] = large.holdId;\n                large.holding = false;\n                large.holdId = -1;\n                act = 'Q';\n            }\n        } else {\n            // not holding \u2013 pick the smallest waiting container\n            int bestRow = -1;\n            int bestId = INT_MAX;\n            for (int i = 0; i < N; ++i) {\n                if (grid[i][0] != -1 && grid[i][0] < bestId) {\n                    bestId = grid[i][0];\n                    bestRow = i;\n                }\n            }\n            if (bestRow == -1) {                        // nothing to do\n                act = '.';\n            } else {\n                if (large.r != bestRow) {               // vertical move\n                    int dr = (bestRow > large.r) ? 1 : -1;\n                    act = (dr == 1) ? 'D' : 'U';\n                    large.r += dr;\n                } else if (large.c != 0) {              // move left to column 0\n                    act = 'L';\n                    large.c -= 1;\n                } else {                                // pick up\n                    int cid = grid[large.r][large.c];\n                    large.holding = true;\n                    large.holdId = cid;\n                    grid[large.r][large.c] = -1;\n                    act = 'P';\n                }\n            }\n        }\n        out[0].push_back(act);\n\n        /* ---- step 3 : dispatch ---- */\n        for (int i = 0; i < N; ++i) {\n            int cid = grid[i][N - 1];\n            if (cid != -1) {\n                ++dispatched;\n                grid[i][N - 1] = -1;\n            }\n        }\n\n        ++turn;\n    }\n\n    // all rows must have the same length (pad with '.')\n    for (int i = 0; i < N; ++i) {\n        if ((int)out[i].size() < turn) out[i] += string(turn - out[i].size(), '.');\n        cout << out[i] << '\\n';\n    }\n    return 0;\n}","ahc034":"#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    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    // working copy of the heights\n    vector<vector<int>> rem = h;\n\n    int curR = 0, curC = 0;      // truck position\n    int load = 0;                // soil on the truck\n    vector<string> ops;          // list of operations\n\n    auto pushMove = [&](char dir) {\n        ops.emplace_back(string(1, dir));\n    };\n    auto pushLoad = [&](int d) {\n        ops.emplace_back(\"+\" + to_string(d));\n        load += d;\n    };\n    auto pushUnload = [&](int d) {\n        ops.emplace_back(\"-\" + to_string(d));\n        load -= d;\n    };\n\n    // move the truck to (tr,tc) along a Manhattan path\n    auto moveTo = [&](int tr, int tc) {\n        int dr = tr - curR;\n        int dc = tc - curC;\n        while (dr != 0) {\n            int step = (dr > 0) ? 1 : -1;\n            char dir = (dr > 0) ? 'D' : 'U';\n            pushMove(dir);\n            curR += step;\n            dr -= step;\n        }\n        while (dc != 0) {\n            int step = (dc > 0) ? 1 : -1;\n            char dir = (dc > 0) ? 'R' : 'L';\n            pushMove(dir);\n            curC += step;\n            dc -= step;\n        }\n    };\n\n    // find the nearest cell that satisfies a predicate\n    auto nearest = [&](auto pred) -> pair<int,int> {\n        int bestDist = INT_MAX;\n        pair<int,int> best(-1,-1);\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (!pred(i,j)) continue;\n                int dist = abs(i - curR) + abs(j - curC);\n                if (dist < bestDist) {\n                    bestDist = dist;\n                    best = {i,j};\n                }\n            }\n        }\n        return best;\n    };\n\n    while (true) {\n        // nearest hill (positive remaining height)\n        auto hill = nearest([&](int i,int j){ return rem[i][j] > 0; });\n        if (hill.first == -1) break;                 // no hill left -> finished\n\n        // go there and load everything\n        moveTo(hill.first, hill.second);\n        int d = rem[hill.first][hill.second];        // >0\n        pushLoad(d);\n        rem[hill.first][hill.second] = 0;\n\n        // deliver the whole load to holes\n        while (load > 0) {\n            auto hole = nearest([&](int i,int j){ return rem[i][j] < 0; });\n            // there must be a hole, otherwise the input would be inconsistent\n            moveTo(hole.first, hole.second);\n            int demand = -rem[hole.first][hole.second]; // positive\n            int unload = min(load, demand);\n            pushUnload(unload);\n            rem[hole.first][hole.second] += unload;    // still \u2264 0\n        }\n    }\n\n    // (optional) safety \u2013 should never be needed because sums are zero\n    while (load > 0) {\n        auto hole = nearest([&](int i,int j){ return rem[i][j] < 0; });\n        if (hole.first == -1) break;\n        moveTo(hole.first, hole.second);\n        int demand = -rem[hole.first][hole.second];\n        int unload = min(load, demand);\n        pushUnload(unload);\n        rem[hole.first][hole.second] += unload;\n    }\n\n    // output all operations\n    for (auto &s : ops) cout << s << '\\n';\n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int N = 6;               // fixed in the statement\n    const int M = 15;              // fixed in the statement\n    const int T = 10;              // fixed in the statement\n    const int SEED_CNT = 2 * N * (N - 1);   // 60\n    const int CELL_CNT = N * N;            // 36\n    const int EDGE_CNT = 2 * N * (N - 1);   // 60\n\n    // ---------- read initial data ----------\n    int tmpN, tmpM, tmpT;\n    if (!(cin >> tmpN >> tmpM >> tmpT)) return 0;\n    // the values are the same as the constants above, ignore them\n\n    vector<vector<int>> seed(SEED_CNT, vector<int>(M));\n    vector<int> seedSum(SEED_CNT, 0);\n    vector<int> X(M, 0);                 // per\u2011dimension maxima of the initial seeds\n\n    for (int i = 0; i < SEED_CNT; ++i) {\n        int s = 0;\n        for (int j = 0; j < M; ++j) {\n            int x; cin >> x;\n            seed[i][j] = x;\n            s += x;\n            X[j] = max(X[j], x);\n        }\n        seedSum[i] = s;\n    }\n\n    // build list of edges (neighbour pairs) once\n    vector<pair<int,int>> edges;\n    edges.reserve(EDGE_CNT);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            int p = i * N + j;\n            if (i + 1 < N) edges.emplace_back(p, (i + 1) * N + j);\n            if (j + 1 < N) edges.emplace_back(p, i * N + (j + 1));\n        }\n\n    // helper: best possible child of two seeds\n    auto best_possible = [&](int a, int b)->int{\n        int ret = 0;\n        const auto &A = seed[a];\n        const auto &B = seed[b];\n        for (int i = 0; i < M; ++i) ret += max(A[i], B[i]);\n        return ret;\n    };\n\n    // helper: evaluate a whole placement\n    // returns {total_sum_of_best , max_best}\n    auto evaluate = [&](const vector<int> &grid)->pair<int,int>{\n        int total = 0, mx = 0;\n        for (auto [u,v] : edges) {\n            int val = best_possible(grid[u], grid[v]);\n            total += val;\n            mx = max(mx, val);\n        }\n        return {total, mx};\n    };\n\n    // ---------- round loop ----------\n    for (int round = 0; round < T; ++round) {\n        // ---- choose the initial 36 seeds: the 36 with largest sum ----\n        vector<int> allIdx(SEED_CNT);\n        iota(allIdx.begin(), allIdx.end(), 0);\n        sort(allIdx.begin(), allIdx.end(),\n             [&](int a, int b){ return seedSum[a] > seedSum[b]; });\n        vector<int> selectedIdx(allIdx.begin(), allIdx.begin() + CELL_CNT);   // 36 seeds\n\n        // best placement found in this round\n        vector<int> bestGrid;\n        long long bestObj = -(1LL<<60);\n\n        // ---- several restarts of hill climbing ----\n        const int RESTARTS = 3;\n        const int ITERATIONS = 2000;\n        const int WEIGHT_MAX = 1000;          // max_best is multiplied by this\n\n        for (int rep = 0; rep < RESTARTS; ++rep) {\n            // current placement: random permutation of the 36 selected seeds\n            vector<int> grid = selectedIdx;\n            shuffle(grid.begin(), grid.end(), mt19937{ random_device{}() });\n\n            // current used / unused lists\n            vector<char> used(SEED_CNT, 0);\n            for (int id : grid) used[id] = 1;\n            vector<int> unused;\n            unused.reserve(SEED_CNT - CELL_CNT);\n            for (int i = 0; i < SEED_CNT; ++i) if (!used[i]) unused.push_back(i);\n\n            // evaluate starting placement\n            auto [totalSum, maxBest] = evaluate(grid);\n            long long curObj = (long long)maxBest * WEIGHT_MAX + totalSum;\n\n            // hill climbing\n            for (int it = 0; it < ITERATIONS; ++it) {\n                bool moveWithUnused = false;\n                if (!unused.empty() && (rand() % 2)) moveWithUnused = true;\n\n                if (moveWithUnused) {\n                    // exchange a planted seed with an unused one\n                    int pos = rand() % CELL_CNT;\n                    int oldSeed = grid[pos];\n                    int idx = rand() % unused.size();\n                    int newSeed = unused[idx];\n                    // temporarily place newSeed\n                    grid[pos] = newSeed;\n                    auto [newSum, newMax] = evaluate(grid);\n                    long long newObj = (long long)newMax * WEIGHT_MAX + newSum;\n                    if (newObj > curObj) {               // accept\n                        used[oldSeed] = 0;\n                        used[newSeed] = 1;\n                        unused[idx] = oldSeed;            // replace\n                        curObj = newObj;\n                        // totalSum, maxBest are already updated by evaluate\n                    } else {\n                        grid[pos] = oldSeed;               // revert\n                    }\n                } else {\n                    // swap two positions\n                    int p = rand() % CELL_CNT;\n                    int q = rand() % CELL_CNT;\n                    if (p == q) continue;\n                    swap(grid[p], grid[q]);\n                    auto [newSum, newMax] = evaluate(grid);\n                    long long newObj = (long long)newMax * WEIGHT_MAX + newSum;\n                    if (newObj > curObj) {               // accept\n                        curObj = newObj;\n                    } else {\n                        swap(grid[p], grid[q]);           // revert\n                    }\n                }\n            } // end of iterations\n\n            // keep the best placement among the restarts\n            if (curObj > bestObj) {\n                bestObj = curObj;\n                bestGrid = grid;\n            }\n        } // restarts\n\n        // ---- output the best grid ----\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (j) cout << ' ';\n                cout << bestGrid[i * N + j];\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n\n        // ---- read the children, they become the seed pool for the next round ----\n        for (int i = 0; i < SEED_CNT; ++i) {\n            int s = 0;\n            for (int j = 0; j < M; ++j) {\n                int x; cin >> x;\n                seed[i][j] = x;\n                s += x;\n            }\n            seedSum[i] = s;\n        }\n    } // round loop\n\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\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> s(N), t(N);\n    for (int i = 0; i < N; ++i) cin >> s[i];\n    for (int i = 0; i < N; ++i) cin >> t[i];\n\n    /* ----------------------------------------------------------\n       board description\n       ---------------------------------------------------------- */\n    vector<vector<char>> is_src(N, vector<char>(N, 0));\n    vector<vector<char>> is_tgt(N, vector<char>(N, 0));\n    vector<vector<char>> occupied(N, vector<char>(N, 0));\n    int src_rem = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            occupied[i][j] = (s[i][j] == '1');\n            if (s[i][j] == '1' && t[i][j] == '0') {\n                is_src[i][j] = 1;\n                ++src_rem;\n            }\n            if (t[i][j] == '1' && s[i][j] == '0') {\n                is_tgt[i][j] = 1;\n            }\n        }\n    }\n\n    /* ----------------------------------------------------------\n       arm geometry \u2013 we always use exactly 5 vertices\n       ---------------------------------------------------------- */\n    const int Vout = 5;                     // root + 4 leaves, always \u2264 V\n    const int C = 4;                        // number of useful leaves\n\n    // directions: 0 = east, 1 = north, 2 = west, 3 = south\n    const int dx[4] = {0, -1, 0, +1};\n    const int dy[4] = {+1, 0, -1, 0};\n\n    // leaf directions after the two initial rotation turns\n    vector<int> dir(C + 1, 0);               // 1\u2011based, initially all east\n    vector<char> loaded(C + 1, 0);           // initially empty\n    int loaded_cnt = 0;\n\n    // root initial position\n    int rx = 0, ry = 0;\n\n    /* ----------------------------------------------------------\n       output the designed tree\n       ---------------------------------------------------------- */\n    cout << Vout << '\\n';\n    for (int i = 1; i < Vout; ++i) cout << 0 << ' ' << 1 << '\\n';\n    cout << rx << ' ' << ry << '\\n';\n\n    /* ----------------------------------------------------------\n       containers for the operation strings\n       ---------------------------------------------------------- */\n    vector<string> ops;\n\n    /* ----------------------------------------------------------\n       first two turns \u2013 rotate three leaves to the remaining directions\n       ---------------------------------------------------------- */\n    // turn 0 : . L L R   (leaf 2,3,4 are rotated)\n    {\n        string op;\n        op.push_back('.');                 // root\n        op.push_back('.');                 // leaf 1\n        op.push_back('L');                 // leaf 2\n        op.push_back('L');                 // leaf 3\n        op.push_back('R');                 // leaf 4\n        for (int i = 0; i < Vout; ++i) op.push_back('.'); // actions\n        ops.push_back(op);\n        // apply rotations\n        dir[2] = (dir[2] + 1) & 3;          // L -> +1 (mod 4)\n        dir[3] = (dir[3] + 1) & 3;          // L\n        dir[4] = (dir[4] + 3) & 3;          // R -> +3 (mod 4)\n    }\n    // turn 1 : . . L .   (leaf 3 gets its second rotation)\n    {\n        string op;\n        op.push_back('.');                 // root\n        op.push_back('.');                 // leaf 1\n        op.push_back('.');                 // leaf 2\n        op.push_back('L');                 // leaf 3\n        op.push_back('.');                 // leaf 4\n        for (int i = 0; i < Vout; ++i) op.push_back('.');\n        ops.push_back(op);\n        // apply rotation\n        dir[3] = (dir[3] + 1) & 3;          // now leaf 3 points west\n    }\n\n    /* ----------------------------------------------------------\n       helper: evaluate a candidate root move\n       ---------------------------------------------------------- */\n    auto evaluate_move = [&](int nx, int ny, int &actions, int &dist, int mode) {\n        actions = 0;\n        // count possible actions\n        for (int i = 1; i <= C; ++i) {\n            int d = dir[i];\n            int cx = nx + dx[d];\n            int cy = ny + dy[d];\n            if (cx < 0 || cx >= N || cy < 0 || cy >= N) continue;\n            if (!loaded[i] && is_src[cx][cy] && occupied[cx][cy]) ++actions;\n            else if (loaded[i] && is_tgt[cx][cy] && !occupied[cx][cy]) ++actions;\n        }\n\n        // distance to the nearest still needed square (mode: 0 = pickup, 1 = delivery)\n        dist = INF;\n        if (mode == 0) { // pickup\n            for (int i = 0; i < N; ++i)\n                for (int j = 0; j < N; ++j)\n                    if (is_src[i][j] && occupied[i][j])\n                        for (int d = 0; d < 4; ++d) {\n                            int ni = i + dx[d];\n                            int nj = j + dy[d];\n                            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                            int ddist = abs(nx - ni) + abs(ny - nj);\n                            dist = min(dist, ddist);\n                        }\n        } else if (mode == 1) { // delivery\n            for (int i = 0; i < N; ++i)\n                for (int j = 0; j < N; ++j)\n                    if (is_tgt[i][j] && !occupied[i][j])\n                        for (int d = 0; d < 4; ++d) {\n                            int ni = i + dx[d];\n                            int nj = j + dy[d];\n                            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                            int ddist = abs(nx - ni) + abs(ny - nj);\n                            dist = min(dist, ddist);\n                        }\n        }\n    };\n\n    /* ----------------------------------------------------------\n       main simulation loop \u2013 stop after 100\u202f000 turns\n       ---------------------------------------------------------- */\n    const vector<char> move_chars = {'U','D','L','R','.'};\n    const vector<int> mv_dx = {-1, +1, 0, 0, 0};\n    const vector<int> mv_dy = {0, 0, -1, +1, 0};\n\n    while ((src_rem > 0 || loaded_cnt > 0) && (int)ops.size() < 100000) {\n        // decide the current mode\n        bool have_empty = false;\n        for (int i = 1; i <= C; ++i) if (!loaded[i]) { have_empty = true; break; }\n        int mode = -1;  // 0 = pickup, 1 = delivery\n        if (src_rem > 0 && have_empty) mode = 0;\n        else if (loaded_cnt > 0) mode = 1;\n        else break; // finished\n\n        // try all five possible root moves\n        int best_move = -1, best_actions = -1, best_dist = INF;\n        for (int m = 0; m < 5; ++m) {\n            char mc = move_chars[m];\n            int nx = rx + mv_dx[m];\n            int ny = ry + mv_dy[m];\n            if (mc != '.' && (nx < 0 || nx >= N || ny < 0 || ny >= N)) continue;\n            int actions, dist;\n            evaluate_move(nx, ny, actions, dist, mode);\n            if (actions > best_actions ||\n                (actions == best_actions && dist < best_dist)) {\n                best_move = m;\n                best_actions = actions;\n                best_dist = dist;\n            }\n        }\n        // if nothing is possible, still move the root somewhere (any legal move)\n        if (best_move == -1) {\n            for (int m = 0; m < 5; ++m) {\n                char mc = move_chars[m];\n                int nx = rx + mv_dx[m];\n                int ny = ry + mv_dy[m];\n                if (mc != '.' && (nx < 0 || nx >= N || ny < 0 || ny >= N)) continue;\n                best_move = m; break;\n            }\n        }\n\n        // apply the chosen move and build the operation string\n        char mv = move_chars[best_move];\n        int nx = rx + mv_dx[best_move];\n        int ny = ry + mv_dy[best_move];\n        string op;\n        op.push_back(mv);                     // root movement\n        for (int i = 1; i < Vout; ++i) op.push_back('.'); // no rotations\n\n        // actions \u2013 root never acts\n        op.push_back('.');\n        for (int i = 1; i <= C; ++i) {\n            int d = dir[i];\n            int cx = nx + dx[d];\n            int cy = ny + dy[d];\n            bool can = false;\n            if (!loaded[i] && cx >= 0 && cx < N && cy >= 0 && cy < N &&\n                is_src[cx][cy] && occupied[cx][cy]) can = true;\n            else if (loaded[i] && cx >= 0 && cx < N && cy >= 0 && cy < N &&\n                     is_tgt[cx][cy] && !occupied[cx][cy]) can = true;\n\n            if (can) {\n                op.push_back('P');\n                if (!loaded[i]) { // pick\n                    occupied[cx][cy] = 0;\n                    loaded[i] = 1;\n                    --src_rem;\n                    ++loaded_cnt;\n                } else { // deliver\n                    occupied[cx][cy] = 1;\n                    loaded[i] = 0;\n                    --loaded_cnt;\n                }\n            } else {\n                op.push_back('.');\n            }\n        }\n        ops.push_back(op);\n        // update root position\n        rx = nx; ry = ny;\n    }\n\n    // ----- output all operation strings -----\n    for (const string &s : ops) cout << s << '\\n';\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int x, y;          // original coordinates\n    int xi, yi;        // compressed indices\n    int w;             // +1 for mackerel, -1 for sardine\n};\n\nstruct Node {\n    int sum;           // total sum of interval\n    int pref;          // max prefix sum (non empty)\n    int pref_r;        // right end of that prefix\n    int suff;          // max suffix sum (non empty)\n    int suff_l;        // left start of that suffix\n    int best;          // max sub\u2011array sum (non empty)\n    int best_l, best_r;// borders of that sub\u2011array\n};\n\nstatic inline Node combine(const Node &L, const Node &R) {\n    Node C;\n    C.sum = L.sum + R.sum;\n\n    // prefix\n    if (L.pref > L.sum + R.pref) {\n        C.pref = L.pref;\n        C.pref_r = L.pref_r;\n    } else {\n        C.pref = L.sum + R.pref;\n        C.pref_r = R.pref_r;\n    }\n\n    // suffix\n    if (R.suff > R.sum + L.suff) {\n        C.suff = R.suff;\n        C.suff_l = R.suff_l;\n    } else {\n        C.suff = R.sum + L.suff;\n        C.suff_l = L.suff_l;\n    }\n\n    // best\n    C.best = L.best;\n    C.best_l = L.best_l;\n    C.best_r = L.best_r;\n\n    if (R.best > C.best) {\n        C.best = R.best;\n        C.best_l = R.best_l;\n        C.best_r = R.best_r;\n    }\n\n    int cross = L.suff + R.pref;\n    if (cross > C.best) {\n        C.best = cross;\n        C.best_l = L.suff_l;\n        C.best_r = R.pref_r;\n    }\n    return 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<Point> pts;\n    pts.reserve(2 * N);\n    vector<int> xs, ys;\n    for (int i = 0; i < 2 * N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        pts.push_back({x, y, -1, -1, (i < N ? +1 : -1)});\n        xs.push_back(x);\n        ys.push_back(y);\n    }\n\n    // coordinate compression\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    int X = (int)xs.size();\n    int Y = (int)ys.size();\n\n    for (auto &p : pts) {\n        p.xi = lower_bound(xs.begin(), xs.end(), p.x) - xs.begin();\n        p.yi = lower_bound(ys.begin(), ys.end(), p.y) - ys.begin();\n    }\n\n    // points per column\n    vector<vector<pair<int,int>>> byX(X);   // (y_idx , weight)\n    for (const auto &p : pts) {\n        byX[p.xi].push_back({p.yi, p.w});\n    }\n\n    // segment tree for y\u2011direction\n    int M = 1;\n    while (M < Y) M <<= 1;\n    vector<Node> seg(2 * M);\n\n    auto tree_build = [&]() {\n        for (int i = 0; i < Y; ++i) {\n            seg[M + i].sum = 0;\n            seg[M + i].pref = seg[M + i].suff = seg[M + i].best = 0;\n            seg[M + i].pref_r = seg[M + i].suff_l = seg[M + i].best_l = seg[M + i].best_r = i;\n        }\n        for (int i = Y; i < M; ++i) {\n            seg[M + i].sum = 0;\n            seg[M + i].pref = seg[M + i].suff = seg[M + i].best = 0;\n            seg[M + i].pref_r = seg[M + i].suff_l = seg[M + i].best_l = seg[M + i].best_r = i;\n        }\n        for (int i = M - 1; i >= 1; --i)\n            seg[i] = combine(seg[i << 1], seg[i << 1 | 1]);\n    };\n\n    auto tree_reset = [&]() {\n        for (int i = 0; i < Y; ++i) {\n            seg[M + i].sum = 0;\n            seg[M + i].pref = seg[M + i].suff = seg[M + i].best = 0;\n            // positions stay unchanged\n        }\n        for (int i = M - 1; i >= 1; --i)\n            seg[i] = combine(seg[i << 1], seg[i << 1 | 1]);\n    };\n\n    auto tree_add = [&](int y_idx, int delta) {\n        int p = M + y_idx;\n        seg[p].sum += delta;\n        int ns = seg[p].sum;\n        seg[p].pref = seg[p].suff = seg[p].best = ns;\n        // the indices already stored for the leaf stay correct\n        for (p >>= 1; p; p >>= 1)\n            seg[p] = combine(seg[p << 1], seg[p << 1 | 1]);\n    };\n\n    // sweep\n    int bestValue = -1;          // -1 means \u201cnot found\u201d\n    int best_left = -1, best_right = -1;\n    int best_bottom = -1, best_top = -1;\n\n    for (int left = 0; left < X; ++left) {\n        tree_reset();\n        for (int right = left; right < X; ++right) {\n            // add column 'right'\n            for (auto &pr : byX[right]) {\n                tree_add(pr.first, pr.second);\n            }\n            const Node &root = seg[1];\n            int cur = root.best;\n            if (cur > bestValue) {\n                bestValue = cur;\n                best_left = left;\n                best_right = right;\n                best_bottom = root.best_l;\n                best_top    = root.best_r;\n            }\n        }\n    }\n\n    // -----------------------------------------------------------------\n    // build the final rectangle\n    int leftX, rightX, bottomY, topY;\n    // arrays to know which coordinates are occupied (for the \u201cempty\u201d extension)\n    vector<char> usedX(100001, 0), usedY(100001, 0);\n    for (auto &p : pts) {\n        usedX[p.x] = 1;\n        usedY[p.y] = 1;\n    }\n\n    auto unused_coord = [&](const vector<char> &used, int after) {\n        for (int v = after + 1; v <= 100000; ++v)\n            if (!used[v]) return v;\n        for (int v = after - 1; v >= 0; --v)\n            if (!used[v]) return v;\n        return -1; // never happens\n    };\n\n    if (bestValue <= 0) {               // no positive rectangle \u2013 use empty one\n        // pick two unused x\u2011coordinates and two unused y\u2011coordinates\n        int ux1 = -1, ux2 = -1;\n        for (int x = 0; x <= 100000; ++x) if (!usedX[x]) { ux1 = x; break; }\n        for (int x = ux1 + 1; x <= 100000; ++x) if (!usedX[x]) { ux2 = x; break; }\n        int uy1 = -1, uy2 = -1;\n        for (int y = 0; y <= 100000; ++y) if (!usedY[y]) { uy1 = y; break; }\n        for (int y = uy1 + 1; y <= 100000; ++y) if (!usedY[y]) { uy2 = y; break; }\n        leftX = ux1; rightX = ux2;\n        bottomY = uy1; topY = uy2;\n    } else {\n        leftX   = xs[best_left];\n        rightX  = xs[best_right];\n        bottomY = ys[best_bottom];\n        topY    = ys[best_top];\n\n        // ensure width > 0, height > 0 using only empty columns / rows\n        if (leftX == rightX) {\n            int nx = unused_coord(usedX, leftX);\n            if (nx > leftX) rightX = nx;\n            else {\n                rightX = leftX;\n                leftX = nx;\n            }\n        }\n        if (bottomY == topY) {\n            int ny = unused_coord(usedY, bottomY);\n            if (ny > bottomY) topY = ny;\n            else {\n                topY = bottomY;\n                bottomY = ny;\n            }\n        }\n    }\n\n    // -----------------------------------------------------------------\n    // output the rectangle (counter\u2011clockwise order)\n    cout << 4 << \"\\n\";\n    cout << leftX   << \" \" << bottomY << \"\\n\";\n    cout << leftX   << \" \" << topY    << \"\\n\";\n    cout << rightX  << \" \" << topY    << \"\\n\";\n    cout << rightX  << \" \" << bottomY << \"\\n\";\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rectangle {\n    int width, height;\n    int x, y; // top-left corner\n};\n\nstruct Placement {\n    int p; // index\n    int r; // rotation\n    char d; // direction 'U' or 'L'\n    int b; // reference rectangle index\n};\n\nclass Packer {\nprivate:\n    int N;\n    vector<int> w, h;\n    vector<Rectangle> placed;\n    vector<Placement> sequence;\n    \n    // Check if two rectangles overlap\n    bool overlap(const Rectangle& a, const Rectangle& b) {\n        return a.x < b.x + b.width && a.x + a.width > b.x &&\n               a.y < b.y + b.height && a.y + a.height > b.y;\n    }\n    \n    // Simulate placing a rectangle with given parameters\n    // Returns the rectangle with final position\n    Rectangle simulatePlace(int idx, int rot, char dir, int ref) {\n        int width = (rot == 0) ? w[idx] : h[idx];\n        int height = (rot == 0) ? h[idx] : w[idx];\n        \n        Rectangle rect;\n        rect.width = width;\n        rect.height = height;\n        \n        if (dir == 'U') {\n            // Align left edge\n            if (ref == -1) {\n                rect.x = 0;\n            } else {\n                rect.x = placed[ref].x + placed[ref].width;\n            }\n            \n            // Start from bottom and slide up (decrease y)\n            // Find the highest position where it doesn't overlap\n            int best_y = 0;\n            // Check all placed rectangles\n            for (const auto& other : placed) {\n                // Check horizontal overlap\n                if (rect.x < other.x + other.width && rect.x + rect.width > other.x) {\n                    // This rectangle blocks upward movement\n                    best_y = max(best_y, other.y + other.height);\n                }\n            }\n            rect.y = best_y;\n        } else { // 'L'\n            // Align top edge\n            if (ref == -1) {\n                rect.y = 0;\n            } else {\n                rect.y = placed[ref].y + placed[ref].height;\n            }\n            \n            // Start from far right and slide left (decrease x)\n            int best_x = 0;\n            // Check all placed rectangles\n            for (const auto& other : placed) {\n                // Check vertical overlap\n                if (rect.y < other.y + other.height && rect.y + rect.height > other.y) {\n                    // This rectangle blocks leftward movement\n                    best_x = max(best_x, other.x + other.width);\n                }\n            }\n            rect.x = best_x;\n        }\n        \n        return rect;\n    }\n    \npublic:\n    Packer(const vector<int>& w, const vector<int>& h) \n        : N(w.size()), w(w), h(h) {}\n    \n    // Generate a random placement sequence\n    pair<vector<Placement>, long long> generateRandom(mt19937& rng) {\n        placed.clear();\n        sequence.clear();\n        \n        // Randomly decide which rectangles to place\n        // For now, try to place all\n        vector<int> placed_indices;\n        long long totalWH = 0;\n        \n        for (int i = 0; i < N; i++) {\n            // Randomly decide to place or skip\n            uniform_real_distribution<double> dist(0.0, 1.0);\n            bool place = dist(rng) < 0.9; // 90% chance to place\n            \n            if (!place) {\n                totalWH += w[i] + h[i];\n                continue;\n            }\n            \n            // Random rotation, direction, reference\n            uniform_int_distribution<int> rot_dist(0, 1);\n            uniform_int_distribution<int> dir_dist(0, 1);\n            uniform_int_distribution<int> ref_dist(-1, (int)placed_indices.size() - 1);\n            \n            int r = rot_dist(rng);\n            char d = (dir_dist(rng) == 0) ? 'U' : 'L';\n            int b = ref_dist(rng);\n            \n            // Simulate placement\n            Rectangle rect = simulatePlace(i, r, d, b);\n            \n            // Check for overlap (shouldn't happen with our algorithm)\n            bool overlaps = false;\n            for (const auto& other : placed) {\n                if (overlap(rect, other)) {\n                    overlaps = true;\n                    break;\n                }\n            }\n            \n            if (overlaps) {\n                // Fallback: skip this rectangle\n                totalWH += w[i] + h[i];\n                continue;\n            }\n            \n            // Add to placed\n            placed.push_back(rect);\n            placed_indices.push_back(i);\n            \n            // Record placement\n            Placement p;\n            p.p = i;\n            p.r = r;\n            p.d = d;\n            p.b = b;\n            sequence.push_back(p);\n        }\n        \n        // Calculate bounding box\n        int maxX = 0, maxY = 0;\n        for (const auto& rect : placed) {\n            maxX = max(maxX, rect.x + rect.width);\n            maxY = max(maxY, rect.y + rect.height);\n        }\n        \n        long long score = (long long)maxX + maxY + totalWH;\n        return {sequence, score};\n    }\n    \n    // Generate a greedy placement sequence\n    pair<vector<Placement>, long long> generateGreedy() {\n        placed.clear();\n        sequence.clear();\n        long long totalWH = 0;\n        \n        for (int i = 0; i < N; i++) {\n            // Try to place rectangle i\n            int best_r = 0;\n            char best_d = 'U';\n            int best_b = -1;\n            long long bestScore = LLONG_MAX;\n            Rectangle bestRect;\n            \n            // Try all combinations\n            for (int r = 0; r <= 1; r++) {\n                for (char d : {'U', 'L'}) {\n                    // Try references: -1 and all previously placed\n                    vector<int> refs;\n                    refs.push_back(-1);\n                    for (int j = 0; j < (int)placed.size(); j++) {\n                        refs.push_back(j);\n                    }\n                    \n                    for (int b : refs) {\n                        Rectangle rect = simulatePlace(i, r, d, b);\n                        \n                        // Check overlap\n                        bool overlaps = false;\n                        for (const auto& other : placed) {\n                            if (overlap(rect, other)) {\n                                overlaps = true;\n                                break;\n                            }\n                        }\n                        if (overlaps) continue;\n                        \n                        // Calculate new bounding box with this rectangle\n                        int maxX = 0, maxY = 0;\n                        for (const auto& p : placed) {\n                            maxX = max(maxX, p.x + p.width);\n                            maxY = max(maxY, p.y + p.height);\n                        }\n                        maxX = max(maxX, rect.x + rect.width);\n                        maxY = max(maxY, rect.y + rect.height);\n                        \n                        long long score = (long long)maxX + maxY;\n                        \n                        if (score < bestScore) {\n                            bestScore = score;\n                            best_r = r;\n                            best_d = d;\n                            best_b = b;\n                            bestRect = rect;\n                        }\n                    }\n                }\n            }\n            \n            // Decide whether to place or skip\n            // Calculate current bounding box\n            int curMaxX = 0, curMaxY = 0;\n            for (const auto& p : placed) {\n                curMaxX = max(curMaxX, p.x + p.width);\n                curMaxY = max(curMaxY, p.y + p.height);\n            }\n            long long curScore = (long long)curMaxX + curMaxY;\n            \n            if (bestScore > curScore + w[i] + h[i]) {\n                // Skip this rectangle\n                totalWH += w[i] + h[i];\n            } else {\n                // Place it\n                placed.push_back(bestRect);\n                Placement p;\n                p.p = i;\n                p.r = best_r;\n                p.d = best_d;\n                p.b = best_b;\n                sequence.push_back(p);\n            }\n        }\n        \n        // Calculate final bounding box\n        int maxX = 0, maxY = 0;\n        for (const auto& rect : placed) {\n            maxX = max(maxX, rect.x + rect.width);\n            maxY = max(maxY, rect.y + rect.height);\n        }\n        \n        long long score = (long long)maxX + maxY + totalWH;\n        return {sequence, score};\n    }\n    \n    // Get the best sequence found so far (for repeated output)\n    const vector<Placement>& getBestSequence() const {\n        return sequence;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, T, sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n    \n    vector<int> w(N), h(N);\n    for (int i = 0; i < N; i++) {\n        cin >> w[i] >> h[i];\n    }\n    \n    Packer packer(w, h);\n    \n    // Random number generator\n    random_device rd;\n    mt19937 rng(rd());\n    \n    // Try to find a good solution first\n    long long bestScore = LLONG_MAX;\n    vector<Placement> bestSequence;\n    \n    // Spend some time finding a good solution\n    // We'll try greedy first\n    auto [greedySeq, greedyScore] = packer.generateGreedy();\n    if (greedyScore < bestScore) {\n        bestScore = greedyScore;\n        bestSequence = greedySeq;\n    }\n    \n    // Then try random improvements\n    int attempts = min(T, 50); // Use up to 50 attempts for search\n    for (int attempt = 0; attempt < attempts; attempt++) {\n        auto [seq, score] = packer.generateRandom(rng);\n        if (score < bestScore) {\n            bestScore = score;\n            bestSequence = seq;\n        }\n    }\n    \n    // Output placements for each turn\n    for (int turn = 0; turn < T; turn++) {\n        // Output best sequence we found\n        cout << bestSequence.size() << \"\\n\";\n        for (const auto& p : bestSequence) {\n            cout << p.p << \" \" << p.r << \" \" << p.d << \" \" << p.b << \"\\n\";\n        }\n        cout << flush;\n        \n        // Read measured W' and H'\n        int Wp, Hp;\n        cin >> Wp >> Hp;\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Tree {\n    int N;                                 // number of vertices\n    int H;                                 // maximal depth (given as 10)\n    const vector<int> &A;                  // beauty values\n    const vector<vector<int>> &adj;        // graph\n    long long sumAAll;                     // \u03a3 A[v]  (constant part of score)\n\n    vector<int> parent;                    // parent[v]  ( -1 for a root )\n    vector<int> depth;                     // depth[v]   (0 \u2026 H)\n    vector<int> sumA;                      // S[v]  \u2013 sum of beauties in subtree\n    vector<int> high;                      // H[v]  \u2013 longest distance to a leaf\n    vector<vector<int>> children;          // children of each vertex\n    long long totalDepthSum;               // \u03a3 depth[v] * A[v]\n\n    // ---------- constructor (all roots) ----------\n    Tree(int N_, int H_, const vector<int> &A_, const vector<vector<int>> &adj_)\n        : N(N_), H(H_), A(A_), adj(adj_) {\n        sumAAll = 0;\n        for (int x : A) sumAAll += x;\n        parent.assign(N, -1);\n        depth.assign(N, 0);\n        sumA = A;                 // each subtree consists only of the vertex itself\n        high.assign(N, 0);\n        children.assign(N, {});\n        totalDepthSum = 0;\n    }\n\n    // ---------- utility ----------\n    bool isDescendant(int anc, int desc) const {\n        int cur = desc;\n        while (cur != -1) {\n            if (cur == anc) return true;\n            cur = parent[cur];\n        }\n        return false;\n    }\n\n    void detach(int v) {\n        int p = parent[v];\n        if (p != -1) {\n            auto &vec = children[p];\n            for (size_t i = 0; i < vec.size(); ++i) {\n                if (vec[i] == v) {\n                    vec.erase(vec.begin() + i);\n                    break;\n                }\n            }\n        }\n        parent[v] = -1;                 // v becomes a root of its own tree\n    }\n\n    void attach(int v, int newParent) {\n        parent[v] = newParent;\n        if (newParent != -1) children[newParent].push_back(v);\n    }\n\n    void applyDepthDelta(int v, int delta) {\n        depth[v] += delta;\n        for (int c : children[v]) applyDepthDelta(c, delta);\n    }\n\n    // recompute sumA and high on the path from v upwards (at most H steps)\n    void recomputeUpward(int v) {\n        while (v != -1) {\n            int s = A[v];\n            int h = 0;\n            for (int c : children[v]) {\n                s += sumA[c];\n                h = max(h, high[c] + 1);\n            }\n            sumA[v] = s;\n            high[v] = h;\n            v = parent[v];\n        }\n    }\n\n    // evaluate a possible move of subtree v to newParent ( -1 = root )\n    // returns {newDepth, gain}  ; gain = -inf if illegal\n    pair<int,long long> evaluateMove(int v, int newParent) const {\n        if (newParent == parent[v]) return {depth[v], 0};          // no change\n        if (newParent != -1 && isDescendant(v, newParent))\n            return {0, LLONG_MIN};                               // would create a cycle\n\n        int newDepth = (newParent == -1 ? 0 : depth[newParent] + 1);\n        if (newDepth + high[v] > H) return {0, LLONG_MIN};       // height violation\n\n        long long delta = (long long)newDepth - (long long)depth[v];\n        long long gain = delta * (long long)sumA[v];\n        return {newDepth, gain};\n    }\n\n    // really perform a move (already known to be legal)\n    void performMove(int v, int newParent, int newDepth) {\n        int oldParent = parent[v];\n        int oldDepth  = depth[v];\n\n        // detach\n        detach(v);\n        if (oldParent != -1) recomputeUpward(oldParent);\n\n        // attach to new parent\n        attach(v, newParent);\n\n        // shift depths inside the whole subtree\n        int delta = newDepth - oldDepth;\n        if (delta != 0) applyDepthDelta(v, delta);\n\n        // recompute sums on the new side\n        if (newParent != -1) recomputeUpward(newParent);\n        else                 recomputeUpward(v);\n\n        totalDepthSum += (long long)delta * (long long)sumA[v];\n    }\n\n    // ---------- greedy hill climbing ----------\n    void greedyPhase(mt19937 &rng, int maxPasses = 30) {\n        bool improved = true;\n        int passes = 0;\n        while (improved && passes < maxPasses) {\n            improved = false;\n            vector<int> order(N);\n            iota(order.begin(), order.end(), 0);\n            shuffle(order.begin(), order.end(), rng);\n            for (int v : order) {\n                int bestParent = -2;\n                int bestDepth  = depth[v];\n                long long bestGain = 0;\n                // try all neighbours\n                for (int u : adj[v]) {\n                    if (u == parent[v]) continue;\n                    auto [newDepth, gain] = evaluateMove(v, u);\n                    if (gain > bestGain) {\n                        bestGain = gain;\n                        bestParent = u;\n                        bestDepth  = newDepth;\n                    }\n                }\n                // also try becoming a root (gain is never positive here)\n                if (bestGain > 0) {\n                    performMove(v, bestParent, bestDepth);\n                    improved = true;\n                }\n            }\n            ++passes;\n        }\n    }\n\n    // ---------- simulated annealing ----------\n    void annealingPhase(mt19937 &rng, double timeLimit) {\n        const double START_TEMP = 2e6;          // a bit larger than maximal possible gain\n        const double END_TEMP   = 1.0;\n        auto start = chrono::steady_clock::now();\n\n        double temp = START_TEMP;\n        uniform_int_distribution<int> VertDist(0, N - 1);\n        uniform_real_distribution<double> ProbDist(0.0, 1.0);\n\n        // iterate until the time budget is exhausted\n        while (true) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - start).count();\n            if (elapsed > timeLimit) break;\n\n            // cooling schedule \u2013 exponential, slower than linear\n            double progress = elapsed / timeLimit;                 // 0 \u2026 1\n            temp = START_TEMP * pow(END_TEMP / START_TEMP, progress);\n\n            int v = VertDist(rng);\n            if (adj[v].empty()) continue;   // never happens (graph is connected)\n\n            // with probability 0.25 try to make the vertex a root,\n            // otherwise pick a random neighbour as new parent\n            int newParent;\n            if (ProbDist(rng) < 0.25) {\n                newParent = -1;\n            } else {\n                int idx = uniform_int_distribution<int>(0, (int)adj[v].size() - 1)(rng);\n                newParent = adj[v][idx];\n            }\n\n            auto [newDepth, gain] = evaluateMove(v, newParent);\n            if (gain == LLONG_MIN) continue;   // illegal\n\n            bool accept = false;\n            if (gain > 0) accept = true;\n            else if (temp > 1e-12) {\n                double prob = exp(gain / temp);\n                if (prob > ProbDist(rng)) accept = true;\n            }\n            if (!accept) continue;\n\n            performMove(v, newParent, newDepth);\n        }\n    }\n\n    long long totalScore() const {\n        return sumAAll + totalDepthSum;\n    }\n};\n\n// -----------------------------------------------------------------------\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, H;\n    if (!(cin >> N >> M >> H)) return 0;\n\n    vector<int> A(N);\n    for (int i = 0; i < N; ++i) cin >> A[i];\n\n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; ++i) {\n        int u, v; cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    // read and discard coordinates\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n    }\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    long long bestScore = 0;\n    vector<int> bestParent(N, -1);\n    {\n        Tree tree(N, H, A, adj);\n        bestScore = tree.totalScore();\n        bestParent = tree.parent;\n    }\n\n    auto start = chrono::steady_clock::now();\n\n    // ---- several restarts (as long as time permits) ----\n    int rounds = 0;\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > 1.85) break;          // total time limit\n\n        Tree tree(N, H, A, adj);\n        tree.greedyPhase(rng, 30);           // up to 30 passes\n\n        // a short but intensive annealing phase\n        double timeLeft = 1.85 - elapsed;\n        if (timeLeft > 0.3) {\n            tree.annealingPhase(rng, timeLeft * 0.75);\n            // final polishing greedy pass\n            tree.greedyPhase(rng, 10);\n        }\n\n        long long cur = tree.totalScore();\n        if (cur > bestScore) {\n            bestScore = cur;\n            bestParent = tree.parent;\n        }\n        ++rounds;\n    }\n\n    // ---------------------------------------------------------------\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << bestParent[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Oni {\n    int i, j;                     // position\n    int upDist, downDist, leftDist, rightDist;\n    bool upSafe, downSafe, leftSafe, rightSafe;\n};\n\n/* -------------------------------------------------------------\n   simulate the whole sequence, respecting the decisions\n   columnsFirst = true  -> columns first, rows afterwards\n   columnsFirst = false -> rows first, columns afterwards\n   moves will be filled with the produced sequence.\n   ------------------------------------------------------------- */\nint simulate(bool columnsFirst,\n             const vector<Oni>& oni,\n             vector<pair<char,int>>& moves) {\n    const int N = 20;                     // board size (fixed in the problem)\n    const int M = (int)oni.size();        // 2*N\n\n    vector<char> removed(M, 0);           // 0 = still on board, 1 = removed\n    int totalMoves = 0;\n    auto addBlock = [&](char dir, int idx, int cnt) {\n        for (int k = 0; k < cnt; ++k) moves.emplace_back(dir, idx);\n        totalMoves += 2 * cnt;            // each block consists of a pair of shifts\n    };\n\n    if (columnsFirst) {\n        // -------------------------------------------------------------\n        // ----- 1. columns (up/down) -----\n        for (int col = 0; col < N; ++col) {\n            // compute the four values for this column\n            int upAll = 0, downAll = 0, upOnly = 0, downOnly = 0;\n            for (int id = 0; id < M; ++id) {\n                const Oni& o = oni[id];\n                if (o.j != col) continue;\n                if (o.upSafe) {\n                    upAll = max(upAll, o.upDist);\n                    if (!o.downSafe) upOnly = max(upOnly, o.upDist);\n                }\n                if (o.downSafe) {\n                    downAll = max(downAll, o.downDist);\n                    if (!o.upSafe) downOnly = max(downOnly, o.downDist);\n                }\n            }\n            // choose the cheaper order\n            bool upFirst = (2 * (upAll + downOnly) <= 2 * (downAll + upOnly));\n\n            if (upFirst) {\n                // up phase\n                int upMax = 0; vector<int> ids;\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.j == col && o.upSafe) {\n                        upMax = max(upMax, o.upDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (upMax) {\n                    addBlock('U', col, upMax);\n                    addBlock('D', col, upMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n                // down phase (only down\u2011safe that are still alive)\n                int downMax = 0; ids.clear();\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.j == col && o.downSafe) {\n                        downMax = max(downMax, o.downDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (downMax) {\n                    addBlock('D', col, downMax);\n                    addBlock('U', col, downMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n            } else {\n                // down phase first\n                int downMax = 0; vector<int> ids;\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.j == col && o.downSafe) {\n                        downMax = max(downMax, o.downDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (downMax) {\n                    addBlock('D', col, downMax);\n                    addBlock('U', col, downMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n                // up phase (only up\u2011safe that are still alive)\n                int upMax = 0; ids.clear();\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.j == col && o.upSafe) {\n                        upMax = max(upMax, o.upDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (upMax) {\n                    addBlock('U', col, upMax);\n                    addBlock('D', col, upMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n            }\n        }\n\n        // -------------------------------------------------------------\n        // ----- 2. rows (left/right) -----\n        for (int row = 0; row < N; ++row) {\n            // recompute the four values using the still alive Oni\n            int leftAll = 0, rightAll = 0, leftOnly = 0, rightOnly = 0;\n            for (int id = 0; id < M; ++id) {\n                const Oni& o = oni[id];\n                if (removed[id] || o.i != row) continue;\n                if (o.leftSafe) {\n                    leftAll = max(leftAll, o.leftDist);\n                    if (!o.rightSafe) leftOnly = max(leftOnly, o.leftDist);\n                }\n                if (o.rightSafe) {\n                    rightAll = max(rightAll, o.rightDist);\n                    if (!o.leftSafe) rightOnly = max(rightOnly, o.rightDist);\n                }\n            }\n            bool leftFirst = (2 * (leftAll + rightOnly) <= 2 * (rightAll + leftOnly));\n\n            if (leftFirst) {\n                // left phase\n                int leftMax = 0; vector<int> ids;\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.i == row && o.leftSafe) {\n                        leftMax = max(leftMax, o.leftDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (leftMax) {\n                    addBlock('L', row, leftMax);\n                    addBlock('R', row, leftMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n                // right phase (only right\u2011safe still alive)\n                int rightMax = 0; ids.clear();\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.i == row && o.rightSafe) {\n                        rightMax = max(rightMax, o.rightDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (rightMax) {\n                    addBlock('R', row, rightMax);\n                    addBlock('L', row, rightMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n            } else {\n                // right phase first\n                int rightMax = 0; vector<int> ids;\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.i == row && o.rightSafe) {\n                        rightMax = max(rightMax, o.rightDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (rightMax) {\n                    addBlock('R', row, rightMax);\n                    addBlock('L', row, rightMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n                // left phase (only left\u2011safe still alive)\n                int leftMax = 0; ids.clear();\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.i == row && o.leftSafe) {\n                        leftMax = max(leftMax, o.leftDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (leftMax) {\n                    addBlock('L', row, leftMax);\n                    addBlock('R', row, leftMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n            }\n        }\n    } else {\n        // -------------------------------------------------------------\n        // ----- rows first, symmetric -----\n        for (int row = 0; row < N; ++row) {\n            int leftAll = 0, rightAll = 0, leftOnly = 0, rightOnly = 0;\n            for (int id = 0; id < M; ++id) {\n                const Oni& o = oni[id];\n                if (o.i != row) continue;\n                if (o.leftSafe) {\n                    leftAll = max(leftAll, o.leftDist);\n                    if (!o.rightSafe) leftOnly = max(leftOnly, o.leftDist);\n                }\n                if (o.rightSafe) {\n                    rightAll = max(rightAll, o.rightDist);\n                    if (!o.leftSafe) rightOnly = max(rightOnly, o.rightDist);\n                }\n            }\n            bool leftFirst = (2 * (leftAll + rightOnly) <= 2 * (rightAll + leftOnly));\n\n            if (leftFirst) {\n                int leftMax = 0; vector<int> ids;\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.i == row && o.leftSafe) {\n                        leftMax = max(leftMax, o.leftDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (leftMax) {\n                    addBlock('L', row, leftMax);\n                    addBlock('R', row, leftMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n                int rightMax = 0; ids.clear();\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.i == row && o.rightSafe) {\n                        rightMax = max(rightMax, o.rightDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (rightMax) {\n                    addBlock('R', row, rightMax);\n                    addBlock('L', row, rightMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n            } else {\n                int rightMax = 0; vector<int> ids;\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.i == row && o.rightSafe) {\n                        rightMax = max(rightMax, o.rightDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (rightMax) {\n                    addBlock('R', row, rightMax);\n                    addBlock('L', row, rightMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n                int leftMax = 0; ids.clear();\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.i == row && o.leftSafe) {\n                        leftMax = max(leftMax, o.leftDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (leftMax) {\n                    addBlock('L', row, leftMax);\n                    addBlock('R', row, leftMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n            }\n        }\n\n        // ----- columns afterwards -----\n        for (int col = 0; col < N; ++col) {\n            int upAll = 0, downAll = 0, upOnly = 0, downOnly = 0;\n            for (int id = 0; id < M; ++id) {\n                const Oni& o = oni[id];\n                if (removed[id] || o.j != col) continue;\n                if (o.upSafe) {\n                    upAll = max(upAll, o.upDist);\n                    if (!o.downSafe) upOnly = max(upOnly, o.upDist);\n                }\n                if (o.downSafe) {\n                    downAll = max(downAll, o.downDist);\n                    if (!o.upSafe) downOnly = max(downOnly, o.downDist);\n                }\n            }\n            bool upFirst = (2 * (upAll + downOnly) <= 2 * (downAll + upOnly));\n\n            if (upFirst) {\n                int upMax = 0; vector<int> ids;\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.j == col && o.upSafe) {\n                        upMax = max(upMax, o.upDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (upMax) {\n                    addBlock('U', col, upMax);\n                    addBlock('D', col, upMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n                int downMax = 0; ids.clear();\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.j == col && o.downSafe) {\n                        downMax = max(downMax, o.downDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (downMax) {\n                    addBlock('D', col, downMax);\n                    addBlock('U', col, downMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n            } else {\n                int downMax = 0; vector<int> ids;\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.j == col && o.downSafe) {\n                        downMax = max(downMax, o.downDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (downMax) {\n                    addBlock('D', col, downMax);\n                    addBlock('U', col, downMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n                int upMax = 0; ids.clear();\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.j == col && o.upSafe) {\n                        upMax = max(upMax, o.upDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (upMax) {\n                    addBlock('U', col, upMax);\n                    addBlock('D', col, upMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n            }\n        }\n    }\n\n    // sanity check \u2013 all Oni must be removed now\n    // (the input guarantees this is possible)\n    return totalMoves;\n}\n\n/* ------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;                                   // N = 20 in the contest\n    if (!(cin >> N)) return 0;\n    vector<string> board(N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n\n    // locate Fuku (only needed for the safety test)\n    vector<vector<bool>> fuku(N, vector<bool>(N, false));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (board[i][j] == 'o') fuku[i][j] = true;\n\n    // -----------------------------------------------------------------\n    // build the list of Oni and compute safety flags\n    vector<Oni> oni;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (board[i][j] == 'x') {\n                Oni o;\n                o.i = i; o.j = j;\n                o.upDist   = i + 1;\n                o.downDist = N - i;\n                o.leftDist = j + 1;\n                o.rightDist = N - j;\n\n                // safety flags\n                o.upSafe = true;\n                for (int ii = 0; ii < i; ++ii) if (fuku[ii][j]) { o.upSafe = false; break; }\n                o.downSafe = true;\n                for (int ii = i + 1; ii < N; ++ii) if (fuku[ii][j]) { o.downSafe = false; break; }\n                o.leftSafe = true;\n                for (int jj = 0; jj < j; ++jj) if (fuku[i][jj]) { o.leftSafe = false; break; }\n                o.rightSafe = true;\n                for (int jj = j + 1; jj < N; ++jj) if (fuku[i][jj]) { o.rightSafe = false; break; }\n\n                oni.push_back(o);\n            }\n\n    // -----------------------------------------------------------------\n    // try both global orders and keep the better one\n    vector<pair<char,int>> moves1, moves2;\n    int cost1 = simulate(true,  oni, moves1);   // columns first\n    int cost2 = simulate(false, oni, moves2);   // rows first\n\n    const auto& bestMoves = (cost1 <= cost2) ? moves1 : moves2;\n\n    // -----------------------------------------------------------------\n    // output the chosen sequence\n    for (auto [dir, idx] : bestMoves) cout << dir << ' ' << idx << '\\n';\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    \n    const int N = 100;\n    const long long L = 500000;\n    const long long AVG = L / N; // 5000\n    const long long STEP = 2500;  // Base adjustment unit\n    \n    vector<long long> T(N);\n    int n_input;\n    long long l_input;\n    cin >> n_input >> l_input;\n    for (int i = 0; i < N; ++i) cin >> T[i];\n    \n    const long long INF = (1LL << 60);\n    long long best_error = INF;\n    vector<int> best_x(N);\n    \n    // Phase 1: DP for odd transitions (proven core model)\n    for (int x0 = 0; x0 <= 1; ++x0) {\n        static long long dp[101][2];\n        static int parent[101][2];\n        \n        dp[0][0] = dp[0][1] = INF;\n        dp[0][x0] = 0;\n        parent[0][x0] = -1;\n        \n        for (int i = 1; i < N; ++i) {\n            dp[i][0] = dp[i][1] = INF;\n            for (int x_curr = 0; x_curr <= 1; ++x_curr) {\n                for (int x_prev = 0; x_prev <= 1; ++x_prev) {\n                    if (dp[i-1][x_prev] == INF) continue;\n                    \n                    long long visits = AVG + STEP * (x_curr - x_prev);\n                    long long error = llabs(T[i] - visits);\n                    long long total = dp[i-1][x_prev] + error;\n                    \n                    if (total < dp[i][x_curr]) {\n                        dp[i][x_curr] = total;\n                        parent[i][x_curr] = x_prev;\n                    }\n                }\n            }\n        }\n        \n        for (int x_last = 0; x_last <= 1; ++x_last) {\n            if (dp[N-1][x_last] == INF) continue;\n            \n            long long visits = AVG + STEP * (x0 - x_last);\n            long long error = llabs(T[0] - visits);\n            long long total = dp[N-1][x_last] + error;\n            \n            if (total < best_error) {\n                best_error = total;\n                best_x[0] = x0;\n                int curr = x_last;\n                for (int i = N-1; i >= 1; --i) {\n                    best_x[i] = curr;\n                    curr = parent[i][curr];\n                }\n            }\n        }\n    }\n    \n    // Phase 2: Aggressive greedy refinement (top 25 employees)\n    vector<int> y(N, 0); // even modifications\n    \n    // Calculate initial residuals\n    vector<long long> residual(N);\n    for (int i = 0; i < N; ++i) {\n        long long adj = STEP * (best_x[i] - best_x[(i-1+N)%N]);\n        residual[i] = llabs(T[i] - (AVG + adj));\n    }\n    \n    // Sort candidates by descending residual error\n    vector<int> candidates(N);\n    iota(candidates.begin(), candidates.end(), 0);\n    sort(candidates.begin(), candidates.end(), [&](int a, int b) {\n        return residual[a] > residual[b];\n    });\n    \n    // Try even modifications for top REFINE_LIMIT candidates\n    const int REFINE_LIMIT = 25;\n    for (int idx = 0; idx < REFINE_LIMIT; ++idx) {\n        int i = candidates[idx];\n        if (best_x[i] == 1) continue; // Safety: avoid double self-loop\n        \n        long long new_visits = AVG + STEP * (best_x[i] - best_x[(i-1+N)%N] + 1);\n        long long new_error = llabs(T[i] - new_visits);\n        \n        if (new_error < residual[i]) {\n            y[i] = 1; // Accept even self-loop\n            residual[i] = new_error;\n        }\n    }\n    \n    // Phase 3: Construct and output\n    vector<int> a(N), b(N);\n    for (int i = 0; i < N; ++i) {\n        a[i] = (best_x[i] == 1) ? i : (i + 1) % N;\n        b[i] = (y[i] == 1) ? i : (i + 1) % N;\n    }\n    \n    for (int i = 0; i < N; ++i) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ---------- integer square root ---------- */\nint isqrt_ll(long long x) {\n    int r = (int)std::sqrt((long double)x);\n    while ((long long)(r + 1) * (r + 1) <= x) ++r;\n    while ((long long)r * r > x) --r;\n    return r;\n}\n\n/* ---------- DSU ---------- */\nstruct DSU {\n    vector<int> parent, sz;\n    int comps;\n    DSU(int n = 0) { init(n); }\n    void init(int n) {\n        parent.resize(n);\n        sz.assign(n, 1);\n        iota(parent.begin(), parent.end(), 0);\n        comps = n;\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 (sz[a] < sz[b]) swap(a, b);\n        parent[b] = a;\n        sz[a] += sz[b];\n        --comps;\n        return true;\n    }\n};\n\n/* ---------- lower bound distance between rectangles ---------- */\nint lowerDistRect(int i, int j,\n                  const vector<int>& lx, const vector<int>& rx,\n                  const vector<int>& ly, const vector<int>& ry) {\n    long long dx = 0, dy = 0;\n    if (rx[i] < lx[j]) dx = (long long)lx[j] - rx[i];\n    else if (rx[j] < lx[i]) dx = (long long)lx[i] - rx[j];\n    else dx = 0;\n\n    if (ry[i] < ly[j]) dy = (long long)ly[j] - ry[i];\n    else if (ry[j] < ly[i]) dy = (long long)ly[i] - ry[j];\n    else dy = 0;\n\n    long long sq = dx * dx + dy * dy;\n    return isqrt_ll(sq);\n}\n\n/* ---------- Hilbert order ---------- */\nvoid rot(int &x, int &y, int rx, int ry, int s) {\n    if (ry == 0) {\n        if (rx == 1) {\n            x = s - 1 - x;\n            y = s - 1 - y;\n        }\n        swap(x, y);\n    }\n}\nint hilbert(int x, int y, int N = 21) {\n    int h = 0, s = 1 << N;\n    for (int rx, ry, s2; s > 1; s = s2) {\n        s2 = s / 2;\n        rx = (x & s2) ? 1 : 0;\n        ry = (y & s2) ? 1 : 0;\n        h += s2 * s2 * ((3 * rx) ^ ry);\n        rot(x, y, rx, ry, s2);\n    }\n    return h;\n}\n\n/* ---------- Morton (Z) order ---------- */\nint morton(int x, int y) {\n    unsigned int mx = (unsigned int)x;\n    unsigned int my = (unsigned int)y;\n    mx = (mx | (mx << 8)) & 0x00FF00FF;\n    mx = (mx | (mx << 4)) & 0x0F0F0F0F;\n    mx = (mx | (mx << 2)) & 0x33333333;\n    mx = (mx | (mx << 1)) & 0x55555555;\n\n    my = (my | (my << 8)) & 0x00FF00FF;\n    my = (my | (my << 4)) & 0x0F0F0F0F;\n    my = (my | (my << 2)) & 0x33333333;\n    my = (my | (my << 1)) & 0x55555555;\n\n    return (int)(mx | (my << 1));\n}\n\n/* ---------- estimate total lower\u2011bound MST cost for a partition ---------- */\nlong long estimate_partition_cost(const vector<vector<int>>& groups,\n                                  const vector<vector<int>>& low) {\n    long long total = 0;\n    for (const auto& g : groups) {\n        int sz = g.size();\n        if (sz <= 1) continue;\n        // Prim's algorithm using lower bounds\n        vector<int> minDist(sz, INT_MAX);\n        vector<bool> inTree(sz, false);\n        inTree[0] = true;\n        for (int i = 1; i < sz; ++i)\n            minDist[i] = low[g[0]][g[i]];\n        for (int i = 1; i < sz; ++i) {\n            int best = -1, bestDist = INT_MAX;\n            for (int j = 0; j < sz; ++j)\n                if (!inTree[j] && minDist[j] < bestDist) {\n                    bestDist = minDist[j];\n                    best = j;\n                }\n            total += bestDist;\n            inTree[best] = true;\n            for (int j = 0; j < sz; ++j)\n                if (!inTree[j]) {\n                    int d = low[g[best]][g[j]];\n                    if (d < minDist[j]) minDist[j] = d;\n                }\n        }\n    }\n    return total;\n}\n\n/* ---------- create a partition from a given order ---------- */\nvector<vector<int>> make_partition_from_order(const vector<int>& order,\n                                               const vector<int>& G) {\n    vector<vector<int>> groups(G.size());\n    int pos = 0;\n    for (size_t i = 0; i < G.size(); ++i) {\n        groups[i].reserve(G[i]);\n        for (int j = 0; j < G[i]; ++j)\n            groups[i].push_back(order[pos++]);\n    }\n    return groups;\n}\n\n/* ---------- main ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, Q, L, W;\n    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    vector<int> lx(N), rx(N), ly(N), ry(N);\n    for (int i = 0; i < N; ++i) cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n\n    /* ----- pre\u2011compute lower bounds ----- */\n    vector<vector<int>> low(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        low[i][i] = 0;\n        for (int j = i + 1; j < N; ++j) {\n            int d = lowerDistRect(i, j, lx, rx, ly, ry);\n            low[i][j] = low[j][i] = d;\n        }\n    }\n\n    /* ----- build several candidate partitions and keep the best ----- */\n    vector<int> cx(N), cy(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    // candidate 1: Hilbert order\n    vector<int> order_hilbert(N);\n    iota(order_hilbert.begin(), order_hilbert.end(), 0);\n    sort(order_hilbert.begin(), order_hilbert.end(),\n         [&](int a, int b) { return hilbert(cx[a], cy[a]) < hilbert(cx[b], cy[b]); });\n    auto part_hilbert = make_partition_from_order(order_hilbert, G);\n    long long cost_hilbert = estimate_partition_cost(part_hilbert, low);\n\n    // candidate 2: Morton order\n    vector<int> order_morton(N);\n    iota(order_morton.begin(), order_morton.end(), 0);\n    sort(order_morton.begin(), order_morton.end(),\n         [&](int a, int b) { return morton(cx[a], cy[a]) < morton(cx[b], cy[b]); });\n    auto part_morton = make_partition_from_order(order_morton, G);\n    long long cost_morton = estimate_partition_cost(part_morton, low);\n\n    // candidate 3: lexicographic (x, y)\n    vector<int> order_xy(N);\n    iota(order_xy.begin(), order_xy.end(), 0);\n    sort(order_xy.begin(), order_xy.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    auto part_xy = make_partition_from_order(order_xy, G);\n    long long cost_xy = estimate_partition_cost(part_xy, low);\n\n    // choose the partition with smallest estimated cost\n    vector<vector<int>> groups;\n    if (cost_morton < cost_hilbert && cost_morton < cost_xy) groups = part_morton;\n    else if (cost_hilbert < cost_xy) groups = part_hilbert;\n    else groups = part_xy;\n\n    /* ----- auxiliary data ----- */\n    vector<int> group_of(N, -1);\n    vector<int> local_idx(N, -1);\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < (int)groups[i].size(); ++j) {\n            int city = groups[i][j];\n            group_of[city] = i;\n            local_idx[city] = j;\n        }\n    }\n\n    vector<DSU> dsu(M);\n    for (int i = 0; i < M; ++i) dsu[i].init((int)groups[i].size());\n\n    vector<vector<pair<int,int>>> group_edges(M);\n\n    /* ----- query phase (deterministic) ----- */\n    int queries_used = 0;\n    while (queries_used < Q) {\n        int best_g = -1, best_comp = 0;\n        for (int i = 0; i < M; ++i) {\n            if (dsu[i].comps > best_comp) {\n                best_comp = dsu[i].comps;\n                best_g = i;\n            }\n        }\n        if (best_g == -1 || best_comp <= 1) break; // all finished\n\n        unordered_map<int,int> rep;   // DSU root -> city id\n        for (int city : groups[best_g]) {\n            int lid = local_idx[city];\n            int root = dsu[best_g].find(lid);\n            if (!rep.count(root)) rep[root] = city;\n        }\n        vector<int> reps;\n        reps.reserve(rep.size());\n        for (auto &kv : rep) reps.push_back(kv.second);\n        sort(reps.begin(), reps.end());   // deterministic order\n\n        vector<int> subset;\n        if ((int)reps.size() <= L) {\n            subset = reps;\n        } else {\n            subset.assign(reps.begin(), reps.begin() + L);\n        }\n\n        int l = (int)subset.size();\n        cout << \"? \" << l;\n        for (int v : subset) cout << ' ' << v;\n        cout << '\\n';\n        cout.flush();\n\n        for (int i = 0; i < l - 1; ++i) {\n            int a, b;\n            cin >> a >> b;\n            if (group_of[a] != group_of[b]) continue;\n            int g = group_of[a];\n            int la = local_idx[a];\n            int lb = local_idx[b];\n            if (dsu[g].unite(la, lb)) {\n                group_edges[g].push_back({a, b});\n            }\n        }\n        ++queries_used;\n    }\n\n    /* ----- finish groups that are still disconnected ----- */\n    for (int g = 0; g < M; ++g) {\n        if (dsu[g].comps == 1) continue;\n        struct Edge {int u, v, w;};\n        vector<Edge> edges;\n        int sz = (int)groups[g].size();\n        edges.reserve(sz * (sz - 1) / 2);\n        for (int i = 0; i < sz; ++i) {\n            int u = groups[g][i];\n            int lu = i;\n            for (int j = i + 1; j < sz; ++j) {\n                int v = groups[g][j];\n                int lv = j;\n                if (dsu[g].find(lu) == dsu[g].find(lv)) continue;\n                int w = low[u][v];\n                edges.push_back({u, v, w});\n            }\n        }\n        sort(edges.begin(), edges.end(),\n             [](const Edge& a, const Edge& b) {\n                 if (a.w != b.w) return a.w < b.w;\n                 if (a.u != b.u) return a.u < b.u;\n                 return a.v < b.v;\n             });\n        for (const Edge &e : edges) {\n            int lu = local_idx[e.u];\n            int lv = local_idx[e.v];\n            if (dsu[g].unite(lu, lv)) {\n                group_edges[g].push_back({e.u, e.v});\n                if (dsu[g].comps == 1) break;\n            }\n        }\n    }\n\n    /* ----- output ----- */\n    cout << \"!\\n\";\n    for (int g = 0; g < M; ++g) {\n        for (size_t i = 0; i < groups[g].size(); ++i) {\n            if (i) cout << ' ';\n            cout << groups[g][i];\n        }\n        cout << '\\n';\n        for (auto &e : group_edges[g])\n            cout << e.first << ' ' << e.second << '\\n';\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint 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>> p(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> p[i].first >> p[i].second;\n    }\n\n    pair<int,int> cur = p[0];                 // start position\n    for (int idx = 1; idx < M; ++idx) {\n        const pair<int,int> tgt = p[idx];\n\n        /* slide to every border that the target touches */\n        if (tgt.first == 0 && cur.first != 0) {\n            cout << \"S U\\n\";\n            cur.first = 0;\n        } else if (tgt.first == N-1 && cur.first != N-1) {\n            cout << \"S D\\n\";\n            cur.first = N-1;\n        }\n\n        if (tgt.second == 0 && cur.second != 0) {\n            cout << \"S L\\n\";\n            cur.second = 0;\n        } else if (tgt.second == N-1 && cur.second != N-1) {\n            cout << \"S R\\n\";\n            cur.second = N-1;\n        }\n\n        /* finish the remaining distance with ordinary moves */\n        while (cur.first < tgt.first) {\n            cout << \"M D\\n\";\n            ++cur.first;\n        }\n        while (cur.first > tgt.first) {\n            cout << \"M U\\n\";\n            --cur.first;\n        }\n        while (cur.second < tgt.second) {\n            cout << \"M R\\n\";\n            ++cur.second;\n        }\n        while (cur.second > tgt.second) {\n            cout << \"M L\\n\";\n            --cur.second;\n        }\n    }\n    return 0;\n}"},"8":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Company {\n    int x, y;\n    long long r;\n    int a, b, c, d;\n};\n\nstruct Region {\n    int x1, y1, x2, y2;\n    vector<int> points;\n};\n\nclass PartitionSolver {\nprivate:\n    vector<Company> &comp;\n    const int W = 10000;\n    const int H = 10000;\n    \n    double satisfaction(long long r, long long s) {\n        if (s == 0) return 0.0;\n        double ratio = min(r, s) / (double)max(r, s);\n        return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n    }\n    \n    bool findBestSplit(const Region &reg, const vector<int> &pts, bool vertical,\n                       int &best_split, int &best_cut, double &best_score) {\n        vector<int> sorted = pts;\n        if (vertical) {\n            sort(sorted.begin(), sorted.end(), [&](int i, int j) {\n                return comp[i].x < comp[j].x;\n            });\n        } else {\n            sort(sorted.begin(), sorted.end(), [&](int i, int j) {\n                return comp[i].y < comp[j].y;\n            });\n        }\n        \n        best_score = -1;\n        long long total_r = 0;\n        for (int i : pts) total_r += comp[i].r;\n        \n        // Try all split positions\n        for (int split = 1; split < sorted.size(); split++) {\n            long long sum_r_left = 0;\n            for (int i = 0; i < split; i++) sum_r_left += comp[sorted[i]].r;\n            \n            // Find feasible cut range\n            int min_cut, max_cut;\n            if (vertical) {\n                int max_left = -1;\n                for (int i = 0; i < split; i++) max_left = max(max_left, comp[sorted[i]].x);\n                int min_right = W;\n                for (int i = split; i < sorted.size(); i++) min_right = min(min_right, comp[sorted[i]].x);\n                min_cut = max_left + 1;\n                max_cut = min_right;\n            } else {\n                int max_left = -1;\n                for (int i = 0; i < split; i++) max_left = max(max_left, comp[sorted[i]].y);\n                int min_right = H;\n                for (int i = split; i < sorted.size(); i++) min_right = min(min_right, comp[sorted[i]].y);\n                min_cut = max_left + 1;\n                max_cut = min_right;\n            }\n            \n            if (min_cut > max_cut) continue;\n            \n            // Target cut based on area\n            int target = vertical ? reg.x1 + (int)((double)sum_r_left / (reg.y2 - reg.y1))\n                                  : reg.y1 + (int)((double)sum_r_left / (reg.x2 - reg.x1));\n            \n            // Test multiple candidates\n            vector<int> cand = {min_cut, max_cut};\n            if (target >= min_cut && target <= max_cut) cand.push_back(target);\n            \n            for (int cut : cand) {\n                long long area_left = vertical ? (long long)(cut - reg.x1) * (reg.y2 - reg.y1)\n                                               : (long long)(reg.x2 - reg.x1) * (cut - reg.y1);\n                long long area_right = total_r - sum_r_left;\n                area_right = vertical ? (long long)(reg.x2 - reg.x1) * (reg.y2 - reg.y1) - area_left\n                                      : (long long)(reg.x2 - reg.x1) * (reg.y2 - reg.y1) - area_left;\n                \n                double score = satisfaction(sum_r_left, area_left) + satisfaction(total_r - sum_r_left, area_right);\n                \n                if (score > best_score) {\n                    best_score = score;\n                    best_split = split;\n                    best_cut = cut;\n                }\n            }\n        }\n        return best_score >= 0;\n    }\n    \n    void solveRegion(Region &reg) {\n        if (reg.points.size() <= 1) {\n            if (reg.points.size() == 1) {\n                int idx = reg.points[0];\n                comp[idx].a = reg.x1;\n                comp[idx].b = reg.y1;\n                comp[idx].c = reg.x2;\n                comp[idx].d = reg.y2;\n            }\n            return;\n        }\n        \n        // Try both orientations\n        int best_split_v, best_cut_v, best_split_h, best_cut_h;\n        double best_score_v = -1, best_score_h = -1;\n        \n        bool found_v = findBestSplit(reg, reg.points, true, best_split_v, best_cut_v, best_score_v);\n        bool found_h = findBestSplit(reg, reg.points, false, best_split_h, best_cut_h, best_score_h);\n        \n        bool vertical;\n        int best_split, best_cut;\n        if (!found_v && !found_h) {\n            // Fallback: median split\n            vertical = (reg.x2 - reg.x1) > (reg.y2 - reg.y1);\n            best_split = reg.points.size() / 2;\n            best_cut = vertical ? (reg.x1 + reg.x2) / 2 : (reg.y1 + reg.y2) / 2;\n        } else if (!found_v) {\n            vertical = false;\n            best_split = best_split_h;\n            best_cut = best_cut_h;\n        } else if (!found_h) {\n            vertical = true;\n            best_split = best_split_v;\n            best_cut = best_cut_v;\n        } else {\n            vertical = best_score_v >= best_score_h;\n            best_split = vertical ? best_split_v : best_split_h;\n            best_cut = vertical ? best_cut_v : best_cut_h;\n        }\n        \n        // Sort points\n        vector<int> sorted = reg.points;\n        if (vertical) {\n            sort(sorted.begin(), sorted.end(), [&](int i, int j) {\n                return comp[i].x < comp[j].x;\n            });\n        } else {\n            sort(sorted.begin(), sorted.end(), [&](int i, int j) {\n                return comp[i].y < comp[j].y;\n            });\n        }\n        \n        // Create sub-regions\n        Region left = reg;\n        Region right = reg;\n        left.points.clear();\n        right.points.clear();\n        \n        if (vertical) {\n            left.x2 = best_cut;\n            right.x1 = best_cut;\n        } else {\n            left.y2 = best_cut;\n            right.y1 = best_cut;\n        }\n        \n        for (int i = 0; i < sorted.size(); i++) {\n            if (i < best_split) left.points.push_back(sorted[i]);\n            else right.points.push_back(sorted[i]);\n        }\n        \n        solveRegion(left);\n        solveRegion(right);\n    }\n    \npublic:\n    PartitionSolver(vector<Company> &c) : comp(c) {}\n    \n    void solve() {\n        Region root{0, 0, W, H};\n        for (int i = 0; i < comp.size(); i++) root.points.push_back(i);\n        solveRegion(root);\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<Company> comp(n);\n    for (int i = 0; i < n; i++) cin >> comp[i].x >> comp[i].y >> comp[i].r;\n    \n    PartitionSolver solver(comp);\n    solver.solve();\n    \n    for (auto &c : comp) {\n        cout << c.a << \" \" << c.b << \" \" << c.c << \" \" << c.d << \"\\n\";\n    }\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Cell {\n    int value;\n    int tile_id;\n    vector<int> neighbors;\n};\n\nchar getDir(int from, int to) {\n    int from_i = from / 50;\n    int from_j = from % 50;\n    int to_i = to / 50;\n    int to_j = to % 50;\n    \n    if (to_i == from_i - 1) return 'U';\n    if (to_i == from_i + 1) return 'D';\n    if (to_j == from_j - 1) return 'L';\n    return 'R';\n}\n\n// Fast neighbor scoring with lookahead - inline for speed\ninline int scoreNeighbor(const vector<Cell>& cells, int neighbor_idx, \n                         const vector<int>& visited_tile, int timestamp) {\n    int base_score = cells[neighbor_idx].value;\n    \n    // Count available neighbors of this neighbor (future options)\n    int future_options = 0;\n    for (int next : cells[neighbor_idx].neighbors) {\n        if (visited_tile[cells[next].tile_id] != timestamp) {\n            future_options++;\n        }\n    }\n    \n    // Flexibility bonus, dead end penalty\n    return base_score + future_options * 15;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 50;\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    \n    int si, sj;\n    \n    while (cin >> si >> sj) {\n        vector<vector<int>> t(N, vector<int>(N));\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cin >> t[i][j];\n            }\n        }\n        \n        vector<vector<int>> p(N, vector<int>(N));\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cin >> p[i][j];\n            }\n        }\n        \n        vector<Cell> cells(N * N);\n        int max_tile_id = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int idx = i * N + j;\n                cells[idx].value = p[i][j];\n                cells[idx].tile_id = t[i][j];\n                max_tile_id = max(max_tile_id, t[i][j]);\n            }\n        }\n        \n        // Build adjacency\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int idx = i * N + j;\n                for (int dir = 0; dir < 4; dir++) {\n                    int ni = i + dx[dir];\n                    int nj = j + dy[dir];\n                    if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                    int nidx = ni * N + nj;\n                    if (cells[idx].tile_id != cells[nidx].tile_id) {\n                        cells[idx].neighbors.push_back(nidx);\n                    }\n                }\n            }\n        }\n        \n        string best_moves;\n        int best_score = -1;\n        mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n        \n        // Fast visited tracking using timestamp technique\n        vector<int> visited_tile(max_tile_id + 1, 0);\n        \n        // More attempts with lookahead but no expensive backtracking\n        for (int attempt = 0; attempt < 30; attempt++) {\n            string current_moves;\n            current_moves.reserve(2500);\n            \n            int current_cell = si * N + sj;\n            int timestamp = attempt + 1;\n            visited_tile[cells[current_cell].tile_id] = timestamp;\n            int current_score = cells[current_cell].value;\n            \n            while (true) {\n                // Collect valid neighbors\n                int valid_neighbors[4];\n                int neighbor_count = 0;\n                \n                for (int neighbor : cells[current_cell].neighbors) {\n                    if (visited_tile[cells[neighbor].tile_id] != timestamp) {\n                        valid_neighbors[neighbor_count++] = neighbor;\n                    }\n                }\n                \n                if (neighbor_count == 0) break;\n                \n                // Score neighbors and find best\n                int best_idx = 0;\n                int best_score_local = -1e9;\n                \n                for (int i = 0; i < neighbor_count; i++) {\n                    int neighbor = valid_neighbors[i];\n                    int score = scoreNeighbor(cells, neighbor, visited_tile, timestamp);\n                    \n                    // Small random tie-breaker\n                    score += (rng() & 7);\n                    \n                    if (score > best_score_local) {\n                        best_score_local = score;\n                        best_idx = i;\n                    }\n                }\n                \n                int next_cell = valid_neighbors[best_idx];\n                current_moves.push_back(getDir(current_cell, next_cell));\n                current_cell = next_cell;\n                visited_tile[cells[current_cell].tile_id] = timestamp;\n                current_score += cells[current_cell].value;\n            }\n            \n            if (current_score > best_score) {\n                best_score = current_score;\n                best_moves = current_moves;\n            }\n        }\n        \n        cout << best_moves << \"\\n\";\n    }\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\n////////////////////  parameters  ////////////////////\n\nstruct EdgeWeights {\n    double h[30][29]; // horizontal edges (i , j) -> (i , j+1)\n    double v[29][30]; // vertical   edges (i , j) -> (i+1 , j)\n};\n\n////////////////////  Dijkstra & path reconstruction  ////////////////////\n\nstruct State {\n    double dist;\n    int node;               // node id = i*30 + j\n    bool operator<(const State& other) const {\n        return dist > other.dist; // reversed for min\u2011heap\n    }\n};\n\n/*  run Dijkstra from (si,sj) to (ti,tj) using the given weight matrices.\n    returns the path as a string of U/D/L/R.                           */\nstring dijkstra_path(int si, int sj, int ti, int tj,\n                     const EdgeWeights& w,\n                     double* path_len = nullptr) {\n    const int N = 30 * 30;\n    const int s = si * 30 + sj;\n    const int t = ti * 30 + tj;\n\n    vector<double> dist(N, 1e100);\n    vector<int> prev(N, -1);\n    vector<char> pdir(N, 0);\n\n    priority_queue<State> pq;\n    dist[s] = 0.0;\n    pq.push({0.0, s});\n\n    while (!pq.empty()) {\n        auto cur = pq.top(); pq.pop();\n        int u = cur.node;\n        double d = cur.dist;\n        if (d > dist[u] + 1e-12) continue;\n        if (u == t) break; // we already know the shortest distance to t\n\n        int ui = u / 30, uj = u % 30;\n\n        // ----- up -----\n        if (ui > 0) {\n            int v = (ui - 1) * 30 + uj;\n            double nd = d + w.v[ui - 1][uj];\n            if (nd + 1e-12 < dist[v]) {\n                dist[v] = nd;\n                prev[v] = u;\n                pdir[v] = 'U';\n                pq.push({nd, v});\n            }\n        }\n        // ----- down -----\n        if (ui < 29) {\n            int v = (ui + 1) * 30 + uj;\n            double nd = d + w.v[ui][uj];\n            if (nd + 1e-12 < dist[v]) {\n                dist[v] = nd;\n                prev[v] = u;\n                pdir[v] = 'D';\n                pq.push({nd, v});\n            }\n        }\n        // ----- left -----\n        if (uj > 0) {\n            int v = ui * 30 + (uj - 1);\n            double nd = d + w.h[ui][uj - 1];\n            if (nd + 1e-12 < dist[v]) {\n                dist[v] = nd;\n                prev[v] = u;\n                pdir[v] = 'L';\n                pq.push({nd, v});\n            }\n        }\n        // ----- right -----\n        if (uj < 29) {\n            int v = ui * 30 + (uj + 1);\n            double nd = d + w.h[ui][uj];\n            if (nd + 1e-12 < dist[v]) {\n                dist[v] = nd;\n                prev[v] = u;\n                pdir[v] = 'R';\n                pq.push({nd, v});\n            }\n        }\n    }\n\n    // reconstruct the path from t to s\n    string path;\n    for (int cur = t; cur != s; cur = prev[cur]) {\n        path.push_back(pdir[cur]);\n    }\n    reverse(path.begin(), path.end());\n\n    if (path_len) *path_len = dist[t];\n    return path;\n}\n\n////////////////////  main  ////////////////////\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    random_device rd;\n    mt19937 rng(rd());\n\n    uniform_real_distribution<double> urd_noise(-500.0, 500.0);\n    bernoulli_distribution bernoulli(0.5); // temporary, will change each query\n\n    // initialise edge weights (mid\u2011range guess)\n    EdgeWeights w;\n    for (int i = 0; i < 30; ++i)\n        for (int j = 0; j < 29; ++j)\n            w.h[i][j] = 5000.0;\n    for (int i = 0; i < 29; ++i)\n        for (int j = 0; j < 30; ++j)\n            w.v[i][j] = 5000.0;\n\n    for (int query = 0; query < 1000; ++query) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) return 0; // no more input\n\n        // --------- exploration / exploitation decision ----------\n        double eps = 0.5 * exp(-query / 150.0);\n        bernoulli_distribution choose_explore(eps);\n        bool explore = choose_explore(rng);\n\n        string path;\n        EdgeWeights w_tmp = w; // copy current weights\n        if (explore) {\n            // add temporary noise\n            for (int i = 0; i < 30; ++i)\n                for (int j = 0; j < 29; ++j)\n                    w_tmp.h[i][j] += urd_noise(rng);\n            for (int i = 0; i < 29; ++i)\n                for (int j = 0; j < 30; ++j)\n                    w_tmp.v[i][j] += urd_noise(rng);\n            path = dijkstra_path(si, sj, ti, tj, w_tmp);\n        } else {\n            path = dijkstra_path(si, sj, ti, tj, w);\n        }\n\n        // --------- output ----------\n        cout << path << '\\n';\n        cout.flush();\n\n        // --------- read noisy observation ----------\n        long long y;\n        cin >> y;\n\n        // --------- accumulate predicted length (using true weights) ----------\n        double pred_len = 0.0;\n        int i = si, j = sj;\n        for (char c : path) {\n            if (c == 'U') {\n                pred_len += w.v[i - 1][j];\n                --i;\n            } else if (c == 'D') {\n                pred_len += w.v[i][j];\n                ++i;\n            } else if (c == 'L') {\n                pred_len += w.h[i][j - 1];\n                --j;\n            } else if (c == 'R') {\n                pred_len += w.h[i][j];\n                ++j;\n            }\n        }\n\n        // --------- update weights (stochastic gradient descent) ----------\n        double err = double(y) - pred_len;\n        double lr = 0.01 / sqrt(query + 1);   // slowly decreasing step size\n        double delta = lr * err / double(path.size());\n\n        i = si; j = sj;\n        for (char c : path) {\n            if (c == 'U') {\n                w.v[i - 1][j] += delta;\n                --i;\n            } else if (c == 'D') {\n                w.v[i][j] += delta;\n                ++i;\n            } else if (c == 'L') {\n                w.h[i][j - 1] += delta;\n                --j;\n            } else if (c == 'R') {\n                w.h[i][j] += delta;\n                ++j;\n            }\n        }\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 20;                 // matrix size (fixed in the statement)\nconstexpr int MAXLEN = 12;            // maximal length of an input string\nconstexpr int ALPH = 8;               // letters A \u2026 H\n\n/* ---------- placement of one string ---------- */\nstruct Placement {\n    uint16_t cell[MAXLEN];   // cell indices (0 \u2026 N*N-1)\n    uint8_t  let[MAXLEN];    // required letters (0 \u2026 7)\n    uint8_t  len;            // actual length ( \u2264 12 )\n};\n\n/* ---------- global data for the whole test case ---------- */\nint Muniq;                                           // number of different strings\nvector<vector<int>> strLetters;                     // letters of each unique string\nvector<vector<Placement>> placements;               // all placements of each string\n\n/* ---------- current working solution ---------- */\narray<int, N * N> curLetter;        // -1 = empty, 0..7 = letter\narray<int, N * N> curUse;           // how many placements occupy the cell\nint curUsedCells;                    // #cells with curUse > 0\nvector<int> curIdx;                  // for each string: chosen placement index, -1 = none\n\n/* --------------------------------------------------------------- */\ninline int cellId(int r, int c) { return r * N + c; }\n\n/* check whether placement p can be inserted into the current grid */\ninline bool canPlace(const Placement& p) {\n    for (int i = 0; i < p.len; ++i) {\n        int c = p.cell[i];\n        if (curUse[c] > 0 && curLetter[c] != (int)p.let[i]) return false;\n    }\n    return true;\n}\n\n/* cost of a placement = number of empty cells it would occupy */\ninline int placeCost(const Placement& p) {\n    int cost = 0;\n    for (int i = 0; i < p.len; ++i)\n        if (curUse[p.cell[i]] == 0) ++cost;\n    return cost;\n}\n\n/* insert a placement into the grid */\ninline void place(const Placement& p) {\n    for (int i = 0; i < p.len; ++i) {\n        int c = p.cell[i];\n        if (curUse[c] == 0) {\n            curLetter[c] = p.let[i];\n            ++curUsedCells;\n        }\n        ++curUse[c];\n    }\n}\n\n/* remove a placement from the grid */\ninline void unplace(const Placement& p) {\n    for (int i = 0; i < p.len; ++i) {\n        int c = p.cell[i];\n        --curUse[c];\n        if (curUse[c] == 0) {\n            curLetter[c] = -1;\n            --curUsedCells;\n        }\n    }\n}\n\n/* test whether string s (index) is a subsequence of the current matrix */\ninline bool isPresent(int s) {\n    for (const Placement& p : placements[s]) {\n        bool ok = true;\n        for (int i = 0; i < p.len; ++i) {\n            int c = p.cell[i];\n            if (curLetter[c] != (int)p.let[i]) { ok = false; break; }\n        }\n        if (ok) return true;\n    }\n    return false;\n}\n\n/* --------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int Ninput, Minput;\n    if (!(cin >> Ninput >> Minput)) return 0;\n    vector<string> allStr(Minput);\n    for (int i = 0; i < Minput; ++i) cin >> allStr[i];\n\n    /* ---- delete duplicate strings (one occurrence is sufficient) ---- */\n    unordered_map<string, int> seen;\n    vector<string> uniqStr;\n    for (const string& x : allStr) {\n        if (seen.find(x) == seen.end()) {\n            seen[x] = 1;\n            uniqStr.push_back(x);\n        }\n    }\n    Muniq = (int)uniqStr.size();                 // number of different strings\n\n    /* ---- convert strings to integer letters ---- */\n    strLetters.resize(Muniq);\n    for (int i = 0; i < Muniq; ++i)\n        for (char ch : uniqStr[i])\n            strLetters[i].push_back(ch - 'A');\n\n    /* ---- pre\u2011compute all placements of each string ---- */\n    placements.assign(Muniq, {});\n    for (int sid = 0; sid < Muniq; ++sid) {\n        const vector<int>& L = strLetters[sid];\n        int len = (int)L.size();\n        // horizontal\n        for (int row = 0; row < N; ++row)\n            for (int startCol = 0; startCol < N; ++startCol) {\n                Placement p;\n                p.len = (uint8_t)len;\n                for (int off = 0; off < len; ++off) {\n                    int col = (startCol + off) % N;\n                    p.cell[off] = (uint16_t)cellId(row, col);\n                    p.let[off]  = (uint8_t)L[off];\n                }\n                placements[sid].push_back(p);\n            }\n        // vertical\n        for (int col = 0; col < N; ++col)\n            for (int startRow = 0; startRow < N; ++startRow) {\n                Placement p;\n                p.len = (uint8_t)len;\n                for (int off = 0; off < len; ++off) {\n                    int row = (startRow + off) % N;\n                    p.cell[off] = (uint16_t)cellId(row, col);\n                    p.let[off]  = (uint8_t)L[off];\n                }\n                placements[sid].push_back(p);\n            }\n    }\n\n    /* ---- compute a simple \"rarity\" score for each string ----\n       (strings that appear in fewer placements are more constrained) ---- */\n    vector<int> rarity(Muniq, 0);\n    for (int sid = 0; sid < Muniq; ++sid) {\n        int sum = 0;\n        for (const Placement& p : placements[sid])\n            for (int i = 0; i < p.len; ++i)\n                ++sum;\n        rarity[sid] = sum;            // larger sum \u2192 more constrained\n    }\n\n    /* ---------- containers for the best solution found ---------- */\n    array<int, N * N> bestLetter;\n    int bestUsed = INT_MAX;\n    int bestPlaced = -1;\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    const double TIME_LIMIT = 2.8;                 // seconds\n    auto start = chrono::steady_clock::now();\n\n    /* ---------- phase 1 : many greedy restarts + adaptive back\u2011tracking ---------- */\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > 0.60 * TIME_LIMIT) break;    // 60\u202f% of total time\n\n        /* ---- start with an empty grid ---- */\n        curLetter.fill(-1);\n        curUse.fill(0);\n        curUsedCells = 0;\n        curIdx.assign(Muniq, -1);\n\n        /* ---- order strings by decreasing rarity (more constrained first) ---- */\n        vector<int> order(Muniq);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(),\n             [&](int a, int b) { return rarity[a] > rarity[b]; });\n        // shuffle the tail a little to keep diversity\n        for (int i = max(0, Muniq - 10); i < Muniq; ++i)\n            swap(order[i], order[uniform_int_distribution<int>(i, Muniq - 1)(rng)]);\n\n        int placed = 0;\n\n        /* ---- greedy construction ---- */\n        for (int sid : order) {\n            const vector<Placement>& cand = placements[sid];\n            int bestCost = INT_MAX;\n            vector<int> bestIdx;               // placement indices with that cost\n            for (int pid = 0; pid < (int)cand.size(); ++pid) {\n                const Placement& p = cand[pid];\n                if (!canPlace(p)) continue;\n                int c = placeCost(p);\n                if (c < bestCost) {\n                    bestCost = c;\n                    bestIdx.clear();\n                    bestIdx.push_back(pid);\n                } else if (c == bestCost) {\n                    bestIdx.push_back(pid);\n                }\n            }\n            if (bestIdx.empty()) continue;          // cannot place now\n            int chosen = bestIdx[uniform_int_distribution<int>(0, (int)bestIdx.size() - 1)(rng)];\n            place(cand[chosen]);\n            curIdx[sid] = chosen;\n            ++placed;\n        }\n\n        /* ---- adaptive back\u2011tracking for missing strings ---- */\n        if (placed < Muniq) {\n            vector<int> missing;\n            for (int i = 0; i < Muniq; ++i) if (curIdx[i] == -1) missing.push_back(i);\n            // adapt number of attempts to difficulty\n            int maxAttempts = (missing.size() >= 5) ? 75 : 30;\n            for (int attempt = 0; attempt < maxAttempts && !missing.empty(); ++attempt) {\n                int sid = missing.back();                     // take one missing string\n                bool ok = false;\n                for (const Placement& p : placements[sid]) {\n                    if (canPlace(p)) {\n                        place(p);\n                        curIdx[sid] = &p - &placements[sid][0]; // store index (any unique id is fine)\n                        missing.pop_back();\n                        ++placed;\n                        ok = true;\n                        break;\n                    }\n                }\n                if (ok) continue;\n                // none fits \u2192 remove a random placed string and retry\n                vector<int> placedIds;\n                for (int i = 0; i < Muniq; ++i) if (curIdx[i] != -1) placedIds.push_back(i);\n                if (placedIds.empty()) continue;\n                int victim = placedIds[uniform_int_distribution<int>(0, (int)placedIds.size() - 1)(rng)];\n                const Placement& vp = placements[victim][curIdx[victim]];\n                unplace(vp);\n                curIdx[victim] = -1;\n                --placed;\n            }\n        }\n\n        /* ---- delete redundant strings (already present as substrings) ---- */\n        if (placed == Muniq) {\n            vector<int> perm = order;\n            shuffle(perm.begin(), perm.end(), rng);\n            for (int sid : perm) {\n                if (curIdx[sid] == -1) continue;\n                const Placement& p = placements[sid][curIdx[sid]];\n                unplace(p);\n                if (isPresent(sid)) {\n                    curIdx[sid] = -1;          // keep removed\n                } else {\n                    place(p);                  // put it back\n                }\n            }\n        }\n\n        /* ---- remember the best solution of this restart ---- */\n        if (placed > bestPlaced ||\n            (placed == bestPlaced && curUsedCells < bestUsed)) {\n            bestPlaced = placed;\n            bestUsed   = curUsedCells;\n            bestLetter = curLetter;               // copy the whole grid (400 ints)\n        }\n    }   // end of restarts\n\n    /* ---- nothing feasible found ? output empty matrix (worst case) ---- */\n    if (bestPlaced == -1) {\n        for (int i = 0; i < N; ++i) cout << string(N, '.') << '\\n';\n        return 0;\n    }\n\n    /* ---- reload the best solution ---- */\n    curLetter = bestLetter;\n    curUse.fill(0);\n    curUsedCells = 0;\n    for (int i = 0; i < N * N; ++i)\n        if (curLetter[i] != -1) {\n            curUse[i] = 1;\n            ++curUsedCells;\n        }\n    curIdx.assign(Muniq, -1);       // exact indices not needed any more\n\n    /* ---------- phase 2 : hill climbing (use remaining time) ---------- */\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > TIME_LIMIT - 0.05) break;    // stop a little before the hard limit\n\n        // pick a random placed string\n        vector<int> placedIds;\n        for (int i = 0; i < Muniq; ++i) if (curIdx[i] != -1) placedIds.push_back(i);\n        if (placedIds.empty()) continue;\n        int sid = placedIds[uniform_int_distribution<int>(0, (int)placedIds.size() - 1)(rng)];\n        const Placement& oldPl = placements[sid][curIdx[sid]];\n\n        // pick a random different placement\n        const vector<Placement>& cand = placements[sid];\n        int pid = uniform_int_distribution<int>(0, (int)cand.size() - 1)(rng);\n        if (pid == curIdx[sid]) continue;\n        const Placement& newPl = cand[pid];\n        if (!canPlace(newPl)) continue;           // would conflict\n\n        // compute \u0394 = newCellsUsed - cellsFreed\n        int freed = 0;\n        for (int i = 0; i < oldPl.len; ++i) {\n            int c = oldPl.cell[i];\n            if (curUse[c] == 1) {\n                bool inNew = false;\n                for (int j = 0; j < newPl.len; ++j)\n                    if (newPl.cell[j] == c) { inNew = true; break; }\n                if (!inNew) ++freed;\n            }\n        }\n        int newlyUsed = 0;\n        for (int i = 0; i < newPl.len; ++i) {\n            int c = newPl.cell[i];\n            if (curUse[c] == 0) {\n                bool inOld = false;\n                for (int j = 0; j < oldPl.len; ++j)\n                    if (oldPl.cell[j] == c) { inOld = true; break; }\n                if (!inOld) ++newlyUsed;\n            }\n        }\n        int delta = newlyUsed - freed;\n        if (delta < 0) {                           // strict improvement only\n            unplace(oldPl);\n            place(newPl);\n            curIdx[sid] = pid;\n            if (curUsedCells < bestUsed) {\n                bestUsed = curUsedCells;\n                bestLetter = curLetter;\n            }\n        }\n    }\n\n    /* ---------- output the best matrix ---------- */\n    for (int r = 0; r < N; ++r) {\n        string line;\n        for (int c = 0; c < N; ++c) {\n            int id = cellId(r, c);\n            if (bestLetter[id] == -1) line += '.';\n            else                       line += char('A' + bestLetter[id]);\n        }\n        cout << line << '\\n';\n    }\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXV = 5005;                 // maximal number of cells (N\u226469 \u2192 < 5000)\n\nstruct Edge {\n    int u, v, w;\n    bool operator<(Edge const& other) const { return w < other.w; }\n};\n\nstruct DSU {\n    vector<int> p, r;\n    DSU(int n = 0) { init(n); }\n    void init(int n) { p.resize(n); r.assign(n,0); iota(p.begin(),p.end(),0); }\n    int find(int x){ return p[x]==x?x:p[x]=find(p[x]); }\n    bool unite(int a,int b){\n        a=find(a); b=find(b);\n        if(a==b) return false;\n        if(r[a]<r[b]) swap(a,b);\n        p[b]=a;\n        if(r[a]==r[b]) ++r[a];\n        return true;\n    }\n};\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    // --- 1. give an id to every road cell, store its weight and coordinates ----------\n    vector<vector<int>> id(N, vector<int>(N,-1));\n    vector<int> weight; weight.reserve(N*N);\n    vector<int> iOf, jOf; iOf.reserve(N*N); jOf.reserve(N*N);\n    int V = 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] = V++;\n                weight.push_back(g[i][j]-'0');\n                iOf.push_back(i);\n                jOf.push_back(j);\n            }\n        }\n    }\n    const int startIdx = id[si][sj];\n\n    // --- 2. row and column segment ids ------------------------------------------------\n    vector<int> rowId(V,-1), colId(V,-1);\n    int rowSegCnt = 0;\n    for(int i=0;i<N;++i){\n        int cur = -1;\n        for(int j=0;j<N;++j){\n            if(g[i][j]!='#'){\n                if(j==0 || g[i][j-1]=='#') cur = rowSegCnt++;\n                rowId[id[i][j]] = cur;\n            }\n        }\n    }\n    int colSegCnt = 0;\n    for(int j=0;j<N;++j){\n        int cur = -1;\n        for(int i=0;i<N;++i){\n            if(g[i][j]!='#'){\n                if(i==0 || g[i-1][j]=='#') cur = colSegCnt++;\n                colId[id[i][j]] = cur;\n            }\n        }\n    }\n\n    // decide which side to cover\n    bool useRow = rowSegCnt <= colSegCnt;\n    vector<int> segId = useRow ? rowId : colId;\n    int segCnt = useRow ? rowSegCnt : colSegCnt;\n\n    // --- 3. build edge list (only right / down, undirected) ----------------------------\n    vector<Edge> edges;\n    edges.reserve(4*V);\n    const int di[4] = {-1,1,0,0};\n    const int dj[4] = {0,0,-1,1};\n    for(int i=0;i<N;++i){\n        for(int j=0;j<N;++j){\n            if(g[i][j]=='#') continue;\n            int u = id[i][j];\n            // right neighbour\n            if(j+1<N && g[i][j+1]!='#'){\n                int v = id[i][j+1];\n                if(u<v) edges.push_back({u,v,weight[u]+weight[v]});\n            }\n            // down neighbour\n            if(i+1<N && g[i+1][j]!='#'){\n                int v = id[i+1][j];\n                if(u<v) edges.push_back({u,v,weight[u]+weight[v]});\n            }\n        }\n    }\n\n    // --- 4. MST with Kruskal ---------------------------------------------------------\n    sort(edges.begin(), edges.end());\n    DSU dsu(V);\n    vector<vector<int>> mstAdj(V);\n    int added = 0;\n    for(const auto& e: edges){\n        if(dsu.unite(e.u, e.v)){\n            mstAdj[e.u].push_back(e.v);\n            mstAdj[e.v].push_back(e.u);\n            if(++added == V-1) break;\n        }\n    }\n\n    // --- 5. root the tree in the start cell -----------------------------------------\n    vector<int> parent(V,-1);\n    vector<vector<int>> children(V);\n    vector<int> order; order.reserve(V);\n    // iterative stack for rooting\n    vector<int> st; st.push_back(startIdx);\n    parent[startIdx] = startIdx;\n    while(!st.empty()){\n        int u = st.back(); st.pop_back();\n        order.push_back(u);\n        for(int v: mstAdj[u]){\n            if(v==parent[u]) continue;\n            parent[v] = u;\n            children[u].push_back(v);\n            st.push_back(v);\n        }\n    }\n\n    // --- 6. subtree masks of segment ids --------------------------------------------\n    using Mask = bitset<MAXV>;\n    vector<Mask> subMask(V);\n    vector<int> subCnt(V,0);\n    // post\u2011order (reverse of the order we obtained above, because every parent appears after its children)\n    for(int i=(int)order.size()-1;i>=0;--i){\n        int u = order[i];\n        subMask[u].reset();\n        subMask[u].set(segId[u]);\n        for(int v: children[u]){\n            subMask[u] |= subMask[v];\n        }\n        subCnt[u] = (int)subMask[u].count();\n    }\n\n    // --- 7. sort children by number of different segments in their subtree ----------\n    for(int u=0;u<V;++u){\n        sort(children[u].begin(), children[u].end(),\n            [&](int a, int b){ return subCnt[a] > subCnt[b]; });\n    }\n\n    // --- 8. depth\u2011first walk, but only when a subtree still contains uncovered segments\n    Mask coveredMask;\n    coveredMask.reset();\n    coveredMask.set(segId[startIdx]);          // start segment already visited\n\n    string answer; answer.reserve(2*V);\n    function<void(int,int)> dfsWalk = [&](int u, int p)->void{\n        for(int v: children[u]){\n            // if nothing uncovered in this subtree \u2013 skip it\n            if ( (subMask[v] & ~coveredMask).none() ) continue;\n            // move u -> v\n            if(iOf[v]==iOf[u]-1 && jOf[v]==jOf[u]) answer.push_back('U');\n            else if(iOf[v]==iOf[u]+1 && jOf[v]==jOf[u]) answer.push_back('D');\n            else if(iOf[v]==iOf[u] && jOf[v]==jOf[u]-1) answer.push_back('L');\n            else if(iOf[v]==iOf[u] && jOf[v]==jOf[u]+1) answer.push_back('R');\n            else { /* should never happen */ }\n\n            coveredMask.set(segId[v]);          // v itself is visited now\n            dfsWalk(v, u);\n            // return v -> u\n            if(iOf[v]==iOf[u]-1 && jOf[v]==jOf[u]) answer.push_back('D');\n            else if(iOf[v]==iOf[u]+1 && jOf[v]==jOf[u]) answer.push_back('U');\n            else if(iOf[v]==iOf[u] && jOf[v]==jOf[u]-1) answer.push_back('R');\n            else if(iOf[v]==iOf[u] && jOf[v]==jOf[u]+1) answer.push_back('L');\n            else { /* should never happen */ }\n        }\n    };\n    dfsWalk(startIdx, -1);\n\n    // --- 9. output ------------------------------------------------------------------\n    cout << answer << '\\n';\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ---------- data structures ---------- */\n\nstruct Task {\n    vector<int> d;          // skill requirements, size K\n    int indegree = 0;       // number of unfinished predecessors\n    int status = -1;        // -1 : not started, 0 : in progress, 1 : completed\n    int start_day = -1;     // day on which the task was started\n    int assigned_to = -1;   // member id (0\u2011based) or -1\n    int total_req = 0;      // \u03a3_k d[k]  (used for a cheap difficulty estimate)\n};\n\nstruct Member {\n    vector<int> s_est;          // not used by the final algorithm, kept for symmetry\n    double avg_time_per_unit = 1.0;   // average observed  (time / total_requirement)\n    int total_processed = 0;    // number of tasks finished by this member\n    int total_time = 0;         // sum of their processing times\n};\n\n/* ---------- main ---------- */\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---- read prior information ---- */\n    int N, M, K, R;\n    if (!(cin >> N >> M >> K >> R)) return 0;\n\n    vector<Task> tasks(N);\n    for (int i = 0; i < N; ++i) {\n        tasks[i].d.resize(K);\n        tasks[i].total_req = 0;\n        for (int k = 0; k < K; ++k) {\n            cin >> tasks[i].d[k];\n            tasks[i].total_req += tasks[i].d[k];\n        }\n    }\n\n    vector<vector<int>> graph(N);          // edge u \u2192 v  (u must be done before v)\n    for (int i = 0; i < R; ++i) {\n        int u, v;  cin >> u >> v;  --u; --v;\n        graph[u].push_back(v);\n        ++tasks[v].indegree;\n    }\n\n    vector<Member> members(M);\n    for (int j = 0; j < M; ++j) members[j].s_est.assign(K, 0);\n\n    vector<int> member_status(M, -1);               // -1 \u2192 idle, otherwise task id\n    unordered_map<int,int> in_progress;             // taskid \u2192 start_day\n\n    int day = 0;\n\n    /* ---- day loop ---- */\n    while (true) {\n        ++day;\n        if (day > 2000) break;                     // safety, should never trigger\n\n        /* -- 1. available tasks -- */\n        vector<int> available;\n        for (int i = 0; i < N; ++i)\n            if (tasks[i].status == -1 && tasks[i].indegree == 0)\n                available.push_back(i);\n\n        sort(available.begin(), available.end(),\n             [&](int a, int b){ return tasks[a].total_req < tasks[b].total_req; });\n\n        /* -- 2. idle members -- */\n        vector<int> idle_members;\n        for (int j = 0; j < M; ++j)\n            if (member_status[j] == -1) idle_members.push_back(j);\n\n        /* -- 3. greedy matching -- */\n        vector<pair<int,int>> assignments;           // (member , task)\n        for (int j : idle_members) {\n            if (available.empty()) break;\n\n            int   best_task = -1;\n            double best_pred = 1e99;\n\n            for (size_t pos = 0; pos < available.size(); ++pos) {\n                int i = available[pos];\n                double pred = members[j].avg_time_per_unit * tasks[i].total_req;\n                if (pred < best_pred) {\n                    best_pred = pred;\n                    best_task = i;\n                }\n            }\n\n            if (best_task != -1) {\n                assignments.emplace_back(j, best_task);\n                // remove the chosen task from the vector (swap with back)\n                auto it = find(available.begin(), available.end(), best_task);\n                *it = available.back();\n                available.pop_back();\n            }\n        }\n\n        /* -- 4. output -- */\n        cout << assignments.size();\n        for (auto [mem, t] : assignments)\n            cout << ' ' << (mem + 1) << ' ' << (t + 1);\n        cout << '\\n';\n        cout.flush();\n\n        /* -- 5. update internal state -- */\n        for (auto [mem, t] : assignments) {\n            tasks[t].status = 0;\n            tasks[t].start_day = day;\n            tasks[t].assigned_to = mem;\n            member_status[mem] = t;\n            in_progress[t] = day;\n        }\n\n        /* -- 6. read completions -- */\n        int num_compl;  cin >> num_compl;\n        if (num_compl == -1) break;                 // finished or time limit\n\n        for (int i = 0; i < num_compl; ++i) {\n            int mem;  cin >> mem;  --mem;\n            int task = member_status[mem];\n            if (task == -1) continue;                // should never happen\n\n            int start_day = in_progress[task];\n            int t = day - start_day;                 // real processing time\n\n            Member &m = members[mem];\n            ++m.total_processed;\n            m.total_time += t;\n\n            // update average time per unit (exponential moving average)\n            int req = tasks[task].total_req;\n            if (req > 0) {\n                double this_avg = static_cast<double>(t) / req;\n                constexpr double alpha = 0.2;         // learning rate\n                m.avg_time_per_unit = (1.0 - alpha) * m.avg_time_per_unit\n                                      + alpha * this_avg;\n            }\n\n            // mark task completed\n            tasks[task].status = 1;\n            tasks[task].assigned_to = -1;\n            member_status[mem] = -1;\n            in_progress.erase(task);\n\n            // make dependent tasks available\n            for (int child : graph[task]) {\n                if (--tasks[child].indegree == 0) {\n                    // will be collected in the next day\n                }\n            }\n        }\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 1000;               // number of orders in the input\nconst int M = 50;                 // orders that have to be chosen\nconst int CENTER_X = 400;\nconst int CENTER_Y = 400;\n\n/*  order data  */\nint a[N], b[N], c_[N], d_[N];\nint internalDist[N];\nint startDist[N];\nint endDist[N];\nint between[N][N];                // delivery i -> pickup j\n\n/*  Manhattan distance  */\ninline int manh(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n/*  cost between two orders, -1 stands for the centre  */\ninline int costBetween(int from, int to) {\n    if (from == -1 && to == -1) return 0;\n    if (from == -1) return startDist[to];\n    if (to   == -1) return endDist[from];\n    return between[from][to];\n}\n\n/*  total travel time of a permutation (block order)  */\nint computeCost(const vector<int>& perm) {\n    int sum = 0;\n    for (int id : perm) sum += internalDist[id];\n    sum += startDist[perm[0]];\n    for (int i = 0; i + 1 < (int)perm.size(); ++i)\n        sum += between[perm[i]][perm[i + 1]];\n    sum += endDist[perm.back()];\n    return sum;\n}\n\n/* -------------------------------------------------------------\n   Greedy insertion \u2013 returns a feasible permutation\n   -------------------------------------------------------------\n*/\nvector<int> greedyInsertion(mt19937& rng) {\n    vector<int> path;                     // current permutation of orders\n    path.reserve(M);\n    vector<char> used(N, 0);               // order already taken ?\n\n    while ((int)path.size() < M) {\n        int bestTotal = INT_MAX;\n        int bestOrder = -1;\n        int bestPos   = -1;\n\n        for (int i = 0; i < N; ++i) if (!used[i]) {\n            int bestDelta = INT_MAX;\n            int bestPos_i = -1;\n            int sz = (int)path.size();\n            for (int pos = 0; pos <= sz; ++pos) {\n                int prev = (pos == 0) ? -1 : path[pos - 1];\n                int nxt  = (pos == sz) ? -1 : path[pos];\n                int delta = costBetween(prev, i) + costBetween(i, nxt)\n                            - costBetween(prev, nxt);\n                if (delta < bestDelta) {\n                    bestDelta = delta;\n                    bestPos_i = pos;\n                }\n            }\n            int totalIncrease = bestDelta + internalDist[i];\n            // random tie\u2011break\n            if (totalIncrease < bestTotal ||\n                (totalIncrease == bestTotal && (rng() & 1))) {\n                bestTotal = totalIncrease;\n                bestOrder = i;\n                bestPos   = bestPos_i;\n            }\n        }\n        // insert the chosen order\n        path.insert(path.begin() + bestPos, bestOrder);\n        used[bestOrder] = 1;\n    }\n    return path;\n}\n\n/* -------------------------------------------------------------\n   Simulated annealing on a permutation (keeps the set of orders)\n   -------------------------------------------------------------\n*/\nvector<int> simulatedAnnealing(const vector<int>& startPerm,\n                               mt19937& rng,\n                               double timeLimit)\n{\n    const double initTemp = 1000.0;\n    const int    movesPerStep = 2000;\n\n    vector<int> cur = startPerm;\n    vector<char> used(N, 0);\n    for (int v : cur) used[v] = 1;\n    int curCost = computeCost(cur);\n    int bestCost = curCost;\n    vector<int> best = cur;\n\n    double start = (double)clock() / CLOCKS_PER_SEC;\n    uniform_real_distribution<double> uni01(0.0, 1.0);\n    uniform_int_distribution<int> posDist(0, M - 1);\n    uniform_int_distribution<int> orderDist(0, N - 1);\n\n    while (true) {\n        double elapsed = (double)clock() / CLOCKS_PER_SEC - start;\n        if (elapsed > timeLimit) break;\n        double temperature = initTemp * (1.0 - elapsed / timeLimit);\n        if (temperature <= 0.0) break;\n\n        for (int step = 0; step < movesPerStep; ++step) {\n            int move = rng() % 4;                     // 0 swap,1 move,2 reverse,3 replace\n            vector<int> nxt = cur;\n            vector<char> nxtUsed = used;\n\n            if (move == 0) {                         // swap two positions\n                int i = posDist(rng), j = posDist(rng);\n                if (i == j) continue;\n                swap(nxt[i], nxt[j]);\n            }\n            else if (move == 1) {                    // move one order\n                int i = posDist(rng), j = posDist(rng);\n                if (i == j) continue;\n                int v = nxt[i];\n                nxt.erase(nxt.begin() + i);\n                nxt.insert(nxt.begin() + j, v);\n            }\n            else if (move == 2) {                    // reverse a segment\n                int i = posDist(rng), j = posDist(rng);\n                if (i >= j) continue;\n                reverse(nxt.begin() + i, nxt.begin() + j + 1);\n            }\n            else {                                    // replace one order\n                int i = posDist(rng);\n                int oldId = nxt[i];\n                int newId;\n                do { newId = orderDist(rng); } while (nxtUsed[newId]);\n                nxt[i] = newId;\n                nxtUsed[oldId] = 0;\n                nxtUsed[newId] = 1;\n            }\n\n            int nxtCost = computeCost(nxt);\n            int delta   = nxtCost - curCost;\n            double prob = (delta < 0) ? 1.0 : exp(-delta / temperature);\n            if (prob > uni01(rng)) {\n                cur.swap(nxt);\n                used.swap(nxtUsed);\n                curCost = nxtCost;\n                if (curCost < bestCost) {\n                    bestCost = curCost;\n                    best = cur;\n                }\n            }\n        }\n    }\n    return best;\n}\n\n/* -------------------------------------------------------------\n   Simple deterministic hill\u2011climbing (reverse / swap)\n   -------------------------------------------------------------\n*/\nvector<int> localImprove(vector<int> perm) {\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        // try to reverse a segment\n        for (int i = 0; i < M; ++i)\n            for (int j = i + 1; j < M; ++j) {\n                vector<int> cand = perm;\n                reverse(cand.begin() + i, cand.begin() + j + 1);\n                int candCost = computeCost(cand);\n                int curCost  = computeCost(perm);\n                if (candCost < curCost) {\n                    perm.swap(cand);\n                    improved = true;\n                    goto nextLoop;               // start again\n                }\n            }\n        // try to swap two positions\n        for (int i = 0; i < M; ++i)\n            for (int j = i + 1; j < M; ++j) {\n                vector<int> cand = perm;\n                swap(cand[i], cand[j]);\n                int candCost = computeCost(cand);\n                int curCost  = computeCost(perm);\n                if (candCost < curCost) {\n                    perm.swap(cand);\n                    improved = true;\n                    goto nextLoop;\n                }\n            }\n    nextLoop: ;\n    }\n    return perm;\n}\n\n/* -------------------------------------------------------------\n   Main\n   -------------------------------------------------------------\n*/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---- read input --------------------------------------------------- */\n    for (int i = 0; i < N; ++i) {\n        if (!(cin >> a[i] >> b[i] >> c_[i] >> d_[i])) return 0;\n    }\n\n    /* ---- pre\u2011compute all distances ------------------------------------ */\n    for (int i = 0; i < N; ++i) {\n        internalDist[i] = manh(a[i], b[i], c_[i], d_[i]);\n        startDist[i]    = manh(CENTER_X, CENTER_Y, a[i], b[i]);\n        endDist[i]      = manh(c_[i], d_[i], CENTER_X, CENTER_Y);\n        for (int j = 0; j < N; ++j)\n            between[i][j] = manh(c_[i], d_[i], a[j], b[j]);\n    }\n\n    /* ---- random generator -------------------------------------------- */\n    std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count());\n\n    /* ---- several runs ------------------------------------------------- */\n    const int runs = 3;\n    const double timePerRun = 1.8 / runs;\n\n    vector<int> bestOverall;\n    int bestOverallCost = INT_MAX;\n\n    for (int r = 0; r < runs; ++r) {\n        vector<int> init = greedyInsertion(rng);\n        vector<int> afterSA = simulatedAnnealing(init, rng, timePerRun);\n        vector<int> afterLocal = localImprove(afterSA);\n        int cost = computeCost(afterLocal);\n        if (cost < bestOverallCost) {\n            bestOverallCost = cost;\n            bestOverall = afterLocal;\n        }\n    }\n\n    /* ---- output ------------------------------------------------------- */\n    cout << \"50\";\n    for (int id : bestOverall) cout << ' ' << id + 1;\n    cout << '\\n';\n\n    cout << \"102 400 400\";\n    for (int id : bestOverall) {\n        cout << ' ' << a[id] << ' ' << b[id] << ' '\n             << c_[id] << ' ' << d_[id];\n    }\n    cout << \" 400 400\\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);\n        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\nstruct Edge {\n    int u, v;\n    int d;\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<pair<int,int>> coords(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    // Read edges and compute d_i\n    vector<Edge> edges(M);\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        cin >> u >> v;\n        edges[i].u = u;\n        edges[i].v = v;\n        long long dx = (long long)coords[u].first - coords[v].first;\n        long long dy = (long long)coords[u].second - coords[v].second;\n        double dist = sqrt((double)dx * dx + (double)dy * dy);\n        edges[i].d = (int)llround(dist);\n    }\n    \n    // Precompute T0: MST based on d_i\n    vector<int> edge_ids(M);\n    iota(edge_ids.begin(), edge_ids.end(), 0);\n    sort(edge_ids.begin(), edge_ids.end(), [&](int a, int b) {\n        return edges[a].d < edges[b].d;\n    });\n    \n    DSU dsu_t0(N);\n    vector<char> inT0(M, 0);\n    for (int idx : edge_ids) {\n        if (dsu_t0.unite(edges[idx].u, edges[idx].v)) {\n            inT0[idx] = 1;\n        }\n    }\n    \n    // Process edges online\n    DSU dsu(N);\n    int components = N;\n    \n    for (int i = 0; i < M; ++i) {\n        int l;\n        cin >> l;\n        \n        // If already connected, reject remaining edges\n        if (components == 1) {\n            cout << 0 << endl;\n            continue;\n        }\n        \n        int u = edges[i].u;\n        int v = edges[i].v;\n        \n        int ru = dsu.find(u);\n        int rv = dsu.find(v);\n        \n        // If edge creates a cycle, reject\n        if (ru == rv) {\n            cout << 0 << endl;\n            continue;\n        }\n        \n        // Always accept edges from T0 (guarantees connectivity)\n        bool accept = inT0[i];\n        \n        // For non-T0 edges, use rank-based selection\n        if (!accept) {\n            double d = edges[i].d;\n            double rank = (l - d) / (2.0 * d);\n            \n            // Clamp rank to [0,1] for safety\n            if (rank < 0.0) rank = 0.0;\n            if (rank > 1.0) rank = 1.0;\n            \n            // Dynamic threshold: 0.1 to 1.0\n            double progress = (double)i / (M - 1);\n            double threshold = 0.1 + 0.9 * progress;\n            \n            accept = (rank <= threshold);\n        }\n        \n        if (accept) {\n            dsu.unite(u, v);\n            --components;\n            cout << 1 << endl;\n        } else {\n            cout << 0 << endl;\n        }\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos {\n    int x, y;\n};\n\nstruct Human {\n    Pos pos;\n};\n\nstruct Pet {\n    Pos pos;\n    int type;\n};\n\nclass Grid {\npublic:\n    static const int SIZE = 30;\n    bool passable[SIZE][SIZE];\n    \n    Grid() {\n        for (int i = 0; i < SIZE; i++)\n            for (int j = 0; j < SIZE; j++)\n                passable[i][j] = true;\n    }\n    \n    bool isValid(int x, int y) const {\n        return x >= 0 && x < SIZE && y >= 0 && y < SIZE;\n    }\n    \n    bool isPassable(int x, int y) const {\n        if (!isValid(x, y)) return false;\n        return passable[x][y];\n    }\n    \n    void block(int x, int y) {\n        if (isValid(x, y)) passable[x][y] = false;\n    }\n};\n\n// BFS to count reachable squares\nint countReachable(const Grid& grid, Pos start) {\n    vector<vector<bool>> vis(Grid::SIZE, vector<bool>(Grid::SIZE, false));\n    queue<Pos> q;\n    q.push(start);\n    vis[start.x][start.y] = true;\n    \n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    \n    while (!q.empty()) {\n        Pos cur = q.front(); q.pop();\n        for (int dir = 0; dir < 4; dir++) {\n            int nx = cur.x + dx[dir];\n            int ny = cur.y + dy[dir];\n            if (grid.isPassable(nx, ny) && !vis[nx][ny]) {\n                vis[nx][ny] = true;\n                q.push({nx, ny});\n            }\n        }\n    }\n    \n    int cnt = 0;\n    for (int i = 0; i < Grid::SIZE; i++)\n        for (int j = 0; j < Grid::SIZE; j++)\n            if (vis[i][j]) cnt++;\n    return cnt;\n}\n\n// Check if a position contains any entity (pet or human)\nbool hasEntity(Pos p, const vector<Pet>& pets, const vector<Human>& humans) {\n    for (const auto& pet : pets)\n        if (pet.pos.x == p.x && pet.pos.y == p.y) return true;\n    for (const auto& human : humans)\n        if (human.pos.x == p.x && human.pos.y == p.y) return true;\n    return false;\n}\n\n// Explicit check: does any pet occupy an adjacent square (orthogonal) of 'pos'?\nbool hasPetAdjacentToBlock(Pos pos, const vector<Pet>& pets) {\n    // Check all 4 orthogonal adjacent squares\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    \n    for (int dir = 0; dir < 4; dir++) {\n        int adjX = pos.x + dx[dir];\n        int adjY = pos.y + dy[dir];\n        \n        // For each adjacent square, check if any pet is there\n        for (const auto& pet : pets) {\n            if (pet.pos.x == adjX && pet.pos.y == adjY) {\n                return true; // Found a pet in adjacent square\n            }\n        }\n    }\n    return false;\n}\n\n// Conservative validation: block only if absolutely safe\nbool isSafeBlock(Pos blockPos, const vector<Pet>& pets, \n                 const vector<Human>& humans, const Grid& grid) {\n    // Must be within grid and passable\n    if (!grid.isPassable(blockPos.x, blockPos.y)) {\n        return false; // Can't block impassable squares\n    }\n    \n    // Cannot contain any entity\n    if (hasEntity(blockPos, pets, humans)) {\n        return false; // Can't block squares with pets or humans\n    }\n    \n    // CRITICAL: Cannot have any pet in adjacent squares\n    if (hasPetAdjacentToBlock(blockPos, pets)) {\n        return false; // This is the rule that was causing runtime errors\n    }\n    \n    return true; // All checks passed\n}\n\n// Choose safest and most beneficial action\nchar chooseAction(const Human& human, const vector<Human>& humans, \n                  const vector<Pet>& pets, const Grid& grid) {\n    const char* allMoves = \".udlrUDLR\";\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    \n    struct ActionScore {\n        char move;\n        int score;\n    };\n    vector<ActionScore> candidates;\n    \n    int reachableNow = countReachable(grid, human.pos);\n    \n    for (int i = 0; i < 9; i++) {\n        char move = allMoves[i];\n        int score = 0;\n        bool valid = true;\n        \n        if (move == '.') {\n            // Staying is always safe\n            score = reachableNow;\n        } else if (move >= 'u' && move <= 'r') {\n            // Block - validate strictly\n            int dir = move - 'u';\n            Pos blockPos = {human.pos.x + dx[dir], human.pos.y + dy[dir]};\n            \n            if (!isSafeBlock(blockPos, pets, humans, grid)) {\n                valid = false;\n            } else {\n                // Score based on proximity to pets (especially dogs)\n                score = 500 + reachableNow;\n                for (const auto& pet : pets) {\n                    int dist = abs(pet.pos.x - blockPos.x) + abs(pet.pos.y - blockPos.y);\n                    if (dist <= 3) {\n                        score += 400;\n                        if (pet.type == 4) score += 800; // Dogs are priority\n                    }\n                }\n                \n                // Penalty if it isolates us too much\n                Grid temp = grid;\n                temp.block(blockPos.x, blockPos.y);\n                int reachableAfter = countReachable(temp, human.pos);\n                if (reachableAfter < reachableNow * 0.6) {\n                    score -= 300; // Too restrictive\n                }\n            }\n        } else {\n            // Move - be very conservative\n            int dir = move - 'U';\n            Pos newPos = {human.pos.x + dx[dir], human.pos.y + dy[dir]};\n            \n            if (!grid.isPassable(newPos.x, newPos.y)) {\n                valid = false;\n            } else {\n                int reachableAfter = countReachable(grid, newPos);\n                score = reachableAfter;\n                \n                // Penalty for moving toward dogs\n                for (const auto& pet : pets) {\n                    if (pet.type == 4) { // Dog\n                        int oldDist = abs(pet.pos.x - human.pos.x) + \n                                      abs(pet.pos.y - human.pos.y);\n                        int newDist = abs(pet.pos.x - newPos.x) + \n                                      abs(pet.pos.y - newPos.y);\n                        if (newDist < oldDist) score -= 200;\n                    }\n                }\n            }\n        }\n        \n        if (valid) {\n            candidates.push_back({move, score});\n        }\n    }\n    \n    // If no valid actions, stay (shouldn't happen)\n    if (candidates.empty()) return '.';\n    \n    // Sort by score\n    sort(candidates.begin(), candidates.end(),\n         [](const ActionScore& a, const ActionScore& b) { return a.score > b.score; });\n    \n    return candidates[0].move;\n}\n\n// Apply all human actions simultaneously to update state\nvoid applyHumanActions(vector<Human>& humans, const string& actions, Grid& grid) {\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    \n    for (size_t i = 0; i < actions.size(); i++) {\n        char action = actions[i];\n        if (action >= 'u' && action <= 'r') {\n            // Block square\n            int dir = action - 'u';\n            grid.block(humans[i].pos.x + dx[dir], humans[i].pos.y + dy[dir]);\n        } else if (action >= 'U' && action <= 'R') {\n            // Move to new position\n            int dir = action - 'U';\n            humans[i].pos.x += dx[dir];\n            humans[i].pos.y += dy[dir];\n        }\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    \n    vector<Pet> pets(N);\n    for (int i = 0; i < N; i++) {\n        cin >> pets[i].pos.x >> pets[i].pos.y >> pets[i].type;\n        // Convert to 0-indexed\n        pets[i].pos.x--;\n        pets[i].pos.y--;\n    }\n    \n    int M;\n    cin >> M;\n    vector<Human> humans(M);\n    for (int i = 0; i < M; i++) {\n        cin >> humans[i].pos.x >> humans[i].pos.y;\n        humans[i].pos.x--;\n        humans[i].pos.y--;\n    }\n    \n    Grid grid;\n    \n    // Main game loop\n    for (int turn = 0; turn < 300; turn++) {\n        // 1. Choose actions (no state modifications)\n        string actions;\n        for (int i = 0; i < M; i++) {\n            actions += chooseAction(humans[i], humans, pets, grid);\n        }\n        \n        // 2. Output actions\n        cout << actions << endl;\n        cout.flush();\n        \n        // 3. Read pet movements\n        vector<string> petMoves(N);\n        for (int i = 0; i < N; i++) {\n            cin >> petMoves[i];\n        }\n        \n        // 4. Apply human actions to update state\n        applyHumanActions(humans, actions, grid);\n        \n        // 5. Update pet positions\n        for (int i = 0; i < N; i++) {\n            const string& move = petMoves[i];\n            if (move == \".\") continue;\n            \n            for (char c : move) {\n                int nx = pets[i].pos.x;\n                int ny = pets[i].pos.y;\n                \n                if (c == 'U') nx--;\n                else if (c == 'D') nx++;\n                else if (c == 'L') ny--;\n                else if (c == 'R') ny++;\n                \n                if (grid.isPassable(nx, ny)) {\n                    pets[i].pos.x = nx;\n                    pets[i].pos.y = ny;\n                }\n            }\n        }\n    }\n    \n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 20;\nconst int W = 20;\nconst int N = H * W;\nconst int INF = 1e9;\n\n/* ---------- global data ---------- */\nint start, target;\ndouble forgetP;                     // probability of forgetting a character\n\narray<array<int,4>,N> neighbour;   // neighbour[v][dir], dir = 0(U),1(D),2(L),3(R)\narray<char,4> dirChar{'U','D','L','R'};\narray<int,256> dirIdx;              // char -> 0..3, -1 = invalid\n\nvector<int> bfsDist;                // shortest deterministic distance to target\n\n/* ---------- evaluation of a route ---------- */\ndouble evaluate(const string &s) {\n    static vector<double> prob, nxt;\n    prob.assign(N, 0.0);\n    nxt.assign(N, 0.0);\n    prob[start] = 1.0;\n    double expected = 0.0;\n    int L = (int)s.size();\n\n    for (int turn = 1; turn <= L; ++turn) {\n        fill(nxt.begin(), nxt.end(), 0.0);\n        int d = dirIdx[(unsigned char)s[turn-1]];\n        double arrival = 0.0;\n\n        for (int v = 0; v < N; ++v) {\n            double cur = prob[v];\n            if (cur == 0.0) continue;\n            double stayProb = cur * forgetP;\n            double moveProb = cur * (1.0 - forgetP);\n            int w = neighbour[v][d];\n            if (w == target) arrival += moveProb;\n            else               nxt[w] += moveProb;\n            nxt[v] += stayProb;\n        }\n        expected += arrival * (401 - turn);\n        prob.swap(nxt);\n    }\n    return expected;\n}\n\n/* ---------- BFS on the grid (ignoring staying) ---------- */\nvector<int> bfs_from(int src) {\n    vector<int> dist(N, INF);\n    queue<int> q;\n    dist[src] = 0;\n    q.push(src);\n    while (!q.empty()) {\n        int v = q.front(); q.pop();\n        int dv = dist[v];\n        for (int dir = 0; dir < 4; ++dir) {\n            int w = neighbour[v][dir];\n            if (w == v) continue;               // blocked by wall\n            if (dist[w] == INF) {\n                dist[w] = dv + 1;\n                q.push(w);\n            }\n        }\n    }\n    return dist;\n}\n\n/* ---------- shortest deterministic path from S to T ---------- */\nvector<char> shortestPath() {\n    vector<int> parent(N, -1);\n    vector<char> pdir(N, 0);\n    vector<int> dist(N, -1);\n    queue<int> q;\n    q.push(start);\n    dist[start] = 0;\n    while (!q.empty()) {\n        int v = q.front(); q.pop();\n        if (v == target) break;\n        for (int dir = 0; dir < 4; ++dir) {\n            int w = neighbour[v][dir];\n            if (w == v) continue;\n            if (dist[w] == -1) {\n                dist[w] = dist[v] + 1;\n                parent[w] = v;\n                pdir[w] = dirChar[dir];\n                q.push(w);\n            }\n        }\n    }\n    vector<char> path;\n    int cur = target;\n    while (cur != start) {\n        path.push_back(pdir[cur]);\n        cur = parent[cur];\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n/* ---------- greedy construction (length = 200) ---------- */\nstring greedyRoute() {\n    const int L = 200;\n    string s;\n    s.reserve(L);\n    vector<double> prob(N, 0.0), nxt(N, 0.0);\n    prob[start] = 1.0;\n\n    for (int turn = 1; turn <= L; ++turn) {\n        double bestVal = -1e100;\n        int bestDir = -1;\n        vector<double> bestNxt(N, 0.0);\n        double bestArr = 0.0;\n\n        for (int dir = 0; dir < 4; ++dir) {\n            fill(nxt.begin(), nxt.end(), 0.0);\n            double arrival = 0.0;\n\n            for (int v = 0; v < N; ++v) {\n                double cur = prob[v];\n                if (cur == 0.0) continue;\n                double stayProb = cur * forgetP;\n                double moveProb = cur * (1.0 - forgetP);\n                int w = neighbour[v][dir];\n                if (w == target) arrival += moveProb;\n                else               nxt[w] += moveProb;\n                nxt[v] += stayProb;\n            }\n            double expDist = 0.0;\n            for (int v = 0; v < N; ++v) expDist += nxt[v] * bfsDist[v];\n\n            double value = arrival * (401 - turn) - expDist;\n            if (value > bestVal) {\n                bestVal = value;\n                bestDir = dir;\n                bestArr = arrival;\n                bestNxt.swap(nxt);\n            }\n        }\n        s.push_back(dirChar[bestDir]);\n        prob.swap(bestNxt);\n    }\n    return s;\n}\n\n/* ---------- random modification of a route ---------- */\nstring modify(const string &cur, int minLen, mt19937 &rng) {\n    string nxt = cur;\n    int L = (int)nxt.size();\n    uniform_int_distribution<int> opDist(0, 9);\n    int op = opDist(rng);\n    if (op < 7) { // replace\n        uniform_int_distribution<int> posDist(0, L - 1);\n        uniform_int_distribution<int> dirDist(0, 3);\n        int pos = posDist(rng);\n        nxt[pos] = dirChar[dirDist(rng)];\n    } else if (op < 9) { // insert\n        if (L < 200) {\n            uniform_int_distribution<int> posDist(0, L);\n            uniform_int_distribution<int> dirDist(0, 3);\n            int pos = posDist(rng);\n            nxt.insert(nxt.begin() + pos, dirChar[dirDist(rng)]);\n        } else {\n            uniform_int_distribution<int> posDist(0, L - 1);\n            uniform_int_distribution<int> dirDist(0, 3);\n            int pos = posDist(rng);\n            nxt[pos] = dirChar[dirDist(rng)];\n        }\n    } else { // delete\n        if (L > minLen) {\n            uniform_int_distribution<int> posDist(0, L - 1);\n            int pos = posDist(rng);\n            nxt.erase(nxt.begin() + pos);\n        } else {\n            uniform_int_distribution<int> posDist(0, L - 1);\n            uniform_int_distribution<int> dirDist(0, 3);\n            int pos = posDist(rng);\n            nxt[pos] = dirChar[dirDist(rng)];\n        }\n    }\n    return nxt;\n}\n\n/* ---------- main ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    /* ---- read input ---- */\n    int si, sj, ti, tj;\n    double p;\n    if (!(cin >> si >> sj >> ti >> tj >> p)) return 0;\n    start = si * W + sj;\n    target = ti * W + tj;\n    forgetP = p;\n\n    vector<string> h(H, string(W - 1, '0'));\n    for (int i = 0; i < H; ++i) cin >> h[i];\n    vector<string> v(H - 1, string(W, '0'));\n    for (int i = 0; i < H - 1; ++i) cin >> v[i];\n\n    /* ---- build neighbour table ---- */\n    for (int i = 0; i < H; ++i) {\n        for (int j = 0; j < W; ++j) {\n            int id = i * W + j;\n            // up\n            if (i == 0) neighbour[id][0] = id;\n            else if (v[i-1][j] == '1') neighbour[id][0] = id;\n            else neighbour[id][0] = (i-1) * W + j;\n            // down\n            if (i == H-1) neighbour[id][1] = id;\n            else if (v[i][j] == '1') neighbour[id][1] = id;\n            else neighbour[id][1] = (i+1) * W + j;\n            // left\n            if (j == 0) neighbour[id][2] = id;\n            else if (h[i][j-1] == '1') neighbour[id][2] = id;\n            else neighbour[id][2] = i * W + (j-1);\n            // right\n            if (j == W-1) neighbour[id][3] = id;\n            else if (h[i][j] == '1') neighbour[id][3] = id;\n            else neighbour[id][3] = i * W + (j+1);\n        }\n    }\n\n    // dirIdx\n    fill(dirIdx.begin(), dirIdx.end(), -1);\n    for (int d = 0; d < 4; ++d) dirIdx[(unsigned char)dirChar[d]] = d;\n\n    /* ---- BFS distances from target ---- */\n    bfsDist = bfs_from(target);\n\n    /* ---- build candidate routes ---- */\n    vector<string> candidates;\n    // 1) shortest path (maybe repeated twice)\n    vector<char> sp = shortestPath();\n    int spLen = (int)sp.size();\n    string cand1;\n    int repeat = (spLen * 2 <= 200) ? 2 : 1;\n    for (char c : sp) {\n        for (int i = 0; i < repeat; ++i) cand1.push_back(c);\n    }\n    candidates.push_back(cand1);\n    // 2) greedy route\n    candidates.push_back(greedyRoute());\n    // 3) random route (optional)\n    {\n        string rnd(200, 'U');\n        mt19937 rng(0);\n        uniform_int_distribution<int> dirDist(0,3);\n        for (char &c : rnd) c = dirChar[dirDist(rng)];\n        candidates.push_back(rnd);\n    }\n\n    /* ---- evaluate all candidates, keep the best ---- */\n    double bestScore = -1.0;\n    string bestRoute = candidates[0];\n    for (const string &cand : candidates) {\n        double sc = evaluate(cand);\n        if (sc > bestScore) {\n            bestScore = sc;\n            bestRoute = cand;\n        }\n    }\n\n    /* ---- hill climbing / simulated annealing ---- */\n    const double TIME_LIMIT = 1.8; // seconds\n    auto startTime = chrono::high_resolution_clock::now();\n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n\n    string cur = bestRoute;\n    double curScore = bestScore;\n    double temperature = 1.0;\n    int minLen = spLen; // we never delete below the original shortest\u2011path length\n\n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - startTime).count();\n        if (elapsed > TIME_LIMIT) break;\n\n        temperature *= 0.999;\n\n        string cand = modify(cur, minLen, rng);\n        double candScore = evaluate(cand);\n\n        double delta = candScore - curScore;\n        bool accept = (delta > 0.0);\n        if (!accept) {\n            uniform_real_distribution<double> uni(0.0, 1.0);\n            if (uni(rng) < exp(delta / temperature)) accept = true;\n        }\n        if (accept) {\n            cur = cand;\n            curScore = candScore;\n        }\n        if (candScore > bestScore) {\n            bestScore = candScore;\n            bestRoute = cand;\n        }\n    }\n\n    /* ---- output ---- */\n    cout << bestRoute << '\\n';\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Constants\nconst int H = 30, W = 30;\nconst int N = H * W;\nconst int DIR = 4;\nconst int NODE_COUNT = N * DIR;\n\n// Tile connection table: TO[t][d] = exit direction when entering tile type t from direction d\nconst int TO[8][4] = {\n    {1, 0, -1, -1},  // 0: left-up curve\n    {3, -1, -1, 0},  // 1: left-down curve\n    {-1, -1, 3, 2},  // 2: right-down curve\n    {-1, 2, 1, -1},  // 3: right-up curve\n    {1, 0, 3, 2},    // 4: double curve (left-up + right-down)\n    {3, 2, 1, 0},    // 5: double curve (left-down + right-up)\n    {2, -1, 0, -1},  // 6: horizontal line\n    {-1, 3, -1, 1}   // 7: vertical line\n};\n\n// Direction vectors: 0=left, 1=up, 2=right, 3=down\nconst int DI[4] = {0, -1, 0, 1};\nconst int DJ[4] = {-1, 0, 1, 0};\n\n// Rotation mapping: ROTATE_MAP[t][r] = effective type after r rotations\nint ROTATE_MAP[8][4];\n\nvoid init_rotate_map() {\n    const int ROT1[8] = {1, 2, 3, 0, 5, 4, 7, 6};\n    for (int t = 0; t < 8; ++t) {\n        ROTATE_MAP[t][0] = t;\n        int cur = t;\n        for (int r = 1; r < 4; ++r) {\n            cur = ROT1[cur];\n            ROTATE_MAP[t][r] = cur;\n        }\n    }\n}\n\n// Fast cycle detection for functional graph\npair<int, int> compute_score(const array<int, N>& rot, const array<int, N>& tiles) {\n    static array<int, NODE_COUNT> nxt;\n    static array<char, NODE_COUNT> state;\n    static vector<int> cycle_lens;\n    \n    // Build next array: for each node (cell, entry_dir), where does it go next?\n    for (int i = 0; i < H; ++i) {\n        for (int j = 0; j < W; ++j) {\n            int idx = i * W + j;\n            int t = tiles[idx];\n            int r = rot[idx];\n            int eff_type = ROTATE_MAP[t][r];\n            \n            int base = idx * DIR;\n            for (int d = 0; d < DIR; ++d) {\n                int d2 = TO[eff_type][d];\n                if (d2 == -1) {\n                    nxt[base + d] = -1;\n                    continue;\n                }\n                int ni = i + DI[d2];\n                int nj = j + DJ[d2];\n                if (ni < 0 || ni >= H || nj < 0 || nj >= W) {\n                    nxt[base + d] = -1;\n                    continue;\n                }\n                int nidx = ni * W + nj;\n                int nd = (d2 + 2) % DIR;\n                nxt[base + d] = nidx * DIR + nd;\n            }\n        }\n    }\n    \n    // Reset state\n    state.fill(0);\n    cycle_lens.clear();\n    \n    // Find cycles using DFS\n    vector<int> path;\n    path.reserve(NODE_COUNT);\n    \n    for (int s = 0; s < NODE_COUNT; ++s) {\n        if (state[s] != 0) continue;\n        \n        int cur = s;\n        path.clear();\n        \n        // Follow path\n        while (cur != -1 && state[cur] == 0) {\n            state[cur] = 1;\n            path.push_back(cur);\n            cur = nxt[cur];\n        }\n        \n        // Check if we found a cycle\n        if (cur != -1 && state[cur] == 1) {\n            // Find cycle start in path\n            int start_idx = -1;\n            for (int i = 0; i < (int)path.size(); ++i) {\n                if (path[i] == cur) {\n                    start_idx = i;\n                    break;\n                }\n            }\n            if (start_idx != -1) {\n                int len = (int)path.size() - start_idx;\n                cycle_lens.push_back(len);\n            }\n        }\n        \n        // Mark all visited nodes as done\n        for (int node : path) {\n            state[node] = 2;\n        }\n    }\n    \n    // Get top two cycle lengths\n    int L1 = 0, L2 = 0;\n    if (!cycle_lens.empty()) {\n        sort(cycle_lens.begin(), cycle_lens.end(), greater<int>());\n        L1 = cycle_lens[0];\n        if (cycle_lens.size() >= 2) L2 = cycle_lens[1];\n    }\n    \n    return {L1, L2};\n}\n\n// Greedy initialization: maximize local connections\nvoid greedy_init(array<int, N>& rot, const array<int, N>& tiles) {\n    for (int i = 0; i < H; ++i) {\n        for (int j = 0; j < W; ++j) {\n            int idx = i * W + j;\n            int t = tiles[idx];\n            int best_rot = 0;\n            int best_connections = -1;\n            \n            for (int r = 0; r < 4; ++r) {\n                int eff_type = ROTATE_MAP[t][r];\n                int connections = 0;\n                \n                // Count how many sides have valid connections\n                for (int d = 0; d < DIR; ++d) {\n                    int d2 = TO[eff_type][d];\n                    if (d2 == -1) continue;\n                    int ni = i + DI[d2];\n                    int nj = j + DJ[d2];\n                    if (ni >= 0 && ni < H && nj >= 0 && nj < W) {\n                        connections++;\n                    }\n                }\n                \n                if (connections > best_connections) {\n                    best_connections = connections;\n                    best_rot = r;\n                }\n            }\n            \n            rot[idx] = best_rot;\n        }\n    }\n}\n\n// Fast hill climbing with time limit\npair<array<int, N>, long long> hill_climbing(const array<int, N>& tiles) {\n    const double TIME_LIMIT = 1.9; // seconds (leave margin)\n    auto start_time = chrono::high_resolution_clock::now();\n    \n    random_device rd;\n    mt19937 rng(rd());\n    uniform_int_distribution<int> dist_tile(0, N-1);\n    uniform_int_distribution<int> dist_rot(0, 3);\n    \n    // Initialize with greedy solution\n    array<int, N> rot;\n    greedy_init(rot, tiles);\n    \n    // Evaluate initial solution\n    auto [L1, L2] = compute_score(rot, tiles);\n    long long best_score = (long long)L1 * L2;\n    array<int, N> best_rot = rot;\n    \n    // Hill climbing parameters\n    const int MAX_STALL = 5000; // Give up after this many non-improving moves\n    int stall_counter = 0;\n    long long current_score = best_score;\n    \n    while (true) {\n        // Check time limit\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > TIME_LIMIT) break;\n        \n        // Random restart if stuck\n        if (stall_counter > MAX_STALL) {\n            for (int i = 0; i < N; ++i) {\n                rot[i] = dist_rot(rng);\n            }\n            auto [new_L1, new_L2] = compute_score(rot, tiles);\n            current_score = (long long)new_L1 * new_L2;\n            if (current_score > best_score) {\n                best_score = current_score;\n                best_rot = rot;\n            }\n            stall_counter = 0;\n            continue;\n        }\n        \n        // Try flipping a random tile\n        int tile = dist_tile(rng);\n        int old_rot = rot[tile];\n        int new_rot;\n        do {\n            new_rot = dist_rot(rng);\n        } while (new_rot == old_rot);\n        \n        // Apply change\n        rot[tile] = new_rot;\n        auto [new_L1, new_L2] = compute_score(rot, tiles);\n        long long new_score = (long long)new_L1 * new_L2;\n        \n        // Acceptance decision (only if improving)\n        if (new_score > current_score) {\n            current_score = new_score;\n            stall_counter = 0;\n            if (new_score > best_score) {\n                best_score = new_score;\n                best_rot = rot;\n            }\n        } else {\n            // Revert change\n            rot[tile] = old_rot;\n            stall_counter++;\n        }\n    }\n    \n    return {best_rot, best_score};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    init_rotate_map();\n    \n    // Read input\n    array<int, N> tiles;\n    for (int i = 0; i < H; ++i) {\n        string line;\n        if (!(cin >> line)) return 0;\n        for (int j = 0; j < W; ++j) {\n            tiles[i * W + j] = line[j] - '0';\n        }\n    }\n    \n    // Run hill climbing\n    auto [best_rot, best_score] = hill_climbing(tiles);\n    \n    // Output result as 900-digit string\n    for (int i = 0; i < N; ++i) {\n        cout << best_rot[i];\n    }\n    cout << '\\n';\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Direction constants\nconst int DIR_LEFT = 1;\nconst int DIR_UP = 2;\nconst int DIR_RIGHT = 4;\nconst int DIR_DOWN = 8;\n\n// Movement vectors\nconst int DR[4] = {-1, 1, 0, 0};\nconst int DC[4] = {0, 0, -1, 1};\nconst char MOVE_CHAR[4] = {'U', 'D', 'L', 'R'};\n\nclass SlidingTreePuzzle {\nprivate:\n    int N, T;\n    vector<int> board;\n    int emptyPos;\n    vector<int> initialBoard; // Store initial state\n    \n    bool hasLine(int tile, int direction) {\n        return (tile & direction) != 0;\n    }\n    \n    int idx(int r, int c) {\n        return r * N + c;\n    }\n    \n    bool inBounds(int r, int c) {\n        return r >= 0 && r < N && c >= 0 && c < N;\n    }\n    \n    // Evaluate: size of largest tree component\n    int evaluate() {\n        vector<int> comp(N*N, -1);\n        vector<int> compSize;\n        vector<int> compEdges;\n        int compCount = 0;\n        vector<vector<int>> adj(N*N);\n        \n        // Build adjacency\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                int pos = idx(r, c);\n                int tile = board[pos];\n                if (tile == 0) continue;\n                \n                // Right neighbor\n                if (c + 1 < N) {\n                    int npos = idx(r, c+1);\n                    int ntile = board[npos];\n                    if (ntile != 0 && hasLine(tile, DIR_RIGHT) && hasLine(ntile, DIR_LEFT)) {\n                        adj[pos].push_back(npos);\n                        adj[npos].push_back(pos);\n                    }\n                }\n                \n                // Down neighbor\n                if (r + 1 < N) {\n                    int npos = idx(r+1, c);\n                    int ntile = board[npos];\n                    if (ntile != 0 && hasLine(tile, DIR_DOWN) && hasLine(ntile, DIR_UP)) {\n                        adj[pos].push_back(npos);\n                        adj[npos].push_back(pos);\n                    }\n                }\n            }\n        }\n        \n        // Find components\n        for (int i = 0; i < N*N; i++) {\n            if (board[i] == 0 || comp[i] != -1) continue;\n            \n            queue<int> q;\n            q.push(i);\n            comp[i] = compCount;\n            int size = 0;\n            \n            while (!q.empty()) {\n                int cur = q.front();\n                q.pop();\n                size++;\n                \n                for (int nxt : adj[cur]) {\n                    if (comp[nxt] == -1) {\n                        comp[nxt] = compCount;\n                        q.push(nxt);\n                    }\n                }\n            }\n            \n            compSize.push_back(size);\n            compEdges.push_back(0);\n            compCount++;\n        }\n        \n        // Count edges\n        for (int i = 0; i < N*N; i++) {\n            if (board[i] == 0) continue;\n            for (int j : adj[i]) {\n                if (i < j) {\n                    int cid = comp[i];\n                    compEdges[cid]++;\n                }\n            }\n        }\n        \n        // Find largest tree\n        int best = 0;\n        for (int i = 0; i < compCount; i++) {\n            if (compEdges[i] == compSize[i] - 1) {\n                best = max(best, compSize[i]);\n            }\n        }\n        \n        return best;\n    }\n    \n    // Make a move\n    char makeMove(int dir) {\n        int r = emptyPos / N;\n        int c = emptyPos % N;\n        int nr = r + DR[dir];\n        int nc = c + DC[dir];\n        \n        if (!inBounds(nr, nc)) return '\\0';\n        \n        int npos = idx(nr, nc);\n        swap(board[emptyPos], board[npos]);\n        emptyPos = npos;\n        return MOVE_CHAR[dir];\n    }\n    \n    // Undo a move\n    void undoMove(int dir) {\n        int oppositeDir = (dir % 2 == 0) ? dir + 1 : dir - 1;\n        makeMove(oppositeDir);\n    }\n    \n    // Reset to initial state\n    void resetToInitial() {\n        board = initialBoard;\n        for (int i = 0; i < N*N; i++) {\n            if (board[i] == 0) {\n                emptyPos = i;\n                break;\n            }\n        }\n    }\n    \npublic:\n    string solve(int N_, int T_, const vector<int>& initialBoard) {\n        N = N_;\n        T = T_;\n        board = initialBoard;\n        this->initialBoard = initialBoard;\n        \n        // Find empty position\n        for (int i = 0; i < N*N; i++) {\n            if (board[i] == 0) {\n                emptyPos = i;\n                break;\n            }\n        }\n        \n        // Initialize best solution tracking\n        vector<int> bestBoard = board;\n        int bestScore = evaluate();\n        string bestMoves = \"\";\n        string currentMoves = \"\";\n        \n        // Hill climbing with periodic restarts\n        double startTime = clock();\n        double timeLimit = 2.8;\n        \n        int steps = 0;\n        \n        while ((clock() - startTime) / CLOCKS_PER_SEC < timeLimit) {\n            // Check move limit before continuing\n            if (currentMoves.size() >= T) {\n                resetToInitial();\n                currentMoves = \"\";\n                continue;\n            }\n            \n            // Reset to initial state every 500 steps\n            if (steps > 0 && steps % 500 == 0) {\n                resetToInitial();\n                currentMoves = \"\";\n            }\n            \n            // Try all 4 directions and pick the best move\n            int bestDir = -1;\n            int bestMoveScore = -1;\n            \n            for (int dir = 0; dir < 4; dir++) {\n                int r = emptyPos / N;\n                int c = emptyPos % N;\n                int nr = r + DR[dir];\n                int nc = c + DC[dir];\n                \n                if (!inBounds(nr, nc)) continue;\n                \n                // Simulate the move\n                char moveChar = makeMove(dir);\n                int score = evaluate();\n                \n                // Choose if better (random tiebreak)\n                if (score > bestMoveScore || (score == bestMoveScore && rand() % 2)) {\n                    bestMoveScore = score;\n                    bestDir = dir;\n                }\n                \n                // Undo the move\n                undoMove(dir);\n            }\n            \n            // If we found a move that doesn't worsen the score, take it\n            if (bestDir != -1 && bestMoveScore >= evaluate()) {\n                char moveChar = makeMove(bestDir);\n                currentMoves.push_back(moveChar);\n                \n                // Check move limit after adding\n                if (currentMoves.size() > T) {\n                    // Return best found so far instead of exceeding limit\n                    return bestMoves.empty() ? currentMoves.substr(0, T) : bestMoves;\n                }\n                \n                // Update best solution if this is better\n                if (bestMoveScore > bestScore) {\n                    bestScore = bestMoveScore;\n                    bestBoard = board;\n                    bestMoves = currentMoves;\n                    \n                    // Early exit if we achieved full tree\n                    if (bestScore == N*N - 1) {\n                        return bestMoves;\n                    }\n                }\n            } else {\n                // No improving move found, make a random move\n                vector<int> validDirs;\n                for (int dir = 0; dir < 4; dir++) {\n                    int r = emptyPos / N;\n                    int c = emptyPos % N;\n                    int nr = r + DR[dir];\n                    int nc = c + DC[dir];\n                    if (inBounds(nr, nc)) {\n                        validDirs.push_back(dir);\n                    }\n                }\n                \n                if (!validDirs.empty()) {\n                    int dir = validDirs[rand() % validDirs.size()];\n                    char moveChar = makeMove(dir);\n                    currentMoves.push_back(moveChar);\n                    \n                    // Check move limit\n                    if (currentMoves.size() > T) {\n                        return bestMoves.empty() ? currentMoves.substr(0, T) : bestMoves;\n                    }\n                }\n            }\n            \n            steps++;\n        }\n        \n        // Return best solution found (never exceeds T)\n        return bestMoves.empty() ? currentMoves.substr(0, T) : bestMoves;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, T;\n    if (!(cin >> N >> T)) return 0;\n    \n    vector<int> board(N*N);\n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            char c = line[j];\n            if (c == '0') {\n                board[i*N + j] = 0;\n            } else {\n                int val = (c >= 'a') ? (c - 'a' + 10) : (c - '0');\n                board[i*N + j] = val;\n            }\n        }\n    }\n    \n    SlidingTreePuzzle solver;\n    string moves = solver.solve(N, T, board);\n    \n    // Ensure we never exceed T moves\n    if (moves.size() > T) {\n        moves = moves.substr(0, T);\n    }\n    \n    cout << moves << '\\n';\n    \n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nstruct Point { int x, y; };\nstruct Line { \n    long long A, B, C, x1, y1, x2, y2; \n    Line() {} \n    Line(long long a, long long b, long long c, long long d) : x1(a), y1(b), x2(c), y2(d) { \n        A = y2 - y1; B = x1 - x2; C = -(A * x1 + B * y1); \n        long long g = std::gcd(std::gcd(abs(A), abs(B)), abs(C)); \n        if (g > 0) { A /= g; B /= g; C /= g; } \n        if (A < 0 || (A == 0 && B < 0)) { A = -A; B = -B; C = -C; } \n    } \n    long long eval(const Point& p) const { return A * p.x + B * p.y + C; } \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    \n    array<int, 11> a{};\n    for (int d = 1; d <= 10; d++) cin >> a[d];\n    vector<Point> points(N);\n    for (int i = 0; i < N; i++) cin >> points[i].x >> points[i].y;\n    \n    vector<Line> lines;\n    vector<unsigned long long> signatures(N, 0);\n    vector<char> dead(N, 0);\n    array<int, 11> remain = a;\n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<long long> coord(-1000000000LL, 1000000000LL);\n    \n    const int CANDIDATES = 35;\n    \n    // Greedy construction: add one line at a time\n    for (int iter = 0; iter < K; iter++) {\n        vector<int> demand_sizes;\n        for (int d = 1; d <= 10; d++) if (remain[d] > 0) demand_sizes.push_back(d);\n        if (demand_sizes.empty()) break; // All demands satisfied\n        \n        int target = demand_sizes[rng() % demand_sizes.size()];\n        double best_score = -1;\n        Line best_line;\n        \n        for (int c = 0; c < CANDIDATES; c++) {\n            Line cand;\n            \n            // Geometric candidate: separate cluster around a random point\n            if (c < 25) {\n                int center = -1;\n                for (int tries = 0; tries < 20; tries++) {\n                    uniform_int_distribution<> idx(0, N-1);\n                    int i = idx(rng);\n                    if (!dead[i]) { center = i; break; }\n                }\n                \n                if (center == -1) {\n                    long long x1 = coord(rng), y1 = coord(rng);\n                    long long x2 = coord(rng), y2 = coord(rng);\n                    if (x1 == x2 && y1 == y2) x2++;\n                    cand = Line(x1, y1, x2, y2);\n                } else {\n                    int nearest = -1;\n                    long long best_dist = (1LL << 60);\n                    for (int i = 0; i < N; i++) {\n                        if (i == center || dead[i]) continue;\n                        long long dx = (long long)points[i].x - points[center].x;\n                        long long dy = (long long)points[i].y - points[center].y;\n                        long long dist = dx*dx + dy*dy;\n                        if (dist < best_dist) {\n                            best_dist = dist;\n                            nearest = i;\n                        }\n                    }\n                    \n                    if (nearest == -1) {\n                        long long x1 = coord(rng), y1 = coord(rng);\n                        long long x2 = coord(rng), y2 = coord(rng);\n                        if (x1 == x2 && y1 == y2) x2++;\n                        cand = Line(x1, y1, x2, y2);\n                    } else {\n                        long long midx = ((long long)points[center].x + points[nearest].x) / 2;\n                        long long midy = ((long long)points[center].y + points[nearest].y) / 2;\n                        long long dx = (long long)points[nearest].x - points[center].x;\n                        long long dy = (long long)points[nearest].y - points[center].y;\n                        cand = Line(midx, midy, midx - dy, midy + dx);\n                    }\n                }\n            } else {\n                long long x1 = coord(rng), y1 = coord(rng);\n                long long x2 = coord(rng), y2 = coord(rng);\n                if (x1 == x2 && y1 == y2) x2++;\n                cand = Line(x1, y1, x2, y2);\n            }\n            \n            // Score this candidate\n            unordered_map<unsigned long long, int> groups;\n            groups.reserve(N / 2);\n            \n            for (int i = 0; i < N; i++) {\n                if (dead[i]) continue;\n                long long val = cand.eval(points[i]);\n                if (val == 0) continue;\n                unsigned long long sig = signatures[i];\n                if (val > 0) sig |= (1ULL << iter);\n                groups[sig]++;\n            }\n            \n            int cnt[11] = {0};\n            for (auto& [sig, sz] : groups) {\n                if (sz >= 1 && sz <= 10) cnt[sz]++;\n            }\n            \n            double score = 0;\n            for (int d = 1; d <= 10; d++) {\n                double w = 1.0 + remain[d] * 0.05;\n                score += w * min(remain[d], cnt[d]);\n            }\n            \n            if (score > best_score) {\n                best_score = score;\n                best_line = cand;\n            }\n        }\n        \n        // Apply the best line\n        unordered_map<unsigned long long, int> final_groups;\n        final_groups.reserve(N / 2);\n        \n        for (int i = 0; i < N; i++) {\n            if (dead[i]) continue;\n            long long val = best_line.eval(points[i]);\n            if (val == 0) {\n                dead[i] = 1;\n            } else {\n                unsigned long long sig = signatures[i];\n                if (val > 0) sig |= (1ULL << iter);\n                final_groups[sig]++;\n            }\n        }\n        \n        for (auto& [sig, sz] : final_groups) {\n            if (sz >= 1 && sz <= 10 && remain[sz] > 0) {\n                remain[sz]--;\n            }\n        }\n        \n        lines.push_back(best_line);\n    }\n    \n    // Output\n    cout << lines.size() << \"\\n\";\n    auto clamp = [](long long v) { return max(-1000000000LL, min(1000000000LL, v)); };\n    for (auto& line : lines) {\n        cout << clamp(line.x1) << \" \" << clamp(line.y1) << \" \"\n             << clamp(line.x2) << \" \" << clamp(line.y2) << \"\\n\";\n    }\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n};\n\nstruct Operation {\n    Point p1, p2, p3, p4; // p1 is new dot, p1->p2->p3->p4 forms rectangle\n};\n\nclass RectJoinSolver {\n    int N, M;\n    double center;\n    vector<vector<bool>> has_dot;\n    vector<vector<bool>> edge_h; // horizontal edges: edge_h[x][y] from (x,y) to (x+1,y)\n    vector<vector<bool>> edge_v; // vertical edges: edge_v[x][y] from (x,y) to (x,y+1)\n    vector<vector<int>> weight;\n    long long total_S = 0;\n    vector<Operation> operations;\n\npublic:\n    RectJoinSolver(int N, int M) : N(N), M(M) {\n        center = (N - 1) / 2.0;\n        has_dot.assign(N, vector<bool>(N, false));\n        edge_h.assign(N, vector<bool>(N, false));\n        edge_v.assign(N, vector<bool>(N, false));\n        weight.assign(N, vector<int>(N, 0));\n        \n        // Precompute weights\n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y < N; y++) {\n                double dx = x - center;\n                double dy = y - center;\n                weight[x][y] = (int)(dx*dx + dy*dy + 1.0);\n                total_S += weight[x][y];\n            }\n        }\n    }\n    \n    void add_initial_dot(int x, int y) {\n        has_dot[x][y] = true;\n    }\n    \n    bool in_bounds(int x, int y) const {\n        return x >= 0 && x < N && y >= 0 && y < N;\n    }\n    \n    bool can_draw_horizontal(int x1, int y1, int x2) {\n        if (x1 > x2) swap(x1, x2);\n        for (int x = x1; x < x2; x++) {\n            if (edge_h[x][y1]) return false;\n        }\n        return true;\n    }\n    \n    bool can_draw_vertical(int x1, int y1, int y2) {\n        if (y1 > y2) swap(y1, y2);\n        for (int y = y1; y < y2; y++) {\n            if (edge_v[x1][y]) return false;\n        }\n        return true;\n    }\n    \n    void draw_horizontal(int x1, int y1, int x2) {\n        if (x1 > x2) swap(x1, x2);\n        for (int x = x1; x < x2; x++) {\n            edge_h[x][y1] = true;\n        }\n    }\n    \n    void draw_vertical(int x1, int y1, int y2) {\n        if (y1 > y2) swap(y1, y2);\n        for (int y = y1; y < y2; y++) {\n            edge_v[x1][y] = true;\n        }\n    }\n    \n    // Try to add axis-aligned rectangle with p1 as new dot\n    // Correct rectangle: p1->p2->p3->p4 forms rectangle\n    // p1 = (x,y) [new], p2 = (x+a,y) [existing], p3 = (x+a,y+b) [existing], p4 = (x,y+b) [existing]\n    bool try_axis_rectangle(const Point& p1, int a, int b) {\n        if (a == 0 || b == 0) return false;\n        if (abs(a) > 30 || abs(b) > 30) return false;\n        \n        Point p2 = {p1.x + a, p1.y};      // right neighbor\n        Point p3 = {p1.x + a, p1.y + b};  // diagonal opposite (bottom-right)\n        Point p4 = {p1.x, p1.y + b};      // bottom neighbor\n        \n        // Bounds check\n        if (!in_bounds(p2.x, p2.y) || !in_bounds(p3.x, p3.y) || \n            !in_bounds(p4.x, p4.y)) return false;\n        \n        // Dot presence: p1 must be empty, p2-p4 must have dots\n        if (has_dot[p1.x][p1.y]) return false;\n        if (!has_dot[p2.x][p2.y]) return false;\n        if (!has_dot[p3.x][p3.y]) return false;\n        if (!has_dot[p4.x][p4.y]) return false;\n        \n        // Check perimeter is clear of other dots (besides vertices)\n        int step_x = (a > 0) ? 1 : -1;\n        int step_y = (b > 0) ? 1 : -1;\n        \n        // Edge p1->p2 (horizontal)\n        for (int x = p1.x + step_x; x != p2.x; x += step_x) {\n            if (has_dot[x][p1.y]) return false;\n        }\n        \n        // Edge p2->p3 (vertical)\n        for (int y = p2.y + step_y; y != p3.y; y += step_y) {\n            if (has_dot[p2.x][y]) return false;\n        }\n        \n        // Edge p3->p4 (horizontal)\n        for (int x = p3.x - step_x; x != p4.x; x -= step_x) {\n            if (has_dot[x][p3.y]) return false;\n        }\n        \n        // Edge p4->p1 (vertical)\n        for (int y = p4.y - step_y; y != p1.y; y -= step_y) {\n            if (has_dot[p4.x][y]) return false;\n        }\n        \n        // Check edge conflicts (no overlapping)\n        if (!can_draw_horizontal(p1.x, p1.y, p2.x)) return false;\n        if (!can_draw_vertical(p2.x, p2.y, p3.y)) return false;\n        if (!can_draw_horizontal(p4.x, p4.y, p3.x)) return false;\n        if (!can_draw_vertical(p1.x, p1.y, p4.y)) return false;\n        \n        // All checks passed - add rectangle\n        has_dot[p1.x][p1.y] = true;\n        draw_horizontal(p1.x, p1.y, p2.x);  // p1->p2\n        draw_vertical(p2.x, p2.y, p3.y);    // p2->p3\n        draw_horizontal(p4.x, p4.y, p3.x);  // p4->p3 (reversed but same segment)\n        draw_vertical(p1.x, p1.y, p4.y);    // p1->p4\n        \n        operations.push_back({p1, p2, p3, p4});\n        return true;\n    }\n    \n    void solve() {\n        // Create list of empty points with negative weight for descending order\n        vector<pair<int, Point>> candidates;\n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y < N; y++) {\n                if (!has_dot[x][y]) {\n                    candidates.push_back({-weight[x][y], {x, y}});\n                }\n            }\n        }\n        \n        // Sort by weight (descending) - only compare first element\n        sort(candidates.begin(), candidates.end(), [](const auto& a, const auto& b) {\n            return a.first < b.first;\n        });\n        \n        bool improved = true;\n        int iter = 0;\n        const int MAX_ITER = 5000;\n        \n        while (improved && iter < MAX_ITER) {\n            improved = false;\n            iter++;\n            \n            for (auto& [neg_w, p1] : candidates) {\n                if (has_dot[p1.x][p1.y]) continue;\n                \n                // Try different rectangle sizes\n                for (int a = -20; a <= 20 && !improved; a++) {\n                    if (a == 0) continue;\n                    for (int b = -20; b <= 20 && !improved; b++) {\n                        if (b == 0) continue;\n                        if (try_axis_rectangle(p1, a, b)) {\n                            improved = true;\n                        }\n                    }\n                }\n                \n                if (improved) break;\n            }\n        }\n    }\n    \n    const vector<Operation>& get_operations() const {\n        return operations;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n    \n    RectJoinSolver solver(N, M);\n    \n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        solver.add_initial_dot(x, y);\n    }\n    \n    solver.solve();\n    \n    const auto& ops = solver.get_operations();\n    cout << ops.size() << \"\\n\";\n    for (const auto& op : ops) {\n        cout << op.p1.x << \" \" << op.p1.y << \" \"\n             << op.p2.x << \" \" << op.p2.y << \" \"\n             << op.p3.x << \" \" << op.p3.y << \" \"\n             << op.p4.x << \" \" << op.p4.y << \"\\n\";\n    }\n    \n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct UnionFind {\n    vector<int> parent, size;\n    UnionFind(int n = 0) { init(n); }\n    \n    void init(int n) {\n        parent.resize(n);\n        size.assign(n, 1);\n        iota(parent.begin(), parent.end(), 0);\n    }\n    \n    int find(int x) {\n        if (parent[x] == x) return x;\n        return parent[x] = find(parent[x]);\n    }\n    \n    void unite(int x, int y) {\n        x = find(x);\n        y = find(y);\n        if (x == y) return;\n        if (size[x] < size[y]) swap(x, y);\n        parent[y] = x;\n        size[x] += size[y];\n    }\n    \n    int getSize(int x) {\n        return size[find(x)];\n    }\n};\n\nclass CandyBox {\n    static const int H = 10;\n    static const int W = 10;\n    static const int N = H * W;\n    static const int SIM_COUNT = 25; // Increased for better quality\n    \n    array<array<int, W>, H> grid;\n    array<array<int, W>, H> tmpGrid;\n    mt19937 rng;\n    \n    int realisticTilt(const array<array<int, W>, H>& state) {\n        int flavorCounts[4] = {0};\n        for (int i = 0; i < H; i++) {\n            for (int j = 0; j < W; j++) {\n                if (state[i][j] != 0) flavorCounts[state[i][j]]++;\n            }\n        }\n        \n        int majorFlavor = 1;\n        for (int f = 2; f <= 3; f++) {\n            if (flavorCounts[f] > flavorCounts[majorFlavor]) majorFlavor = f;\n        }\n        \n        int topCount = 0, bottomCount = 0, leftCount = 0, rightCount = 0;\n        for (int i = 0; i < H; i++) {\n            for (int j = 0; j < W; j++) {\n                if (state[i][j] == majorFlavor) {\n                    if (i < H/2) topCount++; else bottomCount++;\n                    if (j < W/2) leftCount++; else rightCount++;\n                }\n            }\n        }\n        \n        // Add controlled randomness to prevent deterministic patterns\n        int randomBias = rng() % 3; // 0, 1, or 2 random factor\n        \n        if (topCount > bottomCount + randomBias && leftCount > rightCount + randomBias) \n            return (rng() % 2 == 0) ? 0 : 2; // F or L\n        if (topCount > bottomCount + randomBias) return 0; // F\n        if (bottomCount > topCount + randomBias && rightCount > leftCount + randomBias) \n            return (rng() % 2 == 0) ? 1 : 3; // B or R\n        if (bottomCount > topCount + randomBias) return 1; // B\n        if (leftCount > rightCount + randomBias) return 2; // L\n        if (rightCount > leftCount + randomBias) return 3; // R\n        \n        return rng() % 4;\n    }\n    \npublic:\n    CandyBox() : rng(chrono::steady_clock::now().time_since_epoch().count()) {\n        for (int i = 0; i < H; i++)\n            grid[i].fill(0);\n    }\n    \n    void placeCandy(int flavor, int p) {\n        int cnt = 0;\n        for (int i = 0; i < H; i++) {\n            for (int j = 0; j < W; j++) {\n                if (grid[i][j] == 0) {\n                    cnt++;\n                    if (cnt == p) {\n                        grid[i][j] = flavor;\n                        return;\n                    }\n                }\n            }\n        }\n    }\n    \n    void simulateTilt(int d, const array<array<int, W>, H>& src, array<array<int, W>, H>& dst) {\n        dst = src;\n        \n        if (d == 0) { // Forward (up)\n            for (int j = 0; j < W; j++) {\n                int writePos = 0;\n                for (int i = 0; i < H; i++) {\n                    if (dst[i][j] != 0) {\n                        if (i != writePos) {\n                            dst[writePos][j] = dst[i][j];\n                            dst[i][j] = 0;\n                        }\n                        writePos++;\n                    }\n                }\n            }\n        } else if (d == 1) { // Backward (down)\n            for (int j = 0; j < W; j++) {\n                int writePos = H - 1;\n                for (int i = H - 1; i >= 0; i--) {\n                    if (dst[i][j] != 0) {\n                        if (i != writePos) {\n                            dst[writePos][j] = dst[i][j];\n                            dst[i][j] = 0;\n                        }\n                        writePos--;\n                    }\n                }\n            }\n        } else if (d == 2) { // Left\n            for (int i = 0; i < H; i++) {\n                int writePos = 0;\n                for (int j = 0; j < W; j++) {\n                    if (dst[i][j] != 0) {\n                        if (j != writePos) {\n                            dst[i][writePos] = dst[i][j];\n                            dst[i][j] = 0;\n                        }\n                        writePos++;\n                    }\n                }\n            }\n        } else { // Right\n            for (int i = 0; i < H; i++) {\n                int writePos = W - 1;\n                for (int j = W - 1; j >= 0; j--) {\n                    if (dst[i][j] != 0) {\n                        if (j != writePos) {\n                            dst[i][writePos] = dst[i][j];\n                            dst[i][j] = 0;\n                        }\n                        writePos--;\n                    }\n                }\n            }\n        }\n    }\n    \n    long long calculateScore(const array<array<int, W>, H>& g) {\n        UnionFind uf(N);\n        int id[H][W];\n        int curId = 0;\n        \n        for (int i = 0; i < H; i++) {\n            for (int j = 0; j < W; j++) {\n                if (g[i][j] != 0) {\n                    id[i][j] = curId++;\n                } else {\n                    id[i][j] = -1;\n                }\n            }\n        }\n        \n        const int dr[4] = {-1, 1, 0, 0};\n        const int dc[4] = {0, 0, -1, 1};\n        \n        for (int i = 0; i < H; i++) {\n            for (int j = 0; j < W; j++) {\n                if (id[i][j] == -1) continue;\n                for (int dir = 0; dir < 4; dir++) {\n                    int ni = i + dr[dir];\n                    int nj = j + dc[dir];\n                    if (ni >= 0 && ni < H && nj >= 0 && nj < W && id[ni][nj] != -1) {\n                        if (g[i][j] == g[ni][nj]) {\n                            uf.unite(id[i][j], id[ni][nj]);\n                        }\n                    }\n                }\n            }\n        }\n        \n        long long score = 0;\n        vector<char> visited(curId, 0);\n        for (int i = 0; i < curId; i++) {\n            int root = uf.find(i);\n            if (!visited[root]) {\n                int size = uf.getSize(root);\n                score += 1LL * size * size;\n                visited[root] = 1;\n            }\n        }\n        return score;\n    }\n    \n    long long simulateMonteCarlo(int initialDir, const vector<int>& flavors, int currentStep) {\n        long long totalScore = 0;\n        array<array<int, W>, H> simGrid;\n        simulateTilt(initialDir, grid, simGrid);\n        \n        for (int sim = 0; sim < SIM_COUNT; sim++) {\n            array<array<int, W>, H> copy = simGrid;\n            \n            for (int step = currentStep + 1; step < 100; step++) {\n                vector<pair<int, int>> emptyCells;\n                for (int i = 0; i < H; i++) {\n                    for (int j = 0; j < W; j++) {\n                        if (copy[i][j] == 0) {\n                            emptyCells.emplace_back(i, j);\n                        }\n                    }\n                }\n                \n                if (emptyCells.empty()) break;\n                \n                int pos = rng() % emptyCells.size();\n                copy[emptyCells[pos].first][emptyCells[pos].second] = flavors[step];\n                \n                if (step < 99) {\n                    int dir = realisticTilt(copy); // Smart heuristic tilts\n                    array<array<int, W>, H> newGrid;\n                    simulateTilt(dir, copy, newGrid);\n                    copy = newGrid;\n                }\n            }\n            \n            totalScore += calculateScore(copy);\n        }\n        \n        return totalScore / SIM_COUNT;\n    }\n    \n    char chooseDirection(const vector<int>& flavors, int currentStep) {\n        long long greedyScores[4];\n        for (int d = 0; d < 4; d++) {\n            simulateTilt(d, grid, tmpGrid);\n            greedyScores[d] = calculateScore(tmpGrid);\n        }\n        \n        if (currentStep < 60) {\n            long long mcScores[4];\n            for (int d = 0; d < 4; d++) {\n                mcScores[d] = simulateMonteCarlo(d, flavors, currentStep);\n            }\n            \n            int bestMCDir = 0;\n            for (int d = 1; d < 4; d++) {\n                if (mcScores[d] > mcScores[bestMCDir]) bestMCDir = d;\n            }\n            \n            long long bestGreedyScore = *max_element(greedyScores, greedyScores + 4);\n            // More permissive threshold: +5 instead of +10\n            if (mcScores[bestMCDir] > bestGreedyScore + 5) {\n                simulateTilt(bestMCDir, grid, grid);\n                const char dirChar[4] = {'F', 'B', 'L', 'R'};\n                return dirChar[bestMCDir];\n            }\n        }\n        \n        int bestDir = 0;\n        for (int d = 1; d < 4; d++) {\n            if (greedyScores[d] > greedyScores[bestDir]) bestDir = d;\n        }\n        \n        simulateTilt(bestDir, grid, grid);\n        const char dirChar[4] = {'F', 'B', 'L', 'R'};\n        return dirChar[bestDir];\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    vector<int> flavors(100);\n    for (int i = 0; i < 100; i++) {\n        if (!(cin >> flavors[i])) return 0;\n    }\n    \n    CandyBox box;\n    \n    for (int step = 0; step < 100; step++) {\n        int p;\n        cin >> p;\n        box.placeCandy(flavors[step], p);\n        cout << box.chooseDirection(flavors, step) << endl;\n    }\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    const double epsilon = eps;\n    const bool noiseless = (epsilon < 1e-12);\n    int N;                     // number of vertices\n\n    /* -------------------------------------------------------------\n       choose N\n       ------------------------------------------------------------- */\n    if (noiseless) {\n        // N = 5 is enough: 2^10 = 1024 > 100\n        N = 5;\n    } else {\n        double I = log2(max(2, M));          // bits to transmit\n        double H = -epsilon * log2(epsilon) - (1.0 - epsilon) * log2(1.0 - epsilon);\n        double C = 1.0 - H;                  // capacity per edge\n        double need = (I + 5.0) / C;         // a few redundant bits (5 instead of 3)\n        int needEdges = (int)ceil(need);\n        // solve N(N-1)/2 >= needEdges\n        double disc = 1.0 + 8.0 * needEdges;\n        double sq = sqrt(disc);\n        N = (int)ceil((1.0 + sq) / 2.0);\n        if (N < 4) N = 4;\n        if (N > 100) N = 100;\n    }\n\n    const int n = N;\n    const int tot = n * (n - 1) / 2;\n\n    /* -------------------------------------------------------------\n       generate the M graphs (deterministic)\n       ------------------------------------------------------------- */\n    // adjacency matrix G[i][u][v] (0/1)\n    vector<vector<vector<char>>> G(M,\n        vector<vector<char>>(n, vector<char>(n, 0)));\n\n    // vertex order sorted by degree (used for alignment in noiseless case)\n    vector<vector<int>> orderG(M, vector<int>(n));\n    // sorted degree sequences (decreasing)\n    vector<vector<int>> sortedDeg(M, vector<int>(n));\n    // triangle count\n    vector<int> tri(M, 0);\n\n    for (int i = 0; i < M; ++i) {\n        mt19937 rng(i * 10007 + M * 12345 + n * 6789 + 42);\n        uniform_int_distribution<int> dist(0, 1);\n\n        for (int u = 0; u < n; ++u)\n            for (int v = u + 1; v < n; ++v) {\n                char e = (char)dist(rng);\n                G[i][u][v] = G[i][v][u] = e;\n            }\n\n        // degree of each vertex\n        vector<int> deg(n, 0);\n        for (int u = 0; u < n; ++u) {\n            int s = 0;\n            for (int v = 0; v < n; ++v) if (u != v) s += G[i][u][v];\n            deg[u] = s;\n        }\n\n        // order by decreasing degree, tie\u2011break by index\n        vector<int> idx(n);\n        iota(idx.begin(), idx.end(), 0);\n        sort(idx.begin(), idx.end(),\n             [&](int a, int b) {\n                 if (deg[a] != deg[b]) return deg[a] > deg[b];\n                 return a < b;\n             });\n        orderG[i] = idx;\n\n        // sorted degree sequence (decreasing)\n        vector<int> sd = deg;\n        sort(sd.begin(), sd.end(), greater<int>());\n        sortedDeg[i] = sd;\n\n        // count triangles\n        int t = 0;\n        for (int u = 0; u < n; ++u)\n            for (int v = u + 1; v < n; ++v) if (G[i][u][v])\n                for (int w = v + 1; w < n; ++w)\n                    if (G[i][u][w] && G[i][v][w]) ++t;\n        tri[i] = t;\n    }\n\n    /* -------------------------------------------------------------\n       output the graphs\n       ------------------------------------------------------------- */\n    cout << n << '\\n';\n    for (int i = 0; i < M; ++i) {\n        string line;\n        line.reserve(tot);\n        for (int u = 0; u < n; ++u)\n            for (int v = u + 1; v < n; ++v)\n                line.push_back(G[i][u][v] ? '1' : '0');\n        cout << line << '\\n';\n    }\n    cout.flush();\n\n    /* -------------------------------------------------------------\n       pre\u2011compute all permutations (only needed for noiseless case)\n       ------------------------------------------------------------- */\n    vector<vector<int>> perms;\n    if (noiseless) {\n        vector<int> p(n);\n        iota(p.begin(), p.end(), 0);\n        do {\n            perms.push_back(p);\n        } while (next_permutation(p.begin(), p.end()));\n    }\n\n    /* -------------------------------------------------------------\n       answer the 100 queries\n       ------------------------------------------------------------- */\n    for (int q = 0; q < 100; ++q) {\n        string Hstr;\n        cin >> Hstr;\n\n        // adjacency of H (only needed for noiseless case)\n        vector<vector<char>> B(n, vector<char>(n, 0));\n        vector<int> degH(n, 0);\n        int pos = 0;\n        for (int u = 0; u < n; ++u) {\n            for (int v = u + 1; v < n; ++v) {\n                char c = (char)(Hstr[pos++] - '0');\n                B[u][v] = B[v][u] = c;\n                if (c) {\n                    ++degH[u];\n                    ++degH[v];\n                }\n            }\n        }\n\n        int answer = 0;\n\n        if (noiseless) {\n            // exact isomorphism test (N \u2264 5 \u2192 at most 120 permutations)\n            bool found = false;\n            for (int i = 0; i < M && !found; ++i) {\n                for (const auto &perm : perms) {\n                    bool ok = true;\n                    for (int u = 0; u < n && ok; ++u) {\n                        int pu = perm[u];\n                        for (int v = u + 1; v < n; ++v) {\n                            int pv = perm[v];\n                            if (G[i][u][v] != B[pu][pv]) {\n                                ok = false;\n                                break;\n                            }\n                        }\n                    }\n                    if (ok) {\n                        answer = i;\n                        found = true;\n                        break;\n                    }\n                }\n            }\n        } else {\n            // ----- permutation\u2011invariant features -----\n            // sorted degree sequence of H\n            vector<int> sdH = degH;\n            sort(sdH.begin(), sdH.end(), greater<int>());\n\n            // triangle count of H\n            int triH = 0;\n            for (int u = 0; u < n; ++u)\n                for (int v = u + 1; v < n; ++v) if (B[u][v])\n                    for (int w = v + 1; w < n; ++w)\n                        if (B[u][w] && B[v][w]) ++triH;\n\n            // distance to every code word\n            int bestDist = INT_MAX;\n            for (int i = 0; i < M; ++i) {\n                // L1 distance of sorted degree sequences\n                int d = 0;\n                for (int k = 0; k < n; ++k) {\n                    d += abs(sortedDeg[i][k] - sdH[k]);\n                    if (d >= bestDist) break;\n                }\n                // add triangle difference (weighted by n to make it comparable)\n                d += n * abs(tri[i] - triH);\n                if (d < bestDist) {\n                    bestDist = d;\n                    answer = i;\n                }\n            }\n        }\n\n        cout << answer << '\\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    long long w;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n\n    vector<Edge> edges(M);\n    vector<vector<pair<int,int>>> adj(N);          // (to , edge id)\n    for (int i = 0; i < M; ++i) {\n        int a, b;\n        long long w;\n        cin >> a >> b >> w;\n        --a; --b;\n        edges[i] = {a, b, w};\n        adj[a].push_back({b, i});\n        adj[b].push_back({a, i});\n    }\n    // read the coordinates, they are not needed\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        (void)x; (void)y;\n    }\n\n    const long long INF = (1LL << 60);\n\n    /* ----------------------------------------------------------\n       1.  Edge betweenness centrality (Brandes, weighted)\n       ---------------------------------------------------------- */\n    vector<double> ebc(M, 0.0);\n    vector<long long> dist(N);\n    vector<double> sigma(N), delta(N);\n    vector<vector<pair<int,int>>> pred(N);\n    vector<int> order(N);\n\n    for (int s = 0; s < N; ++s) {\n        fill(dist.begin(), dist.end(), INF);\n        fill(sigma.begin(), sigma.end(), 0.0);\n        for (int i = 0; i < N; ++i) pred[i].clear();\n\n        priority_queue<pair<long long,int>, vector<pair<long long,int>>, greater<pair<long long,int>>> pq;\n        dist[s] = 0;\n        sigma[s] = 1.0;\n        pq.emplace(0, s);\n\n        while (!pq.empty()) {\n            auto [d, v] = pq.top(); pq.pop();\n            if (d != dist[v]) continue;\n            for (auto [to, eid] : adj[v]) {\n                long long nd = d + edges[eid].w;\n                if (dist[to] > nd) {\n                    dist[to] = nd;\n                    sigma[to] = sigma[v];\n                    pred[to].clear();\n                    pred[to].emplace_back(v, eid);\n                    pq.emplace(nd, to);\n                } else if (dist[to] == nd) {\n                    sigma[to] += sigma[v];\n                    pred[to].emplace_back(v, eid);\n                }\n            }\n        }\n\n        // vertices in decreasing order of distance\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(),\n             [&](int a, int b){ return dist[a] > dist[b]; });\n\n        fill(delta.begin(), delta.end(), 0.0);\n\n        for (int v : order) {\n            if (dist[v] == INF) continue;\n            for (auto [u, eid] : pred[v]) {\n                double coeff = sigma[u] / sigma[v];\n                double contrib = coeff * (1.0 + delta[v]);\n                ebc[eid] += contrib;\n                delta[u] += contrib;\n            }\n        }\n    }\n\n    for (int i = 0; i < M; ++i) ebc[i] *= 0.5;          // undirected\n\n    /* ----------------------------------------------------------\n       2.  Score of an edge (here only betweenness)\n       ---------------------------------------------------------- */\n    vector<double> score(M);\n    for (int i = 0; i < M; ++i) score[i] = ebc[i];      // * edges[i].w possible\n\n    /* ----------------------------------------------------------\n       3.  Greedy LPT assignment, several random restarts\n       ---------------------------------------------------------- */\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    vector<int> best_assign(M);\n    double best_obj = 1e100;\n    vector<int> order_edges(M);\n    iota(order_edges.begin(), order_edges.end(), 0);\n\n    int restarts = 5;                     // enough, can be increased if time permits\n    for (int rep = 0; rep < restarts; ++rep) {\n        shuffle(order_edges.begin(), order_edges.end(), rng);\n        vector<int> assign(M, -1);\n        vector<double> day_sum(D, 0.0);\n        vector<int> day_cnt(D, 0);\n\n        for (int eid : order_edges) {\n            // choose a day with free capacity and minimal current sum\n            int best_day = -1;\n            double best_val = 1e200;\n            for (int d = 0; d < D; ++d) {\n                if (day_cnt[d] >= K) continue;\n                if (day_sum[d] < best_val) {\n                    best_val = day_sum[d];\n                    best_day = d;\n                }\n            }\n            // it is guaranteed that such a day exists\n            assign[eid] = best_day;\n            day_sum[best_day] += score[eid];\n            day_cnt[best_day]++;\n        }\n\n        double obj = 0.0;\n        for (int d = 0; d < D; ++d) obj += day_sum[d] * day_sum[d];\n        if (obj < best_obj) {\n            best_obj = obj;\n            best_assign = assign;\n        }\n    }\n\n    /* ----------------------------------------------------------\n       4.  Simple hill climbing (improves the surrogate)\n       ---------------------------------------------------------- */\n    vector<int> assign = best_assign;\n    vector<double> day_sum(D, 0.0);\n    vector<int> day_cnt(D, 0);\n    for (int e = 0; e < M; ++e) {\n        int d = assign[e];\n        day_sum[d] += score[e];\n        day_cnt[d]++;\n    }\n\n    uniform_int_distribution<int> edge_dist(0, M - 1);\n    uniform_int_distribution<int> day_dist(0, D - 1);\n    const int HILL_ITER = 20000;          // works well, can be tuned\n    for (int it = 0; it < HILL_ITER; ++it) {\n        int e = edge_dist(rng);\n        int cur = assign[e];\n        if (day_cnt[cur] == 0) continue; // should never happen\n\n        // look for a different day with free capacity\n        int nd = day_dist(rng);\n        if (nd == cur || day_cnt[nd] >= K) continue;\n\n        double cur_sum = day_sum[cur];\n        double new_sum = day_sum[nd];\n        double old_contrib = cur_sum * cur_sum + new_sum * new_sum;\n        double new_contrib = (cur_sum - score[e]) * (cur_sum - score[e]) +\n                             (new_sum + score[e]) * (new_sum + score[e]);\n        if (new_contrib < old_contrib - 1e-12) {\n            // accept move\n            assign[e] = nd;\n            day_sum[cur] -= score[e];\n            day_sum[nd] += score[e];\n            day_cnt[cur]--;\n            day_cnt[nd]++;\n        }\n    }\n\n    /* ----------------------------------------------------------\n       5.  Output\n       ---------------------------------------------------------- */\n    for (int i = 0; i < M; ++i) {\n        if (i) cout << ' ';\n        cout << assign[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    \n    int D;\n    if (!(cin >> D)) return 0;\n\n    // read silhouettes in the correct order\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    // assign to arrays f[2] and r[2]\n    vector<string> f[2], r[2];\n    f[0] = f1; r[0] = r1;\n    f[1] = f2; r[1] = r2;\n\n    // data for both objects\n    vector<vector<int>> X[2], Y[2];\n    vector<vector<pair<int,int>>> intX[2], intY[2];\n    for (int i = 0; i < 2; ++i) {\n        X[i].assign(D, {});\n        Y[i].assign(D, {});\n        intX[i].assign(D, {});\n        intY[i].assign(D, {});\n        for (int z = 0; z < D; ++z) {\n            for (int x = 0; x < D; ++x)\n                if (f[i][z][x] == '1') X[i][z].push_back(x);\n            for (int y = 0; y < D; ++y)\n                if (r[i][z][y] == '1') Y[i][z].push_back(y);\n            // intervals of 1s in f\n            const string &sf = f[i][z];\n            for (int x = 0; x < D; ) {\n                if (sf[x] == '0') { ++x; continue; }\n                int s = x;\n                while (x < D && sf[x] == '1') ++x;\n                int e = x - 1;\n                intX[i][z].push_back({s, e});\n            }\n            // intervals of 1s in r\n            const string &sr = r[i][z];\n            for (int y = 0; y < D; ) {\n                if (sr[y] == '0') { ++y; continue; }\n                int s = y;\n                while (y < D && sr[y] == '1') ++y;\n                int e = y - 1;\n                intY[i][z].push_back({s, e});\n            }\n        }\n    }\n\n    // count bars for each orientation\n    vector<int> cntV[2], cntH[2];\n    cntV[0].assign(D+1, 0); cntV[1].assign(D+1, 0);\n    cntH[0].assign(D+1, 0); cntH[1].assign(D+1, 0);\n    for (int i = 0; i < 2; ++i) {\n        for (int z = 0; z < D; ++z) {\n            // vertical bars (use Y intervals)\n            for (auto &pr : intY[i][z]) {\n                int len = pr.second - pr.first + 1;\n                cntV[i][len] += (int)X[i][z].size();\n            }\n            // horizontal bars (use X intervals)\n            for (auto &pr : intX[i][z]) {\n                int len = pr.second - pr.first + 1;\n                cntH[i][len] += (int)Y[i][z].size();\n            }\n        }\n    }\n\n    // choose the best orientation (both objects must use the same)\n    double bestScore = 1e100;\n    int bestO = -1; // 0 = vertical, 1 = horizontal\n    for (int o = 0; o < 2; ++o) {\n        const vector<int> &a = (o ? cntH[0] : cntV[0]);\n        const vector<int> &b = (o ? cntH[1] : cntV[1]);\n        double score = 0.0;\n        for (int L = 1; L <= D; ++L) {\n            int s = min(a[L], b[L]);\n            int diff = abs(a[L] - b[L]);\n            score += diff * L + (double)s / L;\n        }\n        if (score < bestScore) {\n            bestScore = score;\n            bestO = o;\n        }\n    }\n\n    // final counts according to the chosen orientation\n    vector<int> aCnt = (bestO ? cntH[0] : cntV[0]);\n    vector<int> bCnt = (bestO ? cntH[1] : cntV[1]);\n\n    // create block IDs\n    vector<vector<int>> sharedId(D+1), only1Id(D+1), only2Id(D+1);\n    int totalBlocks = 0;\n    for (int L = 1; L <= D; ++L) {\n        int s = min(aCnt[L], bCnt[L]);\n        for (int k = 0; k < s; ++k) sharedId[L].push_back(++totalBlocks);\n        for (int k = 0; k < aCnt[L] - s; ++k) only1Id[L].push_back(++totalBlocks);\n        for (int k = 0; k < bCnt[L] - s; ++k) only2Id[L].push_back(++totalBlocks);\n    }\n\n    // 3D output arrays (flat)\n    vector<int> b1(D*D*D, 0), b2(D*D*D, 0);\n    auto index = [&](int x, int y, int z) { return x*D*D + y*D + z; };\n\n    // ----- place object 1 -----\n    vector<int> ptrS(D+1, 0), ptr1(D+1, 0);\n    if (bestO == 0) { // vertical\n        for (int z = 0; z < D; ++z) {\n            for (auto &pr : intY[0][z]) {\n                int len = pr.second - pr.first + 1;\n                int y1 = pr.first, y2 = pr.second;\n                for (int x : X[0][z]) {\n                    int id;\n                    if (ptrS[len] < (int)sharedId[len].size())\n                        id = sharedId[len][ptrS[len]++];\n                    else\n                        id = only1Id[len][ptr1[len]++];\n                    for (int y = y1; y <= y2; ++y)\n                        b1[index(x, y, z)] = id;\n                }\n            }\n        }\n    } else { // horizontal\n        for (int z = 0; z < D; ++z) {\n            for (auto &pr : intX[0][z]) {\n                int len = pr.second - pr.first + 1;\n                int x1 = pr.first, x2 = pr.second;\n                for (int y : Y[0][z]) {\n                    int id;\n                    if (ptrS[len] < (int)sharedId[len].size())\n                        id = sharedId[len][ptrS[len]++];\n                    else\n                        id = only1Id[len][ptr1[len]++];\n                    for (int x = x1; x <= x2; ++x)\n                        b1[index(x, y, z)] = id;\n                }\n            }\n        }\n    }\n\n    // ----- place object 2 (same orientation as object 1) -----\n    vector<int> ptrS2(D+1, 0), ptr2(D+1, 0);\n    if (bestO == 0) { // vertical\n        for (int z = 0; z < D; ++z) {\n            for (auto &pr : intY[1][z]) {\n                int len = pr.second - pr.first + 1;\n                int y1 = pr.first, y2 = pr.second;\n                for (int x : X[1][z]) {\n                    int id;\n                    if (ptrS2[len] < (int)sharedId[len].size())\n                        id = sharedId[len][ptrS2[len]++];\n                    else\n                        id = only2Id[len][ptr2[len]++];\n                    for (int y = y1; y <= y2; ++y)\n                        b2[index(x, y, z)] = id;\n                }\n            }\n        }\n    } else { // horizontal\n        for (int z = 0; z < D; ++z) {\n            for (auto &pr : intX[1][z]) {\n                int len = pr.second - pr.first + 1;\n                int x1 = pr.first, x2 = pr.second;\n                for (int y : Y[1][z]) {\n                    int id;\n                    if (ptrS2[len] < (int)sharedId[len].size())\n                        id = sharedId[len][ptrS2[len]++];\n                    else\n                        id = only2Id[len][ptr2[len]++];\n                    for (int x = x1; x <= x2; ++x)\n                        b2[index(x, y, z)] = id;\n                }\n            }\n        }\n    }\n\n    // ----- output -----\n    cout << totalBlocks << '\\n';\n    for (int i = 0; i < D*D*D; ++i) {\n        if (i) cout << ' ';\n        cout << b1[i];\n    }\n    cout << '\\n';\n    for (int i = 0; i < D*D*D; ++i) {\n        if (i) cout << ' ';\n        cout << b2[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {int u, v, w;};\n\nint find(vector<int>& parent, int x) {\n    while (parent[x] != x) {\n        parent[x] = parent[parent[x]];\n        x = parent[x];\n    }\n    return x;\n}\n\nbool unite(vector<int>& parent, vector<int>& rankv, int x, int y) {\n    x = find(parent, x);\n    y = find(parent, y);\n    if (x == y) return false;\n    if (rankv[x] < rankv[y]) swap(x, y);\n    parent[y] = x;\n    if (rankv[x] == rankv[y]) rankv[x]++;\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n    \n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; ++i) cin >> x[i] >> y[i];\n    \n    vector<Edge> edges(M);\n    for (int j = 0; j < M; ++j) {\n        cin >> edges[j].u >> edges[j].v >> edges[j].w;\n        edges[j].u--;\n        edges[j].v--;\n    }\n    \n    vector<int> a(K), b(K);\n    for (int i = 0; i < K; ++i) cin >> a[i] >> b[i];\n    \n    // Build MST (Kruskal)\n    vector<int> parent(N), rankv(N, 0);\n    for (int i = 0; i < N; ++i) parent[i] = i;\n    \n    vector<int> order(M);\n    for (int i = 0; i < M; ++i) order[i] = i;\n    sort(order.begin(), order.end(), [&](int i, int j) { return edges[i].w < edges[j].w; });\n    \n    vector<int> tree_edges;\n    tree_edges.reserve(N - 1);\n    for (int idx : order) {\n        if (unite(parent, rankv, edges[idx].u, edges[idx].v)) {\n            tree_edges.push_back(idx);\n            if ((int)tree_edges.size() == N - 1) break;\n        }\n    }\n    \n    // Mark included vertices (use vector<int> instead of vector<bool>)\n    vector<int> in_tree(N, 0);\n    in_tree[0] = 1;\n    for (int idx : tree_edges) {\n        in_tree[edges[idx].u] = 1;\n        in_tree[edges[idx].v] = 1;\n    }\n    \n    // Greedy assignment with cost minimization\n    vector<int> P(N, 0);\n    vector<double> station_radius(N, 0.0);\n    \n    for (int k = 0; k < K; ++k) {\n        long long best_cost_incr = (1LL << 60);\n        int best_station = -1;\n        double best_dist = 0.0;\n        \n        for (int i = 0; i < N; ++i) {\n            if (!in_tree[i]) continue;\n            \n            long long dx = (long long)a[k] - x[i];\n            long long dy = (long long)b[k] - y[i];\n            double dist = sqrt((double)(dx * dx + dy * dy));\n            \n            double new_radius = max(station_radius[i], dist);\n            long long old_cost = (long long)ceil(station_radius[i]) * (long long)ceil(station_radius[i]);\n            long long new_cost = (long long)ceil(new_radius) * (long long)ceil(new_radius);\n            long long cost_incr = new_cost - old_cost;\n            \n            if (cost_incr < best_cost_incr) {\n                best_cost_incr = cost_incr;\n                best_station = i;\n                best_dist = dist;\n            }\n        }\n        \n        if (best_station != -1) {\n            station_radius[best_station] = max(station_radius[best_station], best_dist);\n        }\n    }\n    \n    // Convert to P_i values\n    for (int i = 0; i < N; ++i) {\n        if (station_radius[i] > 0.0) {\n            P[i] = min(5000, (int)ceil(station_radius[i]));\n        }\n    }\n    \n    // Output\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << \" \";\n        cout << P[i];\n    }\n    cout << \"\\n\";\n    \n    vector<int> B(M, 0);\n    for (int idx : tree_edges) B[idx] = 1;\n    for (int j = 0; j < M; ++j) {\n        if (j) cout << \" \";\n        cout << B[j];\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 30;                     // number of rows\nusing Grid = array<array<int, N>, N>;\n\nstruct Swap {\n    int x1, y1, x2, y2;\n};\n\n/* -------------------------------------------------------------\n   perform the sift\u2011down algorithm on one row using the given order.\n   out : list of performed swaps.\n   ------------------------------------------------------------- */\nvoid siftDown(Grid &g, vector<Swap> &out,\n              int row, const vector<int> &order) {\n    for (int y : order) {\n        int curX = row, curY = y;\n        while (curX < N - 1) {                     // while cur has children\n            int leftX  = curX + 1;\n            int leftY  = curY;\n            int rightX = curX + 1;\n            int rightY = curY + 1;\n\n            // the smaller child\n            int childX, childY;\n            if (g[leftX][leftY] < g[rightX][rightY]) {\n                childX = leftX; childY = leftY;\n            } else {\n                childX = rightX; childY = rightY;\n            }\n\n            if (g[childX][childY] < g[curX][curY]) {\n                // swap and continue downwards\n                swap(g[curX][curY], g[childX][childY]);\n                out.push_back({curX, curY, childX, childY});\n                curX = childX;\n                curY = childY;\n            } else {\n                break; // already smaller than both children\n            }\n        }\n    }\n}\n\n/* -------------------------------------------------------------\n   count how many parent\u2011child pairs violate the required order\n   ------------------------------------------------------------- */\nint countViolations(const Grid &g) {\n    int bad = 0;\n    for (int x = 0; x < N - 1; ++x)\n        for (int y = 0; y <= x; ++y) {\n            int v = g[x][y];\n            if (v > g[x + 1][y])   ++bad;\n            if (v > g[x + 1][y + 1]) ++bad;\n        }\n    return bad;\n}\n\n/* -------------------------------------------------------------\n   run the heapify algorithm with a given row ordering.\n   orderRows : for each row (index = row) a permutation of 0..row.\n   ------------------------------------------------------------- */\nvoid runWithOrders(const Grid &init, Grid &cur,\n                   vector<Swap> &out,\n                   const vector<vector<int>> &orderRows) {\n    cur = init;\n    out.clear();\n    for (int x = N - 2; x >= 0; --x)\n        siftDown(cur, out, x, orderRows[x]);\n}\n\n/* ------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    Grid orig{};\n    for (int x = 0; x < N; ++x)\n        for (int y = 0; y <= x; ++y)\n            cin >> orig[x][y];\n\n    vector<Swap> bestSwaps;\n    int bestK = 1'000'000;               // larger than any possible length\n    Grid cur;\n    vector<Swap> curSwaps;\n\n    // ---- 1) deterministic left\u2011to\u2011right (baseline) -----------------------\n    {\n        vector<vector<int>> orderRows(N);\n        for (int x = 0; x < N; ++x) {\n            orderRows[x].resize(x + 1);\n            iota(orderRows[x].begin(), orderRows[x].end(), 0);\n        }\n        runWithOrders(orig, cur, curSwaps, orderRows);\n        if (countViolations(cur) == 0 && (int)curSwaps.size() < bestK) {\n            bestK = (int)curSwaps.size();\n            bestSwaps = curSwaps;\n        }\n    }\n\n    // ---- 1b) deterministic right\u2011to\u2011left ---------------------------------\n    {\n        vector<vector<int>> orderRows(N);\n        for (int x = 0; x < N; ++x) {\n            orderRows[x].resize(x + 1);\n            for (int y = 0; y <= x; ++y) orderRows[x][y] = x - y; // reverse order\n        }\n        runWithOrders(orig, cur, curSwaps, orderRows);\n        if (countViolations(cur) == 0 && (int)curSwaps.size() < bestK) {\n            bestK = (int)curSwaps.size();\n            bestSwaps = curSwaps;\n        }\n    }\n\n    // ---- 2) deterministic \u201clargest violation first\u201d -----------------------\n    {\n        vector<vector<int>> orderRows(N);\n        for (int x = 0; x < N; ++x) orderRows[x].resize(x + 1);\n        cur = orig;\n        curSwaps.clear();\n        for (int x = N - 2; x >= 0; --x) {\n            vector<pair<int,int>> diffY; // (diff , y)\n            diffY.reserve(x + 1);\n            for (int y = 0; y <= x; ++y) {\n                int left  = cur[x + 1][y];\n                int right = cur[x + 1][y + 1];\n                int mn    = min(left, right);\n                int diff  = cur[x][y] - mn;\n                diffY.emplace_back(diff, y);\n            }\n            sort(diffY.begin(), diffY.end(),\n                 [](const auto &a, const auto &b){ return a.first > b.first; });\n            orderRows[x].clear();\n            for (auto &p : diffY) orderRows[x].push_back(p.second);\n            siftDown(cur, curSwaps, x, orderRows[x]);\n        }\n        if (countViolations(cur) == 0 && (int)curSwaps.size() < bestK) {\n            bestK = (int)curSwaps.size();\n            bestSwaps = curSwaps;\n        }\n    }\n\n    // ---- 3) many random runs ---------------------------------------------\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    for (int iter = 0; iter < 1000; ++iter) {          // increased from 500\n        vector<vector<int>> orderRows(N);\n        for (int x = 0; x < N; ++x) {\n            orderRows[x].resize(x + 1);\n            iota(orderRows[x].begin(), orderRows[x].end(), 0);\n            if (x <= N - 2)                     // rows that really need a shuffle\n                shuffle(orderRows[x].begin(), orderRows[x].end(), rng);\n        }\n        runWithOrders(orig, cur, curSwaps, orderRows);\n        if (countViolations(cur) == 0 && (int)curSwaps.size() < bestK) {\n            bestK = (int)curSwaps.size();\n            bestSwaps = curSwaps;\n        }\n        if (bestK <= 2000) break;   // very good solution \u2013 stop early\n    }\n\n    // ---- output ------------------------------------------------------------\n    cout << bestK << '\\n';\n    for (const auto &s : bestSwaps)\n        cout << s.x1 << ' ' << s.y1 << ' ' << s.x2 << ' ' << s.y2 << '\\n';\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int SZ = 9;                     // board size, fixed by the statement\n\n/* global data */\nint M;                                 // number of containers\nvector<vector<bool>> obstacle;         // true for an obstacle\nvector<vector<bool>> occupied;         // true if a container is stored here\nvector<vector<int>> value;             // transport number, -1 if none\n\n/* auxiliary directions */\nconst int dr[4] = {1, -1, 0, 0};\nconst int dc[4] = {0, 0, 1, -1};\n\n/* --------------------------------------------------------------- */\n/* count empty neighbours of a cell (not obstacles, not occupied) */\nint count_empty_neighbors(int r, int c, const vector<vector<bool>>& occ){\n    int cnt = 0;\n    for (int d=0; d<4; ++d){\n        int nr = r + dr[d];\n        int nc = c + dc[d];\n        if (nr<0||nr>=SZ||nc<0||nc>=SZ) continue;\n        if (obstacle[nr][nc]) continue;\n        if (occ[nr][nc]) continue;\n        ++cnt;\n    }\n    return cnt;\n}\n\n/* --------------------------------------------------------------- */\n/* BFS from the entrance over empty squares.\n   fills reachable[][] , dist[][] and returns the number of reachable empty squares\n   (entrance is counted as empty).                                 */\nint bfs_reachable(vector<vector<bool>>& reachable,\n                  vector<vector<int>>& dist,\n                  const vector<vector<bool>>& occ)\n{\n    reachable.assign(SZ, vector<bool>(SZ, false));\n    dist.assign(SZ, vector<int>(SZ, -1));\n    queue<pair<int,int>> q;\n\n    int ent_r = 0, ent_c = (SZ-1)/2;\n    reachable[ent_r][ent_c] = true;\n    dist[ent_r][ent_c] = 0;\n    q.emplace(ent_r, ent_c);\n    int cnt = 1;                     // entrance itself\n\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];\n            int nc = c + dc[d];\n            if (nr<0||nr>=SZ||nc<0||nc>=SZ) continue;\n            if (obstacle[nr][nc]) continue;\n            if (occ[nr][nc]) continue;                 // not empty\n            if (!reachable[nr][nc]){\n                reachable[nr][nc] = true;\n                dist[nr][nc] = dist[r][c] + 1;\n                ++cnt;\n                q.emplace(nr,nc);\n            }\n        }\n    }\n    return cnt;          // total empty squares reachable (including entrance)\n}\n\n/* --------------------------------------------------------------- */\n/* test whether a reachable empty square (tr,tc) is a cut vertex\n   (i.e. after occupying it the remaining empty squares stay connected) */\nbool is_safe(int tr, int tc,\n             const vector<vector<bool>>& occ,\n             int total_empty)\n{\n    // a second BFS, this time treating (tr,tc) as blocked\n    vector<vector<bool>> reach2(SZ, vector<bool>(SZ,false));\n    queue<pair<int,int>> q;\n    int ent_r = 0, ent_c = (SZ-1)/2;\n    reach2[ent_r][ent_c] = true;\n    q.emplace(ent_r, ent_c);\n    int cnt = 1;\n\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];\n            int nc = c + dc[d];\n            if (nr<0||nr>=SZ||nc<0||nc>=SZ) continue;\n            if (obstacle[nr][nc]) continue;\n            if (occ[nr][nc]) continue;\n            if (nr==tr && nc==tc) continue;          // the blocked cell\n            if (!reach2[nr][nc]){\n                reach2[nr][nc] = true;\n                ++cnt;\n                q.emplace(nr,nc);\n            }\n        }\n    }\n    // after blocking (tr,tc) we must still reach all other empties\n    return cnt == total_empty - 1;\n}\n\n/* --------------------------------------------------------------- */\n/* pick a square for the next container \u2013 prefer leaves (degree\u202f1) */\npair<int,int> choose_square(const vector<vector<bool>>& occ)\n{\n    vector<vector<bool>> reachable;\n    vector<vector<int>> dist;\n    int total_empty = bfs_reachable(reachable, dist, occ);\n\n    vector<pair<int,int>> safe_list, leaf_list;\n\n    for (int r=0; r<SZ; ++r){\n        for (int c=0; c<SZ; ++c){\n            if (!reachable[r][c]) continue;               // not reachable\n            if (occ[r][c]) continue;                       // already occupied\n            if (r==0 && c==(SZ-1)/2) continue;              // entrance\n            // articulation test\n            if (!is_safe(r,c, occ, total_empty)) continue;\n            safe_list.emplace_back(r,c);\n            if (count_empty_neighbors(r,c, occ) == 1)\n                leaf_list.emplace_back(r,c);\n        }\n    }\n\n    const vector<pair<int,int>>& src = leaf_list.empty() ? safe_list : leaf_list;\n    int best_dist = -1;\n    pair<int,int> best{-1,-1};\n    for (auto [r,c] : src){\n        if (dist[r][c] > best_dist){\n            best_dist = dist[r][c];\n            best = {r,c};\n        } else if (dist[r][c]==best_dist && best.first!=-1){\n            if (r < best.first || (r==best.first && c < best.second))\n                best = {r,c};\n        }\n    }\n\n    // normally src is non\u2011empty \u2013 otherwise a fallback (should not happen)\n    if (!src.empty()) return best;\n    // ultimate fallback: any reachable cell\n    for (int r=0; r<SZ; ++r)\n        for (int c=0; c<SZ; ++c)\n            if (reachable[r][c] && !occ[r][c] && !(r==0 && c==(SZ-1)/2))\n                return {r,c};\n    return {-1,-1}; // never reached\n}\n\n/* --------------------------------------------------------------- */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D_input, N;\n    if(!(cin>>D_input>>N)) return 0;       // D_input is always 9, we ignore it\n    obstacle.assign(SZ, vector<bool>(SZ,false));\n    for (int i=0;i<N;++i){\n        int ri,rj; cin>>ri>>rj;\n        obstacle[ri][rj]=true;\n    }\n\n    occupied.assign(SZ, vector<bool>(SZ,false));\n    value.assign(SZ, vector<int>(SZ,-1));\n\n    M = SZ*SZ - 1 - N;\n\n    vector<pair<int,int>> container_position(M);   // by transport number\n\n    /* ---------- placement ---------- */\n    for (int step=0; step<M; ++step){\n        int t; cin>>t;\n        auto pos = choose_square(occupied);\n        int r = pos.first, c = pos.second;\n        // place the container\n        occupied[r][c] = true;\n        value[r][c] = t;\n        container_position[t] = {r,c};\n        cout << r << ' ' << c << '\\n';\n        cout.flush();\n    }\n\n    /* ---------- removal ---------- */\n    vector<pair<int,int>> removal_order;\n    removal_order.reserve(M);\n    int removed = 0;\n    while (removed < M){\n        vector<vector<bool>> reachableEmpty;\n        vector<vector<int>> dummy;\n        bfs_reachable(reachableEmpty, dummy, occupied);   // empty squares only\n\n        // collect removable containers\n        int best_val = INT_MAX;\n        int br=-1, bc=-1;\n        for (int r=0; r<SZ; ++r){\n            for (int c=0; c<SZ; ++c){\n                if (!occupied[r][c]) continue;               // no container here\n                // is it reachable ?   (any neighbour reachableEmpty)\n                bool ok = false;\n                for (int d=0; d<4; ++d){\n                    int nr = r+dr[d];\n                    int nc = c+dc[d];\n                    if (nr<0||nr>=SZ||nc<0||nc>=SZ) continue;\n                    if (reachableEmpty[nr][nc]) { ok=true; break; }\n                }\n                if (!ok) continue;\n                if (value[r][c] < best_val){\n                    best_val = value[r][c];\n                    br=r; bc=c;\n                }\n            }\n        }\n        // remove the chosen container\n        removal_order.emplace_back(br,bc);\n        occupied[br][bc] = false;\n        value[br][bc] = -1;\n        ++removed;\n    }\n\n    for (auto [r,c] : removal_order){\n        cout << r << ' ' << c << '\\n';\n    }\n    cout.flush();\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\n#include <array>\nusing namespace std;\n\nconst int N = 50;\nconst int M = 100;\n\nint n, m;\nint orig[N][N];\n\n/* --------------------------------------------------------------- */\n/*  adjacency of the original map (including colour 0)            */\nbool orig_adj[M + 1][M + 1];                 // symmetric, 0..m\nvector<array<int,6>> adj_pairs;               // c,d,i1,j1,i2,j2  (both >0)\n\n/* --------------------------------------------------------------- */\n/*  colour sets                                                   */\nvector<pair<int,int>> cells_of_color[M + 1];   // 1..m\nbool is_border_colour[M + 1];\nbool is_interior_colour[M + 1];\n\n/* --------------------------------------------------------------- */\n/*  required cells for each colour (see section 2)                */\nbool required_pos[N][N];\nvector<pair<int,int>> required[M + 1];\n\n/* --------------------------------------------------------------- */\n/*  cells that finally stay coloured                              */\nbool keep[N][N];\n\n/* --------------------------------------------------------------- */\n/*  utility: neighbour directions                                  */\nconst int dy[4] = { -1, 1, 0, 0 };\nconst int dx[4] = { 0, 0, -1, 1 };\n\n/* --------------------------------------------------------------- */\n/*  full validation of a produced map                            */\nbool validate(const int out[N][N])\n{\n    /* 1. each colour appears at least once and is connected       */\n    int cnt_colour[M+1];\n    fill(begin(cnt_colour), end(cnt_colour), 0);\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++) {\n        int c = out[i][j];\n        if (c<0 || c>m) return false;\n        ++cnt_colour[c];\n    }\n    for (int c=1;c<=m;c++) if (cnt_colour[c]==0) return false;\n\n    // BFS for each colour\n    bool visited[N][N];\n    for (int c=1;c<=m;c++) {\n        memset(visited,0,sizeof(visited));\n        // find first cell of this colour\n        int sx=-1,sy=-1;\n        for (int i=0;i<n && sx==-1;i++) for (int j=0;j<n;j++)\n            if (out[i][j]==c) { sx=i; sy=j; break; }\n        if (sx==-1) return false;               // should not happen\n        queue<pair<int,int>> q;\n        q.emplace(sx,sy);\n        visited[sx][sy]=true;\n        int reach=0;\n        while(!q.empty()){\n            auto [y,x]=q.front(); q.pop();\n            ++reach;\n            for (int dir=0;dir<4;dir++){\n                int ny=y+dy[dir], nx=x+dx[dir];\n                if (ny<0||ny>=n||nx<0||nx>=n) continue;\n                if (out[ny][nx]==c && !visited[ny][nx]){\n                    visited[ny][nx]=true;\n                    q.emplace(ny,nx);\n                }\n            }\n        }\n        if (reach!=cnt_colour[c]) return false;   // not connected\n    }\n\n    /* 2. zero cells are connected with the outside               */\n    memset(visited,0,sizeof(visited));\n    queue<pair<int,int>> qz;\n    // start from every border zero cell\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++) {\n        if (out[i][j]==0 &&\n            (i==0||i==n-1||j==0||j==n-1)){\n            visited[i][j]=true;\n            qz.emplace(i,j);\n        }\n    }\n    while(!qz.empty()){\n        auto [y,x]=qz.front(); qz.pop();\n        for (int dir=0;dir<4;dir++){\n            int ny=y+dy[dir], nx=x+dx[dir];\n            if (ny<0||ny>=n||nx<0||nx>=n) continue;\n            if (out[ny][nx]==0 && !visited[ny][nx]){\n                visited[ny][nx]=true;\n                qz.emplace(ny,nx);\n            }\n        }\n    }\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++)\n        if (out[i][j]==0 && !visited[i][j]) return false;   // isolated zero\n\n    /* 3. adjacency matrix exactly the original one                */\n    bool out_adj[M+1][M+1];\n    memset(out_adj,0,sizeof(out_adj));\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++) {\n        int c = out[i][j];\n        for (int dir=0;dir<4;dir++){\n            int ni=i+dy[dir], nj=j+dx[dir];\n            if (ni<0||ni>=n||nj<0||nj>=n){\n                // outside -> colour 0\n                out_adj[c][0]=out_adj[0][c]=true;\n                continue;\n            }\n            int d = out[ni][nj];\n            if (c!=d){\n                out_adj[c][d]=out_adj[d][c]=true;\n            }\n        }\n    }\n    for (int c=0;c<=m;c++) for (int d=c;d<=m;d++)\n        if (orig_adj[c][d]!=out_adj[c][d]) return false;\n\n    return true;\n}\n\n/* --------------------------------------------------------------- */\n/*  minimal neighbour set for interior colours                    */\nvoid compute_minimal_neighbours()\n{\n    // mark all cells that are neighbours of an interior colour\n    static bool neigh_of_interior[N][N];\n    memset(neigh_of_interior,0,sizeof(neigh_of_interior));\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++) {\n        if (is_interior_colour[orig[i][j]]){\n            for (int dir=0;dir<4;dir++){\n                int ni=i+dy[dir], nj=j+dx[dir];\n                if (ni<0||ni>=n||nj<0||nj>=n) continue;\n                neigh_of_interior[ni][nj]=true;\n            }\n        }\n    }\n\n    // process each interior colour independently\n    for (int col=1; col<=m; ++col) if (is_interior_colour[col]){\n        // list of interior cells of this colour\n        vector<pair<int,int>> interior_cells;\n        for (auto &p : cells_of_color[col])\n            interior_cells.push_back(p);\n        // list of candidate neighbour cells (belong to border colours)\n        vector<pair<int,int>> candidates;\n        for (auto &p : interior_cells){\n            int y=p.first, x=p.second;\n            for (int dir=0;dir<4;dir++){\n                int ny=y+dy[dir], nx=x+dx[dir];\n                if (ny<0||ny>=n||nx<0||nx>=n) continue;\n                if (orig[ny][nx]==col) continue;   // same colour\n                if (!required_pos[ny][nx])   // not already forced\n                    candidates.emplace_back(ny,nx);\n            }\n        }\n\n        // each (interior_cell, direction) is an element that must be covered\n        struct Need {\n            int y, x, dir;\n        };\n        vector<Need> needs;\n        for (auto &p : interior_cells){\n            int y=p.first, x=p.second;\n            for (int d=0; d<4; ++d)\n                needs.push_back({y,x,d});\n        }\n\n        // which neighbour cell covers which needs\n        vector<vector<int>> cover(candidates.size());\n        for (size_t i=0; i<candidates.size(); ++i){\n            int cy=candidates[i].first, cx=candidates[i].second;\n            for (size_t j=0; j<needs.size(); ++j){\n                int y=needs[j].y, x=needs[j].x, d=needs[j].dir;\n                int ny=y+dy[d], nx=x+dx[d];\n                if (ny==cy && nx==cx){\n                    cover[i].push_back(j);\n                }\n            }\n        }\n\n        // greedy set cover\n        vector<bool> covered(needs.size(), false);\n        bool progress=true;\n        while (progress){\n            progress=false;\n            int best=-1, bestCnt=0;\n            for (size_t i=0; i<candidates.size(); ++i){\n                int cnt=0;\n                for (int needIdx : cover[i])\n                    if (!covered[needIdx]) ++cnt;\n                if (cnt>bestCnt){\n                    bestCnt=cnt;\n                    best=i;\n                }\n            }\n            if (best!=-1){\n                int y=candidates[best].first, x=candidates[best].second;\n                required_pos[y][x]=true;\n                required[orig[y][x]].push_back({y,x});\n                for (int needIdx : cover[best]) covered[needIdx]=true;\n                progress=true;\n            }\n        }\n    }\n}\n\n/* --------------------------------------------------------------- */\n/*  Steiner tree for a border colour (MST on required nodes)       */\nvoid connect_border_colour_steiner(int col)\n{\n    // region = all cells of this colour in the original map\n    static bool inRegion[N][N];\n    for (auto &p : cells_of_color[col]) inRegion[p.first][p.second]=true;\n\n    // required cells of this colour\n    vector<pair<int,int>> req = required[col];\n    int k = req.size();\n    if (k<=1) { /* already connected */ for (auto &p : cells_of_color[col]) inRegion[p.first][p.second]=false; return; }\n\n    auto idx = [&](int y,int x){ return y*N + x; };\n    vector<int> srcIdx;\n    for (auto &p : req) srcIdx.push_back(idx(p.first, p.second));\n\n    // BFS from each required node, store distance and predecessor\n    vector<vector<int>> dist(k, vector<int>(N*N, -1));\n    vector<vector<int>> prv (k, vector<int>(N*N, -1));\n\n    for (int i=0;i<k;i++){\n        queue<int> q;\n        int start = srcIdx[i];\n        q.push(start);\n        dist[i][start]=0;\n        prv[i][start]=start;\n        while(!q.empty()){\n            int cur=q.front(); q.pop();\n            int cy=cur/N, cx=cur%N;\n            for (int dir=0;dir<4;dir++){\n                int ny=cy+dy[dir], nx=cx+dx[dir];\n                if (ny<0||ny>=n||nx<0||nx>=n) continue;\n                if (!inRegion[ny][nx]) continue;\n                int nid=idx(ny,nx);\n                if (dist[i][nid]==-1){\n                    dist[i][nid]=dist[i][cur]+1;\n                    prv[i][nid]=cur;\n                    q.push(nid);\n                }\n            }\n        }\n    }\n\n    // Build complete graph on required nodes (distances)\n    vector<vector<int>> d(k, vector<int>(k,0));\n    for (int i=0;i<k;i++)\n        for (int j=i+1;j<k;j++)\n            d[i][j]=d[j][i]=dist[i][srcIdx[j]];\n\n    // Prim's algorithm for MST\n    vector<bool> inMST(k,false);\n    vector<int> minDist(k, INT_MAX);\n    vector<int> parent(k,-1);\n    minDist[0]=0;\n    for (int i=0;i<k;i++){\n        int v=-1;\n        for (int j=0;j<k;j++) if (!inMST[j] && (v==-1 || minDist[j] < minDist[v])) v=j;\n        inMST[v]=true;\n        if (parent[v]!=-1){\n            int a=v, b=parent[v];\n            // add shortest path between a and b using predecessor of a\n            int cur = srcIdx[b];\n            while (cur != srcIdx[a]){\n                int y = cur/N, x = cur%N;\n                keep[y][x]=true;\n                cur = prv[a][cur];\n            }\n            // also mark the two endpoints themselves (they are already required)\n            keep[req[a].first][req[a].second]=true;\n            keep[req[b].first][req[b].second]=true;\n        }\n        for (int j=0;j<k;j++){\n            if (!inMST[j] && d[v][j] < minDist[j]){\n                minDist[j]=d[v][j];\n                parent[j]=v;\n            }\n        }\n    }\n\n    // clean up\n    for (auto &p : cells_of_color[col]) inRegion[p.first][p.second]=false;\n}\n\n/* --------------------------------------------------------------- */\n/*  leaf pruning for border colours \u2013 delete non\u2011required leaves  */\nvoid leaf_prune(int out_grid[N][N])\n{\n    bool changed=true;\n    while (changed){\n        changed=false;\n        for (int c=1;c<=m;c++) if (is_border_colour[c]){\n            for (auto &p : cells_of_color[c]){\n                int y=p.first, x=p.second;\n                if (!keep[y][x] || required_pos[y][x]) continue;\n                // count kept neighbours of the same colour\n                int cnt=0;\n                for (int dir=0;dir<4;dir++){\n                    int ny=y+dy[dir], nx=x+dx[dir];\n                    if (ny<0||ny>=n||nx<0||nx>=n) continue;\n                    if (keep[ny][nx] && orig[ny][nx]==c) ++cnt;\n                }\n                if (cnt<=1){   // leaf\n                    int oldc = orig[y][x];\n                    out_grid[y][x]=0;\n                    keep[y][x]=false;\n                    if (validate(out_grid)){\n                        changed=true;\n                    } else {\n                        out_grid[y][x]=oldc;\n                        keep[y][x]=true;\n                    }\n                }\n            }\n        }\n    }\n}\n\n/* --------------------------------------------------------------- */\n/*  greedy deletion of non\u2011required cells                         */\nvoid greedy_deletion(int out_grid[N][N])\n{\n    mt19937 rng(123456);\n    bool changed=true;\n    int passes=0;\n    while (changed && passes<8){\n        changed=false;\n        vector<pair<int,int>> cand;\n        for (int i=0;i<n;i++) for (int j=0;j<n;j++)\n            if (keep[i][j] && !required_pos[i][j])\n                cand.emplace_back(i,j);\n        shuffle(cand.begin(), cand.end(), rng);\n        for (auto [y,x] : cand){\n            int oldcol = orig[y][x];\n            // try delete\n            out_grid[y][x]=0;\n            keep[y][x]=false;\n            if (validate(out_grid)){\n                changed=true;\n            } else {\n                // revert\n                out_grid[y][x]=oldcol;\n                keep[y][x]=true;\n            }\n        }\n        ++passes;\n    }\n}\n\n/* --------------------------------------------------------------- */\n/*  repair isolated zero pools                                   */\nvoid repair_isolated_zeros(int out_grid[N][N])\n{\n    bool visited[N][N];\n    memset(visited,0,sizeof(visited));\n    queue<pair<int,int>> q;\n    // start from border zeros\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++){\n        if (out_grid[i][j]==0 && (i==0||i==n-1||j==0||j==n-1)){\n            visited[i][j]=true;\n            q.emplace(i,j);\n        }\n    }\n    while(!q.empty()){\n        auto [y,x]=q.front(); q.pop();\n        for (int dir=0;dir<4;dir++){\n            int ny=y+dy[dir], nx=x+dx[dir];\n            if (ny<0||ny>=n||nx<0||nx>=n) continue;\n            if (out_grid[ny][nx]==0 && !visited[ny][nx]){\n                visited[ny][nx]=true;\n                q.emplace(ny,nx);\n            }\n        }\n    }\n    // revert isolated zeros\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++){\n        if (out_grid[i][j]==0 && !visited[i][j]){\n            out_grid[i][j]=orig[i][j];\n            keep[i][j]=true;          // not used any more, but keep consistent\n        }\n    }\n}\n\n/* --------------------------------------------------------------- */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if(!(cin>>n>>m)) return 0;\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++){\n        cin>>orig[i][j];\n        cells_of_color[orig[i][j]].push_back({i,j});\n        if (i==0||i==n-1||j==0||j==n-1) is_border_colour[orig[i][j]]=true;\n    }\n\n    /* ---- original adjacency ------------------------------------ */\n    memset(orig_adj,0,sizeof(orig_adj));\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++){\n        int c = orig[i][j];\n        for (int dir=0;dir<4;dir++){\n            int ni=i+dy[dir], nj=j+dx[dir];\n            if (ni<0||ni>=n||nj<0||nj>=n){\n                // outside -> colour 0\n                orig_adj[c][0]=orig_adj[0][c]=true;\n                continue;\n            }\n            int d = orig[ni][nj];\n            if (c!=d){\n                orig_adj[c][d]=orig_adj[d][c]=true;\n                // store pair (c,d) together with both cell positions\n                if (c<d)\n                    adj_pairs.push_back({{c,d,i,j,ni,nj}});\n                else\n                    adj_pairs.push_back({{d,c,ni,nj,i,j}});\n            }\n        }\n    }\n\n    /* ---- interior / border colours ----------------------------- */\n    for (int c=1;c<=m;c++) is_interior_colour[c]=!is_border_colour[c];\n\n    /* ---- minimal neighbour set for interior colours ------------ */\n    compute_minimal_neighbours();\n\n    /* ---- must_keep matrix (cells that may not become zero) ------ */\n    bool must_keep[N][N];\n    memset(must_keep,0,sizeof(must_keep));\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++) {\n        if (is_interior_colour[orig[i][j]]){\n            must_keep[i][j]=true;\n            for (int dir=0;dir<4;dir++){\n                int ni=i+dy[dir], nj=j+dx[dir];\n                if (ni<0||ni>=n||nj<0||nj>=n) continue;\n                must_keep[ni][nj]=true;\n            }\n        }\n    }\n\n    /* ---- required cells for border colours (border cell) -------- */\n    for (int c=1;c<=m;c++) if (is_border_colour[c]){\n        // if no required cell on the border exists yet, add one\n        for (auto &p : cells_of_color[c]){\n            int y=p.first, x=p.second;\n            if (y==0||y==n-1||x==0||x==n-1){\n                required_pos[y][x]=true;\n                required[c].push_back({y,x});\n                break;\n            }\n        }\n    }\n\n    /* ---- smarter border\u2011border edge handling -------------------- */\n    bool edge_used[M+1][M+1];\n    memset(edge_used,0,sizeof(edge_used));\n    // first try to reuse already kept cells\n    for (int c=1;c<=m;c++) if (is_border_colour[c])\n        for (int d=c+1;d<=m;d++) if (is_border_colour[d] && !edge_used[c][d]){\n            bool found=false;\n            for (auto &e : adj_pairs){\n                int a=e[0], b=e[1];\n                if (!((a==c && b==d) || (a==d && b==c))) continue;\n                int y1=e[2], x1=e[3], y2=e[4], x2=e[5];\n                if (must_keep[y1][x1] || must_keep[y2][x2] ||\n                    required_pos[y1][x1] || required_pos[y2][x2]){\n                    required_pos[y1][x1]=required_pos[y2][x2]=true;\n                    required[c].push_back({y1,x1});\n                    required[d].push_back({y2,x2});\n                    edge_used[c][d]=true;\n                    found=true;\n                    break;\n                }\n            }\n            if (found) continue;\n            // otherwise take the first pair\n            for (auto &e : adj_pairs){\n                int a=e[0], b=e[1];\n                if (!((a==c && b==d) || (a==d && b==c))) continue;\n                int y1=e[2], x1=e[3], y2=e[4], x2=e[5];\n                if (!required_pos[y1][x1]){\n                    required_pos[y1][x1]=true;\n                    required[c].push_back({y1,x1});\n                }\n                if (!required_pos[y2][x2]){\n                    required_pos[y2][x2]=true;\n                    required[d].push_back({y2,x2});\n                }\n                edge_used[c][d]=true;\n                break;\n            }\n        }\n\n    /* ---- build first keep set ---------------------------------- */\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++) keep[i][j]=must_keep[i][j];\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++)\n        if (required_pos[i][j]) keep[i][j]=true;\n\n    /* ---- Steiner connection for border colours ----------------- */\n    for (int c=1;c<=m;c++) if (is_border_colour[c])\n        connect_border_colour_steiner(c);\n\n    /* ---- initial map ------------------------------------------- */\n    int out_grid[N][N];\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++)\n        out_grid[i][j] = keep[i][j] ? orig[i][j] : 0;\n\n    clock_t start = clock();\n\n    /* ---- iterated refinement ----------------------------------- */\n    do {\n        greedy_deletion(out_grid);\n        leaf_prune(out_grid);\n        repair_isolated_zeros(out_grid);\n    } while (clock() - start < 1.8 * CLOCKS_PER_SEC);\n\n    /* ---- final output ------------------------------------------ */\n    for (int i=0;i<n;i++){\n        for (int j=0;j<n;j++){\n            if (j) cout << ' ';\n            cout << out_grid[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    // comparison_matrix[i][j]: 1 if i > j, -1 if i < j, 0 if unknown, 2 if equal\n    vector<vector<int>> comparison_matrix(N, vector<int>(N, 0));\n    vector<int> comparison_count(N, 0);\n    \n    for (int query = 0; query < Q; query++) {\n        // Find item with minimum comparisons\n        int i = min_element(comparison_count.begin(), comparison_count.end()) - comparison_count.begin();\n        \n        // Find another item to compare with, preferring not yet compared\n        int j = -1;\n        int min_other_count = INT_MAX;\n        \n        // First try: find an item not yet compared with i\n        for (int k = 0; k < N; k++) {\n            if (k != i && comparison_matrix[i][k] == 0 && comparison_count[k] < min_other_count) {\n                min_other_count = comparison_count[k];\n                j = k;\n            }\n        }\n        \n        // Second try: if no new pair, find any item with minimal comparisons\n        if (j == -1) {\n            for (int k = 0; k < N; k++) {\n                if (k != i && comparison_count[k] < min_other_count) {\n                    min_other_count = comparison_count[k];\n                    j = k;\n                }\n            }\n        }\n        \n        // Final fallback\n        if (j == -1) {\n            j = (i + 1) % N;\n            if (j == i) j = (i + 2) % N; // Ensure different items\n        }\n        \n        // Output query: compare single items\n        cout << \"1 1 \" << i << \" \" << j << endl;\n        cout.flush();\n        \n        string result;\n        cin >> result;\n        \n        // Update matrix\n        if (result == \">\") {\n            comparison_matrix[i][j] = 1;\n            comparison_matrix[j][i] = -1;\n        } else if (result == \"<\") {\n            comparison_matrix[i][j] = -1;\n            comparison_matrix[j][i] = 1;\n        } else { // \"=\"\n            comparison_matrix[i][j] = 2; // Equal\n            comparison_matrix[j][i] = 2;\n        }\n        \n        comparison_count[i]++;\n        comparison_count[j]++;\n    }\n    \n    // Calculate score for each item: wins - losses\n    vector<int> score(N, 0);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (i == j) continue;\n            if (comparison_matrix[i][j] == 1) {\n                score[i]++; // i beats j\n            } else if (comparison_matrix[i][j] == -1) {\n                score[i]--; // i loses to j\n            }\n        }\n    }\n    \n    // Create order: items sorted by score descending\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        return score[a] > score[b];\n    });\n    \n    // Assign to D groups using snake pattern for balanced distribution\n    vector<int> assignment(N);\n    for (int pos = 0; pos < N; pos++) {\n        int item = order[pos];\n        int cycle = pos / D;\n        int offset = pos % D;\n        \n        int target_group = (cycle % 2 == 0) ? offset : (D - 1 - offset);\n        assignment[item] = target_group;\n    }\n    \n    // Output assignment\n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << assignment[i];\n    }\n    cout << endl;\n    cout.flush();\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    int h = n / m;                     // height of each stack, fixed to 20\n    vector<vector<int>> st(m);          // stacks, bottom -> top\n    for (int i = 0; i < m; ++i) {\n        st[i].reserve(h);\n        for (int j = 0; j < h; ++j) {\n            int x; cin >> x;\n            st[i].push_back(x);\n        }\n    }\n\n    vector<pair<int,int>> ops;          // answer sequence\n    ops.reserve(5000);\n    long long total_energy = 0;         // only for self check, not output\n\n    // helper: find box v, return (stack index, position inside stack)\n    auto locate = [&](int v, int &si, int &pos){\n        for (int i = 0; i < m; ++i) {\n            for (int j = 0; j < (int)st[i].size(); ++j) {\n                if (st[i][j] == v) {\n                    si = i;\n                    pos = j;\n                    return;\n                }\n            }\n        }\n        // should never happen\n        cerr << \"box \" << v << \" not found!\\n\";\n        exit(1);\n    };\n\n    for (int v = 1; v <= n; ++v) {\n        int si, pos;\n        locate(v, si, pos);\n\n        // if v already on the top -> carry out directly\n        if (pos == (int)st[si].size() - 1) {\n            ops.emplace_back(v, 0);\n            st[si].pop_back();               // remove v\n            continue;\n        }\n\n        // box directly above v\n        int w = st[si][pos + 1];\n\n        // choose a destination stack (different from si)\n        int dest = -1;\n        // 1) any empty stack ?\n        for (int i = 0; i < m; ++i) if (i != si && st[i].empty()) {\n            dest = i; break;\n        }\n        // 2) otherwise the non\u2011empty stack with the largest top number\n        if (dest == -1) {\n            int best_top = -1;\n            for (int i = 0; i < m; ++i) if (i != si && !st[i].empty()) {\n                int cur_top = st[i].back();\n                if (cur_top > best_top) {\n                    best_top = cur_top;\n                    dest = i;\n                }\n            }\n        }\n        // sanity check\n        if (dest == -1) {\n            // should never happen (there is at least one other stack)\n            dest = (si + 1) % m;\n        }\n\n        // ---- move the block w .. top of si to dest ----\n        int start = pos + 1;                         // first element to move\n        vector<int> suffix(st[si].begin() + start, st[si].end());\n        int k = (int)suffix.size();                 // number of moved boxes\n        total_energy += k + 1;\n\n        // erase from source\n        st[si].erase(st[si].begin() + start, st[si].end());\n        // append to destination\n        st[dest].insert(st[dest].end(), suffix.begin(), suffix.end());\n\n        ops.emplace_back(w, dest + 1);               // operation 1\n\n        // ---- now v is on the top of si, carry it out ----\n        ops.emplace_back(v, 0);\n        st[si].pop_back();                           // remove v\n    }\n\n    // ---- output ---------------------------------------------------------\n    for (auto [a, b] : ops) {\n        cout << a << ' ' << b << '\\n';\n    }\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\nvector<vector<bool>> visited;\nvector<vector<int>> last;                // time of last visit\nvector<vector<pair<int,int>>> best_nb;   // cached best neighbour\nstring path;\nconst int MAX_MOVES = 100000;\n\n/* --------------------------------------------------------------- */\ninline bool can_move(int i, int j, int ni, int nj) {\n    if (ni == i - 1 && i > 0)      return h[i - 1][j] == '0';\n    if (ni == i + 1 && i < N - 1)  return h[i][j]     == '0';\n    if (nj == j - 1 && j > 0)      return v[i][j - 1] == '0';\n    if (nj == j + 1 && j < N - 1)  return v[i][j]     == '0';\n    return false;\n}\n\n/* --------------------------------------------------------------- */\ninline void add_move(int di, int dj) {\n    if ((int)path.size() >= MAX_MOVES) return;\n    if (di == -1) path.push_back('U');\n    else if (di == 1) path.push_back('D');\n    else if (dj == -1) path.push_back('L');\n    else if (dj == 1) path.push_back('R');\n}\n\n/* --------------------------------------------------------------- */\n// urgency of cell (i,j) at current time t\ninline double urgency(int i, int j, int t) {\n    int dt = t - last[i][j];\n    if (dt <= 0) return -1.0;\n    return d[i][j] * dt;\n}\n\n/* --------------------------------------------------------------- */\n// most urgent cell\npair<int,int> most_urgent(int t) {\n    double best = -1.0; int bi = -1, bj = -1;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            double u = urgency(i,j,t);\n            if (u > best) {\n                best = u; bi = i; bj = j;\n            }\n        }\n    return {bi,bj};\n}\n\n/* --------------------------------------------------------------- */\n// one step toward (ni,nj); if blocked, any legal step\npair<int,int> step_toward(int i, int j, int ni, int nj) {\n    const int DIRS[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n    int di = 0, dj = 0;\n    if (ni < i) di = -1; else if (ni > i) di = 1;\n    else if (nj < j) dj = -1; else if (nj > j) dj = 1;\n    if (can_move(i,j,i+di,j+dj)) return {i+di,j+dj};\n    for (auto [dii,djj] : DIRS) {\n        int ii = i+dii, jj = j+djj;\n        if (ii>=0 && ii<N && jj>=0 && jj<N && can_move(i,j,ii,jj))\n            return {ii,jj};\n    }\n    return {i,j};                           // nowhere to go\n}\n\n/* --------------------------------------------------------------- */\n// DFS skeleton (guarantees completeness)\nvoid dfs_skeleton(int i, int j) {\n    if ((int)path.size() >= MAX_MOVES) return;\n    visited[i][j] = true;\n    last[i][j] = (int)path.size();\n\n    const int DIRS[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n    vector<pair<int,pair<int,int>>> neigh;\n    for (auto [di,dj] : DIRS) {\n        int ni = i+di, nj = j+dj;\n        if (ni>=0 && ni<N && nj>=0 && nj<N && can_move(i,j,ni,nj) && !visited[ni][nj])\n            neigh.push_back({-d[ni][nj], {ni,nj}});\n    }\n    sort(neigh.begin(), neigh.end());\n\n    for (auto [_,c] : neigh) {\n        int ni = c.first, nj = c.second;\n        if (!visited[ni][nj]) {\n            add_move(ni-i, nj-j);\n            dfs_skeleton(ni,nj);\n            add_move(i-ni, j-nj);\n        }\n    }\n}\n\n/* --------------------------------------------------------------- */\n// Phase\u202f2: insert 4\u2011step detours, but only in the last 30\u202f% of the walk\nvoid long_detour_insertions() {\n    const int DIRS[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n    const int INSERTION_START = (MAX_MOVES * 70) / 100; // start insertions at 70\u202f% of limit\n    string base = path;\n    path.clear();\n\n    int i = 0, j = 0, t = 0;\n    for (size_t k = 0; k < base.size(); ++k) {\n        if ((int)path.size() >= INSERTION_START) {\n            // In the insertion zone: we may add 4\u2011step detours\n            auto [ui,uj] = most_urgent(t);\n            if (ui != -1 && ui != i && uj != j) {\n                double cur = urgency(i,j,t);\n                double tgt = urgency(ui,uj,t);\n                // dynamic threshold: 3 + (remaining_moves / 20000)\n                int remaining = MAX_MOVES - (int)path.size();\n                double thresh = 3.0 + remaining / 20000.0;\n                if (tgt > cur * thresh) {\n                    // first step toward urgent cell\n                    auto [i1,j1] = step_toward(i,j,ui,uj);\n                    if (i1 != i || j1 != j) {\n                        int d1i = i1-i, d1j = j1-j;\n                        add_move(d1i, d1j); ++t; last[i1][j1] = t;\n                        // step to best neighbour of urgent cell\n                        auto [d2i,d2j] = best_nb[ui][uj];\n                        int i2 = i1 + d2i, j2 = j1 + d2j;\n                        if (i2>=0 && i2<N && j2>=0 && j2<N && can_move(i1,j1,i2,j2)) {\n                            add_move(d2i, d2j); ++t; last[i2][j2] = t;\n                            // step back to urgent cell\n                            add_move(-d2i, -d2j); ++t; last[i1][j1] = t;\n                        }\n                        // step back to original cell\n                        add_move(-d1i, -d1j); ++t; last[i][j] = t;\n                        continue; // skip original move \u2013 we are back where we started\n                    }\n                }\n            }\n        }\n        // replay original move\n        char mv = base[k];\n        path.push_back(mv);\n        i += (mv=='U'?-1: mv=='D'?1:0);\n        j += (mv=='L'?-1: mv=='R'?1:0);\n        ++t; last[i][j] = t;\n    }\n}\n\n/* --------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // ---- read input -------------------------------------------------\n    cin >> N;\n    h.resize(N-1); for (int i=0;i<N-1;++i) cin >> h[i];\n    v.resize(N);   for (int i=0;i<N;++i)   cin >> v[i];\n    d.assign(N, vector<int>(N));\n    for (int i=0;i<N;++i)\n        for (int j=0;j<N;++j) cin >> d[i][j];\n\n    // ---- cache best neighbours --------------------------------------\n    const int DIRS[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n    best_nb.assign(N, vector<pair<int,int>>(N, {0,0}));\n    for (int i=0;i<N;++i)\n        for (int j=0;j<N;++j) {\n            int bestVal = -1, bestDi = 0, bestDj = 0;\n            for (auto [di,dj] : DIRS) {\n                int ni = i+di, nj = j+dj;\n                if (ni>=0 && ni<N && nj>=0 && nj<N && can_move(i,j,ni,nj))\n                    if (d[ni][nj] > bestVal) {\n                        bestVal = d[ni][nj];\n                        bestDi = di; bestDj = dj;\n                    }\n            }\n            best_nb[i][j] = {bestDi, bestDj};\n        }\n\n    // ---- build skeleton ---------------------------------------------\n    visited.assign(N, vector<bool>(N, false));\n    last.assign(N, vector<int>(N, -1e9));\n    dfs_skeleton(0,0);\n\n    // ---- enrich with long detours -----------------------------------\n    long_detour_insertions();\n\n    cout << path << '\\n';\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\n\nint N, M;\nint si, sj;\nint startId;                     // linear index of the start cell\nvector<string> board;\nvector<string> pat;              // patterns, length M, each length 5\n\n// for every letter \u2013 list of cell ids that contain this letter\nvector<vector<int>> letterPos;   // size 26\n\n// Manhattan distance between any two cells\nint distCell[225][225];\n// coordinates of a cell id\nint row[225], col[225];\n\n/* -------------------------------------------------------------\n   compute the cheapest sum of Manhattan distances for a fixed\n   sequence of letters (vector<int> seq containing 0..25)\n   ------------------------------------------------------------- */\nint movementDist(const vector<int> &seq) {\n    const vector<int> *prevCand = &letterPos[seq[0]];\n    vector<int> dpPrev(prevCand->size());\n    for (int i = 0; i < (int)prevCand->size(); ++i)\n        dpPrev[i] = distCell[startId][(*prevCand)[i]];\n\n    for (size_t idx = 1; idx < seq.size(); ++idx) {\n        const vector<int> *curCand = &letterPos[seq[idx]];\n        vector<int> dpCur(curCand->size(), INF);\n        for (int ci = 0; ci < (int)curCand->size(); ++ci) {\n            int cur = (*curCand)[ci];\n            int best = INF;\n            for (int pi = 0; pi < (int)prevCand->size(); ++pi) {\n                int cand = (*prevCand)[pi];\n                int val = dpPrev[pi] + distCell[cand][cur];\n                if (val < best) best = val;\n            }\n            dpCur[ci] = best;\n        }\n        dpPrev.swap(dpCur);\n        prevCand = curCand;\n    }\n    int best = INF;\n    for (int v : dpPrev) if (v < best) best = v;\n    return best;\n}\n\n/* -------------------------------------------------------------\n   build the overlapped string for a given order of patterns,\n   store it into seq, return total price = movement + length\n   seq is reused to avoid allocations\n   ------------------------------------------------------------- */\nint priceOfOrder(const vector<int> &order, vector<int> &seq) {\n    seq.clear(); seq.reserve(5 * M);\n    for (int id : order) {\n        const string &p = pat[id];\n        int maxOL = min((int)seq.size(), 5);\n        int overlap = 0;\n        for (int k = maxOL; k > 0; --k) {\n            bool ok = true;\n            for (int i = 0; i < k; ++i)\n                if (seq[seq.size() - k + i] != p[i] - 'A') { ok = false; break; }\n            if (ok) { overlap = k; break; }\n        }\n        for (int i = overlap; i < 5; ++i) seq.push_back(p[i] - 'A');\n    }\n    int move = movementDist(seq);\n    return move + (int)seq.size();\n}\n\n/* -------------------------------------------------------------\n   reconstruct the concrete walk for the best order\n   ------------------------------------------------------------- */\nvector<int> reconstructWalk(const vector<int> &order) {\n    vector<int> seq; seq.reserve(5 * M);\n    for (int id : order) {\n        const string &p = pat[id];\n        int maxOL = min((int)seq.size(), 5);\n        int overlap = 0;\n        for (int k = maxOL; k > 0; --k) {\n            bool ok = true;\n            for (int i = 0; i < k; ++i)\n                if (seq[seq.size() - k + i] != p[i] - 'A') { ok = false; break; }\n            if (ok) { overlap = k; break; }\n        }\n        for (int i = overlap; i < 5; ++i) seq.push_back(p[i] - 'A');\n    }\n    int L = (int)seq.size();\n\n    struct Step {\n        const vector<int> *cells;\n        vector<int> dp;\n        vector<int> pred;\n    };\n    vector<Step> step(L);\n\n    // first layer\n    step[0].cells = &letterPos[seq[0]];\n    step[0].dp.resize(step[0].cells->size());\n    step[0].pred.assign(step[0].cells->size(), -1);\n    for (int i = 0; i < (int)step[0].cells->size(); ++i)\n        step[0].dp[i] = distCell[startId][(*step[0].cells)[i]];\n\n    for (int i = 1; i < L; ++i) {\n        step[i].cells = &letterPos[seq[i]];\n        const vector<int> &prevCells = *step[i - 1].cells;\n        const vector<int> &curCells  = *step[i].cells;\n        step[i].dp.assign(curCells.size(), INF);\n        step[i].pred.assign(curCells.size(), -1);\n        for (int ci = 0; ci < (int)curCells.size(); ++ci) {\n            int cur = curCells[ci];\n            int best = INF, bestIdx = -1;\n            for (int pi = 0; pi < (int)prevCells.size(); ++pi) {\n                int val = step[i - 1].dp[pi] + distCell[prevCells[pi]][cur];\n                if (val < best) {\n                    best = val;\n                    bestIdx = pi;\n                }\n            }\n            step[i].dp[ci] = best;\n            step[i].pred[ci] = bestIdx;\n        }\n    }\n\n    // find cheapest last cell\n    const vector<int> &lastCells = *step[L - 1].cells;\n    int bestCost = INF, bestIdx = -1;\n    for (int i = 0; i < (int)lastCells.size(); ++i)\n        if (step[L - 1].dp[i] < bestCost) {\n            bestCost = step[L - 1].dp[i];\n            bestIdx = i;\n        }\n\n    // backtrack\n    vector<int> walk(L);\n    int idx = bestIdx;\n    for (int i = L - 1; i >= 0; --i) {\n        walk[i] = (*step[i].cells)[idx];\n        if (i > 0) idx = step[i].pred[idx];\n    }\n    return walk;\n}\n\n\n/* ------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M)) return 0;\n    cin >> si >> sj;\n    startId = si * N + sj;\n    board.resize(N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n    pat.resize(M);\n    for (int i = 0; i < M; ++i) cin >> pat[i];\n\n    // ---- build letterPos and coordinates -----------------------\n    letterPos.assign(26, {});\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            int id = i * N + j;\n            char c = board[i][j];\n            letterPos[c - 'A'].push_back(id);\n            row[id] = i; col[id] = j;\n        }\n\n    // ---- all pairwise Manhattan distances ----------------------\n    int C = N * N;\n    for (int a = 0; a < C; ++a)\n        for (int b = 0; b < C; ++b)\n            distCell[a][b] = abs(row[a] - row[b]) + abs(col[a] - col[b]);\n\n    // ---- greedy initial order ---------------------------------\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    // sort by distance of the first character from the start\n    sort(order.begin(), order.end(),\n         [&](int a, int b) {\n             const string &pa = pat[a], &pb = pat[b];\n             int da = distCell[startId][letterPos[pa[0] - 'A'][0]];\n             int db = distCell[startId][letterPos[pb[0] - 'A'][0]];\n             return da < db;\n         });\n\n    vector<int> seq;          // reused buffer\n    int bestPrice = priceOfOrder(order, seq);\n    vector<int> bestOrder = order;\n\n    // ---- aggressive random search with insertions --------------\n    const int TOTAL_TRIALS = 4000;           // enough for good exploration\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    for (int trial = 0; trial < TOTAL_TRIALS; ++trial) {\n        // create a neighbour by applying 3 random insertions\n        vector<int> nxt = bestOrder;\n        for (int k = 0; k < 3; ++k) {\n            int src = rng() % M;\n            int dst = rng() % M;\n            if (src < dst) {\n                // move element src to position dst (after insertion)\n                int val = nxt[src];\n                nxt.erase(nxt.begin() + src);\n                nxt.insert(nxt.begin() + dst, val);\n            } else if (src > dst) {\n                int val = nxt[src];\n                nxt.erase(nxt.begin() + src);\n                nxt.insert(nxt.begin() + dst, val);\n            }\n        }\n\n        int curPrice = priceOfOrder(nxt, seq);\n        if (curPrice < bestPrice) {\n            bestPrice = curPrice;\n            bestOrder = nxt;\n        }\n    }\n\n    // ---- output the walk for the best order --------------------\n    vector<int> walk = reconstructWalk(bestOrder);\n    for (int cell : walk) {\n        int i = cell / N;\n        int j = cell % N;\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<pair<int,int>>> shapes;          // input shapes (not used for the CS part)\n\n/* ------------------------------------------------------------------ */\n/*   bit\u2011mask helpers                                                */\ninline int idx(int i, int j) { return i * N + j; }\n\n/* ------------------------------------------------------------------ */\n/*   data structures for the CSP                                      */\nvector< vector< bitset<400> > > placements;   // placements[s][p] = cells covered by placement p of shape s\nvector< vector< pair<int,int> > > cell_to_placements; // cell \u2192 list of (shape,placement) that cover it\nbitset<400> known_dry, known_oil, unknown;\nvector<int> placement_score;                  // for each placement: how many still\u2011unknown cells it covers\n\n/* ------------------------------------------------------------------ */\nint query_single(int i, int j) {\n    cout << \"q 1 \" << i << ' ' << j << endl;\n    int ret; cin >> ret;\n    return ret;\n}\n\n/* ------------------------------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---- read input -------------------------------------------- */\n    if (!(cin >> N >> M >> eps)) return 0;\n    shapes.resize(M);\n    for (int k = 0; k < M; ++k) {\n        int d; cin >> d;\n        shapes[k].resize(d);\n        for (int i = 0; i < d; ++i) {\n            int x, y; cin >> x >> y;\n            shapes[k][i] = {x, y};\n        }\n    }\n\n    /* ---- generate all placements -------------------------------- */\n    placements.resize(M);\n    cell_to_placements.assign(N * N, {});\n    const int MAXC = N * N;\n\n    for (int s = 0; s < M; ++s) {\n        // normalize shape: shift so that min i,j = 0\n        int min_i = INT_MAX, min_j = INT_MAX;\n        for (auto [i, j] : shapes[s]) {\n            min_i = min(min_i, i);\n            min_j = min(min_j, j);\n        }\n        vector<pair<int,int>> norm_shape;\n        for (auto [i, j] : shapes[s])\n            norm_shape.emplace_back(i - min_i, j - min_j);\n\n        // size of the shape\n        int h = 0, w = 0;\n        for (auto [i, j] : norm_shape) {\n            h = max(h, i + 1);\n            w = max(w, j + 1);\n        }\n\n        // try every translation\n        for (int di = 0; di + h <= N; ++di)\n            for (int dj = 0; dj + w <= N; ++dj) {\n                bitset<400> mask;\n                bool conflict = false;\n                for (auto [i, j] : norm_shape) {\n                    int r = di + i, c = dj + j;\n                    mask.set(idx(r, c));\n                }\n                // store the placement\n                int pid = placements[s].size();\n                placements[s].push_back(mask);\n                // update reverse index\n                for (int i = 0; i < MAXC; ++i)\n                    if (mask[i]) cell_to_placements[i].push_back({s, pid});\n            }\n    }\n\n    /* ---- initialise CSP status ---------------------------------- */\n    known_dry.reset();\n    known_oil.reset();\n    unknown.reset();\n    for (int i = 0; i < MAXC; ++i) unknown.set(i);\n    placement_score.assign(M, 0);   // not used \u2013 we recompute the coverage on the fly\n\n    /* ---- main loop : at most 2\u00b7N\u00b2 iterations -------------------- */\n    int iterations = 0;\n    const int LIMIT = 2 * N * N;\n\n    while (iterations < LIMIT && unknown.any()) {\n        ++iterations;\n\n        /* ---- 1. prune placements that hit known_dry ---------- */\n        for (int s = 0; s < M; ++s) {\n            vector<bitset<400>> keep;\n            for (auto &pl : placements[s])\n                if ((pl & known_dry).none()) keep.push_back(pl);\n            placements[s].swap(keep);\n        }\n\n        /* ---- 2. deduce forced cells --------------------------- */\n        vector<int> newly_dry, newly_oil;\n        for (int i = 0; i < MAXC; ++i) if (unknown[i]) {\n            bool can_be_oil = false, can_be_dry = false;\n            // check if any placement still covers i\n            for (auto [s, pid] : cell_to_placements[i]) {\n                // we have to check if pid is still alive for shape s\n                bool alive = false;\n                for (auto &pl : placements[s])\n                    if (pl[idx(i/N, i%N)]) { alive = true; break; }\n                if (alive) { can_be_oil = true; break; }\n            }\n            if (!can_be_oil) newly_dry.push_back(i);\n        }\n\n        for (int i : newly_dry) {\n            known_dry.set(i);\n            unknown.reset(i);\n        }\n\n        /* ---- 3. choose the most informative cell -------------- */\n        // simple heuristic: cell covered by the most remaining placements\n        int best_cell = -1, best_cov = 0;\n        for (int i = 0; i < MAXC; ++i) if (unknown[i]) {\n            int cov = 0;\n            for (auto [s, pid] : cell_to_placements[i])\n                for (auto &pl : placements[s])\n                    if (pl[idx(i/N, i%N)]) { ++cov; break; }\n            if (cov > best_cov) {\n                best_cov = cov;\n                best_cell = i;\n            }\n        }\n\n        if (best_cell == -1) break;   // nothing left to test\n\n        int r = best_cell / N, c = best_cell % N;\n        int v = query_single(r, c);\n        if (v > 0) {\n            known_oil.set(best_cell);\n            unknown.reset(best_cell);\n        } else {\n            known_dry.set(best_cell);\n            unknown.reset(best_cell);\n        }\n    }\n\n    /* ---- output answer ------------------------------------------ */\n    vector<pair<int,int>> answer;\n    for (int i = 0; i < MAXC; ++i)\n        if (known_oil[i]) answer.emplace_back(i / N, i % N);\n\n    cout << \"a \" << answer.size();\n    for (auto [r, c] : answer) cout << ' ' << r << ' ' << c;\n    cout << endl;\n\n    int ok; cin >> ok;\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXW = 1000;                 // W is fixed to 1000 in the problem\n\n/*------------------------------------------------------------*/\n/*  geometry structures                                       */\n\nstruct Rect {\n    int x0, y0, x1, y1;               // top\u2011left (x0,y0), bottom\u2011right (x1,y1)\n};\n\nstruct Region {\n    int x, y, w, h;                    // top\u2011left corner, width, height\n    int area() const { return w * h; }\n};\n\n/*------------------------------------------------------------*/\n/*  packing of one day                                       */\n\nstatic vector<Rect> pack_day(const vector<int>& request, int W, int N) {\n    // request[k] = a[d][k]\n    vector<pair<int, int>> ord;        // (area , original index)\n    ord.reserve(N);\n    for (int k = 0; k < N; ++k) ord.emplace_back(request[k], k);\n    sort(ord.begin(), ord.end(),\n         [](const pair<int, int>& A, const pair<int, int>& B) {\n             return A.first > B.first;               // decreasing area\n         });\n\n    vector<Region> freeReg;\n    freeReg.push_back({0, 0, W, W});                 // whole hall\n\n    vector<Rect> answer(N);\n\n    for (auto [area, idx] : ord) {\n        // ---- find a region that can contain the rectangle\n        int sel = -1;          // region with area >= request\n        int best = -1;         // region with the largest area (used when no region fits)\n        int bestArea = -1;\n\n        for (int i = 0; i < (int)freeReg.size(); ++i) {\n            int a = freeReg[i].area();\n            if (a >= area) {\n                if (sel == -1 || a < freeReg[sel].area()) sel = i;\n            }\n            if (a > bestArea) {\n                bestArea = a;\n                best = i;\n            }\n        }\n\n        Region R;\n        bool fits = (sel != -1);\n        if (fits) R = freeReg[sel];\n        else      R = freeReg[best];                  // we will pay a penalty\n\n        // ---- choose the size of the rectangle\n        int w, h;\n        if (fits) {\n            // try orientation 1 (prefer a square)\n            int w1 = min(R.w, max(1, (int)std::sqrt((double)area)));\n            int h1 = (area + w1 - 1) / w1;               // ceil\n            if (h1 <= R.h) {\n                w = w1;  h = h1;\n            } else {\n                // orientation 2 (swap roles)\n                int h2 = min(R.h, max(1, (int)std::sqrt((double)area)));\n                int w2 = (area + h2 - 1) / h2;\n                if (w2 <= R.w) {\n                    w = w2;  h = h2;\n                } else {\n                    // fallback \u2013 use whole width of the region\n                    w = R.w;\n                    h = (area + w - 1) / w;\n                }\n            }\n        } else {\n            // we cannot satisfy the area \u2013 fill the whole region (penalty)\n            w = R.w;\n            h = R.h;\n        }\n\n        // ---- store the rectangle\n        answer[idx] = {R.x, R.y, R.x + w, R.y + h};\n\n        // ---- create the two leftover parts (guillotine cut)\n        if (w < R.w) {\n            freeReg.push_back({R.x + w, R.y, R.w - w, R.h});\n        }\n        if (h < R.h) {\n            freeReg.push_back({R.x, R.y + h, w, R.h - h});\n        }\n\n        // ---- delete the used region (swap with last element)\n        if (fits) {\n            freeReg[sel] = freeReg.back();\n            freeReg.pop_back();\n        } else {\n            freeReg[best] = freeReg.back();\n            freeReg.pop_back();\n        }\n    }\n    return answer;\n}\n\n/*------------------------------------------------------------*/\n/*  edge matrices                                             */\n\nstruct EdgeMatrices {\n    vector<vector<char>> H;   // H[i][j] : horizontal edge (i,0..W-1)  i=1..W-1\n    vector<vector<char>> V;   // V[i][j] : vertical   edge (0..W-1,j)  j=1..W-1\n    EdgeMatrices(int W) {\n        H.assign(W + 1, vector<char>(W, 0));\n        V.assign(W, vector<char>(W + 1, 0));\n    }\n    void clear() {\n        for (auto &row : H) fill(row.begin(), row.end(), 0);\n        for (auto &row : V) fill(row.begin(), row.end(), 0);\n    }\n};\n\nvoid mark_edges(const vector<Rect>& rects, int W, EdgeMatrices& em) {\n    em.clear();\n    for (const Rect& r : rects) {\n        if (r.x0 > 0) {\n            for (int j = r.y0; j < r.y1; ++j) em.H[r.x0][j] = 1;\n        }\n        if (r.x1 < W) {\n            for (int j = r.y0; j < r.y1; ++j) em.H[r.x1][j] = 1;\n        }\n        if (r.y0 > 0) {\n            for (int i = r.x0; i < r.x1; ++i) em.V[i][r.y0] = 1;\n        }\n        if (r.y1 < W) {\n            for (int i = r.x0; i < r.x1; ++i) em.V[i][r.y1] = 1;\n        }\n    }\n}\n\n/*------------------------------------------------------------*/\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\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    vector<vector<Rect>> allRects(D, vector<Rect>(N));\n    EdgeMatrices prev(W), cur(W);\n    long long totalCost = 0;               // only for debugging, not needed for output\n\n    for (int d = 0; d < D; ++d) {\n        // ----- pack the day\n        allRects[d] = pack_day(a[d], W, N);\n        // ----- build edge matrices\n        mark_edges(allRects[d], W, cur);\n        // ----- compute transition cost (L0 = 0 is special)\n        if (d > 0) {\n            long long Ld = 0;\n            for (int i = 1; i < W; ++i)\n                for (int j = 0; j < W; ++j)\n                    Ld += (prev.H[i][j] != cur.H[i][j]);\n            for (int i = 0; i < W; ++i)\n                for (int j = 1; j < W; ++j)\n                    Ld += (prev.V[i][j] != cur.V[i][j]);\n            totalCost += Ld;\n        }\n        // ----- store current matrices as previous for the next day\n        prev.H.swap(cur.H);\n        prev.V.swap(cur.V);\n    }\n\n    // ----- output\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            const Rect& r = allRects[d][k];\n            cout << r.x0 << ' ' << r.y0 << ' ' << r.x1 << ' ' << r.y1 << '\\n';\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 (fixed by the statement)\nconst int SZ = 3;           // stamp size\nconst int MAX_K = 81;       // maximum number of operations\n\nstruct Op {\n    int m;       // stamp index\n    int p, q;    // top\u2011left position of the stamp on the board\n};\n\n/* ------------------------------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M, K;\n    // N is always 9, but read it anyway (the input line is \"N M K\")\n    int tmpN;\n    if (!(cin >> tmpN >> M >> K)) return 0;\n\n    int board[N][N];\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> board[i][j];\n\n    int stamp[M][SZ][SZ];\n    for (int m = 0; m < M; ++m)\n        for (int i = 0; i < SZ; ++i)\n            for (int j = 0; j < SZ; ++j)\n                cin >> stamp[m][i][j];\n\n    /* all possible placements (m,p,q) */\n    vector<Op> allOps;\n    for (int m = 0; m < M; ++m)\n        for (int p = 0; p <= N - SZ; ++p)\n            for (int q = 0; q <= N - SZ; ++q)\n                allOps.push_back({m, p, q});\n\n    /* ---------- helper functions ---------- */\n    auto boardScore = [&](const int b[N][N]) -> long long {\n        long long s = 0;\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                s += b[i][j];\n        return s;\n    };\n\n    auto deltaAdd = [&](const int b[N][N], const Op& op) -> long long {\n        const auto& s = stamp[op.m];\n        long long d = 0;\n        for (int i = 0; i < SZ; ++i)\n            for (int j = 0; j < SZ; ++j) {\n                int old = b[op.p + i][op.q + j];\n                int add = s[i][j];\n                int sum = old + add;\n                if (sum >= MOD) d += add - MOD;\n                else            d += add;\n            }\n        return d;\n    };\n\n    auto deltaRemove = [&](const int b[N][N], const Op& op) -> long long {\n        const auto& s = stamp[op.m];\n        long long d = 0;\n        for (int i = 0; i < SZ; ++i)\n            for (int j = 0; j < SZ; ++j) {\n                int old = b[op.p + i][op.q + j];\n                int v = s[i][j];\n                int nw = (old >= v) ? old - v : old + MOD - v;\n                d += nw - old;\n            }\n        return d;\n    };\n\n    auto applyAdd = [&](int b[N][N], long long& sc, const Op& op) {\n        const auto& s = stamp[op.m];\n        for (int i = 0; i < SZ; ++i)\n            for (int j = 0; j < SZ; ++j) {\n                int old = b[op.p + i][op.q + j];\n                int add = s[i][j];\n                int sum = old + add;\n                int nw = (sum >= MOD) ? sum - MOD : sum;\n                b[op.p + i][op.q + j] = nw;\n                sc += nw - old;\n            }\n    };\n\n    auto applyRemove = [&](int b[N][N], long long& sc, const Op& op) {\n        const auto& s = stamp[op.m];\n        for (int i = 0; i < SZ; ++i)\n            for (int j = 0; j < SZ; ++j) {\n                int old = b[op.p + i][op.q + j];\n                int v = s[i][j];\n                int nw = (old >= v) ? old - v : old + MOD - v;\n                b[op.p + i][op.q + j] = nw;\n                sc += nw - old;\n            }\n    };\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    long long bestScore = -1;\n    vector<Op> bestOps;\n\n    const double TIME_LIMIT = 1.8;\n    auto start = chrono::steady_clock::now();\n\n    /* --------------------------------------------------------------- */\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        if (chrono::duration<double>(now - start).count() > TIME_LIMIT) break;\n\n        /* start from the original board */\n        int curBoard[N][N];\n        memcpy(curBoard, board, sizeof(curBoard));\n        long long curScore = boardScore(curBoard);\n        vector<Op> curOps;\n\n        /* ----- greedy construction (add + remove) ----- */\n        do {\n            /* addition */\n            while ((int)curOps.size() < K) {\n                vector<Op> sh = allOps;\n                shuffle(sh.begin(), sh.end(), rng);\n                long long bestDelta = 0;\n                vector<Op> cand;\n                for (const Op& op : sh) {\n                    long long d = deltaAdd(curBoard, op);\n                    if (d > bestDelta) {\n                        bestDelta = d;\n                        cand.clear();\n                        cand.push_back(op);\n                    } else if (d == bestDelta && d > 0) {\n                        cand.push_back(op);\n                    }\n                }\n                if (bestDelta <= 0) break;\n                const Op& chosen = cand[ rng() % cand.size() ];\n                applyAdd(curBoard, curScore, chosen);\n                curOps.push_back(chosen);\n            }\n\n            /* removal */\n            while (true) {\n                long long bestDelta = 0;\n                vector<int> idxCand;\n                for (int i = 0; i < (int)curOps.size(); ++i) {\n                    long long d = deltaRemove(curBoard, curOps[i]);\n                    if (d > bestDelta) {\n                        bestDelta = d;\n                        idxCand.clear();\n                        idxCand.push_back(i);\n                    } else if (d == bestDelta && d > 0) {\n                        idxCand.push_back(i);\n                    }\n                }\n                if (bestDelta <= 0) break;\n                int idx = idxCand[ rng() % idxCand.size() ];\n                Op op = curOps[idx];\n                applyRemove(curBoard, curScore, op);\n                curOps[idx] = curOps.back();\n                curOps.pop_back();\n            }\n\n            if (curScore > bestScore) {\n                bestScore = curScore;\n                bestOps = curOps;          // copy\n            }\n        } while (false);   // run only once \u2013 we will kick afterwards\n\n        /* ----- random kicks and several rebuilds ----- */\n        for (int kickRound = 0; kickRound < 3; ++kickRound) {\n            /* delete up to 5 random operations */\n            int kick = min(5, (int)curOps.size());\n            for (int i = 0; i < kick; ++i) {\n                int idx = rng() % curOps.size();\n                Op op = curOps[idx];\n                applyRemove(curBoard, curScore, op);\n                curOps[idx] = curOps.back();\n                curOps.pop_back();\n            }\n\n            /* rebuild greedily a few times */\n            for (int rebuild = 0; rebuild < 3; ++rebuild) {\n                /* addition */\n                while ((int)curOps.size() < K) {\n                    vector<Op> sh = allOps;\n                    shuffle(sh.begin(), sh.end(), rng);\n                    long long bestDelta = 0;\n                    vector<Op> cand;\n                    for (const Op& op : sh) {\n                        long long d = deltaAdd(curBoard, op);\n                        if (d > bestDelta) {\n                            bestDelta = d;\n                            cand.clear();\n                            cand.push_back(op);\n                        } else if (d == bestDelta && d > 0) {\n                            cand.push_back(op);\n                        }\n                    }\n                    if (bestDelta <= 0) break;\n                    const Op& chosen = cand[ rng() % cand.size() ];\n                    applyAdd(curBoard, curScore, chosen);\n                    curOps.push_back(chosen);\n                }\n\n                /* removal */\n                while (true) {\n                    long long bestDelta = 0;\n                    vector<int> idxCand;\n                    for (int i = 0; i < (int)curOps.size(); ++i) {\n                        long long d = deltaRemove(curBoard, curOps[i]);\n                        if (d > bestDelta) {\n                            bestDelta = d;\n                            idxCand.clear();\n                            idxCand.push_back(i);\n                        } else if (d == bestDelta && d > 0) {\n                            idxCand.push_back(i);\n                        }\n                    }\n                    if (bestDelta <= 0) break;\n                    int idx = idxCand[ rng() % idxCand.size() ];\n                    Op op = curOps[idx];\n                    applyRemove(curBoard, curScore, op);\n                    curOps[idx] = curOps.back();\n                    curOps.pop_back();\n                }\n            }   // end rebuild loop\n\n            if (curScore > bestScore) {\n                bestScore = curScore;\n                bestOps = curOps;\n            }\n        }   // end kick loop\n    }\n\n    cout << bestOps.size() << '\\n';\n    for (const Op& op : bestOps)\n        cout << op.m << ' ' << op.p << ' ' << op.q << '\\n';\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos {\n    int r = -1, c = -1;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n    const int TOTAL = N * N;\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) cin >> A[i][j];\n\n    // which row each container comes from (not needed further)\n    vector<int> sourceRow(TOTAL);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            sourceRow[A[i][j]] = i;\n\n    // grid: container id or -1\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    // how many containers of each row already appeared\n    vector<int> recCnt(N, 0);\n    // how many containers already dispatched\n    int dispatched = 0;\n\n    // the large crane\n    struct Crane {\n        int r = 0, c = 0;\n        bool holding = false;\n        int holdId = -1;\n    } large;\n\n    // output strings, one per row\n    vector<string> out(N);\n\n    int turn = 0;\n    const int LIMIT = 10000;\n\n    while (dispatched < TOTAL && turn < LIMIT) {\n        /* ---- step 1 : containers appear ---- */\n        for (int i = 0; i < N; ++i) {\n            if (recCnt[i] >= N) continue;               // row finished\n            if (grid[i][0] != -1) continue;              // square occupied\n            // a crane holding a container blocks the square\n            bool blocked = (large.r == i && large.c == 0 && large.holding);\n            if (!blocked) {\n                int cid = A[i][recCnt[i]];\n                grid[i][0] = cid;\n                ++recCnt[i];\n            }\n        }\n\n        /* ---- step 2 : crane actions ---- */\n        // small cranes: bomb on turn 0, then only '.'\n        for (int i = 1; i < N; ++i) {\n            if (turn == 0) out[i].push_back('B');\n            else           out[i].push_back('.');\n        }\n\n        // large crane (row 0)\n        char act = '.';\n        if (large.holding) {\n            int targetRow = large.holdId / N;\n            int targetCol = N - 1;\n            if (large.r != targetRow) {                 // vertical move\n                int dr = (targetRow > large.r) ? 1 : -1;\n                act = (dr == 1) ? 'D' : 'U';\n                large.r += dr;\n            } else if (large.c != targetCol) {          // move right\n                act = 'R';\n                large.c += 1;\n            } else {                                    // drop on dispatch gate\n                grid[large.r][large.c] = large.holdId;\n                large.holding = false;\n                large.holdId = -1;\n                act = 'Q';\n            }\n        } else {\n            // not holding \u2013 pick the smallest waiting container\n            int bestRow = -1;\n            int bestId = INT_MAX;\n            for (int i = 0; i < N; ++i) {\n                if (grid[i][0] != -1 && grid[i][0] < bestId) {\n                    bestId = grid[i][0];\n                    bestRow = i;\n                }\n            }\n            if (bestRow == -1) {                        // nothing to do\n                act = '.';\n            } else {\n                if (large.r != bestRow) {               // vertical move\n                    int dr = (bestRow > large.r) ? 1 : -1;\n                    act = (dr == 1) ? 'D' : 'U';\n                    large.r += dr;\n                } else if (large.c != 0) {              // move left to column 0\n                    act = 'L';\n                    large.c -= 1;\n                } else {                                // pick up\n                    int cid = grid[large.r][large.c];\n                    large.holding = true;\n                    large.holdId = cid;\n                    grid[large.r][large.c] = -1;\n                    act = 'P';\n                }\n            }\n        }\n        out[0].push_back(act);\n\n        /* ---- step 3 : dispatch ---- */\n        for (int i = 0; i < N; ++i) {\n            int cid = grid[i][N - 1];\n            if (cid != -1) {\n                ++dispatched;\n                grid[i][N - 1] = -1;\n            }\n        }\n\n        ++turn;\n    }\n\n    // all rows must have the same length (pad with '.')\n    for (int i = 0; i < N; ++i) {\n        if ((int)out[i].size() < turn) out[i] += string(turn - out[i].size(), '.');\n        cout << out[i] << '\\n';\n    }\n    return 0;\n}","ahc034":"#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    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    // working copy of the heights\n    vector<vector<int>> rem = h;\n\n    int curR = 0, curC = 0;      // truck position\n    int load = 0;                // soil on the truck\n    vector<string> ops;          // list of operations\n\n    auto pushMove = [&](char dir) {\n        ops.emplace_back(string(1, dir));\n    };\n    auto pushLoad = [&](int d) {\n        ops.emplace_back(\"+\" + to_string(d));\n        load += d;\n    };\n    auto pushUnload = [&](int d) {\n        ops.emplace_back(\"-\" + to_string(d));\n        load -= d;\n    };\n\n    // move the truck to (tr,tc) along a Manhattan path\n    auto moveTo = [&](int tr, int tc) {\n        int dr = tr - curR;\n        int dc = tc - curC;\n        while (dr != 0) {\n            int step = (dr > 0) ? 1 : -1;\n            char dir = (dr > 0) ? 'D' : 'U';\n            pushMove(dir);\n            curR += step;\n            dr -= step;\n        }\n        while (dc != 0) {\n            int step = (dc > 0) ? 1 : -1;\n            char dir = (dc > 0) ? 'R' : 'L';\n            pushMove(dir);\n            curC += step;\n            dc -= step;\n        }\n    };\n\n    // find the nearest cell that satisfies a predicate\n    auto nearest = [&](auto pred) -> pair<int,int> {\n        int bestDist = INT_MAX;\n        pair<int,int> best(-1,-1);\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (!pred(i,j)) continue;\n                int dist = abs(i - curR) + abs(j - curC);\n                if (dist < bestDist) {\n                    bestDist = dist;\n                    best = {i,j};\n                }\n            }\n        }\n        return best;\n    };\n\n    while (true) {\n        // nearest hill (positive remaining height)\n        auto hill = nearest([&](int i,int j){ return rem[i][j] > 0; });\n        if (hill.first == -1) break;                 // no hill left -> finished\n\n        // go there and load everything\n        moveTo(hill.first, hill.second);\n        int d = rem[hill.first][hill.second];        // >0\n        pushLoad(d);\n        rem[hill.first][hill.second] = 0;\n\n        // deliver the whole load to holes\n        while (load > 0) {\n            auto hole = nearest([&](int i,int j){ return rem[i][j] < 0; });\n            // there must be a hole, otherwise the input would be inconsistent\n            moveTo(hole.first, hole.second);\n            int demand = -rem[hole.first][hole.second]; // positive\n            int unload = min(load, demand);\n            pushUnload(unload);\n            rem[hole.first][hole.second] += unload;    // still \u2264 0\n        }\n    }\n\n    // (optional) safety \u2013 should never be needed because sums are zero\n    while (load > 0) {\n        auto hole = nearest([&](int i,int j){ return rem[i][j] < 0; });\n        if (hole.first == -1) break;\n        moveTo(hole.first, hole.second);\n        int demand = -rem[hole.first][hole.second];\n        int unload = min(load, demand);\n        pushUnload(unload);\n        rem[hole.first][hole.second] += unload;\n    }\n\n    // output all operations\n    for (auto &s : ops) cout << s << '\\n';\n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int N = 6;               // fixed in the statement\n    const int M = 15;              // fixed in the statement\n    const int T = 10;              // fixed in the statement\n    const int SEED_CNT = 2 * N * (N - 1);   // 60\n    const int CELL_CNT = N * N;            // 36\n    const int EDGE_CNT = 2 * N * (N - 1);   // 60\n\n    // ---------- read initial data ----------\n    int tmpN, tmpM, tmpT;\n    if (!(cin >> tmpN >> tmpM >> tmpT)) return 0;\n    // the values are the same as the constants above, ignore them\n\n    vector<vector<int>> seed(SEED_CNT, vector<int>(M));\n    vector<int> seedSum(SEED_CNT, 0);\n    vector<int> X(M, 0);                 // per\u2011dimension maxima of the initial seeds\n\n    for (int i = 0; i < SEED_CNT; ++i) {\n        int s = 0;\n        for (int j = 0; j < M; ++j) {\n            int x; cin >> x;\n            seed[i][j] = x;\n            s += x;\n            X[j] = max(X[j], x);\n        }\n        seedSum[i] = s;\n    }\n\n    // build list of edges (neighbour pairs) once\n    vector<pair<int,int>> edges;\n    edges.reserve(EDGE_CNT);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            int p = i * N + j;\n            if (i + 1 < N) edges.emplace_back(p, (i + 1) * N + j);\n            if (j + 1 < N) edges.emplace_back(p, i * N + (j + 1));\n        }\n\n    // helper: best possible child of two seeds\n    auto best_possible = [&](int a, int b)->int{\n        int ret = 0;\n        const auto &A = seed[a];\n        const auto &B = seed[b];\n        for (int i = 0; i < M; ++i) ret += max(A[i], B[i]);\n        return ret;\n    };\n\n    // helper: evaluate a whole placement\n    // returns {total_sum_of_best , max_best}\n    auto evaluate = [&](const vector<int> &grid)->pair<int,int>{\n        int total = 0, mx = 0;\n        for (auto [u,v] : edges) {\n            int val = best_possible(grid[u], grid[v]);\n            total += val;\n            mx = max(mx, val);\n        }\n        return {total, mx};\n    };\n\n    // ---------- round loop ----------\n    for (int round = 0; round < T; ++round) {\n        // ---- choose the initial 36 seeds: the 36 with largest sum ----\n        vector<int> allIdx(SEED_CNT);\n        iota(allIdx.begin(), allIdx.end(), 0);\n        sort(allIdx.begin(), allIdx.end(),\n             [&](int a, int b){ return seedSum[a] > seedSum[b]; });\n        vector<int> selectedIdx(allIdx.begin(), allIdx.begin() + CELL_CNT);   // 36 seeds\n\n        // best placement found in this round\n        vector<int> bestGrid;\n        long long bestObj = -(1LL<<60);\n\n        // ---- several restarts of hill climbing ----\n        const int RESTARTS = 3;\n        const int ITERATIONS = 2000;\n        const int WEIGHT_MAX = 1000;          // max_best is multiplied by this\n\n        for (int rep = 0; rep < RESTARTS; ++rep) {\n            // current placement: random permutation of the 36 selected seeds\n            vector<int> grid = selectedIdx;\n            shuffle(grid.begin(), grid.end(), mt19937{ random_device{}() });\n\n            // current used / unused lists\n            vector<char> used(SEED_CNT, 0);\n            for (int id : grid) used[id] = 1;\n            vector<int> unused;\n            unused.reserve(SEED_CNT - CELL_CNT);\n            for (int i = 0; i < SEED_CNT; ++i) if (!used[i]) unused.push_back(i);\n\n            // evaluate starting placement\n            auto [totalSum, maxBest] = evaluate(grid);\n            long long curObj = (long long)maxBest * WEIGHT_MAX + totalSum;\n\n            // hill climbing\n            for (int it = 0; it < ITERATIONS; ++it) {\n                bool moveWithUnused = false;\n                if (!unused.empty() && (rand() % 2)) moveWithUnused = true;\n\n                if (moveWithUnused) {\n                    // exchange a planted seed with an unused one\n                    int pos = rand() % CELL_CNT;\n                    int oldSeed = grid[pos];\n                    int idx = rand() % unused.size();\n                    int newSeed = unused[idx];\n                    // temporarily place newSeed\n                    grid[pos] = newSeed;\n                    auto [newSum, newMax] = evaluate(grid);\n                    long long newObj = (long long)newMax * WEIGHT_MAX + newSum;\n                    if (newObj > curObj) {               // accept\n                        used[oldSeed] = 0;\n                        used[newSeed] = 1;\n                        unused[idx] = oldSeed;            // replace\n                        curObj = newObj;\n                        // totalSum, maxBest are already updated by evaluate\n                    } else {\n                        grid[pos] = oldSeed;               // revert\n                    }\n                } else {\n                    // swap two positions\n                    int p = rand() % CELL_CNT;\n                    int q = rand() % CELL_CNT;\n                    if (p == q) continue;\n                    swap(grid[p], grid[q]);\n                    auto [newSum, newMax] = evaluate(grid);\n                    long long newObj = (long long)newMax * WEIGHT_MAX + newSum;\n                    if (newObj > curObj) {               // accept\n                        curObj = newObj;\n                    } else {\n                        swap(grid[p], grid[q]);           // revert\n                    }\n                }\n            } // end of iterations\n\n            // keep the best placement among the restarts\n            if (curObj > bestObj) {\n                bestObj = curObj;\n                bestGrid = grid;\n            }\n        } // restarts\n\n        // ---- output the best grid ----\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (j) cout << ' ';\n                cout << bestGrid[i * N + j];\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n\n        // ---- read the children, they become the seed pool for the next round ----\n        for (int i = 0; i < SEED_CNT; ++i) {\n            int s = 0;\n            for (int j = 0; j < M; ++j) {\n                int x; cin >> x;\n                seed[i][j] = x;\n                s += x;\n            }\n            seedSum[i] = s;\n        }\n    } // round loop\n\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\n\n/* -------------------------------------------------------------\n   geometry constants \u2013 used everywhere\n   ------------------------------------------------------------- */\n// directions of the leaves: 0 = east, 1 = north, 2 = west, 3 = south\nconst int DIR_DX[4] = {0, -1, 0, +1};\nconst int DIR_DY[4] = {+1, 0, -1, 0};\n\n// root moves: order must match move_chars[]\nconst int MV_DX[5] = {-1, +1, 0, 0, 0};\nconst int MV_DY[5] = {0, 0, -1, +1, 0};\nconst char MOVE_CHARS[5] = {'U','D','L','R','.'};\n\n/* -------------------------------------------------------------\n   perform all possible actions for the current root position\n   returns number of actions done and fills the action string\n   ------------------------------------------------------------- */\nint perform_actions(int rx, int ry,\n                    const vector<int> &dir,\n                    vector<char> &loaded, int &loaded_cnt,\n                    const vector<vector<char>> &is_src,\n                    const vector<vector<char>> &is_tgt,\n                    vector<vector<char>> &occupied, int &src_rem,\n                    string &act) {\n    const int C = 4;\n    int actions = 0;\n    act.clear();\n    act.push_back('.');               // root never acts\n    for (int i = 1; i <= C; ++i) {\n        int d = dir[i];\n        int cx = rx + DIR_DX[d];\n        int cy = ry + DIR_DY[d];\n        bool can = false;\n        if (!loaded[i] && cx >= 0 && cx < int(occupied.size()) &&\n            cy >= 0 && cy < int(occupied.size()) &&\n            is_src[cx][cy] && occupied[cx][cy]) {\n            can = true;\n            // pick\n            occupied[cx][cy] = 0;\n            loaded[i] = 1;\n            --src_rem;\n            ++loaded_cnt;\n        } else if (loaded[i] && cx >= 0 && cx < int(occupied.size()) &&\n                   cy >= 0 && cy < int(occupied.size()) &&\n                   is_tgt[cx][cy] && !occupied[cx][cy]) {\n            can = true;\n            // deliver\n            occupied[cx][cy] = 1;\n            loaded[i] = 0;\n            --loaded_cnt;\n        }\n        if (can) { act.push_back('P'); ++actions; }\n        else       act.push_back('.');\n    }\n    return actions;\n}\n\n/* -------------------------------------------------------------\n   main\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> s(N), t(N);\n    for (int i = 0; i < N; ++i) cin >> s[i];\n    for (int i = 0; i < N; ++i) cin >> t[i];\n\n    /* ----- board description ----- */\n    vector<vector<char>> is_src(N, vector<char>(N, 0));\n    vector<vector<char>> is_tgt(N, vector<char>(N, 0));\n    vector<vector<char>> occupied(N, vector<char>(N, 0));\n    int src_rem = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            occupied[i][j] = (s[i][j] == '1');\n            if (s[i][j] == '1' && t[i][j] == '0') {\n                is_src[i][j] = 1;\n                ++src_rem;\n            }\n            if (t[i][j] == '1' && s[i][j] == '0') {\n                is_tgt[i][j] = 1;\n            }\n        }\n    }\n\n    /* ----- arm geometry \u2013 always the same 5\u2011vertex star ----- */\n    const int Vout = 5;                     // root + 4 leaves, always \u2264 V\n    const int C = 4;                        // leaves we actually use\n\n    // leaf directions after the two initial rotation turns\n    vector<int> dir(C + 1, 0);               // 1\u2011based, initially all east\n    vector<char> loaded(C + 1, 0);           // initially empty\n    int loaded_cnt = 0;\n\n    // root initial position\n    int rx = 0, ry = 0;\n\n    /* ----- output the designed tree ----- */\n    cout << Vout << '\\n';\n    for (int i = 1; i < Vout; ++i) cout << 0 << ' ' << 1 << '\\n';\n    cout << rx << ' ' << ry << '\\n';\n\n    /* ----- containers for the operation strings ----- */\n    vector<string> ops;\n\n    /* ----- two initial rotation turns ----- */\n    // turn 0 : . L L R   (leaf 2,3,4 are rotated)\n    {\n        string op;\n        op.push_back('.');                 // root\n        op.push_back('.');                 // leaf 1\n        op.push_back('L');                 // leaf 2\n        op.push_back('L');                 // leaf 3\n        op.push_back('R');                 // leaf 4\n        for (int i = 0; i < Vout; ++i) op.push_back('.'); // actions\n        ops.push_back(op);\n        // apply rotations\n        dir[2] = (dir[2] + 1) & 3;          // L -> +1 (mod 4)\n        dir[3] = (dir[3] + 1) & 3;          // L\n        dir[4] = (dir[4] + 3) & 3;          // R -> +3 (mod 4)\n    }\n    // turn 1 : . . L .   (leaf 3 gets its second rotation)\n    {\n        string op;\n        op.push_back('.');                 // root\n        op.push_back('.');                 // leaf 1\n        op.push_back('.');                 // leaf 2\n        op.push_back('L');                 // leaf 3\n        op.push_back('.');                 // leaf 4\n        for (int i = 0; i < Vout; ++i) op.push_back('.'); // actions\n        ops.push_back(op);\n        // apply rotation\n        dir[3] = (dir[3] + 1) & 3;          // now leaf 3 points west\n    }\n\n    /* ----- main simulation loop \u2013 stop after 100\u202f000 turns ----- */\n    while ((src_rem > 0 || loaded_cnt > 0) && (int)ops.size() < 100000) {\n        // decide the current mode (pickup if we have empty leaves and sources left)\n        bool have_empty = false;\n        for (int i = 1; i <= C; ++i) if (!loaded[i]) { have_empty = true; break; }\n        int mode = (src_rem > 0 && have_empty) ? 0 : 1; // 0 = pickup, 1 = delivery\n\n        // try all five possible root moves\n        int best_move = -1, best_score = -1, best_dist = INF, best_reach = -1;\n        for (int m = 0; m < 5; ++m) {\n            char mc = MOVE_CHARS[m];\n            int nx = rx + MV_DX[m];\n            int ny = ry + MV_DY[m];\n            if (mc != '.' && (nx < 0 || nx >= N || ny < 0 || ny >= N)) continue;\n\n            // count possible actions for this move\n            int pickups = 0, deliveries = 0;\n            for (int i = 1; i <= C; ++i) {\n                int d = dir[i];\n                int cx = nx + DIR_DX[d];\n                int cy = ny + DIR_DY[d];\n                if (cx < 0 || cx >= N || cy < 0 || cy >= N) continue;\n                if (!loaded[i] && is_src[cx][cy] && occupied[cx][cy]) ++pickups;\n                else if (loaded[i] && is_tgt[cx][cy] && !occupied[cx][cy]) ++deliveries;\n            }\n            int score = pickups + deliveries;\n\n            // distance to the nearest still needed square (source or target)\n            int dist = INF;\n            if (mode == 0) { // pickup\n                for (int i = 0; i < N; ++i)\n                    for (int j = 0; j < N; ++j)\n                        if (is_src[i][j] && occupied[i][j])\n                            for (int d = 0; d < 4; ++d) {\n                                int ni = i + DIR_DX[d];\n                                int nj = j + DIR_DY[d];\n                                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                                int ddist = abs(nx - ni) + abs(ny - nj);\n                                dist = min(dist, ddist);\n                            }\n            } else { // delivery\n                for (int i = 0; i < N; ++i)\n                    for (int j = 0; j < N; ++j)\n                        if (is_tgt[i][j] && !occupied[i][j])\n                            for (int d = 0; d < 4; ++d) {\n                                int ni = i + DIR_DX[d];\n                                int nj = j + DIR_DY[d];\n                                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                                int ddist = abs(nx - ni) + abs(ny - nj);\n                                dist = min(dist, ddist);\n                            }\n            }\n\n            // NEW: count how many needed squares become reachable soon (dist \u2264 2)\n            int reach_count = 0;\n            if (mode == 0) { // pickup\n                for (int i = 0; i < N; ++i)\n                    for (int j = 0; j < N; ++j)\n                        if (is_src[i][j] && occupied[i][j])\n                            for (int d = 0; d < 4; ++d) {\n                                int ni = i + DIR_DX[d];\n                                int nj = j + DIR_DY[d];\n                                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                                if (abs(nx - ni) + abs(ny - nj) <= 2) { ++reach_count; break; }\n                            }\n            } else { // delivery\n                for (int i = 0; i < N; ++i)\n                    for (int j = 0; j < N; ++j)\n                        if (is_tgt[i][j] && !occupied[i][j])\n                            for (int d = 0; d < 4; ++d) {\n                                int ni = i + DIR_DX[d];\n                                int nj = j + DIR_DY[d];\n                                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                                if (abs(nx - ni) + abs(ny - nj) <= 2) { ++reach_count; break; }\n                            }\n            }\n\n            // choose best move: higher score, then higher reach_count, then lower dist\n            if (score > best_score ||\n                (score == best_score && reach_count > best_reach) ||\n                (score == best_score && reach_count == best_reach && dist < best_dist)) {\n                best_move = m;\n                best_score = score;\n                best_dist = dist;\n                best_reach = reach_count;\n            }\n        }\n        // if nothing is possible, still move toward the nearest needed square\n        if (best_move == -1) {\n            for (int m = 0; m < 5; ++m) {\n                char mc = MOVE_CHARS[m];\n                int nx = rx + MV_DX[m];\n                int ny = ry + MV_DY[m];\n                if (mc != '.' && (nx < 0 || nx >= N || ny < 0 || ny >= N)) continue;\n                best_move = m; break;\n            }\n        }\n\n        // apply the chosen move and build the operation string\n        char mv = MOVE_CHARS[best_move];\n        int nx = rx + MV_DX[best_move];\n        int ny = ry + MV_DY[best_move];\n        string op;\n        op.push_back(mv);                     // root movement\n        for (int i = 1; i <= C; ++i) op.push_back('.'); // no rotations\n        string act;\n        perform_actions(nx, ny, dir, loaded, loaded_cnt,\n                        is_src, is_tgt, occupied, src_rem, act);\n        op += act;                            // append actions\n        ops.push_back(op);\n        // update root position\n        rx = nx; ry = ny;\n    }\n\n    /* ----- output all operation strings ----- */\n    for (const string &s : ops) cout << s << '\\n';\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Node {\n    int sum;          // total sum of interval\n    int pref;         // max prefix sum (non empty)\n    int pref_r;       // right border of this prefix\n    int suff;         // max suffix sum (non empty)\n    int suff_l;       // left border of this suffix\n    int best;         // max sub\u2011array sum (non empty)\n    int best_l, best_r;   // borders of this sub\u2011array\n};\n\n/* combine two neighbouring nodes, result is stored in c */\nstatic inline void combine(Node &c, const Node &L, const Node &R) {\n    c.sum = L.sum + R.sum;\n\n    // prefix\n    if (L.pref > L.sum + R.pref) {\n        c.pref = L.pref;\n        c.pref_r = L.pref_r;\n    } else {\n        c.pref = L.sum + R.pref;\n        c.pref_r = R.pref_r;\n    }\n\n    // suffix\n    if (R.suff > R.sum + L.suff) {\n        c.suff = R.suff;\n        c.suff_l = R.suff_l;\n    } else {\n        c.suff = R.sum + L.suff;\n        c.suff_l = L.suff_l;\n    }\n\n    // best\n    c.best = L.best;\n    c.best_l = L.best_l;\n    c.best_r = L.best_r;\n\n    if (R.best > c.best) {\n        c.best = R.best;\n        c.best_l = R.best_l;\n        c.best_r = R.best_r;\n    }\n\n    int cross = L.suff + R.pref;\n    if (cross > c.best) {\n        c.best = cross;\n        c.best_l = L.suff_l;\n        c.best_r = R.pref_r;\n    }\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\n    struct Pt { int x, y, xi, yi, w; };\n    vector<Pt> pts;\n    pts.reserve(2 * N);\n    vector<int> xs, ys;\n    for (int i = 0; i < 2 * N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        int w = (i < N) ? +1 : -1;\n        pts.push_back({x, y, -1, -1, w});\n        xs.push_back(x);\n        ys.push_back(y);\n    }\n\n    /* coordinate compression */\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    int X = (int)xs.size();\n    int Y = (int)ys.size();\n\n    for (auto &p : pts) {\n        p.xi = lower_bound(xs.begin(), xs.end(), p.x) - xs.begin();\n        p.yi = lower_bound(ys.begin(), ys.end(), p.y) - ys.begin();\n    }\n\n    /* decide which axis will be the outer sweep */\n    bool sweepX = (X <= Y);          // true \u2192 outer loop over x, tree on y\n    int outerSize = sweepX ? X : Y;\n    int innerSize = sweepX ? Y : X;   // size of the axis stored in the segment tree\n\n    // build the structure \u201cpoints per column\u201d for the outer axis\n    vector<vector<pair<int,int>>> perOuter(outerSize);\n    for (auto &p : pts) {\n        if (sweepX)\n            perOuter[p.xi].push_back({p.yi, p.w});\n        else\n            perOuter[p.yi].push_back({p.xi, p.w});\n    }\n\n    // segment tree for the inner axis\n    int M = 1;\n    while (M < innerSize) M <<= 1;\n    vector<Node> seg(2 * M);\n\n    auto treeReset = [&]() {\n        // whole tree to zero\n        for (int i = 0; i < 2 * M; ++i) {\n            seg[i].sum = seg[i].pref = seg[i].suff = seg[i].best = 0;\n        }\n        // leaf indices (must be set, otherwise the borders of a leaf would be undefined)\n        for (int i = 0; i < innerSize; ++i) {\n            seg[M + i].pref_r = seg[M + i].suff_l = seg[M + i].best_l = seg[M + i].best_r = i;\n        }\n        for (int i = innerSize; i < M; ++i) {\n            seg[M + i].pref_r = seg[M + i].suff_l = seg[M + i].best_l = seg[M + i].best_r = i;\n        }\n        // internal nodes\n        for (int i = M - 1; i >= 1; --i)\n            combine(seg[i], seg[i << 1], seg[i << 1 | 1]);\n    };\n\n    auto treeAdd = [&](int idx, int delta) {\n        int p = M + idx;\n        seg[p].sum += delta;\n        int ns = seg[p].sum;\n        seg[p].pref = seg[p].suff = seg[p].best = ns;\n        for (p >>= 1; p; p >>= 1)\n            combine(seg[p], seg[p << 1], seg[p << 1 | 1]);\n    };\n\n    int bestValue = -1;          // -1 means \u201cno positive rectangle found\u201d\n    int bestL = -1, bestR = -1, bestB = -1, bestT = -1;\n\n    // ----- initialise the tree with the whole range [0 .. outerSize-1] -----\n    for (int right = 0; right < outerSize; ++right)\n        for (auto &pr : perOuter[right])\n            treeAdd(pr.first, pr.second);\n\n    // ----- sweep left side, removing columns one by one -----\n    for (int left = 0; left < outerSize; ++left) {\n        // tree now contains columns [left .. outerSize-1]\n        for (int right = left; right < outerSize; ++right) {\n            const Node &root = seg[1];\n            int cur = root.best;\n            if (cur > bestValue) {\n                bestValue = cur;\n                bestL = left;\n                bestR = right;\n                bestB = root.best_l;\n                bestT = root.best_r;\n            }\n            if (bestValue == N) break;     // cannot improve any more\n        }\n        if (bestValue == N) break;         // stop the whole sweep\n\n        // before moving left forward, delete column left\n        if (left + 1 < outerSize) {        // nothing to delete after the last column\n            for (auto &pr : perOuter[left])\n                treeAdd(pr.first, -pr.second);   // subtract the weight\n        }\n    }\n\n    // -----------------------------------------------------------------\n    // build the final rectangle (swap back if we swept over y)\n    int leftX, rightX, bottomY, topY;\n\n    // arrays that tell which integer coordinates are occupied (for the \u201cempty\u201d extension)\n    vector<char> usedX(100001, 0), usedY(100001, 0);\n    for (auto &p : pts) {\n        usedX[p.x] = 1;\n        usedY[p.y] = 1;\n    }\n\n    auto findUnused = [&](const vector<char> &used, int after) {\n        for (int v = after + 1; v <= 100000; ++v)\n            if (!used[v]) return v;\n        for (int v = after - 1; v >= 0; --v)\n            if (!used[v]) return v;\n        return -1;   // never happens\n    };\n\n    if (bestValue <= 0) {               // no positive rectangle \u2013 use an empty one\n        int x1 = -1, x2 = -1;\n        for (int x = 0; x <= 100000; ++x) if (!usedX[x]) { x1 = x; break; }\n        for (int x = x1 + 1; x <= 100000; ++x) if (!usedX[x]) { x2 = x; break; }\n        int y1 = -1, y2 = -1;\n        for (int y = 0; y <= 100000; ++y) if (!usedY[y]) { y1 = y; break; }\n        for (int y = y1 + 1; y <= 100000; ++y) if (!usedY[y]) { y2 = y; break; }\n        leftX = x1; rightX = x2;\n        bottomY = y1; topY = y2;\n    } else {\n        if (sweepX) {\n            leftX   = xs[bestL];\n            rightX  = xs[bestR];\n            bottomY = ys[bestB];\n            topY    = ys[bestT];\n        } else {\n            leftX   = xs[bestB];\n            rightX  = xs[bestT];\n            bottomY = ys[bestL];\n            topY    = ys[bestR];\n        }\n\n        // make sure both dimensions are positive, using only empty columns / rows\n        if (leftX == rightX) {\n            int nx = findUnused(usedX, leftX);\n            if (nx > leftX) rightX = nx;\n            else {\n                rightX = leftX;\n                leftX = nx;\n            }\n        }\n        if (bottomY == topY) {\n            int ny = findUnused(usedY, bottomY);\n            if (ny > bottomY) topY = ny;\n            else {\n                topY = bottomY;\n                bottomY = ny;\n            }\n        }\n    }\n\n    // -----------------------------------------------------------------\n    // output the rectangle (counter\u2011clockwise order)\n    cout << 4 << \"\\n\";\n    cout << leftX   << ' ' << bottomY << \"\\n\";\n    cout << leftX   << ' ' << topY    << \"\\n\";\n    cout << rightX  << ' ' << topY    << \"\\n\";\n    cout << rightX  << ' ' << bottomY << \"\\n\";\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rectangle {\n    int width, height;\n    int x, y; // top-left corner\n};\n\nstruct Placement {\n    int p; // index\n    int r; // rotation\n    char d; // direction 'U' or 'L'\n    int b; // reference rectangle index\n};\n\nclass Packer {\nprivate:\n    int N;\n    vector<int> w, h;\n    vector<Rectangle> placed;\n    vector<Placement> sequence;\n    \n    // Check if two rectangles overlap\n    bool overlap(const Rectangle& a, const Rectangle& b) {\n        return a.x < b.x + b.width && a.x + a.width > b.x &&\n               a.y < b.y + b.height && a.y + a.height > b.y;\n    }\n    \n    // Simulate placing a rectangle with given parameters\n    // Returns the rectangle with final position\n    Rectangle simulatePlace(int idx, int rot, char dir, int ref) {\n        int width = (rot == 0) ? w[idx] : h[idx];\n        int height = (rot == 0) ? h[idx] : w[idx];\n        \n        Rectangle rect;\n        rect.width = width;\n        rect.height = height;\n        \n        if (dir == 'U') {\n            // Align left edge\n            if (ref == -1) {\n                rect.x = 0;\n            } else {\n                rect.x = placed[ref].x + placed[ref].width;\n            }\n            \n            // Start from bottom and slide up (decrease y)\n            // Find the highest position where it doesn't overlap\n            int best_y = 0;\n            // Check all placed rectangles\n            for (const auto& other : placed) {\n                // Check horizontal overlap\n                if (rect.x < other.x + other.width && rect.x + rect.width > other.x) {\n                    // This rectangle blocks upward movement\n                    best_y = max(best_y, other.y + other.height);\n                }\n            }\n            rect.y = best_y;\n        } else { // 'L'\n            // Align top edge\n            if (ref == -1) {\n                rect.y = 0;\n            } else {\n                rect.y = placed[ref].y + placed[ref].height;\n            }\n            \n            // Start from far right and slide left (decrease x)\n            int best_x = 0;\n            // Check all placed rectangles\n            for (const auto& other : placed) {\n                // Check vertical overlap\n                if (rect.y < other.y + other.height && rect.y + rect.height > other.y) {\n                    // This rectangle blocks leftward movement\n                    best_x = max(best_x, other.x + other.width);\n                }\n            }\n            rect.x = best_x;\n        }\n        \n        return rect;\n    }\n    \npublic:\n    Packer(const vector<int>& w, const vector<int>& h) \n        : N(w.size()), w(w), h(h) {}\n    \n    // Generate a random placement sequence\n    pair<vector<Placement>, long long> generateRandom(mt19937& rng) {\n        placed.clear();\n        sequence.clear();\n        \n        // Randomly decide which rectangles to place\n        // For now, try to place all\n        vector<int> placed_indices;\n        long long totalWH = 0;\n        \n        for (int i = 0; i < N; i++) {\n            // Randomly decide to place or skip\n            uniform_real_distribution<double> dist(0.0, 1.0);\n            bool place = dist(rng) < 0.9; // 90% chance to place\n            \n            if (!place) {\n                totalWH += w[i] + h[i];\n                continue;\n            }\n            \n            // Random rotation, direction, reference\n            uniform_int_distribution<int> rot_dist(0, 1);\n            uniform_int_distribution<int> dir_dist(0, 1);\n            uniform_int_distribution<int> ref_dist(-1, (int)placed_indices.size() - 1);\n            \n            int r = rot_dist(rng);\n            char d = (dir_dist(rng) == 0) ? 'U' : 'L';\n            int b = ref_dist(rng);\n            \n            // Simulate placement\n            Rectangle rect = simulatePlace(i, r, d, b);\n            \n            // Check for overlap (shouldn't happen with our algorithm)\n            bool overlaps = false;\n            for (const auto& other : placed) {\n                if (overlap(rect, other)) {\n                    overlaps = true;\n                    break;\n                }\n            }\n            \n            if (overlaps) {\n                // Fallback: skip this rectangle\n                totalWH += w[i] + h[i];\n                continue;\n            }\n            \n            // Add to placed\n            placed.push_back(rect);\n            placed_indices.push_back(i);\n            \n            // Record placement\n            Placement p;\n            p.p = i;\n            p.r = r;\n            p.d = d;\n            p.b = b;\n            sequence.push_back(p);\n        }\n        \n        // Calculate bounding box\n        int maxX = 0, maxY = 0;\n        for (const auto& rect : placed) {\n            maxX = max(maxX, rect.x + rect.width);\n            maxY = max(maxY, rect.y + rect.height);\n        }\n        \n        long long score = (long long)maxX + maxY + totalWH;\n        return {sequence, score};\n    }\n    \n    // Generate a greedy placement sequence\n    pair<vector<Placement>, long long> generateGreedy() {\n        placed.clear();\n        sequence.clear();\n        long long totalWH = 0;\n        \n        for (int i = 0; i < N; i++) {\n            // Try to place rectangle i\n            int best_r = 0;\n            char best_d = 'U';\n            int best_b = -1;\n            long long bestScore = LLONG_MAX;\n            Rectangle bestRect;\n            \n            // Try all combinations\n            for (int r = 0; r <= 1; r++) {\n                for (char d : {'U', 'L'}) {\n                    // Try references: -1 and all previously placed\n                    vector<int> refs;\n                    refs.push_back(-1);\n                    for (int j = 0; j < (int)placed.size(); j++) {\n                        refs.push_back(j);\n                    }\n                    \n                    for (int b : refs) {\n                        Rectangle rect = simulatePlace(i, r, d, b);\n                        \n                        // Check overlap\n                        bool overlaps = false;\n                        for (const auto& other : placed) {\n                            if (overlap(rect, other)) {\n                                overlaps = true;\n                                break;\n                            }\n                        }\n                        if (overlaps) continue;\n                        \n                        // Calculate new bounding box with this rectangle\n                        int maxX = 0, maxY = 0;\n                        for (const auto& p : placed) {\n                            maxX = max(maxX, p.x + p.width);\n                            maxY = max(maxY, p.y + p.height);\n                        }\n                        maxX = max(maxX, rect.x + rect.width);\n                        maxY = max(maxY, rect.y + rect.height);\n                        \n                        long long score = (long long)maxX + maxY;\n                        \n                        if (score < bestScore) {\n                            bestScore = score;\n                            best_r = r;\n                            best_d = d;\n                            best_b = b;\n                            bestRect = rect;\n                        }\n                    }\n                }\n            }\n            \n            // Decide whether to place or skip\n            // Calculate current bounding box\n            int curMaxX = 0, curMaxY = 0;\n            for (const auto& p : placed) {\n                curMaxX = max(curMaxX, p.x + p.width);\n                curMaxY = max(curMaxY, p.y + p.height);\n            }\n            long long curScore = (long long)curMaxX + curMaxY;\n            \n            if (bestScore > curScore + w[i] + h[i]) {\n                // Skip this rectangle\n                totalWH += w[i] + h[i];\n            } else {\n                // Place it\n                placed.push_back(bestRect);\n                Placement p;\n                p.p = i;\n                p.r = best_r;\n                p.d = best_d;\n                p.b = best_b;\n                sequence.push_back(p);\n            }\n        }\n        \n        // Calculate final bounding box\n        int maxX = 0, maxY = 0;\n        for (const auto& rect : placed) {\n            maxX = max(maxX, rect.x + rect.width);\n            maxY = max(maxY, rect.y + rect.height);\n        }\n        \n        long long score = (long long)maxX + maxY + totalWH;\n        return {sequence, score};\n    }\n    \n    // Get the best sequence found so far (for repeated output)\n    const vector<Placement>& getBestSequence() const {\n        return sequence;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, T, sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n    \n    vector<int> w(N), h(N);\n    for (int i = 0; i < N; i++) {\n        cin >> w[i] >> h[i];\n    }\n    \n    Packer packer(w, h);\n    \n    // Random number generator\n    random_device rd;\n    mt19937 rng(rd());\n    \n    // Try to find a good solution first\n    long long bestScore = LLONG_MAX;\n    vector<Placement> bestSequence;\n    \n    // Spend some time finding a good solution\n    // We'll try greedy first\n    auto [greedySeq, greedyScore] = packer.generateGreedy();\n    if (greedyScore < bestScore) {\n        bestScore = greedyScore;\n        bestSequence = greedySeq;\n    }\n    \n    // Then try random improvements\n    int attempts = min(T, 50); // Use up to 50 attempts for search\n    for (int attempt = 0; attempt < attempts; attempt++) {\n        auto [seq, score] = packer.generateRandom(rng);\n        if (score < bestScore) {\n            bestScore = score;\n            bestSequence = seq;\n        }\n    }\n    \n    // Output placements for each turn\n    for (int turn = 0; turn < T; turn++) {\n        // Output best sequence we found\n        cout << bestSequence.size() << \"\\n\";\n        for (const auto& p : bestSequence) {\n            cout << p.p << \" \" << p.r << \" \" << p.d << \" \" << p.b << \"\\n\";\n        }\n        cout << flush;\n        \n        // Read measured W' and H'\n        int Wp, Hp;\n        cin >> Wp >> Hp;\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Tree {\n    int N;                                 // number of vertices\n    int H;                                 // maximal depth (given as 10)\n    const vector<int> &A;                  // beauty values\n    const vector<vector<int>> &adj;        // graph\n    long long sumAAll;                     // \u03a3 A[v]  (constant part of score)\n\n    vector<int> parent;                    // parent[v]  ( -1 for a root )\n    vector<int> depth;                     // depth[v]   (0 \u2026 H)\n    vector<int> sumA;                      // S[v]  \u2013 sum of beauties in subtree\n    vector<int> high;                      // H[v]  \u2013 longest distance to a leaf\n    vector<vector<int>> children;          // children of each vertex\n    long long totalDepthSum;               // \u03a3 depth[v] * A[v]\n\n    // ---------- constructor (all roots) ----------\n    Tree(int N_, int H_, const vector<int> &A_, const vector<vector<int>> &adj_)\n        : N(N_), H(H_), A(A_), adj(adj_) {\n        sumAAll = 0;\n        for (int x : A) sumAAll += x;\n        parent.assign(N, -1);\n        depth.assign(N, 0);\n        sumA = A;                 // each subtree consists only of the vertex itself\n        high.assign(N, 0);\n        children.assign(N, {});\n        totalDepthSum = 0;\n    }\n\n    // ---------- utility ----------\n    bool isDescendant(int anc, int desc) const {\n        int cur = desc;\n        while (cur != -1) {\n            if (cur == anc) return true;\n            cur = parent[cur];\n        }\n        return false;\n    }\n\n    void detach(int v) {\n        int p = parent[v];\n        if (p != -1) {\n            auto &vec = children[p];\n            for (size_t i = 0; i < vec.size(); ++i) {\n                if (vec[i] == v) {\n                    vec.erase(vec.begin() + i);\n                    break;\n                }\n            }\n        }\n        parent[v] = -1;                 // v becomes a root of its own tree\n    }\n\n    void attach(int v, int newParent) {\n        parent[v] = newParent;\n        if (newParent != -1) children[newParent].push_back(v);\n    }\n\n    void applyDepthDelta(int v, int delta) {\n        depth[v] += delta;\n        for (int c : children[v]) applyDepthDelta(c, delta);\n    }\n\n    // recompute sumA and high on the path from v upwards (at most H steps)\n    void recomputeUpward(int v) {\n        while (v != -1) {\n            int s = A[v];\n            int h = 0;\n            for (int c : children[v]) {\n                s += sumA[c];\n                h = max(h, high[c] + 1);\n            }\n            sumA[v] = s;\n            high[v] = h;\n            v = parent[v];\n        }\n    }\n\n    // evaluate a possible move of subtree v to newParent ( -1 = root )\n    // returns {newDepth, gain}  ; gain = -inf if illegal\n    pair<int,long long> evaluateMove(int v, int newParent) const {\n        if (newParent == parent[v]) return {depth[v], 0};          // no change\n        if (newParent != -1 && isDescendant(v, newParent))\n            return {0, LLONG_MIN};                               // would create a cycle\n\n        int newDepth = (newParent == -1 ? 0 : depth[newParent] + 1);\n        if (newDepth + high[v] > H) return {0, LLONG_MIN};       // height violation\n\n        long long delta = (long long)newDepth - (long long)depth[v];\n        long long gain = delta * (long long)sumA[v];\n        return {newDepth, gain};\n    }\n\n    // really perform a move (already known to be legal)\n    void performMove(int v, int newParent, int newDepth) {\n        int oldParent = parent[v];\n        int oldDepth  = depth[v];\n\n        // detach\n        detach(v);\n        if (oldParent != -1) recomputeUpward(oldParent);\n\n        // attach to new parent\n        attach(v, newParent);\n\n        // shift depths inside the whole subtree\n        int delta = newDepth - oldDepth;\n        if (delta != 0) applyDepthDelta(v, delta);\n\n        // recompute sums on the new side\n        if (newParent != -1) recomputeUpward(newParent);\n        else                 recomputeUpward(v);\n\n        totalDepthSum += (long long)delta * (long long)sumA[v];\n    }\n\n    // ---------- greedy hill climbing ----------\n    void greedyPhase(mt19937 &rng, int maxPasses = 30) {\n        bool improved = true;\n        int passes = 0;\n        while (improved && passes < maxPasses) {\n            improved = false;\n            vector<int> order(N);\n            iota(order.begin(), order.end(), 0);\n            shuffle(order.begin(), order.end(), rng);\n            for (int v : order) {\n                int bestParent = -2;\n                int bestDepth  = depth[v];\n                long long bestGain = 0;\n                // try all neighbours\n                for (int u : adj[v]) {\n                    if (u == parent[v]) continue;\n                    auto [newDepth, gain] = evaluateMove(v, u);\n                    if (gain > bestGain) {\n                        bestGain = gain;\n                        bestParent = u;\n                        bestDepth  = newDepth;\n                    }\n                }\n                // also try becoming a root (gain is never positive here)\n                if (bestGain > 0) {\n                    performMove(v, bestParent, bestDepth);\n                    improved = true;\n                }\n            }\n            ++passes;\n        }\n    }\n\n    // ---------- simulated annealing ----------\n    void annealingPhase(mt19937 &rng, double timeLimit) {\n        const double START_TEMP = 2e6;          // a bit larger than maximal possible gain\n        const double END_TEMP   = 1.0;\n        auto start = chrono::steady_clock::now();\n\n        double temp = START_TEMP;\n        uniform_int_distribution<int> VertDist(0, N - 1);\n        uniform_real_distribution<double> ProbDist(0.0, 1.0);\n\n        // iterate until the time budget is exhausted\n        while (true) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - start).count();\n            if (elapsed > timeLimit) break;\n\n            // cooling schedule \u2013 exponential, slower than linear\n            double progress = elapsed / timeLimit;                 // 0 \u2026 1\n            temp = START_TEMP * pow(END_TEMP / START_TEMP, progress);\n\n            int v = VertDist(rng);\n            if (adj[v].empty()) continue;   // never happens (graph is connected)\n\n            // with probability 0.25 try to make the vertex a root,\n            // otherwise pick a random neighbour as new parent\n            int newParent;\n            if (ProbDist(rng) < 0.25) {\n                newParent = -1;\n            } else {\n                int idx = uniform_int_distribution<int>(0, (int)adj[v].size() - 1)(rng);\n                newParent = adj[v][idx];\n            }\n\n            auto [newDepth, gain] = evaluateMove(v, newParent);\n            if (gain == LLONG_MIN) continue;   // illegal\n\n            bool accept = false;\n            if (gain > 0) accept = true;\n            else if (temp > 1e-12) {\n                double prob = exp(gain / temp);\n                if (prob > ProbDist(rng)) accept = true;\n            }\n            if (!accept) continue;\n\n            performMove(v, newParent, newDepth);\n        }\n    }\n\n    long long totalScore() const {\n        return sumAAll + totalDepthSum;\n    }\n};\n\n// -----------------------------------------------------------------------\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, H;\n    if (!(cin >> N >> M >> H)) return 0;\n\n    vector<int> A(N);\n    for (int i = 0; i < N; ++i) cin >> A[i];\n\n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; ++i) {\n        int u, v; cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    // read and discard coordinates\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n    }\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    long long bestScore = 0;\n    vector<int> bestParent(N, -1);\n    {\n        Tree tree(N, H, A, adj);\n        bestScore = tree.totalScore();\n        bestParent = tree.parent;\n    }\n\n    auto start = chrono::steady_clock::now();\n\n    // ---- several restarts (as long as time permits) ----\n    int rounds = 0;\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > 1.85) break;          // total time limit\n\n        Tree tree(N, H, A, adj);\n        tree.greedyPhase(rng, 30);           // up to 30 passes\n\n        // a short but intensive annealing phase\n        double timeLeft = 1.85 - elapsed;\n        if (timeLeft > 0.3) {\n            tree.annealingPhase(rng, timeLeft * 0.75);\n            // final polishing greedy pass\n            tree.greedyPhase(rng, 10);\n        }\n\n        long long cur = tree.totalScore();\n        if (cur > bestScore) {\n            bestScore = cur;\n            bestParent = tree.parent;\n        }\n        ++rounds;\n    }\n\n    // ---------------------------------------------------------------\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << bestParent[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Oni {\n    int i, j;                     // position\n    int upDist, downDist, leftDist, rightDist;\n    bool upSafe, downSafe, leftSafe, rightSafe;\n};\n\n/* -------------------------------------------------------------\n   simulate the whole sequence, respecting the decisions\n   columnsFirst = true  -> columns first, rows afterwards\n   columnsFirst = false -> rows first, columns afterwards\n   moves will be filled with the produced sequence.\n   ------------------------------------------------------------- */\nint simulate(bool columnsFirst,\n             const vector<Oni>& oni,\n             vector<pair<char,int>>& moves) {\n    const int N = 20;                     // board size (fixed in the problem)\n    const int M = (int)oni.size();        // 2*N\n\n    vector<char> removed(M, 0);           // 0 = still on board, 1 = removed\n    int totalMoves = 0;\n    auto addBlock = [&](char dir, int idx, int cnt) {\n        for (int k = 0; k < cnt; ++k) moves.emplace_back(dir, idx);\n        totalMoves += 2 * cnt;            // each block consists of a pair of shifts\n    };\n\n    if (columnsFirst) {\n        // -------------------------------------------------------------\n        // ----- 1. columns (up/down) -----\n        for (int col = 0; col < N; ++col) {\n            // compute the four values for this column\n            int upAll = 0, downAll = 0, upOnly = 0, downOnly = 0;\n            for (int id = 0; id < M; ++id) {\n                const Oni& o = oni[id];\n                if (o.j != col) continue;\n                if (o.upSafe) {\n                    upAll = max(upAll, o.upDist);\n                    if (!o.downSafe) upOnly = max(upOnly, o.upDist);\n                }\n                if (o.downSafe) {\n                    downAll = max(downAll, o.downDist);\n                    if (!o.upSafe) downOnly = max(downOnly, o.downDist);\n                }\n            }\n            // choose the cheaper order\n            bool upFirst = (2 * (upAll + downOnly) <= 2 * (downAll + upOnly));\n\n            if (upFirst) {\n                // up phase\n                int upMax = 0; vector<int> ids;\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.j == col && o.upSafe) {\n                        upMax = max(upMax, o.upDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (upMax) {\n                    addBlock('U', col, upMax);\n                    addBlock('D', col, upMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n                // down phase (only down\u2011safe that are still alive)\n                int downMax = 0; ids.clear();\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.j == col && o.downSafe) {\n                        downMax = max(downMax, o.downDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (downMax) {\n                    addBlock('D', col, downMax);\n                    addBlock('U', col, downMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n            } else {\n                // down phase first\n                int downMax = 0; vector<int> ids;\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.j == col && o.downSafe) {\n                        downMax = max(downMax, o.downDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (downMax) {\n                    addBlock('D', col, downMax);\n                    addBlock('U', col, downMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n                // up phase (only up\u2011safe that are still alive)\n                int upMax = 0; ids.clear();\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.j == col && o.upSafe) {\n                        upMax = max(upMax, o.upDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (upMax) {\n                    addBlock('U', col, upMax);\n                    addBlock('D', col, upMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n            }\n        }\n\n        // -------------------------------------------------------------\n        // ----- 2. rows (left/right) -----\n        for (int row = 0; row < N; ++row) {\n            // recompute the four values using the still alive Oni\n            int leftAll = 0, rightAll = 0, leftOnly = 0, rightOnly = 0;\n            for (int id = 0; id < M; ++id) {\n                const Oni& o = oni[id];\n                if (removed[id] || o.i != row) continue;\n                if (o.leftSafe) {\n                    leftAll = max(leftAll, o.leftDist);\n                    if (!o.rightSafe) leftOnly = max(leftOnly, o.leftDist);\n                }\n                if (o.rightSafe) {\n                    rightAll = max(rightAll, o.rightDist);\n                    if (!o.leftSafe) rightOnly = max(rightOnly, o.rightDist);\n                }\n            }\n            bool leftFirst = (2 * (leftAll + rightOnly) <= 2 * (rightAll + leftOnly));\n\n            if (leftFirst) {\n                // left phase\n                int leftMax = 0; vector<int> ids;\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.i == row && o.leftSafe) {\n                        leftMax = max(leftMax, o.leftDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (leftMax) {\n                    addBlock('L', row, leftMax);\n                    addBlock('R', row, leftMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n                // right phase (only right\u2011safe still alive)\n                int rightMax = 0; ids.clear();\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.i == row && o.rightSafe) {\n                        rightMax = max(rightMax, o.rightDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (rightMax) {\n                    addBlock('R', row, rightMax);\n                    addBlock('L', row, rightMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n            } else {\n                // right phase first\n                int rightMax = 0; vector<int> ids;\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.i == row && o.rightSafe) {\n                        rightMax = max(rightMax, o.rightDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (rightMax) {\n                    addBlock('R', row, rightMax);\n                    addBlock('L', row, rightMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n                // left phase (only left\u2011safe still alive)\n                int leftMax = 0; ids.clear();\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.i == row && o.leftSafe) {\n                        leftMax = max(leftMax, o.leftDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (leftMax) {\n                    addBlock('L', row, leftMax);\n                    addBlock('R', row, leftMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n            }\n        }\n    } else {\n        // -------------------------------------------------------------\n        // ----- rows first, symmetric -----\n        for (int row = 0; row < N; ++row) {\n            int leftAll = 0, rightAll = 0, leftOnly = 0, rightOnly = 0;\n            for (int id = 0; id < M; ++id) {\n                const Oni& o = oni[id];\n                if (o.i != row) continue;\n                if (o.leftSafe) {\n                    leftAll = max(leftAll, o.leftDist);\n                    if (!o.rightSafe) leftOnly = max(leftOnly, o.leftDist);\n                }\n                if (o.rightSafe) {\n                    rightAll = max(rightAll, o.rightDist);\n                    if (!o.leftSafe) rightOnly = max(rightOnly, o.rightDist);\n                }\n            }\n            bool leftFirst = (2 * (leftAll + rightOnly) <= 2 * (rightAll + leftOnly));\n\n            if (leftFirst) {\n                int leftMax = 0; vector<int> ids;\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.i == row && o.leftSafe) {\n                        leftMax = max(leftMax, o.leftDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (leftMax) {\n                    addBlock('L', row, leftMax);\n                    addBlock('R', row, leftMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n                int rightMax = 0; ids.clear();\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.i == row && o.rightSafe) {\n                        rightMax = max(rightMax, o.rightDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (rightMax) {\n                    addBlock('R', row, rightMax);\n                    addBlock('L', row, rightMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n            } else {\n                int rightMax = 0; vector<int> ids;\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.i == row && o.rightSafe) {\n                        rightMax = max(rightMax, o.rightDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (rightMax) {\n                    addBlock('R', row, rightMax);\n                    addBlock('L', row, rightMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n                int leftMax = 0; ids.clear();\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.i == row && o.leftSafe) {\n                        leftMax = max(leftMax, o.leftDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (leftMax) {\n                    addBlock('L', row, leftMax);\n                    addBlock('R', row, leftMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n            }\n        }\n\n        // ----- columns afterwards -----\n        for (int col = 0; col < N; ++col) {\n            int upAll = 0, downAll = 0, upOnly = 0, downOnly = 0;\n            for (int id = 0; id < M; ++id) {\n                const Oni& o = oni[id];\n                if (removed[id] || o.j != col) continue;\n                if (o.upSafe) {\n                    upAll = max(upAll, o.upDist);\n                    if (!o.downSafe) upOnly = max(upOnly, o.upDist);\n                }\n                if (o.downSafe) {\n                    downAll = max(downAll, o.downDist);\n                    if (!o.upSafe) downOnly = max(downOnly, o.downDist);\n                }\n            }\n            bool upFirst = (2 * (upAll + downOnly) <= 2 * (downAll + upOnly));\n\n            if (upFirst) {\n                int upMax = 0; vector<int> ids;\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.j == col && o.upSafe) {\n                        upMax = max(upMax, o.upDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (upMax) {\n                    addBlock('U', col, upMax);\n                    addBlock('D', col, upMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n                int downMax = 0; ids.clear();\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.j == col && o.downSafe) {\n                        downMax = max(downMax, o.downDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (downMax) {\n                    addBlock('D', col, downMax);\n                    addBlock('U', col, downMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n            } else {\n                int downMax = 0; vector<int> ids;\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.j == col && o.downSafe) {\n                        downMax = max(downMax, o.downDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (downMax) {\n                    addBlock('D', col, downMax);\n                    addBlock('U', col, downMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n                int upMax = 0; ids.clear();\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.j == col && o.upSafe) {\n                        upMax = max(upMax, o.upDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (upMax) {\n                    addBlock('U', col, upMax);\n                    addBlock('D', col, upMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n            }\n        }\n    }\n\n    // sanity check \u2013 all Oni must be removed now\n    // (the input guarantees this is possible)\n    return totalMoves;\n}\n\n/* ------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;                                   // N = 20 in the contest\n    if (!(cin >> N)) return 0;\n    vector<string> board(N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n\n    // locate Fuku (only needed for the safety test)\n    vector<vector<bool>> fuku(N, vector<bool>(N, false));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (board[i][j] == 'o') fuku[i][j] = true;\n\n    // -----------------------------------------------------------------\n    // build the list of Oni and compute safety flags\n    vector<Oni> oni;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (board[i][j] == 'x') {\n                Oni o;\n                o.i = i; o.j = j;\n                o.upDist   = i + 1;\n                o.downDist = N - i;\n                o.leftDist = j + 1;\n                o.rightDist = N - j;\n\n                // safety flags\n                o.upSafe = true;\n                for (int ii = 0; ii < i; ++ii) if (fuku[ii][j]) { o.upSafe = false; break; }\n                o.downSafe = true;\n                for (int ii = i + 1; ii < N; ++ii) if (fuku[ii][j]) { o.downSafe = false; break; }\n                o.leftSafe = true;\n                for (int jj = 0; jj < j; ++jj) if (fuku[i][jj]) { o.leftSafe = false; break; }\n                o.rightSafe = true;\n                for (int jj = j + 1; jj < N; ++jj) if (fuku[i][jj]) { o.rightSafe = false; break; }\n\n                oni.push_back(o);\n            }\n\n    // -----------------------------------------------------------------\n    // try both global orders and keep the better one\n    vector<pair<char,int>> moves1, moves2;\n    int cost1 = simulate(true,  oni, moves1);   // columns first\n    int cost2 = simulate(false, oni, moves2);   // rows first\n\n    const auto& bestMoves = (cost1 <= cost2) ? moves1 : moves2;\n\n    // -----------------------------------------------------------------\n    // output the chosen sequence\n    for (auto [dir, idx] : bestMoves) cout << dir << ' ' << idx << '\\n';\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    \n    const int N = 100;\n    const long long L = 500000;\n    const long long AVG = L / N; // 5000\n    const long long STEP = 2500;  // Base adjustment\n    \n    vector<long long> T(N);\n    int n_input;\n    long long l_input;\n    cin >> n_input >> l_input;\n    for (int i = 0; i < N; ++i) cin >> T[i];\n    \n    const long long INF = (1LL << 60);\n    long long best_error = INF;\n    vector<int> best_x(N);\n    \n    // Phase 1: DP for odd transitions (proven core)\n    for (int x0 = 0; x0 <= 1; ++x0) {\n        static long long dp[101][2];\n        static int parent[101][2];\n        \n        dp[0][0] = dp[0][1] = INF;\n        dp[0][x0] = 0;\n        parent[0][x0] = -1;\n        \n        for (int i = 1; i < N; ++i) {\n            dp[i][0] = dp[i][1] = INF;\n            for (int x_curr = 0; x_curr <= 1; ++x_curr) {\n                for (int x_prev = 0; x_prev <= 1; ++x_prev) {\n                    if (dp[i-1][x_prev] == INF) continue;\n                    \n                    long long visits = AVG + STEP * (x_curr - x_prev);\n                    long long error = llabs(T[i] - visits);\n                    long long total = dp[i-1][x_prev] + error;\n                    \n                    if (total < dp[i][x_curr]) {\n                        dp[i][x_curr] = total;\n                        parent[i][x_curr] = x_prev;\n                    }\n                }\n            }\n        }\n        \n        for (int x_last = 0; x_last <= 1; ++x_last) {\n            if (dp[N-1][x_last] == INF) continue;\n            \n            long long visits = AVG + STEP * (x0 - x_last);\n            long long error = llabs(T[0] - visits);\n            long long total = dp[N-1][x_last] + error;\n            \n            if (total < best_error) {\n                best_error = total;\n                best_x[0] = x0;\n                int curr = x_last;\n                for (int i = N-1; i >= 1; --i) {\n                    best_x[i] = curr;\n                    curr = parent[i][curr];\n                }\n            }\n        }\n    }\n    \n    // Phase 2: Single-pass threshold-based even refinement (SAFE)\n    vector<int> y(N, 0); // even modifications\n    \n    for (int i = 0; i < N; ++i) {\n        // Only modify if no odd self-loop (prevents double-loop)\n        // and only if T_i is significantly above average\n        if (best_x[i] == 0 && T[i] > 6500) {\n            y[i] = 1; // Add 2,500 visits via even self-loop\n        } else {\n            y[i] = 0; // Keep default\n        }\n    }\n    \n    // Phase 3: Construct final answer\n    vector<int> a(N), b(N);\n    for (int i = 0; i < N; ++i) {\n        a[i] = (best_x[i] == 1) ? i : (i + 1) % N;\n        b[i] = (y[i] == 1) ? i : (i + 1) % N;\n    }\n    \n    // Output\n    for (int i = 0; i < N; ++i) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ---------- integer square root ---------- */\nint isqrt_ll(long long x) {\n    int r = (int)std::sqrt((long double)x);\n    while ((long long)(r + 1) * (r + 1) <= x) ++r;\n    while ((long long)r * r > x) --r;\n    return r;\n}\n\n/* ---------- DSU ---------- */\nstruct DSU {\n    vector<int> parent, sz;\n    int comps;\n    DSU(int n = 0) { init(n); }\n    void init(int n) {\n        parent.resize(n);\n        sz.assign(n, 1);\n        iota(parent.begin(), parent.end(), 0);\n        comps = n;\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 (sz[a] < sz[b]) swap(a, b);\n        parent[b] = a;\n        sz[a] += sz[b];\n        --comps;\n        return true;\n    }\n};\n\n/* ---------- lower\u2011bound distance between two rectangles ---------- */\nint lowerDistRect(int i, int j,\n                  const vector<int>& lx, const vector<int>& rx,\n                  const vector<int>& ly, const vector<int>& ry) {\n    long long dx = 0, dy = 0;\n    if (rx[i] < lx[j]) dx = (long long)lx[j] - rx[i];\n    else if (rx[j] < lx[i]) dx = (long long)lx[i] - rx[j];\n    else dx = 0;\n\n    if (ry[i] < ly[j]) dy = (long long)ly[j] - ry[i];\n    else if (ry[j] < ly[i]) dy = (long long)ly[i] - ry[j];\n    else dy = 0;\n\n    long long sq = dx * dx + dy * dy;\n    return isqrt_ll(sq);\n}\n\n/* ---------- Hilbert order ---------- */\nvoid rot(int &x, int &y, int rx, int ry, int s) {\n    if (ry == 0) {\n        if (rx == 1) {\n            x = s - 1 - x;\n            y = s - 1 - y;\n        }\n        swap(x, y);\n    }\n}\nint hilbert(int x, int y, int N = 21) {\n    int h = 0, s = 1 << N;\n    for (int rx, ry, s2; s > 1; s = s2) {\n        s2 = s / 2;\n        rx = (x & s2) ? 1 : 0;\n        ry = (y & s2) ? 1 : 0;\n        h += s2 * s2 * ((3 * rx) ^ ry);\n        rot(x, y, rx, ry, s2);\n    }\n    return h;\n}\n\n/* ---------- Morton (Z) order ---------- */\nint morton(int x, int y) {\n    unsigned int mx = (unsigned int)x;\n    unsigned int my = (unsigned int)y;\n    mx = (mx | (mx << 8)) & 0x00FF00FF;\n    mx = (mx | (mx << 4)) & 0x0F0F0F0F;\n    mx = (mx | (mx << 2)) & 0x33333333;\n    mx = (mx | (mx << 1)) & 0x55555555;\n\n    my = (my | (my << 8)) & 0x00FF00FF;\n    my = (my | (my << 4)) & 0x0F0F0F0F;\n    my = (my | (my << 2)) & 0x33333333;\n    my = (my | (my << 1)) & 0x55555555;\n\n    return (int)(mx | (my << 1));\n}\n\n/* ---------- estimate total lower\u2011bound MST cost for a partition ---------- */\nlong long estimate_partition_cost(const vector<vector<int>>& groups,\n                                  const vector<vector<int>>& low) {\n    long long total = 0;\n    for (const auto& g : groups) {\n        int sz = g.size();\n        if (sz <= 1) continue;\n        // Prim's algorithm on lower bounds\n        vector<int> minDist(sz, INT_MAX);\n        vector<bool> inTree(sz, false);\n        inTree[0] = true;\n        for (int i = 1; i < sz; ++i)\n            minDist[i] = low[g[0]][g[i]];\n        for (int i = 1; i < sz; ++i) {\n            int best = -1, bestDist = INT_MAX;\n            for (int j = 0; j < sz; ++j)\n                if (!inTree[j] && minDist[j] < bestDist) {\n                    bestDist = minDist[j];\n                    best = j;\n                }\n            total += bestDist;\n            inTree[best] = true;\n            for (int j = 0; j < sz; ++j)\n                if (!inTree[j]) {\n                    int d = low[g[best]][g[j]];\n                    if (d < minDist[j]) minDist[j] = d;\n                }\n        }\n    }\n    return total;\n}\n\n/* ---------- build partition from a linear order ---------- */\nvector<vector<int>> make_partition_from_order(const vector<int>& order,\n                                               const vector<int>& G) {\n    vector<vector<int>> groups(G.size());\n    int pos = 0;\n    for (size_t i = 0; i < G.size(); ++i) {\n        groups[i].reserve(G[i]);\n        for (int j = 0; j < G[i]; ++j)\n            groups[i].push_back(order[pos++]);\n    }\n    return groups;\n}\n\n/* ---------- main ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, Q, L, W;\n    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    vector<int> lx(N), rx(N), ly(N), ry(N);\n    for (int i = 0; i < N; ++i) cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n\n    /* ----- pre\u2011compute lower bounds ----- */\n    vector<vector<int>> low(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        low[i][i] = 0;\n        for (int j = i + 1; j < N; ++j) {\n            int d = lowerDistRect(i, j, lx, rx, ly, ry);\n            low[i][j] = low[j][i] = d;\n        }\n    }\n\n    /* ----- centres ----- */\n    vector<int> cx(N), cy(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    /* ----- five candidate partitions ----- */\n    // 1. Hilbert\n    vector<int> order_hilbert(N);\n    iota(order_hilbert.begin(), order_hilbert.end(), 0);\n    sort(order_hilbert.begin(), order_hilbert.end(),\n         [&](int a, int b) { return hilbert(cx[a], cy[a]) < hilbert(cx[b], cy[b]); });\n    auto part_hilbert = make_partition_from_order(order_hilbert, G);\n    long long cost_hilbert = estimate_partition_cost(part_hilbert, low);\n\n    // 2. Morton\n    vector<int> order_morton(N);\n    iota(order_morton.begin(), order_morton.end(), 0);\n    sort(order_morton.begin(), order_morton.end(),\n         [&](int a, int b) { return morton(cx[a], cy[a]) < morton(cx[b], cy[b]); });\n    auto part_morton = make_partition_from_order(order_morton, G);\n    long long cost_morton = estimate_partition_cost(part_morton, low);\n\n    // 3. lexicographic (x, y)\n    vector<int> order_xy(N);\n    iota(order_xy.begin(), order_xy.end(), 0);\n    sort(order_xy.begin(), order_xy.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    auto part_xy = make_partition_from_order(order_xy, G);\n    long long cost_xy = estimate_partition_cost(part_xy, low);\n\n    // 4. lexicographic (y, x)\n    vector<int> order_yx(N);\n    iota(order_yx.begin(), order_yx.end(), 0);\n    sort(order_yx.begin(), order_yx.end(),\n         [&](int a, int b) {\n             if (cy[a] != cy[b]) return cy[a] < cy[b];\n             return cx[a] < cx[b];\n         });\n    auto part_yx = make_partition_from_order(order_yx, G);\n    long long cost_yx = estimate_partition_cost(part_yx, low);\n\n    // 5. distance from origin (0,0)\n    vector<int> order_dist(N);\n    iota(order_dist.begin(), order_dist.end(), 0);\n    sort(order_dist.begin(), order_dist.end(),\n         [&](int a, int b) {\n             long long da = (long long)cx[a] * cx[a] + (long long)cy[a] * cy[a];\n             long long db = (long long)cx[b] * cx[b] + (long long)cy[b] * cy[b];\n             return da < db;\n         });\n    auto part_dist = make_partition_from_order(order_dist, G);\n    long long cost_dist = estimate_partition_cost(part_dist, low);\n\n    // keep the cheapest partition\n    vector<vector<int>> groups = part_hilbert;\n    long long best_cost = cost_hilbert;\n    if (cost_morton < best_cost) {\n        groups = part_morton;\n        best_cost = cost_morton;\n    }\n    if (cost_xy < best_cost) {\n        groups = part_xy;\n        best_cost = cost_xy;\n    }\n    if (cost_yx < best_cost) {\n        groups = part_yx;\n        best_cost = cost_yx;\n    }\n    if (cost_dist < best_cost) {\n        groups = part_dist;\n        best_cost = cost_dist;\n    }\n\n    /* ----- auxiliary data ----- */\n    vector<int> group_of(N, -1);\n    vector<int> local_idx(N, -1);\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < (int)groups[i].size(); ++j) {\n            int city = groups[i][j];\n            group_of[city] = i;\n            local_idx[city] = j;\n        }\n    }\n\n    /* ----- DSU and query structures ----- */\n    vector<DSU> dsu(M);\n    for (int i = 0; i < M; ++i) dsu[i].init((int)groups[i].size());\n\n    vector<vector<pair<int,int>>> group_edges(M);\n\n    int queries_used = 0;\n    while (queries_used < Q) {\n        int best_g = -1, best_comp = 0;\n        for (int i = 0; i < M; ++i) {\n            if (dsu[i].comps > best_comp) {\n                best_comp = dsu[i].comps;\n                best_g = i;\n            }\n        }\n        if (best_g == -1 || best_comp <= 1) break; // all finished\n\n        unordered_map<int,int> rep;   // DSU root -> city id\n        for (int city : groups[best_g]) {\n            int lid = local_idx[city];\n            int root = dsu[best_g].find(lid);\n            if (!rep.count(root)) rep[root] = city;\n        }\n        vector<int> reps;\n        reps.reserve(rep.size());\n        for (auto &kv : rep) reps.push_back(kv.second);\n        sort(reps.begin(), reps.end());   // deterministic order\n\n        vector<int> subset;\n        if ((int)reps.size() <= L) {\n            subset = reps;\n        } else {\n            subset.assign(reps.begin(), reps.begin() + L);\n        }\n\n        int l = (int)subset.size();\n        cout << \"? \" << l;\n        for (int v : subset) cout << ' ' << v;\n        cout << '\\n';\n        cout.flush();\n\n        for (int i = 0; i < l - 1; ++i) {\n            int a, b;\n            cin >> a >> b;\n            if (group_of[a] != group_of[b]) continue;\n            int g = group_of[a];\n            int la = local_idx[a];\n            int lb = local_idx[b];\n            if (dsu[g].unite(la, lb)) {\n                group_edges[g].push_back({a, b});\n            }\n        }\n        ++queries_used;\n    }\n\n    for (int g = 0; g < M; ++g) {\n        if (dsu[g].comps == 1) continue;\n        struct Edge {int u, v, w;};\n        vector<Edge> edges;\n        int sz = (int)groups[g].size();\n        edges.reserve(sz * (sz - 1) / 2);\n        for (int i = 0; i < sz; ++i) {\n            int u = groups[g][i];\n            int lu = i;\n            for (int j = i + 1; j < sz; ++j) {\n                int v = groups[g][j];\n                int lv = j;\n                if (dsu[g].find(lu) == dsu[g].find(lv)) continue;\n                int w = low[u][v];\n                edges.push_back({u, v, w});\n            }\n        }\n        sort(edges.begin(), edges.end(),\n             [](const Edge& a, const Edge& b) {\n                 if (a.w != b.w) return a.w < b.w;\n                 if (a.u != b.u) return a.u < b.u;\n                 return a.v < b.v;\n             });\n        for (const Edge &e : edges) {\n            int lu = local_idx[e.u];\n            int lv = local_idx[e.v];\n            if (dsu[g].unite(lu, lv)) {\n                group_edges[g].push_back({e.u, e.v});\n                if (dsu[g].comps == 1) break;\n            }\n        }\n    }\n\n    cout << \"!\\n\";\n    for (int g = 0; g < M; ++g) {\n        for (size_t i = 0; i < groups[g].size(); ++i) {\n            if (i) cout << ' ';\n            cout << groups[g][i];\n        }\n        cout << '\\n';\n        for (auto &e : group_edges[g])\n            cout << e.first << ' ' << e.second << '\\n';\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint 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>> p(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> p[i].first >> p[i].second;\n    }\n\n    pair<int,int> cur = p[0];                 // start position\n    for (int idx = 1; idx < M; ++idx) {\n        const pair<int,int> tgt = p[idx];\n\n        /* slide to every border that the target touches */\n        if (tgt.first == 0 && cur.first != 0) {\n            cout << \"S U\\n\";\n            cur.first = 0;\n        } else if (tgt.first == N-1 && cur.first != N-1) {\n            cout << \"S D\\n\";\n            cur.first = N-1;\n        }\n\n        if (tgt.second == 0 && cur.second != 0) {\n            cout << \"S L\\n\";\n            cur.second = 0;\n        } else if (tgt.second == N-1 && cur.second != N-1) {\n            cout << \"S R\\n\";\n            cur.second = N-1;\n        }\n\n        /* finish the remaining distance with ordinary moves */\n        while (cur.first < tgt.first) {\n            cout << \"M D\\n\";\n            ++cur.first;\n        }\n        while (cur.first > tgt.first) {\n            cout << \"M U\\n\";\n            --cur.first;\n        }\n        while (cur.second < tgt.second) {\n            cout << \"M R\\n\";\n            ++cur.second;\n        }\n        while (cur.second > tgt.second) {\n            cout << \"M L\\n\";\n            --cur.second;\n        }\n    }\n    return 0;\n}"},"16":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Company {\n    int x, y;\n    long long r;\n    int a, b, c, d;\n};\n\nstruct Region {\n    int x1, y1, x2, y2;\n    vector<int> points;\n};\n\nclass PartitionSolver {\nprivate:\n    vector<Company> &comp;\n    const int W = 10000;\n    const int H = 10000;\n    \n    double satisfaction(long long r, long long s) {\n        if (s == 0) return 0.0;\n        double ratio = min(r, s) / (double)max(r, s);\n        return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n    }\n    \n    bool findBestSplit(const Region &reg, const vector<int> &pts, bool vertical,\n                       int &best_split, int &best_cut, double &best_score) {\n        vector<int> sorted = pts;\n        if (vertical) {\n            sort(sorted.begin(), sorted.end(), [&](int i, int j) {\n                return comp[i].x < comp[j].x;\n            });\n        } else {\n            sort(sorted.begin(), sorted.end(), [&](int i, int j) {\n                return comp[i].y < comp[j].y;\n            });\n        }\n        \n        best_score = -1;\n        long long total_r = 0;\n        for (int i : pts) total_r += comp[i].r;\n        \n        // Try all split positions\n        for (int split = 1; split < sorted.size(); split++) {\n            long long sum_r_left = 0;\n            for (int i = 0; i < split; i++) sum_r_left += comp[sorted[i]].r;\n            \n            // Find feasible cut range\n            int min_cut, max_cut;\n            if (vertical) {\n                int max_left = -1;\n                for (int i = 0; i < split; i++) max_left = max(max_left, comp[sorted[i]].x);\n                int min_right = W;\n                for (int i = split; i < sorted.size(); i++) min_right = min(min_right, comp[sorted[i]].x);\n                min_cut = max_left + 1;\n                max_cut = min_right;\n            } else {\n                int max_left = -1;\n                for (int i = 0; i < split; i++) max_left = max(max_left, comp[sorted[i]].y);\n                int min_right = H;\n                for (int i = split; i < sorted.size(); i++) min_right = min(min_right, comp[sorted[i]].y);\n                min_cut = max_left + 1;\n                max_cut = min_right;\n            }\n            \n            if (min_cut > max_cut) continue;\n            \n            // Target cut based on area\n            int target = vertical ? reg.x1 + (int)((double)sum_r_left / (reg.y2 - reg.y1))\n                                  : reg.y1 + (int)((double)sum_r_left / (reg.x2 - reg.x1));\n            \n            // Test multiple candidates\n            vector<int> cand = {min_cut, max_cut};\n            if (target >= min_cut && target <= max_cut) cand.push_back(target);\n            \n            for (int cut : cand) {\n                long long area_left = vertical ? (long long)(cut - reg.x1) * (reg.y2 - reg.y1)\n                                               : (long long)(reg.x2 - reg.x1) * (cut - reg.y1);\n                long long area_right = total_r - sum_r_left;\n                area_right = vertical ? (long long)(reg.x2 - reg.x1) * (reg.y2 - reg.y1) - area_left\n                                      : (long long)(reg.x2 - reg.x1) * (reg.y2 - reg.y1) - area_left;\n                \n                double score = satisfaction(sum_r_left, area_left) + satisfaction(total_r - sum_r_left, area_right);\n                \n                if (score > best_score) {\n                    best_score = score;\n                    best_split = split;\n                    best_cut = cut;\n                }\n            }\n        }\n        return best_score >= 0;\n    }\n    \n    void solveRegion(Region &reg) {\n        if (reg.points.size() <= 1) {\n            if (reg.points.size() == 1) {\n                int idx = reg.points[0];\n                comp[idx].a = reg.x1;\n                comp[idx].b = reg.y1;\n                comp[idx].c = reg.x2;\n                comp[idx].d = reg.y2;\n            }\n            return;\n        }\n        \n        // Try both orientations\n        int best_split_v, best_cut_v, best_split_h, best_cut_h;\n        double best_score_v = -1, best_score_h = -1;\n        \n        bool found_v = findBestSplit(reg, reg.points, true, best_split_v, best_cut_v, best_score_v);\n        bool found_h = findBestSplit(reg, reg.points, false, best_split_h, best_cut_h, best_score_h);\n        \n        bool vertical;\n        int best_split, best_cut;\n        if (!found_v && !found_h) {\n            // Fallback: median split\n            vertical = (reg.x2 - reg.x1) > (reg.y2 - reg.y1);\n            best_split = reg.points.size() / 2;\n            best_cut = vertical ? (reg.x1 + reg.x2) / 2 : (reg.y1 + reg.y2) / 2;\n        } else if (!found_v) {\n            vertical = false;\n            best_split = best_split_h;\n            best_cut = best_cut_h;\n        } else if (!found_h) {\n            vertical = true;\n            best_split = best_split_v;\n            best_cut = best_cut_v;\n        } else {\n            vertical = best_score_v >= best_score_h;\n            best_split = vertical ? best_split_v : best_split_h;\n            best_cut = vertical ? best_cut_v : best_cut_h;\n        }\n        \n        // Sort points\n        vector<int> sorted = reg.points;\n        if (vertical) {\n            sort(sorted.begin(), sorted.end(), [&](int i, int j) {\n                return comp[i].x < comp[j].x;\n            });\n        } else {\n            sort(sorted.begin(), sorted.end(), [&](int i, int j) {\n                return comp[i].y < comp[j].y;\n            });\n        }\n        \n        // Create sub-regions\n        Region left = reg;\n        Region right = reg;\n        left.points.clear();\n        right.points.clear();\n        \n        if (vertical) {\n            left.x2 = best_cut;\n            right.x1 = best_cut;\n        } else {\n            left.y2 = best_cut;\n            right.y1 = best_cut;\n        }\n        \n        for (int i = 0; i < sorted.size(); i++) {\n            if (i < best_split) left.points.push_back(sorted[i]);\n            else right.points.push_back(sorted[i]);\n        }\n        \n        solveRegion(left);\n        solveRegion(right);\n    }\n    \npublic:\n    PartitionSolver(vector<Company> &c) : comp(c) {}\n    \n    void solve() {\n        Region root{0, 0, W, H};\n        for (int i = 0; i < comp.size(); i++) root.points.push_back(i);\n        solveRegion(root);\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<Company> comp(n);\n    for (int i = 0; i < n; i++) cin >> comp[i].x >> comp[i].y >> comp[i].r;\n    \n    PartitionSolver solver(comp);\n    solver.solve();\n    \n    for (auto &c : comp) {\n        cout << c.a << \" \" << c.b << \" \" << c.c << \" \" << c.d << \"\\n\";\n    }\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Cell {\n    int value;\n    int tile_id;\n    vector<int> neighbors;\n};\n\nchar getDir(int from, int to) {\n    int from_i = from / 50;\n    int from_j = from % 50;\n    int to_i = to / 50;\n    int to_j = to % 50;\n    \n    if (to_i == from_i - 1) return 'U';\n    if (to_i == from_i + 1) return 'D';\n    if (to_j == from_j - 1) return 'L';\n    return 'R';\n}\n\n// Enhanced scoring considering quality of future moves\ninline int scoreNeighbor(const vector<Cell>& cells, int neighbor_idx, \n                         const vector<int>& visited_tile, int timestamp,\n                         int path_length) {\n    int base_score = cells[neighbor_idx].value;\n    \n    int future_options = 0;\n    int future_value_sum = 0;\n    \n    for (int next : cells[neighbor_idx].neighbors) {\n        if (visited_tile[cells[next].tile_id] != timestamp) {\n            future_options++;\n            future_value_sum += cells[next].value;\n        }\n    }\n    \n    // Average value of future moves\n    int avg_future_value = future_options > 0 ? future_value_sum / future_options : 0;\n    \n    // Dynamic flexibility bonus: stronger early, weaker later\n    int bonus_multiplier = 30 - min(10, path_length / 10);\n    int flexibility_bonus = future_options * (bonus_multiplier + avg_future_value / 30);\n    \n    // Dead end penalty\n    if (future_options == 0) {\n        return base_score - 2000;\n    }\n    \n    return base_score + flexibility_bonus;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 50;\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    \n    int si, sj;\n    \n    while (cin >> si >> sj) {\n        vector<vector<int>> t(N, vector<int>(N));\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cin >> t[i][j];\n            }\n        }\n        \n        vector<vector<int>> p(N, vector<int>(N));\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cin >> p[i][j];\n            }\n        }\n        \n        vector<Cell> cells(N * N);\n        int max_tile_id = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int idx = i * N + j;\n                cells[idx].value = p[i][j];\n                cells[idx].tile_id = t[i][j];\n                max_tile_id = max(max_tile_id, t[i][j]);\n            }\n        }\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int idx = i * N + j;\n                for (int dir = 0; dir < 4; dir++) {\n                    int ni = i + dx[dir];\n                    int nj = j + dy[dir];\n                    if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                    int nidx = ni * N + nj;\n                    if (cells[idx].tile_id != cells[nidx].tile_id) {\n                        cells[idx].neighbors.push_back(nidx);\n                    }\n                }\n            }\n        }\n        \n        string best_moves;\n        int best_score = -1;\n        mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n        vector<int> visited_tile(max_tile_id + 1, 0);\n        \n        for (int attempt = 0; attempt < 50; attempt++) {\n            string current_moves;\n            current_moves.reserve(2500);\n            \n            int current_cell = si * N + sj;\n            int timestamp = attempt + 1;\n            visited_tile[cells[current_cell].tile_id] = timestamp;\n            int current_score = cells[current_cell].value;\n            int path_length = 1;\n            \n            while (true) {\n                int valid_neighbors[4];\n                int neighbor_count = 0;\n                \n                for (int neighbor : cells[current_cell].neighbors) {\n                    if (visited_tile[cells[neighbor].tile_id] != timestamp) {\n                        valid_neighbors[neighbor_count++] = neighbor;\n                    }\n                }\n                \n                if (neighbor_count == 0) break;\n                \n                // Score all neighbors\n                int best_idx = 0;\n                int best_score_local = -1e9;\n                int scores[4];\n                \n                for (int i = 0; i < neighbor_count; i++) {\n                    int neighbor = valid_neighbors[i];\n                    int score = scoreNeighbor(cells, neighbor, visited_tile, timestamp, path_length);\n                    scores[i] = score;\n                    \n                    if (score > best_score_local) {\n                        best_score_local = score;\n                        best_idx = i;\n                    }\n                }\n                \n                // Occasionally (10% early, 5% late) explore non-optimal path\n                if (path_length < 30 && (rng() % 100) < (path_length < 15 ? 10 : 5)) {\n                    // Pick random non-best neighbor\n                    int alt_idx = rng() % neighbor_count;\n                    if (alt_idx != best_idx && scores[alt_idx] > best_score_local - 500) {\n                        best_idx = alt_idx;\n                    }\n                }\n                \n                int next_cell = valid_neighbors[best_idx];\n                current_moves.push_back(getDir(current_cell, next_cell));\n                current_cell = next_cell;\n                visited_tile[cells[current_cell].tile_id] = timestamp;\n                current_score += cells[current_cell].value;\n                path_length++;\n            }\n            \n            if (current_score > best_score) {\n                best_score = current_score;\n                best_moves = current_moves;\n            }\n        }\n        \n        cout << best_moves << \"\\n\";\n    }\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* edge weight matrices */\nstruct EdgeWeights {\n    long double h[30][29];\n    long double v[29][30];\n};\n\n/* update counts for adaptive learning rates */\nstruct EdgeCounts {\n    int h[30][29];\n    int v[29][30];\n};\n\n/* momentum storage */\nstruct EdgeMomentum {\n    long double h[30][29];\n    long double v[29][30];\n};\n\n/* variance tracking for exploration */\nstruct EdgeVariance {\n    long double h[30][29];\n    long double v[29][30];\n};\n\n/* Dijkstra on 30x30 grid, returns path string */\nstring dijkstra_path(int si, int sj, int ti, int tj,\n                     const EdgeWeights& w,\n                     long double* path_len = nullptr) {\n    const int N = 30 * 30;\n    const int s = si * 30 + sj;\n    const int t = ti * 30 + tj;\n\n    vector<long double> dist(N, 1e100L);\n    vector<int> prev(N, -1);\n    vector<char> pdir(N, 0);\n\n    using Node = pair<long double, int>;\n    priority_queue<Node, vector<Node>, greater<Node>> pq;\n    dist[s] = 0.0L;\n    pq.emplace(0.0L, s);\n\n    while (!pq.empty()) {\n        auto [d, u] = pq.top(); pq.pop();\n        if (d > dist[u] + 1e-12L) continue;\n        if (u == t) break;\n\n        int ui = u / 30, uj = u % 30;\n\n        // up\n        if (ui > 0) {\n            int v = (ui - 1) * 30 + uj;\n            long double nd = d + w.v[ui - 1][uj];\n            if (nd + 1e-12L < dist[v]) {\n                dist[v] = nd;\n                prev[v] = u;\n                pdir[v] = 'U';\n                pq.emplace(nd, v);\n            }\n        }\n        // down\n        if (ui < 29) {\n            int v = (ui + 1) * 30 + uj;\n            long double nd = d + w.v[ui][uj];\n            if (nd + 1e-12L < dist[v]) {\n                dist[v] = nd;\n                prev[v] = u;\n                pdir[v] = 'D';\n                pq.emplace(nd, v);\n            }\n        }\n        // left\n        if (uj > 0) {\n            int v = ui * 30 + (uj - 1);\n            long double nd = d + w.h[ui][uj - 1];\n            if (nd + 1e-12L < dist[v]) {\n                dist[v] = nd;\n                prev[v] = u;\n                pdir[v] = 'L';\n                pq.emplace(nd, v);\n            }\n        }\n        // right\n        if (uj < 29) {\n            int v = ui * 30 + (uj + 1);\n            long double nd = d + w.h[ui][uj];\n            if (nd + 1e-12L < dist[v]) {\n                dist[v] = nd;\n                prev[v] = u;\n                pdir[v] = 'R';\n                pq.emplace(nd, v);\n            }\n        }\n    }\n\n    string path;\n    for (int cur = t; cur != s; cur = prev[cur])\n        path.push_back(pdir[cur]);\n    reverse(path.begin(), path.end());\n\n    if (path_len) *path_len = dist[t];\n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    random_device rd;\n    mt19937 rng(rd());\n\n    uniform_real_distribution<long double> urd_noise(-400.0L, 400.0L);\n    bernoulli_distribution explore_decision(0.0);\n\n    // initialize\n    EdgeWeights w;\n    EdgeCounts cnt{};\n    EdgeMomentum mom{};\n    EdgeVariance var{};\n    for (int i = 0; i < 30; ++i)\n        for (int j = 0; j < 29; ++j) {\n            w.h[i][j] = 5000.0L;\n            cnt.h[i][j] = 0;\n            var.h[i][j] = 1000.0L;\n        }\n    for (int i = 0; i < 29; ++i)\n        for (int j = 0; j < 30; ++j) {\n            w.v[i][j] = 5000.0L;\n            cnt.v[i][j] = 0;\n            var.v[i][j] = 1000.0L;\n        }\n\n    const long double momentum = 0.87L;\n    const long double base_lr = 0.025L;\n\n    for (int q = 0; q < 1000; ++q) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) return 0;\n\n        // two-stage exploration schedule\n        long double eps = (q < 250) ? 0.75L : 0.55L * exp(-(q - 250) / 300.0L);\n        explore_decision.param(bernoulli_distribution::param_type(eps));\n        bool explore = explore_decision(rng);\n\n        string path;\n        EdgeWeights w_tmp = w;\n        \n        if (explore) {\n            // Thompson sampling with variance-based noise\n            for (int i = 0; i < 30; ++i)\n                for (int j = 0; j < 29; ++j) {\n                    long double stddev = sqrt(var.h[i][j] / (cnt.h[i][j] + 1));\n                    normal_distribution<long double> dist(w.h[i][j], stddev);\n                    w_tmp.h[i][j] = dist(rng);\n                }\n            for (int i = 0; i < 29; ++i)\n                for (int j = 0; j < 30; ++j) {\n                    long double stddev = sqrt(var.v[i][j] / (cnt.v[i][j] + 1));\n                    normal_distribution<long double> dist(w.v[i][j], stddev);\n                    w_tmp.v[i][j] = dist(rng);\n                }\n            path = dijkstra_path(si, sj, ti, tj, w_tmp);\n        } else {\n            path = dijkstra_path(si, sj, ti, tj, w);\n        }\n\n        cout << path << '\\n';\n        cout.flush();\n\n        long long y;\n        cin >> y;\n\n        long double pred = 0.0L;\n        int i = si, j = sj;\n        for (char c : path) {\n            if (c == 'U') {\n                pred += w.v[i - 1][j];\n                --i;\n            } else if (c == 'D') {\n                pred += w.v[i][j];\n                ++i;\n            } else if (c == 'L') {\n                pred += w.h[i][j - 1];\n                --j;\n            } else {\n                pred += w.h[i][j];\n                ++j;\n            }\n        }\n\n        long double err = (long double)y - pred;\n        long double grad = err / (long double)path.size();\n\n        // update weights and track variance\n        i = si; j = sj;\n        for (char c : path) {\n            if (c == 'U') {\n                long double step = base_lr / sqrt((long double)(cnt.v[i - 1][j] + 1));\n                mom.v[i - 1][j] = momentum * mom.v[i - 1][j] + step * grad;\n                w.v[i - 1][j] += mom.v[i - 1][j];\n                // update variance estimate\n                var.v[i - 1][j] = 0.9L * var.v[i - 1][j] + 0.1L * (grad * grad);\n                ++cnt.v[i - 1][j];\n                --i;\n            } else if (c == 'D') {\n                long double step = base_lr / sqrt((long double)(cnt.v[i][j] + 1));\n                mom.v[i][j] = momentum * mom.v[i][j] + step * grad;\n                w.v[i][j] += mom.v[i][j];\n                var.v[i][j] = 0.9L * var.v[i][j] + 0.1L * (grad * grad);\n                ++cnt.v[i][j];\n                ++i;\n            } else if (c == 'L') {\n                long double step = base_lr / sqrt((long double)(cnt.h[i][j - 1] + 1));\n                mom.h[i][j - 1] = momentum * mom.h[i][j - 1] + step * grad;\n                w.h[i][j - 1] += mom.h[i][j - 1];\n                var.h[i][j - 1] = 0.9L * var.h[i][j - 1] + 0.1L * (grad * grad);\n                ++cnt.h[i][j - 1];\n                --j;\n            } else {\n                long double step = base_lr / sqrt((long double)(cnt.h[i][j] + 1));\n                mom.h[i][j] = momentum * mom.h[i][j] + step * grad;\n                w.h[i][j] += mom.h[i][j];\n                var.h[i][j] = 0.9L * var.h[i][j] + 0.1L * (grad * grad);\n                ++cnt.h[i][j];\n                ++j;\n            }\n        }\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 20;                 // matrix size (fixed in the statement)\nconstexpr int MAXLEN = 12;            // maximal length of an input string\nconstexpr int ALPH = 8;               // letters A \u2026 H\n\n/* ---------- placement of one string ---------- */\nstruct Placement {\n    uint16_t cell[MAXLEN];   // cell indices (0 \u2026 N*N-1)\n    uint8_t  let[MAXLEN];    // required letters (0 \u2026 7)\n    uint8_t  len;            // actual length ( \u2264 12 )\n};\n\n/* ---------- global data for the whole test case ---------- */\nint Muniq;                                           // number of different strings\nvector<vector<int>> strLetters;                     // letters of each unique string\nvector<vector<Placement>> placements;               // all placements of each string\n\n/* ---------- current working solution ---------- */\narray<int, N * N> curLetter;        // -1 = empty, 0..7 = letter\narray<int, N * N> curUse;           // how many placements occupy the cell\nint curUsedCells;                    // #cells with curUse > 0\nvector<int> curIdx;                  // for each string: chosen placement index, -1 = none\n\n/* --------------------------------------------------------------- */\ninline int cellId(int r, int c) { return r * N + c; }\n\n/* check whether placement p can be inserted into the current grid */\ninline bool canPlace(const Placement& p) {\n    for (int i = 0; i < p.len; ++i) {\n        int c = p.cell[i];\n        if (curUse[c] > 0 && curLetter[c] != (int)p.let[i]) return false;\n    }\n    return true;\n}\n\n/* cost of a placement = number of empty cells it would occupy */\ninline int placeCost(const Placement& p) {\n    int cost = 0;\n    for (int i = 0; i < p.len; ++i)\n        if (curUse[p.cell[i]] == 0) ++cost;\n    return cost;\n}\n\n/* insert a placement into the grid */\ninline void place(const Placement& p) {\n    for (int i = 0; i < p.len; ++i) {\n        int c = p.cell[i];\n        if (curUse[c] == 0) {\n            curLetter[c] = p.let[i];\n            ++curUsedCells;\n        }\n        ++curUse[c];\n    }\n}\n\n/* remove a placement from the grid */\ninline void unplace(const Placement& p) {\n    for (int i = 0; i < p.len; ++i) {\n        int c = p.cell[i];\n        --curUse[c];\n        if (curUse[c] == 0) {\n            curLetter[c] = -1;\n            --curUsedCells;\n        }\n    }\n}\n\n/* test whether string s (index) is a subsequence of the current matrix */\ninline bool isPresent(int s) {\n    for (const Placement& p : placements[s]) {\n        bool ok = true;\n        for (int i = 0; i < p.len; ++i) {\n            int c = p.cell[i];\n            if (curLetter[c] != (int)p.let[i]) { ok = false; break; }\n        }\n        if (ok) return true;\n    }\n    return false;\n}\n\n/* --------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int Ninput, Minput;\n    if (!(cin >> Ninput >> Minput)) return 0;\n    vector<string> allStr(Minput);\n    for (int i = 0; i < Minput; ++i) cin >> allStr[i];\n\n    /* ---- delete duplicate strings (one occurrence is sufficient) ---- */\n    unordered_map<string, int> seen;\n    vector<string> uniqStr;\n    for (const string& x : allStr) {\n        if (seen.find(x) == seen.end()) {\n            seen[x] = 1;\n            uniqStr.push_back(x);\n        }\n    }\n    Muniq = (int)uniqStr.size();                 // number of different strings\n\n    /* ---- convert strings to integer letters ---- */\n    strLetters.resize(Muniq);\n    for (int i = 0; i < Muniq; ++i)\n        for (char ch : uniqStr[i])\n            strLetters[i].push_back(ch - 'A');\n\n    /* ---- pre\u2011compute all placements of each string ---- */\n    placements.assign(Muniq, {});\n    for (int sid = 0; sid < Muniq; ++sid) {\n        const vector<int>& L = strLetters[sid];\n        int len = (int)L.size();\n        // horizontal\n        for (int row = 0; row < N; ++row)\n            for (int startCol = 0; startCol < N; ++startCol) {\n                Placement p;\n                p.len = (uint8_t)len;\n                for (int off = 0; off < len; ++off) {\n                    int col = (startCol + off) % N;\n                    p.cell[off] = (uint16_t)cellId(row, col);\n                    p.let[off]  = (uint8_t)L[off];\n                }\n                placements[sid].push_back(p);\n            }\n        // vertical\n        for (int col = 0; col < N; ++col)\n            for (int startRow = 0; startRow < N; ++startRow) {\n                Placement p;\n                p.len = (uint8_t)len;\n                for (int off = 0; off < len; ++off) {\n                    int row = (startRow + off) % N;\n                    p.cell[off] = (uint16_t)cellId(row, col);\n                    p.let[off]  = (uint8_t)L[off];\n                }\n                placements[sid].push_back(p);\n            }\n    }\n\n    /* ---- compute a simple \"rarity\" score for each string ----\n       (more constrained strings have larger rarity) ---- */\n    vector<int> rarity(Muniq, 0);\n    for (int sid = 0; sid < Muniq; ++sid) {\n        int sum = 0;\n        for (const Placement& p : placements[sid])\n            sum += p.len;                     // each cell of each placement counts\n        rarity[sid] = sum;\n    }\n\n    /* ---------- containers for the best solution found ---------- */\n    array<int, N * N> bestLetter;\n    int bestUsed = INT_MAX;\n    int bestPlaced = -1;\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    const double TIME_LIMIT = 2.8;                 // seconds\n    auto start = chrono::steady_clock::now();\n\n    /* ---------- phase 1 : many greedy restarts + adaptive back\u2011tracking ---------- */\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > 0.60 * TIME_LIMIT) break;    // 60\u202f% of total time\n\n        /* ---- start with an empty grid ---- */\n        curLetter.fill(-1);\n        curUse.fill(0);\n        curUsedCells = 0;\n        curIdx.assign(Muniq, -1);\n\n        /* ---- order strings by decreasing rarity (more constrained first) ---- */\n        vector<int> order(Muniq);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(),\n             [&](int a, int b) { return rarity[a] > rarity[b]; });\n        // shuffle the tail a little to keep diversity\n        for (int i = max(0, Muniq - 10); i < Muniq; ++i)\n            swap(order[i], order[uniform_int_distribution<int>(i, Muniq - 1)(rng)]);\n\n        int placed = 0;\n\n        /* ---- greedy construction ---- */\n        for (int sid : order) {\n            const vector<Placement>& cand = placements[sid];\n            int bestCost = INT_MAX;\n            vector<int> bestIdx;               // placement indices with that cost\n            for (int pid = 0; pid < (int)cand.size(); ++pid) {\n                const Placement& p = cand[pid];\n                if (!canPlace(p)) continue;\n                int c = placeCost(p);\n                if (c < bestCost) {\n                    bestCost = c;\n                    bestIdx.clear();\n                    bestIdx.push_back(pid);\n                } else if (c == bestCost) {\n                    bestIdx.push_back(pid);\n                }\n            }\n            if (bestIdx.empty()) continue;          // cannot place now\n            int chosen = bestIdx[uniform_int_distribution<int>(0, (int)bestIdx.size() - 1)(rng)];\n            place(cand[chosen]);\n            curIdx[sid] = chosen;\n            ++placed;\n        }\n\n        /* ---- adaptive back\u2011tracking for missing strings ---- */\n        if (placed < Muniq) {\n            vector<int> missing;\n            for (int i = 0; i < Muniq; ++i) if (curIdx[i] == -1) missing.push_back(i);\n            int maxAttempts = (missing.size() >= 5) ? 75 : 30;\n            for (int attempt = 0; attempt < maxAttempts && !missing.empty(); ++attempt) {\n                int sid = missing.back();                     // take one missing string\n                bool ok = false;\n                for (const Placement& p : placements[sid]) {\n                    if (canPlace(p)) {\n                        place(p);\n                        curIdx[sid] = &p - &placements[sid][0]; // store index (any unique id is fine)\n                        missing.pop_back();\n                        ++placed;\n                        ok = true;\n                        break;\n                    }\n                }\n                if (ok) continue;\n                // none fits \u2192 remove a random placed string and retry\n                vector<int> placedIds;\n                for (int i = 0; i < Muniq; ++i) if (curIdx[i] != -1) placedIds.push_back(i);\n                if (placedIds.empty()) continue;\n                int victim = placedIds[uniform_int_distribution<int>(0, (int)placedIds.size() - 1)(rng)];\n                const Placement& vp = placements[victim][curIdx[victim]];\n                unplace(vp);\n                curIdx[victim] = -1;\n                --placed;\n            }\n        }\n\n        /* ---- delete redundant strings (already present as substrings) ---- */\n        if (placed == Muniq) {\n            vector<int> perm = order;\n            shuffle(perm.begin(), perm.end(), rng);\n            for (int sid : perm) {\n                if (curIdx[sid] == -1) continue;\n                const Placement& p = placements[sid][curIdx[sid]];\n                unplace(p);\n                if (isPresent(sid)) {\n                    curIdx[sid] = -1;          // keep removed\n                } else {\n                    place(p);                  // put it back\n                }\n            }\n        }\n\n        /* ---- remember the best solution of this restart ---- */\n        if (placed > bestPlaced ||\n            (placed == bestPlaced && curUsedCells < bestUsed)) {\n            bestPlaced = placed;\n            bestUsed   = curUsedCells;\n            bestLetter = curLetter;               // copy the whole grid (400 ints)\n        }\n    }   // end of restarts\n\n    /* ---- nothing feasible found ? output empty matrix (worst case) ---- */\n    if (bestPlaced == -1) {\n        for (int i = 0; i < N; ++i) cout << string(N, '.') << '\\n';\n        return 0;\n    }\n\n    /* ---- reload the best solution ---- */\n    curLetter = bestLetter;\n    curUse.fill(0);\n    curUsedCells = 0;\n    for (int i = 0; i < N * N; ++i)\n        if (curLetter[i] != -1) {\n            curUse[i] = 1;\n            ++curUsedCells;\n        }\n    curIdx.assign(Muniq, -1);       // exact indices not needed any more\n\n    /* ---------- phase 2 : hill climbing (use remaining time) ---------- */\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > TIME_LIMIT - 0.05) break;    // stop a little before the hard limit\n\n        // pick a random placed string\n        vector<int> placedIds;\n        for (int i = 0; i < Muniq; ++i) if (curIdx[i] != -1) placedIds.push_back(i);\n        if (placedIds.empty()) continue;\n        int sid = placedIds[uniform_int_distribution<int>(0, (int)placedIds.size() - 1)(rng)];\n        const Placement& oldPl = placements[sid][curIdx[sid]];\n\n        // pick a random different placement\n        const vector<Placement>& cand = placements[sid];\n        int pid = uniform_int_distribution<int>(0, (int)cand.size() - 1)(rng);\n        if (pid == curIdx[sid]) continue;\n        const Placement& newPl = cand[pid];\n        if (!canPlace(newPl)) continue;           // would conflict\n\n        // compute \u0394 = newCellsUsed - cellsFreed\n        int freed = 0;\n        for (int i = 0; i < oldPl.len; ++i) {\n            int c = oldPl.cell[i];\n            if (curUse[c] == 1) {\n                bool inNew = false;\n                for (int j = 0; j < newPl.len; ++j)\n                    if (newPl.cell[j] == c) { inNew = true; break; }\n                if (!inNew) ++freed;\n            }\n        }\n        int newlyUsed = 0;\n        for (int i = 0; i < newPl.len; ++i) {\n            int c = newPl.cell[i];\n            if (curUse[c] == 0) {\n                bool inOld = false;\n                for (int j = 0; j < oldPl.len; ++j)\n                    if (oldPl.cell[j] == c) { inOld = true; break; }\n                if (!inOld) ++newlyUsed;\n            }\n        }\n        int delta = newlyUsed - freed;\n        if (delta < 0) {                           // strict improvement only\n            unplace(oldPl);\n            place(newPl);\n            curIdx[sid] = pid;\n            if (curUsedCells < bestUsed) {\n                bestUsed = curUsedCells;\n                bestLetter = curLetter;\n            }\n        }\n    }\n\n    /* ---------- output the best matrix ---------- */\n    for (int r = 0; r < N; ++r) {\n        string line;\n        for (int c = 0; c < N; ++c) {\n            int id = cellId(r, c);\n            if (bestLetter[id] == -1) line += '.';\n            else                       line += char('A' + bestLetter[id]);\n        }\n        cout << line << '\\n';\n    }\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXV = 5005;                 // maximal number of cells (N\u226469 \u2192 < 5000)\n\nstruct Edge {\n    int u, v, w;\n    bool operator<(Edge const& other) const { return w < other.w; }\n};\n\nstruct DSU {\n    vector<int> p, r;\n    DSU(int n = 0) { init(n); }\n    void init(int n) { p.resize(n); r.assign(n,0); iota(p.begin(),p.end(),0); }\n    int find(int x){ return p[x]==x?x:p[x]=find(p[x]); }\n    bool unite(int a,int b){\n        a=find(a); b=find(b);\n        if(a==b) return false;\n        if(r[a]<r[b]) swap(a,b);\n        p[b]=a;\n        if(r[a]==r[b]) ++r[a];\n        return true;\n    }\n};\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    // --- 1. give an id to every road cell, store its weight and coordinates ----------\n    vector<vector<int>> id(N, vector<int>(N,-1));\n    vector<int> weight; weight.reserve(N*N);\n    vector<int> iOf, jOf; iOf.reserve(N*N); jOf.reserve(N*N);\n    int V = 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] = V++;\n                weight.push_back(g[i][j]-'0');\n                iOf.push_back(i);\n                jOf.push_back(j);\n            }\n        }\n    }\n    const int startIdx = id[si][sj];\n\n    // --- 2. row and column segment ids ------------------------------------------------\n    vector<int> rowId(V,-1), colId(V,-1);\n    int rowSegCnt = 0;\n    for(int i=0;i<N;++i){\n        int cur = -1;\n        for(int j=0;j<N;++j){\n            if(g[i][j]!='#'){\n                if(j==0 || g[i][j-1]=='#') cur = rowSegCnt++;\n                rowId[id[i][j]] = cur;\n            }\n        }\n    }\n    int colSegCnt = 0;\n    for(int j=0;j<N;++j){\n        int cur = -1;\n        for(int i=0;i<N;++i){\n            if(g[i][j]!='#'){\n                if(i==0 || g[i-1][j]=='#') cur = colSegCnt++;\n                colId[id[i][j]] = cur;\n            }\n        }\n    }\n\n    // decide which side to cover\n    bool useRow = rowSegCnt <= colSegCnt;\n    vector<int> segId = useRow ? rowId : colId;\n    int segCnt = useRow ? rowSegCnt : colSegCnt;\n\n    // --- 3. build edge list (only right / down, undirected) ----------------------------\n    vector<Edge> edges;\n    edges.reserve(4*V);\n    const int di[4] = {-1,1,0,0};\n    const int dj[4] = {0,0,-1,1};\n    for(int i=0;i<N;++i){\n        for(int j=0;j<N;++j){\n            if(g[i][j]=='#') continue;\n            int u = id[i][j];\n            // right neighbour\n            if(j+1<N && g[i][j+1]!='#'){\n                int v = id[i][j+1];\n                if(u<v) edges.push_back({u,v,weight[u]+weight[v]});\n            }\n            // down neighbour\n            if(i+1<N && g[i+1][j]!='#'){\n                int v = id[i+1][j];\n                if(u<v) edges.push_back({u,v,weight[u]+weight[v]});\n            }\n        }\n    }\n\n    // --- 4. MST with Kruskal ---------------------------------------------------------\n    sort(edges.begin(), edges.end());\n    DSU dsu(V);\n    vector<vector<int>> mstAdj(V);\n    int added = 0;\n    for(const auto& e: edges){\n        if(dsu.unite(e.u, e.v)){\n            mstAdj[e.u].push_back(e.v);\n            mstAdj[e.v].push_back(e.u);\n            if(++added == V-1) break;\n        }\n    }\n\n    // --- 5. root the tree in the start cell -----------------------------------------\n    vector<int> parent(V,-1);\n    vector<vector<int>> children(V);\n    vector<int> order; order.reserve(V);\n    // iterative stack for rooting\n    vector<int> st; st.push_back(startIdx);\n    parent[startIdx] = startIdx;\n    while(!st.empty()){\n        int u = st.back(); st.pop_back();\n        order.push_back(u);\n        for(int v: mstAdj[u]){\n            if(v==parent[u]) continue;\n            parent[v] = u;\n            children[u].push_back(v);\n            st.push_back(v);\n        }\n    }\n\n    // --- 6. subtree masks of segment ids --------------------------------------------\n    using Mask = bitset<MAXV>;\n    vector<Mask> subMask(V);\n    vector<int> subCnt(V,0);\n    // post\u2011order (reverse of the order we obtained above, because every parent appears after its children)\n    for(int i=(int)order.size()-1;i>=0;--i){\n        int u = order[i];\n        subMask[u].reset();\n        subMask[u].set(segId[u]);\n        for(int v: children[u]){\n            subMask[u] |= subMask[v];\n        }\n        subCnt[u] = (int)subMask[u].count();\n    }\n\n    // --- 7. sort children by number of different segments in their subtree ----------\n    for(int u=0;u<V;++u){\n        sort(children[u].begin(), children[u].end(),\n            [&](int a, int b){ return subCnt[a] > subCnt[b]; });\n    }\n\n    // --- 8. depth\u2011first walk, but only when a subtree still contains uncovered segments\n    Mask coveredMask;\n    coveredMask.reset();\n    coveredMask.set(segId[startIdx]);          // start segment already visited\n\n    string answer; answer.reserve(2*V);\n    function<void(int,int)> dfsWalk = [&](int u, int p)->void{\n        for(int v: children[u]){\n            // if nothing uncovered in this subtree \u2013 skip it\n            if ( (subMask[v] & ~coveredMask).none() ) continue;\n            // move u -> v\n            if(iOf[v]==iOf[u]-1 && jOf[v]==jOf[u]) answer.push_back('U');\n            else if(iOf[v]==iOf[u]+1 && jOf[v]==jOf[u]) answer.push_back('D');\n            else if(iOf[v]==iOf[u] && jOf[v]==jOf[u]-1) answer.push_back('L');\n            else if(iOf[v]==iOf[u] && jOf[v]==jOf[u]+1) answer.push_back('R');\n            else { /* should never happen */ }\n\n            coveredMask.set(segId[v]);          // v itself is visited now\n            dfsWalk(v, u);\n            // return v -> u\n            if(iOf[v]==iOf[u]-1 && jOf[v]==jOf[u]) answer.push_back('D');\n            else if(iOf[v]==iOf[u]+1 && jOf[v]==jOf[u]) answer.push_back('U');\n            else if(iOf[v]==iOf[u] && jOf[v]==jOf[u]-1) answer.push_back('R');\n            else if(iOf[v]==iOf[u] && jOf[v]==jOf[u]+1) answer.push_back('L');\n            else { /* should never happen */ }\n        }\n    };\n    dfsWalk(startIdx, -1);\n\n    // --- 9. output ------------------------------------------------------------------\n    cout << answer << '\\n';\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ---------- data structures ---------- */\n\nstruct Task {\n    vector<int> d;          // skill requirements, size K\n    int indegree = 0;       // number of unfinished predecessors\n    int status = -1;        // -1 : not started, 0 : in progress, 1 : completed\n    int start_day = -1;     // day on which the task was started\n    int assigned_to = -1;   // member id (0\u2011based) or -1\n    int total_req = 0;      // \u03a3_k d[k]  (used for a cheap difficulty estimate)\n};\n\nstruct Member {\n    vector<int> s_est;          // not used by the final algorithm, kept for symmetry\n    double avg_time_per_unit = 1.0;   // average observed  (time / total_requirement)\n    int total_processed = 0;    // number of tasks finished by this member\n    int total_time = 0;         // sum of their processing times\n};\n\n/* ---------- main ---------- */\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---- read prior information ---- */\n    int N, M, K, R;\n    if (!(cin >> N >> M >> K >> R)) return 0;\n\n    vector<Task> tasks(N);\n    for (int i = 0; i < N; ++i) {\n        tasks[i].d.resize(K);\n        tasks[i].total_req = 0;\n        for (int k = 0; k < K; ++k) {\n            cin >> tasks[i].d[k];\n            tasks[i].total_req += tasks[i].d[k];\n        }\n    }\n\n    vector<vector<int>> graph(N);          // edge u \u2192 v  (u must be done before v)\n    for (int i = 0; i < R; ++i) {\n        int u, v;  cin >> u >> v;  --u; --v;\n        graph[u].push_back(v);\n        ++tasks[v].indegree;\n    }\n\n    vector<Member> members(M);\n    for (int j = 0; j < M; ++j) members[j].s_est.assign(K, 0);\n\n    vector<int> member_status(M, -1);               // -1 \u2192 idle, otherwise task id\n    unordered_map<int,int> in_progress;             // taskid \u2192 start_day\n\n    int day = 0;\n\n    /* ---- day loop ---- */\n    while (true) {\n        ++day;\n        if (day > 2000) break;                     // safety, should never trigger\n\n        /* -- 1. available tasks -- */\n        vector<int> available;\n        for (int i = 0; i < N; ++i)\n            if (tasks[i].status == -1 && tasks[i].indegree == 0)\n                available.push_back(i);\n\n        sort(available.begin(), available.end(),\n             [&](int a, int b){ return tasks[a].total_req < tasks[b].total_req; });\n\n        /* -- 2. idle members -- */\n        vector<int> idle_members;\n        for (int j = 0; j < M; ++j)\n            if (member_status[j] == -1) idle_members.push_back(j);\n\n        /* -- 3. greedy matching -- */\n        vector<pair<int,int>> assignments;           // (member , task)\n        for (int j : idle_members) {\n            if (available.empty()) break;\n\n            int   best_task = -1;\n            double best_pred = 1e99;\n\n            for (size_t pos = 0; pos < available.size(); ++pos) {\n                int i = available[pos];\n                double pred = members[j].avg_time_per_unit * tasks[i].total_req;\n                if (pred < best_pred) {\n                    best_pred = pred;\n                    best_task = i;\n                }\n            }\n\n            if (best_task != -1) {\n                assignments.emplace_back(j, best_task);\n                // remove the chosen task from the vector (swap with back)\n                auto it = find(available.begin(), available.end(), best_task);\n                *it = available.back();\n                available.pop_back();\n            }\n        }\n\n        /* -- 4. output -- */\n        cout << assignments.size();\n        for (auto [mem, t] : assignments)\n            cout << ' ' << (mem + 1) << ' ' << (t + 1);\n        cout << '\\n';\n        cout.flush();\n\n        /* -- 5. update internal state -- */\n        for (auto [mem, t] : assignments) {\n            tasks[t].status = 0;\n            tasks[t].start_day = day;\n            tasks[t].assigned_to = mem;\n            member_status[mem] = t;\n            in_progress[t] = day;\n        }\n\n        /* -- 6. read completions -- */\n        int num_compl;  cin >> num_compl;\n        if (num_compl == -1) break;                 // finished or time limit\n\n        for (int i = 0; i < num_compl; ++i) {\n            int mem;  cin >> mem;  --mem;\n            int task = member_status[mem];\n            if (task == -1) continue;                // should never happen\n\n            int start_day = in_progress[task];\n            int t = day - start_day;                 // real processing time\n\n            Member &m = members[mem];\n            ++m.total_processed;\n            m.total_time += t;\n\n            // update average time per unit (exponential moving average)\n            int req = tasks[task].total_req;\n            if (req > 0) {\n                double this_avg = static_cast<double>(t) / req;\n                constexpr double alpha = 0.2;         // learning rate\n                m.avg_time_per_unit = (1.0 - alpha) * m.avg_time_per_unit\n                                      + alpha * this_avg;\n            }\n\n            // mark task completed\n            tasks[task].status = 1;\n            tasks[task].assigned_to = -1;\n            member_status[mem] = -1;\n            in_progress.erase(task);\n\n            // make dependent tasks available\n            for (int child : graph[task]) {\n                if (--tasks[child].indegree == 0) {\n                    // will be collected in the next day\n                }\n            }\n        }\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 1000;               // number of orders in the input\nconst int M = 50;                 // orders that have to be chosen\nconst int CENTER_X = 400;\nconst int CENTER_Y = 400;\n\n/*  order data  */\nint a[N], b[N], c_[N], d_[N];\nint internalDist[N];\nint startDist[N];\nint endDist[N];\nint between[N][N];                // delivery i -> pickup j\n\n/*  Manhattan distance  */\ninline int manh(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n/*  cost between two orders, -1 stands for the centre  */\ninline int costBetween(int from, int to) {\n    if (from == -1 && to == -1) return 0;\n    if (from == -1) return startDist[to];\n    if (to   == -1) return endDist[from];\n    return between[from][to];\n}\n\n/*  total travel time of a permutation (block order)  */\nint computeCost(const vector<int>& perm) {\n    int sum = 0;\n    for (int id : perm) sum += internalDist[id];\n    sum += startDist[perm[0]];\n    for (int i = 0; i + 1 < (int)perm.size(); ++i)\n        sum += between[perm[i]][perm[i + 1]];\n    sum += endDist[perm.back()];\n    return sum;\n}\n\n/* -------------------------------------------------------------\n   Greedy insertion \u2013 returns a feasible permutation\n   -------------------------------------------------------------\n*/\nvector<int> greedyInsertion(mt19937& rng) {\n    vector<int> path;                     // current permutation of orders\n    path.reserve(M);\n    vector<char> used(N, 0);               // order already taken ?\n\n    while ((int)path.size() < M) {\n        int bestTotal = INT_MAX;\n        int bestOrder = -1;\n        int bestPos   = -1;\n\n        for (int i = 0; i < N; ++i) if (!used[i]) {\n            int bestDelta = INT_MAX;\n            int bestPos_i = -1;\n            int sz = (int)path.size();\n            for (int pos = 0; pos <= sz; ++pos) {\n                int prev = (pos == 0) ? -1 : path[pos - 1];\n                int nxt  = (pos == sz) ? -1 : path[pos];\n                int delta = costBetween(prev, i) + costBetween(i, nxt)\n                            - costBetween(prev, nxt);\n                if (delta < bestDelta) {\n                    bestDelta = delta;\n                    bestPos_i = pos;\n                }\n            }\n            int totalIncrease = bestDelta + internalDist[i];\n            // random tie\u2011break\n            if (totalIncrease < bestTotal ||\n                (totalIncrease == bestTotal && (rng() & 1))) {\n                bestTotal = totalIncrease;\n                bestOrder = i;\n                bestPos   = bestPos_i;\n            }\n        }\n        // insert the chosen order\n        path.insert(path.begin() + bestPos, bestOrder);\n        used[bestOrder] = 1;\n    }\n    return path;\n}\n\n/* -------------------------------------------------------------\n   Simulated annealing on a permutation (keeps the set of orders)\n   -------------------------------------------------------------\n*/\nvector<int> simulatedAnnealing(const vector<int>& startPerm,\n                               mt19937& rng,\n                               double timeLimit)\n{\n    const double initTemp = 1000.0;\n    const int    movesPerStep = 2000;\n\n    vector<int> cur = startPerm;\n    vector<char> used(N, 0);\n    for (int v : cur) used[v] = 1;\n    int curCost = computeCost(cur);\n    int bestCost = curCost;\n    vector<int> best = cur;\n\n    double start = (double)clock() / CLOCKS_PER_SEC;\n    uniform_real_distribution<double> uni01(0.0, 1.0);\n    uniform_int_distribution<int> posDist(0, M - 1);\n    uniform_int_distribution<int> orderDist(0, N - 1);\n\n    while (true) {\n        double elapsed = (double)clock() / CLOCKS_PER_SEC - start;\n        if (elapsed > timeLimit) break;\n        double temperature = initTemp * (1.0 - elapsed / timeLimit);\n        if (temperature <= 0.0) break;\n\n        for (int step = 0; step < movesPerStep; ++step) {\n            int move = rng() % 4;                     // 0 swap,1 move,2 reverse,3 replace\n            vector<int> nxt = cur;\n            vector<char> nxtUsed = used;\n\n            if (move == 0) {                         // swap two positions\n                int i = posDist(rng), j = posDist(rng);\n                if (i == j) continue;\n                swap(nxt[i], nxt[j]);\n            }\n            else if (move == 1) {                    // move one order\n                int i = posDist(rng), j = posDist(rng);\n                if (i == j) continue;\n                int v = nxt[i];\n                nxt.erase(nxt.begin() + i);\n                nxt.insert(nxt.begin() + j, v);\n            }\n            else if (move == 2) {                    // reverse a segment\n                int i = posDist(rng), j = posDist(rng);\n                if (i >= j) continue;\n                reverse(nxt.begin() + i, nxt.begin() + j + 1);\n            }\n            else {                                    // replace one order\n                int i = posDist(rng);\n                int oldId = nxt[i];\n                int newId;\n                do { newId = orderDist(rng); } while (nxtUsed[newId]);\n                nxt[i] = newId;\n                nxtUsed[oldId] = 0;\n                nxtUsed[newId] = 1;\n            }\n\n            int nxtCost = computeCost(nxt);\n            int delta   = nxtCost - curCost;\n            double prob = (delta < 0) ? 1.0 : exp(-delta / temperature);\n            if (prob > uni01(rng)) {\n                cur.swap(nxt);\n                used.swap(nxtUsed);\n                curCost = nxtCost;\n                if (curCost < bestCost) {\n                    bestCost = curCost;\n                    best = cur;\n                }\n            }\n        }\n    }\n    return best;\n}\n\n/* -------------------------------------------------------------\n   Simple deterministic hill\u2011climbing (reverse / swap)\n   -------------------------------------------------------------\n*/\nvector<int> localImprove(vector<int> perm) {\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        // try to reverse a segment\n        for (int i = 0; i < M; ++i)\n            for (int j = i + 1; j < M; ++j) {\n                vector<int> cand = perm;\n                reverse(cand.begin() + i, cand.begin() + j + 1);\n                int candCost = computeCost(cand);\n                int curCost  = computeCost(perm);\n                if (candCost < curCost) {\n                    perm.swap(cand);\n                    improved = true;\n                    goto nextLoop;               // start again\n                }\n            }\n        // try to swap two positions\n        for (int i = 0; i < M; ++i)\n            for (int j = i + 1; j < M; ++j) {\n                vector<int> cand = perm;\n                swap(cand[i], cand[j]);\n                int candCost = computeCost(cand);\n                int curCost  = computeCost(perm);\n                if (candCost < curCost) {\n                    perm.swap(cand);\n                    improved = true;\n                    goto nextLoop;\n                }\n            }\n    nextLoop: ;\n    }\n    return perm;\n}\n\n/* -------------------------------------------------------------\n   Main\n   -------------------------------------------------------------\n*/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---- read input --------------------------------------------------- */\n    for (int i = 0; i < N; ++i) {\n        if (!(cin >> a[i] >> b[i] >> c_[i] >> d_[i])) return 0;\n    }\n\n    /* ---- pre\u2011compute all distances ------------------------------------ */\n    for (int i = 0; i < N; ++i) {\n        internalDist[i] = manh(a[i], b[i], c_[i], d_[i]);\n        startDist[i]    = manh(CENTER_X, CENTER_Y, a[i], b[i]);\n        endDist[i]      = manh(c_[i], d_[i], CENTER_X, CENTER_Y);\n        for (int j = 0; j < N; ++j)\n            between[i][j] = manh(c_[i], d_[i], a[j], b[j]);\n    }\n\n    /* ---- random generator -------------------------------------------- */\n    std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count());\n\n    /* ---- several runs ------------------------------------------------- */\n    const int runs = 3;\n    const double timePerRun = 1.8 / runs;\n\n    vector<int> bestOverall;\n    int bestOverallCost = INT_MAX;\n\n    for (int r = 0; r < runs; ++r) {\n        vector<int> init = greedyInsertion(rng);\n        vector<int> afterSA = simulatedAnnealing(init, rng, timePerRun);\n        vector<int> afterLocal = localImprove(afterSA);\n        int cost = computeCost(afterLocal);\n        if (cost < bestOverallCost) {\n            bestOverallCost = cost;\n            bestOverall = afterLocal;\n        }\n    }\n\n    /* ---- output ------------------------------------------------------- */\n    cout << \"50\";\n    for (int id : bestOverall) cout << ' ' << id + 1;\n    cout << '\\n';\n\n    cout << \"102 400 400\";\n    for (int id : bestOverall) {\n        cout << ' ' << a[id] << ' ' << b[id] << ' '\n             << c_[id] << ' ' << d_[id];\n    }\n    cout << \" 400 400\\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);\n        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\nstruct Edge {\n    int u, v;\n    int d;\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<pair<int,int>> coords(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    // Read edges and compute d_i\n    vector<Edge> edges(M);\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        cin >> u >> v;\n        edges[i].u = u;\n        edges[i].v = v;\n        long long dx = (long long)coords[u].first - coords[v].first;\n        long long dy = (long long)coords[u].second - coords[v].second;\n        double dist = sqrt((double)dx * dx + (double)dy * dy);\n        edges[i].d = (int)llround(dist);\n    }\n    \n    // Precompute T0: MST based on d_i\n    vector<int> edge_ids(M);\n    iota(edge_ids.begin(), edge_ids.end(), 0);\n    sort(edge_ids.begin(), edge_ids.end(), [&](int a, int b) {\n        return edges[a].d < edges[b].d;\n    });\n    \n    DSU dsu_t0(N);\n    vector<char> inT0(M, 0);\n    for (int idx : edge_ids) {\n        if (dsu_t0.unite(edges[idx].u, edges[idx].v)) {\n            inT0[idx] = 1;\n        }\n    }\n    \n    // Process edges online\n    DSU dsu(N);\n    int components = N;\n    \n    for (int i = 0; i < M; ++i) {\n        int l;\n        cin >> l;\n        \n        // If already connected, reject remaining edges\n        if (components == 1) {\n            cout << 0 << endl;\n            continue;\n        }\n        \n        int u = edges[i].u;\n        int v = edges[i].v;\n        \n        int ru = dsu.find(u);\n        int rv = dsu.find(v);\n        \n        // If edge creates a cycle, reject\n        if (ru == rv) {\n            cout << 0 << endl;\n            continue;\n        }\n        \n        // Always accept edges from T0 (guarantees connectivity)\n        bool accept = inT0[i];\n        \n        // For non-T0 edges, use rank-based selection\n        if (!accept) {\n            double d = edges[i].d;\n            double rank = (l - d) / (2.0 * d);\n            \n            // Clamp rank to [0,1] for safety\n            if (rank < 0.0) rank = 0.0;\n            if (rank > 1.0) rank = 1.0;\n            \n            // Dynamic threshold: 0.1 to 1.0\n            double progress = (double)i / (M - 1);\n            double threshold = 0.1 + 0.9 * progress;\n            \n            accept = (rank <= threshold);\n        }\n        \n        if (accept) {\n            dsu.unite(u, v);\n            --components;\n            cout << 1 << endl;\n        } else {\n            cout << 0 << endl;\n        }\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos {\n    int x, y;\n};\n\nstruct Human {\n    Pos pos;\n};\n\nstruct Pet {\n    Pos pos;\n    int type;\n};\n\nclass Grid {\npublic:\n    static const int SIZE = 30;\n    bool passable[SIZE][SIZE];\n    \n    Grid() {\n        for (int i = 0; i < SIZE; i++)\n            for (int j = 0; j < SIZE; j++)\n                passable[i][j] = true;\n    }\n    \n    bool isValid(int x, int y) const {\n        return x >= 0 && x < SIZE && y >= 0 && y < SIZE;\n    }\n    \n    bool isPassable(int x, int y) const {\n        if (!isValid(x, y)) return false;\n        return passable[x][y];\n    }\n    \n    void block(int x, int y) {\n        if (isValid(x, y)) passable[x][y] = false;\n    }\n};\n\n// BFS to count reachable squares\nint countReachable(const Grid& grid, Pos start) {\n    vector<vector<bool>> vis(Grid::SIZE, vector<bool>(Grid::SIZE, false));\n    queue<Pos> q;\n    q.push(start);\n    vis[start.x][start.y] = true;\n    \n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    \n    while (!q.empty()) {\n        Pos cur = q.front(); q.pop();\n        for (int dir = 0; dir < 4; dir++) {\n            int nx = cur.x + dx[dir];\n            int ny = cur.y + dy[dir];\n            if (grid.isPassable(nx, ny) && !vis[nx][ny]) {\n                vis[nx][ny] = true;\n                q.push({nx, ny});\n            }\n        }\n    }\n    \n    int cnt = 0;\n    for (int i = 0; i < Grid::SIZE; i++)\n        for (int j = 0; j < Grid::SIZE; j++)\n            if (vis[i][j]) cnt++;\n    return cnt;\n}\n\n// Check if a position contains any entity (pet or human)\nbool hasEntity(Pos p, const vector<Pet>& pets, const vector<Human>& humans) {\n    for (const auto& pet : pets)\n        if (pet.pos.x == p.x && pet.pos.y == p.y) return true;\n    for (const auto& human : humans)\n        if (human.pos.x == p.x && human.pos.y == p.y) return true;\n    return false;\n}\n\n// Explicit check: does any pet occupy an adjacent square (orthogonal) of 'pos'?\nbool hasPetAdjacentToBlock(Pos pos, const vector<Pet>& pets) {\n    // Check all 4 orthogonal adjacent squares\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    \n    for (int dir = 0; dir < 4; dir++) {\n        int adjX = pos.x + dx[dir];\n        int adjY = pos.y + dy[dir];\n        \n        // For each adjacent square, check if any pet is there\n        for (const auto& pet : pets) {\n            if (pet.pos.x == adjX && pet.pos.y == adjY) {\n                return true; // Found a pet in adjacent square\n            }\n        }\n    }\n    return false;\n}\n\n// Conservative validation: block only if absolutely safe\nbool isSafeBlock(Pos blockPos, const vector<Pet>& pets, \n                 const vector<Human>& humans, const Grid& grid) {\n    // Must be within grid and passable\n    if (!grid.isPassable(blockPos.x, blockPos.y)) {\n        return false; // Can't block impassable squares\n    }\n    \n    // Cannot contain any entity\n    if (hasEntity(blockPos, pets, humans)) {\n        return false; // Can't block squares with pets or humans\n    }\n    \n    // CRITICAL: Cannot have any pet in adjacent squares\n    if (hasPetAdjacentToBlock(blockPos, pets)) {\n        return false; // This is the rule that was causing runtime errors\n    }\n    \n    return true; // All checks passed\n}\n\n// Choose safest and most beneficial action\nchar chooseAction(const Human& human, const vector<Human>& humans, \n                  const vector<Pet>& pets, const Grid& grid) {\n    const char* allMoves = \".udlrUDLR\";\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    \n    struct ActionScore {\n        char move;\n        int score;\n    };\n    vector<ActionScore> candidates;\n    \n    int reachableNow = countReachable(grid, human.pos);\n    \n    for (int i = 0; i < 9; i++) {\n        char move = allMoves[i];\n        int score = 0;\n        bool valid = true;\n        \n        if (move == '.') {\n            // Staying is always safe\n            score = reachableNow;\n        } else if (move >= 'u' && move <= 'r') {\n            // Block - validate strictly\n            int dir = move - 'u';\n            Pos blockPos = {human.pos.x + dx[dir], human.pos.y + dy[dir]};\n            \n            if (!isSafeBlock(blockPos, pets, humans, grid)) {\n                valid = false;\n            } else {\n                // Score based on proximity to pets (especially dogs)\n                score = 500 + reachableNow;\n                for (const auto& pet : pets) {\n                    int dist = abs(pet.pos.x - blockPos.x) + abs(pet.pos.y - blockPos.y);\n                    if (dist <= 3) {\n                        score += 400;\n                        if (pet.type == 4) score += 800; // Dogs are priority\n                    }\n                }\n                \n                // Penalty if it isolates us too much\n                Grid temp = grid;\n                temp.block(blockPos.x, blockPos.y);\n                int reachableAfter = countReachable(temp, human.pos);\n                if (reachableAfter < reachableNow * 0.6) {\n                    score -= 300; // Too restrictive\n                }\n            }\n        } else {\n            // Move - be very conservative\n            int dir = move - 'U';\n            Pos newPos = {human.pos.x + dx[dir], human.pos.y + dy[dir]};\n            \n            if (!grid.isPassable(newPos.x, newPos.y)) {\n                valid = false;\n            } else {\n                int reachableAfter = countReachable(grid, newPos);\n                score = reachableAfter;\n                \n                // Penalty for moving toward dogs\n                for (const auto& pet : pets) {\n                    if (pet.type == 4) { // Dog\n                        int oldDist = abs(pet.pos.x - human.pos.x) + \n                                      abs(pet.pos.y - human.pos.y);\n                        int newDist = abs(pet.pos.x - newPos.x) + \n                                      abs(pet.pos.y - newPos.y);\n                        if (newDist < oldDist) score -= 200;\n                    }\n                }\n            }\n        }\n        \n        if (valid) {\n            candidates.push_back({move, score});\n        }\n    }\n    \n    // If no valid actions, stay (shouldn't happen)\n    if (candidates.empty()) return '.';\n    \n    // Sort by score\n    sort(candidates.begin(), candidates.end(),\n         [](const ActionScore& a, const ActionScore& b) { return a.score > b.score; });\n    \n    return candidates[0].move;\n}\n\n// Apply all human actions simultaneously to update state\nvoid applyHumanActions(vector<Human>& humans, const string& actions, Grid& grid) {\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    \n    for (size_t i = 0; i < actions.size(); i++) {\n        char action = actions[i];\n        if (action >= 'u' && action <= 'r') {\n            // Block square\n            int dir = action - 'u';\n            grid.block(humans[i].pos.x + dx[dir], humans[i].pos.y + dy[dir]);\n        } else if (action >= 'U' && action <= 'R') {\n            // Move to new position\n            int dir = action - 'U';\n            humans[i].pos.x += dx[dir];\n            humans[i].pos.y += dy[dir];\n        }\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    \n    vector<Pet> pets(N);\n    for (int i = 0; i < N; i++) {\n        cin >> pets[i].pos.x >> pets[i].pos.y >> pets[i].type;\n        // Convert to 0-indexed\n        pets[i].pos.x--;\n        pets[i].pos.y--;\n    }\n    \n    int M;\n    cin >> M;\n    vector<Human> humans(M);\n    for (int i = 0; i < M; i++) {\n        cin >> humans[i].pos.x >> humans[i].pos.y;\n        humans[i].pos.x--;\n        humans[i].pos.y--;\n    }\n    \n    Grid grid;\n    \n    // Main game loop\n    for (int turn = 0; turn < 300; turn++) {\n        // 1. Choose actions (no state modifications)\n        string actions;\n        for (int i = 0; i < M; i++) {\n            actions += chooseAction(humans[i], humans, pets, grid);\n        }\n        \n        // 2. Output actions\n        cout << actions << endl;\n        cout.flush();\n        \n        // 3. Read pet movements\n        vector<string> petMoves(N);\n        for (int i = 0; i < N; i++) {\n            cin >> petMoves[i];\n        }\n        \n        // 4. Apply human actions to update state\n        applyHumanActions(humans, actions, grid);\n        \n        // 5. Update pet positions\n        for (int i = 0; i < N; i++) {\n            const string& move = petMoves[i];\n            if (move == \".\") continue;\n            \n            for (char c : move) {\n                int nx = pets[i].pos.x;\n                int ny = pets[i].pos.y;\n                \n                if (c == 'U') nx--;\n                else if (c == 'D') nx++;\n                else if (c == 'L') ny--;\n                else if (c == 'R') ny++;\n                \n                if (grid.isPassable(nx, ny)) {\n                    pets[i].pos.x = nx;\n                    pets[i].pos.y = ny;\n                }\n            }\n        }\n    }\n    \n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 20;\nconst int W = 20;\nconst int N = H * W;\nconst int INF = 1e9;\n\n/* ---------- global data ---------- */\nint start, target;\ndouble forgetP;                     // probability of forgetting a character\n\narray<array<int,4>,N> neighbour;   // neighbour[v][dir], dir = 0(U),1(D),2(L),3(R)\narray<char,4> dirChar{'U','D','L','R'};\narray<int,256> dirIdx;              // char -> 0..3, -1 = invalid\n\nvector<int> bfsDist;                // shortest deterministic distance to target\n\n/* ---------- evaluation of a route ---------- */\ndouble evaluate(const string &s) {\n    static vector<double> prob, nxt;\n    prob.assign(N, 0.0);\n    nxt.assign(N, 0.0);\n    prob[start] = 1.0;\n    double expected = 0.0;\n    int L = (int)s.size();\n\n    for (int turn = 1; turn <= L; ++turn) {\n        fill(nxt.begin(), nxt.end(), 0.0);\n        int d = dirIdx[(unsigned char)s[turn-1]];\n        double arrival = 0.0;\n\n        for (int v = 0; v < N; ++v) {\n            double cur = prob[v];\n            if (cur == 0.0) continue;\n            double stayProb = cur * forgetP;\n            double moveProb = cur * (1.0 - forgetP);\n            int w = neighbour[v][d];\n            if (w == target) arrival += moveProb;\n            else               nxt[w] += moveProb;\n            nxt[v] += stayProb;\n        }\n        expected += arrival * (401 - turn);\n        prob.swap(nxt);\n    }\n    return expected;\n}\n\n/* ---------- BFS on the grid (ignoring staying) ---------- */\nvector<int> bfs_from(int src) {\n    vector<int> dist(N, INF);\n    queue<int> q;\n    dist[src] = 0;\n    q.push(src);\n    while (!q.empty()) {\n        int v = q.front(); q.pop();\n        int dv = dist[v];\n        for (int dir = 0; dir < 4; ++dir) {\n            int w = neighbour[v][dir];\n            if (w == v) continue;               // blocked by wall\n            if (dist[w] == INF) {\n                dist[w] = dv + 1;\n                q.push(w);\n            }\n        }\n    }\n    return dist;\n}\n\n/* ---------- shortest deterministic path from S to T ---------- */\nvector<char> shortestPath() {\n    vector<int> parent(N, -1);\n    vector<char> pdir(N, 0);\n    vector<int> dist(N, -1);\n    queue<int> q;\n    q.push(start);\n    dist[start] = 0;\n    while (!q.empty()) {\n        int v = q.front(); q.pop();\n        if (v == target) break;\n        for (int dir = 0; dir < 4; ++dir) {\n            int w = neighbour[v][dir];\n            if (w == v) continue;\n            if (dist[w] == -1) {\n                dist[w] = dist[v] + 1;\n                parent[w] = v;\n                pdir[w] = dirChar[dir];\n                q.push(w);\n            }\n        }\n    }\n    vector<char> path;\n    int cur = target;\n    while (cur != start) {\n        path.push_back(pdir[cur]);\n        cur = parent[cur];\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n/* ---------- greedy construction (length = 200) ---------- */\nstring greedyRoute() {\n    const int L = 200;\n    string s;\n    s.reserve(L);\n    vector<double> prob(N, 0.0), nxt(N, 0.0);\n    prob[start] = 1.0;\n\n    for (int turn = 1; turn <= L; ++turn) {\n        double bestVal = -1e100;\n        int bestDir = -1;\n        vector<double> bestNxt(N, 0.0);\n        double bestArr = 0.0;\n\n        for (int dir = 0; dir < 4; ++dir) {\n            fill(nxt.begin(), nxt.end(), 0.0);\n            double arrival = 0.0;\n\n            for (int v = 0; v < N; ++v) {\n                double cur = prob[v];\n                if (cur == 0.0) continue;\n                double stayProb = cur * forgetP;\n                double moveProb = cur * (1.0 - forgetP);\n                int w = neighbour[v][dir];\n                if (w == target) arrival += moveProb;\n                else               nxt[w] += moveProb;\n                nxt[v] += stayProb;\n            }\n            double expDist = 0.0;\n            for (int v = 0; v < N; ++v) expDist += nxt[v] * bfsDist[v];\n\n            double value = arrival * (401 - turn) - expDist;\n            if (value > bestVal) {\n                bestVal = value;\n                bestDir = dir;\n                bestArr = arrival;\n                bestNxt.swap(nxt);\n            }\n        }\n        s.push_back(dirChar[bestDir]);\n        prob.swap(bestNxt);\n    }\n    return s;\n}\n\n/* ---------- random modification of a route ---------- */\nstring modify(const string &cur, int minLen, mt19937 &rng) {\n    string nxt = cur;\n    int L = (int)nxt.size();\n    uniform_int_distribution<int> opDist(0, 9);\n    int op = opDist(rng);\n    if (op < 7) { // replace\n        uniform_int_distribution<int> posDist(0, L - 1);\n        uniform_int_distribution<int> dirDist(0, 3);\n        int pos = posDist(rng);\n        nxt[pos] = dirChar[dirDist(rng)];\n    } else if (op < 9) { // insert\n        if (L < 200) {\n            uniform_int_distribution<int> posDist(0, L);\n            uniform_int_distribution<int> dirDist(0, 3);\n            int pos = posDist(rng);\n            nxt.insert(nxt.begin() + pos, dirChar[dirDist(rng)]);\n        } else {\n            uniform_int_distribution<int> posDist(0, L - 1);\n            uniform_int_distribution<int> dirDist(0, 3);\n            int pos = posDist(rng);\n            nxt[pos] = dirChar[dirDist(rng)];\n        }\n    } else { // delete\n        if (L > minLen) {\n            uniform_int_distribution<int> posDist(0, L - 1);\n            int pos = posDist(rng);\n            nxt.erase(nxt.begin() + pos);\n        } else {\n            uniform_int_distribution<int> posDist(0, L - 1);\n            uniform_int_distribution<int> dirDist(0, 3);\n            int pos = posDist(rng);\n            nxt[pos] = dirChar[dirDist(rng)];\n        }\n    }\n    return nxt;\n}\n\n/* ---------- main ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    /* ---- read input ---- */\n    int si, sj, ti, tj;\n    double p;\n    if (!(cin >> si >> sj >> ti >> tj >> p)) return 0;\n    start = si * W + sj;\n    target = ti * W + tj;\n    forgetP = p;\n\n    vector<string> h(H, string(W - 1, '0'));\n    for (int i = 0; i < H; ++i) cin >> h[i];\n    vector<string> v(H - 1, string(W, '0'));\n    for (int i = 0; i < H - 1; ++i) cin >> v[i];\n\n    /* ---- build neighbour table ---- */\n    for (int i = 0; i < H; ++i) {\n        for (int j = 0; j < W; ++j) {\n            int id = i * W + j;\n            // up\n            if (i == 0) neighbour[id][0] = id;\n            else if (v[i-1][j] == '1') neighbour[id][0] = id;\n            else neighbour[id][0] = (i-1) * W + j;\n            // down\n            if (i == H-1) neighbour[id][1] = id;\n            else if (v[i][j] == '1') neighbour[id][1] = id;\n            else neighbour[id][1] = (i+1) * W + j;\n            // left\n            if (j == 0) neighbour[id][2] = id;\n            else if (h[i][j-1] == '1') neighbour[id][2] = id;\n            else neighbour[id][2] = i * W + (j-1);\n            // right\n            if (j == W-1) neighbour[id][3] = id;\n            else if (h[i][j] == '1') neighbour[id][3] = id;\n            else neighbour[id][3] = i * W + (j+1);\n        }\n    }\n\n    // dirIdx\n    fill(dirIdx.begin(), dirIdx.end(), -1);\n    for (int d = 0; d < 4; ++d) dirIdx[(unsigned char)dirChar[d]] = d;\n\n    /* ---- BFS distances from target ---- */\n    bfsDist = bfs_from(target);\n\n    /* ---- build candidate routes ---- */\n    vector<string> candidates;\n    // 1) shortest path (maybe repeated twice)\n    vector<char> sp = shortestPath();\n    int spLen = (int)sp.size();\n    string cand1;\n    int repeat = (spLen * 2 <= 200) ? 2 : 1;\n    for (char c : sp) {\n        for (int i = 0; i < repeat; ++i) cand1.push_back(c);\n    }\n    candidates.push_back(cand1);\n    // 2) greedy route\n    candidates.push_back(greedyRoute());\n    // 3) random route (optional)\n    {\n        string rnd(200, 'U');\n        mt19937 rng(0);\n        uniform_int_distribution<int> dirDist(0,3);\n        for (char &c : rnd) c = dirChar[dirDist(rng)];\n        candidates.push_back(rnd);\n    }\n\n    /* ---- evaluate all candidates, keep the best ---- */\n    double bestScore = -1.0;\n    string bestRoute = candidates[0];\n    for (const string &cand : candidates) {\n        double sc = evaluate(cand);\n        if (sc > bestScore) {\n            bestScore = sc;\n            bestRoute = cand;\n        }\n    }\n\n    /* ---- hill climbing / simulated annealing ---- */\n    const double TIME_LIMIT = 1.8; // seconds\n    auto startTime = chrono::high_resolution_clock::now();\n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n\n    string cur = bestRoute;\n    double curScore = bestScore;\n    double temperature = 1.0;\n    int minLen = spLen; // we never delete below the original shortest\u2011path length\n\n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - startTime).count();\n        if (elapsed > TIME_LIMIT) break;\n\n        temperature *= 0.999;\n\n        string cand = modify(cur, minLen, rng);\n        double candScore = evaluate(cand);\n\n        double delta = candScore - curScore;\n        bool accept = (delta > 0.0);\n        if (!accept) {\n            uniform_real_distribution<double> uni(0.0, 1.0);\n            if (uni(rng) < exp(delta / temperature)) accept = true;\n        }\n        if (accept) {\n            cur = cand;\n            curScore = candScore;\n        }\n        if (candScore > bestScore) {\n            bestScore = candScore;\n            bestRoute = cand;\n        }\n    }\n\n    /* ---- output ---- */\n    cout << bestRoute << '\\n';\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Constants\nconst int H = 30, W = 30;\nconst int N = H * W;\nconst int DIR = 4;\nconst int NODE_COUNT = N * DIR;\n\n// Tile connection table\nconst int TO[8][4] = {\n    {1, 0, -1, -1}, {3, -1, -1, 0}, {-1, -1, 3, 2}, {-1, 2, 1, -1},\n    {1, 0, 3, 2}, {3, 2, 1, 0}, {2, -1, 0, -1}, {-1, 3, -1, 1}\n};\n\n// Direction vectors\nconst int DI[4] = {0, -1, 0, 1};\nconst int DJ[4] = {-1, 0, 1, 0};\n\n// Rotation mapping\nint ROTATE_MAP[8][4];\n\nvoid init_rotate_map() {\n    const int ROT1[8] = {1, 2, 3, 0, 5, 4, 7, 6};\n    for (int t = 0; t < 8; ++t) {\n        ROTATE_MAP[t][0] = t;\n        int cur = t;\n        for (int r = 1; r < 4; ++r) {\n            cur = ROT1[cur];\n            ROTATE_MAP[t][r] = cur;\n        }\n    }\n}\n\n// Fast cycle detection\npair<int, int> compute_score(const array<int, N>& rot, const array<int, N>& tiles) {\n    static array<int, NODE_COUNT> nxt;\n    static array<char, NODE_COUNT> state;\n    static vector<int> cycle_lens;\n    \n    // Build next array\n    for (int i = 0; i < H; ++i) {\n        for (int j = 0; j < W; ++j) {\n            int idx = i * W + j;\n            int t = tiles[idx];\n            int r = rot[idx];\n            int eff_type = ROTATE_MAP[t][r];\n            \n            int base = idx * DIR;\n            for (int d = 0; d < DIR; ++d) {\n                int d2 = TO[eff_type][d];\n                if (d2 == -1) {\n                    nxt[base + d] = -1;\n                    continue;\n                }\n                int ni = i + DI[d2];\n                int nj = j + DJ[d2];\n                if (ni < 0 || ni >= H || nj < 0 || nj >= W) {\n                    nxt[base + d] = -1;\n                    continue;\n                }\n                int nidx = ni * W + nj;\n                int nd = (d2 + 2) % DIR;\n                nxt[base + d] = nidx * DIR + nd;\n            }\n        }\n    }\n    \n    // Find cycles\n    state.fill(0);\n    cycle_lens.clear();\n    vector<int> path;\n    path.reserve(NODE_COUNT);\n    \n    for (int s = 0; s < NODE_COUNT; ++s) {\n        if (state[s] != 0) continue;\n        \n        int cur = s;\n        path.clear();\n        \n        while (cur != -1 && state[cur] == 0) {\n            state[cur] = 1;\n            path.push_back(cur);\n            cur = nxt[cur];\n        }\n        \n        if (cur != -1 && state[cur] == 1) {\n            int start_idx = -1;\n            for (int i = 0; i < (int)path.size(); ++i) {\n                if (path[i] == cur) {\n                    start_idx = i;\n                    break;\n                }\n            }\n            if (start_idx != -1) {\n                int len = (int)path.size() - start_idx;\n                cycle_lens.push_back(len);\n            }\n        }\n        \n        for (int node : path) {\n            state[node] = 2;\n        }\n    }\n    \n    // Get top two cycle lengths\n    int L1 = 0, L2 = 0;\n    if (!cycle_lens.empty()) {\n        sort(cycle_lens.begin(), cycle_lens.end(), greater<int>());\n        L1 = cycle_lens[0];\n        if (cycle_lens.size() >= 2) L2 = cycle_lens[1];\n    }\n    \n    return {L1, L2};\n}\n\n// Greedy initialization with bug fix\nvoid greedy_init(array<int, N>& rot, const array<int, N>& tiles) {\n    for (int i = 0; i < H; ++i) {\n        for (int j = 0; j < W; ++j) {\n            int idx = i * W + j;\n            int t = tiles[idx];\n            int best_rot = 0;\n            int best_connections = -1;\n            \n            for (int r = 0; r < 4; ++r) {\n                int eff_type = ROTATE_MAP[t][r];\n                int connections = 0;\n                \n                for (int d = 0; d < DIR; ++d) {\n                    int d2 = TO[eff_type][d];\n                    if (d2 == -1) continue;\n                    int ni = i + DI[d2];\n                    int nj = j + DJ[d2];\n                    if (ni >= 0 && ni < H && nj >= 0 && nj < W) {\n                        connections++;\n                    }\n                }\n                \n                if (connections > best_connections) {\n                    best_connections = connections;\n                    best_rot = r;\n                }\n            }\n            \n            rot[idx] = best_rot;\n        }\n    }\n}\n\n// Simulated annealing with block perturbation\npair<array<int, N>, long long> simulated_annealing(const array<int, N>& tiles) {\n    const double TIME_LIMIT = 1.9;\n    auto start_time = chrono::high_resolution_clock::now();\n    \n    random_device rd;\n    mt19937 rng(rd());\n    uniform_int_distribution<int> dist_tile(0, N-1);\n    uniform_int_distribution<int> dist_rot(0, 3);\n    uniform_real_distribution<double> dist_prob(0.0, 1.0);\n    \n    array<int, N> rot;\n    greedy_init(rot, tiles);\n    \n    auto [L1, L2] = compute_score(rot, tiles);\n    long long best_score = (long long)L1 * L2;\n    array<int, N> best_rot = rot;\n    long long current_score = best_score;\n    \n    double temp = 2.0;\n    const double COOLING = 0.995;\n    const double MIN_TEMP = 0.001;\n    \n    int iterations = 0;\n    \n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > TIME_LIMIT) break;\n        \n        temp *= COOLING;\n        if (temp < MIN_TEMP) temp = MIN_TEMP;\n        \n        // Try flipping a 2x2 block for stronger perturbation\n        int center = dist_tile(rng);\n        int ci = center / W;\n        int cj = center % W;\n        \n        vector<pair<int, int>> block;\n        for (int di = -1; di <= 1; ++di) {\n            for (int dj = -1; dj <= 1; ++dj) {\n                int ni = ci + di;\n                int nj = cj + dj;\n                if (ni >= 0 && ni < H && nj >= 0 && nj < W) {\n                    block.push_back({ni, nj});\n                }\n            }\n        }\n        \n        // Save old rotations\n        vector<int> old_rots;\n        for (auto [i, j] : block) {\n            old_rots.push_back(rot[i * W + j]);\n        }\n        \n        // Apply random rotations to block\n        for (auto [i, j] : block) {\n            rot[i * W + j] = dist_rot(rng);\n        }\n        \n        auto [new_L1, new_L2] = compute_score(rot, tiles);\n        long long new_score = (long long)new_L1 * new_L2;\n        \n        double delta = new_score - current_score;\n        bool accept = false;\n        if (delta > 0) {\n            accept = true;\n        } else {\n            double prob = exp(delta / temp);\n            if (dist_prob(rng) < prob) accept = true;\n        }\n        \n        if (accept) {\n            current_score = new_score;\n            if (new_score > best_score) {\n                best_score = new_score;\n                best_rot = rot;\n            }\n        } else {\n            // Revert changes\n            for (int i = 0; i < (int)block.size(); ++i) {\n                int ti = block[i].first;\n                int tj = block[i].second;\n                rot[ti * W + tj] = old_rots[i];\n            }\n        }\n        \n        ++iterations;\n    }\n    \n    return {best_rot, best_score};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    init_rotate_map();\n    \n    array<int, N> tiles;\n    for (int i = 0; i < H; ++i) {\n        string line;\n        if (!(cin >> line)) return 0;\n        for (int j = 0; j < W; ++j) {\n            tiles[i * W + j] = line[j] - '0';\n        }\n    }\n    \n    auto [best_rot, best_score] = simulated_annealing(tiles);\n    \n    for (int i = 0; i < N; ++i) {\n        cout << best_rot[i];\n    }\n    cout << '\\n';\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Direction constants\nconst int DIR_LEFT = 1;\nconst int DIR_UP = 2;\nconst int DIR_RIGHT = 4;\nconst int DIR_DOWN = 8;\n\n// Movement vectors\nconst int DR[4] = {-1, 1, 0, 0};\nconst int DC[4] = {0, 0, -1, 1};\nconst char MOVE_CHAR[4] = {'U', 'D', 'L', 'R'};\n\nclass SlidingTreePuzzle {\nprivate:\n    int N, T;\n    vector<int> board;\n    int emptyPos;\n    vector<int> initialBoard; // Store initial state\n    \n    bool hasLine(int tile, int direction) {\n        return (tile & direction) != 0;\n    }\n    \n    int idx(int r, int c) {\n        return r * N + c;\n    }\n    \n    bool inBounds(int r, int c) {\n        return r >= 0 && r < N && c >= 0 && c < N;\n    }\n    \n    // Evaluate: size of largest tree component\n    int evaluate() {\n        vector<int> comp(N*N, -1);\n        vector<int> compSize;\n        vector<int> compEdges;\n        int compCount = 0;\n        vector<vector<int>> adj(N*N);\n        \n        // Build adjacency\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                int pos = idx(r, c);\n                int tile = board[pos];\n                if (tile == 0) continue;\n                \n                // Right neighbor\n                if (c + 1 < N) {\n                    int npos = idx(r, c+1);\n                    int ntile = board[npos];\n                    if (ntile != 0 && hasLine(tile, DIR_RIGHT) && hasLine(ntile, DIR_LEFT)) {\n                        adj[pos].push_back(npos);\n                        adj[npos].push_back(pos);\n                    }\n                }\n                \n                // Down neighbor\n                if (r + 1 < N) {\n                    int npos = idx(r+1, c);\n                    int ntile = board[npos];\n                    if (ntile != 0 && hasLine(tile, DIR_DOWN) && hasLine(ntile, DIR_UP)) {\n                        adj[pos].push_back(npos);\n                        adj[npos].push_back(pos);\n                    }\n                }\n            }\n        }\n        \n        // Find components\n        for (int i = 0; i < N*N; i++) {\n            if (board[i] == 0 || comp[i] != -1) continue;\n            \n            queue<int> q;\n            q.push(i);\n            comp[i] = compCount;\n            int size = 0;\n            \n            while (!q.empty()) {\n                int cur = q.front();\n                q.pop();\n                size++;\n                \n                for (int nxt : adj[cur]) {\n                    if (comp[nxt] == -1) {\n                        comp[nxt] = compCount;\n                        q.push(nxt);\n                    }\n                }\n            }\n            \n            compSize.push_back(size);\n            compEdges.push_back(0);\n            compCount++;\n        }\n        \n        // Count edges\n        for (int i = 0; i < N*N; i++) {\n            if (board[i] == 0) continue;\n            for (int j : adj[i]) {\n                if (i < j) {\n                    int cid = comp[i];\n                    compEdges[cid]++;\n                }\n            }\n        }\n        \n        // Find largest tree\n        int best = 0;\n        for (int i = 0; i < compCount; i++) {\n            if (compEdges[i] == compSize[i] - 1) {\n                best = max(best, compSize[i]);\n            }\n        }\n        \n        return best;\n    }\n    \n    // Make a move\n    char makeMove(int dir) {\n        int r = emptyPos / N;\n        int c = emptyPos % N;\n        int nr = r + DR[dir];\n        int nc = c + DC[dir];\n        \n        if (!inBounds(nr, nc)) return '\\0';\n        \n        int npos = idx(nr, nc);\n        swap(board[emptyPos], board[npos]);\n        emptyPos = npos;\n        return MOVE_CHAR[dir];\n    }\n    \n    // Undo a move\n    void undoMove(int dir) {\n        int oppositeDir = (dir % 2 == 0) ? dir + 1 : dir - 1;\n        makeMove(oppositeDir);\n    }\n    \n    // Reset to initial state\n    void resetToInitial() {\n        board = initialBoard;\n        for (int i = 0; i < N*N; i++) {\n            if (board[i] == 0) {\n                emptyPos = i;\n                break;\n            }\n        }\n    }\n    \npublic:\n    string solve(int N_, int T_, const vector<int>& initialBoard) {\n        N = N_;\n        T = T_;\n        board = initialBoard;\n        this->initialBoard = initialBoard;\n        \n        // Find empty position\n        for (int i = 0; i < N*N; i++) {\n            if (board[i] == 0) {\n                emptyPos = i;\n                break;\n            }\n        }\n        \n        // Initialize best solution tracking\n        vector<int> bestBoard = board;\n        int bestScore = evaluate();\n        string bestMoves = \"\";\n        string currentMoves = \"\";\n        \n        // Hill climbing with periodic restarts\n        double startTime = clock();\n        double timeLimit = 2.8;\n        \n        int steps = 0;\n        \n        while ((clock() - startTime) / CLOCKS_PER_SEC < timeLimit) {\n            // Check move limit before continuing\n            if (currentMoves.size() >= T) {\n                resetToInitial();\n                currentMoves = \"\";\n                continue;\n            }\n            \n            // Reset to initial state every 500 steps\n            if (steps > 0 && steps % 500 == 0) {\n                resetToInitial();\n                currentMoves = \"\";\n            }\n            \n            // Try all 4 directions and pick the best move\n            int bestDir = -1;\n            int bestMoveScore = -1;\n            \n            for (int dir = 0; dir < 4; dir++) {\n                int r = emptyPos / N;\n                int c = emptyPos % N;\n                int nr = r + DR[dir];\n                int nc = c + DC[dir];\n                \n                if (!inBounds(nr, nc)) continue;\n                \n                // Simulate the move\n                char moveChar = makeMove(dir);\n                int score = evaluate();\n                \n                // Choose if better (random tiebreak)\n                if (score > bestMoveScore || (score == bestMoveScore && rand() % 2)) {\n                    bestMoveScore = score;\n                    bestDir = dir;\n                }\n                \n                // Undo the move\n                undoMove(dir);\n            }\n            \n            // If we found a move that doesn't worsen the score, take it\n            if (bestDir != -1 && bestMoveScore >= evaluate()) {\n                char moveChar = makeMove(bestDir);\n                currentMoves.push_back(moveChar);\n                \n                // Check move limit after adding\n                if (currentMoves.size() > T) {\n                    // Return best found so far instead of exceeding limit\n                    return bestMoves.empty() ? currentMoves.substr(0, T) : bestMoves;\n                }\n                \n                // Update best solution if this is better\n                if (bestMoveScore > bestScore) {\n                    bestScore = bestMoveScore;\n                    bestBoard = board;\n                    bestMoves = currentMoves;\n                    \n                    // Early exit if we achieved full tree\n                    if (bestScore == N*N - 1) {\n                        return bestMoves;\n                    }\n                }\n            } else {\n                // No improving move found, make a random move\n                vector<int> validDirs;\n                for (int dir = 0; dir < 4; dir++) {\n                    int r = emptyPos / N;\n                    int c = emptyPos % N;\n                    int nr = r + DR[dir];\n                    int nc = c + DC[dir];\n                    if (inBounds(nr, nc)) {\n                        validDirs.push_back(dir);\n                    }\n                }\n                \n                if (!validDirs.empty()) {\n                    int dir = validDirs[rand() % validDirs.size()];\n                    char moveChar = makeMove(dir);\n                    currentMoves.push_back(moveChar);\n                    \n                    // Check move limit\n                    if (currentMoves.size() > T) {\n                        return bestMoves.empty() ? currentMoves.substr(0, T) : bestMoves;\n                    }\n                }\n            }\n            \n            steps++;\n        }\n        \n        // Return best solution found (never exceeds T)\n        return bestMoves.empty() ? currentMoves.substr(0, T) : bestMoves;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, T;\n    if (!(cin >> N >> T)) return 0;\n    \n    vector<int> board(N*N);\n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            char c = line[j];\n            if (c == '0') {\n                board[i*N + j] = 0;\n            } else {\n                int val = (c >= 'a') ? (c - 'a' + 10) : (c - '0');\n                board[i*N + j] = val;\n            }\n        }\n    }\n    \n    SlidingTreePuzzle solver;\n    string moves = solver.solve(N, T, board);\n    \n    // Ensure we never exceed T moves\n    if (moves.size() > T) {\n        moves = moves.substr(0, T);\n    }\n    \n    cout << moves << '\\n';\n    \n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nstruct Point { int x, y; };\nstruct Line { \n    long long A, B, C, x1, y1, x2, y2; \n    Line() {} \n    Line(long long a, long long b, long long c, long long d) : x1(a), y1(b), x2(c), y2(d) { \n        A = y2 - y1; B = x1 - x2; C = -(A * x1 + B * y1); \n        long long g = std::gcd(std::gcd(abs(A), abs(B)), abs(C)); \n        if (g > 0) { A /= g; B /= g; C /= g; } \n        if (A < 0 || (A == 0 && B < 0)) { A = -A; B = -B; C = -C; } \n    } \n    long long eval(const Point& p) const { return A * p.x + B * p.y + C; } \n};\n\n// Fast scoring function\nint compute_score(const vector<Point>& points, const vector<Line>& lines, const array<int, 11>& demand) {\n    unordered_map<unsigned long long, int> groups;\n    groups.reserve(points.size() * 2);\n    \n    for (int i = 0; i < (int)points.size(); i++) {\n        unsigned long long sig = 0;\n        bool dead = false;\n        for (int j = 0; j < (int)lines.size(); j++) {\n            long long val = lines[j].eval(points[i]);\n            if (val == 0) { dead = true; break; }\n            if (val > 0) sig |= (1ULL << j);\n        }\n        if (!dead) groups[sig]++;\n    }\n    \n    int cnt[11] = {0};\n    for (auto& [sig, sz] : groups) {\n        if (sz >= 1 && sz <= 10) cnt[sz]++;\n    }\n    \n    int score = 0;\n    for (int d = 1; d <= 10; d++) {\n        score += min(demand[d], cnt[d]);\n    }\n    return score;\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    \n    array<int, 11> a{};\n    for (int d = 1; d <= 10; d++) cin >> a[d];\n    vector<Point> points(N);\n    for (int i = 0; i < N; i++) cin >> points[i].x >> points[i].y;\n    \n    vector<Line> lines;\n    vector<unsigned long long> signatures(N, 0);\n    vector<char> dead(N, 0);\n    array<int, 11> remain = a;\n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<long long> coord(-1000000000LL, 1000000000LL);\n    \n    const int CANDIDATES = 40; // 20 NN + 10 subset + 10 random\n    \n    // Phase 1: Greedy construction with multi-strategy candidates\n    for (int iter = 0; iter < K; iter++) {\n        vector<int> demand_sizes;\n        for (int d = 1; d <= 10; d++) if (remain[d] > 0) demand_sizes.push_back(d);\n        if (demand_sizes.empty()) break;\n        int target = demand_sizes[rng() % demand_sizes.size()];\n        \n        double best_score = -1;\n        Line best_line;\n        \n        for (int c = 0; c < CANDIDATES; c++) {\n            Line cand;\n            \n            // Strategy 1: Nearest neighbor (proven effective)\n            if (c < 20) {\n                int center = -1;\n                for (int tries = 0; tries < 25; tries++) {\n                    uniform_int_distribution<> idx(0, N-1);\n                    int i = idx(rng);\n                    if (!dead[i]) { center = i; break; }\n                }\n                \n                if (center == -1) {\n                    long long x1 = coord(rng), y1 = coord(rng);\n                    long long x2 = coord(rng), y2 = coord(rng);\n                    if (x1 == x2 && y1 == y2) x2++;\n                    cand = Line(x1, y1, x2, y2);\n                } else {\n                    int nearest = -1;\n                    long long best_dist = (1LL << 60);\n                    for (int i = 0; i < N; i++) {\n                        if (i == center || dead[i]) continue;\n                        long long dx = (long long)points[i].x - points[center].x;\n                        long long dy = (long long)points[i].y - points[center].y;\n                        long long dist = dx*dx + dy*dy;\n                        if (dist < best_dist) {\n                            best_dist = dist;\n                            nearest = i;\n                        }\n                    }\n                    \n                    if (nearest == -1) {\n                        long long x1 = coord(rng), y1 = coord(rng);\n                        long long x2 = coord(rng), y2 = coord(rng);\n                        if (x1 == x2 && y1 == y2) x2++;\n                        cand = Line(x1, y1, x2, y2);\n                    } else {\n                        long long midx = ((long long)points[center].x + points[nearest].x) / 2;\n                        long long midy = ((long long)points[center].y + points[nearest].y) / 2;\n                        long long dx = (long long)points[nearest].x - points[center].x;\n                        long long dy = (long long)points[nearest].y - points[center].y;\n                        cand = Line(midx, midy, midx - dy, midy + dx);\n                    }\n                }\n            }\n            // Strategy 2: Small random subset\n            else if (c < 30) {\n                vector<int> subset;\n                for (int tries = 0; tries < 10 && subset.size() < 3; tries++) {\n                    uniform_int_distribution<> idx(0, N-1);\n                    int i = idx(rng);\n                    if (!dead[i]) subset.push_back(i);\n                }\n                \n                if (subset.size() < 2) {\n                    long long x1 = coord(rng), y1 = coord(rng);\n                    long long x2 = coord(rng), y2 = coord(rng);\n                    if (x1 == x2 && y1 == y2) x2++;\n                    cand = Line(x1, y1, x2, y2);\n                } else {\n                    long long midx = 0, midy = 0;\n                    for (int idx : subset) {\n                        midx += points[idx].x;\n                        midy += points[idx].y;\n                    }\n                    midx /= subset.size();\n                    midy /= subset.size();\n                    \n                    long long dx = (long long)points[subset[1]].x - points[subset[0]].x;\n                    long long dy = (long long)points[subset[1]].y - points[subset[0]].y;\n                    cand = Line(midx, midy, midx - dy, midy + dx);\n                }\n            }\n            // Strategy 3: Pure random\n            else {\n                long long x1 = coord(rng), y1 = coord(rng);\n                long long x2 = coord(rng), y2 = coord(rng);\n                if (x1 == x2 && y1 == y2) x2++;\n                cand = Line(x1, y1, x2, y2);\n            }\n            \n            // Score\n            unordered_map<unsigned long long, int> groups;\n            groups.reserve(N / 2);\n            \n            for (int i = 0; i < N; i++) {\n                if (dead[i]) continue;\n                long long val = cand.eval(points[i]);\n                if (val == 0) continue;\n                unsigned long long sig = signatures[i];\n                if (val > 0) sig |= (1ULL << iter);\n                groups[sig]++;\n            }\n            \n            int cnt[11] = {0};\n            for (auto& [sig, sz] : groups) {\n                if (sz >= 1 && sz <= 10) cnt[sz]++;\n            }\n            \n            double score = 0;\n            for (int d = 1; d <= 10; d++) {\n                double w = 1.0 + remain[d] * 0.05;\n                score += w * min(remain[d], cnt[d]);\n            }\n            \n            if (score > best_score) {\n                best_score = score;\n                best_line = cand;\n            }\n        }\n        \n        // Apply line\n        unordered_map<unsigned long long, int> final_groups;\n        final_groups.reserve(N / 2);\n        \n        for (int i = 0; i < N; i++) {\n            if (dead[i]) continue;\n            long long val = best_line.eval(points[i]);\n            if (val == 0) dead[i] = 1;\n            else {\n                unsigned long long sig = signatures[i];\n                if (val > 0) sig |= (1ULL << iter);\n                final_groups[sig]++;\n            }\n        }\n        \n        for (auto& [sig, sz] : final_groups) {\n            if (sz >= 1 && sz <= 10 && remain[sz] > 0) {\n                remain[sz]--;\n            }\n        }\n        \n        lines.push_back(best_line);\n    }\n    \n    // Phase 2: Hill climbing with proper evaluation\n    const int LOCAL_STEPS = 50;\n    int current_score = compute_score(points, lines, a);\n    \n    for (int step = 0; step < LOCAL_STEPS && !lines.empty(); step++) {\n        uniform_int_distribution<> line_idx(0, lines.size() - 1);\n        int idx = line_idx(rng);\n        \n        Line original = lines[idx];\n        \n        // Generate candidate replacement\n        long long x1 = coord(rng), y1 = coord(rng);\n        long long x2 = coord(rng), y2 = coord(rng);\n        if (x1 == x2 && y1 == y2) x2++;\n        Line candidate(x1, y1, x2, y2);\n        \n        // Evaluate\n        lines[idx] = candidate;\n        int new_score = compute_score(points, lines, a);\n        \n        if (new_score > current_score) {\n            current_score = new_score;\n            // Keep improvement\n        } else {\n            // Revert\n            lines[idx] = original;\n        }\n    }\n    \n    cout << lines.size() << \"\\n\";\n    auto clamp = [](long long v) { return max(-1000000000LL, min(1000000000LL, v)); };\n    for (auto& line : lines) {\n        cout << clamp(line.x1) << \" \" << clamp(line.y1) << \" \"\n             << clamp(line.x2) << \" \" << clamp(line.y2) << \"\\n\";\n    }\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n};\n\nstruct Operation {\n    Point p1, p2, p3, p4;\n};\n\nclass RectJoinSolver {\n    int N, M;\n    double center;\n    vector<vector<bool>> has_dot;\n    vector<vector<bool>> edge_h, edge_v, edge_d1, edge_d2;\n    vector<vector<int>> weight;\n    long long total_S = 0;\n    vector<Operation> operations;\n    \n    chrono::steady_clock::time_point start_time;\n    const double TIME_LIMIT = 4.92; // Near-maximum safe limit\n\n    bool in_bounds(const Point& p) const {\n        return p.x >= 0 && p.x < N && p.y >= 0 && p.y < N; // FIXED: p.y instead of y\n    }\n\n    bool time_exceeded() const {\n        auto now = chrono::steady_clock::now();\n        return chrono::duration<double>(now - start_time).count() > TIME_LIMIT;\n    }\n\n    // Unified handlers with bounds check elimination\n    bool handle_diagonal1(int x1, int y1, int x2, int y2, bool dry_run) {\n        if (x2 <= x1 || y2 - y1 != x2 - x1) return false;\n        for (int x = x1; x < x2; x++) {\n            int y = y1 + (x - x1);\n            if ((unsigned)x >= (unsigned)(N-1) || (unsigned)y >= (unsigned)(N-1)) return false;\n            if (dry_run) {\n                if (edge_d1[x][y]) return false;\n            } else {\n                edge_d1[x][y] = true;\n            }\n        }\n        return true;\n    }\n\n    bool handle_diagonal2(int x1, int y1, int x2, int y2, bool dry_run) {\n        if (x2 <= x1 || y2 - y1 != -(x2 - x1)) return false;\n        for (int x = x1; x < x2; x++) {\n            int y = y1 - (x - x1);\n            if ((unsigned)x >= (unsigned)(N-1) || (unsigned)y >= (unsigned)N) return false;\n            if (dry_run) {\n                if (edge_d2[x][y]) return false;\n            } else {\n                edge_d2[x][y] = true;\n            }\n        }\n        return true;\n    }\n\n    bool handle_horizontal(int x1, int x2, int y, bool dry_run) {\n        for (int x = min(x1,x2); x < max(x1,x2); x++) {\n            if ((unsigned)x >= (unsigned)(N-1)) return false;\n            if (dry_run) {\n                if (edge_h[x][y]) return false;\n            } else {\n                edge_h[x][y] = true;\n            }\n        }\n        return true;\n    }\n\n    bool handle_vertical(int y1, int y2, int x, bool dry_run) {\n        for (int y = min(y1,y2); y < max(y1,y2); y++) {\n            if ((unsigned)y >= (unsigned)(N-1)) return false;\n            if (dry_run) {\n                if (edge_v[x][y]) return false;\n            } else {\n                edge_v[x][y] = true;\n            }\n        }\n        return true;\n    }\n\npublic:\n    RectJoinSolver(int N, int M) : N(N), M(M) {\n        start_time = chrono::steady_clock::now();\n        center = (N - 1) / 2.0;\n        has_dot.assign(N, vector<bool>(N, false));\n        edge_h.assign(N, vector<bool>(N, false));\n        edge_v.assign(N, vector<bool>(N, false));\n        edge_d1.assign(N, vector<bool>(N, false));\n        edge_d2.assign(N, vector<bool>(N, false));\n        weight.assign(N, vector<int>(N, 0));\n        \n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y < N; y++) {\n                double dx = x - center;\n                double dy = y - center;\n                weight[x][y] = (int)(dx*dx + dy*dy + 1.0);\n                total_S += weight[x][y];\n            }\n        }\n    }\n\n    void add_initial_dot(int x, int y) {\n        has_dot[x][y] = true;\n    }\n\n    bool try_axis(const Point& p1, int a, int b) {\n        if (a == 0 || b == 0 || abs(a) > 35 || abs(b) > 35) return false;\n        \n        Point p2 = {p1.x + a, p1.y};\n        Point p3 = {p1.x + a, p1.y + b};\n        Point p4 = {p1.x, p1.y + b};\n        \n        if (!in_bounds(p2) || !in_bounds(p3) || !in_bounds(p4)) return false;\n        if (has_dot[p1.x][p1.y]) return false;\n        if (!has_dot[p2.x][p2.y] || !has_dot[p3.x][p3.y] || !has_dot[p4.x][p4.y]) return false;\n\n        int sx = (a > 0) ? 1 : -1, sy = (b > 0) ? 1 : -1;\n        for (int x = p1.x + sx; x != p2.x; x += sx) if (has_dot[x][p1.y]) return false;\n        for (int y = p2.y + sy; y != p3.y; y += sy) if (has_dot[p2.x][y]) return false;\n        for (int x = p3.x - sx; x != p4.x; x -= sx) if (has_dot[x][p3.y]) return false;\n        for (int y = p4.y - sy; y != p1.y; y -= sy) if (has_dot[p4.x][y]) return false;\n\n        if (!handle_horizontal(p1.x, p2.x, p1.y, true)) return false;\n        if (!handle_vertical(p2.y, p3.y, p2.x, true)) return false;\n        if (!handle_horizontal(p4.x, p3.x, p4.y, true)) return false;\n        if (!handle_vertical(p1.y, p4.y, p1.x, true)) return false;\n\n        has_dot[p1.x][p1.y] = true;\n        handle_horizontal(p1.x, p2.x, p1.y, false);\n        handle_vertical(p2.y, p3.y, p2.x, false);\n        handle_horizontal(p4.x, p3.x, p4.y, false);\n        handle_vertical(p1.y, p4.y, p1.x, false);\n        \n        operations.push_back({p1, p2, p3, p4});\n        return true;\n    }\n\n    bool try_diagonal(const Point& p1, int d, int e) {\n        if (d == 0 || e == 0 || abs(d) > 25 || abs(e) > 25) return false;\n        \n        Point p2 = {p1.x + d, p1.y + d};\n        Point p4 = {p1.x + e, p1.y - e};\n        Point p3 = {p2.x + e, p2.y - e};\n        \n        if (!in_bounds(p2) || !in_bounds(p3) || !in_bounds(p4)) return false;\n        if (has_dot[p1.x][p1.y]) return false;\n        if (!has_dot[p2.x][p2.y] || !has_dot[p3.x][p3.y] || !has_dot[p4.x][p4.y]) return false;\n\n        int s1 = (d > 0) ? 1 : -1, s2 = (e > 0) ? 1 : -1;\n        for (int i = 1; i < abs(d); i++) {\n            int x = p1.x + i * s1, y = p1.y + i * s1;\n            if (has_dot[x][y]) return false;\n        }\n        for (int i = 1; i < abs(e); i++) {\n            int x = p2.x + i * s2, y = p2.y - i * s2;\n            if (has_dot[x][y]) return false;\n        }\n        for (int i = 1; i < abs(d); i++) {\n            int x = p4.x + i * s1, y = p4.y + i * s1;\n            if (has_dot[x][y]) return false;\n        }\n        for (int i = 1; i < abs(e); i++) {\n            int x = p1.x + i * s2, y = p1.y - i * s2;\n            if (has_dot[x][y]) return false;\n        }\n\n        if (!handle_diagonal1(p1.x, p1.y, p2.x, p2.y, true)) return false;\n        if (!handle_diagonal2(p2.x, p2.y, p3.x, p3.y, true)) return false;\n        if (!handle_diagonal1(p4.x, p4.y, p3.x, p3.y, true)) return false;\n        if (!handle_diagonal2(p1.x, p1.y, p4.x, p4.y, true)) return false;\n\n        has_dot[p1.x][p1.y] = true;\n        handle_diagonal1(p1.x, p1.y, p2.x, p2.y, false);\n        handle_diagonal2(p2.x, p2.y, p3.x, p3.y, false);\n        handle_diagonal1(p4.x, p4.y, p3.x, p3.y, false);\n        handle_diagonal2(p1.x, p1.y, p4.x, p4.y, false);\n        \n        operations.push_back({p1, p2, p3, p4});\n        return true;\n    }\n\n    bool is_corner(const Point& p) const {\n        return (p.x == 0 || p.x == N-1) && (p.y == 0 || p.y == N-1);\n    }\n\n    bool is_edge(const Point& p) const {\n        return p.x == 0 || p.x == N-1 || p.y == 0 || p.y == N-1;\n    }\n\n    bool try_corner_pair(const Point& c1, const Point& c2) {\n        if (c1.x == c2.x || c1.y == c2.y) return false;\n        Point new_corner = {min(c1.x, c2.x), min(c1.y, c2.y)};\n        Point p2 = {max(c1.x, c2.x), min(c1.y, c2.y)};\n        Point p3 = {max(c1.x, c2.x), max(c1.y, c2.y)};\n        Point p4 = {min(c1.x, c2.x), max(c1.y, c2.y)};\n        \n        if (!has_dot[new_corner.x][new_corner.y] && \n            has_dot[p2.x][p2.y] && has_dot[p3.x][p3.y] && has_dot[p4.x][p4.y]) {\n            return try_axis(new_corner, p2.x - new_corner.x, p4.y - new_corner.y);\n        }\n        return false;\n    }\n\n    void solve() {\n        // Build candidates\n        vector<pair<int, Point>> candidates;\n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y < N; y++) {\n                if (!has_dot[x][y]) {\n                    candidates.push_back({-weight[x][y], {x, y}});\n                }\n            }\n        }\n        sort(candidates.begin(), candidates.end(), \n            [](const auto& a, const auto& b){ return a.first < b.first; });\n\n        // Phase 0: Corner pairs (highest weight opportunity)\n        if (!time_exceeded()) {\n            vector<Point> corners = {{0,0}, {0,N-1}, {N-1,0}, {N-1,N-1}};\n            for (int i = 0; i < 4 && !time_exceeded(); i++) {\n                for (int j = i+1; j < 4 && !time_exceeded(); j++) {\n                    try_corner_pair(corners[i], corners[j]);\n                }\n            }\n        }\n\n        // Phase 1: Moderate corner focus (5 attempts each)\n        if (!time_exceeded()) {\n            for (const auto& [neg_w, p] : candidates) {\n                if (has_dot[p.x][p.y]) continue;\n                if (!is_corner(p)) continue;\n                for (int sz : {30,25,20,15}) {\n                    for (int tries = 0; tries < 5 && !time_exceeded(); tries++) {\n                        int a = (rand() % (2*sz + 1)) - sz;\n                        int b = (rand() % (2*sz + 1)) - sz;\n                        if (a && b && try_axis(p, a, b)) break;\n                        int d = (rand() % (2*sz + 1)) - sz;\n                        int e = (rand() % (2*sz + 1)) - sz;\n                        if (d && e && try_diagonal(p, d, e)) break;\n                    }\n                }\n            }\n        }\n\n        // Phase 2: Alternating axis/diagonal for interior cells (prevents starvation)\n        if (!time_exceeded()) {\n            for (int round = 0; round < 12 && !time_exceeded(); round++) {\n                // Axis pass\n                for (auto& [neg_w, p] : candidates) {\n                    if (has_dot[p.x][p.y]) continue;\n                    if (is_edge(p)) continue; // Edges handled later\n                    for (int sz : {25,20,15,12,10}) {\n                        for (int tries = 0; tries < 8 && !time_exceeded(); tries++) {\n                            int a = (rand() % (2*sz + 1)) - sz;\n                            int b = (rand() % (2*sz + 1)) - sz;\n                            if (a && b && try_axis(p, a, b)) break;\n                        }\n                    }\n                }\n                // Diagonal pass\n                for (auto& [neg_w, p] : candidates) {\n                    if (has_dot[p.x][p.y]) continue;\n                    if (is_edge(p)) continue;\n                    for (int sz : {20,15,12,10,8}) {\n                        for (int tries = 0; tries < 6 && !time_exceeded(); tries++) {\n                            int d = (rand() % (2*sz + 1)) - sz;\n                            int e = (rand() % (2*sz + 1)) - sz;\n                            if (d && e && try_diagonal(p, d, e)) break;\n                        }\n                    }\n                }\n            }\n        }\n\n        // Phase 3: Edge cells (moderate weight boost)\n        if (!time_exceeded()) {\n            for (auto& [neg_w, p] : candidates) {\n                if (has_dot[p.x][p.y]) continue;\n                if (!is_edge(p)) continue;\n                for (int sz : {20,15,12,10}) {\n                    for (int tries = 0; tries < 6 && !time_exceeded(); tries++) {\n                        int mode = rand() % 2;\n                        if (mode == 0) {\n                            int a = (rand() % (2*sz + 1)) - sz;\n                            int b = (rand() % (2*sz + 1)) - sz;\n                            if (a && b && try_axis(p, a, b)) break;\n                        } else {\n                            int d = (rand() % (2*sz + 1)) - sz;\n                            int e = (rand() % (2*sz + 1)) - sz;\n                            if (d && e && try_diagonal(p, d, e)) break;\n                        }\n                    }\n                }\n            }\n        }\n\n        // Phase 4: Systematic small rectangles (high success rate, completes coverage)\n        if (!time_exceeded()) {\n            for (int a = -5; a <= 5 && !time_exceeded(); a++) {\n                for (int b = -5; b <= 5 && !time_exceeded(); b++) {\n                    if (a == 0 || b == 0) continue;\n                    for (auto& [neg_w, p] : candidates) {\n                        if (has_dot[p.x][p.y]) continue;\n                        try_axis(p, a, b);\n                    }\n                }\n            }\n        }\n\n        // Phase 5: Random until time expires (covers gaps)\n        while (!time_exceeded()) {\n            const auto& [neg_w, p] = candidates[rand() % candidates.size()];\n            if (has_dot[p.x][p.y]) continue;\n            int mode = rand() % 2;\n            int sz = 15 + rand() % 10;\n            if (mode == 0) {\n                int a = (rand() % (2*sz + 1)) - sz;\n                int b = (rand() % (2*sz + 1)) - sz;\n                if (a && b) try_axis(p, a, b);\n            } else {\n                int d = (rand() % (2*sz + 1)) - sz;\n                int e = (rand() % (2*sz + 1)) - sz;\n                if (d && e) try_diagonal(p, d, e);\n            }\n        }\n    }\n\n    const vector<Operation>& get_operations() const {\n        return operations;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    srand(chrono::steady_clock::now().time_since_epoch().count());\n    \n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n    \n    RectJoinSolver solver(N, M);\n    \n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        solver.add_initial_dot(x, y);\n    }\n    \n    solver.solve();\n    \n    const auto& ops = solver.get_operations();\n    cout << ops.size() << \"\\n\";\n    for (const auto& op : ops) {\n        cout << op.p1.x << \" \" << op.p1.y << \" \"\n             << op.p2.x << \" \" << op.p2.y << \" \"\n             << op.p3.x << \" \" << op.p3.y << \" \"\n             << op.p4.x << \" \" << op.p4.y << \"\\n\";\n    }\n    \n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct UnionFind {\n    vector<int> parent, size;\n    UnionFind(int n = 0) { init(n); }\n    \n    void init(int n) {\n        parent.resize(n);\n        size.assign(n, 1);\n        iota(parent.begin(), parent.end(), 0);\n    }\n    \n    int find(int x) {\n        if (parent[x] == x) return x;\n        return parent[x] = find(parent[x]);\n    }\n    \n    void unite(int x, int y) {\n        x = find(x);\n        y = find(y);\n        if (x == y) return;\n        if (size[x] < size[y]) swap(x, y);\n        parent[y] = x;\n        size[x] += size[y];\n    }\n    \n    int getSize(int x) {\n        return size[find(x)];\n    }\n};\n\nclass CandyBox {\n    static const int H = 10;\n    static const int W = 10;\n    static const int N = H * W;\n    static const int SIM_COUNT = 55; // Maximum practical\n    static const int EARLY_TERM = 12;\n    \n    array<array<int, W>, H> grid;\n    array<array<int, W>, H> tmpGrid;\n    mt19937 rng;\n    \n    // Enhanced realistic tilt considering top 2 flavors\n    int realisticTilt(const array<array<int, W>, H>& state, const vector<int>& remainingFlavors) {\n        int futureCounts[4] = {0};\n        for (int f : remainingFlavors) futureCounts[f]++;\n        \n        int currentCounts[4] = {0};\n        for (int i = 0; i < H; i++) {\n            for (int j = 0; j < W; j++) {\n                if (state[i][j] != 0) currentCounts[state[i][j]]++;\n            }\n        }\n        \n        // Find top 2 flavors by combined count\n        int flavors[3] = {1, 2, 3};\n        sort(flavors, flavors + 3, [&](int a, int b) {\n            return (currentCounts[a] + futureCounts[a]) > (currentCounts[b] + futureCounts[b]);\n        });\n        \n        int primary = flavors[0];\n        int secondary = flavors[1];\n        \n        // Count both in quadrants (weighted: primary 2x, secondary 1x)\n        int scores[4] = {0}; // F, B, L, R\n        \n        for (int i = 0; i < H; i++) {\n            for (int j = 0; j < W; j++) {\n                int cellFlavor = state[i][j];\n                if (cellFlavor == primary) {\n                    if (i < H/2) scores[0] += 2; else scores[1] += 2; // F/B\n                    if (j < W/2) scores[2] += 2; else scores[3] += 2; // L/R\n                } else if (cellFlavor == secondary) {\n                    if (i < H/2) scores[0] += 1; else scores[1] += 1;\n                    if (j < W/2) scores[2] += 1; else scores[3] += 1;\n                }\n            }\n        }\n        \n        // Choose direction with highest score\n        int bestDir = 0;\n        for (int d = 1; d < 4; d++) {\n            if (scores[d] > scores[bestDir]) bestDir = d;\n        }\n        \n        // Small random element (20% chance) to avoid deterministic patterns\n        return (rng() % 5 == 0) ? (rng() % 4) : bestDir;\n    }\n    \npublic:\n    CandyBox() : rng(chrono::steady_clock::now().time_since_epoch().count()) {\n        for (int i = 0; i < H; i++)\n            grid[i].fill(0);\n    }\n    \n    void placeCandy(int flavor, int p) {\n        int cnt = 0;\n        for (int i = 0; i < H; i++) {\n            for (int j = 0; j < W; j++) {\n                if (grid[i][j] == 0) {\n                    cnt++;\n                    if (cnt == p) {\n                        grid[i][j] = flavor;\n                        return;\n                    }\n                }\n            }\n        }\n    }\n    \n    void simulateTilt(int d, const array<array<int, W>, H>& src, array<array<int, W>, H>& dst) {\n        dst = src;\n        \n        if (d == 0) { // Forward (up)\n            for (int j = 0; j < W; j++) {\n                int writePos = 0;\n                for (int i = 0; i < H; i++) {\n                    if (dst[i][j] != 0) {\n                        if (i != writePos) {\n                            dst[writePos][j] = dst[i][j];\n                            dst[i][j] = 0;\n                        }\n                        writePos++;\n                    }\n                }\n            }\n        } else if (d == 1) { // Backward (down)\n            for (int j = 0; j < W; j++) {\n                int writePos = H - 1;\n                for (int i = H - 1; i >= 0; i--) {\n                    if (dst[i][j] != 0) {\n                        if (i != writePos) {\n                            dst[writePos][j] = dst[i][j];\n                            dst[i][j] = 0;\n                        }\n                        writePos--;\n                    }\n                }\n            }\n        } else if (d == 2) { // Left\n            for (int i = 0; i < H; i++) {\n                int writePos = 0;\n                for (int j = 0; j < W; j++) {\n                    if (dst[i][j] != 0) {\n                        if (j != writePos) {\n                            dst[i][writePos] = dst[i][j];\n                            dst[i][j] = 0;\n                        }\n                        writePos++;\n                    }\n                }\n            }\n        } else { // Right\n            for (int i = 0; i < H; i++) {\n                int writePos = W - 1;\n                for (int j = W - 1; j >= 0; j--) {\n                    if (dst[i][j] != 0) {\n                        if (j != writePos) {\n                            dst[i][writePos] = dst[i][j];\n                            dst[i][j] = 0;\n                        }\n                        writePos--;\n                    }\n                }\n            }\n        }\n    }\n    \n    long long calculateScore(const array<array<int, W>, H>& g) {\n        UnionFind uf(N);\n        int id[H][W];\n        int curId = 0;\n        \n        for (int i = 0; i < H; i++) {\n            for (int j = 0; j < W; j++) {\n                if (g[i][j] != 0) {\n                    id[i][j] = curId++;\n                } else {\n                    id[i][j] = -1;\n                }\n            }\n        }\n        \n        const int dr[4] = {-1, 1, 0, 0};\n        const int dc[4] = {0, 0, -1, 1};\n        \n        for (int i = 0; i < H; i++) {\n            for (int j = 0; j < W; j++) {\n                if (id[i][j] == -1) continue;\n                for (int dir = 0; dir < 4; dir++) {\n                    int ni = i + dr[dir];\n                    int nj = j + dc[dir];\n                    if (ni >= 0 && ni < H && nj >= 0 && nj < W && id[ni][nj] != -1) {\n                        if (g[i][j] == g[ni][nj]) {\n                            uf.unite(id[i][j], id[ni][nj]);\n                        }\n                    }\n                }\n            }\n        }\n        \n        long long score = 0;\n        vector<char> visited(curId, 0);\n        for (int i = 0; i < curId; i++) {\n            int root = uf.find(i);\n            if (!visited[root]) {\n                int size = uf.getSize(root);\n                score += 1LL * size * size;\n                visited[root] = 1;\n            }\n        }\n        return score;\n    }\n    \n    long long simulateMonteCarlo(int initialDir, const vector<int>& flavors, int currentStep) {\n        long long totalScore = 0;\n        array<array<int, W>, H> simGrid;\n        simulateTilt(initialDir, grid, simGrid);\n        \n        // Cross-direction early termination tracking\n        static long long dirSums[4] = {0};\n        static int dirCounts[4] = {0};\n        \n        for (int sim = 0; sim < SIM_COUNT; sim++) {\n            array<array<int, W>, H> copy = simGrid;\n            vector<int> remainingFlavors(flavors.begin() + currentStep + 1, flavors.end());\n            \n            for (int step = currentStep + 1; step < 100; step++) {\n                vector<pair<int, int>> emptyCells;\n                for (int i = 0; i < H; i++) {\n                    for (int j = 0; j < W; j++) {\n                        if (copy[i][j] == 0) {\n                            emptyCells.emplace_back(i, j);\n                        }\n                    }\n                }\n                \n                if (emptyCells.empty()) break;\n                \n                int pos = rng() % emptyCells.size();\n                copy[emptyCells[pos].first][emptyCells[pos].second] = flavors[step];\n                remainingFlavors.erase(remainingFlavors.begin());\n                \n                if (step < 99) {\n                    int dir = realisticTilt(copy, remainingFlavors);\n                    array<array<int, W>, H> newGrid;\n                    simulateTilt(dir, copy, newGrid);\n                    copy = newGrid;\n                }\n            }\n            \n            long long score = calculateScore(copy);\n            totalScore += score;\n            \n            if (sim < EARLY_TERM) {\n                dirSums[initialDir] += score;\n                dirCounts[initialDir]++;\n            }\n            \n            // Cross-direction early termination (after EARLY_TERM)\n            if (sim == EARLY_TERM - 1 && currentStep < 30) {\n                bool dominant = true;\n                for (int d = 0; d < 4; d++) {\n                    if (dirCounts[d] > 0 && d != initialDir) {\n                        if (dirSums[d] > 0) {\n                            if (dirSums[d] * 1.15 > dirSums[initialDir]) {\n                                dominant = false;\n                                break;\n                            }\n                        }\n                    }\n                }\n                if (dominant) break;\n            }\n        }\n        \n        return totalScore / SIM_COUNT;\n    }\n    \n    char chooseDirection(const vector<int>& flavors, int currentStep) {\n        long long greedyScores[4];\n        for (int d = 0; d < 4; d++) {\n            simulateTilt(d, grid, tmpGrid);\n            greedyScores[d] = calculateScore(tmpGrid);\n        }\n        \n        if (currentStep < 60) {\n            long long mcScores[4];\n            for (int d = 0; d < 4; d++) {\n                mcScores[d] = simulateMonteCarlo(d, flavors, currentStep);\n            }\n            \n            int bestMCDir = 0;\n            for (int d = 1; d < 4; d++) {\n                if (mcScores[d] > mcScores[bestMCDir]) bestMCDir = d;\n            }\n            \n            long long bestGreedyScore = *max_element(greedyScores, greedyScores + 4);\n            // Ultra-aggressive tiered threshold for maximum early-game impact\n            int threshold = (currentStep < 10) ? -1 : (currentStep < 20 ? 0 : (currentStep < 30 ? 1 : (currentStep < 45 ? 3 : 5)));\n            if (mcScores[bestMCDir] > bestGreedyScore + threshold) {\n                simulateTilt(bestMCDir, grid, grid);\n                const char dirChar[4] = {'F', 'B', 'L', 'R'};\n                return dirChar[bestMCDir];\n            }\n        }\n        \n        int bestDir = 0;\n        for (int d = 1; d < 4; d++) {\n            if (greedyScores[d] > greedyScores[bestDir]) bestDir = d;\n        }\n        \n        simulateTilt(bestDir, grid, grid);\n        const char dirChar[4] = {'F', 'B', 'L', 'R'};\n        return dirChar[bestDir];\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    vector<int> flavors(100);\n    for (int i = 0; i < 100; i++) {\n        if (!(cin >> flavors[i])) return 0;\n    }\n    \n    CandyBox box;\n    \n    for (int step = 0; step < 100; step++) {\n        int p;\n        cin >> p;\n        box.placeCandy(flavors[step], p);\n        cout << box.chooseDirection(flavors, step) << endl;\n    }\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    const double epsilon = eps;\n    const bool noiseless = (epsilon < 1e-12);\n    int N;                     // number of vertices\n\n    /* -------------------------------------------------------------\n       choose N\n       ------------------------------------------------------------- */\n    if (noiseless) {\n        // N = 5 is enough: 2^10 = 1024 > 100\n        N = 5;\n    } else {\n        double I = log2(max(2, M));          // bits to transmit\n        double H = -epsilon * log2(epsilon) - (1.0 - epsilon) * log2(1.0 - epsilon);\n        double C = 1.0 - H;                  // capacity per edge\n        double need = (I + 5.0) / C;         // a few redundant bits (5 instead of 3)\n        int needEdges = (int)ceil(need);\n        // solve N(N-1)/2 >= needEdges\n        double disc = 1.0 + 8.0 * needEdges;\n        double sq = sqrt(disc);\n        N = (int)ceil((1.0 + sq) / 2.0);\n        if (N < 4) N = 4;\n        if (N > 100) N = 100;\n    }\n\n    const int n = N;\n    const int tot = n * (n - 1) / 2;\n\n    /* -------------------------------------------------------------\n       generate the M graphs (deterministic)\n       ------------------------------------------------------------- */\n    // adjacency matrix G[i][u][v] (0/1)\n    vector<vector<vector<char>>> G(M,\n        vector<vector<char>>(n, vector<char>(n, 0)));\n\n    // vertex order sorted by degree (used for alignment in noiseless case)\n    vector<vector<int>> orderG(M, vector<int>(n));\n    // sorted degree sequences (decreasing)\n    vector<vector<int>> sortedDeg(M, vector<int>(n));\n    // triangle count\n    vector<int> tri(M, 0);\n\n    for (int i = 0; i < M; ++i) {\n        mt19937 rng(i * 10007 + M * 12345 + n * 6789 + 42);\n        uniform_int_distribution<int> dist(0, 1);\n\n        for (int u = 0; u < n; ++u)\n            for (int v = u + 1; v < n; ++v) {\n                char e = (char)dist(rng);\n                G[i][u][v] = G[i][v][u] = e;\n            }\n\n        // degree of each vertex\n        vector<int> deg(n, 0);\n        for (int u = 0; u < n; ++u) {\n            int s = 0;\n            for (int v = 0; v < n; ++v) if (u != v) s += G[i][u][v];\n            deg[u] = s;\n        }\n\n        // order by decreasing degree, tie\u2011break by index\n        vector<int> idx(n);\n        iota(idx.begin(), idx.end(), 0);\n        sort(idx.begin(), idx.end(),\n             [&](int a, int b) {\n                 if (deg[a] != deg[b]) return deg[a] > deg[b];\n                 return a < b;\n             });\n        orderG[i] = idx;\n\n        // sorted degree sequence (decreasing)\n        vector<int> sd = deg;\n        sort(sd.begin(), sd.end(), greater<int>());\n        sortedDeg[i] = sd;\n\n        // count triangles\n        int t = 0;\n        for (int u = 0; u < n; ++u)\n            for (int v = u + 1; v < n; ++v) if (G[i][u][v])\n                for (int w = v + 1; w < n; ++w)\n                    if (G[i][u][w] && G[i][v][w]) ++t;\n        tri[i] = t;\n    }\n\n    /* -------------------------------------------------------------\n       output the graphs\n       ------------------------------------------------------------- */\n    cout << n << '\\n';\n    for (int i = 0; i < M; ++i) {\n        string line;\n        line.reserve(tot);\n        for (int u = 0; u < n; ++u)\n            for (int v = u + 1; v < n; ++v)\n                line.push_back(G[i][u][v] ? '1' : '0');\n        cout << line << '\\n';\n    }\n    cout.flush();\n\n    /* -------------------------------------------------------------\n       pre\u2011compute all permutations (only needed for noiseless case)\n       ------------------------------------------------------------- */\n    vector<vector<int>> perms;\n    if (noiseless) {\n        vector<int> p(n);\n        iota(p.begin(), p.end(), 0);\n        do {\n            perms.push_back(p);\n        } while (next_permutation(p.begin(), p.end()));\n    }\n\n    /* -------------------------------------------------------------\n       answer the 100 queries\n       ------------------------------------------------------------- */\n    for (int q = 0; q < 100; ++q) {\n        string Hstr;\n        cin >> Hstr;\n\n        // adjacency of H (only needed for noiseless case)\n        vector<vector<char>> B(n, vector<char>(n, 0));\n        vector<int> degH(n, 0);\n        int pos = 0;\n        for (int u = 0; u < n; ++u) {\n            for (int v = u + 1; v < n; ++v) {\n                char c = (char)(Hstr[pos++] - '0');\n                B[u][v] = B[v][u] = c;\n                if (c) {\n                    ++degH[u];\n                    ++degH[v];\n                }\n            }\n        }\n\n        int answer = 0;\n\n        if (noiseless) {\n            // exact isomorphism test (N \u2264 5 \u2192 at most 120 permutations)\n            bool found = false;\n            for (int i = 0; i < M && !found; ++i) {\n                for (const auto &perm : perms) {\n                    bool ok = true;\n                    for (int u = 0; u < n && ok; ++u) {\n                        int pu = perm[u];\n                        for (int v = u + 1; v < n; ++v) {\n                            int pv = perm[v];\n                            if (G[i][u][v] != B[pu][pv]) {\n                                ok = false;\n                                break;\n                            }\n                        }\n                    }\n                    if (ok) {\n                        answer = i;\n                        found = true;\n                        break;\n                    }\n                }\n            }\n        } else {\n            // ----- permutation\u2011invariant features -----\n            // sorted degree sequence of H\n            vector<int> sdH = degH;\n            sort(sdH.begin(), sdH.end(), greater<int>());\n\n            // triangle count of H\n            int triH = 0;\n            for (int u = 0; u < n; ++u)\n                for (int v = u + 1; v < n; ++v) if (B[u][v])\n                    for (int w = v + 1; w < n; ++w)\n                        if (B[u][w] && B[v][w]) ++triH;\n\n            // distance to every code word\n            int bestDist = INT_MAX;\n            for (int i = 0; i < M; ++i) {\n                // L1 distance of sorted degree sequences\n                int d = 0;\n                for (int k = 0; k < n; ++k) {\n                    d += abs(sortedDeg[i][k] - sdH[k]);\n                    if (d >= bestDist) break;\n                }\n                // add triangle difference (weighted by n to make it comparable)\n                d += n * abs(tri[i] - triH);\n                if (d < bestDist) {\n                    bestDist = d;\n                    answer = i;\n                }\n            }\n        }\n\n        cout << answer << '\\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    long long w;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n\n    vector<Edge> edges(M);\n    vector<vector<pair<int,int>>> adj(N);          // (to , edge id)\n    for (int i = 0; i < M; ++i) {\n        int a, b;\n        long long w;\n        cin >> a >> b >> w;\n        --a; --b;\n        edges[i] = {a, b, w};\n        adj[a].push_back({b, i});\n        adj[b].push_back({a, i});\n    }\n    // read the coordinates, they are not needed\n    for (int i = 0; i < N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        (void)x; (void)y;\n    }\n\n    const long long INF = (1LL << 60);\n\n    /* ----------------------------------------------------------\n       1.  Edge betweenness centrality (Brandes, weighted)\n       ---------------------------------------------------------- */\n    vector<double> ebc(M, 0.0);\n    vector<long long> dist(N);\n    vector<double> sigma(N), delta(N);\n    vector<vector<pair<int,int>>> pred(N);\n    vector<int> order(N);\n\n    for (int s = 0; s < N; ++s) {\n        fill(dist.begin(), dist.end(), INF);\n        fill(sigma.begin(), sigma.end(), 0.0);\n        for (int i = 0; i < N; ++i) pred[i].clear();\n\n        priority_queue<pair<long long,int>, vector<pair<long long,int>>, greater<pair<long long,int>>> pq;\n        dist[s] = 0;\n        sigma[s] = 1.0;\n        pq.emplace(0, s);\n\n        while (!pq.empty()) {\n            auto [d, v] = pq.top(); pq.pop();\n            if (d != dist[v]) continue;\n            for (auto [to, eid] : adj[v]) {\n                long long nd = d + edges[eid].w;\n                if (dist[to] > nd) {\n                    dist[to] = nd;\n                    sigma[to] = sigma[v];\n                    pred[to].clear();\n                    pred[to].emplace_back(v, eid);\n                    pq.emplace(nd, to);\n                } else if (dist[to] == nd) {\n                    sigma[to] += sigma[v];\n                    pred[to].emplace_back(v, eid);\n                }\n            }\n        }\n\n        // vertices in decreasing order of distance\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(),\n             [&](int a, int b){ return dist[a] > dist[b]; });\n\n        fill(delta.begin(), delta.end(), 0.0);\n\n        for (int v : order) {\n            if (dist[v] == INF) continue;\n            for (auto [u, eid] : pred[v]) {\n                double coeff = sigma[u] / sigma[v];\n                double contrib = coeff * (1.0 + delta[v]);\n                ebc[eid] += contrib;\n                delta[u] += contrib;\n            }\n        }\n    }\n\n    for (int i = 0; i < M; ++i) ebc[i] *= 0.5;          // undirected\n\n    /* ----------------------------------------------------------\n       2.  Score of an edge (here only betweenness)\n       ---------------------------------------------------------- */\n    vector<double> score(M);\n    for (int i = 0; i < M; ++i) score[i] = ebc[i];      // * edges[i].w possible\n\n    /* ----------------------------------------------------------\n       3.  Greedy LPT assignment, several random restarts\n       ---------------------------------------------------------- */\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    vector<int> best_assign(M);\n    double best_obj = 1e100;\n    vector<int> order_edges(M);\n    iota(order_edges.begin(), order_edges.end(), 0);\n\n    int restarts = 5;                     // enough, can be increased if time permits\n    for (int rep = 0; rep < restarts; ++rep) {\n        shuffle(order_edges.begin(), order_edges.end(), rng);\n        vector<int> assign(M, -1);\n        vector<double> day_sum(D, 0.0);\n        vector<int> day_cnt(D, 0);\n\n        for (int eid : order_edges) {\n            // choose a day with free capacity and minimal current sum\n            int best_day = -1;\n            double best_val = 1e200;\n            for (int d = 0; d < D; ++d) {\n                if (day_cnt[d] >= K) continue;\n                if (day_sum[d] < best_val) {\n                    best_val = day_sum[d];\n                    best_day = d;\n                }\n            }\n            // it is guaranteed that such a day exists\n            assign[eid] = best_day;\n            day_sum[best_day] += score[eid];\n            day_cnt[best_day]++;\n        }\n\n        double obj = 0.0;\n        for (int d = 0; d < D; ++d) obj += day_sum[d] * day_sum[d];\n        if (obj < best_obj) {\n            best_obj = obj;\n            best_assign = assign;\n        }\n    }\n\n    /* ----------------------------------------------------------\n       4.  Simple hill climbing (improves the surrogate)\n       ---------------------------------------------------------- */\n    vector<int> assign = best_assign;\n    vector<double> day_sum(D, 0.0);\n    vector<int> day_cnt(D, 0);\n    for (int e = 0; e < M; ++e) {\n        int d = assign[e];\n        day_sum[d] += score[e];\n        day_cnt[d]++;\n    }\n\n    uniform_int_distribution<int> edge_dist(0, M - 1);\n    uniform_int_distribution<int> day_dist(0, D - 1);\n    const int HILL_ITER = 20000;          // works well, can be tuned\n    for (int it = 0; it < HILL_ITER; ++it) {\n        int e = edge_dist(rng);\n        int cur = assign[e];\n        if (day_cnt[cur] == 0) continue; // should never happen\n\n        // look for a different day with free capacity\n        int nd = day_dist(rng);\n        if (nd == cur || day_cnt[nd] >= K) continue;\n\n        double cur_sum = day_sum[cur];\n        double new_sum = day_sum[nd];\n        double old_contrib = cur_sum * cur_sum + new_sum * new_sum;\n        double new_contrib = (cur_sum - score[e]) * (cur_sum - score[e]) +\n                             (new_sum + score[e]) * (new_sum + score[e]);\n        if (new_contrib < old_contrib - 1e-12) {\n            // accept move\n            assign[e] = nd;\n            day_sum[cur] -= score[e];\n            day_sum[nd] += score[e];\n            day_cnt[cur]--;\n            day_cnt[nd]++;\n        }\n    }\n\n    /* ----------------------------------------------------------\n       5.  Output\n       ---------------------------------------------------------- */\n    for (int i = 0; i < M; ++i) {\n        if (i) cout << ' ';\n        cout << assign[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    \n    int D;\n    if (!(cin >> D)) return 0;\n\n    // read silhouettes in the correct order\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    // assign to arrays f[2] and r[2]\n    vector<string> f[2], r[2];\n    f[0] = f1; r[0] = r1;\n    f[1] = f2; r[1] = r2;\n\n    // data for both objects\n    vector<vector<int>> X[2], Y[2];\n    vector<vector<pair<int,int>>> intX[2], intY[2];\n    for (int i = 0; i < 2; ++i) {\n        X[i].assign(D, {});\n        Y[i].assign(D, {});\n        intX[i].assign(D, {});\n        intY[i].assign(D, {});\n        for (int z = 0; z < D; ++z) {\n            for (int x = 0; x < D; ++x)\n                if (f[i][z][x] == '1') X[i][z].push_back(x);\n            for (int y = 0; y < D; ++y)\n                if (r[i][z][y] == '1') Y[i][z].push_back(y);\n            // intervals of 1s in f\n            const string &sf = f[i][z];\n            for (int x = 0; x < D; ) {\n                if (sf[x] == '0') { ++x; continue; }\n                int s = x;\n                while (x < D && sf[x] == '1') ++x;\n                int e = x - 1;\n                intX[i][z].push_back({s, e});\n            }\n            // intervals of 1s in r\n            const string &sr = r[i][z];\n            for (int y = 0; y < D; ) {\n                if (sr[y] == '0') { ++y; continue; }\n                int s = y;\n                while (y < D && sr[y] == '1') ++y;\n                int e = y - 1;\n                intY[i][z].push_back({s, e});\n            }\n        }\n    }\n\n    // count bars for each orientation\n    vector<int> cntV[2], cntH[2];\n    cntV[0].assign(D+1, 0); cntV[1].assign(D+1, 0);\n    cntH[0].assign(D+1, 0); cntH[1].assign(D+1, 0);\n    for (int i = 0; i < 2; ++i) {\n        for (int z = 0; z < D; ++z) {\n            // vertical bars (use Y intervals)\n            for (auto &pr : intY[i][z]) {\n                int len = pr.second - pr.first + 1;\n                cntV[i][len] += (int)X[i][z].size();\n            }\n            // horizontal bars (use X intervals)\n            for (auto &pr : intX[i][z]) {\n                int len = pr.second - pr.first + 1;\n                cntH[i][len] += (int)Y[i][z].size();\n            }\n        }\n    }\n\n    // choose the best orientation (both objects must use the same)\n    double bestScore = 1e100;\n    int bestO = -1; // 0 = vertical, 1 = horizontal\n    for (int o = 0; o < 2; ++o) {\n        const vector<int> &a = (o ? cntH[0] : cntV[0]);\n        const vector<int> &b = (o ? cntH[1] : cntV[1]);\n        double score = 0.0;\n        for (int L = 1; L <= D; ++L) {\n            int s = min(a[L], b[L]);\n            int diff = abs(a[L] - b[L]);\n            score += diff * L + (double)s / L;\n        }\n        if (score < bestScore) {\n            bestScore = score;\n            bestO = o;\n        }\n    }\n\n    // final counts according to the chosen orientation\n    vector<int> aCnt = (bestO ? cntH[0] : cntV[0]);\n    vector<int> bCnt = (bestO ? cntH[1] : cntV[1]);\n\n    // create block IDs\n    vector<vector<int>> sharedId(D+1), only1Id(D+1), only2Id(D+1);\n    int totalBlocks = 0;\n    for (int L = 1; L <= D; ++L) {\n        int s = min(aCnt[L], bCnt[L]);\n        for (int k = 0; k < s; ++k) sharedId[L].push_back(++totalBlocks);\n        for (int k = 0; k < aCnt[L] - s; ++k) only1Id[L].push_back(++totalBlocks);\n        for (int k = 0; k < bCnt[L] - s; ++k) only2Id[L].push_back(++totalBlocks);\n    }\n\n    // 3D output arrays (flat)\n    vector<int> b1(D*D*D, 0), b2(D*D*D, 0);\n    auto index = [&](int x, int y, int z) { return x*D*D + y*D + z; };\n\n    // ----- place object 1 -----\n    vector<int> ptrS(D+1, 0), ptr1(D+1, 0);\n    if (bestO == 0) { // vertical\n        for (int z = 0; z < D; ++z) {\n            for (auto &pr : intY[0][z]) {\n                int len = pr.second - pr.first + 1;\n                int y1 = pr.first, y2 = pr.second;\n                for (int x : X[0][z]) {\n                    int id;\n                    if (ptrS[len] < (int)sharedId[len].size())\n                        id = sharedId[len][ptrS[len]++];\n                    else\n                        id = only1Id[len][ptr1[len]++];\n                    for (int y = y1; y <= y2; ++y)\n                        b1[index(x, y, z)] = id;\n                }\n            }\n        }\n    } else { // horizontal\n        for (int z = 0; z < D; ++z) {\n            for (auto &pr : intX[0][z]) {\n                int len = pr.second - pr.first + 1;\n                int x1 = pr.first, x2 = pr.second;\n                for (int y : Y[0][z]) {\n                    int id;\n                    if (ptrS[len] < (int)sharedId[len].size())\n                        id = sharedId[len][ptrS[len]++];\n                    else\n                        id = only1Id[len][ptr1[len]++];\n                    for (int x = x1; x <= x2; ++x)\n                        b1[index(x, y, z)] = id;\n                }\n            }\n        }\n    }\n\n    // ----- place object 2 (same orientation as object 1) -----\n    vector<int> ptrS2(D+1, 0), ptr2(D+1, 0);\n    if (bestO == 0) { // vertical\n        for (int z = 0; z < D; ++z) {\n            for (auto &pr : intY[1][z]) {\n                int len = pr.second - pr.first + 1;\n                int y1 = pr.first, y2 = pr.second;\n                for (int x : X[1][z]) {\n                    int id;\n                    if (ptrS2[len] < (int)sharedId[len].size())\n                        id = sharedId[len][ptrS2[len]++];\n                    else\n                        id = only2Id[len][ptr2[len]++];\n                    for (int y = y1; y <= y2; ++y)\n                        b2[index(x, y, z)] = id;\n                }\n            }\n        }\n    } else { // horizontal\n        for (int z = 0; z < D; ++z) {\n            for (auto &pr : intX[1][z]) {\n                int len = pr.second - pr.first + 1;\n                int x1 = pr.first, x2 = pr.second;\n                for (int y : Y[1][z]) {\n                    int id;\n                    if (ptrS2[len] < (int)sharedId[len].size())\n                        id = sharedId[len][ptrS2[len]++];\n                    else\n                        id = only2Id[len][ptr2[len]++];\n                    for (int x = x1; x <= x2; ++x)\n                        b2[index(x, y, z)] = id;\n                }\n            }\n        }\n    }\n\n    // ----- output -----\n    cout << totalBlocks << '\\n';\n    for (int i = 0; i < D*D*D; ++i) {\n        if (i) cout << ' ';\n        cout << b1[i];\n    }\n    cout << '\\n';\n    for (int i = 0; i < D*D*D; ++i) {\n        if (i) cout << ' ';\n        cout << b2[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {int u, v, w;};\n\nint find(vector<int>& parent, int x) {\n    while (parent[x] != x) {\n        parent[x] = parent[parent[x]];\n        x = parent[x];\n    }\n    return x;\n}\n\nbool unite(vector<int>& parent, vector<int>& rankv, int x, int y) {\n    x = find(parent, x);\n    y = find(parent, y);\n    if (x == y) return false;\n    if (rankv[x] < rankv[y]) swap(x, y);\n    parent[y] = x;\n    if (rankv[x] == rankv[y]) rankv[x]++;\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n    \n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; ++i) cin >> x[i] >> y[i];\n    \n    vector<Edge> edges(M);\n    for (int j = 0; j < M; ++j) {\n        cin >> edges[j].u >> edges[j].v >> edges[j].w;\n        edges[j].u--;\n        edges[j].v--;\n    }\n    \n    vector<int> a(K), b(K);\n    for (int i = 0; i < K; ++i) cin >> a[i] >> b[i];\n    \n    // Build MST (Kruskal)\n    vector<int> parent(N), rankv(N, 0);\n    for (int i = 0; i < N; ++i) parent[i] = i;\n    \n    vector<int> order(M);\n    for (int i = 0; i < M; ++i) order[i] = i;\n    sort(order.begin(), order.end(), [&](int i, int j) { return edges[i].w < edges[j].w; });\n    \n    vector<int> tree_edges;\n    tree_edges.reserve(N - 1);\n    for (int idx : order) {\n        if (unite(parent, rankv, edges[idx].u, edges[idx].v)) {\n            tree_edges.push_back(idx);\n            if ((int)tree_edges.size() == N - 1) break;\n        }\n    }\n    \n    // Mark included vertices (use vector<int> instead of vector<bool>)\n    vector<int> in_tree(N, 0);\n    in_tree[0] = 1;\n    for (int idx : tree_edges) {\n        in_tree[edges[idx].u] = 1;\n        in_tree[edges[idx].v] = 1;\n    }\n    \n    // Greedy assignment with cost minimization\n    vector<int> P(N, 0);\n    vector<double> station_radius(N, 0.0);\n    \n    for (int k = 0; k < K; ++k) {\n        long long best_cost_incr = (1LL << 60);\n        int best_station = -1;\n        double best_dist = 0.0;\n        \n        for (int i = 0; i < N; ++i) {\n            if (!in_tree[i]) continue;\n            \n            long long dx = (long long)a[k] - x[i];\n            long long dy = (long long)b[k] - y[i];\n            double dist = sqrt((double)(dx * dx + dy * dy));\n            \n            double new_radius = max(station_radius[i], dist);\n            long long old_cost = (long long)ceil(station_radius[i]) * (long long)ceil(station_radius[i]);\n            long long new_cost = (long long)ceil(new_radius) * (long long)ceil(new_radius);\n            long long cost_incr = new_cost - old_cost;\n            \n            if (cost_incr < best_cost_incr) {\n                best_cost_incr = cost_incr;\n                best_station = i;\n                best_dist = dist;\n            }\n        }\n        \n        if (best_station != -1) {\n            station_radius[best_station] = max(station_radius[best_station], best_dist);\n        }\n    }\n    \n    // Convert to P_i values\n    for (int i = 0; i < N; ++i) {\n        if (station_radius[i] > 0.0) {\n            P[i] = min(5000, (int)ceil(station_radius[i]));\n        }\n    }\n    \n    // Output\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << \" \";\n        cout << P[i];\n    }\n    cout << \"\\n\";\n    \n    vector<int> B(M, 0);\n    for (int idx : tree_edges) B[idx] = 1;\n    for (int j = 0; j < M; ++j) {\n        if (j) cout << \" \";\n        cout << B[j];\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 30;\nusing Grid = array<array<int, N>, N>;\n\nstruct Swap {\n    int x1, y1, x2, y2;\n};\n\nvoid siftDown(Grid &g, vector<Swap> &out, int row, const vector<int> &order) {\n    for (int y : order) {\n        int curX = row, curY = y;\n        while (curX < N - 1) {\n            int leftX = curX + 1, leftY = curY;\n            int rightX = curX + 1, rightY = curY + 1;\n            int childX, childY;\n            if (g[leftX][leftY] < g[rightX][rightY]) {\n                childX = leftX; childY = leftY;\n            } else {\n                childX = rightX; childY = rightY;\n            }\n            if (g[childX][childY] < g[curX][curY]) {\n                swap(g[curX][curY], g[childX][childY]);\n                out.push_back({curX, curY, childX, childY});\n                curX = childX; curY = childY;\n            } else break;\n        }\n    }\n}\n\nint countViolations(const Grid &g) {\n    int bad = 0;\n    for (int x = 0; x < N - 1; ++x)\n        for (int y = 0; y <= x; ++y) {\n            int v = g[x][y];\n            if (v > g[x + 1][y]) ++bad;\n            if (v > g[x + 1][y + 1]) ++bad;\n        }\n    return bad;\n}\n\nvoid runWithOrders(const Grid &init, Grid &cur, vector<Swap> &out,\n                   const vector<vector<int>> &orderRows) {\n    cur = init; out.clear();\n    for (int x = N - 2; x >= 0; --x)\n        siftDown(cur, out, x, orderRows[x]);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    Grid orig{};\n    for (int x = 0; x < N; ++x)\n        for (int y = 0; y <= x; ++y)\n            cin >> orig[x][y];\n\n    vector<Swap> bestSwaps;\n    int bestK = 1'000'000;\n    Grid cur;\n    vector<Swap> curSwaps;\n\n    // left-to-right baseline\n    {\n        vector<vector<int>> orderRows(N);\n        for (int x = 0; x < N; ++x) {\n            orderRows[x].resize(x + 1);\n            iota(orderRows[x].begin(), orderRows[x].end(), 0);\n        }\n        runWithOrders(orig, cur, curSwaps, orderRows);\n        if (countViolations(cur) == 0 && (int)curSwaps.size() < bestK) {\n            bestK = (int)curSwaps.size();\n            bestSwaps = curSwaps;\n        }\n    }\n\n    // right-to-left\n    {\n        vector<vector<int>> orderRows(N);\n        for (int x = 0; x < N; ++x) {\n            orderRows[x].resize(x + 1);\n            for (int y = 0; y <= x; ++y) orderRows[x][y] = x - y;\n        }\n        runWithOrders(orig, cur, curSwaps, orderRows);\n        if (countViolations(cur) == 0 && (int)curSwaps.size() < bestK) {\n            bestK = (int)curSwaps.size();\n            bestSwaps = curSwaps;\n        }\n    }\n\n    // largest violation first\n    {\n        vector<vector<int>> orderRows(N);\n        for (int x = 0; x < N; ++x) orderRows[x].resize(x + 1);\n        cur = orig; curSwaps.clear();\n        for (int x = N - 2; x >= 0; --x) {\n            vector<pair<int,int>> diffY;\n            diffY.reserve(x + 1);\n            for (int y = 0; y <= x; ++y) {\n                int left = cur[x + 1][y];\n                int right = cur[x + 1][y + 1];\n                int mn = min(left, right);\n                int diff = cur[x][y] - mn;\n                diffY.emplace_back(diff, y);\n            }\n            sort(diffY.begin(), diffY.end(),\n                 [](const auto &a, const auto &b){ return a.first > b.first; });\n            orderRows[x].clear();\n            for (auto &p : diffY) orderRows[x].push_back(p.second);\n            siftDown(cur, curSwaps, x, orderRows[x]);\n        }\n        if (countViolations(cur) == 0 && (int)curSwaps.size() < bestK) {\n            bestK = (int)curSwaps.size();\n            bestSwaps = curSwaps;\n        }\n    }\n\n    // many random runs\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    for (int iter = 0; iter < 10000; ++iter) {\n        vector<vector<int>> orderRows(N);\n        for (int x = 0; x < N; ++x) {\n            orderRows[x].resize(x + 1);\n            iota(orderRows[x].begin(), orderRows[x].end(), 0);\n            if (x <= N - 2) shuffle(orderRows[x].begin(), orderRows[x].end(), rng);\n        }\n        runWithOrders(orig, cur, curSwaps, orderRows);\n        if (countViolations(cur) == 0 && (int)curSwaps.size() < bestK) {\n            bestK = (int)curSwaps.size();\n            bestSwaps = curSwaps;\n        }\n        if (bestK <= 2000) break;\n    }\n\n    // try to remove redundant swaps from the end\n    if (!bestSwaps.empty()) {\n        cur = orig;\n        for (const auto &s : bestSwaps) swap(cur[s.x1][s.y1], cur[s.x2][s.y2]);\n        for (int i = (int)bestSwaps.size() - 1; i >= max(0, (int)bestSwaps.size() - 100); --i) {\n            swap(cur[bestSwaps[i].x1][bestSwaps[i].y1], cur[bestSwaps[i].x2][bestSwaps[i].y2]);\n            if (countViolations(cur) == 0) {\n                bestSwaps.erase(bestSwaps.begin() + i);\n                bestK--;\n            } else {\n                swap(cur[bestSwaps[i].x1][bestSwaps[i].y1], cur[bestSwaps[i].x2][bestSwaps[i].y2]);\n            }\n        }\n    }\n\n    cout << bestK << '\\n';\n    for (const auto &s : bestSwaps)\n        cout << s.x1 << ' ' << s.y1 << ' ' << s.x2 << ' ' << s.y2 << '\\n';\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int SZ = 9;                     // board size, fixed by the statement\n\n/* global data */\nint M;                                 // number of containers\nvector<vector<bool>> obstacle;         // true for an obstacle\nvector<vector<bool>> occupied;         // true if a container is stored here\nvector<vector<int>> value;             // transport number, -1 if none\n\n/* auxiliary directions */\nconst int dr[4] = {1, -1, 0, 0};\nconst int dc[4] = {0, 0, 1, -1};\n\n/* --------------------------------------------------------------- */\n/* count empty neighbours of a cell (not obstacles, not occupied) */\nint count_empty_neighbors(int r, int c, const vector<vector<bool>>& occ){\n    int cnt = 0;\n    for (int d=0; d<4; ++d){\n        int nr = r + dr[d];\n        int nc = c + dc[d];\n        if (nr<0||nr>=SZ||nc<0||nc>=SZ) continue;\n        if (obstacle[nr][nc]) continue;\n        if (occ[nr][nc]) continue;\n        ++cnt;\n    }\n    return cnt;\n}\n\n/* --------------------------------------------------------------- */\n/* BFS from the entrance over empty squares.\n   fills reachable[][] , dist[][] and returns the number of reachable empty squares\n   (entrance is counted as empty).                                 */\nint bfs_reachable(vector<vector<bool>>& reachable,\n                  vector<vector<int>>& dist,\n                  const vector<vector<bool>>& occ)\n{\n    reachable.assign(SZ, vector<bool>(SZ, false));\n    dist.assign(SZ, vector<int>(SZ, -1));\n    queue<pair<int,int>> q;\n\n    int ent_r = 0, ent_c = (SZ-1)/2;\n    reachable[ent_r][ent_c] = true;\n    dist[ent_r][ent_c] = 0;\n    q.emplace(ent_r, ent_c);\n    int cnt = 1;                     // entrance itself\n\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];\n            int nc = c + dc[d];\n            if (nr<0||nr>=SZ||nc<0||nc>=SZ) continue;\n            if (obstacle[nr][nc]) continue;\n            if (occ[nr][nc]) continue;                 // not empty\n            if (!reachable[nr][nc]){\n                reachable[nr][nc] = true;\n                dist[nr][nc] = dist[r][c] + 1;\n                ++cnt;\n                q.emplace(nr,nc);\n            }\n        }\n    }\n    return cnt;          // total empty squares reachable (including entrance)\n}\n\n/* --------------------------------------------------------------- */\n/* test whether a reachable empty square (tr,tc) is a cut vertex\n   (i.e. after occupying it the remaining empty squares stay connected) */\nbool is_safe(int tr, int tc,\n             const vector<vector<bool>>& occ,\n             int total_empty)\n{\n    // a second BFS, this time treating (tr,tc) as blocked\n    vector<vector<bool>> reach2(SZ, vector<bool>(SZ,false));\n    queue<pair<int,int>> q;\n    int ent_r = 0, ent_c = (SZ-1)/2;\n    reach2[ent_r][ent_c] = true;\n    q.emplace(ent_r, ent_c);\n    int cnt = 1;\n\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];\n            int nc = c + dc[d];\n            if (nr<0||nr>=SZ||nc<0||nc>=SZ) continue;\n            if (obstacle[nr][nc]) continue;\n            if (occ[nr][nc]) continue;\n            if (nr==tr && nc==tc) continue;          // the blocked cell\n            if (!reach2[nr][nc]){\n                reach2[nr][nc] = true;\n                ++cnt;\n                q.emplace(nr,nc);\n            }\n        }\n    }\n    // after blocking (tr,tc) we must still reach all other empties\n    return cnt == total_empty - 1;\n}\n\n/* --------------------------------------------------------------- */\n/* pick a square for the next container \u2013 prefer leaves (degree\u202f1) */\npair<int,int> choose_square(const vector<vector<bool>>& occ)\n{\n    vector<vector<bool>> reachable;\n    vector<vector<int>> dist;\n    int total_empty = bfs_reachable(reachable, dist, occ);\n\n    vector<pair<int,int>> safe_list, leaf_list;\n\n    for (int r=0; r<SZ; ++r){\n        for (int c=0; c<SZ; ++c){\n            if (!reachable[r][c]) continue;               // not reachable\n            if (occ[r][c]) continue;                       // already occupied\n            if (r==0 && c==(SZ-1)/2) continue;              // entrance\n            // articulation test\n            if (!is_safe(r,c, occ, total_empty)) continue;\n            safe_list.emplace_back(r,c);\n            if (count_empty_neighbors(r,c, occ) == 1)\n                leaf_list.emplace_back(r,c);\n        }\n    }\n\n    const vector<pair<int,int>>& src = leaf_list.empty() ? safe_list : leaf_list;\n    int best_dist = -1;\n    pair<int,int> best{-1,-1};\n    for (auto [r,c] : src){\n        if (dist[r][c] > best_dist){\n            best_dist = dist[r][c];\n            best = {r,c};\n        } else if (dist[r][c]==best_dist && best.first!=-1){\n            if (r < best.first || (r==best.first && c < best.second))\n                best = {r,c};\n        }\n    }\n\n    // normally src is non\u2011empty \u2013 otherwise a fallback (should not happen)\n    if (!src.empty()) return best;\n    // ultimate fallback: any reachable cell\n    for (int r=0; r<SZ; ++r)\n        for (int c=0; c<SZ; ++c)\n            if (reachable[r][c] && !occ[r][c] && !(r==0 && c==(SZ-1)/2))\n                return {r,c};\n    return {-1,-1}; // never reached\n}\n\n/* --------------------------------------------------------------- */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D_input, N;\n    if(!(cin>>D_input>>N)) return 0;       // D_input is always 9, we ignore it\n    obstacle.assign(SZ, vector<bool>(SZ,false));\n    for (int i=0;i<N;++i){\n        int ri,rj; cin>>ri>>rj;\n        obstacle[ri][rj]=true;\n    }\n\n    occupied.assign(SZ, vector<bool>(SZ,false));\n    value.assign(SZ, vector<int>(SZ,-1));\n\n    M = SZ*SZ - 1 - N;\n\n    vector<pair<int,int>> container_position(M);   // by transport number\n\n    /* ---------- placement ---------- */\n    for (int step=0; step<M; ++step){\n        int t; cin>>t;\n        auto pos = choose_square(occupied);\n        int r = pos.first, c = pos.second;\n        // place the container\n        occupied[r][c] = true;\n        value[r][c] = t;\n        container_position[t] = {r,c};\n        cout << r << ' ' << c << '\\n';\n        cout.flush();\n    }\n\n    /* ---------- removal ---------- */\n    vector<pair<int,int>> removal_order;\n    removal_order.reserve(M);\n    int removed = 0;\n    while (removed < M){\n        vector<vector<bool>> reachableEmpty;\n        vector<vector<int>> dummy;\n        bfs_reachable(reachableEmpty, dummy, occupied);   // empty squares only\n\n        // collect removable containers\n        int best_val = INT_MAX;\n        int br=-1, bc=-1;\n        for (int r=0; r<SZ; ++r){\n            for (int c=0; c<SZ; ++c){\n                if (!occupied[r][c]) continue;               // no container here\n                // is it reachable ?   (any neighbour reachableEmpty)\n                bool ok = false;\n                for (int d=0; d<4; ++d){\n                    int nr = r+dr[d];\n                    int nc = c+dc[d];\n                    if (nr<0||nr>=SZ||nc<0||nc>=SZ) continue;\n                    if (reachableEmpty[nr][nc]) { ok=true; break; }\n                }\n                if (!ok) continue;\n                if (value[r][c] < best_val){\n                    best_val = value[r][c];\n                    br=r; bc=c;\n                }\n            }\n        }\n        // remove the chosen container\n        removal_order.emplace_back(br,bc);\n        occupied[br][bc] = false;\n        value[br][bc] = -1;\n        ++removed;\n    }\n\n    for (auto [r,c] : removal_order){\n        cout << r << ' ' << c << '\\n';\n    }\n    cout.flush();\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\n#include <array>\nusing namespace std;\n\nconst int N = 50;\nconst int M = 100;\n\nint n, m;\nint orig[N][N];\n\n/* --------------------------------------------------------------- */\n/*  adjacency of the original map (including colour 0)            */\nbool orig_adj[M + 1][M + 1];                 // symmetric, 0..m\nvector<array<int,6>> adj_pairs;               // c,d,i1,j1,i2,j2  (both >0)\n\n/* --------------------------------------------------------------- */\n/*  colour sets                                                   */\nvector<pair<int,int>> cells_of_color[M + 1];   // 1..m\nbool is_border_colour[M + 1];\nbool is_interior_colour[M + 1];\n\n/* --------------------------------------------------------------- */\n/*  required cells for each colour (see section 2)                */\nbool required_pos[N][N];\nvector<pair<int,int>> required[M + 1];\n\n/* --------------------------------------------------------------- */\n/*  cells that finally stay coloured                              */\nbool keep[N][N];\n\n/* --------------------------------------------------------------- */\n/*  utility: neighbour directions                                  */\nconst int dy[4] = { -1, 1, 0, 0 };\nconst int dx[4] = { 0, 0, -1, 1 };\n\n/* --------------------------------------------------------------- */\n/*  full validation of a produced map                            */\nbool validate(const int out[N][N])\n{\n    /* 1. each colour appears at least once and is connected       */\n    int cnt_colour[M+1];\n    fill(begin(cnt_colour), end(cnt_colour), 0);\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++) {\n        int c = out[i][j];\n        if (c<0 || c>m) return false;\n        ++cnt_colour[c];\n    }\n    for (int c=1;c<=m;c++) if (cnt_colour[c]==0) return false;\n\n    // BFS for each colour\n    bool visited[N][N];\n    for (int c=1;c<=m;c++) {\n        memset(visited,0,sizeof(visited));\n        // find first cell of this colour\n        int sx=-1,sy=-1;\n        for (int i=0;i<n && sx==-1;i++) for (int j=0;j<n;j++)\n            if (out[i][j]==c) { sx=i; sy=j; break; }\n        if (sx==-1) return false;               // should not happen\n        queue<pair<int,int>> q;\n        q.emplace(sx,sy);\n        visited[sx][sy]=true;\n        int reach=0;\n        while(!q.empty()){\n            auto [y,x]=q.front(); q.pop();\n            ++reach;\n            for (int dir=0;dir<4;dir++){\n                int ny=y+dy[dir], nx=x+dx[dir];\n                if (ny<0||ny>=n||nx<0||nx>=n) continue;\n                if (out[ny][nx]==c && !visited[ny][nx]){\n                    visited[ny][nx]=true;\n                    q.emplace(ny,nx);\n                }\n            }\n        }\n        if (reach!=cnt_colour[c]) return false;   // not connected\n    }\n\n    /* 2. zero cells are connected with the outside               */\n    memset(visited,0,sizeof(visited));\n    queue<pair<int,int>> qz;\n    // start from every border zero cell\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++) {\n        if (out[i][j]==0 &&\n            (i==0||i==n-1||j==0||j==n-1)){\n            visited[i][j]=true;\n            qz.emplace(i,j);\n        }\n    }\n    while(!qz.empty()){\n        auto [y,x]=qz.front(); qz.pop();\n        for (int dir=0;dir<4;dir++){\n            int ny=y+dy[dir], nx=x+dx[dir];\n            if (ny<0||ny>=n||nx<0||nx>=n) continue;\n            if (out[ny][nx]==0 && !visited[ny][nx]){\n                visited[ny][nx]=true;\n                qz.emplace(ny,nx);\n            }\n        }\n    }\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++)\n        if (out[i][j]==0 && !visited[i][j]) return false;   // isolated zero\n\n    /* 3. adjacency matrix exactly the original one                */\n    bool out_adj[M+1][M+1];\n    memset(out_adj,0,sizeof(out_adj));\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++) {\n        int c = out[i][j];\n        for (int dir=0;dir<4;dir++){\n            int ni=i+dy[dir], nj=j+dx[dir];\n            if (ni<0||ni>=n||nj<0||nj>=n){\n                // outside -> colour 0\n                out_adj[c][0]=out_adj[0][c]=true;\n                continue;\n            }\n            int d = out[ni][nj];\n            if (c!=d){\n                out_adj[c][d]=out_adj[d][c]=true;\n            }\n        }\n    }\n    for (int c=0;c<=m;c++) for (int d=c;d<=m;d++)\n        if (orig_adj[c][d]!=out_adj[c][d]) return false;\n\n    return true;\n}\n\n/* --------------------------------------------------------------- */\n/*  minimal neighbour set for interior colours                    */\nvoid compute_minimal_neighbours()\n{\n    // mark all cells that are neighbours of an interior colour\n    static bool neigh_of_interior[N][N];\n    memset(neigh_of_interior,0,sizeof(neigh_of_interior));\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++) {\n        if (is_interior_colour[orig[i][j]]){\n            for (int dir=0;dir<4;dir++){\n                int ni=i+dy[dir], nj=j+dx[dir];\n                if (ni<0||ni>=n||nj<0||nj>=n) continue;\n                neigh_of_interior[ni][nj]=true;\n            }\n        }\n    }\n\n    // process each interior colour independently\n    for (int col=1; col<=m; ++col) if (is_interior_colour[col]){\n        // list of interior cells of this colour\n        vector<pair<int,int>> interior_cells;\n        for (auto &p : cells_of_color[col])\n            interior_cells.push_back(p);\n        // list of candidate neighbour cells (belong to border colours)\n        vector<pair<int,int>> candidates;\n        for (auto &p : interior_cells){\n            int y=p.first, x=p.second;\n            for (int dir=0;dir<4;dir++){\n                int ny=y+dy[dir], nx=x+dx[dir];\n                if (ny<0||ny>=n||nx<0||nx>=n) continue;\n                if (orig[ny][nx]==col) continue;   // same colour\n                if (!required_pos[ny][nx])   // not already forced\n                    candidates.emplace_back(ny,nx);\n            }\n        }\n\n        // each (interior_cell, direction) is an element that must be covered\n        struct Need {\n            int y, x, dir;\n        };\n        vector<Need> needs;\n        for (auto &p : interior_cells){\n            int y=p.first, x=p.second;\n            for (int d=0; d<4; ++d)\n                needs.push_back({y,x,d});\n        }\n\n        // which neighbour cell covers which needs\n        vector<vector<int>> cover(candidates.size());\n        for (size_t i=0; i<candidates.size(); ++i){\n            int cy=candidates[i].first, cx=candidates[i].second;\n            for (size_t j=0; j<needs.size(); ++j){\n                int y=needs[j].y, x=needs[j].x, d=needs[j].dir;\n                int ny=y+dy[d], nx=x+dx[d];\n                if (ny==cy && nx==cx){\n                    cover[i].push_back(j);\n                }\n            }\n        }\n\n        // greedy set cover\n        vector<bool> covered(needs.size(), false);\n        bool progress=true;\n        while (progress){\n            progress=false;\n            int best=-1, bestCnt=0;\n            for (size_t i=0; i<candidates.size(); ++i){\n                int cnt=0;\n                for (int needIdx : cover[i])\n                    if (!covered[needIdx]) ++cnt;\n                if (cnt>bestCnt){\n                    bestCnt=cnt;\n                    best=i;\n                }\n            }\n            if (best!=-1){\n                int y=candidates[best].first, x=candidates[best].second;\n                required_pos[y][x]=true;\n                required[orig[y][x]].push_back({y,x});\n                for (int needIdx : cover[best]) covered[needIdx]=true;\n                progress=true;\n            }\n        }\n    }\n}\n\n/* --------------------------------------------------------------- */\n/*  Steiner tree for a border colour (MST on required nodes)       */\nvoid connect_border_colour_steiner(int col)\n{\n    // region = all cells of this colour in the original map\n    static bool inRegion[N][N];\n    for (auto &p : cells_of_color[col]) inRegion[p.first][p.second]=true;\n\n    // required cells of this colour\n    vector<pair<int,int>> req = required[col];\n    int k = req.size();\n    if (k<=1) { /* already connected */ for (auto &p : cells_of_color[col]) inRegion[p.first][p.second]=false; return; }\n\n    auto idx = [&](int y,int x){ return y*N + x; };\n    vector<int> srcIdx;\n    for (auto &p : req) srcIdx.push_back(idx(p.first, p.second));\n\n    // BFS from each required node, store distance and predecessor\n    vector<vector<int>> dist(k, vector<int>(N*N, -1));\n    vector<vector<int>> prv (k, vector<int>(N*N, -1));\n\n    for (int i=0;i<k;i++){\n        queue<int> q;\n        int start = srcIdx[i];\n        q.push(start);\n        dist[i][start]=0;\n        prv[i][start]=start;\n        while(!q.empty()){\n            int cur=q.front(); q.pop();\n            int cy=cur/N, cx=cur%N;\n            for (int dir=0;dir<4;dir++){\n                int ny=cy+dy[dir], nx=cx+dx[dir];\n                if (ny<0||ny>=n||nx<0||nx>=n) continue;\n                if (!inRegion[ny][nx]) continue;\n                int nid=idx(ny,nx);\n                if (dist[i][nid]==-1){\n                    dist[i][nid]=dist[i][cur]+1;\n                    prv[i][nid]=cur;\n                    q.push(nid);\n                }\n            }\n        }\n    }\n\n    // Build complete graph on required nodes (distances)\n    vector<vector<int>> d(k, vector<int>(k,0));\n    for (int i=0;i<k;i++)\n        for (int j=i+1;j<k;j++)\n            d[i][j]=d[j][i]=dist[i][srcIdx[j]];\n\n    // Prim's algorithm for MST\n    vector<bool> inMST(k,false);\n    vector<int> minDist(k, INT_MAX);\n    vector<int> parent(k,-1);\n    minDist[0]=0;\n    for (int i=0;i<k;i++){\n        int v=-1;\n        for (int j=0;j<k;j++) if (!inMST[j] && (v==-1 || minDist[j] < minDist[v])) v=j;\n        inMST[v]=true;\n        if (parent[v]!=-1){\n            int a=v, b=parent[v];\n            // add shortest path between a and b using predecessor of a\n            int cur = srcIdx[b];\n            while (cur != srcIdx[a]){\n                int y = cur/N, x = cur%N;\n                keep[y][x]=true;\n                cur = prv[a][cur];\n            }\n            // also mark the two endpoints themselves (they are already required)\n            keep[req[a].first][req[a].second]=true;\n            keep[req[b].first][req[b].second]=true;\n        }\n        for (int j=0;j<k;j++){\n            if (!inMST[j] && d[v][j] < minDist[j]){\n                minDist[j]=d[v][j];\n                parent[j]=v;\n            }\n        }\n    }\n\n    // clean up\n    for (auto &p : cells_of_color[col]) inRegion[p.first][p.second]=false;\n}\n\n/* --------------------------------------------------------------- */\n/*  leaf pruning for border colours \u2013 delete non\u2011required leaves  */\nvoid leaf_prune(int out_grid[N][N])\n{\n    bool changed=true;\n    while (changed){\n        changed=false;\n        for (int c=1;c<=m;c++) if (is_border_colour[c]){\n            for (auto &p : cells_of_color[c]){\n                int y=p.first, x=p.second;\n                if (!keep[y][x] || required_pos[y][x]) continue;\n                // count kept neighbours of the same colour\n                int cnt=0;\n                for (int dir=0;dir<4;dir++){\n                    int ny=y+dy[dir], nx=x+dx[dir];\n                    if (ny<0||ny>=n||nx<0||nx>=n) continue;\n                    if (keep[ny][nx] && orig[ny][nx]==c) ++cnt;\n                }\n                if (cnt<=1){   // leaf\n                    int oldc = orig[y][x];\n                    out_grid[y][x]=0;\n                    keep[y][x]=false;\n                    if (validate(out_grid)){\n                        changed=true;\n                    } else {\n                        out_grid[y][x]=oldc;\n                        keep[y][x]=true;\n                    }\n                }\n            }\n        }\n    }\n}\n\n/* --------------------------------------------------------------- */\n/*  greedy deletion of non\u2011required cells                         */\nvoid greedy_deletion(int out_grid[N][N])\n{\n    mt19937 rng(123456);\n    bool changed=true;\n    int passes=0;\n    while (changed && passes<8){\n        changed=false;\n        vector<pair<int,int>> cand;\n        for (int i=0;i<n;i++) for (int j=0;j<n;j++)\n            if (keep[i][j] && !required_pos[i][j])\n                cand.emplace_back(i,j);\n        shuffle(cand.begin(), cand.end(), rng);\n        for (auto [y,x] : cand){\n            int oldcol = orig[y][x];\n            // try delete\n            out_grid[y][x]=0;\n            keep[y][x]=false;\n            if (validate(out_grid)){\n                changed=true;\n            } else {\n                // revert\n                out_grid[y][x]=oldcol;\n                keep[y][x]=true;\n            }\n        }\n        ++passes;\n    }\n}\n\n/* --------------------------------------------------------------- */\n/*  repair isolated zero pools                                   */\nvoid repair_isolated_zeros(int out_grid[N][N])\n{\n    bool visited[N][N];\n    memset(visited,0,sizeof(visited));\n    queue<pair<int,int>> q;\n    // start from border zeros\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++){\n        if (out_grid[i][j]==0 && (i==0||i==n-1||j==0||j==n-1)){\n            visited[i][j]=true;\n            q.emplace(i,j);\n        }\n    }\n    while(!q.empty()){\n        auto [y,x]=q.front(); q.pop();\n        for (int dir=0;dir<4;dir++){\n            int ny=y+dy[dir], nx=x+dx[dir];\n            if (ny<0||ny>=n||nx<0||nx>=n) continue;\n            if (out_grid[ny][nx]==0 && !visited[ny][nx]){\n                visited[ny][nx]=true;\n                q.emplace(ny,nx);\n            }\n        }\n    }\n    // revert isolated zeros\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++){\n        if (out_grid[i][j]==0 && !visited[i][j]){\n            out_grid[i][j]=orig[i][j];\n            keep[i][j]=true;          // not used any more, but keep consistent\n        }\n    }\n}\n\n/* --------------------------------------------------------------- */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if(!(cin>>n>>m)) return 0;\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++){\n        cin>>orig[i][j];\n        cells_of_color[orig[i][j]].push_back({i,j});\n        if (i==0||i==n-1||j==0||j==n-1) is_border_colour[orig[i][j]]=true;\n    }\n\n    /* ---- original adjacency ------------------------------------ */\n    memset(orig_adj,0,sizeof(orig_adj));\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++){\n        int c = orig[i][j];\n        for (int dir=0;dir<4;dir++){\n            int ni=i+dy[dir], nj=j+dx[dir];\n            if (ni<0||ni>=n||nj<0||nj>=n){\n                // outside -> colour 0\n                orig_adj[c][0]=orig_adj[0][c]=true;\n                continue;\n            }\n            int d = orig[ni][nj];\n            if (c!=d){\n                orig_adj[c][d]=orig_adj[d][c]=true;\n                // store pair (c,d) together with both cell positions\n                if (c<d)\n                    adj_pairs.push_back({{c,d,i,j,ni,nj}});\n                else\n                    adj_pairs.push_back({{d,c,ni,nj,i,j}});\n            }\n        }\n    }\n\n    /* ---- interior / border colours ----------------------------- */\n    for (int c=1;c<=m;c++) is_interior_colour[c]=!is_border_colour[c];\n\n    /* ---- minimal neighbour set for interior colours ------------ */\n    compute_minimal_neighbours();\n\n    /* ---- must_keep matrix (cells that may not become zero) ------ */\n    bool must_keep[N][N];\n    memset(must_keep,0,sizeof(must_keep));\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++) {\n        if (is_interior_colour[orig[i][j]]){\n            must_keep[i][j]=true;\n            for (int dir=0;dir<4;dir++){\n                int ni=i+dy[dir], nj=j+dx[dir];\n                if (ni<0||ni>=n||nj<0||nj>=n) continue;\n                must_keep[ni][nj]=true;\n            }\n        }\n    }\n\n    /* ---- required cells for border colours (border cell) -------- */\n    for (int c=1;c<=m;c++) if (is_border_colour[c]){\n        // if no required cell on the border exists yet, add one\n        for (auto &p : cells_of_color[c]){\n            int y=p.first, x=p.second;\n            if (y==0||y==n-1||x==0||x==n-1){\n                required_pos[y][x]=true;\n                required[c].push_back({y,x});\n                break;\n            }\n        }\n    }\n\n    /* ---- smarter border\u2011border edge handling -------------------- */\n    bool edge_used[M+1][M+1];\n    memset(edge_used,0,sizeof(edge_used));\n    // first try to reuse already kept cells\n    for (int c=1;c<=m;c++) if (is_border_colour[c])\n        for (int d=c+1;d<=m;d++) if (is_border_colour[d] && !edge_used[c][d]){\n            bool found=false;\n            for (auto &e : adj_pairs){\n                int a=e[0], b=e[1];\n                if (!((a==c && b==d) || (a==d && b==c))) continue;\n                int y1=e[2], x1=e[3], y2=e[4], x2=e[5];\n                if (must_keep[y1][x1] || must_keep[y2][x2] ||\n                    required_pos[y1][x1] || required_pos[y2][x2]){\n                    required_pos[y1][x1]=required_pos[y2][x2]=true;\n                    required[c].push_back({y1,x1});\n                    required[d].push_back({y2,x2});\n                    edge_used[c][d]=true;\n                    found=true;\n                    break;\n                }\n            }\n            if (found) continue;\n            // otherwise take the first pair\n            for (auto &e : adj_pairs){\n                int a=e[0], b=e[1];\n                if (!((a==c && b==d) || (a==d && b==c))) continue;\n                int y1=e[2], x1=e[3], y2=e[4], x2=e[5];\n                if (!required_pos[y1][x1]){\n                    required_pos[y1][x1]=true;\n                    required[c].push_back({y1,x1});\n                }\n                if (!required_pos[y2][x2]){\n                    required_pos[y2][x2]=true;\n                    required[d].push_back({y2,x2});\n                }\n                edge_used[c][d]=true;\n                break;\n            }\n        }\n\n    /* ---- build first keep set ---------------------------------- */\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++) keep[i][j]=must_keep[i][j];\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++)\n        if (required_pos[i][j]) keep[i][j]=true;\n\n    /* ---- Steiner connection for border colours ----------------- */\n    for (int c=1;c<=m;c++) if (is_border_colour[c])\n        connect_border_colour_steiner(c);\n\n    /* ---- initial map ------------------------------------------- */\n    int out_grid[N][N];\n    for (int i=0;i<n;i++) for (int j=0;j<n;j++)\n        out_grid[i][j] = keep[i][j] ? orig[i][j] : 0;\n\n    clock_t start = clock();\n\n    /* ---- iterated refinement ----------------------------------- */\n    do {\n        greedy_deletion(out_grid);\n        leaf_prune(out_grid);\n        repair_isolated_zeros(out_grid);\n    } while (clock() - start < 1.8 * CLOCKS_PER_SEC);\n\n    /* ---- final output ------------------------------------------ */\n    for (int i=0;i<n;i++){\n        for (int j=0;j<n;j++){\n            if (j) cout << ' ';\n            cout << out_grid[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    // comparison_matrix[i][j]: 1 if i > j, -1 if i < j, 0 if unknown, 2 if equal\n    vector<vector<int>> comparison_matrix(N, vector<int>(N, 0));\n    vector<int> comparison_count(N, 0);\n    \n    for (int query = 0; query < Q; query++) {\n        // Find item with minimum comparisons\n        int i = min_element(comparison_count.begin(), comparison_count.end()) - comparison_count.begin();\n        \n        // Find another item to compare with, preferring not yet compared\n        int j = -1;\n        int min_other_count = INT_MAX;\n        \n        // First try: find an item not yet compared with i\n        for (int k = 0; k < N; k++) {\n            if (k != i && comparison_matrix[i][k] == 0 && comparison_count[k] < min_other_count) {\n                min_other_count = comparison_count[k];\n                j = k;\n            }\n        }\n        \n        // Second try: if no new pair, find any item with minimal comparisons\n        if (j == -1) {\n            for (int k = 0; k < N; k++) {\n                if (k != i && comparison_count[k] < min_other_count) {\n                    min_other_count = comparison_count[k];\n                    j = k;\n                }\n            }\n        }\n        \n        // Final fallback\n        if (j == -1) {\n            j = (i + 1) % N;\n            if (j == i) j = (i + 2) % N; // Ensure different items\n        }\n        \n        // Output query: compare single items\n        cout << \"1 1 \" << i << \" \" << j << endl;\n        cout.flush();\n        \n        string result;\n        cin >> result;\n        \n        // Update matrix\n        if (result == \">\") {\n            comparison_matrix[i][j] = 1;\n            comparison_matrix[j][i] = -1;\n        } else if (result == \"<\") {\n            comparison_matrix[i][j] = -1;\n            comparison_matrix[j][i] = 1;\n        } else { // \"=\"\n            comparison_matrix[i][j] = 2; // Equal\n            comparison_matrix[j][i] = 2;\n        }\n        \n        comparison_count[i]++;\n        comparison_count[j]++;\n    }\n    \n    // Calculate score for each item: wins - losses\n    vector<int> score(N, 0);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (i == j) continue;\n            if (comparison_matrix[i][j] == 1) {\n                score[i]++; // i beats j\n            } else if (comparison_matrix[i][j] == -1) {\n                score[i]--; // i loses to j\n            }\n        }\n    }\n    \n    // Create order: items sorted by score descending\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        return score[a] > score[b];\n    });\n    \n    // Assign to D groups using snake pattern for balanced distribution\n    vector<int> assignment(N);\n    for (int pos = 0; pos < N; pos++) {\n        int item = order[pos];\n        int cycle = pos / D;\n        int offset = pos % D;\n        \n        int target_group = (cycle % 2 == 0) ? offset : (D - 1 - offset);\n        assignment[item] = target_group;\n    }\n    \n    // Output assignment\n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << assignment[i];\n    }\n    cout << endl;\n    cout.flush();\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    int h = n / m;                     // height of each stack, fixed to 20\n    vector<vector<int>> st(m);          // stacks, bottom -> top\n    for (int i = 0; i < m; ++i) {\n        st[i].reserve(h);\n        for (int j = 0; j < h; ++j) {\n            int x; cin >> x;\n            st[i].push_back(x);\n        }\n    }\n\n    vector<pair<int,int>> ops;          // answer sequence\n    ops.reserve(5000);\n    long long total_energy = 0;         // only for self check, not output\n\n    // helper: find box v, return (stack index, position inside stack)\n    auto locate = [&](int v, int &si, int &pos){\n        for (int i = 0; i < m; ++i) {\n            for (int j = 0; j < (int)st[i].size(); ++j) {\n                if (st[i][j] == v) {\n                    si = i;\n                    pos = j;\n                    return;\n                }\n            }\n        }\n        // should never happen\n        cerr << \"box \" << v << \" not found!\\n\";\n        exit(1);\n    };\n\n    for (int v = 1; v <= n; ++v) {\n        int si, pos;\n        locate(v, si, pos);\n\n        // if v already on the top -> carry out directly\n        if (pos == (int)st[si].size() - 1) {\n            ops.emplace_back(v, 0);\n            st[si].pop_back();               // remove v\n            continue;\n        }\n\n        // box directly above v\n        int w = st[si][pos + 1];\n\n        // choose a destination stack (different from si)\n        int dest = -1;\n        // 1) any empty stack ?\n        for (int i = 0; i < m; ++i) if (i != si && st[i].empty()) {\n            dest = i; break;\n        }\n        // 2) otherwise the non\u2011empty stack with the largest top number\n        if (dest == -1) {\n            int best_top = -1;\n            for (int i = 0; i < m; ++i) if (i != si && !st[i].empty()) {\n                int cur_top = st[i].back();\n                if (cur_top > best_top) {\n                    best_top = cur_top;\n                    dest = i;\n                }\n            }\n        }\n        // sanity check\n        if (dest == -1) {\n            // should never happen (there is at least one other stack)\n            dest = (si + 1) % m;\n        }\n\n        // ---- move the block w .. top of si to dest ----\n        int start = pos + 1;                         // first element to move\n        vector<int> suffix(st[si].begin() + start, st[si].end());\n        int k = (int)suffix.size();                 // number of moved boxes\n        total_energy += k + 1;\n\n        // erase from source\n        st[si].erase(st[si].begin() + start, st[si].end());\n        // append to destination\n        st[dest].insert(st[dest].end(), suffix.begin(), suffix.end());\n\n        ops.emplace_back(w, dest + 1);               // operation 1\n\n        // ---- now v is on the top of si, carry it out ----\n        ops.emplace_back(v, 0);\n        st[si].pop_back();                           // remove v\n    }\n\n    // ---- output ---------------------------------------------------------\n    for (auto [a, b] : ops) {\n        cout << a << ' ' << b << '\\n';\n    }\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\nvector<vector<bool>> visited;\nvector<vector<int>> last;                // time of last visit\nvector<vector<pair<int,int>>> best_nb;   // cached best neighbour\nstring path;\nconst int MAX_MOVES = 100000;\n\n/* --------------------------------------------------------------- */\ninline bool can_move(int i, int j, int ni, int nj) {\n    if (ni == i - 1 && i > 0)      return h[i - 1][j] == '0';\n    if (ni == i + 1 && i < N - 1)  return h[i][j]     == '0';\n    if (nj == j - 1 && j > 0)      return v[i][j - 1] == '0';\n    if (nj == j + 1 && j < N - 1)  return v[i][j]     == '0';\n    return false;\n}\n\n/* --------------------------------------------------------------- */\ninline void add_move(int di, int dj) {\n    if ((int)path.size() >= MAX_MOVES) return;\n    if (di == -1) path.push_back('U');\n    else if (di == 1) path.push_back('D');\n    else if (dj == -1) path.push_back('L');\n    else if (dj == 1) path.push_back('R');\n}\n\n/* --------------------------------------------------------------- */\n// urgency of cell (i,j) at current time t\ninline double urgency(int i, int j, int t) {\n    int dt = t - last[i][j];\n    if (dt <= 0) return -1.0;\n    return d[i][j] * dt;\n}\n\n/* --------------------------------------------------------------- */\n// most urgent cell\npair<int,int> most_urgent(int t) {\n    double best = -1.0; int bi = -1, bj = -1;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            double u = urgency(i,j,t);\n            if (u > best) {\n                best = u; bi = i; bj = j;\n            }\n        }\n    return {bi,bj};\n}\n\n/* --------------------------------------------------------------- */\n// one step toward (ni,nj); if blocked, any legal step\npair<int,int> step_toward(int i, int j, int ni, int nj) {\n    const int DIRS[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n    int di = 0, dj = 0;\n    if (ni < i) di = -1; else if (ni > i) di = 1;\n    else if (nj < j) dj = -1; else if (nj > j) dj = 1;\n    if (can_move(i,j,i+di,j+dj)) return {i+di,j+dj};\n    for (auto [dii,djj] : DIRS) {\n        int ii = i+dii, jj = j+djj;\n        if (ii>=0 && ii<N && jj>=0 && jj<N && can_move(i,j,ii,jj))\n            return {ii,jj};\n    }\n    return {i,j};                           // nowhere to go\n}\n\n/* --------------------------------------------------------------- */\n// DFS skeleton (guarantees completeness)\nvoid dfs_skeleton(int i, int j) {\n    if ((int)path.size() >= MAX_MOVES) return;\n    visited[i][j] = true;\n    last[i][j] = (int)path.size();\n\n    const int DIRS[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n    vector<pair<int,pair<int,int>>> neigh;\n    for (auto [di,dj] : DIRS) {\n        int ni = i+di, nj = j+dj;\n        if (ni>=0 && ni<N && nj>=0 && nj<N && can_move(i,j,ni,nj) && !visited[ni][nj])\n            neigh.push_back({-d[ni][nj], {ni,nj}});\n    }\n    sort(neigh.begin(), neigh.end());\n\n    for (auto [_,c] : neigh) {\n        int ni = c.first, nj = c.second;\n        if (!visited[ni][nj]) {\n            add_move(ni-i, nj-j);\n            dfs_skeleton(ni,nj);\n            add_move(i-ni, j-nj);\n        }\n    }\n}\n\n/* --------------------------------------------------------------- */\n// Phase\u202f2: insert 4\u2011step detours, but only in the last 30\u202f% of the walk\nvoid long_detour_insertions() {\n    const int DIRS[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n    const int INSERTION_START = (MAX_MOVES * 70) / 100; // start insertions at 70\u202f% of limit\n    string base = path;\n    path.clear();\n\n    int i = 0, j = 0, t = 0;\n    for (size_t k = 0; k < base.size(); ++k) {\n        if ((int)path.size() >= INSERTION_START) {\n            // In the insertion zone: we may add 4\u2011step detours\n            auto [ui,uj] = most_urgent(t);\n            if (ui != -1 && ui != i && uj != j) {\n                double cur = urgency(i,j,t);\n                double tgt = urgency(ui,uj,t);\n                // dynamic threshold: 3 + (remaining_moves / 20000)\n                int remaining = MAX_MOVES - (int)path.size();\n                double thresh = 3.0 + remaining / 20000.0;\n                if (tgt > cur * thresh) {\n                    // first step toward urgent cell\n                    auto [i1,j1] = step_toward(i,j,ui,uj);\n                    if (i1 != i || j1 != j) {\n                        int d1i = i1-i, d1j = j1-j;\n                        add_move(d1i, d1j); ++t; last[i1][j1] = t;\n                        // step to best neighbour of urgent cell\n                        auto [d2i,d2j] = best_nb[ui][uj];\n                        int i2 = i1 + d2i, j2 = j1 + d2j;\n                        if (i2>=0 && i2<N && j2>=0 && j2<N && can_move(i1,j1,i2,j2)) {\n                            add_move(d2i, d2j); ++t; last[i2][j2] = t;\n                            // step back to urgent cell\n                            add_move(-d2i, -d2j); ++t; last[i1][j1] = t;\n                        }\n                        // step back to original cell\n                        add_move(-d1i, -d1j); ++t; last[i][j] = t;\n                        continue; // skip original move \u2013 we are back where we started\n                    }\n                }\n            }\n        }\n        // replay original move\n        char mv = base[k];\n        path.push_back(mv);\n        i += (mv=='U'?-1: mv=='D'?1:0);\n        j += (mv=='L'?-1: mv=='R'?1:0);\n        ++t; last[i][j] = t;\n    }\n}\n\n/* --------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // ---- read input -------------------------------------------------\n    cin >> N;\n    h.resize(N-1); for (int i=0;i<N-1;++i) cin >> h[i];\n    v.resize(N);   for (int i=0;i<N;++i)   cin >> v[i];\n    d.assign(N, vector<int>(N));\n    for (int i=0;i<N;++i)\n        for (int j=0;j<N;++j) cin >> d[i][j];\n\n    // ---- cache best neighbours --------------------------------------\n    const int DIRS[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n    best_nb.assign(N, vector<pair<int,int>>(N, {0,0}));\n    for (int i=0;i<N;++i)\n        for (int j=0;j<N;++j) {\n            int bestVal = -1, bestDi = 0, bestDj = 0;\n            for (auto [di,dj] : DIRS) {\n                int ni = i+di, nj = j+dj;\n                if (ni>=0 && ni<N && nj>=0 && nj<N && can_move(i,j,ni,nj))\n                    if (d[ni][nj] > bestVal) {\n                        bestVal = d[ni][nj];\n                        bestDi = di; bestDj = dj;\n                    }\n            }\n            best_nb[i][j] = {bestDi, bestDj};\n        }\n\n    // ---- build skeleton ---------------------------------------------\n    visited.assign(N, vector<bool>(N, false));\n    last.assign(N, vector<int>(N, -1e9));\n    dfs_skeleton(0,0);\n\n    // ---- enrich with long detours -----------------------------------\n    long_detour_insertions();\n\n    cout << path << '\\n';\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\n\nint N, M;\nint si, sj;\nint startId;\nvector<string> board;\nvector<string> pat;\nvector<vector<int>> letterPos;\n\nint distCell[225][225];\nint row[225], col[225];\n\n/* compute movement distance for a sequence */\nint movementDist(const vector<int> &seq) {\n    const vector<int> *prevCand = &letterPos[seq[0]];\n    vector<int> dpPrev(prevCand->size());\n    for (int i = 0; i < (int)prevCand->size(); ++i)\n        dpPrev[i] = distCell[startId][(*prevCand)[i]];\n\n    for (size_t idx = 1; idx < seq.size(); ++idx) {\n        const vector<int> *curCand = &letterPos[seq[idx]];\n        vector<int> dpCur(curCand->size(), INF);\n        for (int ci = 0; ci < (int)curCand->size(); ++ci) {\n            int cur = (*curCand)[ci];\n            int best = INF;\n            for (int pi = 0; pi < (int)prevCand->size(); ++pi) {\n                int cand = (*prevCand)[pi];\n                int val = dpPrev[pi] + distCell[cand][cur];\n                if (val < best) best = val;\n            }\n            dpCur[ci] = best;\n        }\n        dpPrev.swap(dpCur);\n        prevCand = curCand;\n    }\n    int best = INF;\n    for (int v : dpPrev) if (v < best) best = v;\n    return best;\n}\n\n/* total price for an order */\nint priceOfOrder(const vector<int> &order, vector<int> &seq) {\n    seq.clear(); seq.reserve(5 * M);\n    for (int id : order) {\n        const string &p = pat[id];\n        int maxOL = min((int)seq.size(), 5);\n        int overlap = 0;\n        for (int k = maxOL; k > 0; --k) {\n            bool ok = true;\n            for (int i = 0; i < k; ++i)\n                if (seq[seq.size() - k + i] != p[i] - 'A') { ok = false; break; }\n            if (ok) { overlap = k; break; }\n        }\n        for (int i = overlap; i < 5; ++i) seq.push_back(p[i] - 'A');\n    }\n    int move = movementDist(seq);\n    return move + (int)seq.size();\n}\n\n/* reconstruct walk for best order */\nvector<int> reconstructWalk(const vector<int> &order) {\n    vector<int> seq; seq.reserve(5 * M);\n    for (int id : order) {\n        const string &p = pat[id];\n        int maxOL = min((int)seq.size(), 5);\n        int overlap = 0;\n        for (int k = maxOL; k > 0; --k) {\n            bool ok = true;\n            for (int i = 0; i < k; ++i)\n                if (seq[seq.size() - k + i] != p[i] - 'A') { ok = false; break; }\n            if (ok) { overlap = k; break; }\n        }\n        for (int i = overlap; i < 5; ++i) seq.push_back(p[i] - 'A');\n    }\n    int L = (int)seq.size();\n\n    struct Step {\n        const vector<int> *cells;\n        vector<int> dp;\n        vector<int> pred;\n    };\n    vector<Step> step(L);\n\n    step[0].cells = &letterPos[seq[0]];\n    step[0].dp.resize(step[0].cells->size());\n    step[0].pred.assign(step[0].cells->size(), -1);\n    for (int i = 0; i < (int)step[0].cells->size(); ++i)\n        step[0].dp[i] = distCell[startId][(*step[0].cells)[i]];\n\n    for (int i = 1; i < L; ++i) {\n        step[i].cells = &letterPos[seq[i]];\n        const vector<int> &prevCells = *step[i - 1].cells;\n        const vector<int> &curCells  = *step[i].cells;\n        step[i].dp.assign(curCells.size(), INF);\n        step[i].pred.assign(curCells.size(), -1);\n        for (int ci = 0; ci < (int)curCells.size(); ++ci) {\n            int cur = curCells[ci];\n            int best = INF, bestIdx = -1;\n            for (int pi = 0; pi < (int)prevCells.size(); ++pi) {\n                int val = step[i - 1].dp[pi] + distCell[prevCells[pi]][cur];\n                if (val < best) {\n                    best = val;\n                    bestIdx = pi;\n                }\n            }\n            step[i].dp[ci] = best;\n            step[i].pred[ci] = bestIdx;\n        }\n    }\n\n    const vector<int> &lastCells = *step[L - 1].cells;\n    int bestCost = INF, bestIdx = -1;\n    for (int i = 0; i < (int)lastCells.size(); ++i)\n        if (step[L - 1].dp[i] < bestCost) {\n            bestCost = step[L - 1].dp[i];\n            bestIdx = i;\n        }\n\n    vector<int> walk(L);\n    int idx = bestIdx;\n    for (int i = L - 1; i >= 0; --i) {\n        walk[i] = (*step[i].cells)[idx];\n        if (i > 0) idx = step[i].pred[idx];\n    }\n    return walk;\n}\n\n/* fast random generator */\nstatic uint32_t xs_state = 123456789;\nstatic uint32_t ys_state = 362436069;\nstatic uint32_t zs_state = 521288629;\nstatic uint32_t ws_state = 88675123;\n\nuint32_t xorshift(void) {\n    uint32_t t = xs_state ^ (xs_state << 11);\n    xs_state = ys_state; ys_state = zs_state; zs_state = ws_state;\n    ws_state = ws_state ^ (ws_state >> 19) ^ t ^ (t >> 8);\n    return ws_state;\n}\n\n/* main */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N >> M)) return 0;\n    cin >> si >> sj;\n    startId = si * N + sj;\n    board.resize(N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n    pat.resize(M);\n    for (int i = 0; i < M; ++i) cin >> pat[i];\n\n    // build letterPos and coordinates\n    letterPos.assign(26, {});\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            int id = i * N + j;\n            char c = board[i][j];\n            letterPos[c - 'A'].push_back(id);\n            row[id] = i; col[id] = j;\n        }\n\n    // all pairwise Manhattan distances\n    int C = N * N;\n    for (int a = 0; a < C; ++a)\n        for (int b = 0; b < C; ++b)\n            distCell[a][b] = abs(row[a] - row[b]) + abs(col[a] - col[b]);\n\n    // greedy initial order (simple, by first character distance)\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(),\n         [&](int a, int b) {\n             const string &pa = pat[a], &pb = pat[b];\n             int da = distCell[startId][letterPos[pa[0] - 'A'][0]];\n             int db = distCell[startId][letterPos[pb[0] - 'A'][0]];\n             return da < db;\n         });\n\n    vector<int> seq;\n    int bestPrice = priceOfOrder(order, seq);\n    vector<int> bestOrder = order;\n\n    // aggressive random search: 8000 trials of random swaps\n    const int TOTAL_TRIALS = 8000;\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    for (int trial = 0; trial < TOTAL_TRIALS; ++trial) {\n        // create neighbor by swapping two random patterns\n        vector<int> nxt = bestOrder;  // start from current best\n        int i = rng() % M;\n        int j = rng() % M;\n        if (i != j) swap(nxt[i], nxt[j]);  // safe operation\n\n        int newPrice = priceOfOrder(nxt, seq);\n        if (newPrice < bestPrice) {\n            bestPrice = newPrice;\n            bestOrder = nxt;\n        }\n    }\n\n    // final improvement: try a few adjacent swaps\n    for (int p = 0; p < min(50, M); ++p) {\n        vector<int> nxt = bestOrder;\n        swap(nxt[p], nxt[(p + 1) % M]);\n        int newPrice = priceOfOrder(nxt, seq);\n        if (newPrice < bestPrice) {\n            bestPrice = newPrice;\n            bestOrder = nxt;\n        }\n    }\n\n    // output final walk\n    vector<int> walk = reconstructWalk(bestOrder);\n    for (int cell : walk) {\n        int i = cell / N;\n        int j = cell % N;\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<pair<int,int>>> shapes;          // input shapes (not used for the CS part)\n\n/* ------------------------------------------------------------------ */\n/*   bit\u2011mask helpers                                                */\ninline int idx(int i, int j) { return i * N + j; }\n\n/* ------------------------------------------------------------------ */\n/*   data structures for the CSP                                      */\nvector< vector< bitset<400> > > placements;   // placements[s][p] = cells covered by placement p of shape s\nvector< vector< pair<int,int> > > cell_to_placements; // cell \u2192 list of (shape,placement) that cover it\nbitset<400> known_dry, known_oil, unknown;\nvector<int> placement_score;                  // for each placement: how many still\u2011unknown cells it covers\n\n/* ------------------------------------------------------------------ */\nint query_single(int i, int j) {\n    cout << \"q 1 \" << i << ' ' << j << endl;\n    int ret; cin >> ret;\n    return ret;\n}\n\n/* ------------------------------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---- read input -------------------------------------------- */\n    if (!(cin >> N >> M >> eps)) return 0;\n    shapes.resize(M);\n    for (int k = 0; k < M; ++k) {\n        int d; cin >> d;\n        shapes[k].resize(d);\n        for (int i = 0; i < d; ++i) {\n            int x, y; cin >> x >> y;\n            shapes[k][i] = {x, y};\n        }\n    }\n\n    /* ---- generate all placements -------------------------------- */\n    placements.resize(M);\n    cell_to_placements.assign(N * N, {});\n    const int MAXC = N * N;\n\n    for (int s = 0; s < M; ++s) {\n        // normalize shape: shift so that min i,j = 0\n        int min_i = INT_MAX, min_j = INT_MAX;\n        for (auto [i, j] : shapes[s]) {\n            min_i = min(min_i, i);\n            min_j = min(min_j, j);\n        }\n        vector<pair<int,int>> norm_shape;\n        for (auto [i, j] : shapes[s])\n            norm_shape.emplace_back(i - min_i, j - min_j);\n\n        // size of the shape\n        int h = 0, w = 0;\n        for (auto [i, j] : norm_shape) {\n            h = max(h, i + 1);\n            w = max(w, j + 1);\n        }\n\n        // try every translation\n        for (int di = 0; di + h <= N; ++di)\n            for (int dj = 0; dj + w <= N; ++dj) {\n                bitset<400> mask;\n                bool conflict = false;\n                for (auto [i, j] : norm_shape) {\n                    int r = di + i, c = dj + j;\n                    mask.set(idx(r, c));\n                }\n                // store the placement\n                int pid = placements[s].size();\n                placements[s].push_back(mask);\n                // update reverse index\n                for (int i = 0; i < MAXC; ++i)\n                    if (mask[i]) cell_to_placements[i].push_back({s, pid});\n            }\n    }\n\n    /* ---- initialise CSP status ---------------------------------- */\n    known_dry.reset();\n    known_oil.reset();\n    unknown.reset();\n    for (int i = 0; i < MAXC; ++i) unknown.set(i);\n    placement_score.assign(M, 0);   // not used \u2013 we recompute the coverage on the fly\n\n    /* ---- main loop : at most 2\u00b7N\u00b2 iterations -------------------- */\n    int iterations = 0;\n    const int LIMIT = 2 * N * N;\n\n    while (iterations < LIMIT && unknown.any()) {\n        ++iterations;\n\n        /* ---- 1. prune placements that hit known_dry ---------- */\n        for (int s = 0; s < M; ++s) {\n            vector<bitset<400>> keep;\n            for (auto &pl : placements[s])\n                if ((pl & known_dry).none()) keep.push_back(pl);\n            placements[s].swap(keep);\n        }\n\n        /* ---- 2. deduce forced cells --------------------------- */\n        vector<int> newly_dry, newly_oil;\n        for (int i = 0; i < MAXC; ++i) if (unknown[i]) {\n            bool can_be_oil = false, can_be_dry = false;\n            // check if any placement still covers i\n            for (auto [s, pid] : cell_to_placements[i]) {\n                // we have to check if pid is still alive for shape s\n                bool alive = false;\n                for (auto &pl : placements[s])\n                    if (pl[idx(i/N, i%N)]) { alive = true; break; }\n                if (alive) { can_be_oil = true; break; }\n            }\n            if (!can_be_oil) newly_dry.push_back(i);\n        }\n\n        for (int i : newly_dry) {\n            known_dry.set(i);\n            unknown.reset(i);\n        }\n\n        /* ---- 3. choose the most informative cell -------------- */\n        // simple heuristic: cell covered by the most remaining placements\n        int best_cell = -1, best_cov = 0;\n        for (int i = 0; i < MAXC; ++i) if (unknown[i]) {\n            int cov = 0;\n            for (auto [s, pid] : cell_to_placements[i])\n                for (auto &pl : placements[s])\n                    if (pl[idx(i/N, i%N)]) { ++cov; break; }\n            if (cov > best_cov) {\n                best_cov = cov;\n                best_cell = i;\n            }\n        }\n\n        if (best_cell == -1) break;   // nothing left to test\n\n        int r = best_cell / N, c = best_cell % N;\n        int v = query_single(r, c);\n        if (v > 0) {\n            known_oil.set(best_cell);\n            unknown.reset(best_cell);\n        } else {\n            known_dry.set(best_cell);\n            unknown.reset(best_cell);\n        }\n    }\n\n    /* ---- output answer ------------------------------------------ */\n    vector<pair<int,int>> answer;\n    for (int i = 0; i < MAXC; ++i)\n        if (known_oil[i]) answer.emplace_back(i / N, i % N);\n\n    cout << \"a \" << answer.size();\n    for (auto [r, c] : answer) cout << ' ' << r << ' ' << c;\n    cout << endl;\n\n    int ok; cin >> ok;\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXW = 1000;                 // W is fixed to 1000 in the problem\n\n/*------------------------------------------------------------*/\n/*  geometry structures                                       */\n\nstruct Rect {\n    int x0, y0, x1, y1;               // top\u2011left (x0,y0), bottom\u2011right (x1,y1)\n};\n\nstruct Region {\n    int x, y, w, h;                    // top\u2011left corner, width, height\n    int area() const { return w * h; }\n};\n\n/*------------------------------------------------------------*/\n/*  packing of one day                                       */\n\nstatic vector<Rect> pack_day(const vector<int>& request, int W, int N) {\n    // request[k] = a[d][k]\n    vector<pair<int, int>> ord;        // (area , original index)\n    ord.reserve(N);\n    for (int k = 0; k < N; ++k) ord.emplace_back(request[k], k);\n    sort(ord.begin(), ord.end(),\n         [](const pair<int, int>& A, const pair<int, int>& B) {\n             return A.first > B.first;               // decreasing area\n         });\n\n    vector<Region> freeReg;\n    freeReg.push_back({0, 0, W, W});                 // whole hall\n\n    vector<Rect> answer(N);\n\n    for (auto [area, idx] : ord) {\n        // ---- find a region that can contain the rectangle\n        int sel = -1;          // region with area >= request\n        int best = -1;         // region with the largest area (used when no region fits)\n        int bestArea = -1;\n\n        for (int i = 0; i < (int)freeReg.size(); ++i) {\n            int a = freeReg[i].area();\n            if (a >= area) {\n                if (sel == -1 || a < freeReg[sel].area()) sel = i;\n            }\n            if (a > bestArea) {\n                bestArea = a;\n                best = i;\n            }\n        }\n\n        Region R;\n        bool fits = (sel != -1);\n        if (fits) R = freeReg[sel];\n        else      R = freeReg[best];                  // we will pay a penalty\n\n        // ---- choose the size of the rectangle\n        int w, h;\n        if (fits) {\n            // try orientation 1 (prefer a square)\n            int w1 = min(R.w, max(1, (int)std::sqrt((double)area)));\n            int h1 = (area + w1 - 1) / w1;               // ceil\n            if (h1 <= R.h) {\n                w = w1;  h = h1;\n            } else {\n                // orientation 2 (swap roles)\n                int h2 = min(R.h, max(1, (int)std::sqrt((double)area)));\n                int w2 = (area + h2 - 1) / h2;\n                if (w2 <= R.w) {\n                    w = w2;  h = h2;\n                } else {\n                    // fallback \u2013 use whole width of the region\n                    w = R.w;\n                    h = (area + w - 1) / w;\n                }\n            }\n        } else {\n            // we cannot satisfy the area \u2013 fill the whole region (penalty)\n            w = R.w;\n            h = R.h;\n        }\n\n        // ---- store the rectangle\n        answer[idx] = {R.x, R.y, R.x + w, R.y + h};\n\n        // ---- create the two leftover parts (guillotine cut)\n        if (w < R.w) {\n            freeReg.push_back({R.x + w, R.y, R.w - w, R.h});\n        }\n        if (h < R.h) {\n            freeReg.push_back({R.x, R.y + h, w, R.h - h});\n        }\n\n        // ---- delete the used region (swap with last element)\n        if (fits) {\n            freeReg[sel] = freeReg.back();\n            freeReg.pop_back();\n        } else {\n            freeReg[best] = freeReg.back();\n            freeReg.pop_back();\n        }\n    }\n    return answer;\n}\n\n/*------------------------------------------------------------*/\n/*  edge matrices                                             */\n\nstruct EdgeMatrices {\n    vector<vector<char>> H;   // H[i][j] : horizontal edge (i,0..W-1)  i=1..W-1\n    vector<vector<char>> V;   // V[i][j] : vertical   edge (0..W-1,j)  j=1..W-1\n    EdgeMatrices(int W) {\n        H.assign(W + 1, vector<char>(W, 0));\n        V.assign(W, vector<char>(W + 1, 0));\n    }\n    void clear() {\n        for (auto &row : H) fill(row.begin(), row.end(), 0);\n        for (auto &row : V) fill(row.begin(), row.end(), 0);\n    }\n};\n\nvoid mark_edges(const vector<Rect>& rects, int W, EdgeMatrices& em) {\n    em.clear();\n    for (const Rect& r : rects) {\n        if (r.x0 > 0) {\n            for (int j = r.y0; j < r.y1; ++j) em.H[r.x0][j] = 1;\n        }\n        if (r.x1 < W) {\n            for (int j = r.y0; j < r.y1; ++j) em.H[r.x1][j] = 1;\n        }\n        if (r.y0 > 0) {\n            for (int i = r.x0; i < r.x1; ++i) em.V[i][r.y0] = 1;\n        }\n        if (r.y1 < W) {\n            for (int i = r.x0; i < r.x1; ++i) em.V[i][r.y1] = 1;\n        }\n    }\n}\n\n/*------------------------------------------------------------*/\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\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    vector<vector<Rect>> allRects(D, vector<Rect>(N));\n    EdgeMatrices prev(W), cur(W);\n    long long totalCost = 0;               // only for debugging, not needed for output\n\n    for (int d = 0; d < D; ++d) {\n        // ----- pack the day\n        allRects[d] = pack_day(a[d], W, N);\n        // ----- build edge matrices\n        mark_edges(allRects[d], W, cur);\n        // ----- compute transition cost (L0 = 0 is special)\n        if (d > 0) {\n            long long Ld = 0;\n            for (int i = 1; i < W; ++i)\n                for (int j = 0; j < W; ++j)\n                    Ld += (prev.H[i][j] != cur.H[i][j]);\n            for (int i = 0; i < W; ++i)\n                for (int j = 1; j < W; ++j)\n                    Ld += (prev.V[i][j] != cur.V[i][j]);\n            totalCost += Ld;\n        }\n        // ----- store current matrices as previous for the next day\n        prev.H.swap(cur.H);\n        prev.V.swap(cur.V);\n    }\n\n    // ----- output\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            const Rect& r = allRects[d][k];\n            cout << r.x0 << ' ' << r.y0 << ' ' << r.x1 << ' ' << r.y1 << '\\n';\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 (fixed by the statement)\nconst int SZ = 3;           // stamp size\nconst int MAX_K = 81;       // maximum number of operations\n\nstruct Op {\n    int m;       // stamp index\n    int p, q;    // top\u2011left position of the stamp on the board\n};\n\n/* ------------------------------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M, K;\n    int tmpN;\n    if (!(cin >> tmpN >> M >> K)) return 0;\n\n    int board[N][N];\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> board[i][j];\n\n    int stamp[M][SZ][SZ];\n    for (int m = 0; m < M; ++m)\n        for (int i = 0; i < SZ; ++i)\n            for (int j = 0; j < SZ; ++j)\n                cin >> stamp[m][i][j];\n\n    /* all possible placements (m,p,q) */\n    vector<Op> allOps;\n    for (int m = 0; m < M; ++m)\n        for (int p = 0; p <= N - SZ; ++p)\n            for (int q = 0; q <= N - SZ; ++q)\n                allOps.push_back({m, p, q});\n\n    /* ---------- helper functions ---------- */\n    auto boardScore = [&](const int b[N][N]) -> long long {\n        long long s = 0;\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < N; ++j)\n                s += b[i][j];\n        return s;\n    };\n\n    auto deltaAdd = [&](const int b[N][N], const Op& op) -> long long {\n        const auto& s = stamp[op.m];\n        long long d = 0;\n        for (int i = 0; i < SZ; ++i)\n            for (int j = 0; j < SZ; ++j) {\n                int old = b[op.p + i][op.q + j];\n                int add = s[i][j];\n                int sum = old + add;\n                if (sum >= MOD) d += add - MOD;\n                else            d += add;\n            }\n        return d;\n    };\n\n    auto deltaRemove = [&](const int b[N][N], const Op& op) -> long long {\n        const auto& s = stamp[op.m];\n        long long d = 0;\n        for (int i = 0; i < SZ; ++i)\n            for (int j = 0; j < SZ; ++j) {\n                int old = b[op.p + i][op.q + j];\n                int v = s[i][j];\n                int nw = (old >= v) ? old - v : old + MOD - v;\n                d += nw - old;\n            }\n        return d;\n    };\n\n    auto applyAdd = [&](int b[N][N], long long& sc, const Op& op) {\n        const auto& s = stamp[op.m];\n        for (int i = 0; i < SZ; ++i)\n            for (int j = 0; j < SZ; ++j) {\n                int old = b[op.p + i][op.q + j];\n                int add = s[i][j];\n                int sum = old + add;\n                int nw = (sum >= MOD) ? sum - MOD : sum;\n                b[op.p + i][op.q + j] = nw;\n                sc += nw - old;\n            }\n    };\n\n    auto applyRemove = [&](int b[N][N], long long& sc, const Op& op) {\n        const auto& s = stamp[op.m];\n        for (int i = 0; i < SZ; ++i)\n            for (int j = 0; j < SZ; ++j) {\n                int old = b[op.p + i][op.q + j];\n                int v = s[i][j];\n                int nw = (old >= v) ? old - v : old + MOD - v;\n                b[op.p + i][op.q + j] = nw;\n                sc += nw - old;\n            }\n    };\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    long long bestScore = -1;\n    vector<Op> bestOps;\n\n    const double TIME_LIMIT = 1.8;\n    auto start = chrono::steady_clock::now();\n\n    /* --------------------------------------------------------------- */\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        if (chrono::duration<double>(now - start).count() > TIME_LIMIT) break;\n\n        /* start from the original board */\n        int curBoard[N][N];\n        memcpy(curBoard, board, sizeof(curBoard));\n        long long curScore = boardScore(curBoard);\n        vector<Op> curOps;\n\n        /* ----- greedy construction (add + remove) ----- */\n        do {\n            /* addition */\n            while ((int)curOps.size() < K) {\n                vector<Op> sh = allOps;\n                shuffle(sh.begin(), sh.end(), rng);\n                long long bestDelta = 0;\n                vector<Op> cand;\n                for (const Op& op : sh) {\n                    long long d = deltaAdd(curBoard, op);\n                    if (d > bestDelta) {\n                        bestDelta = d;\n                        cand.clear();\n                        cand.push_back(op);\n                    } else if (d == bestDelta && d > 0) {\n                        cand.push_back(op);\n                    }\n                }\n                if (bestDelta <= 0) break;\n                const Op& chosen = cand[0];\n                applyAdd(curBoard, curScore, chosen);\n                curOps.push_back(chosen);\n            }\n\n            /* removal */\n            while (true) {\n                long long bestDelta = 0;\n                vector<int> idxCand;\n                for (int i = 0; i < (int)curOps.size(); ++i) {\n                    long long d = deltaRemove(curBoard, curOps[i]);\n                    if (d > bestDelta) {\n                        bestDelta = d;\n                        idxCand.clear();\n                        idxCand.push_back(i);\n                    } else if (d == bestDelta && d > 0) {\n                        idxCand.push_back(i);\n                    }\n                }\n                if (bestDelta <= 0) break;\n                int idx = idxCand[0];\n                Op op = curOps[idx];\n                applyRemove(curBoard, curScore, op);\n                curOps[idx] = curOps.back();\n                curOps.pop_back();\n            }\n\n            if (curScore > bestScore) {\n                bestScore = curScore;\n                bestOps = curOps;          // copy\n            }\n        } while (false);   // run only once \u2013 we will kick afterwards\n\n        /* ----- random kicks and many rebuilds ----- */\n        for (int kickRound = 0; kickRound < 10; ++kickRound) {\n            /* delete up to 5 random operations */\n            int kick = min(5, (int)curOps.size());\n            for (int i = 0; i < kick; ++i) {\n                int idx = rng() % curOps.size();\n                Op op = curOps[idx];\n                applyRemove(curBoard, curScore, op);\n                curOps[idx] = curOps.back();\n                curOps.pop_back();\n            }\n\n            /* rebuild greedily many times */\n            for (int rebuild = 0; rebuild < 10; ++rebuild) {\n                /* addition */\n                while ((int)curOps.size() < K) {\n                    vector<Op> sh = allOps;\n                    shuffle(sh.begin(), sh.end(), rng);\n                    long long bestDelta = 0;\n                    vector<Op> cand;\n                    for (const Op& op : sh) {\n                        long long d = deltaAdd(curBoard, op);\n                        if (d > bestDelta) {\n                            bestDelta = d;\n                            cand.clear();\n                            cand.push_back(op);\n                        } else if (d == bestDelta && d > 0) {\n                            cand.push_back(op);\n                        }\n                    }\n                    if (bestDelta <= 0) break;\n                    const Op& chosen = cand[0];\n                    applyAdd(curBoard, curScore, chosen);\n                    curOps.push_back(chosen);\n                }\n\n                /* removal */\n                while (true) {\n                    long long bestDelta = 0;\n                    vector<int> idxCand;\n                    for (int i = 0; i < (int)curOps.size(); ++i) {\n                        long long d = deltaRemove(curBoard, curOps[i]);\n                        if (d > bestDelta) {\n                            bestDelta = d;\n                            idxCand.clear();\n                            idxCand.push_back(i);\n                        } else if (d == bestDelta && d > 0) {\n                            idxCand.push_back(i);\n                        }\n                    }\n                    if (bestDelta <= 0) break;\n                    int idx = idxCand[0];\n                    Op op = curOps[idx];\n                    applyRemove(curBoard, curScore, op);\n                    curOps[idx] = curOps.back();\n                    curOps.pop_back();\n                }\n            }   // end rebuild loop\n\n            if (curScore > bestScore) {\n                bestScore = curScore;\n                bestOps = curOps;\n            }\n        }   // end kick loop\n    }\n\n    cout << bestOps.size() << '\\n';\n    for (const Op& op : bestOps)\n        cout << op.m << ' ' << op.p << ' ' << op.q << '\\n';\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos {\n    int r = -1, c = -1;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n    const int TOTAL = N * N;\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) cin >> A[i][j];\n\n    // which row each container comes from (not needed further)\n    vector<int> sourceRow(TOTAL);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            sourceRow[A[i][j]] = i;\n\n    // grid: container id or -1\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    // how many containers of each row already appeared\n    vector<int> recCnt(N, 0);\n    // how many containers already dispatched\n    int dispatched = 0;\n\n    // the large crane\n    struct Crane {\n        int r = 0, c = 0;\n        bool holding = false;\n        int holdId = -1;\n    } large;\n\n    // output strings, one per row\n    vector<string> out(N);\n\n    int turn = 0;\n    const int LIMIT = 10000;\n\n    while (dispatched < TOTAL && turn < LIMIT) {\n        /* ---- step 1 : containers appear ---- */\n        for (int i = 0; i < N; ++i) {\n            if (recCnt[i] >= N) continue;               // row finished\n            if (grid[i][0] != -1) continue;              // square occupied\n            // a crane holding a container blocks the square\n            bool blocked = (large.r == i && large.c == 0 && large.holding);\n            if (!blocked) {\n                int cid = A[i][recCnt[i]];\n                grid[i][0] = cid;\n                ++recCnt[i];\n            }\n        }\n\n        /* ---- step 2 : crane actions ---- */\n        // small cranes: bomb on turn 0, then only '.'\n        for (int i = 1; i < N; ++i) {\n            if (turn == 0) out[i].push_back('B');\n            else           out[i].push_back('.');\n        }\n\n        // large crane (row 0)\n        char act = '.';\n        if (large.holding) {\n            int targetRow = large.holdId / N;\n            int targetCol = N - 1;\n            if (large.r != targetRow) {                 // vertical move\n                int dr = (targetRow > large.r) ? 1 : -1;\n                act = (dr == 1) ? 'D' : 'U';\n                large.r += dr;\n            } else if (large.c != targetCol) {          // move right\n                act = 'R';\n                large.c += 1;\n            } else {                                    // drop on dispatch gate\n                grid[large.r][large.c] = large.holdId;\n                large.holding = false;\n                large.holdId = -1;\n                act = 'Q';\n            }\n        } else {\n            // not holding \u2013 pick the smallest waiting container\n            int bestRow = -1;\n            int bestId = INT_MAX;\n            for (int i = 0; i < N; ++i) {\n                if (grid[i][0] != -1 && grid[i][0] < bestId) {\n                    bestId = grid[i][0];\n                    bestRow = i;\n                }\n            }\n            if (bestRow == -1) {                        // nothing to do\n                act = '.';\n            } else {\n                if (large.r != bestRow) {               // vertical move\n                    int dr = (bestRow > large.r) ? 1 : -1;\n                    act = (dr == 1) ? 'D' : 'U';\n                    large.r += dr;\n                } else if (large.c != 0) {              // move left to column 0\n                    act = 'L';\n                    large.c -= 1;\n                } else {                                // pick up\n                    int cid = grid[large.r][large.c];\n                    large.holding = true;\n                    large.holdId = cid;\n                    grid[large.r][large.c] = -1;\n                    act = 'P';\n                }\n            }\n        }\n        out[0].push_back(act);\n\n        /* ---- step 3 : dispatch ---- */\n        for (int i = 0; i < N; ++i) {\n            int cid = grid[i][N - 1];\n            if (cid != -1) {\n                ++dispatched;\n                grid[i][N - 1] = -1;\n            }\n        }\n\n        ++turn;\n    }\n\n    // all rows must have the same length (pad with '.')\n    for (int i = 0; i < N; ++i) {\n        if ((int)out[i].size() < turn) out[i] += string(turn - out[i].size(), '.');\n        cout << out[i] << '\\n';\n    }\n    return 0;\n}","ahc034":"#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    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    // working copy of the heights\n    vector<vector<int>> rem = h;\n\n    int curR = 0, curC = 0;      // truck position\n    int load = 0;                // soil on the truck\n    vector<string> ops;          // list of operations\n\n    auto pushMove = [&](char dir) {\n        ops.emplace_back(string(1, dir));\n    };\n    auto pushLoad = [&](int d) {\n        ops.emplace_back(\"+\" + to_string(d));\n        load += d;\n    };\n    auto pushUnload = [&](int d) {\n        ops.emplace_back(\"-\" + to_string(d));\n        load -= d;\n    };\n\n    // move the truck to (tr,tc) along a Manhattan path\n    auto moveTo = [&](int tr, int tc) {\n        int dr = tr - curR;\n        int dc = tc - curC;\n        while (dr != 0) {\n            int step = (dr > 0) ? 1 : -1;\n            char dir = (dr > 0) ? 'D' : 'U';\n            pushMove(dir);\n            curR += step;\n            dr -= step;\n        }\n        while (dc != 0) {\n            int step = (dc > 0) ? 1 : -1;\n            char dir = (dc > 0) ? 'R' : 'L';\n            pushMove(dir);\n            curC += step;\n            dc -= step;\n        }\n    };\n\n    // find the nearest cell that satisfies a predicate\n    auto nearest = [&](auto pred) -> pair<int,int> {\n        int bestDist = INT_MAX;\n        pair<int,int> best(-1,-1);\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (!pred(i,j)) continue;\n                int dist = abs(i - curR) + abs(j - curC);\n                if (dist < bestDist) {\n                    bestDist = dist;\n                    best = {i,j};\n                }\n            }\n        }\n        return best;\n    };\n\n    while (true) {\n        // nearest hill (positive remaining height)\n        auto hill = nearest([&](int i,int j){ return rem[i][j] > 0; });\n        if (hill.first == -1) break;                 // no hill left -> finished\n\n        // go there and load everything\n        moveTo(hill.first, hill.second);\n        int d = rem[hill.first][hill.second];        // >0\n        pushLoad(d);\n        rem[hill.first][hill.second] = 0;\n\n        // deliver the whole load to holes\n        while (load > 0) {\n            auto hole = nearest([&](int i,int j){ return rem[i][j] < 0; });\n            // there must be a hole, otherwise the input would be inconsistent\n            moveTo(hole.first, hole.second);\n            int demand = -rem[hole.first][hole.second]; // positive\n            int unload = min(load, demand);\n            pushUnload(unload);\n            rem[hole.first][hole.second] += unload;    // still \u2264 0\n        }\n    }\n\n    // (optional) safety \u2013 should never be needed because sums are zero\n    while (load > 0) {\n        auto hole = nearest([&](int i,int j){ return rem[i][j] < 0; });\n        if (hole.first == -1) break;\n        moveTo(hole.first, hole.second);\n        int demand = -rem[hole.first][hole.second];\n        int unload = min(load, demand);\n        pushUnload(unload);\n        rem[hole.first][hole.second] += unload;\n    }\n\n    // output all operations\n    for (auto &s : ops) cout << s << '\\n';\n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int N = 6;               // fixed in the statement\n    const int M = 15;              // fixed in the statement\n    const int T = 10;              // fixed in the statement\n    const int SEED_CNT = 2 * N * (N - 1);   // 60\n    const int CELL_CNT = N * N;            // 36\n    const int EDGE_CNT = 2 * N * (N - 1);   // 60\n\n    // ---------- read initial data ----------\n    int tmpN, tmpM, tmpT;\n    if (!(cin >> tmpN >> tmpM >> tmpT)) return 0;\n    // the values are the same as the constants above, ignore them\n\n    vector<vector<int>> seed(SEED_CNT, vector<int>(M));\n    vector<int> seedSum(SEED_CNT, 0);\n    vector<int> X(M, 0);                 // per\u2011dimension maxima of the initial seeds\n\n    for (int i = 0; i < SEED_CNT; ++i) {\n        int s = 0;\n        for (int j = 0; j < M; ++j) {\n            int x; cin >> x;\n            seed[i][j] = x;\n            s += x;\n            X[j] = max(X[j], x);\n        }\n        seedSum[i] = s;\n    }\n\n    // build list of edges (neighbour pairs) once\n    vector<pair<int,int>> edges;\n    edges.reserve(EDGE_CNT);\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            int p = i * N + j;\n            if (i + 1 < N) edges.emplace_back(p, (i + 1) * N + j);\n            if (j + 1 < N) edges.emplace_back(p, i * N + (j + 1));\n        }\n\n    // helper: best possible child of two seeds\n    auto best_possible = [&](int a, int b)->int{\n        int ret = 0;\n        const auto &A = seed[a];\n        const auto &B = seed[b];\n        for (int i = 0; i < M; ++i) ret += max(A[i], B[i]);\n        return ret;\n    };\n\n    // helper: evaluate a whole placement\n    // returns {total_sum_of_best , max_best}\n    auto evaluate = [&](const vector<int> &grid)->pair<int,int>{\n        int total = 0, mx = 0;\n        for (auto [u,v] : edges) {\n            int val = best_possible(grid[u], grid[v]);\n            total += val;\n            mx = max(mx, val);\n        }\n        return {total, mx};\n    };\n\n    // ---------- round loop ----------\n    for (int round = 0; round < T; ++round) {\n        // ---- choose the initial 36 seeds: the 36 with largest sum ----\n        vector<int> allIdx(SEED_CNT);\n        iota(allIdx.begin(), allIdx.end(), 0);\n        sort(allIdx.begin(), allIdx.end(),\n             [&](int a, int b){ return seedSum[a] > seedSum[b]; });\n        vector<int> selectedIdx(allIdx.begin(), allIdx.begin() + CELL_CNT);   // 36 seeds\n\n        // best placement found in this round\n        vector<int> bestGrid;\n        long long bestObj = -(1LL<<60);\n\n        // ---- several restarts of hill climbing ----\n        const int RESTARTS = 3;\n        const int ITERATIONS = 2000;\n        const int WEIGHT_MAX = 1000;          // max_best is multiplied by this\n\n        for (int rep = 0; rep < RESTARTS; ++rep) {\n            // current placement: random permutation of the 36 selected seeds\n            vector<int> grid = selectedIdx;\n            shuffle(grid.begin(), grid.end(), mt19937{ random_device{}() });\n\n            // current used / unused lists\n            vector<char> used(SEED_CNT, 0);\n            for (int id : grid) used[id] = 1;\n            vector<int> unused;\n            unused.reserve(SEED_CNT - CELL_CNT);\n            for (int i = 0; i < SEED_CNT; ++i) if (!used[i]) unused.push_back(i);\n\n            // evaluate starting placement\n            auto [totalSum, maxBest] = evaluate(grid);\n            long long curObj = (long long)maxBest * WEIGHT_MAX + totalSum;\n\n            // hill climbing\n            for (int it = 0; it < ITERATIONS; ++it) {\n                bool moveWithUnused = false;\n                if (!unused.empty() && (rand() % 2)) moveWithUnused = true;\n\n                if (moveWithUnused) {\n                    // exchange a planted seed with an unused one\n                    int pos = rand() % CELL_CNT;\n                    int oldSeed = grid[pos];\n                    int idx = rand() % unused.size();\n                    int newSeed = unused[idx];\n                    // temporarily place newSeed\n                    grid[pos] = newSeed;\n                    auto [newSum, newMax] = evaluate(grid);\n                    long long newObj = (long long)newMax * WEIGHT_MAX + newSum;\n                    if (newObj > curObj) {               // accept\n                        used[oldSeed] = 0;\n                        used[newSeed] = 1;\n                        unused[idx] = oldSeed;            // replace\n                        curObj = newObj;\n                        // totalSum, maxBest are already updated by evaluate\n                    } else {\n                        grid[pos] = oldSeed;               // revert\n                    }\n                } else {\n                    // swap two positions\n                    int p = rand() % CELL_CNT;\n                    int q = rand() % CELL_CNT;\n                    if (p == q) continue;\n                    swap(grid[p], grid[q]);\n                    auto [newSum, newMax] = evaluate(grid);\n                    long long newObj = (long long)newMax * WEIGHT_MAX + newSum;\n                    if (newObj > curObj) {               // accept\n                        curObj = newObj;\n                    } else {\n                        swap(grid[p], grid[q]);           // revert\n                    }\n                }\n            } // end of iterations\n\n            // keep the best placement among the restarts\n            if (curObj > bestObj) {\n                bestObj = curObj;\n                bestGrid = grid;\n            }\n        } // restarts\n\n        // ---- output the best grid ----\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (j) cout << ' ';\n                cout << bestGrid[i * N + j];\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n\n        // ---- read the children, they become the seed pool for the next round ----\n        for (int i = 0; i < SEED_CNT; ++i) {\n            int s = 0;\n            for (int j = 0; j < M; ++j) {\n                int x; cin >> x;\n                seed[i][j] = x;\n                s += x;\n            }\n            seedSum[i] = s;\n        }\n    } // round loop\n\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\n\n/* -------------------------------------------------------------\n   geometry constants \u2013 used everywhere\n   ------------------------------------------------------------- */\n// directions of the leaves: 0 = east, 1 = north, 2 = west, 3 = south\nconst int DIR_DX[4] = {0, -1, 0, +1};\nconst int DIR_DY[4] = {+1, 0, -1, 0};\n\n// root moves: order must match move_chars[]\nconst int MV_DX[5] = {-1, +1, 0, 0, 0};\nconst int MV_DY[5] = {0, 0, -1, +1, 0};\nconst char MOVE_CHARS[5] = {'U','D','L','R','.'};\n\n/* -------------------------------------------------------------\n   perform all possible actions for the current root position\n   returns number of actions done and fills the action string\n   ------------------------------------------------------------- */\nint perform_actions(int rx, int ry,\n                    const vector<int> &dir,\n                    vector<char> &loaded, int &loaded_cnt,\n                    const vector<vector<char>> &is_src,\n                    const vector<vector<char>> &is_tgt,\n                    vector<vector<char>> &occupied, int &src_rem,\n                    string &act) {\n    const int C = 4;\n    int actions = 0;\n    act.clear();\n    act.push_back('.');               // root never acts\n    for (int i = 1; i <= C; ++i) {\n        int d = dir[i];\n        int cx = rx + DIR_DX[d];\n        int cy = ry + DIR_DY[d];\n        bool can = false;\n        if (!loaded[i] && cx >= 0 && cx < int(occupied.size()) &&\n            cy >= 0 && cy < int(occupied.size()) &&\n            is_src[cx][cy] && occupied[cx][cy]) {\n            can = true;\n            // pick\n            occupied[cx][cy] = 0;\n            loaded[i] = 1;\n            --src_rem;\n            ++loaded_cnt;\n        } else if (loaded[i] && cx >= 0 && cx < int(occupied.size()) &&\n                   cy >= 0 && cy < int(occupied.size()) &&\n                   is_tgt[cx][cy] && !occupied[cx][cy]) {\n            can = true;\n            // deliver\n            occupied[cx][cy] = 1;\n            loaded[i] = 0;\n            --loaded_cnt;\n        }\n        if (can) { act.push_back('P'); ++actions; }\n        else       act.push_back('.');\n    }\n    return actions;\n}\n\n/* -------------------------------------------------------------\n   main\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> s(N), t(N);\n    for (int i = 0; i < N; ++i) cin >> s[i];\n    for (int i = 0; i < N; ++i) cin >> t[i];\n\n    /* ----- board description ----- */\n    vector<vector<char>> is_src(N, vector<char>(N, 0));\n    vector<vector<char>> is_tgt(N, vector<char>(N, 0));\n    vector<vector<char>> occupied(N, vector<char>(N, 0));\n    int src_rem = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            occupied[i][j] = (s[i][j] == '1');\n            if (s[i][j] == '1' && t[i][j] == '0') {\n                is_src[i][j] = 1;\n                ++src_rem;\n            }\n            if (t[i][j] == '1' && s[i][j] == '0') {\n                is_tgt[i][j] = 1;\n            }\n        }\n    }\n\n    /* ----- arm geometry \u2013 always the same 5\u2011vertex star ----- */\n    const int Vout = 5;                     // root + 4 leaves, always \u2264 V\n    const int C = 4;                        // leaves we actually use\n\n    // leaf directions after the two initial rotation turns\n    vector<int> dir(C + 1, 0);               // 1\u2011based, initially all east\n    vector<char> loaded(C + 1, 0);           // initially empty\n    int loaded_cnt = 0;\n\n    // root initial position\n    int rx = 0, ry = 0;\n\n    /* ----- output the designed tree ----- */\n    cout << Vout << '\\n';\n    for (int i = 1; i < Vout; ++i) cout << 0 << ' ' << 1 << '\\n';\n    cout << rx << ' ' << ry << '\\n';\n\n    /* ----- containers for the operation strings ----- */\n    vector<string> ops;\n\n    /* ----- two initial rotation turns ----- */\n    // turn 0 : . L L R   (leaf 2,3,4 are rotated)\n    {\n        string op;\n        op.push_back('.');                 // root\n        op.push_back('.');                 // leaf 1\n        op.push_back('L');                 // leaf 2\n        op.push_back('L');                 // leaf 3\n        op.push_back('R');                 // leaf 4\n        for (int i = 0; i < Vout; ++i) op.push_back('.'); // actions\n        ops.push_back(op);\n        // apply rotations\n        dir[2] = (dir[2] + 1) & 3;          // L -> +1 (mod 4)\n        dir[3] = (dir[3] + 1) & 3;          // L\n        dir[4] = (dir[4] + 3) & 3;          // R -> +3 (mod 4)\n    }\n    // turn 1 : . . L .   (leaf 3 gets its second rotation)\n    {\n        string op;\n        op.push_back('.');                 // root\n        op.push_back('.');                 // leaf 1\n        op.push_back('.');                 // leaf 2\n        op.push_back('L');                 // leaf 3\n        op.push_back('.');                 // leaf 4\n        for (int i = 0; i < Vout; ++i) op.push_back('.'); // actions\n        ops.push_back(op);\n        // apply rotation\n        dir[3] = (dir[3] + 1) & 3;          // now leaf 3 points west\n    }\n\n    /* ----- main simulation loop \u2013 stop after 100\u202f000 turns ----- */\n    while ((src_rem > 0 || loaded_cnt > 0) && (int)ops.size() < 100000) {\n        // decide the current mode (pickup if we have empty leaves and sources left)\n        bool have_empty = false;\n        for (int i = 1; i <= C; ++i) if (!loaded[i]) { have_empty = true; break; }\n        int mode = (src_rem > 0 && have_empty) ? 0 : 1; // 0 = pickup, 1 = delivery\n\n        // try all five possible root moves\n        int best_move = -1, best_score = -1, best_dist = INF, best_reach = -1;\n        for (int m = 0; m < 5; ++m) {\n            char mc = MOVE_CHARS[m];\n            int nx = rx + MV_DX[m];\n            int ny = ry + MV_DY[m];\n            if (mc != '.' && (nx < 0 || nx >= N || ny < 0 || ny >= N)) continue;\n\n            // count possible actions for this move\n            int pickups = 0, deliveries = 0;\n            for (int i = 1; i <= C; ++i) {\n                int d = dir[i];\n                int cx = nx + DIR_DX[d];\n                int cy = ny + DIR_DY[d];\n                if (cx < 0 || cx >= N || cy < 0 || cy >= N) continue;\n                if (!loaded[i] && is_src[cx][cy] && occupied[cx][cy]) ++pickups;\n                else if (loaded[i] && is_tgt[cx][cy] && !occupied[cx][cy]) ++deliveries;\n            }\n            int score = pickups + deliveries;\n\n            // distance to the nearest still needed square (source or target)\n            int dist = INF;\n            if (mode == 0) { // pickup\n                for (int i = 0; i < N; ++i)\n                    for (int j = 0; j < N; ++j)\n                        if (is_src[i][j] && occupied[i][j])\n                            for (int d = 0; d < 4; ++d) {\n                                int ni = i + DIR_DX[d];\n                                int nj = j + DIR_DY[d];\n                                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                                int ddist = abs(nx - ni) + abs(ny - nj);\n                                dist = min(dist, ddist);\n                            }\n            } else { // delivery\n                for (int i = 0; i < N; ++i)\n                    for (int j = 0; j < N; ++j)\n                        if (is_tgt[i][j] && !occupied[i][j])\n                            for (int d = 0; d < 4; ++d) {\n                                int ni = i + DIR_DX[d];\n                                int nj = j + DIR_DY[d];\n                                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                                int ddist = abs(nx - ni) + abs(ny - nj);\n                                dist = min(dist, ddist);\n                            }\n            }\n\n            // NEW: count how many needed squares become reachable soon (dist \u2264 2)\n            int reach_count = 0;\n            if (mode == 0) { // pickup\n                for (int i = 0; i < N; ++i)\n                    for (int j = 0; j < N; ++j)\n                        if (is_src[i][j] && occupied[i][j])\n                            for (int d = 0; d < 4; ++d) {\n                                int ni = i + DIR_DX[d];\n                                int nj = j + DIR_DY[d];\n                                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                                if (abs(nx - ni) + abs(ny - nj) <= 2) { ++reach_count; break; }\n                            }\n            } else { // delivery\n                for (int i = 0; i < N; ++i)\n                    for (int j = 0; j < N; ++j)\n                        if (is_tgt[i][j] && !occupied[i][j])\n                            for (int d = 0; d < 4; ++d) {\n                                int ni = i + DIR_DX[d];\n                                int nj = j + DIR_DY[d];\n                                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                                if (abs(nx - ni) + abs(ny - nj) <= 2) { ++reach_count; break; }\n                            }\n            }\n\n            // choose best move: higher score, then higher reach_count, then lower dist\n            if (score > best_score ||\n                (score == best_score && reach_count > best_reach) ||\n                (score == best_score && reach_count == best_reach && dist < best_dist)) {\n                best_move = m;\n                best_score = score;\n                best_dist = dist;\n                best_reach = reach_count;\n            }\n        }\n        // if nothing is possible, still move toward the nearest needed square\n        if (best_move == -1) {\n            for (int m = 0; m < 5; ++m) {\n                char mc = MOVE_CHARS[m];\n                int nx = rx + MV_DX[m];\n                int ny = ry + MV_DY[m];\n                if (mc != '.' && (nx < 0 || nx >= N || ny < 0 || ny >= N)) continue;\n                best_move = m; break;\n            }\n        }\n\n        // apply the chosen move and build the operation string\n        char mv = MOVE_CHARS[best_move];\n        int nx = rx + MV_DX[best_move];\n        int ny = ry + MV_DY[best_move];\n        string op;\n        op.push_back(mv);                     // root movement\n        for (int i = 1; i <= C; ++i) op.push_back('.'); // no rotations\n        string act;\n        perform_actions(nx, ny, dir, loaded, loaded_cnt,\n                        is_src, is_tgt, occupied, src_rem, act);\n        op += act;                            // append actions\n        ops.push_back(op);\n        // update root position\n        rx = nx; ry = ny;\n    }\n\n    /* ----- output all operation strings ----- */\n    for (const string &s : ops) cout << s << '\\n';\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Node {\n    int sum;          // total sum of interval\n    int pref;         // max prefix sum (non empty)\n    int pref_r;       // right border of this prefix\n    int suff;         // max suffix sum (non empty)\n    int suff_l;       // left border of this suffix\n    int best;         // max sub\u2011array sum (non empty)\n    int best_l, best_r;   // borders of this sub\u2011array\n};\n\n/* combine two neighbouring nodes, result is stored in c */\nstatic inline void combine(Node &c, const Node &L, const Node &R) {\n    c.sum = L.sum + R.sum;\n\n    // prefix\n    if (L.pref > L.sum + R.pref) {\n        c.pref = L.pref;\n        c.pref_r = L.pref_r;\n    } else {\n        c.pref = L.sum + R.pref;\n        c.pref_r = R.pref_r;\n    }\n\n    // suffix\n    if (R.suff > R.sum + L.suff) {\n        c.suff = R.suff;\n        c.suff_l = R.suff_l;\n    } else {\n        c.suff = R.sum + L.suff;\n        c.suff_l = L.suff_l;\n    }\n\n    // best\n    c.best = L.best;\n    c.best_l = L.best_l;\n    c.best_r = L.best_r;\n\n    if (R.best > c.best) {\n        c.best = R.best;\n        c.best_l = R.best_l;\n        c.best_r = R.best_r;\n    }\n\n    int cross = L.suff + R.pref;\n    if (cross > c.best) {\n        c.best = cross;\n        c.best_l = L.suff_l;\n        c.best_r = R.pref_r;\n    }\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\n    struct Pt { int x, y, xi, yi, w; };\n    vector<Pt> pts;\n    pts.reserve(2 * N);\n    vector<int> xs, ys;\n    for (int i = 0; i < 2 * N; ++i) {\n        int x, y;\n        cin >> x >> y;\n        int w = (i < N) ? +1 : -1;\n        pts.push_back({x, y, -1, -1, w});\n        xs.push_back(x);\n        ys.push_back(y);\n    }\n\n    /* coordinate compression */\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    int X = (int)xs.size();\n    int Y = (int)ys.size();\n\n    for (auto &p : pts) {\n        p.xi = lower_bound(xs.begin(), xs.end(), p.x) - xs.begin();\n        p.yi = lower_bound(ys.begin(), ys.end(), p.y) - ys.begin();\n    }\n\n    /* decide which axis will be the outer sweep */\n    bool sweepX = (X <= Y);          // true \u2192 outer loop over x, tree on y\n    int outerSize = sweepX ? X : Y;\n    int innerSize = sweepX ? Y : X;   // size of the axis stored in the segment tree\n\n    // build the structure \u201cpoints per column\u201d for the outer axis\n    vector<vector<pair<int,int>>> perOuter(outerSize);\n    for (auto &p : pts) {\n        if (sweepX)\n            perOuter[p.xi].push_back({p.yi, p.w});\n        else\n            perOuter[p.yi].push_back({p.xi, p.w});\n    }\n\n    // segment tree for the inner axis\n    int M = 1;\n    while (M < innerSize) M <<= 1;\n    vector<Node> seg(2 * M);\n\n    auto treeReset = [&]() {\n        // whole tree to zero\n        for (int i = 0; i < 2 * M; ++i) {\n            seg[i].sum = seg[i].pref = seg[i].suff = seg[i].best = 0;\n        }\n        // leaf indices (must be set, otherwise the borders of a leaf would be undefined)\n        for (int i = 0; i < innerSize; ++i) {\n            seg[M + i].pref_r = seg[M + i].suff_l = seg[M + i].best_l = seg[M + i].best_r = i;\n        }\n        for (int i = innerSize; i < M; ++i) {\n            seg[M + i].pref_r = seg[M + i].suff_l = seg[M + i].best_l = seg[M + i].best_r = i;\n        }\n        // internal nodes\n        for (int i = M - 1; i >= 1; --i)\n            combine(seg[i], seg[i << 1], seg[i << 1 | 1]);\n    };\n\n    auto treeAdd = [&](int idx, int delta) {\n        int p = M + idx;\n        seg[p].sum += delta;\n        int ns = seg[p].sum;\n        seg[p].pref = seg[p].suff = seg[p].best = ns;\n        for (p >>= 1; p; p >>= 1)\n            combine(seg[p], seg[p << 1], seg[p << 1 | 1]);\n    };\n\n    int bestValue = -1;          // -1 means \u201cno positive rectangle found\u201d\n    int bestL = -1, bestR = -1, bestB = -1, bestT = -1;\n\n    // ----- initialise the tree with the whole range [0 .. outerSize-1] -----\n    for (int right = 0; right < outerSize; ++right)\n        for (auto &pr : perOuter[right])\n            treeAdd(pr.first, pr.second);\n\n    // ----- sweep left side, removing columns one by one -----\n    for (int left = 0; left < outerSize; ++left) {\n        // tree now contains columns [left .. outerSize-1]\n        for (int right = left; right < outerSize; ++right) {\n            const Node &root = seg[1];\n            int cur = root.best;\n            if (cur > bestValue) {\n                bestValue = cur;\n                bestL = left;\n                bestR = right;\n                bestB = root.best_l;\n                bestT = root.best_r;\n            }\n            if (bestValue == N) break;     // cannot improve any more\n        }\n        if (bestValue == N) break;         // stop the whole sweep\n\n        // before moving left forward, delete column left\n        if (left + 1 < outerSize) {        // nothing to delete after the last column\n            for (auto &pr : perOuter[left])\n                treeAdd(pr.first, -pr.second);   // subtract the weight\n        }\n    }\n\n    // -----------------------------------------------------------------\n    // build the final rectangle (swap back if we swept over y)\n    int leftX, rightX, bottomY, topY;\n\n    // arrays that tell which integer coordinates are occupied (for the \u201cempty\u201d extension)\n    vector<char> usedX(100001, 0), usedY(100001, 0);\n    for (auto &p : pts) {\n        usedX[p.x] = 1;\n        usedY[p.y] = 1;\n    }\n\n    auto findUnused = [&](const vector<char> &used, int after) {\n        for (int v = after + 1; v <= 100000; ++v)\n            if (!used[v]) return v;\n        for (int v = after - 1; v >= 0; --v)\n            if (!used[v]) return v;\n        return -1;   // never happens\n    };\n\n    if (bestValue <= 0) {               // no positive rectangle \u2013 use an empty one\n        int x1 = -1, x2 = -1;\n        for (int x = 0; x <= 100000; ++x) if (!usedX[x]) { x1 = x; break; }\n        for (int x = x1 + 1; x <= 100000; ++x) if (!usedX[x]) { x2 = x; break; }\n        int y1 = -1, y2 = -1;\n        for (int y = 0; y <= 100000; ++y) if (!usedY[y]) { y1 = y; break; }\n        for (int y = y1 + 1; y <= 100000; ++y) if (!usedY[y]) { y2 = y; break; }\n        leftX = x1; rightX = x2;\n        bottomY = y1; topY = y2;\n    } else {\n        if (sweepX) {\n            leftX   = xs[bestL];\n            rightX  = xs[bestR];\n            bottomY = ys[bestB];\n            topY    = ys[bestT];\n        } else {\n            leftX   = xs[bestB];\n            rightX  = xs[bestT];\n            bottomY = ys[bestL];\n            topY    = ys[bestR];\n        }\n\n        // make sure both dimensions are positive, using only empty columns / rows\n        if (leftX == rightX) {\n            int nx = findUnused(usedX, leftX);\n            if (nx > leftX) rightX = nx;\n            else {\n                rightX = leftX;\n                leftX = nx;\n            }\n        }\n        if (bottomY == topY) {\n            int ny = findUnused(usedY, bottomY);\n            if (ny > bottomY) topY = ny;\n            else {\n                topY = bottomY;\n                bottomY = ny;\n            }\n        }\n    }\n\n    // -----------------------------------------------------------------\n    // output the rectangle (counter\u2011clockwise order)\n    cout << 4 << \"\\n\";\n    cout << leftX   << ' ' << bottomY << \"\\n\";\n    cout << leftX   << ' ' << topY    << \"\\n\";\n    cout << rightX  << ' ' << topY    << \"\\n\";\n    cout << rightX  << ' ' << bottomY << \"\\n\";\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rectangle {\n    int width, height;\n    int x, y; // top-left corner, y increases downward\n};\n\nstruct Placement {\n    int p; // rectangle index (position in sequence)\n    int r; // rotation (0=normal, 1=rotated)\n    char d; // direction: 'U'=upward, 'L'=leftward\n    int b; // reference rectangle index in sequence (-1 for boundary)\n};\n\nclass Packer {\n    int N;\n    const vector<int>& w;\n    const vector<int>& h;\n    \n    // Check if two rectangles overlap\n    bool overlap(const Rectangle& a, const Rectangle& b) const {\n        return a.x < b.x + b.width && a.x + a.width > b.x &&\n               a.y < b.y + b.height && a.y + a.height > b.y;\n    }\n    \npublic:\n    explicit Packer(const vector<int>& w, const vector<int>& h) \n        : N(w.size()), w(w), h(h) {}\n    \n    // Simulate placement with explicit i==0 check to prevent out-of-range access\n    pair<vector<Rectangle>, pair<int,int>> simulate(const vector<Placement>& seq) const {\n        vector<Rectangle> placed;\n        placed.reserve(N);\n        \n        for (int i = 0; i < N; i++) {\n            const auto& p = seq[i];\n            int width = (p.r == 0) ? w[i] : h[i];\n            int height = (p.r == 0) ? h[i] : w[i];\n            \n            Rectangle rect{width, height, 0, 0};\n            \n            if (p.d == 'U') {\n                // SAFE: Explicitly check i == 0 to avoid accessing placed[-1]\n                if (i == 0 || p.b == -1 || p.b >= i) {\n                    rect.x = 0;\n                } else {\n                    rect.x = placed[p.b].x + placed[p.b].width;\n                }\n                \n                int min_y = 0;\n                for (int j = 0; j < i; j++) {\n                    const auto& other = placed[j];\n                    if (rect.x < other.x + other.width && rect.x + rect.width > other.x) {\n                        min_y = max(min_y, other.y + other.height);\n                    }\n                }\n                rect.y = min_y;\n            } else { // 'L'\n                // SAFE: Explicitly check i == 0 to avoid accessing placed[-1]\n                if (i == 0 || p.b == -1 || p.b >= i) {\n                    rect.y = 0;\n                } else {\n                    rect.y = placed[p.b].y + placed[p.b].height;\n                }\n                \n                int min_x = 0;\n                for (int j = 0; j < i; j++) {\n                    const auto& other = placed[j];\n                    if (rect.y < other.y + other.height && rect.y + rect.height > other.y) {\n                        min_x = max(min_x, other.x + other.width);\n                    }\n                }\n                rect.x = min_x;\n            }\n            placed.push_back(rect);\n        }\n        \n        int maxX = 0, maxY = 0;\n        for (const auto& r : placed) {\n            maxX = max(maxX, r.x + r.width);\n            maxY = max(maxY, r.y + r.height);\n        }\n        return {placed, {maxX, maxY}};\n    }\n    \n    // Calculate score (W + H)\n    long long calculateScore(const vector<Placement>& seq) const {\n        auto [placed, bbox] = simulate(seq);\n        return (long long)bbox.first + bbox.second;\n    }\n    \n    // Greedy construction - handles i=0 safely\n    vector<Placement> generateGreedy() const {\n        vector<Placement> seq;\n        vector<Rectangle> placed;\n        seq.reserve(N);\n        placed.reserve(N);\n        \n        for (int i = 0; i < N; i++) {\n            int best_r = 0;\n            char best_d = 'U';\n            int best_b = -1;\n            long long bestScore = LLONG_MAX;\n            Rectangle bestRect;\n            \n            // For i=0, only b=-1 is valid (loop runs once with b=-1)\n            // For i>0, try all valid references\n            for (int r = 0; r <= 1; r++) {\n                for (char d : {'U', 'L'}) {\n                    int bStart = -1;\n                    int bEnd = i;\n                    for (int b = bStart; b < bEnd; b++) {\n                        int width = (r == 0) ? w[i] : h[i];\n                        int height = (r == 0) ? h[i] : w[i];\n                        \n                        Rectangle rect{width, height, 0, 0};\n                        \n                        if (d == 'U') {\n                            rect.x = (b == -1) ? 0 : placed[b].x + placed[b].width;\n                            int min_y = 0;\n                            for (int j = 0; j < i; j++) {\n                                const auto& other = placed[j];\n                                if (rect.x < other.x + other.width && rect.x + rect.width > other.x) {\n                                    min_y = max(min_y, other.y + other.height);\n                                }\n                            }\n                            rect.y = min_y;\n                        } else {\n                            rect.y = (b == -1) ? 0 : placed[b].y + placed[b].height;\n                            int min_x = 0;\n                            for (int j = 0; j < i; j++) {\n                                const auto& other = placed[j];\n                                if (rect.y < other.y + other.height && rect.y + rect.height > other.y) {\n                                    min_x = max(min_x, other.x + other.width);\n                                }\n                            }\n                            rect.x = min_x;\n                        }\n                        \n                        // Check overlap\n                        bool overlaps = false;\n                        for (int j = 0; j < i; j++) {\n                            if (overlap(rect, placed[j])) {\n                                overlaps = true;\n                                break;\n                            }\n                        }\n                        if (overlaps) continue;\n                        \n                        // Evaluate placement\n                        placed.push_back(rect);\n                        int maxX = 0, maxY = 0;\n                        for (const auto& r : placed) {\n                            maxX = max(maxX, r.x + r.width);\n                            maxY = max(maxY, r.y + r.height);\n                        }\n                        long long score = (long long)maxX + maxY;\n                        placed.pop_back();\n                        \n                        if (score < bestScore) {\n                            bestScore = score;\n                            best_r = r;\n                            best_d = d;\n                            best_b = b;\n                            bestRect = rect;\n                        }\n                    }\n                }\n            }\n            \n            // Ensure we have a valid placement (should always be true)\n            if (bestScore == LLONG_MAX) {\n                // Fallback: place at (0,0) with no rotation\n                best_r = 0;\n                best_d = 'U';\n                best_b = -1;\n                bestRect = {w[i], h[i], 0, 0};\n            }\n            \n            placed.push_back(bestRect);\n            seq.push_back({i, best_r, best_d, best_b});\n        }\n        return seq;\n    }\n    \n    // Safe mutation that never produces invalid references\n    void safeMutate(vector<Placement>& seq, mt19937& rng) const {\n        int pos = uniform_int_distribution<>(0, N - 1)(rng);\n        \n        if (pos == 0) {\n            // Position 0: only r and d can change, b must be -1\n            seq[pos].b = -1; // Enforce valid reference\n            if (uniform_int_distribution<>(0, 1)(rng)) {\n                seq[pos].r = uniform_int_distribution<>(0, 1)(rng);\n            } else {\n                seq[pos].d = uniform_int_distribution<>(0, 1)(rng) ? 'L' : 'U';\n            }\n            return;\n        }\n        \n        // Other positions: mutate one aspect\n        switch (uniform_int_distribution<>(0, 2)(rng)) {\n            case 0:\n                seq[pos].r = uniform_int_distribution<>(0, 1)(rng);\n                break;\n            case 1:\n                seq[pos].d = uniform_int_distribution<>(0, 1)(rng) ? 'L' : 'U';\n                break;\n            case 2:\n                // Safe reference: ensure b < pos\n                uniform_int_distribution<int> ref(-1, pos - 1);\n                seq[pos].b = ref(rng);\n                break;\n        }\n    }\n    \n    // Hill climbing with fixed iterations for predictable runtime\n    vector<Placement> hillClimb(const vector<Placement>& initial, mt19937& rng, \n                               int maxIterations) const {\n        auto best = initial;\n        long long bestScore = calculateScore(best);\n        auto candidate = best;\n        \n        for (int iter = 0; iter < maxIterations; iter++) {\n            // Try 15 mutations per iteration\n            for (int t = 0; t < 15; t++) {\n                candidate = best;\n                safeMutate(candidate, rng);\n                \n                long long score = calculateScore(candidate);\n                if (score < bestScore) {\n                    bestScore = score;\n                    best.swap(candidate);\n                }\n            }\n        }\n        \n        return best;\n    }\n    \n    // Generate random valid sequence\n    vector<Placement> generateRandom(mt19937& rng) const {\n        vector<Placement> seq;\n        seq.reserve(N);\n        for (int i = 0; i < N; i++) {\n            uniform_int_distribution<int> rot(0, 1);\n            uniform_int_distribution<int> dir(0, 1);\n            uniform_int_distribution<int> ref(-1, i - 1);\n            seq.push_back({i, rot(rng), ref(rng), dir(rng) ? 'L' : 'U'});\n        }\n        return seq;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, T, sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n    \n    vector<int> w(N), h(N);\n    for (int i = 0; i < N; i++) cin >> w[i] >> h[i];\n    \n    Packer packer(w, h);\n    \n    // Safe random seed without random_device (prevents potential exceptions)\n    uint64_t seed = chrono::steady_clock::now().time_since_epoch().count();\n    mt19937 rng(seed);\n    \n    // Greedy baseline (safe initialization)\n    auto seq = packer.generateGreedy();\n    \n    // Single hill climb with 800 iterations (predictable runtime < 3 seconds)\n    seq = packer.hillClimb(seq, rng, 800);\n    \n    // Output for all turns\n    for (int turn = 0; turn < T; turn++) {\n        cout << N << \"\\n\";\n        for (int i = 0; i < N; i++) {\n            const auto& p = seq[i];\n            cout << p.p << \" \" << p.r << \" \" << p.d << \" \" << p.b << \"\\n\";\n        }\n        cout.flush();\n        \n        int Wp, Hp;\n        cin >> Wp >> Hp;\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Tree {\n    int N;                                 // number of vertices\n    int H;                                 // maximal depth (given as 10)\n    const vector<int> &A;                  // beauty values\n    const vector<vector<int>> &adj;        // graph\n    long long sumAAll;                     // \u03a3 A[v]  (constant part of score)\n\n    vector<int> parent;                    // parent[v]  ( -1 for a root )\n    vector<int> depth;                     // depth[v]   (0 \u2026 H)\n    vector<int> sumA;                      // S[v]  \u2013 sum of beauties in subtree\n    vector<int> high;                      // H[v]  \u2013 longest distance to a leaf\n    vector<vector<int>> children;          // children of each vertex\n    long long totalDepthSum;               // \u03a3 depth[v] * A[v]\n\n    // ---------- constructor (all roots) ----------\n    Tree(int N_, int H_, const vector<int> &A_, const vector<vector<int>> &adj_)\n        : N(N_), H(H_), A(A_), adj(adj_) {\n        sumAAll = 0;\n        for (int x : A) sumAAll += x;\n        parent.assign(N, -1);\n        depth.assign(N, 0);\n        sumA = A;                 // each subtree consists only of the vertex itself\n        high.assign(N, 0);\n        children.assign(N, {});\n        totalDepthSum = 0;\n    }\n\n    // ---------- utility ----------\n    bool isDescendant(int anc, int desc) const {\n        int cur = desc;\n        while (cur != -1) {\n            if (cur == anc) return true;\n            cur = parent[cur];\n        }\n        return false;\n    }\n\n    void detach(int v) {\n        int p = parent[v];\n        if (p != -1) {\n            auto &vec = children[p];\n            for (size_t i = 0; i < vec.size(); ++i) {\n                if (vec[i] == v) {\n                    vec.erase(vec.begin() + i);\n                    break;\n                }\n            }\n        }\n        parent[v] = -1;                 // v becomes a root of its own tree\n    }\n\n    void attach(int v, int newParent) {\n        parent[v] = newParent;\n        if (newParent != -1) children[newParent].push_back(v);\n    }\n\n    void applyDepthDelta(int v, int delta) {\n        depth[v] += delta;\n        for (int c : children[v]) applyDepthDelta(c, delta);\n    }\n\n    // recompute sumA and high on the path from v upwards (at most H steps)\n    void recomputeUpward(int v) {\n        while (v != -1) {\n            int s = A[v];\n            int h = 0;\n            for (int c : children[v]) {\n                s += sumA[c];\n                h = max(h, high[c] + 1);\n            }\n            sumA[v] = s;\n            high[v] = h;\n            v = parent[v];\n        }\n    }\n\n    // evaluate a possible move of subtree v to newParent ( -1 = root )\n    // returns {newDepth, gain}  ; gain = -inf if illegal\n    pair<int,long long> evaluateMove(int v, int newParent) const {\n        if (newParent == parent[v]) return {depth[v], 0};          // no change\n        if (newParent != -1 && isDescendant(v, newParent))\n            return {0, LLONG_MIN};                               // would create a cycle\n\n        int newDepth = (newParent == -1 ? 0 : depth[newParent] + 1);\n        if (newDepth + high[v] > H) return {0, LLONG_MIN};       // height violation\n\n        long long delta = (long long)newDepth - (long long)depth[v];\n        long long gain = delta * (long long)sumA[v];\n        return {newDepth, gain};\n    }\n\n    // really perform a move (already known to be legal)\n    void performMove(int v, int newParent, int newDepth) {\n        int oldParent = parent[v];\n        int oldDepth  = depth[v];\n\n        // detach\n        detach(v);\n        if (oldParent != -1) recomputeUpward(oldParent);\n\n        // attach to new parent\n        attach(v, newParent);\n\n        // shift depths inside the whole subtree\n        int delta = newDepth - oldDepth;\n        if (delta != 0) applyDepthDelta(v, delta);\n\n        // recompute sums on the new side\n        if (newParent != -1) recomputeUpward(newParent);\n        else                 recomputeUpward(v);\n\n        totalDepthSum += (long long)delta * (long long)sumA[v];\n    }\n\n    // ---------- greedy hill climbing ----------\n    void greedyPhase(mt19937 &rng, int maxPasses = 30) {\n        bool improved = true;\n        int passes = 0;\n        while (improved && passes < maxPasses) {\n            improved = false;\n            vector<int> order(N);\n            iota(order.begin(), order.end(), 0);\n            shuffle(order.begin(), order.end(), rng);\n            for (int v : order) {\n                int bestParent = -2;\n                int bestDepth  = depth[v];\n                long long bestGain = 0;\n                // try all neighbours\n                for (int u : adj[v]) {\n                    if (u == parent[v]) continue;\n                    auto [newDepth, gain] = evaluateMove(v, u);\n                    if (gain > bestGain) {\n                        bestGain = gain;\n                        bestParent = u;\n                        bestDepth  = newDepth;\n                    }\n                }\n                // also try becoming a root (gain is never positive here)\n                if (bestGain > 0) {\n                    performMove(v, bestParent, bestDepth);\n                    improved = true;\n                }\n            }\n            ++passes;\n        }\n    }\n\n    // ---------- simulated annealing ----------\n    void annealingPhase(mt19937 &rng, double timeLimit) {\n        const double START_TEMP = 2e6;          // a bit larger than maximal possible gain\n        const double END_TEMP   = 1.0;\n        auto start = chrono::steady_clock::now();\n\n        double temp = START_TEMP;\n        uniform_int_distribution<int> VertDist(0, N - 1);\n        uniform_real_distribution<double> ProbDist(0.0, 1.0);\n\n        // iterate until the time budget is exhausted\n        while (true) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - start).count();\n            if (elapsed > timeLimit) break;\n\n            // cooling schedule \u2013 exponential, slower than linear\n            double progress = elapsed / timeLimit;                 // 0 \u2026 1\n            temp = START_TEMP * pow(END_TEMP / START_TEMP, progress);\n\n            int v = VertDist(rng);\n            if (adj[v].empty()) continue;   // never happens (graph is connected)\n\n            // with probability 0.25 try to make the vertex a root,\n            // otherwise pick a random neighbour as new parent\n            int newParent;\n            if (ProbDist(rng) < 0.25) {\n                newParent = -1;\n            } else {\n                int idx = uniform_int_distribution<int>(0, (int)adj[v].size() - 1)(rng);\n                newParent = adj[v][idx];\n            }\n\n            auto [newDepth, gain] = evaluateMove(v, newParent);\n            if (gain == LLONG_MIN) continue;   // illegal\n\n            bool accept = false;\n            if (gain > 0) accept = true;\n            else if (temp > 1e-12) {\n                double prob = exp(gain / temp);\n                if (prob > ProbDist(rng)) accept = true;\n            }\n            if (!accept) continue;\n\n            performMove(v, newParent, newDepth);\n        }\n    }\n\n    long long totalScore() const {\n        return sumAAll + totalDepthSum;\n    }\n};\n\n// -----------------------------------------------------------------------\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, H;\n    if (!(cin >> N >> M >> H)) return 0;\n\n    vector<int> A(N);\n    for (int i = 0; i < N; ++i) cin >> A[i];\n\n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; ++i) {\n        int u, v; cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    // read and discard coordinates\n    for (int i = 0; i < N; ++i) {\n        int x, y; cin >> x >> y;\n    }\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    long long bestScore = 0;\n    vector<int> bestParent(N, -1);\n    {\n        Tree tree(N, H, A, adj);\n        bestScore = tree.totalScore();\n        bestParent = tree.parent;\n    }\n\n    auto start = chrono::steady_clock::now();\n\n    // ---- several restarts (as long as time permits) ----\n    int rounds = 0;\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > 1.85) break;          // total time limit\n\n        Tree tree(N, H, A, adj);\n        tree.greedyPhase(rng, 30);           // up to 30 passes\n\n        // a short but intensive annealing phase\n        double timeLeft = 1.85 - elapsed;\n        if (timeLeft > 0.3) {\n            tree.annealingPhase(rng, timeLeft * 0.75);\n            // final polishing greedy pass\n            tree.greedyPhase(rng, 10);\n        }\n\n        long long cur = tree.totalScore();\n        if (cur > bestScore) {\n            bestScore = cur;\n            bestParent = tree.parent;\n        }\n        ++rounds;\n    }\n\n    // ---------------------------------------------------------------\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << bestParent[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Oni {\n    int i, j;                     // position\n    int upDist, downDist, leftDist, rightDist;\n    bool upSafe, downSafe, leftSafe, rightSafe;\n};\n\n/* -------------------------------------------------------------\n   simulate the whole sequence, respecting the decisions\n   columnsFirst = true  -> columns first, rows afterwards\n   columnsFirst = false -> rows first, columns afterwards\n   moves will be filled with the produced sequence.\n   ------------------------------------------------------------- */\nint simulate(bool columnsFirst,\n             const vector<Oni>& oni,\n             vector<pair<char,int>>& moves) {\n    const int N = 20;                     // board size (fixed in the problem)\n    const int M = (int)oni.size();        // 2*N\n\n    vector<char> removed(M, 0);           // 0 = still on board, 1 = removed\n    int totalMoves = 0;\n    auto addBlock = [&](char dir, int idx, int cnt) {\n        for (int k = 0; k < cnt; ++k) moves.emplace_back(dir, idx);\n        totalMoves += 2 * cnt;            // each block consists of a pair of shifts\n    };\n\n    if (columnsFirst) {\n        // -------------------------------------------------------------\n        // ----- 1. columns (up/down) -----\n        for (int col = 0; col < N; ++col) {\n            // compute the four values for this column\n            int upAll = 0, downAll = 0, upOnly = 0, downOnly = 0;\n            for (int id = 0; id < M; ++id) {\n                const Oni& o = oni[id];\n                if (o.j != col) continue;\n                if (o.upSafe) {\n                    upAll = max(upAll, o.upDist);\n                    if (!o.downSafe) upOnly = max(upOnly, o.upDist);\n                }\n                if (o.downSafe) {\n                    downAll = max(downAll, o.downDist);\n                    if (!o.upSafe) downOnly = max(downOnly, o.downDist);\n                }\n            }\n            // choose the cheaper order\n            bool upFirst = (2 * (upAll + downOnly) <= 2 * (downAll + upOnly));\n\n            if (upFirst) {\n                // up phase\n                int upMax = 0; vector<int> ids;\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.j == col && o.upSafe) {\n                        upMax = max(upMax, o.upDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (upMax) {\n                    addBlock('U', col, upMax);\n                    addBlock('D', col, upMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n                // down phase (only down\u2011safe that are still alive)\n                int downMax = 0; ids.clear();\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.j == col && o.downSafe) {\n                        downMax = max(downMax, o.downDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (downMax) {\n                    addBlock('D', col, downMax);\n                    addBlock('U', col, downMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n            } else {\n                // down phase first\n                int downMax = 0; vector<int> ids;\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.j == col && o.downSafe) {\n                        downMax = max(downMax, o.downDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (downMax) {\n                    addBlock('D', col, downMax);\n                    addBlock('U', col, downMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n                // up phase (only up\u2011safe that are still alive)\n                int upMax = 0; ids.clear();\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.j == col && o.upSafe) {\n                        upMax = max(upMax, o.upDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (upMax) {\n                    addBlock('U', col, upMax);\n                    addBlock('D', col, upMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n            }\n        }\n\n        // -------------------------------------------------------------\n        // ----- 2. rows (left/right) -----\n        for (int row = 0; row < N; ++row) {\n            // recompute the four values using the still alive Oni\n            int leftAll = 0, rightAll = 0, leftOnly = 0, rightOnly = 0;\n            for (int id = 0; id < M; ++id) {\n                const Oni& o = oni[id];\n                if (removed[id] || o.i != row) continue;\n                if (o.leftSafe) {\n                    leftAll = max(leftAll, o.leftDist);\n                    if (!o.rightSafe) leftOnly = max(leftOnly, o.leftDist);\n                }\n                if (o.rightSafe) {\n                    rightAll = max(rightAll, o.rightDist);\n                    if (!o.leftSafe) rightOnly = max(rightOnly, o.rightDist);\n                }\n            }\n            bool leftFirst = (2 * (leftAll + rightOnly) <= 2 * (rightAll + leftOnly));\n\n            if (leftFirst) {\n                // left phase\n                int leftMax = 0; vector<int> ids;\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.i == row && o.leftSafe) {\n                        leftMax = max(leftMax, o.leftDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (leftMax) {\n                    addBlock('L', row, leftMax);\n                    addBlock('R', row, leftMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n                // right phase (only right\u2011safe still alive)\n                int rightMax = 0; ids.clear();\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.i == row && o.rightSafe) {\n                        rightMax = max(rightMax, o.rightDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (rightMax) {\n                    addBlock('R', row, rightMax);\n                    addBlock('L', row, rightMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n            } else {\n                // right phase first\n                int rightMax = 0; vector<int> ids;\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.i == row && o.rightSafe) {\n                        rightMax = max(rightMax, o.rightDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (rightMax) {\n                    addBlock('R', row, rightMax);\n                    addBlock('L', row, rightMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n                // left phase (only left\u2011safe still alive)\n                int leftMax = 0; ids.clear();\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.i == row && o.leftSafe) {\n                        leftMax = max(leftMax, o.leftDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (leftMax) {\n                    addBlock('L', row, leftMax);\n                    addBlock('R', row, leftMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n            }\n        }\n    } else {\n        // -------------------------------------------------------------\n        // ----- rows first, symmetric -----\n        for (int row = 0; row < N; ++row) {\n            int leftAll = 0, rightAll = 0, leftOnly = 0, rightOnly = 0;\n            for (int id = 0; id < M; ++id) {\n                const Oni& o = oni[id];\n                if (o.i != row) continue;\n                if (o.leftSafe) {\n                    leftAll = max(leftAll, o.leftDist);\n                    if (!o.rightSafe) leftOnly = max(leftOnly, o.leftDist);\n                }\n                if (o.rightSafe) {\n                    rightAll = max(rightAll, o.rightDist);\n                    if (!o.leftSafe) rightOnly = max(rightOnly, o.rightDist);\n                }\n            }\n            bool leftFirst = (2 * (leftAll + rightOnly) <= 2 * (rightAll + leftOnly));\n\n            if (leftFirst) {\n                int leftMax = 0; vector<int> ids;\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.i == row && o.leftSafe) {\n                        leftMax = max(leftMax, o.leftDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (leftMax) {\n                    addBlock('L', row, leftMax);\n                    addBlock('R', row, leftMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n                int rightMax = 0; ids.clear();\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.i == row && o.rightSafe) {\n                        rightMax = max(rightMax, o.rightDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (rightMax) {\n                    addBlock('R', row, rightMax);\n                    addBlock('L', row, rightMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n            } else {\n                int rightMax = 0; vector<int> ids;\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.i == row && o.rightSafe) {\n                        rightMax = max(rightMax, o.rightDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (rightMax) {\n                    addBlock('R', row, rightMax);\n                    addBlock('L', row, rightMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n                int leftMax = 0; ids.clear();\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.i == row && o.leftSafe) {\n                        leftMax = max(leftMax, o.leftDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (leftMax) {\n                    addBlock('L', row, leftMax);\n                    addBlock('R', row, leftMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n            }\n        }\n\n        // ----- columns afterwards -----\n        for (int col = 0; col < N; ++col) {\n            int upAll = 0, downAll = 0, upOnly = 0, downOnly = 0;\n            for (int id = 0; id < M; ++id) {\n                const Oni& o = oni[id];\n                if (removed[id] || o.j != col) continue;\n                if (o.upSafe) {\n                    upAll = max(upAll, o.upDist);\n                    if (!o.downSafe) upOnly = max(upOnly, o.upDist);\n                }\n                if (o.downSafe) {\n                    downAll = max(downAll, o.downDist);\n                    if (!o.upSafe) downOnly = max(downOnly, o.downDist);\n                }\n            }\n            bool upFirst = (2 * (upAll + downOnly) <= 2 * (downAll + upOnly));\n\n            if (upFirst) {\n                int upMax = 0; vector<int> ids;\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.j == col && o.upSafe) {\n                        upMax = max(upMax, o.upDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (upMax) {\n                    addBlock('U', col, upMax);\n                    addBlock('D', col, upMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n                int downMax = 0; ids.clear();\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.j == col && o.downSafe) {\n                        downMax = max(downMax, o.downDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (downMax) {\n                    addBlock('D', col, downMax);\n                    addBlock('U', col, downMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n            } else {\n                int downMax = 0; vector<int> ids;\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.j == col && o.downSafe) {\n                        downMax = max(downMax, o.downDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (downMax) {\n                    addBlock('D', col, downMax);\n                    addBlock('U', col, downMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n                int upMax = 0; ids.clear();\n                for (int id = 0; id < M; ++id) {\n                    const Oni& o = oni[id];\n                    if (!removed[id] && o.j == col && o.upSafe) {\n                        upMax = max(upMax, o.upDist);\n                        ids.push_back(id);\n                    }\n                }\n                if (upMax) {\n                    addBlock('U', col, upMax);\n                    addBlock('D', col, upMax);\n                    for (int id : ids) removed[id] = 1;\n                }\n            }\n        }\n    }\n\n    // sanity check \u2013 all Oni must be removed now\n    // (the input guarantees this is possible)\n    return totalMoves;\n}\n\n/* ------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;                                   // N = 20 in the contest\n    if (!(cin >> N)) return 0;\n    vector<string> board(N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n\n    // locate Fuku (only needed for the safety test)\n    vector<vector<bool>> fuku(N, vector<bool>(N, false));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (board[i][j] == 'o') fuku[i][j] = true;\n\n    // -----------------------------------------------------------------\n    // build the list of Oni and compute safety flags\n    vector<Oni> oni;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (board[i][j] == 'x') {\n                Oni o;\n                o.i = i; o.j = j;\n                o.upDist   = i + 1;\n                o.downDist = N - i;\n                o.leftDist = j + 1;\n                o.rightDist = N - j;\n\n                // safety flags\n                o.upSafe = true;\n                for (int ii = 0; ii < i; ++ii) if (fuku[ii][j]) { o.upSafe = false; break; }\n                o.downSafe = true;\n                for (int ii = i + 1; ii < N; ++ii) if (fuku[ii][j]) { o.downSafe = false; break; }\n                o.leftSafe = true;\n                for (int jj = 0; jj < j; ++jj) if (fuku[i][jj]) { o.leftSafe = false; break; }\n                o.rightSafe = true;\n                for (int jj = j + 1; jj < N; ++jj) if (fuku[i][jj]) { o.rightSafe = false; break; }\n\n                oni.push_back(o);\n            }\n\n    // -----------------------------------------------------------------\n    // try both global orders and keep the better one\n    vector<pair<char,int>> moves1, moves2;\n    int cost1 = simulate(true,  oni, moves1);   // columns first\n    int cost2 = simulate(false, oni, moves2);   // rows first\n\n    const auto& bestMoves = (cost1 <= cost2) ? moves1 : moves2;\n\n    // -----------------------------------------------------------------\n    // output the chosen sequence\n    for (auto [dir, idx] : bestMoves) cout << dir << ' ' << idx << '\\n';\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    \n    const int N = 100;\n    const long long L = 500000;\n    const long long AVG = L / N; // 5000\n    const long long STEP = 2500;  // Base adjustment\n    \n    vector<long long> T(N);\n    int n_input;\n    long long l_input;\n    cin >> n_input >> l_input;\n    for (int i = 0; i < N; ++i) cin >> T[i];\n    \n    const long long INF = (1LL << 60);\n    long long best_error = INF;\n    vector<int> best_x(N);\n    \n    // Phase 1: DP for odd transitions (proven core)\n    for (int x0 = 0; x0 <= 1; ++x0) {\n        static long long dp[101][2];\n        static int parent[101][2];\n        \n        dp[0][0] = dp[0][1] = INF;\n        dp[0][x0] = 0;\n        parent[0][x0] = -1;\n        \n        for (int i = 1; i < N; ++i) {\n            dp[i][0] = dp[i][1] = INF;\n            for (int x_curr = 0; x_curr <= 1; ++x_curr) {\n                for (int x_prev = 0; x_prev <= 1; ++x_prev) {\n                    if (dp[i-1][x_prev] == INF) continue;\n                    \n                    long long visits = AVG + STEP * (x_curr - x_prev);\n                    long long error = llabs(T[i] - visits);\n                    long long total = dp[i-1][x_prev] + error;\n                    \n                    if (total < dp[i][x_curr]) {\n                        dp[i][x_curr] = total;\n                        parent[i][x_curr] = x_prev;\n                    }\n                }\n            }\n        }\n        \n        for (int x_last = 0; x_last <= 1; ++x_last) {\n            if (dp[N-1][x_last] == INF) continue;\n            \n            long long visits = AVG + STEP * (x0 - x_last);\n            long long error = llabs(T[0] - visits);\n            long long total = dp[N-1][x_last] + error;\n            \n            if (total < best_error) {\n                best_error = total;\n                best_x[0] = x0;\n                int curr = x_last;\n                for (int i = N-1; i >= 1; --i) {\n                    best_x[i] = curr;\n                    curr = parent[i][curr];\n                }\n            }\n        }\n    }\n    \n    // Phase 2: Enhanced threshold-based even refinement\n    // Lower threshold from 6500 to 6000 for better coverage\n    vector<int> y(N, 0);\n    \n    for (int i = 0; i < N; ++i) {\n        // Safety: only modify if no odd self-loop AND T[i] significantly above average\n        if (best_x[i] == 0 && T[i] > 6000) {\n            y[i] = 1; // Add 2,500 visits via even self-loop\n        }\n    }\n    \n    // Phase 3: Construct final answer\n    vector<int> a(N), b(N);\n    for (int i = 0; i < N; ++i) {\n        a[i] = (best_x[i] == 1) ? i : (i + 1) % N;\n        b[i] = (y[i] == 1) ? i : (i + 1) % N;\n    }\n    \n    // Output\n    for (int i = 0; i < N; ++i) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ---------- integer square root ---------- */\nint isqrt_ll(long long x) {\n    int r = (int)std::sqrt((long double)x);\n    while ((long long)(r + 1) * (r + 1) <= x) ++r;\n    while ((long long)r * r > x) --r;\n    return r;\n}\n\n/* ---------- DSU ---------- */\nstruct DSU {\n    vector<int> parent, sz;\n    int comps;\n    DSU(int n = 0) { init(n); }\n    void init(int n) {\n        parent.resize(n);\n        sz.assign(n, 1);\n        iota(parent.begin(), parent.end(), 0);\n        comps = n;\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 (sz[a] < sz[b]) swap(a, b);\n        parent[b] = a;\n        sz[a] += sz[b];\n        --comps;\n        return true;\n    }\n};\n\n/* ---------- lower\u2011bound distance between two rectangles ---------- */\nint lowerDistRect(int i, int j,\n                  const vector<int>& lx, const vector<int>& rx,\n                  const vector<int>& ly, const vector<int>& ry) {\n    long long dx = 0, dy = 0;\n    if (rx[i] < lx[j]) dx = (long long)lx[j] - rx[i];\n    else if (rx[j] < lx[i]) dx = (long long)lx[i] - rx[j];\n    else dx = 0;\n\n    if (ry[i] < ly[j]) dy = (long long)ly[j] - ry[i];\n    else if (ry[j] < ly[i]) dy = (long long)ly[i] - ry[j];\n    else dy = 0;\n\n    long long sq = dx * dx + dy * dy;\n    return isqrt_ll(sq);\n}\n\n/* ---------- Hilbert order ---------- */\nvoid rot(int &x, int &y, int rx, int ry, int s) {\n    if (ry == 0) {\n        if (rx == 1) {\n            x = s - 1 - x;\n            y = s - 1 - y;\n        }\n        swap(x, y);\n    }\n}\nint hilbert(int x, int y, int N = 21) {\n    int h = 0, s = 1 << N;\n    for (int rx, ry, s2; s > 1; s = s2) {\n        s2 = s / 2;\n        rx = (x & s2) ? 1 : 0;\n        ry = (y & s2) ? 1 : 0;\n        h += s2 * s2 * ((3 * rx) ^ ry);\n        rot(x, y, rx, ry, s2);\n    }\n    return h;\n}\n\n/* ---------- Morton (Z) order ---------- */\nint morton(int x, int y) {\n    unsigned int mx = (unsigned int)x;\n    unsigned int my = (unsigned int)y;\n    mx = (mx | (mx << 8)) & 0x00FF00FF;\n    mx = (mx | (mx << 4)) & 0x0F0F0F0F;\n    mx = (mx | (mx << 2)) & 0x33333333;\n    mx = (mx | (mx << 1)) & 0x55555555;\n\n    my = (my | (my << 8)) & 0x00FF00FF;\n    my = (my | (my << 4)) & 0x0F0F0F0F;\n    my = (my | (my << 2)) & 0x33333333;\n    my = (my | (my << 1)) & 0x55555555;\n\n    return (int)(mx | (my << 1));\n}\n\n/* ---------- estimate total lower\u2011bound MST cost for a partition ---------- */\nlong long estimate_partition_cost(const vector<vector<int>>& groups,\n                                  const vector<vector<int>>& low) {\n    long long total = 0;\n    for (const auto& g : groups) {\n        int sz = g.size();\n        if (sz <= 1) continue;\n        // Prim's algorithm on lower bounds\n        vector<int> minDist(sz, INT_MAX);\n        vector<bool> inTree(sz, false);\n        inTree[0] = true;\n        for (int i = 1; i < sz; ++i)\n            minDist[i] = low[g[0]][g[i]];\n        for (int i = 1; i < sz; ++i) {\n            int best = -1, bestDist = INT_MAX;\n            for (int j = 0; j < sz; ++j)\n                if (!inTree[j] && minDist[j] < bestDist) {\n                    bestDist = minDist[j];\n                    best = j;\n                }\n            total += bestDist;\n            inTree[best] = true;\n            for (int j = 0; j < sz; ++j)\n                if (!inTree[j]) {\n                    int d = low[g[best]][g[j]];\n                    if (d < minDist[j]) minDist[j] = d;\n                }\n        }\n    }\n    return total;\n}\n\n/* ---------- build partition from a linear order ---------- */\nvector<vector<int>> make_partition_from_order(const vector<int>& order,\n                                               const vector<int>& G) {\n    vector<vector<int>> groups(G.size());\n    int pos = 0;\n    for (size_t i = 0; i < G.size(); ++i) {\n        groups[i].reserve(G[i]);\n        for (int j = 0; j < G[i]; ++j)\n            groups[i].push_back(order[pos++]);\n    }\n    return groups;\n}\n\n/* ---------- main ---------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, Q, L, W;\n    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    vector<int> lx(N), rx(N), ly(N), ry(N);\n    for (int i = 0; i < N; ++i) cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n\n    /* ----- pre\u2011compute lower bounds ----- */\n    vector<vector<int>> low(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        low[i][i] = 0;\n        for (int j = i + 1; j < N; ++j) {\n            int d = lowerDistRect(i, j, lx, rx, ly, ry);\n            low[i][j] = low[j][i] = d;\n        }\n    }\n\n    /* ----- centres ----- */\n    vector<int> cx(N), cy(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    /* ----- five candidate partitions ----- */\n    // 1. Hilbert\n    vector<int> order_hilbert(N);\n    iota(order_hilbert.begin(), order_hilbert.end(), 0);\n    sort(order_hilbert.begin(), order_hilbert.end(),\n         [&](int a, int b) { return hilbert(cx[a], cy[a]) < hilbert(cx[b], cy[b]); });\n    auto part_hilbert = make_partition_from_order(order_hilbert, G);\n    long long cost_hilbert = estimate_partition_cost(part_hilbert, low);\n\n    // 2. Morton\n    vector<int> order_morton(N);\n    iota(order_morton.begin(), order_morton.end(), 0);\n    sort(order_morton.begin(), order_morton.end(),\n         [&](int a, int b) { return morton(cx[a], cy[a]) < morton(cx[b], cy[b]); });\n    auto part_morton = make_partition_from_order(order_morton, G);\n    long long cost_morton = estimate_partition_cost(part_morton, low);\n\n    // 3. lexicographic (x, y)\n    vector<int> order_xy(N);\n    iota(order_xy.begin(), order_xy.end(), 0);\n    sort(order_xy.begin(), order_xy.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    auto part_xy = make_partition_from_order(order_xy, G);\n    long long cost_xy = estimate_partition_cost(part_xy, low);\n\n    // 4. lexicographic (y, x)\n    vector<int> order_yx(N);\n    iota(order_yx.begin(), order_yx.end(), 0);\n    sort(order_yx.begin(), order_yx.end(),\n         [&](int a, int b) {\n             if (cy[a] != cy[b]) return cy[a] < cy[b];\n             return cx[a] < cx[b];\n         });\n    auto part_yx = make_partition_from_order(order_yx, G);\n    long long cost_yx = estimate_partition_cost(part_yx, low);\n\n    // 5. distance from origin (0,0)\n    vector<int> order_dist(N);\n    iota(order_dist.begin(), order_dist.end(), 0);\n    sort(order_dist.begin(), order_dist.end(),\n         [&](int a, int b) {\n             long long da = (long long)cx[a] * cx[a] + (long long)cy[a] * cy[a];\n             long long db = (long long)cx[b] * cx[b] + (long long)cy[b] * cy[b];\n             return da < db;\n         });\n    auto part_dist = make_partition_from_order(order_dist, G);\n    long long cost_dist = estimate_partition_cost(part_dist, low);\n\n    // keep the cheapest partition\n    vector<vector<int>> groups = part_hilbert;\n    long long best_cost = cost_hilbert;\n    if (cost_morton < best_cost) {\n        groups = part_morton;\n        best_cost = cost_morton;\n    }\n    if (cost_xy < best_cost) {\n        groups = part_xy;\n        best_cost = cost_xy;\n    }\n    if (cost_yx < best_cost) {\n        groups = part_yx;\n        best_cost = cost_yx;\n    }\n    if (cost_dist < best_cost) {\n        groups = part_dist;\n        best_cost = cost_dist;\n    }\n\n    /* ----- auxiliary data ----- */\n    vector<int> group_of(N, -1);\n    vector<int> local_idx(N, -1);\n    for (int i = 0; i < M; ++i) {\n        for (int j = 0; j < (int)groups[i].size(); ++j) {\n            int city = groups[i][j];\n            group_of[city] = i;\n            local_idx[city] = j;\n        }\n    }\n\n    /* ----- DSU and query structures ----- */\n    vector<DSU> dsu(M);\n    for (int i = 0; i < M; ++i) dsu[i].init((int)groups[i].size());\n\n    vector<vector<pair<int,int>>> group_edges(M);\n\n    int queries_used = 0;\n    while (queries_used < Q) {\n        int best_g = -1, best_comp = 0;\n        for (int i = 0; i < M; ++i) {\n            if (dsu[i].comps > best_comp) {\n                best_comp = dsu[i].comps;\n                best_g = i;\n            }\n        }\n        if (best_g == -1 || best_comp <= 1) break; // all finished\n\n        unordered_map<int,int> rep;   // DSU root -> city id\n        for (int city : groups[best_g]) {\n            int lid = local_idx[city];\n            int root = dsu[best_g].find(lid);\n            if (!rep.count(root)) rep[root] = city;\n        }\n        vector<int> reps;\n        reps.reserve(rep.size());\n        for (auto &kv : rep) reps.push_back(kv.second);\n        sort(reps.begin(), reps.end());   // deterministic order\n\n        vector<int> subset;\n        if ((int)reps.size() <= L) {\n            subset = reps;\n        } else {\n            subset.assign(reps.begin(), reps.begin() + L);\n        }\n\n        int l = (int)subset.size();\n        cout << \"? \" << l;\n        for (int v : subset) cout << ' ' << v;\n        cout << '\\n';\n        cout.flush();\n\n        for (int i = 0; i < l - 1; ++i) {\n            int a, b;\n            cin >> a >> b;\n            if (group_of[a] != group_of[b]) continue;\n            int g = group_of[a];\n            int la = local_idx[a];\n            int lb = local_idx[b];\n            if (dsu[g].unite(la, lb)) {\n                group_edges[g].push_back({a, b});\n            }\n        }\n        ++queries_used;\n    }\n\n    for (int g = 0; g < M; ++g) {\n        if (dsu[g].comps == 1) continue;\n        struct Edge {int u, v, w;};\n        vector<Edge> edges;\n        int sz = (int)groups[g].size();\n        edges.reserve(sz * (sz - 1) / 2);\n        for (int i = 0; i < sz; ++i) {\n            int u = groups[g][i];\n            int lu = i;\n            for (int j = i + 1; j < sz; ++j) {\n                int v = groups[g][j];\n                int lv = j;\n                if (dsu[g].find(lu) == dsu[g].find(lv)) continue;\n                int w = low[u][v];\n                edges.push_back({u, v, w});\n            }\n        }\n        sort(edges.begin(), edges.end(),\n             [](const Edge& a, const Edge& b) {\n                 if (a.w != b.w) return a.w < b.w;\n                 if (a.u != b.u) return a.u < b.u;\n                 return a.v < b.v;\n             });\n        for (const Edge &e : edges) {\n            int lu = local_idx[e.u];\n            int lv = local_idx[e.v];\n            if (dsu[g].unite(lu, lv)) {\n                group_edges[g].push_back({e.u, e.v});\n                if (dsu[g].comps == 1) break;\n            }\n        }\n    }\n\n    cout << \"!\\n\";\n    for (int g = 0; g < M; ++g) {\n        for (size_t i = 0; i < groups[g].size(); ++i) {\n            if (i) cout << ' ';\n            cout << groups[g][i];\n        }\n        cout << '\\n';\n        for (auto &e : group_edges[g])\n            cout << e.first << ' ' << e.second << '\\n';\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint 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>> p(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> p[i].first >> p[i].second;\n    }\n\n    pair<int,int> cur = p[0];                 // start position\n    for (int idx = 1; idx < M; ++idx) {\n        const pair<int,int> tgt = p[idx];\n\n        /* slide to every border that the target touches */\n        if (tgt.first == 0 && cur.first != 0) {\n            cout << \"S U\\n\";\n            cur.first = 0;\n        } else if (tgt.first == N-1 && cur.first != N-1) {\n            cout << \"S D\\n\";\n            cur.first = N-1;\n        }\n\n        if (tgt.second == 0 && cur.second != 0) {\n            cout << \"S L\\n\";\n            cur.second = 0;\n        } else if (tgt.second == N-1 && cur.second != N-1) {\n            cout << \"S R\\n\";\n            cur.second = N-1;\n        }\n\n        /* finish the remaining distance with ordinary moves */\n        while (cur.first < tgt.first) {\n            cout << \"M D\\n\";\n            ++cur.first;\n        }\n        while (cur.first > tgt.first) {\n            cout << \"M U\\n\";\n            --cur.first;\n        }\n        while (cur.second < tgt.second) {\n            cout << \"M R\\n\";\n            ++cur.second;\n        }\n        while (cur.second > tgt.second) {\n            cout << \"M L\\n\";\n            --cur.second;\n        }\n    }\n    return 0;\n}"}}}